@chenzy-design/core 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/ai-chat-dialogue.d.ts +300 -0
  2. package/dist/ai-chat-dialogue.d.ts.map +1 -0
  3. package/dist/ai-chat-dialogue.js +699 -0
  4. package/dist/ai-chat-dialogue.js.map +1 -0
  5. package/dist/ai-chat-dialogue.test.d.ts +2 -0
  6. package/dist/ai-chat-dialogue.test.d.ts.map +1 -0
  7. package/dist/ai-chat-dialogue.test.js +338 -0
  8. package/dist/ai-chat-dialogue.test.js.map +1 -0
  9. package/dist/ai-chat-input.d.ts +191 -0
  10. package/dist/ai-chat-input.d.ts.map +1 -0
  11. package/dist/ai-chat-input.js +274 -0
  12. package/dist/ai-chat-input.js.map +1 -0
  13. package/dist/ai-chat-input.test.d.ts +2 -0
  14. package/dist/ai-chat-input.test.d.ts.map +1 -0
  15. package/dist/ai-chat-input.test.js +339 -0
  16. package/dist/ai-chat-input.test.js.map +1 -0
  17. package/dist/audio-player.d.ts +154 -0
  18. package/dist/audio-player.d.ts.map +1 -0
  19. package/dist/audio-player.js +254 -0
  20. package/dist/audio-player.js.map +1 -0
  21. package/dist/audio-player.test.d.ts +2 -0
  22. package/dist/audio-player.test.d.ts.map +1 -0
  23. package/dist/audio-player.test.js +275 -0
  24. package/dist/audio-player.test.js.map +1 -0
  25. package/dist/back-top.d.ts +4 -1
  26. package/dist/back-top.d.ts.map +1 -1
  27. package/dist/back-top.js +5 -2
  28. package/dist/back-top.js.map +1 -1
  29. package/dist/back-top.test.js +3 -2
  30. package/dist/back-top.test.js.map +1 -1
  31. package/dist/calendar.d.ts +132 -44
  32. package/dist/calendar.d.ts.map +1 -1
  33. package/dist/calendar.js +413 -70
  34. package/dist/calendar.js.map +1 -1
  35. package/dist/calendar.test.js +160 -76
  36. package/dist/calendar.test.js.map +1 -1
  37. package/dist/chat.d.ts +172 -0
  38. package/dist/chat.d.ts.map +1 -0
  39. package/dist/chat.js +210 -0
  40. package/dist/chat.js.map +1 -0
  41. package/dist/chat.test.d.ts +2 -0
  42. package/dist/chat.test.d.ts.map +1 -0
  43. package/dist/chat.test.js +181 -0
  44. package/dist/chat.test.js.map +1 -0
  45. package/dist/code-highlight.d.ts +30 -0
  46. package/dist/code-highlight.d.ts.map +1 -0
  47. package/dist/code-highlight.js +37 -0
  48. package/dist/code-highlight.js.map +1 -0
  49. package/dist/code-highlight.test.d.ts +2 -0
  50. package/dist/code-highlight.test.d.ts.map +1 -0
  51. package/dist/code-highlight.test.js +36 -0
  52. package/dist/code-highlight.test.js.map +1 -0
  53. package/dist/collapsible.d.ts +41 -0
  54. package/dist/collapsible.d.ts.map +1 -0
  55. package/dist/collapsible.js +33 -0
  56. package/dist/collapsible.js.map +1 -0
  57. package/dist/collapsible.test.d.ts +2 -0
  58. package/dist/collapsible.test.d.ts.map +1 -0
  59. package/dist/collapsible.test.js +57 -0
  60. package/dist/collapsible.test.js.map +1 -0
  61. package/dist/color-value.d.ts +60 -0
  62. package/dist/color-value.d.ts.map +1 -0
  63. package/dist/color-value.js +165 -0
  64. package/dist/color-value.js.map +1 -0
  65. package/dist/color-value.test.d.ts +2 -0
  66. package/dist/color-value.test.d.ts.map +1 -0
  67. package/dist/color-value.test.js +104 -0
  68. package/dist/color-value.test.js.map +1 -0
  69. package/dist/config-provider.d.ts +76 -37
  70. package/dist/config-provider.d.ts.map +1 -1
  71. package/dist/config-provider.js +107 -32
  72. package/dist/config-provider.js.map +1 -1
  73. package/dist/config-provider.test.js +123 -60
  74. package/dist/config-provider.test.js.map +1 -1
  75. package/dist/cropper.d.ts +164 -0
  76. package/dist/cropper.d.ts.map +1 -0
  77. package/dist/cropper.js +841 -0
  78. package/dist/cropper.js.map +1 -0
  79. package/dist/cropper.test.d.ts +2 -0
  80. package/dist/cropper.test.d.ts.map +1 -0
  81. package/dist/cropper.test.js +259 -0
  82. package/dist/cropper.test.js.map +1 -0
  83. package/dist/drag-move.d.ts +119 -0
  84. package/dist/drag-move.d.ts.map +1 -0
  85. package/dist/drag-move.js +237 -0
  86. package/dist/drag-move.js.map +1 -0
  87. package/dist/drag-move.test.d.ts +2 -0
  88. package/dist/drag-move.test.d.ts.map +1 -0
  89. package/dist/drag-move.test.js +304 -0
  90. package/dist/drag-move.test.js.map +1 -0
  91. package/dist/editable.d.ts +24 -4
  92. package/dist/editable.d.ts.map +1 -1
  93. package/dist/editable.js +18 -0
  94. package/dist/editable.js.map +1 -1
  95. package/dist/editable.test.js +55 -2
  96. package/dist/editable.test.js.map +1 -1
  97. package/dist/ellipsis.d.ts +13 -0
  98. package/dist/ellipsis.d.ts.map +1 -1
  99. package/dist/ellipsis.js +36 -0
  100. package/dist/ellipsis.js.map +1 -1
  101. package/dist/ellipsis.test.js +37 -1
  102. package/dist/ellipsis.test.js.map +1 -1
  103. package/dist/form-path.d.ts +19 -0
  104. package/dist/form-path.d.ts.map +1 -0
  105. package/dist/form-path.js +97 -0
  106. package/dist/form-path.js.map +1 -0
  107. package/dist/form-path.test.d.ts +2 -0
  108. package/dist/form-path.test.d.ts.map +1 -0
  109. package/dist/form-path.test.js +57 -0
  110. package/dist/form-path.test.js.map +1 -0
  111. package/dist/form-validate.d.ts +13 -0
  112. package/dist/form-validate.d.ts.map +1 -0
  113. package/dist/form-validate.js +204 -0
  114. package/dist/form-validate.js.map +1 -0
  115. package/dist/form.d.ts +91 -18
  116. package/dist/form.d.ts.map +1 -1
  117. package/dist/form.js +170 -115
  118. package/dist/form.js.map +1 -1
  119. package/dist/form.test.js +349 -76
  120. package/dist/form.test.js.map +1 -1
  121. package/dist/highlight.d.ts +42 -32
  122. package/dist/highlight.d.ts.map +1 -1
  123. package/dist/highlight.js +67 -41
  124. package/dist/highlight.js.map +1 -1
  125. package/dist/highlight.test.js +73 -32
  126. package/dist/highlight.test.js.map +1 -1
  127. package/dist/hotkeys.d.ts +151 -0
  128. package/dist/hotkeys.d.ts.map +1 -0
  129. package/dist/hotkeys.js +188 -0
  130. package/dist/hotkeys.js.map +1 -0
  131. package/dist/hotkeys.test.d.ts +2 -0
  132. package/dist/hotkeys.test.d.ts.map +1 -0
  133. package/dist/hotkeys.test.js +170 -0
  134. package/dist/hotkeys.test.js.map +1 -0
  135. package/dist/index.d.ts +33 -17
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +32 -13
  138. package/dist/index.js.map +1 -1
  139. package/dist/input.d.ts +34 -0
  140. package/dist/input.d.ts.map +1 -0
  141. package/dist/input.js +54 -0
  142. package/dist/input.js.map +1 -0
  143. package/dist/input.test.d.ts +2 -0
  144. package/dist/input.test.d.ts.map +1 -0
  145. package/dist/input.test.js +56 -0
  146. package/dist/input.test.js.map +1 -0
  147. package/dist/markdown-render.d.ts +49 -0
  148. package/dist/markdown-render.d.ts.map +1 -0
  149. package/dist/markdown-render.js +61 -0
  150. package/dist/markdown-render.js.map +1 -0
  151. package/dist/markdown-render.test.d.ts +2 -0
  152. package/dist/markdown-render.test.d.ts.map +1 -0
  153. package/dist/markdown-render.test.js +106 -0
  154. package/dist/markdown-render.test.js.map +1 -0
  155. package/dist/notification.d.ts +40 -31
  156. package/dist/notification.d.ts.map +1 -1
  157. package/dist/notification.js +86 -70
  158. package/dist/notification.js.map +1 -1
  159. package/dist/notification.test.js +62 -39
  160. package/dist/notification.test.js.map +1 -1
  161. package/dist/numeral.d.ts +32 -0
  162. package/dist/numeral.d.ts.map +1 -0
  163. package/dist/numeral.js +67 -0
  164. package/dist/numeral.js.map +1 -0
  165. package/dist/numeral.test.d.ts +2 -0
  166. package/dist/numeral.test.d.ts.map +1 -0
  167. package/dist/numeral.test.js +59 -0
  168. package/dist/numeral.test.js.map +1 -0
  169. package/dist/overflow-list.d.ts +9 -40
  170. package/dist/overflow-list.d.ts.map +1 -1
  171. package/dist/overflow-list.js +9 -70
  172. package/dist/overflow-list.js.map +1 -1
  173. package/dist/overflow-list.test.js +1 -122
  174. package/dist/overflow-list.test.js.map +1 -1
  175. package/dist/pagination.d.ts +17 -0
  176. package/dist/pagination.d.ts.map +1 -1
  177. package/dist/pagination.js +48 -0
  178. package/dist/pagination.js.map +1 -1
  179. package/dist/pagination.test.js +40 -1
  180. package/dist/pagination.test.js.map +1 -1
  181. package/dist/pincode.d.ts +79 -0
  182. package/dist/pincode.d.ts.map +1 -0
  183. package/dist/pincode.js +119 -0
  184. package/dist/pincode.js.map +1 -0
  185. package/dist/pincode.test.d.ts +2 -0
  186. package/dist/pincode.test.d.ts.map +1 -0
  187. package/dist/pincode.test.js +151 -0
  188. package/dist/pincode.test.js.map +1 -0
  189. package/dist/progress.d.ts +32 -30
  190. package/dist/progress.d.ts.map +1 -1
  191. package/dist/progress.js +257 -64
  192. package/dist/progress.js.map +1 -1
  193. package/dist/progress.test.js +50 -47
  194. package/dist/progress.test.js.map +1 -1
  195. package/dist/resizable.d.ts +200 -0
  196. package/dist/resizable.d.ts.map +1 -0
  197. package/dist/resizable.js +329 -0
  198. package/dist/resizable.js.map +1 -0
  199. package/dist/resizable.test.d.ts +2 -0
  200. package/dist/resizable.test.d.ts.map +1 -0
  201. package/dist/resizable.test.js +302 -0
  202. package/dist/resizable.test.js.map +1 -0
  203. package/dist/scroll-list.d.ts +69 -62
  204. package/dist/scroll-list.d.ts.map +1 -1
  205. package/dist/scroll-list.js +103 -144
  206. package/dist/scroll-list.js.map +1 -1
  207. package/dist/scroll-list.test.js +100 -110
  208. package/dist/scroll-list.test.js.map +1 -1
  209. package/dist/sidebar.d.ts +46 -0
  210. package/dist/sidebar.d.ts.map +1 -0
  211. package/dist/sidebar.js +65 -0
  212. package/dist/sidebar.js.map +1 -0
  213. package/dist/sidebar.test.d.ts +2 -0
  214. package/dist/sidebar.test.d.ts.map +1 -0
  215. package/dist/sidebar.test.js +88 -0
  216. package/dist/sidebar.test.js.map +1 -0
  217. package/dist/spin.d.ts +5 -5
  218. package/dist/spin.d.ts.map +1 -1
  219. package/dist/spin.js +13 -39
  220. package/dist/spin.js.map +1 -1
  221. package/dist/spin.test.js +2 -26
  222. package/dist/spin.test.js.map +1 -1
  223. package/dist/toast.d.ts +33 -30
  224. package/dist/toast.d.ts.map +1 -1
  225. package/dist/toast.js +77 -72
  226. package/dist/toast.js.map +1 -1
  227. package/dist/toast.test.js +63 -37
  228. package/dist/toast.test.js.map +1 -1
  229. package/dist/tree.d.ts +22 -5
  230. package/dist/tree.d.ts.map +1 -1
  231. package/dist/tree.js +61 -9
  232. package/dist/tree.js.map +1 -1
  233. package/dist/tree.test.js +72 -1
  234. package/dist/tree.test.js.map +1 -1
  235. package/dist/user-guide.d.ts +73 -0
  236. package/dist/user-guide.d.ts.map +1 -0
  237. package/dist/user-guide.js +95 -0
  238. package/dist/user-guide.js.map +1 -0
  239. package/dist/user-guide.test.d.ts +2 -0
  240. package/dist/user-guide.test.d.ts.map +1 -0
  241. package/dist/user-guide.test.js +109 -0
  242. package/dist/user-guide.test.js.map +1 -0
  243. package/dist/video-player.d.ts +196 -0
  244. package/dist/video-player.d.ts.map +1 -0
  245. package/dist/video-player.js +461 -0
  246. package/dist/video-player.js.map +1 -0
  247. package/dist/video-player.test.d.ts +2 -0
  248. package/dist/video-player.test.d.ts.map +1 -0
  249. package/dist/video-player.test.js +435 -0
  250. package/dist/video-player.test.js.map +1 -0
  251. package/package.json +17 -1
  252. package/dist/banner.d.ts +0 -19
  253. package/dist/banner.d.ts.map +0 -1
  254. package/dist/banner.js +0 -20
  255. package/dist/banner.js.map +0 -1
  256. package/dist/banner.test.d.ts +0 -2
  257. package/dist/banner.test.d.ts.map +0 -1
  258. package/dist/banner.test.js +0 -29
  259. package/dist/banner.test.js.map +0 -1
  260. package/dist/breakpoints.d.ts +0 -30
  261. package/dist/breakpoints.d.ts.map +0 -1
  262. package/dist/breakpoints.js +0 -45
  263. package/dist/breakpoints.js.map +0 -1
  264. package/dist/breakpoints.test.d.ts +0 -2
  265. package/dist/breakpoints.test.d.ts.map +0 -1
  266. package/dist/breakpoints.test.js +0 -46
  267. package/dist/breakpoints.test.js.map +0 -1
  268. package/dist/lottie-icon.d.ts +0 -88
  269. package/dist/lottie-icon.d.ts.map +0 -1
  270. package/dist/lottie-icon.js +0 -84
  271. package/dist/lottie-icon.js.map +0 -1
  272. package/dist/lottie-icon.test.d.ts +0 -2
  273. package/dist/lottie-icon.test.d.ts.map +0 -1
  274. package/dist/lottie-icon.test.js +0 -88
  275. package/dist/lottie-icon.test.js.map +0 -1
  276. package/dist/sider.d.ts +0 -26
  277. package/dist/sider.d.ts.map +0 -1
  278. package/dist/sider.js +0 -55
  279. package/dist/sider.js.map +0 -1
  280. package/dist/sider.test.d.ts +0 -2
  281. package/dist/sider.test.d.ts.map +0 -1
  282. package/dist/sider.test.js +0 -29
  283. package/dist/sider.test.js.map +0 -1
package/dist/editable.js CHANGED
@@ -16,6 +16,19 @@ export function clampLength(value, maxLength) {
16
16
  return value;
17
17
  return value.length > maxLength ? value.slice(0, maxLength) : value;
18
18
  }
19
+ /**
20
+ * over-limit predicate: true when `value` exceeds `maxLength` (in code units).
21
+ * undefined/0-or-less maxLength = no limit → never over.
22
+ *
23
+ * Aligns with Ant Design: the draft is allowed to exceed maxLength (turns red +
24
+ * blocks commit) instead of being hard-truncated. The render layer uses this to
25
+ * paint the textarea red; core uses it to refuse commit while over-limit.
26
+ */
27
+ export function isOverLimit(value, maxLength) {
28
+ if (maxLength === undefined || maxLength <= 0)
29
+ return false;
30
+ return value.length > maxLength;
31
+ }
19
32
  /** Pure: map a keydown (while editing) to its semantic action. */
20
33
  export function resolveEditableKey(e) {
21
34
  if (e.key === 'Escape')
@@ -37,15 +50,20 @@ export function createEditable(options = {}) {
37
50
  get draft() {
38
51
  return draft;
39
52
  },
53
+ get overLimit() {
54
+ return isOverLimit(draft, options.maxLength);
55
+ },
40
56
  start(source) {
41
57
  if (editing)
42
58
  return;
43
59
  editing = true;
60
+ // hard-clamp the seed to maxLength: input can never exceed the cap.
44
61
  draft = clampLength(source ?? options.value ?? '', options.maxLength);
45
62
  options.onStart?.();
46
63
  emit();
47
64
  },
48
65
  setDraft(next) {
66
+ // hard clamp: characters beyond maxLength are dropped (can't type past the cap).
49
67
  const clamped = clampLength(next, options.maxLength);
50
68
  if (clamped === draft)
51
69
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"editable.js","sourceRoot":"","sources":["../src/editable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kFAAkF;AAClF,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,SAAkB;IAC3D,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACtE,CAAC;AAYD,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,CAAmB;IACpD,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,OAAO,MAAM,CAAC;AAChB,CAAC;AAuCD,MAAM,UAAU,cAAc,CAAC,UAA2B,EAAE;IAC1D,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAEhC,SAAS,IAAI;QACX,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,OAAO;QACL,IAAI,OAAO;YACT,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,KAAK;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,CAAC,MAAM;YACV,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,GAAG,WAAW,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACtE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACpB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,QAAQ,CAAC,IAAI;YACX,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,OAAO,KAAK,KAAK;gBAAE,OAAO;YAC9B,KAAK,GAAG,OAAO,CAAC;YAChB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,OAAO;YACL,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,SAAS,GAAG,KAAK,CAAC;YACxB,qEAAqE;YACrE,IAAI,SAAS,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,EAAE,CAAC;QACT,CAAC;QACD,MAAM;YACJ,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,GAAG,KAAK,CAAC;YAChB,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,SAAS,CAAC,CAAC;YACT,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,OAAO,EAAE,CAAC;iBACpC,IAAI,MAAM,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,gEAAgE;YAChE,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"editable.js","sourceRoot":"","sources":["../src/editable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kFAAkF;AAClF,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,SAAkB;IAC3D,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACtE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,SAAkB;IAC3D,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;AAClC,CAAC;AAYD,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,CAAmB;IACpD,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,OAAO,MAAM,CAAC;AAChB,CAAC;AAkDD,MAAM,UAAU,cAAc,CAAC,UAA2B,EAAE;IAC1D,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAEhC,SAAS,IAAI;QACX,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,OAAO;QACL,IAAI,OAAO;YACT,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,KAAK;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,SAAS;YACX,OAAO,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,CAAC,MAAM;YACV,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,oEAAoE;YACpE,KAAK,GAAG,WAAW,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACtE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACpB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,QAAQ,CAAC,IAAI;YACX,iFAAiF;YACjF,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,OAAO,KAAK,KAAK;gBAAE,OAAO;YAC9B,KAAK,GAAG,OAAO,CAAC;YAChB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,OAAO;YACL,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,SAAS,GAAG,KAAK,CAAC;YACxB,qEAAqE;YACrE,IAAI,SAAS,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,EAAE,CAAC;QACT,CAAC;QACD,MAAM;YACJ,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,GAAG,KAAK,CAAC;YAChB,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrB,IAAI,EAAE,CAAC;QACT,CAAC;QACD,SAAS,CAAC,CAAC;YACT,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,OAAO,EAAE,CAAC;iBACpC,IAAI,MAAM,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,gEAAgE;YAChE,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
- import { createEditable, clampLength, resolveEditableKey } from './editable.js';
2
+ import { createEditable, clampLength, isOverLimit, resolveEditableKey } from './editable.js';
3
3
  describe('clampLength', () => {
4
4
  it('returns value unchanged when no maxLength', () => {
5
5
  expect(clampLength('hello')).toBe('hello');
@@ -11,6 +11,23 @@ describe('clampLength', () => {
11
11
  expect(clampLength('hello', 0)).toBe('hello');
12
12
  });
13
13
  });
14
+ describe('isOverLimit', () => {
15
+ it('false when no maxLength', () => {
16
+ expect(isOverLimit('hello')).toBe(false);
17
+ });
18
+ it('false when within limit', () => {
19
+ expect(isOverLimit('hel', 3)).toBe(false);
20
+ });
21
+ it('false at exactly the limit', () => {
22
+ expect(isOverLimit('hel', 3)).toBe(false);
23
+ });
24
+ it('true when over the limit', () => {
25
+ expect(isOverLimit('hello', 3)).toBe(true);
26
+ });
27
+ it('false when maxLength <= 0', () => {
28
+ expect(isOverLimit('hello', 0)).toBe(false);
29
+ });
30
+ });
14
31
  describe('resolveEditableKey', () => {
15
32
  it('Enter → confirm', () => {
16
33
  expect(resolveEditableKey({ key: 'Enter' })).toBe('confirm');
@@ -37,11 +54,47 @@ describe('createEditable', () => {
37
54
  e.start('other');
38
55
  expect(e.draft).toBe('other');
39
56
  });
40
- it('setDraft clamps to maxLength', () => {
57
+ it('setDraft hard-clamps to maxLength (chars past the cap are dropped)', () => {
41
58
  const e = createEditable({ value: '', maxLength: 3 });
42
59
  e.start();
43
60
  e.setDraft('abcdef');
44
61
  expect(e.draft).toBe('abc');
62
+ expect(e.overLimit).toBe(false);
63
+ });
64
+ it('overLimit stays false since draft is always clamped', () => {
65
+ const e = createEditable({ value: '', maxLength: 3 });
66
+ e.start();
67
+ e.setDraft('abc');
68
+ expect(e.overLimit).toBe(false);
69
+ });
70
+ it('confirm commits the clamped draft', () => {
71
+ const onCommit = vi.fn();
72
+ const e = createEditable({ value: 'a', maxLength: 3, onCommit });
73
+ e.start();
74
+ e.setDraft('abcdef');
75
+ e.confirm();
76
+ expect(e.editing).toBe(false);
77
+ expect(onCommit).toHaveBeenCalledWith('abc');
78
+ });
79
+ it('handleKey Enter confirms the clamped draft', () => {
80
+ const onCommit = vi.fn();
81
+ const e = createEditable({ value: 'a', maxLength: 3, onCommit });
82
+ e.start();
83
+ e.setDraft('abcdef');
84
+ const action = e.handleKey({ key: 'Enter' });
85
+ expect(action).toBe('confirm');
86
+ expect(e.editing).toBe(false);
87
+ expect(onCommit).toHaveBeenCalledWith('abc');
88
+ });
89
+ it('start clamps an over-limit source to maxLength', () => {
90
+ const e = createEditable({ value: 'abcdef', maxLength: 3 });
91
+ e.start();
92
+ expect(e.draft).toBe('abc');
93
+ expect(e.overLimit).toBe(false);
94
+ });
95
+ it('accepts text / both triggers (informational)', () => {
96
+ expect(() => createEditable({ trigger: 'text' })).not.toThrow();
97
+ expect(() => createEditable({ trigger: 'both' })).not.toThrow();
45
98
  });
46
99
  it('confirm fires onCommit only when changed and exits editing', () => {
47
100
  const onCommit = vi.fn();
@@ -1 +1 @@
1
- {"version":3,"file":"editable.test.js","sourceRoot":"","sources":["../src/editable.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editable.test.js","sourceRoot":"","sources":["../src/editable.test.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,19 @@ export declare function isOverflowing(input: EllipsisMeasureInput): boolean;
39
39
  * end truncation is normally left to CSS. Always inserts the ellipsis char.
40
40
  */
41
41
  export declare function truncateText(text: string, maxChars: number, pos: EllipsisPos, ellipsis?: string): string;
42
+ /**
43
+ * Pure: binary-search the largest visible-char budget whose `truncateText`
44
+ * output still fits, using a caller-supplied `fits(candidate)` predicate. The
45
+ * render layer owns DOM measurement (writes the candidate, reads scrollWidth);
46
+ * this keeps the search algorithm framework-agnostic and unit-testable.
47
+ *
48
+ * Returns the best-fitting truncated string. If the full text already fits
49
+ * (`fits(text)` true) it is returned unchanged; if not even the ellipsis alone
50
+ * fits, the ellipsis is returned as a floor.
51
+ *
52
+ * `pos` selects head/tail retention (start/middle/end). Single-line only.
53
+ */
54
+ export declare function fitTruncatedText(text: string, pos: EllipsisPos, fits: (candidate: string) => boolean, ellipsis?: string): string;
42
55
  export interface EllipsisOptions {
43
56
  /** clamp rows (default 1) */
44
57
  rows?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"ellipsis.d.ts","sourceRoot":"","sources":["../src/ellipsis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAYlE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,EAChB,QAAQ,SAAM,GACb,MAAM,CAcR;AAED,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,6BAA6B;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7C,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,kDAAkD;IAClD,MAAM,IAAI,IAAI,CAAC;IACf,8BAA8B;IAC9B,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,qEAAqE;IACrE,OAAO,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC;CAC/C;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,WAAW,CA0CzE"}
1
+ {"version":3,"file":"ellipsis.d.ts","sourceRoot":"","sources":["../src/ellipsis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAYlE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,EAChB,QAAQ,SAAM,GACb,MAAM,CAcR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,EACpC,QAAQ,SAAM,GACb,MAAM,CAoBR;AAED,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,6BAA6B;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7C,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,kDAAkD;IAClD,MAAM,IAAI,IAAI,CAAC;IACf,8BAA8B;IAC9B,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,qEAAqE;IACrE,OAAO,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC;CAC/C;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,WAAW,CA0CzE"}
package/dist/ellipsis.js CHANGED
@@ -53,6 +53,42 @@ export function truncateText(text, maxChars, pos, ellipsis = '…') {
53
53
  // end
54
54
  return text.slice(0, budget) + ellipsis;
55
55
  }
56
+ /**
57
+ * Pure: binary-search the largest visible-char budget whose `truncateText`
58
+ * output still fits, using a caller-supplied `fits(candidate)` predicate. The
59
+ * render layer owns DOM measurement (writes the candidate, reads scrollWidth);
60
+ * this keeps the search algorithm framework-agnostic and unit-testable.
61
+ *
62
+ * Returns the best-fitting truncated string. If the full text already fits
63
+ * (`fits(text)` true) it is returned unchanged; if not even the ellipsis alone
64
+ * fits, the ellipsis is returned as a floor.
65
+ *
66
+ * `pos` selects head/tail retention (start/middle/end). Single-line only.
67
+ */
68
+ export function fitTruncatedText(text, pos, fits, ellipsis = '…') {
69
+ if (text.length === 0)
70
+ return text;
71
+ // Fast path: nothing to truncate.
72
+ if (fits(text))
73
+ return text;
74
+ // Search the char budget in [1, text.length]. `truncateText` never yields a
75
+ // longer string than the budget, so a fitting budget yields a fitting string.
76
+ let lo = 1;
77
+ let hi = text.length;
78
+ let best = ellipsis; // floor: ellipsis alone
79
+ while (lo <= hi) {
80
+ const mid = (lo + hi) >> 1;
81
+ const candidate = truncateText(text, mid, pos, ellipsis);
82
+ if (fits(candidate)) {
83
+ best = candidate;
84
+ lo = mid + 1;
85
+ }
86
+ else {
87
+ hi = mid - 1;
88
+ }
89
+ }
90
+ return best;
91
+ }
56
92
  export function createEllipsis(options = {}) {
57
93
  const rows = options.rows ?? 1;
58
94
  let expanded = options.defaultExpanded ?? false;
@@ -1 +1 @@
1
- {"version":3,"file":"ellipsis.js","sourceRoot":"","sources":["../src/ellipsis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ellipsis.js","sourceRoot":"","sources":["../src/ellipsis.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
- import { createEllipsis, isOverflowing, truncateText } from './ellipsis.js';
2
+ import { createEllipsis, isOverflowing, truncateText, fitTruncatedText } from './ellipsis.js';
3
3
  describe('isOverflowing', () => {
4
4
  it('multi-row: scrollHeight exceeds clientHeight → true', () => {
5
5
  expect(isOverflowing({ scrollHeight: 60, clientHeight: 40, rows: 2 })).toBe(true);
@@ -36,6 +36,42 @@ describe('truncateText', () => {
36
36
  expect(truncateText('abc', 0, 'end')).toBe('…');
37
37
  });
38
38
  });
39
+ describe('fitTruncatedText', () => {
40
+ // Model width as char count: candidate "fits" when its length <= capacity.
41
+ const fitsByLen = (capacity) => (candidate) => candidate.length <= capacity;
42
+ it('returns full text unchanged when it fits', () => {
43
+ expect(fitTruncatedText('abcdef', 'end', () => true)).toBe('abcdef');
44
+ });
45
+ it('empty text returned as-is', () => {
46
+ expect(fitTruncatedText('', 'middle', () => false)).toBe('');
47
+ });
48
+ it('end: binary-searches the largest fitting budget', () => {
49
+ // capacity 5 → truncateText('abcdefgh',5,'end') = 'abcd…'
50
+ expect(fitTruncatedText('abcdefgh', 'end', fitsByLen(5))).toBe('abcd…');
51
+ });
52
+ it('middle: keeps head + tail around ellipsis and fits capacity', () => {
53
+ const out = fitTruncatedText('abcdefghij', 'middle', fitsByLen(5));
54
+ expect(out).toContain('…');
55
+ expect(out.length).toBeLessThanOrEqual(5);
56
+ // head from start, tail from end
57
+ expect(out.startsWith('a')).toBe(true);
58
+ expect(out.endsWith('j')).toBe(true);
59
+ });
60
+ it('start: keeps tail after ellipsis', () => {
61
+ const out = fitTruncatedText('abcdefghij', 'start', fitsByLen(5));
62
+ expect(out.startsWith('…')).toBe(true);
63
+ expect(out.endsWith('j')).toBe(true);
64
+ expect(out.length).toBeLessThanOrEqual(5);
65
+ });
66
+ it('nothing fits → ellipsis floor', () => {
67
+ expect(fitTruncatedText('abcdef', 'end', () => false)).toBe('…');
68
+ });
69
+ it('wider capacity yields more visible chars than a narrow one', () => {
70
+ const narrow = fitTruncatedText('abcdefghijklmnop', 'end', fitsByLen(4));
71
+ const wide = fitTruncatedText('abcdefghijklmnop', 'end', fitsByLen(9));
72
+ expect(wide.length).toBeGreaterThan(narrow.length);
73
+ });
74
+ });
39
75
  describe('createEllipsis', () => {
40
76
  it('truncated starts unknown (null) on CSS clamp path', () => {
41
77
  const e = createEllipsis({ rows: 2 });
@@ -1 +1 @@
1
- {"version":3,"file":"ellipsis.test.js","sourceRoot":"","sources":["../src/ellipsis.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ellipsis.test.js","sourceRoot":"","sources":["../src/ellipsis.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** read a nested value by path (`a[0].b` / `a.0.b`). Undefined when absent. */
2
+ export declare function pathGet(obj: unknown, path: string): unknown;
3
+ /** whether `path` resolves to a defined leaf in `obj`. */
4
+ export declare function pathHas(obj: unknown, path: string): boolean;
5
+ /** normalize a path string to its segment array (`users[0].name` → ['users','0','name']). */
6
+ export declare function toSegments(path: string): string[];
7
+ /**
8
+ * immutable set: returns a NEW root with `path` set to `value`, cloning only the
9
+ * branch along the path (structural sharing elsewhere). Numeric segments create
10
+ * arrays, so `pathSet({}, 'a[0].b', 1) === { a: [{ b: 1 }] }`.
11
+ */
12
+ export declare function pathSet(root: unknown, path: string, value: unknown): Record<string, unknown>;
13
+ /**
14
+ * immutable remove: returns a NEW root with the leaf at `path` deleted, cloning
15
+ * the branch. Array leaves are set to `undefined` (index preserved) to mirror
16
+ * Semi's array-hole semantics; object leaves are `delete`d.
17
+ */
18
+ export declare function pathRemove(root: unknown, path: string): Record<string, unknown>;
19
+ //# sourceMappingURL=form-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-path.d.ts","sourceRoot":"","sources":["../src/form-path.ts"],"names":[],"mappings":"AAgBA,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,0DAA0D;AAC1D,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAcD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAe5F;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2B/E"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * form-path — nested-path read/write for the form data model, aligned with Semi.
3
+ *
4
+ * Semi's Form stores values as a *nested* tree (`{ users: [{ name: 'x' }] }`) and
5
+ * addresses fields by lodash-style paths (`users[0].name`). We reuse lodash
6
+ * `get`/`set`/`toPath`/`has`/`unset` (same source as Semi's `utils/object.ts`) so
7
+ * `toPath('users[0].name') === ['users','0','name']` and `set` auto-creates arrays
8
+ * for numeric segments.
9
+ *
10
+ * Immutability: the form state's `values` object is treated as immutable so Svelte
11
+ * `$state`/subscribers see a fresh reference on every write. `pathSet`/`pathRemove`
12
+ * clone the branch touched by the path (structural sharing along that branch only)
13
+ * and return a NEW root — never mutate in place.
14
+ */
15
+ import { get as lodashGet, toPath as lodashToPath } from 'lodash-es';
16
+ /** read a nested value by path (`a[0].b` / `a.0.b`). Undefined when absent. */
17
+ export function pathGet(obj, path) {
18
+ return lodashGet(obj, path);
19
+ }
20
+ /** whether `path` resolves to a defined leaf in `obj`. */
21
+ export function pathHas(obj, path) {
22
+ return pathGet(obj, path) !== undefined;
23
+ }
24
+ /** normalize a path string to its segment array (`users[0].name` → ['users','0','name']). */
25
+ export function toSegments(path) {
26
+ return lodashToPath(path);
27
+ }
28
+ function isIndexSegment(seg) {
29
+ return /^\d+$/.test(seg);
30
+ }
31
+ /** shallow-clone a container, preserving array vs object identity. */
32
+ function cloneContainer(node, nextSegIsIndex) {
33
+ if (Array.isArray(node))
34
+ return node.slice();
35
+ if (node !== null && typeof node === 'object')
36
+ return { ...node };
37
+ // create the shape the *next* segment needs
38
+ return nextSegIsIndex ? [] : {};
39
+ }
40
+ /**
41
+ * immutable set: returns a NEW root with `path` set to `value`, cloning only the
42
+ * branch along the path (structural sharing elsewhere). Numeric segments create
43
+ * arrays, so `pathSet({}, 'a[0].b', 1) === { a: [{ b: 1 }] }`.
44
+ */
45
+ export function pathSet(root, path, value) {
46
+ const segs = toSegments(path);
47
+ if (segs.length === 0)
48
+ return root ?? {};
49
+ const nextRoot = cloneContainer(root, isIndexSegment(segs[0]));
50
+ let cursor = nextRoot;
51
+ for (let i = 0; i < segs.length - 1; i++) {
52
+ const seg = segs[i];
53
+ const nextIsIndex = isIndexSegment(segs[i + 1]);
54
+ const child = cursor[seg];
55
+ const clonedChild = cloneContainer(child, nextIsIndex);
56
+ cursor[seg] = clonedChild;
57
+ cursor = clonedChild;
58
+ }
59
+ cursor[segs[segs.length - 1]] = value;
60
+ return nextRoot;
61
+ }
62
+ /**
63
+ * immutable remove: returns a NEW root with the leaf at `path` deleted, cloning
64
+ * the branch. Array leaves are set to `undefined` (index preserved) to mirror
65
+ * Semi's array-hole semantics; object leaves are `delete`d.
66
+ */
67
+ export function pathRemove(root, path) {
68
+ const segs = toSegments(path);
69
+ if (segs.length === 0)
70
+ return root ?? {};
71
+ // if the parent branch doesn't exist there's nothing to remove — return a clone
72
+ const nextRoot = cloneContainer(root, isIndexSegment(segs[0]));
73
+ let cursor = nextRoot;
74
+ for (let i = 0; i < segs.length - 1; i++) {
75
+ const seg = segs[i];
76
+ const child = cursor[seg];
77
+ if (child === null || typeof child !== 'object') {
78
+ // path parent missing → nothing to delete
79
+ return nextRoot;
80
+ }
81
+ const clonedChild = Array.isArray(child)
82
+ ? child.slice()
83
+ : { ...child };
84
+ cursor[seg] = clonedChild;
85
+ cursor = clonedChild;
86
+ }
87
+ const leaf = segs[segs.length - 1];
88
+ if (Array.isArray(cursor)) {
89
+ // array leaf: null the slot (keep index) — mirrors Semi placing `undefined`
90
+ cursor[Number(leaf)] = undefined;
91
+ }
92
+ else {
93
+ delete cursor[leaf];
94
+ }
95
+ return nextRoot;
96
+ }
97
+ //# sourceMappingURL=form-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-path.js","sourceRoot":"","sources":["../src/form-path.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=form-path.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-path.test.d.ts","sourceRoot":"","sources":["../src/form-path.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { pathGet, pathSet, pathHas, pathRemove, toSegments } from './form-path.js';
3
+ describe('form-path', () => {
4
+ it('toSegments parses bracket + dot paths', () => {
5
+ expect(toSegments('users[0].name')).toEqual(['users', '0', 'name']);
6
+ expect(toSegments('a.b.c')).toEqual(['a', 'b', 'c']);
7
+ });
8
+ it('pathGet reads nested array/object paths', () => {
9
+ const obj = { users: [{ name: 'ada' }, { name: 'bob' }] };
10
+ expect(pathGet(obj, 'users[0].name')).toBe('ada');
11
+ expect(pathGet(obj, 'users[1].name')).toBe('bob');
12
+ expect(pathGet(obj, 'users[2].name')).toBeUndefined();
13
+ });
14
+ it('pathSet auto-creates arrays for numeric segments', () => {
15
+ const out = pathSet({}, 'users[0].name', 'ada');
16
+ expect(out).toEqual({ users: [{ name: 'ada' }] });
17
+ expect(Array.isArray(out.users)).toBe(true);
18
+ });
19
+ it('pathSet is immutable — returns a fresh root, does not mutate input', () => {
20
+ const before = { a: { b: 1 } };
21
+ const after = pathSet(before, 'a.c', 2);
22
+ expect(after).not.toBe(before);
23
+ expect(before).toEqual({ a: { b: 1 } }); // untouched
24
+ expect(after).toEqual({ a: { b: 1, c: 2 } });
25
+ });
26
+ it('pathSet clones only the touched branch (structural sharing elsewhere)', () => {
27
+ const shared = { keep: 1 };
28
+ const before = { branch: { x: 1 }, other: shared };
29
+ const after = pathSet(before, 'branch.y', 2);
30
+ // the untouched sibling keeps the same reference
31
+ expect(after.other).toBe(shared);
32
+ // the touched branch is a new object
33
+ expect(after.branch).not.toBe(before.branch);
34
+ });
35
+ it('pathHas reflects presence', () => {
36
+ const obj = { a: [{ b: 1 }] };
37
+ expect(pathHas(obj, 'a[0].b')).toBe(true);
38
+ expect(pathHas(obj, 'a[0].c')).toBe(false);
39
+ expect(pathHas(obj, 'z')).toBe(false);
40
+ });
41
+ it('pathRemove deletes an object leaf immutably', () => {
42
+ const before = { a: { b: 1, c: 2 } };
43
+ const after = pathRemove(before, 'a.b');
44
+ expect(after).not.toBe(before);
45
+ expect(after.a).toEqual({ c: 2 });
46
+ expect(before.a).toEqual({ b: 1, c: 2 });
47
+ });
48
+ it('pathRemove nulls an array leaf (keeps the index slot)', () => {
49
+ const before = { a: [{ b: 1 }, { b: 2 }] };
50
+ const after = pathRemove(before, 'a[0]');
51
+ expect(after.a[0]).toBeUndefined();
52
+ expect(after.a[1]).toEqual({ b: 2 });
53
+ // length preserved (Semi-style hole, not a splice)
54
+ expect(after.a.length).toBe(2);
55
+ });
56
+ });
57
+ //# sourceMappingURL=form-path.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-path.test.js","sourceRoot":"","sources":["../src/form-path.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEnF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAE,GAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY;QACrD,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAkB,CAAC;QAC9D,iDAAiD;QACjD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,qCAAqC;QACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,CAAmC,CAAC;QAC1E,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAqB,CAAC;QAC7D,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACrC,mDAAmD;QACnD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { FormValues, MessageDescriptor, Rule } from './form.js';
2
+ type Resolve = (d: MessageDescriptor) => string;
3
+ /**
4
+ * Run one field's rules through async-validator (built-ins + custom), splitting
5
+ * `warningOnly` failures into the warning channel. Returns the first blocking
6
+ * error and the first warning, honoring `stopValidateWithError`.
7
+ */
8
+ export declare function runFieldRules(field: string, value: unknown, values: FormValues, rules: Rule[], label: string, resolve: Resolve, stopWithError: boolean): Promise<{
9
+ error?: string;
10
+ warning?: string;
11
+ }>;
12
+ export {};
13
+ //# sourceMappingURL=form-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-validate.d.ts","sourceRoot":"","sources":["../src/form-validate.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAErE,KAAK,OAAO,GAAG,CAAC,CAAC,EAAE,iBAAiB,KAAK,MAAM,CAAC;AA+IhD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,IAAI,EAAE,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAY/C"}