@jbpark/live-editor 6.0.0 → 6.1.1

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 (67) hide show
  1. package/README.ko.md +8 -0
  2. package/README.md +8 -0
  3. package/dist/{boundary-CySnDUs2.js → boundary-CLMNMZFa.js} +4 -4
  4. package/dist/boundary-CLMNMZFa.js.map +1 -0
  5. package/dist/{cn-CAnad2vL.js → compile-BWZ5U59y.js} +135 -2
  6. package/dist/compile-BWZ5U59y.js.map +1 -0
  7. package/dist/{context-Bjq0CvBE.js → context-DJxX9epB.js} +2 -3
  8. package/dist/context-DJxX9epB.js.map +1 -0
  9. package/dist/{core-BNVuH8-l.js → core-BfJwD8Jx.js} +3 -6
  10. package/dist/core-BfJwD8Jx.js.map +1 -0
  11. package/dist/dnd/index.js +2 -2
  12. package/dist/{dnd-BvjEDo-x.js → dnd-DAGjlJ0_.js} +241 -170
  13. package/dist/dnd-DAGjlJ0_.js.map +1 -0
  14. package/dist/{document-uHqw0mvr.js → document-MkQGxfry.js} +1182 -636
  15. package/dist/document-MkQGxfry.js.map +1 -0
  16. package/dist/editor/index.js +2 -2
  17. package/dist/{editor-CvnzrM9J.js → editor-B_VOz3Q0.js} +2 -2
  18. package/dist/{editor-CvnzrM9J.js.map → editor-B_VOz3Q0.js.map} +1 -1
  19. package/dist/editor-caches-DXYXgWeD.js +63 -0
  20. package/dist/editor-caches-DXYXgWeD.js.map +1 -0
  21. package/dist/error/index.d.ts +1 -1
  22. package/dist/error/index.js +2 -2
  23. package/dist/{error-CFzvnLCf.js → error-E3T5CS3m.js} +13 -12
  24. package/dist/error-E3T5CS3m.js.map +1 -0
  25. package/dist/{index-DfIvkht8.d.ts → index-BC9hY7dI.d.ts} +5 -5
  26. package/dist/{index-CqsS207F.d.ts → index-D-Dfv65w.d.ts} +3 -2
  27. package/dist/index.d.ts +4 -4
  28. package/dist/index.js +5 -5
  29. package/dist/preview/index.d.ts +1 -1
  30. package/dist/preview/index.js +1 -1
  31. package/dist/{preview-B05MkVIQ.js → preview-DFb1pOqJ.js} +30 -11
  32. package/dist/preview-DFb1pOqJ.js.map +1 -0
  33. package/dist/provider/index.js +1 -1
  34. package/dist/{sections-DhH_aVf5.js → sections-CnG7OLr8.js} +3 -3
  35. package/dist/{sections-DhH_aVf5.js.map → sections-CnG7OLr8.js.map} +1 -1
  36. package/dist/states-Ci1AvoQ9.js.map +1 -1
  37. package/dist/style.css +74 -74
  38. package/dist/ui-kit/index.js +2 -2
  39. package/dist/ui-kit/style.css +22 -6
  40. package/dist/{update-BuYQJqjq.js → update-DnX2ibYn.js} +162 -43
  41. package/dist/update-DnX2ibYn.js.map +1 -0
  42. package/dist/{use-dynamic-tailwind-B3l1qZRW.js → use-dynamic-tailwind-CjXeHjsr.js} +115 -40
  43. package/dist/use-dynamic-tailwind-CjXeHjsr.js.map +1 -0
  44. package/dist/{use-field-state-iQGW0vc6.js → use-field-state-B1VLhWfr.js} +2 -2
  45. package/dist/{use-field-state-iQGW0vc6.js.map → use-field-state-B1VLhWfr.js.map} +1 -1
  46. package/dist/utils/ast/index.js +1 -86
  47. package/dist/utils/index.js +3 -4
  48. package/package.json +3 -4
  49. package/dist/boundary-CySnDUs2.js.map +0 -1
  50. package/dist/cn-CAnad2vL.js.map +0 -1
  51. package/dist/compile-my0AjsCw.js +0 -136
  52. package/dist/compile-my0AjsCw.js.map +0 -1
  53. package/dist/constants-st9gnJ5g.js +0 -55
  54. package/dist/constants-st9gnJ5g.js.map +0 -1
  55. package/dist/context-Bjq0CvBE.js.map +0 -1
  56. package/dist/core-BNVuH8-l.js.map +0 -1
  57. package/dist/detect-typescript-CMF0FVKD.js +0 -10
  58. package/dist/detect-typescript-CMF0FVKD.js.map +0 -1
  59. package/dist/dnd-BvjEDo-x.js.map +0 -1
  60. package/dist/document-uHqw0mvr.js.map +0 -1
  61. package/dist/editor-caches-ClMvdcQF.js +0 -23
  62. package/dist/editor-caches-ClMvdcQF.js.map +0 -1
  63. package/dist/error-CFzvnLCf.js.map +0 -1
  64. package/dist/preview-B05MkVIQ.js.map +0 -1
  65. package/dist/update-BuYQJqjq.js.map +0 -1
  66. package/dist/use-dynamic-tailwind-B3l1qZRW.js.map +0 -1
  67. package/dist/utils/ast/index.js.map +0 -1
package/dist/style.css CHANGED
@@ -288,7 +288,7 @@
288
288
  }
289
289
  }
290
290
  @layer components.primitives {
291
- ._49iObG_button {
291
+ .d70MaW_button {
292
292
  border-radius: var(--live-editor-radius-lg);
293
293
  height: 2rem;
294
294
  font: inherit;
@@ -311,98 +311,98 @@
311
311
  display: inline-flex;
312
312
  }
313
313
 
314
- ._49iObG_button:focus-visible {
314
+ .d70MaW_button:focus-visible {
315
315
  outline: 2px solid var(--live-editor-color-focus);
316
316
  outline-offset: 2px;
317
317
  }
318
318
 
319
- ._49iObG_button:disabled {
319
+ .d70MaW_button:disabled {
320
320
  opacity: .5;
321
321
  cursor: not-allowed;
322
322
  }
323
323
 
324
- ._49iObG_button svg {
324
+ .d70MaW_button svg {
325
325
  flex-shrink: 0;
326
326
  width: 1rem;
327
327
  height: 1rem;
328
328
  }
329
329
 
330
- ._49iObG_small {
330
+ .d70MaW_small {
331
331
  height: 1.5rem;
332
332
  font-size: var(--live-editor-font-size-xs);
333
333
  padding: 0 .5rem;
334
334
  }
335
335
 
336
- ._49iObG_small svg {
336
+ .d70MaW_small svg {
337
337
  width: .75rem;
338
338
  height: .75rem;
339
339
  }
340
340
 
341
- ._49iObG_iconOnly {
341
+ .d70MaW_iconOnly {
342
342
  width: 2rem;
343
343
  padding: 0;
344
344
  }
345
345
 
346
- ._49iObG_iconOnly._49iObG_small {
346
+ .d70MaW_iconOnly.d70MaW_small {
347
347
  width: 1.5rem;
348
348
  }
349
349
 
350
- ._49iObG_circle {
350
+ .d70MaW_circle {
351
351
  border-radius: 9999px;
352
352
  }
353
353
 
354
- ._49iObG_primary {
354
+ .d70MaW_primary {
355
355
  --tone: var(--live-editor-color-primary);
356
356
  --tone-soft: var(--live-editor-color-primary-soft);
357
357
  --tone-border: var(--live-editor-color-primary-border);
358
358
  --tone-text: var(--live-editor-color-primary-text);
359
359
  }
360
360
 
361
- ._49iObG_danger {
361
+ .d70MaW_danger {
362
362
  --tone: var(--live-editor-color-danger);
363
363
  --tone-soft: var(--live-editor-color-danger-soft);
364
364
  --tone-border: var(--live-editor-color-danger);
365
365
  --tone-text: #fff;
366
366
  }
367
367
 
368
- ._49iObG_success {
368
+ .d70MaW_success {
369
369
  --tone: var(--live-editor-color-success);
370
370
  --tone-soft: var(--live-editor-color-surface-muted);
371
371
  --tone-border: var(--live-editor-color-success);
372
372
  --tone-text: #fff;
373
373
  }
374
374
 
375
- ._49iObG_outlined {
375
+ .d70MaW_outlined {
376
376
  border-color: var(--tone-border);
377
377
  background: var(--live-editor-color-surface);
378
378
  color: var(--tone);
379
379
  }
380
380
 
381
- ._49iObG_outlined:hover:not(:disabled) {
381
+ .d70MaW_outlined:hover:not(:disabled) {
382
382
  background: var(--tone-soft);
383
383
  }
384
384
 
385
- ._49iObG_solid {
385
+ .d70MaW_solid {
386
386
  border-color: var(--tone);
387
387
  background: var(--tone);
388
388
  color: var(--tone-text);
389
389
  }
390
390
 
391
- ._49iObG_solid:hover:not(:disabled) {
391
+ .d70MaW_solid:hover:not(:disabled) {
392
392
  filter: brightness(.92);
393
393
  }
394
394
 
395
- ._49iObG_text {
395
+ .d70MaW_text {
396
396
  color: var(--tone);
397
397
  background: none;
398
398
  }
399
399
 
400
- ._49iObG_text:hover:not(:disabled) {
400
+ .d70MaW_text:hover:not(:disabled) {
401
401
  background: var(--tone-soft);
402
402
  }
403
403
  }
404
404
  @layer components {
405
- .YlF_3q_region {
405
+ .zcJzfW_region {
406
406
  z-index: 1000;
407
407
  flex-direction: column;
408
408
  gap: .5rem;
@@ -415,7 +415,7 @@
415
415
  transform: translateX(-50%);
416
416
  }
417
417
 
418
- .YlF_3q_toast {
418
+ .zcJzfW_toast {
419
419
  box-sizing: border-box;
420
420
  border: 1px solid var(--live-editor-color-danger);
421
421
  border-radius: var(--live-editor-radius-lg);
@@ -429,18 +429,18 @@
429
429
  box-shadow: 0 10px 15px -3px #0000001a;
430
430
  }
431
431
 
432
- .YlF_3q_title {
432
+ .zcJzfW_title {
433
433
  color: var(--live-editor-color-danger);
434
434
  font-weight: 600;
435
435
  }
436
436
 
437
- .YlF_3q_description {
437
+ .zcJzfW_description {
438
438
  color: var(--live-editor-color-text-muted);
439
439
  margin-top: .25rem;
440
440
  }
441
441
  }
442
442
  @layer components {
443
- ._ty1rG_drawer {
443
+ .SoEwJW_drawer {
444
444
  box-sizing: border-box;
445
445
  border-radius: var(--live-editor-radius-lg) var(--live-editor-radius-lg) 0 0;
446
446
  background: var(--live-editor-color-surface);
@@ -452,20 +452,20 @@
452
452
  border: 0;
453
453
  margin: auto 0 0;
454
454
  padding: 0;
455
- animation: .2s ease-out _ty1rG_slide-up;
455
+ animation: .2s ease-out SoEwJW_slide-up;
456
456
  }
457
457
 
458
- ._ty1rG_drawer::backdrop {
458
+ .SoEwJW_drawer::backdrop {
459
459
  background: #0006;
460
460
  }
461
461
 
462
- ._ty1rG_content {
462
+ .SoEwJW_content {
463
463
  flex-direction: column;
464
464
  height: 100%;
465
465
  display: flex;
466
466
  }
467
467
 
468
- ._ty1rG_header {
468
+ .SoEwJW_header {
469
469
  border-bottom: 1px solid var(--live-editor-color-border-subtle);
470
470
  justify-content: space-between;
471
471
  align-items: center;
@@ -474,30 +474,73 @@
474
474
  display: flex;
475
475
  }
476
476
 
477
- ._ty1rG_title {
477
+ .SoEwJW_title {
478
478
  font-size: var(--live-editor-font-size-lg);
479
479
  margin: 0;
480
480
  font-weight: 600;
481
481
  }
482
482
 
483
- ._ty1rG_body {
483
+ .SoEwJW_body {
484
484
  flex: 1;
485
485
  padding: 1rem;
486
486
  overflow-y: auto;
487
487
  }
488
488
 
489
- @keyframes _ty1rG_slide-up {
489
+ @keyframes SoEwJW_slide-up {
490
490
  from {
491
491
  transform: translateY(100%);
492
492
  }
493
493
  }
494
494
 
495
495
  @media (prefers-reduced-motion: reduce) {
496
- ._ty1rG_drawer {
496
+ .SoEwJW_drawer {
497
497
  animation: none;
498
498
  }
499
499
  }
500
500
  }
501
+ @layer components {
502
+ .Z4yoxa_container {
503
+ width: 100%;
504
+ min-width: 0;
505
+ height: 100%;
506
+ display: flex;
507
+ }
508
+
509
+ .Z4yoxa_pane {
510
+ flex-grow: 0;
511
+ flex-shrink: 0;
512
+ min-width: 0;
513
+ height: 100%;
514
+ overflow: hidden;
515
+ }
516
+
517
+ .Z4yoxa_pane[hidden] {
518
+ display: none;
519
+ }
520
+
521
+ .Z4yoxa_center {
522
+ flex: 1 1 0;
523
+ min-width: 0;
524
+ height: 100%;
525
+ }
526
+
527
+ .Z4yoxa_handle {
528
+ z-index: 1;
529
+ background: var(--live-editor-color-border-subtle);
530
+ cursor: col-resize;
531
+ touch-action: none;
532
+ background-clip: padding-box;
533
+ border-inline: 3px solid #0000;
534
+ flex: 0 0 1px;
535
+ margin: 0 -3px;
536
+ position: relative;
537
+ }
538
+
539
+ .Z4yoxa_handle:hover, .Z4yoxa_handle:focus-visible {
540
+ background-color: var(--live-editor-color-focus);
541
+ outline: none;
542
+ }
543
+ }
501
544
  @layer components {
502
545
  .gbKovW_empty {
503
546
  font-size: var(--live-editor-font-size-sm);
@@ -834,49 +877,6 @@
834
877
  display: inline-flex;
835
878
  }
836
879
  }
837
- @layer components {
838
- .s-4F9W_container {
839
- width: 100%;
840
- min-width: 0;
841
- height: 100%;
842
- display: flex;
843
- }
844
-
845
- .s-4F9W_pane {
846
- flex-grow: 0;
847
- flex-shrink: 0;
848
- min-width: 0;
849
- height: 100%;
850
- overflow: hidden;
851
- }
852
-
853
- .s-4F9W_pane[hidden] {
854
- display: none;
855
- }
856
-
857
- .s-4F9W_center {
858
- flex: 1 1 0;
859
- min-width: 0;
860
- height: 100%;
861
- }
862
-
863
- .s-4F9W_handle {
864
- z-index: 1;
865
- background: var(--live-editor-color-border-subtle);
866
- cursor: col-resize;
867
- touch-action: none;
868
- background-clip: padding-box;
869
- border-inline: 3px solid #0000;
870
- flex: 0 0 1px;
871
- margin: 0 -3px;
872
- position: relative;
873
- }
874
-
875
- .s-4F9W_handle:hover, .s-4F9W_handle:focus-visible {
876
- background-color: var(--live-editor-color-focus);
877
- outline: none;
878
- }
879
- }
880
880
  @layer components {
881
881
  .frCP-q_control {
882
882
  appearance: auto;
@@ -1,5 +1,5 @@
1
- import { n as createDocument } from "../sections-DhH_aVf5.js";
2
- import { i as getFieldKind, o as FieldError, t as useFieldState } from "../use-field-state-iQGW0vc6.js";
1
+ import { n as createDocument } from "../sections-CnG7OLr8.js";
2
+ import { i as getFieldKind, o as FieldError, t as useFieldState } from "../use-field-state-B1VLhWfr.js";
3
3
  import { useEffect, useRef, useState } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { useDebounce } from "@jbpark/use-hooks";
@@ -172,6 +172,10 @@
172
172
  inset-inline-end: calc(var(--spacing) * 2);
173
173
  }
174
174
 
175
+ .end-4 {
176
+ inset-inline-end: calc(var(--spacing) * 4);
177
+ }
178
+
175
179
  .top-0 {
176
180
  top: 0;
177
181
  }
@@ -200,10 +204,6 @@
200
204
  right: calc(var(--spacing) * 2);
201
205
  }
202
206
 
203
- .right-4 {
204
- right: calc(var(--spacing) * 4);
205
- }
206
-
207
207
  .right-5 {
208
208
  right: calc(var(--spacing) * 5);
209
209
  }
@@ -750,6 +750,10 @@
750
750
  max-height: calc(var(--spacing) * 60);
751
751
  }
752
752
 
753
+ .max-h-\[80vh\] {
754
+ max-height: 80vh;
755
+ }
756
+
753
757
  .max-h-\[calc\(100dvh-2rem\)\] {
754
758
  max-height: calc(100dvh - 2rem);
755
759
  }
@@ -1205,6 +1209,10 @@
1205
1209
  cursor: pointer;
1206
1210
  }
1207
1211
 
1212
+ .cursor-zoom-in {
1213
+ cursor: zoom-in;
1214
+ }
1215
+
1208
1216
  .touch-none {
1209
1217
  touch-action: none;
1210
1218
  }
@@ -1815,6 +1823,10 @@
1815
1823
  fill: var(--primary);
1816
1824
  }
1817
1825
 
1826
+ .object-contain {
1827
+ object-fit: contain;
1828
+ }
1829
+
1818
1830
  .object-cover {
1819
1831
  object-fit: cover;
1820
1832
  }
@@ -3608,6 +3620,10 @@
3608
3620
  grid-row-start: 1;
3609
3621
  }
3610
3622
 
3623
+ .sm\:max-w-\[min\(90vw\,64rem\)\] {
3624
+ max-width: min(90vw, 64rem);
3625
+ }
3626
+
3611
3627
  .sm\:max-w-lg {
3612
3628
  max-width: var(--container-lg);
3613
3629
  }
@@ -3640,8 +3656,8 @@
3640
3656
  padding-inline: calc(var(--spacing) * 6);
3641
3657
  }
3642
3658
 
3643
- .sm\:text-left {
3644
- text-align: left;
3659
+ .sm\:text-start {
3660
+ text-align: start;
3645
3661
  }
3646
3662
 
3647
3663
  .sm\:text-2xl {
@@ -1,8 +1,6 @@
1
- import { $ as jsxOpeningFragment, A as isJSXText, B as isTSSatisfiesExpression, C as isJSXElement, D as isJSXIdentifier, E as isJSXFragment, F as isParenthesizedExpression, G as jsxClosingElement, H as isTemplateLiteral, J as jsxExpressionContainer, K as jsxClosingFragment, L as isStringLiteral, M as isNumericLiteral, N as isObjectExpression, O as isJSXOpeningElement, P as isObjectProperty, Q as jsxOpeningElement, R as isTSAsExpression, S as isJSXAttribute, T as isJSXExpressionContainer, U as isUnaryExpression, V as isTSTypeAssertion, W as jsxAttribute, X as jsxIdentifier, Y as jsxFragment, Z as jsxMemberExpression, _ as identifier, at as stringLiteral, c as traverse, ct as traverseFast, d as applyEdits, dt as parseExpression, et as jsxText, f as getJSXTagName, g as booleanLiteral, h as arrayExpression, it as objectProperty, j as isNullLiteral, k as isJSXSpreadAttribute, lt as unaryExpression, m as generate, nt as numericLiteral, p as nanoid, q as jsxElement, rt as objectExpression, tt as nullLiteral, ut as parse, v as isArrayExpression, w as isJSXEmptyExpression, x as isIdentifier, y as isBooleanLiteral, z as isTSNonNullExpression } from "./document-uHqw0mvr.js";
2
- import { n as CONFIG, o as REGEX, r as DATA_ATTR, s as RESERVED_BINDING_PROPERTIES, t as BINDING_PROP } from "./constants-st9gnJ5g.js";
3
- import { n as registerEditorCache } from "./editor-caches-ClMvdcQF.js";
1
+ import { $ as jsxOpeningFragment, A as isJSXText, B as isTSSatisfiesExpression, C as isJSXElement, D as isJSXIdentifier, E as isJSXFragment, F as isParenthesizedExpression, G as jsxClosingElement, H as isTemplateLiteral, I as isSpreadElement, J as jsxExpressionContainer, K as jsxClosingFragment, L as isStringLiteral, M as isNumericLiteral, N as isObjectExpression, O as isJSXOpeningElement, P as isObjectProperty, Q as jsxOpeningElement, R as isTSAsExpression, S as isJSXAttribute, T as isJSXExpressionContainer, U as isUnaryExpression, V as isTSTypeAssertion, W as jsxAttribute, X as jsxIdentifier, Y as jsxFragment, Z as jsxMemberExpression, _ as identifier, at as stringLiteral, c as traverse, ct as traverseFast, d as applyEdits, dt as parseExpression, et as jsxText, f as getJSXTagName, g as booleanLiteral, h as arrayExpression, it as objectProperty, j as isNullLiteral, k as isJSXSpreadAttribute, lt as unaryExpression, m as generate, nt as numericLiteral, p as nanoid, q as jsxElement, rt as objectExpression, tt as nullLiteral, ut as parse, v as isArrayExpression, w as isJSXEmptyExpression, x as isIdentifier, y as isBooleanLiteral, z as isTSNonNullExpression } from "./document-MkQGxfry.js";
2
+ import { a as CONFIG, i as BINDING_PROP, l as REGEX, n as registerEditorCache, o as DATA_ATTR, u as RESERVED_BINDING_PROPERTIES } from "./editor-caches-DXYXgWeD.js";
4
3
  import { t as createBoundedCache } from "./cache-B0-XcIxJ.js";
5
- import { z } from "zod";
6
4
  //#region src/utils/ast/types.ts
7
5
  const BINDING_TYPES = [
8
6
  "array",
@@ -28,11 +26,20 @@ const wrap = (code) => {
28
26
  const unwrap = (generated) => {
29
27
  return generated.replace(/^<>\s*/g, "").replace(/\s*<\/>\s*;?\s*$/g, "").trim();
30
28
  };
29
+ const assertJsxParses = (code) => {
30
+ parse(wrap(code), {
31
+ sourceType: "module",
32
+ plugins: ["jsx", "typescript"]
33
+ });
34
+ };
31
35
  const attrValue = ({ value, isStringLiteral }) => {
32
36
  if (value === null) return null;
33
37
  if (isStringLiteral) return stringLiteral(value);
34
38
  const trimmed = value.trim();
35
- if (REGEX.NUMBER.test(trimmed)) return jsxExpressionContainer(numericLiteral(parseFloat(trimmed)));
39
+ if (REGEX.NUMBER.test(trimmed)) {
40
+ const magnitude = numericLiteral(Math.abs(parseFloat(trimmed)));
41
+ return jsxExpressionContainer(trimmed.startsWith("-") ? unaryExpression("-", magnitude) : magnitude);
42
+ }
36
43
  if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {
37
44
  const expr = parseExpression(trimmed, { plugins: ["jsx", "typescript"] });
38
45
  return jsxExpressionContainer(expr);
@@ -198,31 +205,137 @@ const extractObjectProperties = (element) => {
198
205
  return properties;
199
206
  };
200
207
  //#endregion
208
+ //#region src/utils/ast/editable-value.ts
209
+ const MAX_FLATTEN_DEPTH = 20;
210
+ const isEditablePrimitive = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
211
+ const flattenEditableValue = (value) => {
212
+ const parsed = parseValue(value);
213
+ if (typeof parsed !== "object" || parsed === null || Object.keys(parsed).length === 0) return null;
214
+ const entries = [];
215
+ const walk = (node, path, depth) => {
216
+ if (depth > MAX_FLATTEN_DEPTH) return;
217
+ if (isEditablePrimitive(node)) {
218
+ entries.push({
219
+ path,
220
+ value: node
221
+ });
222
+ return;
223
+ }
224
+ if (Array.isArray(node)) {
225
+ node.forEach((item, index) => walk(item, [...path, index], depth + 1));
226
+ return;
227
+ }
228
+ if (typeof node === "object" && node !== null) Object.entries(node).forEach(([key, item]) => walk(item, [...path, key], depth + 1));
229
+ };
230
+ walk(parsed, [], 0);
231
+ return entries.length ? entries : null;
232
+ };
233
+ const findEditableLeaf = (root, path) => {
234
+ let node = unwrapExpression(root);
235
+ for (const segment of path) {
236
+ if (isArrayExpression(node)) {
237
+ if (typeof segment !== "number") return null;
238
+ const elements = node.elements.slice(0, segment + 1);
239
+ const element = node.elements[segment];
240
+ if (!element || elements.some((item) => isSpreadElement(item))) return null;
241
+ node = unwrapExpression(element);
242
+ continue;
243
+ }
244
+ if (isObjectExpression(node)) {
245
+ const key = String(segment);
246
+ const matches = (property) => isObjectProperty(property) && !property.computed && (isIdentifier(property.key) && property.key.name === key || isStringLiteral(property.key) && property.key.value === key || isNumericLiteral(property.key) && String(property.key.value) === key);
247
+ let index = node.properties.length - 1;
248
+ while (index >= 0 && !matches(node.properties[index])) index--;
249
+ const property = node.properties[index];
250
+ if (!property || !isObjectProperty(property) || node.properties.slice(index + 1).some((item) => isSpreadElement(item))) return null;
251
+ node = unwrapExpression(property.value);
252
+ continue;
253
+ }
254
+ return null;
255
+ }
256
+ return node;
257
+ };
258
+ const isEditableLeaf = (node) => isStringLiteral(node) || isNumericLiteral(node) || isBooleanLiteral(node) || isUnaryExpression(node) && node.operator === "-" && isNumericLiteral(node.argument) || isTemplateLiteral(node) && node.expressions.length === 0 || isJSXElement(node) || isJSXFragment(node);
259
+ const quoteString = (text, quote) => {
260
+ if (quote === "`") return `\`${text.replace(/[\\`]|\$\{/g, (match) => `\\${match}`)}\``;
261
+ const escaped = JSON.stringify(text).slice(1, -1);
262
+ return quote === "\"" ? `"${escaped}"` : `'${escaped.replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
263
+ };
264
+ const isJSXSource = (text) => {
265
+ try {
266
+ const expression = parseExpression(text, { plugins: ["jsx"] });
267
+ return isJSXElement(expression) || isJSXFragment(expression);
268
+ } catch {
269
+ return false;
270
+ }
271
+ };
272
+ const leafSource = (value, leaf, next) => {
273
+ if (typeof next !== "string") return String(next);
274
+ if ((isJSXElement(leaf) || isJSXFragment(leaf)) && isJSXSource(next)) return next.trim();
275
+ const quote = isStringLiteral(leaf) || isTemplateLiteral(leaf) ? value[leaf.start] : "'";
276
+ return quoteString(next, quote);
277
+ };
278
+ const setEditableValue = (value, path, next) => {
279
+ if (!path.length) return value;
280
+ let leaf;
281
+ try {
282
+ leaf = findEditableLeaf(parseExpression(value, { plugins: ["jsx", "typescript"] }), path);
283
+ } catch {
284
+ return value;
285
+ }
286
+ if (!leaf || !isEditableLeaf(leaf) || leaf.start == null || leaf.end == null) return value;
287
+ return `${value.slice(0, leaf.start)}${leafSource(value, leaf, next)}${value.slice(leaf.end)}`;
288
+ };
289
+ const findStructuredNode = (value, path) => {
290
+ let node;
291
+ try {
292
+ node = findEditableLeaf(parseExpression(value, { plugins: ["jsx", "typescript"] }), path);
293
+ } catch {
294
+ return null;
295
+ }
296
+ return node && (isObjectExpression(node) || isArrayExpression(node)) && node.start != null && node.end != null ? node : null;
297
+ };
298
+ const getEditableSource = (value, path) => {
299
+ const node = findStructuredNode(value, path);
300
+ return node ? value.slice(node.start, node.end) : null;
301
+ };
302
+ const setEditableSource = (value, path, source) => {
303
+ const node = findStructuredNode(value, path);
304
+ return node ? `${value.slice(0, node.start)}${source}${value.slice(node.end)}` : null;
305
+ };
306
+ //#endregion
201
307
  //#region src/utils/ast/binding.ts
202
- const bindingTypeSchema = z.enum(BINDING_TYPES);
203
- const countSchema = z.number().int().nonnegative();
204
- const dateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2})?$/);
205
- const bindingOptionSchema = z.object({
206
- label: z.string(),
207
- value: z.string()
208
- });
209
- const bindingWidgetSchema = z.object({
210
- type: z.string().min(1),
211
- step: z.number().optional(),
212
- unit: z.string().optional()
213
- }).passthrough();
214
- const pick = (schema, value) => {
215
- const parsed = schema.safeParse(value);
216
- return parsed.success ? parsed.data : void 0;
308
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
309
+ const string = (value) => typeof value === "string" ? value : void 0;
310
+ const boolean = (value) => typeof value === "boolean" ? value : void 0;
311
+ const number = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
312
+ const positiveNumber = (value) => {
313
+ const checked = number(value);
314
+ return checked !== void 0 && checked > 0 ? checked : void 0;
315
+ };
316
+ const count = (value) => Number.isSafeInteger(value) && value >= 0 ? value : void 0;
317
+ const DATE = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2})?$/;
318
+ const date = (value) => typeof value === "string" && DATE.test(value) ? value : void 0;
319
+ const bindingType = (value) => BINDING_TYPES.includes(value) ? value : void 0;
320
+ const protocols = (value) => Array.isArray(value) && value.every((item) => typeof item === "string" && item.length > 0) ? [...value] : void 0;
321
+ const bindingOption = (value) => isObject(value) && typeof value.label === "string" && typeof value.value === "string" ? {
322
+ label: value.label,
323
+ value: value.value
324
+ } : void 0;
325
+ const bindingWidget = (value) => {
326
+ if (!isObject(value) || typeof value.type !== "string" || value.type.length === 0) return;
327
+ if (value.step !== void 0 && number(value.step) === void 0) return;
328
+ if (value.unit !== void 0 && typeof value.unit !== "string") return;
329
+ return { ...value };
217
330
  };
218
331
  const sanitizeWidget = (value) => {
219
332
  if (typeof value === "string") return value ? { type: value } : void 0;
220
- return pick(bindingWidgetSchema, value);
333
+ return bindingWidget(value);
221
334
  };
222
335
  const sanitizeOptions = (value) => {
223
336
  if (!Array.isArray(value)) return;
224
337
  const options = value.flatMap((option) => {
225
- const parsed = pick(bindingOptionSchema, option);
338
+ const parsed = bindingOption(option);
226
339
  return parsed ? [parsed] : [];
227
340
  });
228
341
  return options.length > 0 ? options : void 0;
@@ -254,25 +367,25 @@ const isPlainObject = (value) => {
254
367
  const sanitizeField = (raw) => {
255
368
  const metaEntries = Object.entries(raw).filter(([key]) => !KNOWN_BINDING_KEYS.has(key));
256
369
  const field = {
257
- label: pick(z.string(), raw.label),
258
- property: pick(z.string(), raw.property),
259
- type: pick(bindingTypeSchema, raw.type),
370
+ label: string(raw.label),
371
+ property: string(raw.property),
372
+ type: bindingType(raw.type),
260
373
  widget: sanitizeWidget(raw.widget),
261
374
  options: sanitizeOptions(raw.options),
262
375
  render: sanitizeRenderMap(raw.render),
263
- min: pick(z.number(), raw.min),
264
- max: pick(z.number(), raw.max),
265
- pattern: pick(z.string(), raw.pattern),
266
- patternMessage: pick(z.string(), raw.patternMessage),
267
- required: pick(z.boolean(), raw.required),
268
- minLength: pick(countSchema, raw.minLength),
269
- maxLength: pick(countSchema, raw.maxLength),
270
- step: pick(z.number().positive(), raw.step),
271
- minItems: pick(countSchema, raw.minItems),
272
- maxItems: pick(countSchema, raw.maxItems),
273
- minDate: pick(dateSchema, raw.minDate),
274
- maxDate: pick(dateSchema, raw.maxDate),
275
- protocols: pick(z.array(z.string().min(1)), raw.protocols),
376
+ min: number(raw.min),
377
+ max: number(raw.max),
378
+ pattern: string(raw.pattern),
379
+ patternMessage: string(raw.patternMessage),
380
+ required: boolean(raw.required),
381
+ minLength: count(raw.minLength),
382
+ maxLength: count(raw.maxLength),
383
+ step: positiveNumber(raw.step),
384
+ minItems: count(raw.minItems),
385
+ maxItems: count(raw.maxItems),
386
+ minDate: date(raw.minDate),
387
+ maxDate: date(raw.maxDate),
388
+ protocols: protocols(raw.protocols),
276
389
  meta: metaEntries.length > 0 ? Object.fromEntries(metaEntries) : void 0
277
390
  };
278
391
  return Object.fromEntries(Object.entries(field).filter(([, value]) => value !== void 0));
@@ -708,7 +821,8 @@ function extract(raw, options = {}) {
708
821
  }
709
822
  function extractFromNode(node, processedNodes, source, options) {
710
823
  processedNodes?.add(node);
711
- const { tagName, allAttrs, dataAttrs, bindings, childrenBinding, rawChildren } = readNodeBindingInfo(node, source, options);
824
+ const { tagName, allAttrs, dataAttrs, bindings, childrenBinding, arrayBindings, rawChildren } = readNodeBindingInfo(node, source, options);
825
+ if (processedNodes) for (const arrayBinding of arrayBindings) skipItemsChildren(node, processedNodes, arrayBinding.property);
712
826
  let childrenNodes;
713
827
  if (childrenBinding) childrenNodes = processChildrenBinding(node, processedNodes, true, source, options);
714
828
  if (!childrenNodes) childrenNodes = processChildrenBinding(node, processedNodes, false, source, options);
@@ -876,10 +990,15 @@ const editChildrenSource = (source, parent, input, options) => {
876
990
  };
877
991
  //#endregion
878
992
  //#region src/utils/ast/value-expression.ts
993
+ const numberToExpression = (value) => {
994
+ if (!Number.isFinite(value)) return null;
995
+ if (value < 0 || Object.is(value, -0)) return unaryExpression("-", numericLiteral(-value));
996
+ return numericLiteral(value);
997
+ };
879
998
  const createNodeFromValue = (type, value) => {
880
999
  switch (type) {
881
1000
  case "boolean": return booleanLiteral(value === true);
882
- case "number": return numericLiteral(Number(value));
1001
+ case "number": return numberToExpression(Number(value));
883
1002
  case "string": return stringLiteral(String(value));
884
1003
  case "null": return nullLiteral();
885
1004
  case "array":
@@ -890,7 +1009,7 @@ const createNodeFromValue = (type, value) => {
890
1009
  };
891
1010
  const valueToExpression = (value) => {
892
1011
  if (typeof value === "string") return stringLiteral(value);
893
- if (typeof value === "number") return value < 0 ? unaryExpression("-", numericLiteral(-value)) : numericLiteral(value);
1012
+ if (typeof value === "number") return numberToExpression(value);
894
1013
  if (typeof value === "boolean") return booleanLiteral(value);
895
1014
  if (value === null) return nullLiteral();
896
1015
  if (Array.isArray(value)) return arrayExpression(value.map((item) => valueToExpression(item) ?? nullLiteral()));
@@ -1307,6 +1426,6 @@ const updateAll = (raw, entries, options = {}) => {
1307
1426
  };
1308
1427
  };
1309
1428
  //#endregion
1310
- export { parseArrayExpression as _, getChildrenSignatures as a, generateCode as b, removeIndices as c, getStructuredValue as d, readNodeBindings as f, isLosslesslyEvaluable as g, extractObjectProperties as h, valueToExpression as i, findEditableChildren as l, extractNodeValue as m, updateAll as n, extract as o, canLosslesslyEvaluateSource as p, createNodeFromValue as r, moveSelectedIndices as s, update as t, getCurrentValue as u, parseValue as v, unwrapExpression as y };
1429
+ export { parseValue as C, parseArrayExpression as S, generateCode as T, setEditableValue as _, getChildrenSignatures as a, extractObjectProperties as b, removeIndices as c, getStructuredValue as d, readNodeBindings as f, setEditableSource as g, isEditablePrimitive as h, valueToExpression as i, findEditableChildren as l, getEditableSource as m, updateAll as n, extract as o, flattenEditableValue as p, createNodeFromValue as r, moveSelectedIndices as s, update as t, getCurrentValue as u, canLosslesslyEvaluateSource as v, assertJsxParses as w, isLosslesslyEvaluable as x, extractNodeValue as y };
1311
1430
 
1312
- //# sourceMappingURL=update-BuYQJqjq.js.map
1431
+ //# sourceMappingURL=update-DnX2ibYn.js.map