@beyondwork/docx-react-component 1.0.11 → 1.0.13
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.
- package/README.md +8 -2
- package/package.json +35 -21
- package/src/api/public-types.ts +103 -1
- package/src/core/commands/formatting-commands.ts +742 -0
- package/src/core/commands/image-commands.ts +84 -2
- package/src/core/commands/structural-helpers.ts +309 -0
- package/src/core/commands/table-structure-commands.ts +721 -0
- package/src/core/commands/text-commands.ts +166 -1
- package/src/core/state/editor-state.ts +318 -9
- package/src/formats/xlsx/io/parse-sheet.ts +177 -7
- package/src/formats/xlsx/io/parse-styles.ts +2 -0
- package/src/formats/xlsx/io/xlsx-session.ts +18 -12
- package/src/formats/xlsx/model/sheet.ts +81 -1
- package/src/formats/xlsx/model/workbook.ts +10 -6
- package/src/io/docx-session.ts +392 -22
- package/src/io/export/export-session.ts +55 -0
- package/src/io/export/serialize-footnotes.ts +5 -20
- package/src/io/export/serialize-headers-footers.ts +5 -31
- package/src/io/export/serialize-main-document.ts +78 -5
- package/src/io/normalize/normalize-text.ts +90 -1
- package/src/io/ooxml/parse-footnotes.ts +68 -5
- package/src/io/ooxml/parse-headers-footers.ts +67 -9
- package/src/io/ooxml/parse-main-document.ts +169 -6
- package/src/io/opc/package-reader.ts +3 -3
- package/src/io/source-package-provenance.ts +241 -0
- package/src/model/canonical-document.ts +450 -2
- package/src/model/cds-1.0.0.ts +5 -2
- package/src/model/snapshot.ts +190 -19
- package/src/preservation/package-preservation.ts +0 -7
- package/src/runtime/document-runtime.ts +7 -1
- package/src/runtime/read-only-diagnostics-runtime.ts +1 -1
- package/src/runtime/surface-projection.ts +200 -17
- package/src/runtime/table-commands.ts +79 -0
- package/src/runtime/table-schema.ts +9 -0
- package/src/ui/WordReviewEditor.tsx +708 -16
- package/src/ui-tailwind/editor-surface/pm-schema.ts +121 -5
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +73 -7
- package/src/ui-tailwind/editor-surface/search-plugin.ts +76 -16
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +162 -14
- package/src/validation/compatibility-engine.ts +208 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/bwllaming/React-OOXML-Office/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
|
-
`@beyondwork/docx-react-component` is the shipped product in this repository: `WordReviewEditor`, a fidelity-first React editor for legal-review-safe `docx` workflows.
|
|
5
|
+
`@beyondwork/docx-react-component` is the shipped product in this repository: `WordReviewEditor`, a fidelity-first React editor for legal-review-safe `docx` workflows. Waves 20 through 23 land live table editing, package distribution, validator-backed CI, and legal workflow helpers. Wave 24 is the next production-hardening packet.
|
|
6
6
|
|
|
7
7
|
The broader repository is still evolving toward a layered `react-ooxml-office` platform, but the source reality is unchanged:
|
|
8
8
|
|
|
@@ -43,6 +43,11 @@ import { WordReviewEditor } from "@beyondwork/docx-react-component";
|
|
|
43
43
|
- runtime owns the live working session
|
|
44
44
|
- host receives events, warnings, errors, snapshots, and exported artifacts
|
|
45
45
|
|
|
46
|
+
Snapshot/export note:
|
|
47
|
+
|
|
48
|
+
- when a session starts from a real `.docx`, persisted snapshots now carry embedded source-package provenance so later snapshot-origin `.docx` export can use the same package-backed exporter
|
|
49
|
+
- legacy snapshots without that provenance still load, but `.docx` export is intentionally blocked rather than falling back to a lossy minimal package
|
|
50
|
+
|
|
46
51
|
The current public ESM exports are:
|
|
47
52
|
|
|
48
53
|
- `@beyondwork/docx-react-component` -> `WordReviewEditor`
|
|
@@ -87,7 +92,7 @@ Start here:
|
|
|
87
92
|
Current shipped docx contracts:
|
|
88
93
|
|
|
89
94
|
- `docs/reference/public-api.md`
|
|
90
|
-
This doc separates the shipped
|
|
95
|
+
This doc separates the shipped Waves 20-23 surface from the future Waves 25 through 27 ref expansion.
|
|
91
96
|
- `docs/reference/ooxml-compliance.md`
|
|
92
97
|
- `docs/reference/word-review-editor-frontend-architecture.md`
|
|
93
98
|
- `docs/reference/word-review-editor-ux-guide.md`
|
|
@@ -117,6 +122,7 @@ Shared platform and planned xlsx docs:
|
|
|
117
122
|
- do not silently drop unknown OOXML
|
|
118
123
|
- keep docs honest about shipped versus planned behavior
|
|
119
124
|
- add or extend fixtures for compatibility-critical changes
|
|
125
|
+
- `bash scripts/validate-fixtures.sh` now uses the Railway validator service and requires `OPENXML_VALIDATOR_AUTH_TOKEN` when hitting the public domain
|
|
120
126
|
|
|
121
127
|
## Guiding Principle
|
|
122
128
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondwork/docx-react-component",
|
|
3
3
|
"publisher": "beyondwork",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.13",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
|
+
"packageManager": "pnpm@10.30.3",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"sideEffects": [
|
|
8
9
|
"**/*.css"
|
|
@@ -45,6 +46,29 @@
|
|
|
45
46
|
"./package.json": "./package.json"
|
|
46
47
|
},
|
|
47
48
|
"types": "./src/index.ts",
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsup",
|
|
51
|
+
"test": "bash scripts/run-workspace-tests.sh",
|
|
52
|
+
"test:repo": "node scripts/run-repo-tests.mjs core",
|
|
53
|
+
"test:repo:all": "node scripts/run-repo-tests.mjs all",
|
|
54
|
+
"test:repo:optional": "node scripts/run-repo-tests.mjs optional",
|
|
55
|
+
"test:wcag-audit": "node scripts/run-repo-tests.mjs wcag-audit",
|
|
56
|
+
"test:harness": "pnpm --filter @docx-react-component/react-word-editor-harness test",
|
|
57
|
+
"lint": "pnpm run lint:no-authored-js && pnpm run lint:tsgo && pnpm run lint:tsgo:harness",
|
|
58
|
+
"lint:no-authored-js": "bash scripts/check-no-authored-js.sh",
|
|
59
|
+
"lint:tsgo": "tsgo --noEmit -p tsconfig.build.json",
|
|
60
|
+
"lint:tsgo:harness": "pnpm --filter @docx-react-component/react-word-editor-harness lint:tsgo",
|
|
61
|
+
"context7:api-check": "bash scripts/context7-export-env.sh run bash scripts/context7-api-check.sh",
|
|
62
|
+
"wave:doctor": "bash scripts/context7-export-env.sh run pnpm exec wave doctor --json",
|
|
63
|
+
"wave:dry-run": "bash scripts/context7-export-env.sh run pnpm exec wave launch --lane main --dry-run --no-dashboard",
|
|
64
|
+
"wave:launch": "bash scripts/context7-export-env.sh run pnpm exec wave launch --lane main",
|
|
65
|
+
"wave:launch:managed": "bash scripts/wave-launch.sh",
|
|
66
|
+
"wave:status": "bash scripts/wave-status.sh",
|
|
67
|
+
"wave:watch": "bash scripts/wave-watch.sh --follow",
|
|
68
|
+
"wave:dashboard:current": "bash scripts/wave-dashboard-attach.sh current",
|
|
69
|
+
"wave:dashboard:global": "bash scripts/wave-dashboard-attach.sh global",
|
|
70
|
+
"harness:dev": "pnpm --filter @docx-react-component/react-word-editor-harness dev"
|
|
71
|
+
},
|
|
48
72
|
"keywords": [
|
|
49
73
|
"docx",
|
|
50
74
|
"word",
|
|
@@ -90,7 +114,7 @@
|
|
|
90
114
|
"tailwindcss": "^4.2.2"
|
|
91
115
|
},
|
|
92
116
|
"devDependencies": {
|
|
93
|
-
"@chllming/wave-orchestration": "^0.9.
|
|
117
|
+
"@chllming/wave-orchestration": "^0.9.13",
|
|
94
118
|
"@types/react": "19.2.14",
|
|
95
119
|
"@types/react-dom": "19.2.3",
|
|
96
120
|
"@typescript/native-preview": "7.0.0-dev.20260409.1",
|
|
@@ -107,24 +131,14 @@
|
|
|
107
131
|
"tsup": "^8.3.0",
|
|
108
132
|
"tsx": "^4.21.0"
|
|
109
133
|
},
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"context7:api-check": "bash scripts/context7-export-env.sh run bash scripts/context7-api-check.sh",
|
|
120
|
-
"wave:doctor": "bash scripts/context7-export-env.sh run pnpm exec wave doctor --json",
|
|
121
|
-
"wave:dry-run": "bash scripts/context7-export-env.sh run pnpm exec wave launch --lane main --dry-run --no-dashboard",
|
|
122
|
-
"wave:launch": "bash scripts/context7-export-env.sh run pnpm exec wave launch --lane main",
|
|
123
|
-
"wave:launch:managed": "bash scripts/wave-launch.sh",
|
|
124
|
-
"wave:status": "bash scripts/wave-status.sh",
|
|
125
|
-
"wave:watch": "bash scripts/wave-watch.sh --follow",
|
|
126
|
-
"wave:dashboard:current": "bash scripts/wave-dashboard-attach.sh current",
|
|
127
|
-
"wave:dashboard:global": "bash scripts/wave-dashboard-attach.sh global",
|
|
128
|
-
"harness:dev": "pnpm --filter @docx-react-component/react-word-editor-harness dev"
|
|
134
|
+
"pnpm": {
|
|
135
|
+
"onlyBuiltDependencies": [
|
|
136
|
+
"esbuild",
|
|
137
|
+
"sharp"
|
|
138
|
+
],
|
|
139
|
+
"overrides": {
|
|
140
|
+
"react": "19.2.4",
|
|
141
|
+
"react-dom": "19.2.4"
|
|
142
|
+
}
|
|
129
143
|
}
|
|
130
144
|
}
|
package/src/api/public-types.ts
CHANGED
|
@@ -123,11 +123,62 @@ export interface TrackedChangesSnapshot {
|
|
|
123
123
|
revisions: TrackedChangeEntrySnapshot[];
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
export type FormattingAlignment = "left" | "center" | "right" | "justify";
|
|
127
|
+
|
|
128
|
+
export interface FormattingStateSnapshot {
|
|
129
|
+
bold: boolean;
|
|
130
|
+
italic: boolean;
|
|
131
|
+
underline: boolean;
|
|
132
|
+
strikethrough: boolean;
|
|
133
|
+
superscript: boolean;
|
|
134
|
+
subscript: boolean;
|
|
135
|
+
fontFamily?: string;
|
|
136
|
+
fontSize?: number;
|
|
137
|
+
textColor?: string;
|
|
138
|
+
highlightColor?: string | null;
|
|
139
|
+
alignment?: FormattingAlignment;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface SearchOptions {
|
|
143
|
+
matchCase?: boolean;
|
|
144
|
+
wholeWord?: boolean;
|
|
145
|
+
limit?: number;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface SearchResultSnapshot {
|
|
149
|
+
resultId: string;
|
|
150
|
+
anchor: EditorAnchorProjection;
|
|
151
|
+
excerpt: string;
|
|
152
|
+
isActive: boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface InsertTableOptions {
|
|
156
|
+
rows: number;
|
|
157
|
+
columns: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface InsertImageOptions {
|
|
161
|
+
data: Uint8Array;
|
|
162
|
+
mimeType: string;
|
|
163
|
+
width?: number;
|
|
164
|
+
height?: number;
|
|
165
|
+
altText?: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
126
168
|
export type SurfaceTextMark =
|
|
127
169
|
| "bold"
|
|
128
170
|
| "italic"
|
|
129
171
|
| "underline"
|
|
130
|
-
| "strikethrough"
|
|
172
|
+
| "strikethrough"
|
|
173
|
+
| "doubleStrikethrough"
|
|
174
|
+
| "superscript"
|
|
175
|
+
| "subscript"
|
|
176
|
+
| "vanish"
|
|
177
|
+
| "emboss"
|
|
178
|
+
| "imprint"
|
|
179
|
+
| "shadow"
|
|
180
|
+
| "smallCaps"
|
|
181
|
+
| "allCaps";
|
|
131
182
|
|
|
132
183
|
export type SurfaceInlineSegment =
|
|
133
184
|
| {
|
|
@@ -137,6 +188,15 @@ export type SurfaceInlineSegment =
|
|
|
137
188
|
to: number;
|
|
138
189
|
text: string;
|
|
139
190
|
marks?: SurfaceTextMark[];
|
|
191
|
+
markAttrs?: {
|
|
192
|
+
backgroundColor?: string;
|
|
193
|
+
charSpacing?: number;
|
|
194
|
+
kerning?: number;
|
|
195
|
+
textFill?: string;
|
|
196
|
+
fontFamily?: string;
|
|
197
|
+
fontSize?: number;
|
|
198
|
+
textColor?: string;
|
|
199
|
+
};
|
|
140
200
|
hyperlinkHref?: string;
|
|
141
201
|
}
|
|
142
202
|
| {
|
|
@@ -174,6 +234,7 @@ export interface SurfaceTableCellSnapshot {
|
|
|
174
234
|
verticalMerge: "restart" | "continue" | null;
|
|
175
235
|
colspan: number;
|
|
176
236
|
rowspan: number;
|
|
237
|
+
backgroundColor?: string | null;
|
|
177
238
|
content: SurfaceBlockSnapshot[];
|
|
178
239
|
}
|
|
179
240
|
|
|
@@ -192,6 +253,17 @@ export type SurfaceBlockSnapshot =
|
|
|
192
253
|
numberingInstanceId: string;
|
|
193
254
|
level: number;
|
|
194
255
|
};
|
|
256
|
+
alignment?: "left" | "center" | "right" | "both" | "distribute";
|
|
257
|
+
spacing?: { before?: number; after?: number; line?: number; lineRule?: string };
|
|
258
|
+
indentation?: { left?: number; right?: number; firstLine?: number; hanging?: number };
|
|
259
|
+
borders?: { top?: unknown; left?: unknown; bottom?: unknown; right?: unknown; bar?: unknown; between?: unknown };
|
|
260
|
+
shading?: { fill?: string; color?: string; val?: string };
|
|
261
|
+
tabStops?: Array<{ pos: number; val?: string; leader?: string }>;
|
|
262
|
+
keepNext?: boolean;
|
|
263
|
+
keepLines?: boolean;
|
|
264
|
+
pageBreakBefore?: boolean;
|
|
265
|
+
outlineLevel?: number;
|
|
266
|
+
bidi?: boolean;
|
|
195
267
|
segments: SurfaceInlineSegment[];
|
|
196
268
|
}
|
|
197
269
|
| {
|
|
@@ -346,6 +418,7 @@ export interface PersistedEditorSnapshot {
|
|
|
346
418
|
canonicalDocument: RuntimePersistedEditorSnapshot["canonicalDocument"];
|
|
347
419
|
compatibility: CompatibilityReport;
|
|
348
420
|
warningLog: EditorWarning[];
|
|
421
|
+
sourcePackage?: RuntimePersistedEditorSnapshot["sourcePackage"];
|
|
349
422
|
}
|
|
350
423
|
|
|
351
424
|
export interface AddCommentParams {
|
|
@@ -508,6 +581,35 @@ export interface WordReviewEditorRef {
|
|
|
508
581
|
getWarnings(): EditorWarning[];
|
|
509
582
|
getComments(): CommentSidebarSnapshot;
|
|
510
583
|
getTrackedChanges(): TrackedChangesSnapshot;
|
|
584
|
+
getFormattingState(): FormattingStateSnapshot;
|
|
585
|
+
toggleBold(): void;
|
|
586
|
+
toggleItalic(): void;
|
|
587
|
+
toggleUnderline(): void;
|
|
588
|
+
toggleStrikethrough(): void;
|
|
589
|
+
toggleSuperscript(): void;
|
|
590
|
+
toggleSubscript(): void;
|
|
591
|
+
setFontFamily(fontFamily: string | null): void;
|
|
592
|
+
setFontSize(size: number | null): void;
|
|
593
|
+
setTextColor(color: string | null): void;
|
|
594
|
+
setHighlightColor(color: string | null): void;
|
|
595
|
+
setAlignment(alignment: FormattingAlignment): void;
|
|
596
|
+
indent(): void;
|
|
597
|
+
outdent(): void;
|
|
598
|
+
insertPageBreak(): void;
|
|
599
|
+
insertTable(options: InsertTableOptions): void;
|
|
600
|
+
insertImage(options: InsertImageOptions): void;
|
|
601
|
+
addRowBefore(): void;
|
|
602
|
+
addRowAfter(): void;
|
|
603
|
+
addColumnBefore(): void;
|
|
604
|
+
addColumnAfter(): void;
|
|
605
|
+
deleteRow(): void;
|
|
606
|
+
deleteColumn(): void;
|
|
607
|
+
deleteTable(): void;
|
|
608
|
+
mergeCells(): void;
|
|
609
|
+
splitCell(): void;
|
|
610
|
+
setCellBackground(color: string): void;
|
|
611
|
+
search(query: string, options?: SearchOptions): SearchResultSnapshot[];
|
|
612
|
+
clearSearch(): void;
|
|
511
613
|
scrollToRevision(revisionId: string): void;
|
|
512
614
|
scrollToComment(commentId: string): void;
|
|
513
615
|
}
|