mail-editor-pancake 0.2.7 → 0.3.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 (60) hide show
  1. package/README.md +37 -4
  2. package/package.json +1 -1
  3. package/packages/blocks/dist/index.js +275 -263
  4. package/packages/blocks/dist/index.js.map +1 -1
  5. package/packages/blocks/package.json +1 -3
  6. package/packages/blocks/src/button.ts +1 -1
  7. package/packages/blocks/src/hero.ts +6 -3
  8. package/packages/blocks/src/i18n.ts +10 -11
  9. package/packages/blocks/src/image.ts +2 -1
  10. package/packages/blocks/src/index.ts +5 -3
  11. package/packages/blocks/src/social.ts +3 -3
  12. package/packages/blocks/src/socialGroup.ts +4 -4
  13. package/packages/blocks/src/socialShared.ts +23 -3
  14. package/packages/blocks/src/text.ts +8 -4
  15. package/packages/blocks/vite.config.ts +1 -1
  16. package/packages/core/dist/index.d.ts +96 -1
  17. package/packages/core/dist/index.js +4349 -3594
  18. package/packages/core/dist/index.js.map +1 -1
  19. package/packages/core/dist/style.css +1 -1
  20. package/packages/core/package.json +1 -3
  21. package/packages/core/src/editor/BlockCodeModal.ts +6 -7
  22. package/packages/core/src/editor/Canvas.ts +559 -21
  23. package/packages/core/src/editor/ColorPickerPopover.ts +2 -2
  24. package/packages/core/src/editor/Editor.ts +381 -41
  25. package/packages/core/src/editor/ExportModal.ts +7 -9
  26. package/packages/core/src/editor/FocusBreadcrumb.ts +3 -3
  27. package/packages/core/src/editor/ImportDocModal.ts +50 -7
  28. package/packages/core/src/editor/InlineEditor.ts +43 -39
  29. package/packages/core/src/editor/LeftPanel.ts +2 -4
  30. package/packages/core/src/editor/Modal.ts +1 -1
  31. package/packages/core/src/editor/PreviewModal.ts +3 -8
  32. package/packages/core/src/editor/RichTextToolbar.ts +26 -15
  33. package/packages/core/src/editor/RightPanel.ts +142 -126
  34. package/packages/core/src/editor/SourceView.ts +5 -3
  35. package/packages/core/src/editor/Topbar.ts +79 -34
  36. package/packages/core/src/editor/VariablePickerPanel.ts +3 -5
  37. package/packages/core/src/editor/imageAssets.ts +1 -1
  38. package/packages/core/src/editor/styles.css +258 -86
  39. package/packages/core/src/i18n/index.ts +139 -41
  40. package/packages/core/src/index.ts +11 -1
  41. package/packages/core/src/renderer/index.ts +3 -6
  42. package/packages/core/src/renderer/mjml.ts +5 -10
  43. package/packages/core/src/store/store.ts +2 -6
  44. package/packages/core/src/types.ts +3 -3
  45. package/packages/core/src/utils/accentColor.ts +3 -3
  46. package/packages/core/src/utils/docClipboard.ts +107 -2
  47. package/packages/core/src/utils/dynamicVariantHtml.ts +1 -1
  48. package/packages/core/src/utils/emailListStyles.ts +1 -1
  49. package/packages/core/src/utils/fontWeightSteps.ts +7 -6
  50. package/packages/core/src/utils/html.ts +3 -2
  51. package/packages/core/src/utils/inlineListEditing.ts +19 -35
  52. package/packages/core/src/utils/link.ts +3 -6
  53. package/packages/core/src/utils/lockedMjml.ts +2 -2
  54. package/packages/core/src/utils/modalSize.ts +4 -3
  55. package/packages/core/src/utils/richHtmlEmpty.ts +3 -1
  56. package/packages/core/src/variables/index.ts +4 -5
  57. package/packages/core/vite.config.ts +1 -1
  58. package/playground/vanilla/index.html +17 -0
  59. package/playground/vanilla/src/main.ts +152 -123
  60. package/playground/vanilla/vite.config.ts +5 -2
@@ -7,7 +7,7 @@
7
7
  /* Inter 是默认字体(运营预期)。
8
8
  用 CDN 懒加载;离线时自动 fallback 到 system-ui,不影响功能。
9
9
  宿主可在自己的入口里换源(自托管 / @fontsource/inter 等)。 */
10
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
10
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
11
11
 
12
12
  .sm-root {
13
13
  --sm-bg: #f5f6f8;
@@ -65,8 +65,8 @@
65
65
  grid-template-rows: 52px 1fr;
66
66
  height: 100%;
67
67
  min-height: 480px;
68
- font: 13px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC',
69
- 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
68
+ font: 13px / 1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB",
69
+ "Microsoft YaHei", sans-serif;
70
70
  color: var(--sm-text);
71
71
  background: var(--sm-bg);
72
72
  }
@@ -115,9 +115,7 @@
115
115
  --sm-float-bar-bg: #3d444d;
116
116
  --sm-float-bar-fg: #e6edf3;
117
117
  --sm-float-bar-border: #6e7681;
118
- --sm-float-bar-shadow:
119
- 0 0 0 1px rgba(230, 237, 243, 0.1),
120
- 0 8px 32px rgba(0, 0, 0, 0.55);
118
+ --sm-float-bar-shadow: 0 0 0 1px rgba(230, 237, 243, 0.1), 0 8px 32px rgba(0, 0, 0, 0.55);
121
119
  --sm-float-bar-control-bg: rgba(255, 255, 255, 0.1);
122
120
  --sm-float-bar-hover-bg: rgba(255, 255, 255, 0.14);
123
121
  --sm-float-bar-sep: rgba(255, 255, 255, 0.16);
@@ -157,9 +155,7 @@
157
155
  --sm-float-bar-bg: #3d444d;
158
156
  --sm-float-bar-fg: #e6edf3;
159
157
  --sm-float-bar-border: #6e7681;
160
- --sm-float-bar-shadow:
161
- 0 0 0 1px rgba(230, 237, 243, 0.1),
162
- 0 8px 32px rgba(0, 0, 0, 0.55);
158
+ --sm-float-bar-shadow: 0 0 0 1px rgba(230, 237, 243, 0.1), 0 8px 32px rgba(0, 0, 0, 0.55);
163
159
  --sm-float-bar-control-bg: rgba(255, 255, 255, 0.1);
164
160
  --sm-float-bar-hover-bg: rgba(255, 255, 255, 0.14);
165
161
  --sm-float-bar-sep: rgba(255, 255, 255, 0.16);
@@ -404,8 +400,13 @@
404
400
  cursor: pointer;
405
401
  font: inherit;
406
402
  }
407
- .sm-btn:hover { background: var(--sm-surface-hover); }
408
- .sm-btn[disabled] { opacity: 0.45; cursor: not-allowed; }
403
+ .sm-btn:hover {
404
+ background: var(--sm-surface-hover);
405
+ }
406
+ .sm-btn[disabled] {
407
+ opacity: 0.45;
408
+ cursor: not-allowed;
409
+ }
409
410
  .sm-btn--primary {
410
411
  background: var(--sm-primary);
411
412
  border-color: var(--sm-primary);
@@ -421,8 +422,13 @@
421
422
  color: var(--sm-on-primary);
422
423
  filter: brightness(1.05);
423
424
  }
424
- .sm-btn--ghost { border-color: transparent; background: transparent; }
425
- .sm-btn--ghost:hover { background: var(--sm-ghost-hover-bg); }
425
+ .sm-btn--ghost {
426
+ border-color: transparent;
427
+ background: transparent;
428
+ }
429
+ .sm-btn--ghost:hover {
430
+ background: var(--sm-ghost-hover-bg);
431
+ }
426
432
  .sm-btn--secondary {
427
433
  border: 1px solid var(--sm-border);
428
434
  background: var(--sm-surface);
@@ -481,7 +487,8 @@
481
487
  position: relative;
482
488
  z-index: 2;
483
489
  display: grid;
484
- grid-template-columns: var(--sm-layout-col-left) minmax(0, 1fr)
490
+ grid-template-columns:
491
+ var(--sm-layout-col-left) minmax(0, 1fr)
485
492
  var(--sm-layout-col-right);
486
493
  min-height: 0;
487
494
  overflow: auto;
@@ -589,7 +596,9 @@
589
596
  padding: 8px 12px 24px;
590
597
  }
591
598
 
592
- .sm-blocks__group + .sm-blocks__group { margin-top: 12px; }
599
+ .sm-blocks__group + .sm-blocks__group {
600
+ margin-top: 12px;
601
+ }
593
602
 
594
603
  .sm-blocks__grid {
595
604
  display: grid;
@@ -617,7 +626,9 @@
617
626
  border-color: var(--sm-primary);
618
627
  box-shadow: var(--sm-shadow);
619
628
  }
620
- .sm-block-card:active { cursor: grabbing; }
629
+ .sm-block-card:active {
630
+ cursor: grabbing;
631
+ }
621
632
  .sm-block-card__dot {
622
633
  position: absolute;
623
634
  top: 6px;
@@ -646,8 +657,7 @@
646
657
  /* 中栏:画布 ------------------------------------------------------------- */
647
658
  .sm-canvas-wrap {
648
659
  background: var(--sm-canvas-bg);
649
- padding: var(--sm-canvas-pad-top) var(--sm-canvas-pad-x)
650
- var(--sm-canvas-pad-bottom);
660
+ padding: var(--sm-canvas-pad-top) var(--sm-canvas-pad-x) var(--sm-canvas-pad-bottom);
651
661
  overflow: auto;
652
662
  min-width: 0;
653
663
  }
@@ -700,22 +710,9 @@
700
710
  }
701
711
 
702
712
  /* 宿主全局 reset(如 p/strong { font-weight:400 })会盖过块级字重配置,子节点须继承容器 */
703
- .sm-canvas .sm-text-content :where(
704
- p,
705
- li,
706
- td,
707
- th,
708
- span,
709
- div,
710
- h1,
711
- h2,
712
- h3,
713
- h4,
714
- h5,
715
- h6,
716
- address,
717
- caption
718
- ) {
713
+ .sm-canvas
714
+ .sm-text-content
715
+ :where(p, li, td, th, span, div, h1, h2, h3, h4, h5, h6, address, caption) {
719
716
  font-weight: inherit;
720
717
  }
721
718
 
@@ -791,15 +788,17 @@
791
788
  .sm-root.sm-show-layout-borders .sm-section-host:not(.is-selected) .sm-section {
792
789
  outline-color: var(--sm-outline-layout-section);
793
790
  }
794
- .sm-root.sm-show-layout-borders
795
- .sm-section-host:not(.is-selected):not(:hover)
796
- .sm-section {
791
+ .sm-root.sm-show-layout-borders .sm-section-host:not(.is-selected):not(:hover) .sm-section {
797
792
  outline-offset: -2px;
798
793
  }
799
794
  .sm-section-host:not(.is-selected):has(.sm-block:hover, .sm-block.is-selected, .sm-block.is-editing)
800
795
  .sm-section,
801
796
  .sm-root.sm-show-layout-borders
802
- .sm-section-host:not(.is-selected):has(.sm-block:hover, .sm-block.is-selected, .sm-block.is-editing)
797
+ .sm-section-host:not(.is-selected):has(
798
+ .sm-block:hover,
799
+ .sm-block.is-selected,
800
+ .sm-block.is-editing
801
+ )
803
802
  .sm-section {
804
803
  outline-color: var(--sm-outline-section-context);
805
804
  outline-offset: 0;
@@ -808,7 +807,9 @@
808
807
  .sm-section.sm-section--dynamic-variant {
809
808
  outline-color: var(--sm-outline-section-context);
810
809
  }
811
- .sm-section-host:hover:not(.is-selected):not(:has(.sm-block:hover, .sm-block.is-selected, .sm-block.is-editing))
810
+ .sm-section-host:hover:not(.is-selected):not(
811
+ :has(.sm-block:hover, .sm-block.is-selected, .sm-block.is-editing)
812
+ )
812
813
  .sm-section {
813
814
  outline-color: var(--sm-primary);
814
815
  /* outline-offset: -2px; */
@@ -912,10 +913,18 @@
912
913
  border-radius: 4px;
913
914
  cursor: pointer;
914
915
  }
915
- .sm-tool-btn:hover { filter: brightness(1.1); }
916
- .sm-tool-btn--danger { background: var(--sm-danger); }
917
- .sm-section__handle { cursor: grab; }
918
- .sm-section__handle:active { cursor: grabbing; }
916
+ .sm-tool-btn:hover {
917
+ filter: brightness(1.1);
918
+ }
919
+ .sm-tool-btn--danger {
920
+ background: var(--sm-danger);
921
+ }
922
+ .sm-section__handle {
923
+ cursor: grab;
924
+ }
925
+ .sm-section__handle:active {
926
+ cursor: grabbing;
927
+ }
919
928
 
920
929
  .sm-section__columns {
921
930
  position: relative;
@@ -967,8 +976,7 @@
967
976
  outline-offset: -2px;
968
977
  }
969
978
  /* 展示边框:Block 更浅的辅助线(非 hover) */
970
- .sm-root.sm-show-layout-borders
971
- .sm-block:not(.is-selected):not(.is-editing):not(:hover) {
979
+ .sm-root.sm-show-layout-borders .sm-block:not(.is-selected):not(.is-editing):not(:hover) {
972
980
  outline-color: var(--sm-outline-layout-block);
973
981
  }
974
982
  .sm-block:hover:not(.is-selected):not(.is-editing),
@@ -996,7 +1004,9 @@
996
1004
  outline-offset: 0;
997
1005
  z-index: 2;
998
1006
  }
999
- .sm-block__content { position: relative; }
1007
+ .sm-block__content {
1008
+ position: relative;
1009
+ }
1000
1010
 
1001
1011
  .sm-block__toolbar {
1002
1012
  position: absolute;
@@ -1062,8 +1072,12 @@
1062
1072
  .sm-block.is-editing .sm-block__toolbar-actions {
1063
1073
  display: inline-flex;
1064
1074
  }
1065
- .sm-block__handle { cursor: grab; }
1066
- .sm-block__handle:active { cursor: grabbing; }
1075
+ .sm-block__handle {
1076
+ cursor: grab;
1077
+ }
1078
+ .sm-block__handle:active {
1079
+ cursor: grabbing;
1080
+ }
1067
1081
 
1068
1082
  .sm-block.is-locked::before {
1069
1083
  content: attr(data-locked-label);
@@ -1118,7 +1132,10 @@
1118
1132
  cursor: pointer;
1119
1133
  color: var(--sm-text);
1120
1134
  }
1121
- .sm-add-section-bar__btn:hover { border-color: var(--sm-primary); color: var(--sm-primary); }
1135
+ .sm-add-section-bar__btn:hover {
1136
+ border-color: var(--sm-primary);
1137
+ color: var(--sm-primary);
1138
+ }
1122
1139
 
1123
1140
  /* 右栏:属性面板 --------------------------------------------------------- */
1124
1141
  .sm-tabs {
@@ -1290,7 +1307,12 @@
1290
1307
  background: var(--sm-surface);
1291
1308
  color: var(--sm-text);
1292
1309
  }
1293
- .sm-textarea { height: auto; min-height: 64px; padding: 6px 8px; resize: vertical; }
1310
+ .sm-textarea {
1311
+ height: auto;
1312
+ min-height: 64px;
1313
+ padding: 6px 8px;
1314
+ resize: vertical;
1315
+ }
1294
1316
  .sm-input:focus,
1295
1317
  .sm-textarea:focus,
1296
1318
  .sm-select:focus {
@@ -1311,7 +1333,9 @@
1311
1333
  grid-template-columns: repeat(4, 1fr);
1312
1334
  gap: 4px;
1313
1335
  }
1314
- .sm-spacing-grid input { text-align: center; }
1336
+ .sm-spacing-grid input {
1337
+ text-align: center;
1338
+ }
1315
1339
 
1316
1340
  .sm-spacing-rows {
1317
1341
  display: flex;
@@ -1331,17 +1355,17 @@
1331
1355
  text-align: center;
1332
1356
  line-height: 1.2;
1333
1357
  }
1334
- .sm-spacing-row input[type='range'],
1335
- .sm-field__slider-row input[type='range'],
1336
- .sm-width-field__slider-row input[type='range'] {
1358
+ .sm-spacing-row input[type="range"],
1359
+ .sm-field__slider-row input[type="range"],
1360
+ .sm-width-field__slider-row input[type="range"] {
1337
1361
  cursor: pointer;
1338
1362
  }
1339
- .sm-spacing-row input[type='range']::-webkit-slider-thumb,
1340
- .sm-field__slider-row input[type='range']::-webkit-slider-thumb,
1341
- .sm-width-field__slider-row input[type='range']::-webkit-slider-thumb {
1363
+ .sm-spacing-row input[type="range"]::-webkit-slider-thumb,
1364
+ .sm-field__slider-row input[type="range"]::-webkit-slider-thumb,
1365
+ .sm-width-field__slider-row input[type="range"]::-webkit-slider-thumb {
1342
1366
  cursor: pointer;
1343
1367
  }
1344
- .sm-spacing-row input[type='range'] {
1368
+ .sm-spacing-row input[type="range"] {
1345
1369
  flex: 1 1 auto;
1346
1370
  min-width: 0;
1347
1371
  height: 28px;
@@ -1419,17 +1443,17 @@
1419
1443
  .sm-field__slider-row--inherit {
1420
1444
  opacity: 0.55;
1421
1445
  }
1422
- .sm-field__slider-row--inherit input[type='range'] {
1446
+ .sm-field__slider-row--inherit input[type="range"] {
1423
1447
  accent-color: var(--sm-outline-muted);
1424
1448
  }
1425
- .sm-field__slider-row--inherit input[type='number']:disabled {
1449
+ .sm-field__slider-row--inherit input[type="number"]:disabled {
1426
1450
  background: var(--sm-surface-hover);
1427
1451
  color: var(--sm-text-muted);
1428
1452
  }
1429
1453
  .sm-input--inherit-disabled {
1430
1454
  opacity: 0.55;
1431
1455
  }
1432
- .sm-field__slider-row input[type='range'] {
1456
+ .sm-field__slider-row input[type="range"] {
1433
1457
  flex: 1;
1434
1458
  min-width: 0;
1435
1459
  height: 28px;
@@ -1456,7 +1480,7 @@
1456
1480
  gap: 10px;
1457
1481
  min-width: 0;
1458
1482
  }
1459
- .sm-width-field__slider-row input[type='range'] {
1483
+ .sm-width-field__slider-row input[type="range"] {
1460
1484
  flex: 1 1 auto;
1461
1485
  min-width: 0;
1462
1486
  height: 28px;
@@ -1473,8 +1497,12 @@
1473
1497
  pointer-events: none;
1474
1498
  }
1475
1499
 
1476
- .sm-color-row { display: flex; align-items: center; gap: 6px; }
1477
- .sm-color-row input[type='color'] {
1500
+ .sm-color-row {
1501
+ display: flex;
1502
+ align-items: center;
1503
+ gap: 6px;
1504
+ }
1505
+ .sm-color-row input[type="color"] {
1478
1506
  width: 28px;
1479
1507
  height: 28px;
1480
1508
  padding: 0;
@@ -1483,7 +1511,7 @@
1483
1511
  background: none;
1484
1512
  cursor: pointer;
1485
1513
  }
1486
- .sm-color-row input[type='color'].sm-color-row__pick--inherit {
1514
+ .sm-color-row input[type="color"].sm-color-row__pick--inherit {
1487
1515
  opacity: 0.55;
1488
1516
  border-style: dashed;
1489
1517
  }
@@ -1526,7 +1554,10 @@
1526
1554
  background: var(--sm-code-bg) !important;
1527
1555
  color: var(--sm-text);
1528
1556
  }
1529
- .sm-code .cm-content { padding: 8px; color: var(--sm-text); }
1557
+ .sm-code .cm-content {
1558
+ padding: 8px;
1559
+ color: var(--sm-text);
1560
+ }
1530
1561
 
1531
1562
  .sm-doc-source {
1532
1563
  height: 100%;
@@ -1566,10 +1597,7 @@
1566
1597
  background-color: color-mix(in srgb, var(--sm-primary-soft) 55%, transparent);
1567
1598
  cursor: text;
1568
1599
  caret-color: var(--sm-primary);
1569
- transition:
1570
- outline-color 0.12s ease,
1571
- box-shadow 0.12s ease,
1572
- background-color 0.12s ease;
1600
+ transition: outline-color 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease;
1573
1601
  }
1574
1602
  .sm-inline-editing:focus {
1575
1603
  outline: 2px solid var(--sm-primary) !important;
@@ -1626,7 +1654,9 @@
1626
1654
  flex-wrap: wrap;
1627
1655
  max-width: calc(100% - 16px);
1628
1656
  }
1629
- .sm-floating-toolbar.is-visible { display: inline-flex; }
1657
+ .sm-floating-toolbar.is-visible {
1658
+ display: inline-flex;
1659
+ }
1630
1660
 
1631
1661
  .sm-floating-toolbar__group {
1632
1662
  display: inline-flex;
@@ -1654,7 +1684,9 @@
1654
1684
  font: inherit;
1655
1685
  cursor: pointer;
1656
1686
  }
1657
- .sm-floating-toolbar__btn:hover { background: var(--sm-float-bar-hover-bg); }
1687
+ .sm-floating-toolbar__btn:hover {
1688
+ background: var(--sm-float-bar-hover-bg);
1689
+ }
1658
1690
  .sm-floating-toolbar__btn.is-active {
1659
1691
  background: var(--sm-primary);
1660
1692
  color: var(--sm-on-primary);
@@ -1670,7 +1702,9 @@
1670
1702
  font: inherit;
1671
1703
  max-width: 130px;
1672
1704
  }
1673
- .sm-floating-toolbar__select option { color: var(--sm-float-bar-select-option-fg); }
1705
+ .sm-floating-toolbar__select option {
1706
+ color: var(--sm-float-bar-select-option-fg);
1707
+ }
1674
1708
 
1675
1709
  .sm-floating-toolbar__color {
1676
1710
  width: 26px;
@@ -1689,7 +1723,9 @@
1689
1723
  gap: 6px;
1690
1724
  padding: 4px 4px 0;
1691
1725
  }
1692
- .sm-floating-toolbar__link-panel.is-visible { display: flex; }
1726
+ .sm-floating-toolbar__link-panel.is-visible {
1727
+ display: flex;
1728
+ }
1693
1729
  .sm-floating-toolbar__link-panel .sm-input {
1694
1730
  flex: 1;
1695
1731
  height: 26px;
@@ -1700,7 +1736,9 @@
1700
1736
  .sm-floating-toolbar__link-panel .sm-input::placeholder {
1701
1737
  color: var(--sm-float-bar-placeholder);
1702
1738
  }
1703
- .sm-floating-toolbar__link-panel .sm-btn { height: 26px; }
1739
+ .sm-floating-toolbar__link-panel .sm-btn {
1740
+ height: 26px;
1741
+ }
1704
1742
 
1705
1743
  .sm-floating-toolbar__select--list-indent {
1706
1744
  min-width: 52px;
@@ -1840,8 +1878,13 @@
1840
1878
  background: transparent;
1841
1879
  font: inherit;
1842
1880
  }
1843
- .sm-popover__item:hover { background: var(--sm-surface-hover); }
1844
- .sm-popover__label { font-size: 13px; color: var(--sm-text); }
1881
+ .sm-popover__item:hover {
1882
+ background: var(--sm-surface-hover);
1883
+ }
1884
+ .sm-popover__label {
1885
+ font-size: 13px;
1886
+ color: var(--sm-text);
1887
+ }
1845
1888
  .sm-popover__key {
1846
1889
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
1847
1890
  font-size: 12px;
@@ -1910,7 +1953,9 @@
1910
1953
  --sm-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
1911
1954
  --sm-shadow-md: 0 4px 16px rgba(16, 24, 40, 0.08);
1912
1955
  }
1913
- .sm-modal__mask.is-open { opacity: 1; }
1956
+ .sm-modal__mask.is-open {
1957
+ opacity: 1;
1958
+ }
1914
1959
 
1915
1960
  .sm-modal__card {
1916
1961
  display: flex;
@@ -1919,10 +1964,8 @@
1919
1964
  color: var(--sm-text, #1f2328);
1920
1965
  border-radius: 12px;
1921
1966
  border: 1px solid var(--sm-border, #e6e8ec);
1922
- box-shadow:
1923
- 0 0 0 1px rgba(255, 255, 255, 0.08) inset,
1924
- 0 24px 48px rgba(15, 23, 42, 0.14),
1925
- 0 8px 24px rgba(15, 23, 42, 0.08);
1967
+ box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08) inset, 0 24px 48px rgba(15, 23, 42, 0.14), 0 8px
1968
+ 24px rgba(15, 23, 42, 0.08);
1926
1969
  max-width: 96vw;
1927
1970
  max-height: 92vh;
1928
1971
  transform: translateY(8px) scale(0.98);
@@ -2012,7 +2055,9 @@
2012
2055
  border-top: 1px solid var(--sm-border, #e6e8ec);
2013
2056
  background: var(--sm-modal-footer-bg, #fafbfc);
2014
2057
  }
2015
- .sm-modal__footer:empty { display: none; }
2058
+ .sm-modal__footer:empty {
2059
+ display: none;
2060
+ }
2016
2061
 
2017
2062
  .sm-modal--gallery .sm-modal__body {
2018
2063
  padding: 0;
@@ -2195,9 +2240,7 @@
2195
2240
  }
2196
2241
  .sm-gallery-modal__cell.is-selected {
2197
2242
  border-color: var(--sm-primary, #4f46e5);
2198
- box-shadow:
2199
- 0 0 0 2px var(--sm-primary-soft, #eef2ff),
2200
- 0 4px 14px rgba(79, 70, 229, 0.12);
2243
+ box-shadow: 0 0 0 2px var(--sm-primary-soft, #eef2ff), 0 4px 14px rgba(79, 70, 229, 0.12);
2201
2244
  }
2202
2245
 
2203
2246
  .sm-gallery-modal__thumb {
@@ -2332,3 +2375,132 @@
2332
2375
  opacity: 1;
2333
2376
  transform: translateX(-50%) translateY(0);
2334
2377
  }
2378
+
2379
+ /* --------------------- 节选择模式(批量复制 / 导出 / 删除) --------------------- */
2380
+ .sm-canvas-wrap.sm-section-select-mode .sm-section-host {
2381
+ cursor: pointer;
2382
+ }
2383
+ .sm-canvas-wrap.sm-section-select-mode .sm-block {
2384
+ cursor: pointer;
2385
+ }
2386
+ .sm-canvas-wrap.sm-section-select-mode .sm-section__toolbar,
2387
+ .sm-canvas-wrap.sm-section-select-mode .sm-block__toolbar {
2388
+ display: none !important;
2389
+ }
2390
+ .sm-canvas-wrap.sm-section-select-mode .sm-add-section-bar {
2391
+ pointer-events: none;
2392
+ opacity: 0.45;
2393
+ }
2394
+ /* 模式内块 hover:淡虚线提示可点,与选中实线区分 */
2395
+ .sm-canvas-wrap.sm-section-select-mode .sm-block:hover:not(.is-check-selected) {
2396
+ outline: 2px dashed color-mix(in srgb, var(--sm-primary, #4f46e5) 45%, transparent);
2397
+ outline-offset: 0;
2398
+ }
2399
+ /* 散选块高亮:实线描边 */
2400
+ .sm-canvas-wrap.sm-section-select-mode .sm-block.is-check-selected {
2401
+ outline: 2px solid var(--sm-primary, #4f46e5);
2402
+ outline-offset: 0;
2403
+ }
2404
+ /* 勾选气泡:Section 左上角;自身接收点击(点击冒泡到 host = 命中整节) */
2405
+ .sm-section-check {
2406
+ display: none;
2407
+ }
2408
+ .sm-canvas-wrap.sm-section-select-mode .sm-section-check {
2409
+ display: flex;
2410
+ align-items: center;
2411
+ justify-content: center;
2412
+ position: absolute;
2413
+ top: -11px;
2414
+ left: -11px;
2415
+ width: 22px;
2416
+ height: 22px;
2417
+ border-radius: 50%;
2418
+ border: 2px solid var(--sm-primary, #4f46e5);
2419
+ background: var(--sm-surface, #fff);
2420
+ color: var(--sm-primary, #4f46e5);
2421
+ z-index: 40;
2422
+ box-shadow: 0 1px 4px rgba(16, 24, 40, 0.18);
2423
+ cursor: pointer;
2424
+ }
2425
+ /* 扩大圈命中区(含突出 host 外的弧形部分) */
2426
+ .sm-canvas-wrap.sm-section-select-mode .sm-section-check::after {
2427
+ content: "";
2428
+ position: absolute;
2429
+ inset: -6px;
2430
+ border-radius: 50%;
2431
+ }
2432
+ .sm-section-check svg {
2433
+ opacity: 0;
2434
+ /* 勾 / 减号两个图标绝对定位叠放于圆心:脱离 flex 流,避免并排各占一半宽度导致偏心 */
2435
+ position: absolute;
2436
+ top: 50%;
2437
+ left: 50%;
2438
+ transform: translate(-50%, -50%);
2439
+ }
2440
+ /* 三态:全选 = 实底 + 勾;半选 = 空心底 + 减号;无选 = 空圈(svg 全隐) */
2441
+ .sm-section-host.is-check-selected .sm-section-check .sm-section-check__icon-check,
2442
+ .sm-section-host.is-check-partial .sm-section-check .sm-section-check__icon-minus {
2443
+ opacity: 1;
2444
+ }
2445
+ .sm-section-host.is-check-selected .sm-section-check {
2446
+ background: var(--sm-primary, #4f46e5);
2447
+ color: var(--sm-on-primary, #fff);
2448
+ }
2449
+ .sm-section-host.is-check-selected .sm-section {
2450
+ outline: 2px solid var(--sm-primary, #4f46e5);
2451
+ outline-offset: 2px;
2452
+ }
2453
+ /* 半选节:虚线描边(实线 = 全选) */
2454
+ .sm-section-host.is-check-partial .sm-section {
2455
+ outline: 2px dashed var(--sm-primary, #4f46e5);
2456
+ outline-offset: 2px;
2457
+ }
2458
+ /* 底部浮动操作条(sticky 于滚动容器内) */
2459
+ .sm-section-select-bar {
2460
+ position: sticky;
2461
+ bottom: 12px;
2462
+ z-index: 60;
2463
+ display: flex;
2464
+ align-items: center;
2465
+ gap: 4px;
2466
+ width: max-content;
2467
+ margin: 12px auto 0;
2468
+ padding: 6px 8px;
2469
+ border-radius: 10px;
2470
+ background: rgba(31, 35, 40, 0.92);
2471
+ box-shadow: 0 6px 20px rgba(16, 24, 40, 0.22);
2472
+ }
2473
+ .sm-section-select-bar__count {
2474
+ font-size: 12px;
2475
+ color: rgba(255, 255, 255, 0.85);
2476
+ padding: 0 4px;
2477
+ white-space: nowrap;
2478
+ }
2479
+ .sm-section-select-bar__btn {
2480
+ border: 0;
2481
+ border-radius: 6px;
2482
+ padding: 5px 10px;
2483
+ font-size: 12px;
2484
+ line-height: 1.2;
2485
+ background: transparent;
2486
+ color: rgba(255, 255, 255, 0.88);
2487
+ cursor: pointer;
2488
+ white-space: nowrap;
2489
+ }
2490
+ .sm-section-select-bar__btn:hover:not(:disabled) {
2491
+ background: rgba(255, 255, 255, 0.14);
2492
+ }
2493
+ .sm-section-select-bar__btn:disabled {
2494
+ opacity: 0.4;
2495
+ cursor: not-allowed;
2496
+ }
2497
+ .sm-section-select-bar__btn--danger {
2498
+ color: #fca5a5;
2499
+ }
2500
+ .sm-section-select-bar__btn--primary {
2501
+ background: var(--sm-primary, #4f46e5);
2502
+ color: var(--sm-on-primary, #fff);
2503
+ }
2504
+ .sm-section-select-bar__btn--primary:hover:not(:disabled) {
2505
+ filter: brightness(1.08);
2506
+ }