@dotit/editor 1.1.0 → 1.2.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.
@@ -0,0 +1,2 @@
1
+ import { Extension } from "@tiptap/core";
2
+ export declare const LineKeymap: Extension<any, any>;
@@ -21,5 +21,12 @@ export interface PageGeometry {
21
21
  }
22
22
  /** Compute the page geometry from `.it` source (its page:/header:/footer: blocks). */
23
23
  export declare function getPageGeometry(source: string): PageGeometry;
24
+ /**
25
+ * Set (or replace) the `margin:` property on the document's `page:` block.
26
+ * Idempotent: replaces any existing margin/margins prop rather than appending,
27
+ * so repeated ruler drags never accumulate duplicate pipe segments. Inserts a
28
+ * `page:` block (after the meta/title preamble) when the document has none.
29
+ */
30
+ export declare function setPageMargin(source: string, marginValue: string): string;
24
31
  /** Resolve {{page}}/{{pages}} tokens for on-screen display. */
25
32
  export declare function resolvePageTokens(text: string, page: number, pages: number): string;
package/dist/print.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export type PrintMode = "normal" | "minimal-ink";
2
2
  /** Print / save-as-PDF via the browser's print dialog. Browser-only. */
3
3
  export declare function exportDocumentPDF(content: string, theme: string, printMode?: PrintMode): void;
4
+ /** Download the raw `.it` source as a file. This is the editor's "Save".
5
+ * Derives a filename from the document's meta id / title when available. */
6
+ export declare function downloadItFile(content: string, filename?: string): void;
4
7
  /** Download the print-ready HTML document. Browser-only. */
5
8
  export declare function exportDocumentHTML(content: string, theme: string, printMode?: PrintMode): void;
6
9
  /** Built-in theme ids — for the ribbon's theme select. */
package/dist/style.css CHANGED
@@ -790,28 +790,54 @@
790
790
  color: #555;
791
791
  }
792
792
 
793
- /* sign → core .it-signature: signature rule line (hairline on top). */
793
+ /* sign → core .it-signature: name + (role · date) above a signature rule, with
794
+ a "Signed" badge at the line end. Structure mirrors core's renderer exactly. */
794
795
  .docs-page .tiptap .it-doc-trust--sign {
795
- margin: 14px 0 10px;
796
- padding: 7px 2px 5px;
796
+ display: flex;
797
+ flex-wrap: nowrap;
798
+ gap: 14px;
799
+ align-items: flex-end;
800
+ justify-content: space-between;
801
+ margin: 16px 0 8px;
802
+ padding: 0;
803
+ border: 0;
804
+ }
805
+ .docs-page .tiptap .it-doc-trust__body {
806
+ flex: 1;
807
+ min-width: 0;
808
+ display: flex;
809
+ flex-direction: column;
810
+ }
811
+ .docs-page .tiptap .it-doc-trust__rule {
812
+ display: block;
813
+ order: 3;
814
+ margin-top: 6px;
797
815
  border-top: 1px solid #111;
816
+ width: 100%;
817
+ height: 0;
798
818
  }
799
819
  .docs-page .tiptap .it-doc-trust__name {
820
+ order: 1;
800
821
  font-weight: 600;
801
822
  font-size: 0.95rem;
802
823
  color: #111;
803
824
  }
804
- .docs-page .tiptap .it-doc-trust__role {
805
- font-size: 0.85rem;
806
- color: #555;
825
+ .docs-page .tiptap .it-doc-trust__meta {
826
+ order: 2;
827
+ font-size: 0.82rem;
828
+ color: #666;
829
+ margin-top: 1px;
807
830
  }
808
- .docs-page .tiptap .it-doc-trust__status {
831
+ .docs-page .tiptap .it-doc-trust__badge {
832
+ flex-shrink: 0;
809
833
  font-size: 0.72rem;
810
834
  font-weight: 600;
811
- margin-inline-start: auto;
812
835
  text-transform: uppercase;
813
- letter-spacing: 0.08em;
836
+ letter-spacing: 0.07em;
814
837
  color: #2e7d32;
838
+ white-space: nowrap;
839
+ align-self: flex-end;
840
+ padding-bottom: 7px;
815
841
  }
816
842
 
817
843
  /* seal / freeze → core .it-sealed-banner: SEALED band, thin top+bottom rules. */
@@ -864,11 +890,6 @@
864
890
  margin-inline-start: auto;
865
891
  font-variant-numeric: tabular-nums;
866
892
  }
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;
870
- }
871
-
872
893
  /* ─── Template variables ({{path}}) ───────────────────────── */
873
894
  .docs-page .tiptap .it-doc-var {
874
895
  background: #eef2ff;
@@ -1116,6 +1137,38 @@
1116
1137
  color: #1d4ed8;
1117
1138
  }
1118
1139
 
1140
+ /* ─── Info callout — quiet variant (parity with core .intent-info) ───
1141
+ The Plain Writing Overrides above flatten every callout; info is the
1142
+ exception — a soft gray panel with an italic body and an ⓘ marker (no loud
1143
+ "NOTE" label), exactly matching core's document-css.ts so editor == print.
1144
+ Declared AFTER the overrides so it wins. */
1145
+ .docs-page .tiptap .it-doc-callout[data-variant="info"] {
1146
+ display: block;
1147
+ margin: 10px 0;
1148
+ padding: 8px 14px 8px 12px;
1149
+ background: #f5f6f8;
1150
+ border: none;
1151
+ border-inline-start: 3px solid #c7ccd3;
1152
+ border-radius: 0 3px 3px 0;
1153
+ }
1154
+ .docs-page .tiptap .it-doc-callout[data-variant="info"] .it-doc-callout-icon {
1155
+ display: none;
1156
+ }
1157
+ .docs-page .tiptap .it-doc-callout[data-variant="info"] .it-doc-callout-text {
1158
+ display: inline;
1159
+ font-style: italic;
1160
+ color: #4f4f4f;
1161
+ }
1162
+ .docs-page
1163
+ .tiptap
1164
+ .it-doc-callout[data-variant="info"]
1165
+ .it-doc-callout-text::before {
1166
+ content: "ⓘ ";
1167
+ font-style: normal;
1168
+ font-weight: 600;
1169
+ color: #6e6e6e;
1170
+ }
1171
+
1119
1172
  /* ═══════════════════════════════════════════════════════════════
1120
1173
  Ribbon — ONE compact Docs-style toolbar row
1121
1174
  (Edit | File | Text | Paragraph | Insert | Trust)
@@ -1259,6 +1312,16 @@
1259
1312
  background: rgba(220, 38, 38, 0.12);
1260
1313
  color: #dc2626;
1261
1314
  }
1315
+ .docs-trust-banner__warn {
1316
+ margin-inline-start: auto;
1317
+ flex-shrink: 0;
1318
+ padding: 2px 9px;
1319
+ border-radius: 10px;
1320
+ font-size: 11.5px;
1321
+ font-weight: 600;
1322
+ background: rgba(217, 119, 6, 0.13);
1323
+ color: #b45309;
1324
+ }
1262
1325
 
1263
1326
  .docs-props-bar {
1264
1327
  flex-shrink: 0;
@@ -1386,6 +1449,271 @@
1386
1449
  font-variant-numeric: tabular-nums;
1387
1450
  }
1388
1451
 
1452
+ /* Draggable margin stops (Google-Docs blue markers). */
1453
+ .docs-ruler--draggable .docs-ruler-stop {
1454
+ position: absolute;
1455
+ z-index: 2;
1456
+ }
1457
+ .docs-ruler-stop--h {
1458
+ top: 2px;
1459
+ width: 9px;
1460
+ height: 9px;
1461
+ margin-left: -4.5px;
1462
+ cursor: ew-resize;
1463
+ border-left: 4px solid transparent;
1464
+ border-right: 4px solid transparent;
1465
+ border-top: 7px solid #5b6b8c;
1466
+ }
1467
+ .docs-ruler-stop--h:hover,
1468
+ .docs-ruler-stop--h.dragging {
1469
+ border-top-color: #1a73e8;
1470
+ }
1471
+
1472
+ /* ═══════════════════════════════════════════════════════════════
1473
+ Canvas row — left vertical ruler + the scrollable canvas
1474
+ ═══════════════════════════════════════════════════════════════ */
1475
+ .docs-canvas-row {
1476
+ flex: 1;
1477
+ min-height: 0;
1478
+ display: flex;
1479
+ }
1480
+ .docs-canvas-row .docs-canvas {
1481
+ flex: 1;
1482
+ min-width: 0;
1483
+ }
1484
+
1485
+ .docs-ruler-v {
1486
+ flex-shrink: 0;
1487
+ width: 20px;
1488
+ background: #fff;
1489
+ border-right: 1px solid #dadce0;
1490
+ overflow: hidden;
1491
+ user-select: none;
1492
+ }
1493
+ .docs-ruler-v-track {
1494
+ position: relative;
1495
+ width: 100%;
1496
+ margin: 14px auto 0; /* matches .docs-canvas top padding so 0 aligns to sheet top */
1497
+ }
1498
+ .docs-ruler-margin--v {
1499
+ position: absolute;
1500
+ left: 0;
1501
+ right: 0;
1502
+ top: auto;
1503
+ bottom: auto;
1504
+ width: auto;
1505
+ background: rgba(60, 64, 67, 0.1);
1506
+ }
1507
+ .docs-ruler-tick--v {
1508
+ bottom: auto;
1509
+ left: auto;
1510
+ right: 4px;
1511
+ width: 4px;
1512
+ height: 1px;
1513
+ }
1514
+ .docs-ruler-tick--v.docs-ruler-tick--major {
1515
+ width: 7px;
1516
+ }
1517
+ .docs-ruler-num--v {
1518
+ top: auto;
1519
+ left: 50%;
1520
+ transform: translate(-50%, -50%);
1521
+ writing-mode: vertical-rl;
1522
+ }
1523
+ .docs-ruler-stop--v {
1524
+ position: absolute;
1525
+ z-index: 2;
1526
+ left: 2px;
1527
+ width: 9px;
1528
+ height: 9px;
1529
+ margin-top: -4.5px;
1530
+ cursor: ns-resize;
1531
+ border-top: 4px solid transparent;
1532
+ border-bottom: 4px solid transparent;
1533
+ border-left: 7px solid #5b6b8c;
1534
+ }
1535
+ .docs-ruler-stop--v:hover,
1536
+ .docs-ruler-stop--v.dragging {
1537
+ border-left-color: #1a73e8;
1538
+ }
1539
+
1540
+ /* ═══════════════════════════════════════════════════════════════
1541
+ Trust control — one self-explanatory state button + popover
1542
+ ═══════════════════════════════════════════════════════════════ */
1543
+ .trust-control {
1544
+ position: relative;
1545
+ }
1546
+ .trust-face {
1547
+ gap: 5px;
1548
+ }
1549
+ .trust-face__icon {
1550
+ display: inline-flex;
1551
+ }
1552
+ .trust-face__ok {
1553
+ color: #188038;
1554
+ font-weight: 700;
1555
+ }
1556
+ .trust-face--draft {
1557
+ color: #5f6368;
1558
+ }
1559
+ .trust-face--signed {
1560
+ color: #1a73e8;
1561
+ }
1562
+ .trust-face--sealed {
1563
+ color: #188038;
1564
+ }
1565
+ .trust-face--broken {
1566
+ color: #d93025;
1567
+ }
1568
+ .trust-popover {
1569
+ position: absolute;
1570
+ top: calc(100% + 6px);
1571
+ right: 0;
1572
+ z-index: 50;
1573
+ width: 280px;
1574
+ background: #fff;
1575
+ border: 1px solid #dadce0;
1576
+ border-radius: 10px;
1577
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
1578
+ padding: 12px;
1579
+ font-size: 13px;
1580
+ }
1581
+ .trust-popover__state strong {
1582
+ display: block;
1583
+ font-size: 14px;
1584
+ margin-bottom: 2px;
1585
+ }
1586
+ .trust-popover__meta {
1587
+ color: #5f6368;
1588
+ font-size: 12px;
1589
+ line-height: 1.4;
1590
+ }
1591
+ .trust-popover__warn {
1592
+ margin-top: 7px;
1593
+ padding: 6px 8px;
1594
+ border-radius: 6px;
1595
+ background: rgba(217, 119, 6, 0.1);
1596
+ color: #b45309;
1597
+ font-size: 11.5px;
1598
+ font-weight: 500;
1599
+ line-height: 1.35;
1600
+ }
1601
+ .trust-popover__help-toggle {
1602
+ display: block;
1603
+ width: 100%;
1604
+ margin-top: 8px;
1605
+ padding: 0;
1606
+ border: none;
1607
+ background: none;
1608
+ text-align: start;
1609
+ color: #1a73e8;
1610
+ font-size: 11.5px;
1611
+ cursor: pointer;
1612
+ }
1613
+ .trust-popover__help-toggle:hover {
1614
+ text-decoration: underline;
1615
+ }
1616
+ .trust-popover__help {
1617
+ margin-top: 6px;
1618
+ padding: 8px 10px;
1619
+ background: #f6f8fb;
1620
+ border-radius: 6px;
1621
+ font-size: 11.5px;
1622
+ line-height: 1.45;
1623
+ color: #3c4043;
1624
+ }
1625
+ .trust-popover__help p {
1626
+ margin: 0 0 6px;
1627
+ }
1628
+ .trust-popover__help p:last-child {
1629
+ margin-bottom: 0;
1630
+ }
1631
+ .trust-popover__divider {
1632
+ height: 1px;
1633
+ background: #ececec;
1634
+ margin: 10px 0;
1635
+ }
1636
+ .trust-popover__action {
1637
+ display: flex;
1638
+ align-items: center;
1639
+ gap: 8px;
1640
+ width: 100%;
1641
+ padding: 8px 10px;
1642
+ margin-top: 4px;
1643
+ border: 1px solid #dadce0;
1644
+ border-radius: 7px;
1645
+ background: #fff;
1646
+ cursor: pointer;
1647
+ font-size: 13px;
1648
+ color: #202124;
1649
+ text-align: left;
1650
+ }
1651
+ .trust-popover__action:hover {
1652
+ background: #f1f3f4;
1653
+ }
1654
+ .trust-popover__action:disabled {
1655
+ opacity: 0.5;
1656
+ cursor: default;
1657
+ }
1658
+ .trust-popover__action--primary {
1659
+ background: #1a73e8;
1660
+ border-color: #1a73e8;
1661
+ color: #fff;
1662
+ }
1663
+ .trust-popover__action--primary:hover {
1664
+ background: #1666c8;
1665
+ }
1666
+ .trust-popover__action--warn {
1667
+ color: #b06000;
1668
+ }
1669
+ .trust-popover__verify {
1670
+ font-size: 12px;
1671
+ margin-bottom: 6px;
1672
+ }
1673
+ .trust-verify--ok {
1674
+ color: #188038;
1675
+ }
1676
+ .trust-verify--bad {
1677
+ color: #d93025;
1678
+ }
1679
+ .trust-popover__hash {
1680
+ margin-top: 6px;
1681
+ }
1682
+ .trust-popover__hash summary {
1683
+ cursor: pointer;
1684
+ color: #5f6368;
1685
+ }
1686
+ .trust-popover__hash code {
1687
+ display: block;
1688
+ margin-top: 4px;
1689
+ word-break: break-all;
1690
+ font-size: 11px;
1691
+ color: #5f6368;
1692
+ }
1693
+ .trust-sign-form {
1694
+ display: flex;
1695
+ flex-direction: column;
1696
+ gap: 6px;
1697
+ }
1698
+ .trust-sign-input {
1699
+ width: 100%;
1700
+ padding: 7px 9px;
1701
+ border: 1px solid #dadce0;
1702
+ border-radius: 6px;
1703
+ font-size: 13px;
1704
+ }
1705
+ .trust-sign-input:focus {
1706
+ outline: none;
1707
+ border-color: #1a73e8;
1708
+ }
1709
+ .trust-sign-actions {
1710
+ display: flex;
1711
+ gap: 6px;
1712
+ }
1713
+ .trust-sign-actions .trust-popover__action {
1714
+ margin-top: 2px;
1715
+ }
1716
+
1389
1717
  /* ─── Mobile ──────────────────────────────────────────────── */
1390
1718
 
1391
1719
  @media (max-width: 768px) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotit/editor",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
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.1"
66
+ "@dotit/core": "^1.2.1"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@types/react": "^19.2.14",
@@ -76,7 +76,7 @@
76
76
  },
77
77
  "scripts": {
78
78
  "build:core": "pnpm --filter @dotit/core build",
79
- "build": "pnpm run build:core && rm -rf dist && vite build && tsc && cp src/styles.css dist/style.css",
79
+ "build": "pnpm run build:core && rm -rf dist && vite build && tsc -p tsconfig.build.json && cp src/styles.css dist/style.css",
80
80
  "dev": "vite build --watch"
81
81
  }
82
82
  }