@rowsncolumns/ui 15.0.38

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 (358) hide show
  1. package/LICENSE.md +100 -0
  2. package/dist/cjs/arrow/index.d.ts +17 -0
  3. package/dist/cjs/arrow/index.d.ts.map +1 -0
  4. package/dist/cjs/arrow/index.js +46 -0
  5. package/dist/cjs/button/index.d.ts +14 -0
  6. package/dist/cjs/button/index.d.ts.map +1 -0
  7. package/dist/cjs/button/index.js +46 -0
  8. package/dist/cjs/calendar/index.d.ts +5 -0
  9. package/dist/cjs/calendar/index.d.ts.map +1 -0
  10. package/dist/cjs/calendar/index.js +13 -0
  11. package/dist/cjs/card/index.d.ts +10 -0
  12. package/dist/cjs/card/index.d.ts.map +1 -0
  13. package/dist/cjs/card/index.js +32 -0
  14. package/dist/cjs/cell-tooltip/index.d.ts +17 -0
  15. package/dist/cjs/cell-tooltip/index.d.ts.map +1 -0
  16. package/dist/cjs/cell-tooltip/index.js +38 -0
  17. package/dist/cjs/circular-loader/index.d.ts +9 -0
  18. package/dist/cjs/circular-loader/index.d.ts.map +1 -0
  19. package/dist/cjs/circular-loader/index.js +11 -0
  20. package/dist/cjs/color-picker/index.d.ts +12 -0
  21. package/dist/cjs/color-picker/index.d.ts.map +1 -0
  22. package/dist/cjs/color-picker/index.js +101 -0
  23. package/dist/cjs/color-picker/style.d.ts +5 -0
  24. package/dist/cjs/color-picker/style.d.ts.map +1 -0
  25. package/dist/cjs/color-picker/style.js +11 -0
  26. package/dist/cjs/command/index.d.ts +74 -0
  27. package/dist/cjs/command/index.d.ts.map +1 -0
  28. package/dist/cjs/command/index.js +37 -0
  29. package/dist/cjs/conditional-wrapper/index.d.ts +9 -0
  30. package/dist/cjs/conditional-wrapper/index.d.ts.map +1 -0
  31. package/dist/cjs/conditional-wrapper/index.js +4 -0
  32. package/dist/cjs/dialog/index.d.ts +17 -0
  33. package/dist/cjs/dialog/index.d.ts.map +1 -0
  34. package/dist/cjs/dialog/index.js +50 -0
  35. package/dist/cjs/dropdown/index.d.ts +34 -0
  36. package/dist/cjs/dropdown/index.d.ts.map +1 -0
  37. package/dist/cjs/dropdown/index.js +73 -0
  38. package/dist/cjs/editor/constants.d.ts +7 -0
  39. package/dist/cjs/editor/constants.d.ts.map +1 -0
  40. package/dist/cjs/editor/constants.js +50 -0
  41. package/dist/cjs/editor/editor-error-boundary.d.ts +3 -0
  42. package/dist/cjs/editor/editor-error-boundary.d.ts.map +1 -0
  43. package/dist/cjs/editor/editor-error-boundary.js +9 -0
  44. package/dist/cjs/editor/style.d.ts +12 -0
  45. package/dist/cjs/editor/style.d.ts.map +1 -0
  46. package/dist/cjs/editor/style.js +24 -0
  47. package/dist/cjs/editor/suggestions-dropdown.d.ts +25 -0
  48. package/dist/cjs/editor/suggestions-dropdown.d.ts.map +1 -0
  49. package/dist/cjs/editor/suggestions-dropdown.js +120 -0
  50. package/dist/cjs/editor-pm/constants.d.ts +2 -0
  51. package/dist/cjs/editor-pm/constants.d.ts.map +1 -0
  52. package/dist/cjs/editor-pm/constants.js +2 -0
  53. package/dist/cjs/editor-pm/decoration-plugin.d.ts +15 -0
  54. package/dist/cjs/editor-pm/decoration-plugin.d.ts.map +1 -0
  55. package/dist/cjs/editor-pm/decoration-plugin.js +38 -0
  56. package/dist/cjs/editor-pm/helpers.d.ts +197 -0
  57. package/dist/cjs/editor-pm/helpers.d.ts.map +1 -0
  58. package/dist/cjs/editor-pm/helpers.js +1170 -0
  59. package/dist/cjs/editor-pm/index.d.ts +10 -0
  60. package/dist/cjs/editor-pm/index.d.ts.map +1 -0
  61. package/dist/cjs/editor-pm/index.js +9 -0
  62. package/dist/cjs/editor-pm/mention-nodeview.d.ts +31 -0
  63. package/dist/cjs/editor-pm/mention-nodeview.d.ts.map +1 -0
  64. package/dist/cjs/editor-pm/mention-nodeview.js +105 -0
  65. package/dist/cjs/editor-pm/mentions-dropdown.d.ts +13 -0
  66. package/dist/cjs/editor-pm/mentions-dropdown.d.ts.map +1 -0
  67. package/dist/cjs/editor-pm/mentions-dropdown.js +19 -0
  68. package/dist/cjs/editor-pm/mentions-plugin.d.ts +18 -0
  69. package/dist/cjs/editor-pm/mentions-plugin.d.ts.map +1 -0
  70. package/dist/cjs/editor-pm/mentions-plugin.js +72 -0
  71. package/dist/cjs/editor-pm/placeholder-plugin.d.ts +4 -0
  72. package/dist/cjs/editor-pm/placeholder-plugin.d.ts.map +1 -0
  73. package/dist/cjs/editor-pm/placeholder-plugin.js +20 -0
  74. package/dist/cjs/editor-pm/prosemirror-editor.d.ts +493 -0
  75. package/dist/cjs/editor-pm/prosemirror-editor.d.ts.map +1 -0
  76. package/dist/cjs/editor-pm/prosemirror-editor.js +1145 -0
  77. package/dist/cjs/editor-pm/schema.d.ts +3 -0
  78. package/dist/cjs/editor-pm/schema.d.ts.map +1 -0
  79. package/dist/cjs/editor-pm/schema.js +183 -0
  80. package/dist/cjs/editor-pm/types.d.ts +8 -0
  81. package/dist/cjs/editor-pm/types.d.ts.map +1 -0
  82. package/dist/cjs/editor-pm/types.js +1 -0
  83. package/dist/cjs/editor-pm/unfocused-selection-plugin.d.ts +25 -0
  84. package/dist/cjs/editor-pm/unfocused-selection-plugin.d.ts.map +1 -0
  85. package/dist/cjs/editor-pm/unfocused-selection-plugin.js +61 -0
  86. package/dist/cjs/editor-pm/use-dropdown-change-pm.d.ts +24 -0
  87. package/dist/cjs/editor-pm/use-dropdown-change-pm.d.ts.map +1 -0
  88. package/dist/cjs/editor-pm/use-dropdown-change-pm.js +140 -0
  89. package/dist/cjs/editor-pm/use-editor-change-pm.d.ts +29 -0
  90. package/dist/cjs/editor-pm/use-editor-change-pm.d.ts.map +1 -0
  91. package/dist/cjs/editor-pm/use-editor-change-pm.js +154 -0
  92. package/dist/cjs/editor-pm/use-editor-decorator-pm.d.ts +17 -0
  93. package/dist/cjs/editor-pm/use-editor-decorator-pm.d.ts.map +1 -0
  94. package/dist/cjs/editor-pm/use-editor-decorator-pm.js +59 -0
  95. package/dist/cjs/editor-pm/use-editor-keydown-pm.d.ts +21 -0
  96. package/dist/cjs/editor-pm/use-editor-keydown-pm.d.ts.map +1 -0
  97. package/dist/cjs/editor-pm/use-editor-keydown-pm.js +81 -0
  98. package/dist/cjs/editor-pm/use-mention-keydown.d.ts +11 -0
  99. package/dist/cjs/editor-pm/use-mention-keydown.d.ts.map +1 -0
  100. package/dist/cjs/editor-pm/use-mention-keydown.js +59 -0
  101. package/dist/cjs/editor-pm/use-parameter-suggestions.d.ts +19 -0
  102. package/dist/cjs/editor-pm/use-parameter-suggestions.d.ts.map +1 -0
  103. package/dist/cjs/editor-pm/use-parameter-suggestions.js +79 -0
  104. package/dist/cjs/editor-pm/use-parameter-suggestions.test.d.ts +2 -0
  105. package/dist/cjs/editor-pm/use-parameter-suggestions.test.d.ts.map +1 -0
  106. package/dist/cjs/editor-pm/use-parameter-suggestions.test.js +122 -0
  107. package/dist/cjs/eye-dropper/index.d.ts +10 -0
  108. package/dist/cjs/eye-dropper/index.d.ts.map +1 -0
  109. package/dist/cjs/eye-dropper/index.js +24 -0
  110. package/dist/cjs/function-info/helpers.d.ts +10 -0
  111. package/dist/cjs/function-info/helpers.d.ts.map +1 -0
  112. package/dist/cjs/function-info/helpers.js +20 -0
  113. package/dist/cjs/function-info/index.d.ts +11 -0
  114. package/dist/cjs/function-info/index.d.ts.map +1 -0
  115. package/dist/cjs/function-info/index.js +71 -0
  116. package/dist/cjs/function-info/style.d.ts +7 -0
  117. package/dist/cjs/function-info/style.d.ts.map +1 -0
  118. package/dist/cjs/function-info/style.js +13 -0
  119. package/dist/cjs/hex-color-picker/index.d.ts +8 -0
  120. package/dist/cjs/hex-color-picker/index.d.ts.map +1 -0
  121. package/dist/cjs/hex-color-picker/index.js +47 -0
  122. package/dist/cjs/hooks/use-cycle-reference.d.ts +16 -0
  123. package/dist/cjs/hooks/use-cycle-reference.d.ts.map +1 -0
  124. package/dist/cjs/hooks/use-cycle-reference.js +72 -0
  125. package/dist/cjs/hooks/use-dropdown-categories.d.ts +9 -0
  126. package/dist/cjs/hooks/use-dropdown-categories.d.ts.map +1 -0
  127. package/dist/cjs/hooks/use-dropdown-categories.js +45 -0
  128. package/dist/cjs/hooks/use-dropdown.d.ts +38 -0
  129. package/dist/cjs/hooks/use-dropdown.d.ts.map +1 -0
  130. package/dist/cjs/hooks/use-dropdown.js +236 -0
  131. package/dist/cjs/hooks/use-isomorphic-layout-effect.ts.d.ts +6 -0
  132. package/dist/cjs/hooks/use-isomorphic-layout-effect.ts.d.ts.map +1 -0
  133. package/dist/cjs/hooks/use-isomorphic-layout-effect.ts.js +8 -0
  134. package/dist/cjs/hooks/use-modal.d.ts +28 -0
  135. package/dist/cjs/hooks/use-modal.d.ts.map +1 -0
  136. package/dist/cjs/hooks/use-modal.js +101 -0
  137. package/dist/cjs/hooks/use-visibility.d.ts +2 -0
  138. package/dist/cjs/hooks/use-visibility.d.ts.map +1 -0
  139. package/dist/cjs/hooks/use-visibility.js +12 -0
  140. package/dist/cjs/icon-button/index.d.ts +15 -0
  141. package/dist/cjs/icon-button/index.d.ts.map +1 -0
  142. package/dist/cjs/icon-button/index.js +34 -0
  143. package/dist/cjs/index.d.ts +34 -0
  144. package/dist/cjs/index.d.ts.map +1 -0
  145. package/dist/cjs/index.js +33 -0
  146. package/dist/cjs/input/index.d.ts +9 -0
  147. package/dist/cjs/input/index.d.ts.map +1 -0
  148. package/dist/cjs/input/index.js +9 -0
  149. package/dist/cjs/popover/index.d.ts +13 -0
  150. package/dist/cjs/popover/index.d.ts.map +1 -0
  151. package/dist/cjs/popover/index.js +29 -0
  152. package/dist/cjs/progress/index.d.ts +10 -0
  153. package/dist/cjs/progress/index.d.ts.map +1 -0
  154. package/dist/cjs/progress/index.js +15 -0
  155. package/dist/cjs/select/index.d.ts +14 -0
  156. package/dist/cjs/select/index.d.ts.map +1 -0
  157. package/dist/cjs/select/index.js +46 -0
  158. package/dist/cjs/separator/index.d.ts +5 -0
  159. package/dist/cjs/separator/index.d.ts.map +1 -0
  160. package/dist/cjs/separator/index.js +10 -0
  161. package/dist/cjs/skeleton/index.d.ts +7 -0
  162. package/dist/cjs/skeleton/index.d.ts.map +1 -0
  163. package/dist/cjs/skeleton/index.js +11 -0
  164. package/dist/cjs/stack/index.d.ts +11 -0
  165. package/dist/cjs/stack/index.d.ts.map +1 -0
  166. package/dist/cjs/stack/index.js +22 -0
  167. package/dist/cjs/tabs/index.d.ts +8 -0
  168. package/dist/cjs/tabs/index.d.ts.map +1 -0
  169. package/dist/cjs/tabs/index.js +21 -0
  170. package/dist/cjs/tooltip/index.d.ts +12 -0
  171. package/dist/cjs/tooltip/index.d.ts.map +1 -0
  172. package/dist/cjs/tooltip/index.js +20 -0
  173. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  174. package/dist/cjs/utils.d.ts +3 -0
  175. package/dist/cjs/utils.d.ts.map +1 -0
  176. package/dist/cjs/utils.js +9 -0
  177. package/dist/cjs/vitest.config.d.ts +3 -0
  178. package/dist/cjs/vitest.config.d.ts.map +1 -0
  179. package/dist/cjs/vitest.config.js +21 -0
  180. package/dist/esm/arrow/index.d.ts +17 -0
  181. package/dist/esm/arrow/index.d.ts.map +1 -0
  182. package/dist/esm/arrow/index.js +45 -0
  183. package/dist/esm/button/index.d.ts +14 -0
  184. package/dist/esm/button/index.d.ts.map +1 -0
  185. package/dist/esm/button/index.js +44 -0
  186. package/dist/esm/calendar/index.d.ts +5 -0
  187. package/dist/esm/calendar/index.d.ts.map +1 -0
  188. package/dist/esm/calendar/index.js +34 -0
  189. package/dist/esm/card/index.d.ts +10 -0
  190. package/dist/esm/card/index.d.ts.map +1 -0
  191. package/dist/esm/card/index.js +24 -0
  192. package/dist/esm/cell-tooltip/index.d.ts +17 -0
  193. package/dist/esm/cell-tooltip/index.d.ts.map +1 -0
  194. package/dist/esm/cell-tooltip/index.js +31 -0
  195. package/dist/esm/circular-loader/index.d.ts +9 -0
  196. package/dist/esm/circular-loader/index.d.ts.map +1 -0
  197. package/dist/esm/circular-loader/index.js +7 -0
  198. package/dist/esm/color-picker/index.d.ts +12 -0
  199. package/dist/esm/color-picker/index.d.ts.map +1 -0
  200. package/dist/esm/color-picker/index.js +99 -0
  201. package/dist/esm/color-picker/style.d.ts +5 -0
  202. package/dist/esm/color-picker/style.d.ts.map +1 -0
  203. package/dist/esm/color-picker/style.js +7 -0
  204. package/dist/esm/command/index.d.ts +74 -0
  205. package/dist/esm/command/index.d.ts.map +1 -0
  206. package/dist/esm/command/index.js +18 -0
  207. package/dist/esm/conditional-wrapper/index.d.ts +9 -0
  208. package/dist/esm/conditional-wrapper/index.d.ts.map +1 -0
  209. package/dist/esm/conditional-wrapper/index.js +1 -0
  210. package/dist/esm/dialog/index.d.ts +17 -0
  211. package/dist/esm/dialog/index.d.ts.map +1 -0
  212. package/dist/esm/dialog/index.js +30 -0
  213. package/dist/esm/dropdown/index.d.ts +34 -0
  214. package/dist/esm/dropdown/index.d.ts.map +1 -0
  215. package/dist/esm/dropdown/index.js +42 -0
  216. package/dist/esm/editor/constants.d.ts +7 -0
  217. package/dist/esm/editor/constants.d.ts.map +1 -0
  218. package/dist/esm/editor/constants.js +51 -0
  219. package/dist/esm/editor/editor-error-boundary.d.ts +3 -0
  220. package/dist/esm/editor/editor-error-boundary.d.ts.map +1 -0
  221. package/dist/esm/editor/editor-error-boundary.js +9 -0
  222. package/dist/esm/editor/style.d.ts +12 -0
  223. package/dist/esm/editor/style.d.ts.map +1 -0
  224. package/dist/esm/editor/style.js +17 -0
  225. package/dist/esm/editor/suggestions-dropdown.d.ts +25 -0
  226. package/dist/esm/editor/suggestions-dropdown.d.ts.map +1 -0
  227. package/dist/esm/editor/suggestions-dropdown.js +115 -0
  228. package/dist/esm/editor-pm/constants.d.ts +2 -0
  229. package/dist/esm/editor-pm/constants.d.ts.map +1 -0
  230. package/dist/esm/editor-pm/constants.js +2 -0
  231. package/dist/esm/editor-pm/decoration-plugin.d.ts +15 -0
  232. package/dist/esm/editor-pm/decoration-plugin.d.ts.map +1 -0
  233. package/dist/esm/editor-pm/decoration-plugin.js +38 -0
  234. package/dist/esm/editor-pm/helpers.d.ts +197 -0
  235. package/dist/esm/editor-pm/helpers.d.ts.map +1 -0
  236. package/dist/esm/editor-pm/helpers.js +1113 -0
  237. package/dist/esm/editor-pm/index.d.ts +10 -0
  238. package/dist/esm/editor-pm/index.d.ts.map +1 -0
  239. package/dist/esm/editor-pm/index.js +9 -0
  240. package/dist/esm/editor-pm/mention-nodeview.d.ts +31 -0
  241. package/dist/esm/editor-pm/mention-nodeview.d.ts.map +1 -0
  242. package/dist/esm/editor-pm/mention-nodeview.js +88 -0
  243. package/dist/esm/editor-pm/mentions-dropdown.d.ts +13 -0
  244. package/dist/esm/editor-pm/mentions-dropdown.d.ts.map +1 -0
  245. package/dist/esm/editor-pm/mentions-dropdown.js +17 -0
  246. package/dist/esm/editor-pm/mentions-plugin.d.ts +18 -0
  247. package/dist/esm/editor-pm/mentions-plugin.d.ts.map +1 -0
  248. package/dist/esm/editor-pm/mentions-plugin.js +92 -0
  249. package/dist/esm/editor-pm/placeholder-plugin.d.ts +4 -0
  250. package/dist/esm/editor-pm/placeholder-plugin.d.ts.map +1 -0
  251. package/dist/esm/editor-pm/placeholder-plugin.js +20 -0
  252. package/dist/esm/editor-pm/prosemirror-editor.d.ts +493 -0
  253. package/dist/esm/editor-pm/prosemirror-editor.d.ts.map +1 -0
  254. package/dist/esm/editor-pm/prosemirror-editor.js +1135 -0
  255. package/dist/esm/editor-pm/schema.d.ts +3 -0
  256. package/dist/esm/editor-pm/schema.d.ts.map +1 -0
  257. package/dist/esm/editor-pm/schema.js +179 -0
  258. package/dist/esm/editor-pm/types.d.ts +8 -0
  259. package/dist/esm/editor-pm/types.d.ts.map +1 -0
  260. package/dist/esm/editor-pm/types.js +1 -0
  261. package/dist/esm/editor-pm/unfocused-selection-plugin.d.ts +25 -0
  262. package/dist/esm/editor-pm/unfocused-selection-plugin.d.ts.map +1 -0
  263. package/dist/esm/editor-pm/unfocused-selection-plugin.js +61 -0
  264. package/dist/esm/editor-pm/use-dropdown-change-pm.d.ts +24 -0
  265. package/dist/esm/editor-pm/use-dropdown-change-pm.d.ts.map +1 -0
  266. package/dist/esm/editor-pm/use-dropdown-change-pm.js +137 -0
  267. package/dist/esm/editor-pm/use-editor-change-pm.d.ts +29 -0
  268. package/dist/esm/editor-pm/use-editor-change-pm.d.ts.map +1 -0
  269. package/dist/esm/editor-pm/use-editor-change-pm.js +152 -0
  270. package/dist/esm/editor-pm/use-editor-decorator-pm.d.ts +17 -0
  271. package/dist/esm/editor-pm/use-editor-decorator-pm.d.ts.map +1 -0
  272. package/dist/esm/editor-pm/use-editor-decorator-pm.js +57 -0
  273. package/dist/esm/editor-pm/use-editor-keydown-pm.d.ts +21 -0
  274. package/dist/esm/editor-pm/use-editor-keydown-pm.d.ts.map +1 -0
  275. package/dist/esm/editor-pm/use-editor-keydown-pm.js +79 -0
  276. package/dist/esm/editor-pm/use-mention-keydown.d.ts +11 -0
  277. package/dist/esm/editor-pm/use-mention-keydown.d.ts.map +1 -0
  278. package/dist/esm/editor-pm/use-mention-keydown.js +57 -0
  279. package/dist/esm/editor-pm/use-parameter-suggestions.d.ts +19 -0
  280. package/dist/esm/editor-pm/use-parameter-suggestions.d.ts.map +1 -0
  281. package/dist/esm/editor-pm/use-parameter-suggestions.js +66 -0
  282. package/dist/esm/editor-pm/use-parameter-suggestions.test.d.ts +2 -0
  283. package/dist/esm/editor-pm/use-parameter-suggestions.test.d.ts.map +1 -0
  284. package/dist/esm/editor-pm/use-parameter-suggestions.test.js +66 -0
  285. package/dist/esm/eye-dropper/index.d.ts +10 -0
  286. package/dist/esm/eye-dropper/index.d.ts.map +1 -0
  287. package/dist/esm/eye-dropper/index.js +23 -0
  288. package/dist/esm/function-info/helpers.d.ts +10 -0
  289. package/dist/esm/function-info/helpers.d.ts.map +1 -0
  290. package/dist/esm/function-info/helpers.js +20 -0
  291. package/dist/esm/function-info/index.d.ts +11 -0
  292. package/dist/esm/function-info/index.d.ts.map +1 -0
  293. package/dist/esm/function-info/index.js +68 -0
  294. package/dist/esm/function-info/style.d.ts +7 -0
  295. package/dist/esm/function-info/style.d.ts.map +1 -0
  296. package/dist/esm/function-info/style.js +10 -0
  297. package/dist/esm/hex-color-picker/index.d.ts +8 -0
  298. package/dist/esm/hex-color-picker/index.d.ts.map +1 -0
  299. package/dist/esm/hex-color-picker/index.js +44 -0
  300. package/dist/esm/hooks/use-cycle-reference.d.ts +16 -0
  301. package/dist/esm/hooks/use-cycle-reference.d.ts.map +1 -0
  302. package/dist/esm/hooks/use-cycle-reference.js +70 -0
  303. package/dist/esm/hooks/use-dropdown-categories.d.ts +9 -0
  304. package/dist/esm/hooks/use-dropdown-categories.d.ts.map +1 -0
  305. package/dist/esm/hooks/use-dropdown-categories.js +38 -0
  306. package/dist/esm/hooks/use-dropdown.d.ts +38 -0
  307. package/dist/esm/hooks/use-dropdown.d.ts.map +1 -0
  308. package/dist/esm/hooks/use-dropdown.js +236 -0
  309. package/dist/esm/hooks/use-isomorphic-layout-effect.ts.d.ts +6 -0
  310. package/dist/esm/hooks/use-isomorphic-layout-effect.ts.d.ts.map +1 -0
  311. package/dist/esm/hooks/use-isomorphic-layout-effect.ts.js +8 -0
  312. package/dist/esm/hooks/use-modal.d.ts +28 -0
  313. package/dist/esm/hooks/use-modal.d.ts.map +1 -0
  314. package/dist/esm/hooks/use-modal.js +93 -0
  315. package/dist/esm/hooks/use-visibility.d.ts +2 -0
  316. package/dist/esm/hooks/use-visibility.d.ts.map +1 -0
  317. package/dist/esm/hooks/use-visibility.js +12 -0
  318. package/dist/esm/icon-button/index.d.ts +15 -0
  319. package/dist/esm/icon-button/index.d.ts.map +1 -0
  320. package/dist/esm/icon-button/index.js +32 -0
  321. package/dist/esm/index.d.ts +34 -0
  322. package/dist/esm/index.d.ts.map +1 -0
  323. package/dist/esm/index.js +33 -0
  324. package/dist/esm/input/index.d.ts +9 -0
  325. package/dist/esm/input/index.d.ts.map +1 -0
  326. package/dist/esm/input/index.js +7 -0
  327. package/dist/esm/popover/index.d.ts +13 -0
  328. package/dist/esm/popover/index.d.ts.map +1 -0
  329. package/dist/esm/popover/index.js +22 -0
  330. package/dist/esm/progress/index.d.ts +10 -0
  331. package/dist/esm/progress/index.d.ts.map +1 -0
  332. package/dist/esm/progress/index.js +12 -0
  333. package/dist/esm/select/index.d.ts +14 -0
  334. package/dist/esm/select/index.d.ts.map +1 -0
  335. package/dist/esm/select/index.js +30 -0
  336. package/dist/esm/separator/index.d.ts +5 -0
  337. package/dist/esm/separator/index.d.ts.map +1 -0
  338. package/dist/esm/separator/index.js +6 -0
  339. package/dist/esm/skeleton/index.d.ts +7 -0
  340. package/dist/esm/skeleton/index.d.ts.map +1 -0
  341. package/dist/esm/skeleton/index.js +9 -0
  342. package/dist/esm/stack/index.d.ts +11 -0
  343. package/dist/esm/stack/index.d.ts.map +1 -0
  344. package/dist/esm/stack/index.js +20 -0
  345. package/dist/esm/tabs/index.d.ts +8 -0
  346. package/dist/esm/tabs/index.d.ts.map +1 -0
  347. package/dist/esm/tabs/index.js +11 -0
  348. package/dist/esm/tooltip/index.d.ts +12 -0
  349. package/dist/esm/tooltip/index.d.ts.map +1 -0
  350. package/dist/esm/tooltip/index.js +13 -0
  351. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  352. package/dist/esm/utils.d.ts +3 -0
  353. package/dist/esm/utils.d.ts.map +1 -0
  354. package/dist/esm/utils.js +5 -0
  355. package/dist/esm/vitest.config.d.ts +3 -0
  356. package/dist/esm/vitest.config.d.ts.map +1 -0
  357. package/dist/esm/vitest.config.js +21 -0
  358. package/package.json +78 -0
@@ -0,0 +1,1113 @@
1
+ import { cleanupColumnName } from "@rowsncolumns/calculator";
2
+ import { tokenVocabulary } from "@rowsncolumns/fast-formula-parser";
3
+ import { CELL_SUGGESTION_PREFIX, CELL_SUGGESTION_SUFFIX, } from "../editor/constants";
4
+ /**
5
+ * Converts string to ProseMirror document
6
+ * @param str
7
+ * @param schema
8
+ * @returns
9
+ */
10
+ export const deserializeString = (str, schema) => {
11
+ try {
12
+ if (typeof str === "object") {
13
+ str = tryParseRichText(str);
14
+ }
15
+ // Validate input
16
+ if (typeof str !== "string") {
17
+ console.warn("deserializeString: input is not a string, using empty string");
18
+ str = "";
19
+ }
20
+ // Sanitize string - remove null characters and other problematic chars
21
+ str = str
22
+ .replace(/\0/g, "")
23
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
24
+ const lines = str.split("\n");
25
+ const nodes = lines.map((line) => schema.node("line", null, line ? [schema.text(line)] : []));
26
+ return schema.node("doc", null, nodes);
27
+ }
28
+ catch (error) {
29
+ console.error("Error deserializing string:", error);
30
+ // Return empty document as fallback
31
+ return schema.node("doc", null, [schema.node("line", null, [])]);
32
+ }
33
+ };
34
+ export const tryParseRichText = (str) => {
35
+ // Temporary workaround for .richText
36
+ if ("richText" in str) {
37
+ str = str?.richText?.map((value) => value.text).join("");
38
+ }
39
+ else {
40
+ str = "Unable to parse string";
41
+ }
42
+ return str;
43
+ };
44
+ /**
45
+ * Converts ProseMirror document to string
46
+ * @param doc
47
+ * @returns
48
+ */
49
+ export const serializeEditorValue = (doc) => {
50
+ let text = "";
51
+ doc.content.forEach((node, offset, index) => {
52
+ if (node.type.name === "line") {
53
+ if (index > 0)
54
+ text += "\n";
55
+ // Serialize line content, handling mention nodes properly
56
+ let lineText = "";
57
+ node.content.forEach((child) => {
58
+ if (child.type.name === "mention") {
59
+ // Serialize mention as just the label
60
+ lineText += child.attrs.label;
61
+ }
62
+ else if (child.isText) {
63
+ // Regular text node
64
+ lineText += child.text;
65
+ }
66
+ });
67
+ text += lineText;
68
+ }
69
+ });
70
+ return text;
71
+ };
72
+ /**
73
+ * Extracts text format runs from ProseMirror document
74
+ * @param doc ProseMirror document node
75
+ * @returns Array of TextFormatRun objects
76
+ */
77
+ export const extractTextFormatRuns = (doc) => {
78
+ if (!doc) {
79
+ return undefined;
80
+ }
81
+ const formatRuns = [];
82
+ let currentIndex = 0;
83
+ doc.content.forEach((node, _, lineIndex) => {
84
+ if (node.type.name === "line") {
85
+ if (lineIndex > 0) {
86
+ // Add newline character to index
87
+ currentIndex++;
88
+ }
89
+ // First pass: collect all child nodes with their start positions
90
+ const childNodes = [];
91
+ let nodeIndex = currentIndex;
92
+ node.content.forEach((child) => {
93
+ childNodes.push({
94
+ node: child,
95
+ startIndex: nodeIndex,
96
+ });
97
+ // Calculate the next start index based on the node type
98
+ if (child.type.name === "mention") {
99
+ // For mentions, use just the label length for positioning
100
+ nodeIndex += child.attrs.label.length;
101
+ }
102
+ else if (child.isText && child.text) {
103
+ nodeIndex += child.text.length;
104
+ }
105
+ });
106
+ // Second pass: create format runs using next child's start index as end boundary
107
+ childNodes.forEach((childData, index) => {
108
+ const { node: child, startIndex } = childData;
109
+ // Calculate endIndex using next child's startIndex, or end of line
110
+ const nextChild = childNodes[index + 1];
111
+ const endIndex = nextChild ? nextChild.startIndex : nodeIndex;
112
+ if (child.type.name === "mention") {
113
+ formatRuns.push({
114
+ startIndex,
115
+ endIndex,
116
+ nodeType: "mention",
117
+ mention: { ...child.attrs },
118
+ });
119
+ }
120
+ else if (child.isText && child.text) {
121
+ if (child.marks && child.marks.length > 0) {
122
+ // Extract format from marks
123
+ const format = {};
124
+ child.marks.forEach((mark) => {
125
+ switch (mark.type.name) {
126
+ case "bold":
127
+ format.bold = true;
128
+ break;
129
+ case "italic":
130
+ format.italic = true;
131
+ break;
132
+ case "underline":
133
+ format.underline = true;
134
+ break;
135
+ case "strikethrough":
136
+ format.strikethrough = true;
137
+ break;
138
+ case "superscript":
139
+ format.baselineOffset = "superscript";
140
+ break;
141
+ case "subscript":
142
+ format.baselineOffset = "subscript";
143
+ break;
144
+ case "color":
145
+ format.color = mark.attrs.color;
146
+ break;
147
+ case "fontSize":
148
+ format.fontSize = mark.attrs.size;
149
+ break;
150
+ case "fontFamily":
151
+ format.fontFamily = mark.attrs.family;
152
+ break;
153
+ }
154
+ });
155
+ formatRuns.push({
156
+ startIndex,
157
+ endIndex,
158
+ format,
159
+ nodeType: "text",
160
+ });
161
+ }
162
+ else {
163
+ // Plain text without formatting
164
+ formatRuns.push({
165
+ startIndex,
166
+ endIndex,
167
+ format: {},
168
+ nodeType: "text",
169
+ });
170
+ }
171
+ }
172
+ });
173
+ currentIndex = nodeIndex;
174
+ }
175
+ });
176
+ // Filter out text nodes with empty format objects
177
+ const filteredRuns = formatRuns.filter((run) => {
178
+ if (run.nodeType === "text" && Object.keys(run.format).length === 0) {
179
+ return false;
180
+ }
181
+ return true;
182
+ });
183
+ return filteredRuns.length === 0 ? undefined : filteredRuns;
184
+ };
185
+ export const applyTextFormatRuns = (text, formatRuns, schema, resolveColor) => {
186
+ // Handle empty text case
187
+ if (text === "") {
188
+ return schema.nodes.doc.create(null, [schema.nodes.line.create(null, [])]);
189
+ }
190
+ // If no format runs, create simple document with plain text
191
+ if (!formatRuns || formatRuns?.length === 0) {
192
+ const lines = text.split("\n");
193
+ const lineNodes = lines.map((lineText) => schema.nodes.line.create(null, lineText ? [schema.text(lineText)] : []));
194
+ return schema.nodes.doc.create(null, lineNodes);
195
+ }
196
+ const sortedFormatRuns = [...formatRuns].sort((a, b) => a.startIndex - b.startIndex || a.endIndex - b.endIndex);
197
+ const createMarks = (formatRun) => {
198
+ const marks = [];
199
+ // Engine-emitted runs (rnc window cells) can omit `format` on the
200
+ // unformatted gap runs between styled spans.
201
+ if (!formatRun.format) {
202
+ return marks;
203
+ }
204
+ if (formatRun.format.bold) {
205
+ marks.push(schema.marks.bold.create());
206
+ }
207
+ if (formatRun.format.italic) {
208
+ marks.push(schema.marks.italic.create());
209
+ }
210
+ if (formatRun.format.underline) {
211
+ marks.push(schema.marks.underline.create());
212
+ }
213
+ if (formatRun.format.strikethrough) {
214
+ marks.push(schema.marks.strikethrough.create());
215
+ }
216
+ if (formatRun.format.color) {
217
+ const css = typeof formatRun.format.color === "string"
218
+ ? formatRun.format.color
219
+ : resolveColor?.(formatRun.format.color);
220
+ if (css) {
221
+ marks.push(schema.marks.color.create({ color: css }));
222
+ }
223
+ }
224
+ if (formatRun.format.baselineOffset === "superscript") {
225
+ marks.push(schema.marks.superscript.create());
226
+ }
227
+ else if (formatRun.format.baselineOffset === "subscript") {
228
+ marks.push(schema.marks.subscript.create());
229
+ }
230
+ if (formatRun.format.fontSize != null) {
231
+ marks.push(schema.marks.fontSize.create({ size: formatRun.format.fontSize }));
232
+ }
233
+ if (formatRun.format.fontFamily) {
234
+ marks.push(schema.marks.fontFamily.create({ family: formatRun.format.fontFamily }));
235
+ }
236
+ return marks;
237
+ };
238
+ // Split text into lines
239
+ const lines = text.split("\n");
240
+ const lineNodes = [];
241
+ let currentTextIndex = 0;
242
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
243
+ const lineText = lines[lineIndex];
244
+ const lineContent = [];
245
+ if (lineIndex > 0) {
246
+ // Account for newline character
247
+ currentTextIndex++;
248
+ }
249
+ const lineStartIndex = currentTextIndex;
250
+ const lineEndIndex = currentTextIndex + lineText.length;
251
+ // Get format runs that overlap this line. Runs may span newlines,
252
+ // but ProseMirror stores each line separately, so split by line.
253
+ const lineFormatRuns = sortedFormatRuns.filter((run) => run.startIndex < lineEndIndex && run.endIndex > lineStartIndex);
254
+ if (lineFormatRuns.length === 0 && lineText.length > 0) {
255
+ // No formatting, create plain text node
256
+ lineContent.push(schema.text(lineText));
257
+ }
258
+ else if (lineText.length > 0) {
259
+ // Process format runs for this line
260
+ let processedIndex = lineStartIndex;
261
+ for (const formatRun of lineFormatRuns) {
262
+ const runStart = Math.max(formatRun.startIndex, lineStartIndex);
263
+ const runEnd = Math.min(formatRun.endIndex, lineEndIndex);
264
+ if (runEnd <= runStart || processedIndex >= lineEndIndex) {
265
+ continue;
266
+ }
267
+ // Add any unformatted text before this run
268
+ if (processedIndex < runStart) {
269
+ const unformattedText = text.substring(processedIndex, runStart);
270
+ if (unformattedText) {
271
+ lineContent.push(schema.text(unformattedText));
272
+ }
273
+ }
274
+ if (formatRun.nodeType === "mention") {
275
+ // Create mention node from format run data
276
+ if (formatRun.mention && formatRun.startIndex >= lineStartIndex) {
277
+ lineContent.push(schema.nodes.mention.create({
278
+ label: formatRun.mention.label,
279
+ value: formatRun.mention.value,
280
+ }));
281
+ // Since mentions are now stored as just the label, advance by label length
282
+ processedIndex = runStart + formatRun.mention.label.length;
283
+ }
284
+ }
285
+ else {
286
+ // Any non-mention run is a text run. xlsx-imported runs (rnc
287
+ // engine and excel-parser) omit `nodeType`, so an exact
288
+ // `=== "text"` check skipped them entirely — processedIndex
289
+ // never advanced and the gap/tail fillers re-emitted the
290
+ // already-covered text (e.g. "kpmg" painting as "kpmgkpmg").
291
+ const runText = text.substring(Math.max(processedIndex, runStart), runEnd);
292
+ if (runText) {
293
+ lineContent.push(schema.text(runText, createMarks(formatRun)));
294
+ processedIndex = runEnd;
295
+ }
296
+ }
297
+ }
298
+ // Add any remaining unformatted text at the end of the line
299
+ if (processedIndex < lineEndIndex) {
300
+ const remainingText = text.substring(processedIndex, lineEndIndex);
301
+ if (remainingText) {
302
+ lineContent.push(schema.text(remainingText));
303
+ }
304
+ }
305
+ }
306
+ // Create line node
307
+ lineNodes.push(schema.nodes.line.create(null, lineContent));
308
+ currentTextIndex += lineText.length;
309
+ }
310
+ // Create document
311
+ return schema.nodes.doc.create(null, lineNodes);
312
+ };
313
+ /**
314
+ * Applies a `TextFormat` patch to the editor's CURRENT SELECTION as marks —
315
+ * the per-run counterpart of the toolbar's cell-level `onChangeFormatting`.
316
+ * This is what makes the toolbar's bold/superscript/font-size controls format
317
+ * just the selected span while the cell editor is open, the way Cmd+B already
318
+ * does through the keymap.
319
+ *
320
+ * Semantics per key (only keys PRESENT on `format` are touched):
321
+ * - `bold`/`italic`/`underline`/`strikethrough`: TOGGLE against the
322
+ * selection's own mark state (same rule as prosemirror-commands
323
+ * `toggleMark`: any marked text in range → remove, else add) — the caller's
324
+ * cell-level boolean is ignored because it describes the cell, not the span.
325
+ * - `baselineOffset`: if the selection already carries the target offset the
326
+ * pair is cleared; otherwise the target replaces both (mutually exclusive).
327
+ * - `fontSize`/`fontFamily`/`color`: SET to the given value (clear on nullish).
328
+ * Theme-object colors resolve through `resolveColor`.
329
+ *
330
+ * A collapsed selection applies the change to the stored marks, so it affects
331
+ * what is typed next — Google Sheets behavior.
332
+ *
333
+ * Returns `false` (and dispatches nothing) when `format` carries none of the
334
+ * run-representable keys, so the caller can fall back to cell-level formatting.
335
+ */
336
+ export const applyTextFormatToSelection = (state, dispatch, format, schema, resolveColor) => {
337
+ const { from, to, empty } = state.selection;
338
+ const cursorMarks = state.storedMarks ?? state.selection.$from.marks();
339
+ let tr = state.tr;
340
+ let handled = false;
341
+ const hasMark = (markType) => empty
342
+ ? markType.isInSet(cursorMarks) != null
343
+ : state.doc.rangeHasMark(from, to, markType);
344
+ const add = (mark) => {
345
+ tr = empty ? tr.addStoredMark(mark) : tr.addMark(from, to, mark);
346
+ };
347
+ const remove = (markType) => {
348
+ tr = empty ? tr.removeStoredMark(markType) : tr.removeMark(from, to, markType);
349
+ };
350
+ for (const key of ["bold", "italic", "underline", "strikethrough"]) {
351
+ if (!(key in format))
352
+ continue;
353
+ handled = true;
354
+ const markType = schema.marks[key];
355
+ if (hasMark(markType)) {
356
+ remove(markType);
357
+ }
358
+ else {
359
+ add(markType.create());
360
+ }
361
+ }
362
+ if ("baselineOffset" in format) {
363
+ handled = true;
364
+ const target = format.baselineOffset;
365
+ const targetType = target ? schema.marks[target] : undefined;
366
+ const alreadyOn = targetType ? hasMark(targetType) : false;
367
+ remove(schema.marks.superscript);
368
+ remove(schema.marks.subscript);
369
+ if (targetType && !alreadyOn) {
370
+ add(targetType.create());
371
+ }
372
+ }
373
+ if ("fontSize" in format) {
374
+ handled = true;
375
+ remove(schema.marks.fontSize);
376
+ if (format.fontSize != null) {
377
+ add(schema.marks.fontSize.create({ size: format.fontSize }));
378
+ }
379
+ }
380
+ if ("fontFamily" in format) {
381
+ handled = true;
382
+ remove(schema.marks.fontFamily);
383
+ if (format.fontFamily) {
384
+ add(schema.marks.fontFamily.create({ family: format.fontFamily }));
385
+ }
386
+ }
387
+ if ("color" in format) {
388
+ handled = true;
389
+ remove(schema.marks.color);
390
+ const css = typeof format.color === "string"
391
+ ? format.color
392
+ : format.color
393
+ ? resolveColor?.(format.color)
394
+ : undefined;
395
+ if (css) {
396
+ add(schema.marks.color.create({ color: css }));
397
+ }
398
+ }
399
+ if (!handled) {
400
+ return false;
401
+ }
402
+ dispatch?.(tr);
403
+ return true;
404
+ };
405
+ /**
406
+ * Effective fontSize (pt) of the current selection, or `null` when the
407
+ * selection carries no fontSize mark. A collapsed selection reads the stored
408
+ * marks (what the next typed character would get); a range reads the marks of
409
+ * the first text node in the range, matching how the run is rendered.
410
+ */
411
+ export const getSelectionFontSize = (state) => {
412
+ const { from, to, empty } = state.selection;
413
+ let marks = null;
414
+ if (empty) {
415
+ marks = state.storedMarks ?? state.selection.$from.marks();
416
+ }
417
+ else {
418
+ state.doc.nodesBetween(from, to, (node) => {
419
+ if (marks)
420
+ return false;
421
+ if (node.isText) {
422
+ marks = node.marks;
423
+ return false;
424
+ }
425
+ return true;
426
+ });
427
+ }
428
+ const mark = marks?.find((m) => m.type.name === "fontSize");
429
+ const size = mark?.attrs?.size;
430
+ return typeof size === "number" && Number.isFinite(size) ? size : null;
431
+ };
432
+ /**
433
+ * Get current cursor position
434
+ * @param state
435
+ * @returns
436
+ */
437
+ export const getCursorPosition = (state) => {
438
+ try {
439
+ const { selection } = state;
440
+ if (!selection || !selection.empty) {
441
+ return undefined;
442
+ }
443
+ // Bounds checking
444
+ const pos = selection.from;
445
+ if (pos < 0 || pos > state.doc.content.size) {
446
+ console.warn(`Invalid cursor position: ${pos}, doc size: ${state.doc.content.size}`);
447
+ return undefined;
448
+ }
449
+ return pos;
450
+ }
451
+ catch (error) {
452
+ console.warn("Error getting cursor position:", error);
453
+ return undefined;
454
+ }
455
+ };
456
+ /**
457
+ * Get currently focused token
458
+ * @param position
459
+ * @param tokens
460
+ * @returns
461
+ */
462
+ export const getActiveToken = (position, tokens) => {
463
+ return tokens.find((token) => token.endColumn >= position);
464
+ };
465
+ export const enableCellSelection = (position, cursorPos, tokens) => {
466
+ if (!Number.isFinite(cursorPos) || !tokens.length) {
467
+ return false;
468
+ }
469
+ const [prev, active, next] = getSurroundingTokens(position, tokens);
470
+ const isStringLike = (token) => !!token &&
471
+ (token.tokenType.name === tokenVocabulary.String.name ||
472
+ token.tokenType.name === tokenVocabulary.UnterminatedStringStart.name ||
473
+ token.image === '"');
474
+ const isCoveringPosition = (token) => isStringLike(token) &&
475
+ position >= (token?.startColumn ?? position) &&
476
+ position <= (token?.endColumn ?? position);
477
+ if (isStringLike(active) || isStringLike(next) || isCoveringPosition(prev)) {
478
+ return false;
479
+ }
480
+ const isEmptyFunctionCall = prev?.tokenType.name === tokenVocabulary.Function.name &&
481
+ active?.tokenType.name === tokenVocabulary.CloseParen.name &&
482
+ (prev.image ?? "").endsWith("(") &&
483
+ (active.startColumn ?? 0) === (prev.endColumn ?? -1) + 1;
484
+ if (isEmptyFunctionCall) {
485
+ return false;
486
+ }
487
+ const isAfterCloseParen = active?.tokenType.name === tokenVocabulary.CloseParen.name &&
488
+ cursorPos === position + 1;
489
+ if (isAfterCloseParen) {
490
+ return false;
491
+ }
492
+ const prevAllowed = prev &&
493
+ CELL_SUGGESTION_PREFIX.includes(prev.tokenType.name) &&
494
+ position > (prev.endColumn ?? -Infinity);
495
+ // The cursor must actually be inside (or at the trailing edge of) the
496
+ // active token for it to count as the prefix that enables cell
497
+ // selection. Without the `position >= startColumn` guard, a cursor
498
+ // positioned BEFORE the active token (e.g. caret at index 0 of `=$12`)
499
+ // would still treat the leading `=` as the prefix and flip the editor
500
+ // into cell-suggestion mode. Calculator columns are 1-indexed while
501
+ // `position` (offsetInLine) is 0-indexed, so cursor-just-before-token
502
+ // satisfies `position < startColumn`.
503
+ const activeAllowed = active &&
504
+ CELL_SUGGESTION_PREFIX.includes(active.tokenType.name) &&
505
+ position >= (active.startColumn ?? Infinity) &&
506
+ position <= (active.endColumn ?? position);
507
+ const prefixToken = prevAllowed ? prev : activeAllowed ? active : undefined;
508
+ if (!prefixToken) {
509
+ return false;
510
+ }
511
+ const isActiveReferenceStart = active &&
512
+ isReferenceToken(active) &&
513
+ position + 1 === (active.startColumn ?? position + 1);
514
+ if (isActiveReferenceStart) {
515
+ return false;
516
+ }
517
+ const isNextReferenceStart = next &&
518
+ isReferenceToken(next) &&
519
+ position + 1 === (next.startColumn ?? position + 1);
520
+ if (isNextReferenceStart) {
521
+ return false;
522
+ }
523
+ if (next && !CELL_SUGGESTION_SUFFIX.includes(next.tokenType.name)) {
524
+ return false;
525
+ }
526
+ const activeType = active?.tokenType?.name;
527
+ const isInsideReference = isReferenceToken(active) &&
528
+ position >= (active?.startColumn ?? position) &&
529
+ position <= (active?.endColumn ?? position);
530
+ let isInsideFunctionName = false;
531
+ if (activeType === tokenVocabulary.Function.name && active) {
532
+ const start = active.startColumn ?? position;
533
+ let nameEnd = active.endColumn ?? position;
534
+ const image = active.image ?? "";
535
+ if (image.endsWith("(") && image.length > 1) {
536
+ const nameLength = image.length - 1;
537
+ nameEnd = start + nameLength - 1;
538
+ }
539
+ isInsideFunctionName = position >= start && position <= nameEnd;
540
+ }
541
+ if (isInsideReference ||
542
+ isInsideFunctionName ||
543
+ activeType === tokenVocabulary.String.name ||
544
+ activeType === tokenVocabulary.UnterminatedStringStart.name ||
545
+ activeType === tokenVocabulary.Number.name ||
546
+ activeType === tokenVocabulary.Boolean.name) {
547
+ return false;
548
+ }
549
+ return true;
550
+ };
551
+ /**
552
+ * Get prev, current and next tokens using a position
553
+ * @param position
554
+ * @param tokens
555
+ * @returns
556
+ */
557
+ export const getSurroundingTokens = (position, tokens) => {
558
+ const activeToken = getActiveToken(position, tokens);
559
+ return [
560
+ getPreviousToken(position, tokens),
561
+ activeToken,
562
+ getNextToken(position, tokens, activeToken),
563
+ ];
564
+ };
565
+ /**
566
+ * Get the previous token from the current position
567
+ * @param position
568
+ * @param tokens
569
+ * @returns
570
+ */
571
+ export const getPreviousToken = (position, tokens) => {
572
+ let previous;
573
+ for (const token of tokens) {
574
+ if (token.endColumn < position) {
575
+ previous = token;
576
+ continue;
577
+ }
578
+ if (token.startColumn <= position && token.endColumn >= position) {
579
+ return previous;
580
+ }
581
+ if (token.startColumn > position) {
582
+ break;
583
+ }
584
+ }
585
+ return previous;
586
+ };
587
+ /**
588
+ * Get next token from position
589
+ * @param position
590
+ * @param tokens
591
+ * @returns
592
+ */
593
+ export const getNextToken = (position, tokens, activeToken) => {
594
+ return tokens.find((token) => {
595
+ if (activeToken && token === activeToken) {
596
+ return false;
597
+ }
598
+ const start = token.startColumn && token.startColumn > 0
599
+ ? token.startColumn - 1
600
+ : token.startOffset;
601
+ return start !== undefined && start >= position;
602
+ });
603
+ };
604
+ /**
605
+ * Is current token a cell token
606
+ * @param token
607
+ * @returns
608
+ */
609
+ export const isCellToken = (token) => token.tokenType.name === tokenVocabulary.Cell.name || token.selection;
610
+ export const isTableColumnToken = (token) => token.tokenType.name === tokenVocabulary.TableColumnName.name;
611
+ export const isTableNameToken = (token) => token.tokenType.name === tokenVocabulary.TableName.name;
612
+ export const isNamedRangeToken = (token) => token.tokenType.name === tokenVocabulary.Name.name;
613
+ export const isStringToken = (token) => token.tokenType.name === tokenVocabulary.String.name;
614
+ export const isNumberToken = (token) => token.tokenType.name === tokenVocabulary.Number.name;
615
+ const isReferenceToken = (token) => {
616
+ if (!token)
617
+ return false;
618
+ return (isCellToken(token) ||
619
+ isTableColumnToken(token) ||
620
+ isTableNameToken(token) ||
621
+ isNamedRangeToken(token) ||
622
+ token.tokenType.name === tokenVocabulary.Column.name);
623
+ };
624
+ /**
625
+ * Check if token is a cell reference with property (e.g., A1.title or A1.)
626
+ * @param token
627
+ * @returns
628
+ */
629
+ export const getPropertyStartIndex = (token) => {
630
+ if (!token?.image) {
631
+ return -1;
632
+ }
633
+ if (token.tokenType.name === tokenVocabulary.Cell.name ||
634
+ token.tokenType.name === tokenVocabulary.Name.name) {
635
+ return token.image.indexOf(".");
636
+ }
637
+ if (token.tokenType.name === tokenVocabulary.TableColumnName.name ||
638
+ token.tokenType.name === tokenVocabulary.SpecialItem.name ||
639
+ token.tokenType.name === tokenVocabulary.TableName.name) {
640
+ const lastClosingBracket = token.image.lastIndexOf("]");
641
+ if (lastClosingBracket === -1) {
642
+ return -1;
643
+ }
644
+ return token.image.indexOf(".", lastClosingBracket + 1);
645
+ }
646
+ return -1;
647
+ };
648
+ export const hasPropertyReference = (token) => {
649
+ const index = getPropertyStartIndex(token);
650
+ return index !== -1;
651
+ };
652
+ /**
653
+ * Get current active function
654
+ * @param curToken
655
+ * @param tokens
656
+ */
657
+ export const getActiveFunctionToken = (curToken, tokens) => {
658
+ if (!curToken)
659
+ return void 0;
660
+ let i = tokens.findIndex((token) => token === curToken);
661
+ let fn;
662
+ let skip = 0;
663
+ while (i > 0) {
664
+ const token = tokens[i];
665
+ if (token.tokenType.name === tokenVocabulary.CloseParen.name) {
666
+ skip++;
667
+ }
668
+ if (token.tokenType.name === tokenVocabulary.Function.name) {
669
+ if (skip > 0) {
670
+ skip--;
671
+ }
672
+ else {
673
+ fn = token;
674
+ break;
675
+ }
676
+ }
677
+ i--;
678
+ }
679
+ return fn;
680
+ };
681
+ /**
682
+ * get selection index from activetoken
683
+ * @param activeToken
684
+ * @returns
685
+ */
686
+ export const getActiveSelectionIndex = (activeToken) => {
687
+ return activeToken?.structured ||
688
+ activeToken?.isNamedRange ||
689
+ activeToken?.selection
690
+ ? activeToken.index ?? -1
691
+ : -1;
692
+ };
693
+ /**
694
+ * Suggestion token
695
+ * @param position
696
+ * @param activeToken
697
+ * @param view
698
+ * @returns
699
+ */
700
+ export const getActiveSuggestionToken = (position, activeToken, view) => {
701
+ // If the token is already a function, lets ignore
702
+ if (!activeToken ||
703
+ activeToken.tokenType.name === tokenVocabulary.Function.name) {
704
+ return undefined;
705
+ }
706
+ const propertyStart = hasPropertyReference(activeToken)
707
+ ? getPropertyStartIndex(activeToken)
708
+ : -1;
709
+ if (propertyStart !== -1 && activeToken?.image != null) {
710
+ const propertyImage = activeToken.image.slice(propertyStart + 1);
711
+ const propertyStartOffset = (activeToken.startOffset ?? 0) + propertyStart + 1;
712
+ const propertyStartColumn = (activeToken.startColumn ?? 0) + propertyStart + 1;
713
+ const suggestionToken = {
714
+ ...activeToken,
715
+ image: propertyImage,
716
+ startOffset: propertyStartOffset,
717
+ endOffset: propertyStartOffset + propertyImage.length,
718
+ startColumn: propertyStartColumn,
719
+ endColumn: propertyStartColumn + propertyImage.length,
720
+ };
721
+ suggestionToken.basePropertyToken = activeToken;
722
+ return suggestionToken;
723
+ }
724
+ // Named ranges.
725
+ // Resolved named ranges have `index` property. If its resolved,
726
+ // lets not show suggestions anymore
727
+ if (activeToken.tokenType.name === tokenVocabulary.Name.name &&
728
+ activeToken.index !== undefined) {
729
+ return undefined;
730
+ }
731
+ // For tables
732
+ if (activeToken.tokenType.name === tokenVocabulary.TableName.name ||
733
+ activeToken.tokenType.name === tokenVocabulary.TableColumnName.name) {
734
+ try {
735
+ const result = getWordAtPosition(view.state, position);
736
+ if (result?.end === position) {
737
+ return undefined;
738
+ }
739
+ // Use the token's image directly for cleanup
740
+ // This avoids complex ProseMirror position calculations
741
+ const tokenImage = activeToken.image || "";
742
+ const tableNameLength = activeToken.tableName
743
+ ? activeToken.tableName.length + 1
744
+ : 0;
745
+ if (!tokenImage) {
746
+ return undefined;
747
+ }
748
+ const cleanupImage = cleanupColumnName(tokenImage);
749
+ const change = tokenImage.length - cleanupImage.length;
750
+ return {
751
+ ...activeToken,
752
+ startOffset: activeToken.startOffset + tableNameLength + change,
753
+ image: cleanupImage,
754
+ };
755
+ }
756
+ catch (error) {
757
+ console.warn("Error processing table suggestion token:", error);
758
+ return activeToken;
759
+ }
760
+ }
761
+ return activeToken.tokenType.name === tokenVocabulary.TableColumnName.name ||
762
+ activeToken.tokenType.name === tokenVocabulary.Column.name ||
763
+ activeToken.tokenType.name === tokenVocabulary.Name.name ||
764
+ activeToken.tokenType.name === tokenVocabulary.Function.name ||
765
+ activeToken.tokenType.name === tokenVocabulary.UnterminatedStringStart.name
766
+ ? activeToken
767
+ : undefined;
768
+ };
769
+ export const resolveCellPropertyToken = (activeToken, tokens) => {
770
+ if (hasPropertyReference(activeToken)) {
771
+ return activeToken;
772
+ }
773
+ if (!activeToken) {
774
+ return undefined;
775
+ }
776
+ const index = tokens.findIndex((token) => token === activeToken);
777
+ if (index === -1) {
778
+ return undefined;
779
+ }
780
+ for (let i = index - 1; i >= 0; i--) {
781
+ const token = tokens[i];
782
+ if (token.tokenType.name === tokenVocabulary.Cell.name ||
783
+ token.tokenType.name === tokenVocabulary.TableColumnName.name ||
784
+ token.tokenType.name === tokenVocabulary.TableName.name) {
785
+ if (hasPropertyReference(token)) {
786
+ return token;
787
+ }
788
+ }
789
+ }
790
+ return undefined;
791
+ };
792
+ /**
793
+ * Get active table token
794
+ * @param position
795
+ * @param activeToken
796
+ * @param tokens
797
+ * @param view
798
+ * @param isEdge
799
+ * @returns
800
+ */
801
+ export const getActiveTableToken = (position, activeToken, tokens, view, isEdge) => {
802
+ if (!activeToken)
803
+ return undefined;
804
+ let table = void 0;
805
+ // Get character before cursor - use tokenized content for consistency
806
+ const { state } = view;
807
+ const fullContent = state.doc.textContent;
808
+ // Map position back to the original content
809
+ // For now, use simple approach since position is within tokenized text
810
+ const previousCharacter = position > 0 && fullContent.length > position - 1
811
+ ? fullContent.charAt(position - 1)
812
+ : "";
813
+ const isFocusOutsideToken = position > activeToken.endColumn;
814
+ // Table1[Column]<--
815
+ if (isEdge && previousCharacter === "]") {
816
+ return undefined;
817
+ }
818
+ // Table[Column] <--- token with spaces
819
+ if (activeToken.tokenType.name === tokenVocabulary.TableName.name &&
820
+ !isFocusOutsideToken) {
821
+ return activeToken;
822
+ }
823
+ // [ <--- Square with space
824
+ if (activeToken.tokenType.name === tokenVocabulary.OpenSquareParen.name &&
825
+ !isFocusOutsideToken) {
826
+ table = activeToken;
827
+ }
828
+ let i = tokens.findIndex((token) => token === activeToken);
829
+ while (i > 0) {
830
+ const token = tokens[i];
831
+ // User starts with [ or [Column
832
+ if (token.tokenType.name === tokenVocabulary.OpenSquareParen.name ||
833
+ token.tokenType.name === tokenVocabulary.TableColumnName.name) {
834
+ const previousToken = tokens[i - 1];
835
+ if (!previousToken ||
836
+ CELL_SUGGESTION_PREFIX.indexOf(previousToken.tokenType.name) !== -1) {
837
+ return token;
838
+ }
839
+ }
840
+ // Find tableName by going back from the
841
+ // current location
842
+ if ([
843
+ tokenVocabulary.Name.name,
844
+ tokenVocabulary.OpenSquareParen.name,
845
+ tokenVocabulary.CloseSquareParen.name,
846
+ tokenVocabulary.Colon.name,
847
+ tokenVocabulary.Column.name,
848
+ ].indexOf(token.tokenType.name) !== -1) {
849
+ i--;
850
+ continue;
851
+ }
852
+ // Exclude certain tokens that should not be inside
853
+ // a structured reference
854
+ if (CELL_SUGGESTION_SUFFIX.indexOf(token.tokenType.name) !== -1 ||
855
+ CELL_SUGGESTION_PREFIX.indexOf(token.tokenType.name) !== -1) {
856
+ return undefined;
857
+ }
858
+ // Found table
859
+ if (token.tokenType.name === tokenVocabulary.TableName.name) {
860
+ table = token;
861
+ break;
862
+ }
863
+ i--;
864
+ }
865
+ return table;
866
+ };
867
+ /**
868
+ * Get current parameter index that use is focused on
869
+ * @param curToken
870
+ * @param functionToken
871
+ * @param tokens
872
+ */
873
+ export const getParameterIndex = (curToken, functionToken, tokens) => {
874
+ let startIndex = tokens.findIndex((token) => token === curToken);
875
+ const endIndex = tokens.findIndex((token) => token === functionToken);
876
+ let count = 0;
877
+ /* Skips nested functions */
878
+ let skip = 0;
879
+ // Fix for =SUMX2MY2({1, 2, 3}, {4, 5, 6}), Store indices we should skip
880
+ let replace = false;
881
+ const skipCommaIndices = [];
882
+ for (let i = tokens.length - 1; i >= 0; i--) {
883
+ const token = tokens[i];
884
+ if (token.image === "}") {
885
+ replace = true;
886
+ }
887
+ else if (token.image === "{") {
888
+ replace = false;
889
+ }
890
+ else {
891
+ if (replace) {
892
+ skipCommaIndices.push(i);
893
+ }
894
+ }
895
+ }
896
+ while (startIndex > endIndex) {
897
+ const token = tokens[startIndex];
898
+ if (token.image === ")") {
899
+ skip++;
900
+ }
901
+ else if (token.tokenType.name === "Comma" &&
902
+ skip === 0 &&
903
+ !(skipCommaIndices.indexOf(startIndex) !== -1)) {
904
+ count++;
905
+ }
906
+ if (token.tokenType.name === "Function") {
907
+ if (skip > 0)
908
+ skip--;
909
+ }
910
+ startIndex--;
911
+ }
912
+ return count;
913
+ };
914
+ export const getFunctionParameters = (input, functionToken) => {
915
+ if (!functionToken) {
916
+ return { parameters: [], ranges: [] };
917
+ }
918
+ const searchStart = functionToken.startColumn ?? 0;
919
+ const openIndex = input.indexOf("(", searchStart);
920
+ if (openIndex === -1) {
921
+ return { parameters: [], ranges: [] };
922
+ }
923
+ let depth = 0;
924
+ let closeIndex = -1;
925
+ for (let i = openIndex; i < input.length; i++) {
926
+ const ch = input[i];
927
+ if (ch === "(")
928
+ depth++;
929
+ else if (ch === ")") {
930
+ depth--;
931
+ if (depth === 0) {
932
+ closeIndex = i;
933
+ break;
934
+ }
935
+ }
936
+ }
937
+ // If user hasn't typed the closing paren yet, use the end of the string
938
+ if (closeIndex === -1) {
939
+ closeIndex = input.length;
940
+ }
941
+ if (closeIndex <= openIndex) {
942
+ return { parameters: [], ranges: [] };
943
+ }
944
+ const argsSlice = input.slice(openIndex + 1, closeIndex);
945
+ const parameters = [];
946
+ const ranges = [];
947
+ let start = 0;
948
+ let brace = 0;
949
+ let bracket = 0;
950
+ let paren = 0;
951
+ let inSingle = false;
952
+ let inDouble = false;
953
+ const pushParam = (endIndex) => {
954
+ const raw = argsSlice.slice(start, endIndex);
955
+ const leading = raw.length - raw.trimStart().length;
956
+ const trailing = raw.length - raw.trimEnd().length;
957
+ const absoluteStart = openIndex + 1 + start + leading;
958
+ const absoluteEnd = openIndex + 1 + endIndex - trailing;
959
+ parameters.push(raw.trim());
960
+ ranges.push({ start: absoluteStart, end: absoluteEnd });
961
+ };
962
+ for (let i = 0; i <= argsSlice.length; i++) {
963
+ const ch = argsSlice[i];
964
+ if (i === argsSlice.length ||
965
+ (ch === "," &&
966
+ paren === 0 &&
967
+ brace === 0 &&
968
+ bracket === 0 &&
969
+ !inSingle &&
970
+ !inDouble)) {
971
+ pushParam(i);
972
+ start = i + 1;
973
+ continue;
974
+ }
975
+ if (ch === "'" && !inDouble) {
976
+ inSingle = !inSingle;
977
+ continue;
978
+ }
979
+ if (ch === '"' && !inSingle) {
980
+ inDouble = !inDouble;
981
+ continue;
982
+ }
983
+ if (inSingle || inDouble)
984
+ continue;
985
+ if (ch === "(")
986
+ paren++;
987
+ else if (ch === ")")
988
+ paren--;
989
+ else if (ch === "{")
990
+ brace++;
991
+ else if (ch === "}")
992
+ brace--;
993
+ else if (ch === "[")
994
+ bracket++;
995
+ else if (ch === "]")
996
+ bracket--;
997
+ }
998
+ return { parameters, ranges };
999
+ };
1000
+ /**
1001
+ * Get content and offset for tokenization, handling both single and multi-line scenarios
1002
+ * @param state ProseMirror editor state
1003
+ * @param cursorPos Current cursor position
1004
+ * @returns Object with line content and offset within that content
1005
+ */
1006
+ export const getTokenizationContent = (state, cursorPos) => {
1007
+ try {
1008
+ // Validate cursor position
1009
+ if (cursorPos < 0 || cursorPos > state.doc.content.size) {
1010
+ console.warn(`Invalid cursor position: ${cursorPos}, doc size: ${state.doc.content.size}`);
1011
+ return {
1012
+ line: state.doc.textContent || "",
1013
+ offsetInLine: 0,
1014
+ };
1015
+ }
1016
+ const $pos = state.doc.resolve(cursorPos);
1017
+ // Strategy 1: For typical spreadsheet formulas, tokenize entire content
1018
+ // This works best when content is a single formula that may span lines
1019
+ const fullContent = state.doc.textContent;
1020
+ if (fullContent.startsWith("=") || fullContent.length <= 1000) {
1021
+ // This looks like a formula or is short enough to tokenize entirely
1022
+ // Calculate position in the full text content
1023
+ // Need to account for ProseMirror's document structure vs plain text
1024
+ let textPosition = 0;
1025
+ let found = false;
1026
+ state.doc.descendants((node, pos) => {
1027
+ if (found)
1028
+ return false;
1029
+ if (node.isText) {
1030
+ if (pos <= cursorPos && cursorPos <= pos + node.nodeSize) {
1031
+ // Cursor is within this text node
1032
+ textPosition += cursorPos - pos;
1033
+ found = true;
1034
+ return false;
1035
+ }
1036
+ else if (pos + node.nodeSize < cursorPos) {
1037
+ // This text node is before cursor position
1038
+ textPosition += node.text?.length || 0;
1039
+ }
1040
+ }
1041
+ return !found;
1042
+ });
1043
+ return {
1044
+ line: fullContent,
1045
+ offsetInLine: Math.max(0, textPosition),
1046
+ };
1047
+ }
1048
+ // Strategy 2: For non-formula content, use current line approach
1049
+ // This works better for multi-line text that isn't a single formula
1050
+ const parent = $pos.parent;
1051
+ if (parent && parent.isTextblock) {
1052
+ const lineStart = $pos.start($pos.depth);
1053
+ const offsetInLine = Math.max(0, cursorPos - lineStart);
1054
+ return {
1055
+ line: parent.textContent || "",
1056
+ offsetInLine: offsetInLine,
1057
+ };
1058
+ }
1059
+ // Strategy 3: Fallback to full content with simple position mapping
1060
+ return {
1061
+ line: fullContent,
1062
+ offsetInLine: Math.max(0, Math.min(cursorPos, fullContent.length)),
1063
+ };
1064
+ }
1065
+ catch (error) {
1066
+ console.warn("Error getting tokenization content:", error);
1067
+ // Safe fallback
1068
+ const safeContent = state.doc.textContent || "";
1069
+ return {
1070
+ line: safeContent,
1071
+ offsetInLine: Math.max(0, Math.min(cursorPos, safeContent.length)),
1072
+ };
1073
+ }
1074
+ };
1075
+ /**
1076
+ * Cleanup function token to remove parentheses
1077
+ * @param text
1078
+ */
1079
+ export const cleanFunctionToken = (text) => {
1080
+ return text.replace(new RegExp(/\(|\)/, "gi"), "");
1081
+ };
1082
+ // Alternative approach using ProseMirror's built-in word detection:
1083
+ function getWordAtPosition(editorState, pos) {
1084
+ const doc = editorState.doc;
1085
+ const $pos = doc.resolve(pos);
1086
+ // Use ProseMirror's word pattern matching
1087
+ const wordRE = /\w+/g;
1088
+ const textNode = $pos.parent;
1089
+ const textContent = textNode.textContent;
1090
+ const localPos = $pos.parentOffset;
1091
+ let match;
1092
+ let wordStart = null;
1093
+ let wordEnd = null;
1094
+ // Find all word matches and determine which one contains our position
1095
+ while ((match = wordRE.exec(textContent)) !== null) {
1096
+ const matchStart = match.index;
1097
+ const matchEnd = match.index + match[0].length;
1098
+ if (localPos >= matchStart && localPos <= matchEnd) {
1099
+ wordStart = $pos.start() + matchStart;
1100
+ wordEnd = $pos.start() + matchEnd;
1101
+ break;
1102
+ }
1103
+ }
1104
+ if (wordStart === null || wordEnd === null) {
1105
+ return undefined;
1106
+ }
1107
+ const wordText = doc.textBetween(wordStart, wordEnd, " ");
1108
+ return {
1109
+ start: wordStart,
1110
+ end: wordEnd,
1111
+ text: wordText,
1112
+ };
1113
+ }