@dotit/editor 1.0.0 → 1.1.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.
@@ -16,6 +16,8 @@ export interface PageGeometry {
16
16
  header: string;
17
17
  /** Footer text ('' if none). Supports {{page}}/{{pages}} tokens. */
18
18
  footer: string;
19
+ /** Ruler unit derived from the page size (A-series → cm, Letter/Legal → in). */
20
+ unit: "cm" | "in";
19
21
  }
20
22
  /** Compute the page geometry from `.it` source (its page:/header:/footer: blocks). */
21
23
  export declare function getPageGeometry(source: string): PageGeometry;
package/dist/style.css CHANGED
@@ -33,12 +33,14 @@
33
33
  GOOGLE DOCS – Visual Editor (TipTap)
34
34
  ═══════════════════════════════════════════════════════════════ */
35
35
 
36
- /* Container fills the panel */
36
+ /* Container fills the panel — a flat, full-bleed Docs-style workspace:
37
+ light-gray canvas, white page sheet floating on it, no rounded corners. */
37
38
  .docs-container {
39
+ --docs-canvas-bg: #f9fbfd;
38
40
  display: flex;
39
41
  flex-direction: column;
40
42
  height: 100%;
41
- background: #f8f9fa;
43
+ background: var(--docs-canvas-bg);
42
44
  }
43
45
 
44
46
  /* ─── Docs Toolbar (formatting bar) ───────────────────────── */
@@ -48,7 +50,7 @@
48
50
  align-items: center;
49
51
  gap: 2px;
50
52
  padding: 4px 12px;
51
- background: rgba(108, 63, 197, 0.08);
53
+ background: #fff;
52
54
  border-bottom: 1px solid #dadce0;
53
55
  flex-shrink: 0;
54
56
  min-height: 40px;
@@ -75,8 +77,8 @@
75
77
  background: rgba(0, 0, 0, 0.06);
76
78
  }
77
79
  .docs-toolbar button.active {
78
- background: rgba(108, 63, 197, 0.12);
79
- color: #6c3fc5;
80
+ background: rgba(26, 115, 232, 0.12);
81
+ color: #1a73e8;
80
82
  }
81
83
  .docs-toolbar select {
82
84
  padding: 0 4px;
@@ -119,11 +121,11 @@
119
121
  cursor: default;
120
122
  }
121
123
  .docs-tb-btn.active {
122
- background: rgba(108, 63, 197, 0.12);
123
- color: #6c3fc5;
124
+ background: rgba(26, 115, 232, 0.12);
125
+ color: #1a73e8;
124
126
  }
125
127
  .docs-tb-btn.active:hover {
126
- background: rgba(108, 63, 197, 0.18);
128
+ background: rgba(26, 115, 232, 0.18);
127
129
  }
128
130
  .docs-tb-sep {
129
131
  width: 1px;
@@ -202,8 +204,8 @@
202
204
  background: #f1f3f4;
203
205
  }
204
206
  .docs-tb-dropdown-item.active {
205
- background: rgba(108, 63, 197, 0.08);
206
- color: #6c3fc5;
207
+ background: rgba(26, 115, 232, 0.08);
208
+ color: #1a73e8;
207
209
  }
208
210
  .docs-style-preview {
209
211
  display: block;
@@ -386,7 +388,8 @@
386
388
  .docs-canvas {
387
389
  flex: 1;
388
390
  overflow: auto;
389
- padding: 20px 0 60px;
391
+ background: var(--docs-canvas-bg, #f9fbfd);
392
+ padding: 14px 0 72px;
390
393
  }
391
394
  /* Auto-hide scrollbars — appear only when scrolling */
392
395
  .docs-canvas {
@@ -430,12 +433,15 @@
430
433
  margin boxes); horizontal margins are padding on the content (.tiptap).
431
434
  Geometry (size + margins) comes inline from the document's page: block. */
432
435
 
436
+ /* The white sheet: hairline edge + soft 1px shadow, square corners (Docs).
437
+ The hairline is a box-shadow ring (NOT a border) so it never shifts the
438
+ content box — page geometry must stay identical to print. */
433
439
  .docs-page {
434
440
  background: #fff;
435
441
  box-shadow:
436
- 0 1px 3px rgba(60, 64, 67, 0.15),
437
- 0 1px 2px rgba(60, 64, 67, 0.1);
438
- border-radius: 2px;
442
+ 0 0 0 1px rgba(60, 64, 67, 0.14),
443
+ 0 1px 3px rgba(60, 64, 67, 0.12);
444
+ border-radius: 0;
439
445
  position: relative;
440
446
  overflow: visible;
441
447
  }
@@ -499,7 +505,7 @@
499
505
  /* The gap reads as "space between two sheets of paper": canvas color with a
500
506
  soft shadow edge on each page card. */
501
507
  .docs-pb-gap {
502
- background: var(--bg-app, #eef0f3);
508
+ background: var(--docs-canvas-bg, #f9fbfd);
503
509
  box-shadow:
504
510
  inset 0 6px 5px -4px rgba(15, 23, 42, 0.14),
505
511
  inset 0 -4px 4px -3px rgba(15, 23, 42, 0.1);
@@ -743,66 +749,124 @@
743
749
  vertical-align: top;
744
750
  }
745
751
 
746
- /* ─── Trust blocks (sign / seal / approve / freeze / amendment) ─── */
752
+ /* ─── Trust blocks (sign / seal / approve / freeze / amendment) ──────────────
753
+ Ink-first, exactly mirroring core's print CSS (document-css.ts .it-approval /
754
+ .it-signature / .it-sealed-banner): hairlines + small-caps labels, no colored
755
+ fills — what you see in the editor is what core prints. */
756
+
747
757
  .docs-page .tiptap .it-doc-trust {
748
758
  display: flex;
749
759
  flex-wrap: wrap;
750
- gap: 8px;
751
- align-items: center;
752
- margin: 10px 0;
753
- padding: 9px 14px;
754
- border: 1px solid #daa520;
755
- border-radius: 8px;
756
- background: #fffdf5;
760
+ gap: 10px;
761
+ align-items: baseline;
757
762
  font-size: 0.9rem;
758
763
  user-select: none;
759
764
  }
760
- .docs-page .tiptap .it-doc-trust--seal {
761
- border: 2px solid #c62828;
762
- background: #fdf5f5;
763
- font-weight: 600;
764
- }
765
+
766
+ /* approve → core .it-approval: single hairline row, ✓ APPROVED label. */
765
767
  .docs-page .tiptap .it-doc-trust--approve {
766
- border-color: #4caf50;
767
- background: #f6fbf6;
768
- }
769
- .docs-page .tiptap .it-doc-trust--freeze {
770
- border-color: #5b8def;
771
- background: #f5f8ff;
768
+ margin: 12px 0;
769
+ padding: 7px 2px;
770
+ border-bottom: 1px solid #ddd;
772
771
  }
773
- .docs-page .tiptap .it-doc-trust--amendment,
774
- .docs-page .tiptap .it-doc-trust--amend {
775
- border-color: #b0b0b0;
776
- background: #fafafa;
772
+ .docs-page .tiptap .it-doc-trust--approve .it-doc-trust__label {
773
+ font-size: 0.7rem;
774
+ font-weight: 700;
775
+ text-transform: uppercase;
776
+ letter-spacing: 0.1em;
777
+ color: #2e7d32;
778
+ flex-shrink: 0;
777
779
  }
778
- .docs-page .tiptap .it-doc-trust__icon {
779
- font-size: 1rem;
780
- line-height: 1;
780
+ .docs-page .tiptap .it-doc-trust--approve .it-doc-trust__label::before {
781
+ content: "✓ ";
781
782
  }
782
- .docs-page .tiptap .it-doc-trust__label {
783
+ .docs-page .tiptap .it-doc-trust__what {
784
+ font-size: 0.9rem;
783
785
  font-weight: 600;
784
- letter-spacing: 0.02em;
786
+ color: #111;
787
+ }
788
+ .docs-page .tiptap .it-doc-trust__who {
789
+ font-size: 0.9rem;
790
+ color: #555;
791
+ }
792
+
793
+ /* sign → core .it-signature: signature rule line (hairline on top). */
794
+ .docs-page .tiptap .it-doc-trust--sign {
795
+ margin: 14px 0 10px;
796
+ padding: 7px 2px 5px;
797
+ border-top: 1px solid #111;
785
798
  }
786
799
  .docs-page .tiptap .it-doc-trust__name {
787
800
  font-weight: 600;
801
+ font-size: 0.95rem;
788
802
  color: #111;
789
803
  }
790
804
  .docs-page .tiptap .it-doc-trust__role {
805
+ font-size: 0.85rem;
791
806
  color: #555;
792
807
  }
793
- .docs-page .tiptap .it-doc-trust__date {
794
- color: #777;
795
- font-size: 0.8rem;
796
- margin-left: auto;
808
+ .docs-page .tiptap .it-doc-trust__status {
809
+ font-size: 0.72rem;
810
+ font-weight: 600;
811
+ margin-inline-start: auto;
812
+ text-transform: uppercase;
813
+ letter-spacing: 0.08em;
814
+ color: #2e7d32;
797
815
  }
798
- .docs-page .tiptap .it-doc-trust__hash {
799
- font-family: ui-monospace, monospace;
800
- font-size: 0.78rem;
801
- color: #444;
816
+
817
+ /* seal / freeze → core .it-sealed-banner: SEALED band, thin top+bottom rules. */
818
+ .docs-page .tiptap .it-doc-trust--seal,
819
+ .docs-page .tiptap .it-doc-trust--freeze {
820
+ gap: 12px;
821
+ margin: 18px 0;
822
+ padding: 8px 2px;
823
+ border-top: 1px solid #111;
824
+ border-bottom: 1px solid #111;
802
825
  }
803
- .docs-page .tiptap .it-doc-trust__meta {
826
+ .docs-page .tiptap .it-doc-trust--seal .it-doc-trust__label,
827
+ .docs-page .tiptap .it-doc-trust--freeze .it-doc-trust__label {
804
828
  font-size: 0.78rem;
829
+ font-weight: 700;
830
+ color: #111;
831
+ text-transform: uppercase;
832
+ letter-spacing: 0.14em;
833
+ }
834
+ .docs-page .tiptap .it-doc-trust--seal .it-doc-trust__date,
835
+ .docs-page .tiptap .it-doc-trust--freeze .it-doc-trust__date {
836
+ margin-inline-start: auto;
837
+ }
838
+ .docs-page .tiptap .it-doc-trust__hash {
839
+ font-family: "SFMono-Regular", ui-monospace, Consolas, monospace;
840
+ font-size: 0.72rem;
841
+ color: #999;
842
+ }
843
+
844
+ /* amendment → muted hairline row. */
845
+ .docs-page .tiptap .it-doc-trust--amendment,
846
+ .docs-page .tiptap .it-doc-trust--amend {
847
+ margin: 12px 0;
848
+ padding: 7px 2px;
849
+ border-bottom: 1px solid #ddd;
850
+ }
851
+ .docs-page .tiptap .it-doc-trust--amendment .it-doc-trust__label,
852
+ .docs-page .tiptap .it-doc-trust--amend .it-doc-trust__label {
853
+ font-size: 0.7rem;
854
+ font-weight: 700;
855
+ text-transform: uppercase;
856
+ letter-spacing: 0.1em;
857
+ color: #555;
858
+ flex-shrink: 0;
859
+ }
860
+
861
+ .docs-page .tiptap .it-doc-trust__date {
805
862
  color: #777;
863
+ font-size: 0.8rem;
864
+ margin-inline-start: auto;
865
+ font-variant-numeric: tabular-nums;
866
+ }
867
+ /* sign rows: status sits at the end — date stays inline. */
868
+ .docs-page .tiptap .it-doc-trust--sign .it-doc-trust__date {
869
+ margin-inline-start: 0;
806
870
  }
807
871
 
808
872
  /* ─── Template variables ({{path}}) ───────────────────────── */
@@ -1053,42 +1117,26 @@
1053
1117
  }
1054
1118
 
1055
1119
  /* ═══════════════════════════════════════════════════════════════
1056
- Ribbon — ONE Word-like toolbar with labeled groups
1120
+ Ribbon — ONE compact Docs-style toolbar row
1057
1121
  (Edit | File | Text | Paragraph | Insert | Trust)
1058
1122
  ═══════════════════════════════════════════════════════════════ */
1059
1123
 
1060
1124
  .docs-ribbon {
1061
- align-items: stretch;
1125
+ align-items: center;
1062
1126
  gap: 0;
1063
- padding: 6px 10px 3px;
1127
+ padding: 4px 10px;
1064
1128
  }
1065
1129
  .ribbon-group {
1066
- display: flex;
1067
- flex-direction: column;
1068
- align-items: center;
1069
- justify-content: space-between;
1070
- padding: 0 2px;
1071
- }
1072
- .ribbon-group-row {
1073
1130
  display: flex;
1074
1131
  align-items: center;
1075
1132
  gap: 2px;
1076
- }
1077
- .ribbon-group-label {
1078
- font-size: 9px;
1079
- font-weight: 600;
1080
- letter-spacing: 0.07em;
1081
- text-transform: uppercase;
1082
- color: #9aa0a6;
1083
- margin-top: 2px;
1084
- user-select: none;
1085
- white-space: nowrap;
1133
+ padding: 0 2px;
1086
1134
  }
1087
1135
  .ribbon-sep {
1088
1136
  width: 1px;
1089
- align-self: stretch;
1090
- background: #d8d2c4;
1091
- margin: 2px 7px;
1137
+ height: 22px;
1138
+ background: #dadce0;
1139
+ margin: 0 6px;
1092
1140
  flex-shrink: 0;
1093
1141
  }
1094
1142
  .ribbon-btn-text {
@@ -1116,7 +1164,7 @@
1116
1164
  .ribbon-editing,
1117
1165
  .ribbon-locked {
1118
1166
  display: flex;
1119
- align-items: stretch;
1167
+ align-items: center;
1120
1168
  }
1121
1169
  /* Sealed documents: formatting is read-only. */
1122
1170
  .ribbon-locked {
@@ -1152,59 +1200,6 @@
1152
1200
  white-space: pre-wrap;
1153
1201
  }
1154
1202
 
1155
- /* ═══════════════════════════════════════════════════════════════
1156
- Signature line — sign: blocks render like a signed paper document
1157
- (script autograph over a rule, printed name / role / date below)
1158
- ═══════════════════════════════════════════════════════════════ */
1159
-
1160
- .docs-page .tiptap .it-doc-sign {
1161
- display: inline-block;
1162
- min-width: 300px;
1163
- max-width: 420px;
1164
- margin: 22px 0 8px;
1165
- margin-inline-end: 28px;
1166
- padding: 0;
1167
- border: none;
1168
- background: none;
1169
- font-weight: 400;
1170
- user-select: none;
1171
- }
1172
- .docs-page .tiptap .it-doc-sign__script {
1173
- font-family: "Snell Roundhand", "Savoye LET", "Segoe Script",
1174
- "Brush Script MT", cursive;
1175
- font-size: 23px;
1176
- line-height: 1.15;
1177
- color: #1a2a52;
1178
- padding: 0 6px 2px;
1179
- min-height: 27px;
1180
- }
1181
- .docs-page .tiptap .it-doc-sign__rule {
1182
- border-bottom: 1.5px solid #202124;
1183
- }
1184
- .docs-page .tiptap .it-doc-sign__row {
1185
- display: flex;
1186
- align-items: baseline;
1187
- gap: 8px;
1188
- margin-top: 5px;
1189
- font-size: 0.85rem;
1190
- }
1191
- .docs-page .tiptap .it-doc-sign__name {
1192
- font-weight: 600;
1193
- color: #111;
1194
- }
1195
- .docs-page .tiptap .it-doc-sign__role {
1196
- color: #555;
1197
- }
1198
- .docs-page .tiptap .it-doc-sign__role::before {
1199
- content: "· ";
1200
- color: #9aa0a6;
1201
- }
1202
- .docs-page .tiptap .it-doc-sign__date {
1203
- margin-inline-start: auto;
1204
- color: #777;
1205
- font-size: 0.8rem;
1206
- }
1207
-
1208
1203
  /* ═══════════════════════════════════════════════════════════════
1209
1204
  Document status banner (trust) + document properties strip
1210
1205
  ═══════════════════════════════════════════════════════════════ */
@@ -1336,17 +1331,59 @@
1336
1331
  unicode-bidi: plaintext;
1337
1332
  }
1338
1333
 
1339
- /* ─── Look refresh (folded from the app's 2026 UI refresh overrides) ──────── */
1340
-
1341
- .docs-toolbar {
1342
- background: linear-gradient(90deg, rgba(15, 118, 110, 0.07), rgba(183, 106, 31, 0.08));
1343
- border-bottom: 1px solid rgba(216, 203, 181, 0.95);
1344
- }
1334
+ /* ─── Active-control accent (Docs blue) ───────────────────── */
1345
1335
 
1346
1336
  .docs-toolbar button.active,
1347
1337
  .docs-tb-btn.active {
1348
- background: rgba(15, 118, 110, 0.16);
1349
- color: #0f766e;
1338
+ background: rgba(26, 115, 232, 0.12);
1339
+ color: #1a73e8;
1340
+ }
1341
+
1342
+ /* ═══════════════════════════════════════════════════════════════
1343
+ Horizontal ruler — Google Docs strip above the page
1344
+ ═══════════════════════════════════════════════════════════════ */
1345
+
1346
+ .docs-ruler {
1347
+ flex-shrink: 0;
1348
+ height: 20px;
1349
+ background: #fff;
1350
+ border-bottom: 1px solid #dadce0;
1351
+ overflow: hidden;
1352
+ user-select: none;
1353
+ }
1354
+ /* Exactly as wide as the page sheet (geometry.width × zoom), centered the same
1355
+ way; translated by the canvas' scrollLeft so it stays glued to the sheet. */
1356
+ .docs-ruler-track {
1357
+ position: relative;
1358
+ height: 100%;
1359
+ margin: 0 auto;
1360
+ }
1361
+ .docs-ruler-margin {
1362
+ position: absolute;
1363
+ top: 0;
1364
+ bottom: 0;
1365
+ background: rgba(60, 64, 67, 0.1);
1366
+ }
1367
+ .docs-ruler-tick {
1368
+ position: absolute;
1369
+ bottom: 4px;
1370
+ width: 1px;
1371
+ background: #9aa0a6;
1372
+ }
1373
+ .docs-ruler-tick--minor {
1374
+ height: 4px;
1375
+ }
1376
+ .docs-ruler-tick--major {
1377
+ height: 7px;
1378
+ }
1379
+ .docs-ruler-num {
1380
+ position: absolute;
1381
+ top: 50%;
1382
+ transform: translate(-50%, -50%);
1383
+ font-size: 9px;
1384
+ line-height: 1;
1385
+ color: #80868b;
1386
+ font-variant-numeric: tabular-nums;
1350
1387
  }
1351
1388
 
1352
1389
  /* ─── Mobile ──────────────────────────────────────────────── */
@@ -1361,4 +1398,7 @@
1361
1398
  .docs-canvas {
1362
1399
  padding: 0;
1363
1400
  }
1401
+ .docs-ruler {
1402
+ display: none;
1403
+ }
1364
1404
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotit/editor",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Embeddable WYSIWYG visual editor for IntentText (.it) documents — Word-like pages, ribbon, trust banner, and WYSIWYG PDF/HTML export. Drop it into any React app (ERPs, portals, back offices).",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -63,7 +63,7 @@
63
63
  "@tiptap/react": "^3.20.1",
64
64
  "@tiptap/starter-kit": "^3.20.1",
65
65
  "lucide-react": "^0.577.0",
66
- "@dotit/core": "^1.1.0"
66
+ "@dotit/core": "^1.1.1"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@types/react": "^19.2.14",