@beyondwork/docx-react-component 1.0.0 → 1.0.2
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 +44 -104
- package/package.json +66 -15
- package/src/api/public-types.ts +1 -1
- package/src/compare/diff-engine.ts +530 -0
- package/src/compare/export-redlines.ts +162 -0
- package/src/compare/snapshot.ts +37 -0
- package/src/core/commands/index.ts +1 -1
- package/src/core/state/editor-state.ts +2 -2
- package/src/index.ts +45 -0
- package/src/legal/bookmarks.ts +196 -0
- package/src/legal/cross-references.ts +356 -0
- package/src/legal/defined-terms.ts +203 -0
- package/src/runtime/document-runtime.ts +3 -5
- package/src/runtime/table-commands.ts +4 -1
- package/src/runtime/table-schema.ts +17 -2
- package/src/runtime/virtualized-rendering.ts +258 -0
- package/src/ui/WordReviewEditor.tsx +256 -35
- package/src/ui-tailwind/editor-surface/tw-editor-surface.tsx +2 -2
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +16 -2
- package/.codex/config.toml +0 -5
- package/.corepack/v1/pnpm/10.30.3/.corepack +0 -1
- package/.corepack/v1/pnpm/10.30.3/LICENSE +0 -22
- package/.corepack/v1/pnpm/10.30.3/README.md +0 -240
- package/.corepack/v1/pnpm/10.30.3/dist/node-gyp-bin/node-gyp +0 -6
- package/.corepack/v1/pnpm/10.30.3/dist/node-gyp-bin/node-gyp.cmd +0 -5
- package/.corepack/v1/pnpm/10.30.3/dist/pnpm.cjs +0 -195400
- package/.corepack/v1/pnpm/10.30.3/dist/pnpmrc +0 -2
- package/.corepack/v1/pnpm/10.30.3/dist/reflink.darwin-arm64-2HJ4WGO6.node +0 -0
- package/.corepack/v1/pnpm/10.30.3/dist/reflink.darwin-x64-3G3H6IW4.node +0 -0
- package/.corepack/v1/pnpm/10.30.3/dist/reflink.win32-arm64-msvc-Q6BARPPB.node +0 -0
- package/.corepack/v1/pnpm/10.30.3/dist/reflink.win32-x64-msvc-J2TZHRQI.node +0 -0
- package/.corepack/v1/pnpm/10.30.3/dist/templates/completion.bash +0 -31
- package/.corepack/v1/pnpm/10.30.3/dist/templates/completion.fish +0 -22
- package/.corepack/v1/pnpm/10.30.3/dist/templates/completion.ps1 +0 -193
- package/.corepack/v1/pnpm/10.30.3/dist/templates/completion.zsh +0 -27
- package/.corepack/v1/pnpm/10.30.3/dist/vendor/fastlist-0.3.0-x64.exe +0 -0
- package/.corepack/v1/pnpm/10.30.3/dist/vendor/fastlist-0.3.0-x86.exe +0 -0
- package/.corepack/v1/pnpm/10.30.3/dist/worker.js +0 -10119
- package/.corepack/v1/pnpm/10.30.3/package.json +0 -192
- package/.cursor/mcp.json +0 -7
- package/.github/workflows/ci.yml +0 -35
- package/.mcp.json +0 -7
- package/.openclaw/workspace-state.json +0 -4
- package/.pnpmrc.json +0 -1
- package/.wave-launch.sh +0 -7
- package/.workspace-marker +0 -1
- package/AGENTS.md +0 -78
- package/CHANGELOG.md +0 -177
- package/DESIGN.md +0 -929
- package/HEARTBEAT.md +0 -7
- package/IDENTITY.md +0 -23
- package/SOUL.md +0 -36
- package/TOOLS.md +0 -40
- package/USER.md +0 -17
- package/docs/README.md +0 -107
- package/docs/agents/wave-cont-eval-role.md +0 -36
- package/docs/agents/wave-cont-qa-role.md +0 -52
- package/docs/agents/wave-deploy-verifier-role.md +0 -34
- package/docs/agents/wave-design-role.md +0 -47
- package/docs/agents/wave-documentation-role.md +0 -34
- package/docs/agents/wave-infra-role.md +0 -34
- package/docs/agents/wave-integration-role.md +0 -37
- package/docs/agents/wave-launcher-role.md +0 -41
- package/docs/agents/wave-orchestrator-role.md +0 -52
- package/docs/agents/wave-planner-role.md +0 -39
- package/docs/agents/wave-security-role.md +0 -40
- package/docs/architecture/docx/README.md +0 -10
- package/docs/architecture/future/README.md +0 -8
- package/docs/architecture/ooxml-upgrade-analysis.md +0 -134
- package/docs/architecture/platform/shared-openxml-editor-platform.md +0 -153
- package/docs/architecture/xlsx/canonical-workbook-model-and-commands.md +0 -187
- package/docs/architecture/xlsx/spreadsheet-editor-frontend-architecture.md +0 -150
- package/docs/comment-redline-overview.md +0 -350
- package/docs/concepts/context7-vs-skills.md +0 -118
- package/docs/concepts/operating-modes.md +0 -91
- package/docs/concepts/runtime-agnostic-orchestration.md +0 -111
- package/docs/concepts/what-is-a-wave.md +0 -217
- package/docs/context7/bundles.json +0 -222
- package/docs/context7/planner-agent/README.md +0 -28
- package/docs/context7/planner-agent/manifest.json +0 -83
- package/docs/context7/planner-agent/papers/cooperbench-why-coding-agents-cannot-be-your-teammates-yet.md +0 -3283
- package/docs/context7/planner-agent/papers/dova-deliberation-first-multi-agent-orchestration-for-autonomous-research-automation.md +0 -1699
- package/docs/context7/planner-agent/papers/dpbench-large-language-models-struggle-with-simultaneous-coordination.md +0 -2251
- package/docs/context7/planner-agent/papers/incremental-planning-to-control-a-blackboard-based-problem-solver.md +0 -1729
- package/docs/context7/planner-agent/papers/silo-bench-a-scalable-environment-for-evaluating-distributed-coordination-in-multi-agent-llm-systems.md +0 -3747
- package/docs/context7/planner-agent/papers/todoevolve-learning-to-architect-agent-planning-systems.md +0 -1675
- package/docs/context7/planner-agent/papers/verified-multi-agent-orchestration-a-plan-execute-verify-replan-framework-for-complex-query-resolution.md +0 -1173
- package/docs/context7/planner-agent/papers/why-do-multi-agent-llm-systems-fail.md +0 -5211
- package/docs/context7/planner-agent/topics/planning-and-orchestration.md +0 -24
- package/docs/evals/arm-templates/README.md +0 -13
- package/docs/evals/arm-templates/full-wave.json +0 -15
- package/docs/evals/arm-templates/single-agent.json +0 -15
- package/docs/evals/benchmark-catalog.json +0 -670
- package/docs/evals/cases/README.md +0 -47
- package/docs/evals/cases/wave-blackboard-inbox-targeting.json +0 -73
- package/docs/evals/cases/wave-contradiction-conflict.json +0 -104
- package/docs/evals/cases/wave-expert-routing-preservation.json +0 -69
- package/docs/evals/cases/wave-hidden-profile-private-evidence.json +0 -81
- package/docs/evals/cases/wave-premature-closure-guard.json +0 -71
- package/docs/evals/cases/wave-silo-cross-agent-state.json +0 -77
- package/docs/evals/cases/wave-simultaneous-lockstep.json +0 -92
- package/docs/evals/external-benchmarks.json +0 -85
- package/docs/evals/external-command-config.sample.json +0 -9
- package/docs/evals/external-command-config.swe-bench-pro.json +0 -8
- package/docs/evals/pilots/README.md +0 -47
- package/docs/evals/pilots/swe-bench-pro-public-full-wave-review-10.json +0 -64
- package/docs/evals/pilots/swe-bench-pro-public-pilot.json +0 -111
- package/docs/evals/wave-benchmark-program.md +0 -302
- package/docs/guides/planner.md +0 -220
- package/docs/guides/recommendations-0.8.9.md +0 -133
- package/docs/guides/signal-wrappers.md +0 -165
- package/docs/guides/terminal-surfaces.md +0 -96
- package/docs/image copy.png +0 -0
- package/docs/image.png +0 -0
- package/docs/images/image.png +0 -0
- package/docs/legal-feedback-architecture.md +0 -498
- package/docs/plans/component-cutover-matrix.json +0 -1072
- package/docs/plans/component-cutover-matrix.md +0 -307
- package/docs/plans/context7-wave-orchestrator.md +0 -155
- package/docs/plans/current-state.md +0 -198
- package/docs/plans/docx/README.md +0 -9
- package/docs/plans/examples/wave-benchmark-improvement.md +0 -108
- package/docs/plans/examples/wave-example-live-proof.md +0 -435
- package/docs/plans/master-plan.md +0 -224
- package/docs/plans/migration.md +0 -538
- package/docs/plans/operations/README.md +0 -7
- package/docs/plans/operations/wave-10-word-certification.md +0 -87
- package/docs/plans/operations/wave-8-railway-staging.md +0 -153
- package/docs/plans/operations/wave-9-manual-certification.md +0 -73
- package/docs/plans/platform/README.md +0 -9
- package/docs/plans/reference/legal-checklist-coverage.md +0 -258
- package/docs/plans/wave-orchestrator.md +0 -423
- package/docs/plans/waves/README.md +0 -75
- package/docs/plans/waves/completed/wave-0.md +0 -195
- package/docs/plans/waves/completed/wave-1.md +0 -379
- package/docs/plans/waves/completed/wave-10.md +0 -670
- package/docs/plans/waves/completed/wave-11.md +0 -335
- package/docs/plans/waves/completed/wave-12.md +0 -417
- package/docs/plans/waves/completed/wave-13.md +0 -316
- package/docs/plans/waves/completed/wave-14.md +0 -319
- package/docs/plans/waves/completed/wave-15.md +0 -321
- package/docs/plans/waves/completed/wave-16.md +0 -316
- package/docs/plans/waves/completed/wave-17.md +0 -331
- package/docs/plans/waves/completed/wave-18.md +0 -328
- package/docs/plans/waves/completed/wave-2.md +0 -438
- package/docs/plans/waves/completed/wave-3.md +0 -435
- package/docs/plans/waves/completed/wave-4.md +0 -430
- package/docs/plans/waves/completed/wave-5.md +0 -430
- package/docs/plans/waves/completed/wave-6.md +0 -430
- package/docs/plans/waves/completed/wave-7.md +0 -526
- package/docs/plans/waves/completed/wave-8.md +0 -596
- package/docs/plans/waves/completed/wave-9.md +0 -552
- package/docs/plans/waves/deferred/README.md +0 -14
- package/docs/plans/waves/deferred/encrypted-intake-contracts.md +0 -282
- package/docs/plans/waves/deferred/legal-feedback-wave-expansion.md +0 -308
- package/docs/plans/waves/deferred/wave-encrypted-intake.md +0 -451
- package/docs/plans/waves/design/README.md +0 -5
- package/docs/plans/waves/design/wave-1-a1.md +0 -309
- package/docs/plans/waves/reviews/README.md +0 -5
- package/docs/plans/waves/reviews/wave-0-cont-qa.md +0 -151
- package/docs/plans/waves/reviews/wave-1-cont-qa.md +0 -46
- package/docs/plans/waves/reviews/wave-10-accessibility-and-design.md +0 -51
- package/docs/plans/waves/reviews/wave-10-cont-qa.md +0 -24
- package/docs/plans/waves/reviews/wave-10-dashboard-proof.md +0 -46
- package/docs/plans/waves/reviews/wave-10-performance-signoff.md +0 -55
- package/docs/plans/waves/reviews/wave-10-regression-proof.md +0 -23
- package/docs/plans/waves/reviews/wave-10-release-audit.md +0 -31
- package/docs/plans/waves/reviews/wave-10-service-proof.md +0 -83
- package/docs/plans/waves/reviews/wave-10-word-certification.md +0 -31
- package/docs/plans/waves/reviews/wave-18-ai-contract-closure.md +0 -277
- package/docs/plans/waves/reviews/wave-18-cont-qa.md +0 -255
- package/docs/plans/waves/reviews/wave-18-parity-proof.md +0 -271
- package/docs/plans/waves/reviews/wave-19-cont-qa.md +0 -59
- package/docs/plans/waves/reviews/wave-2-cont-qa.md +0 -72
- package/docs/plans/waves/reviews/wave-20-cont-qa.md +0 -60
- package/docs/plans/waves/reviews/wave-25-cont-qa.md +0 -48
- package/docs/plans/waves/reviews/wave-28-cont-qa.md +0 -46
- package/docs/plans/waves/reviews/wave-29-cont-qa.md +0 -53
- package/docs/plans/waves/reviews/wave-3-cont-qa.md +0 -53
- package/docs/plans/waves/reviews/wave-3-core-proof.md +0 -77
- package/docs/plans/waves/reviews/wave-3-validator-proof.md +0 -73
- package/docs/plans/waves/reviews/wave-32-cont-qa.md +0 -43
- package/docs/plans/waves/reviews/wave-33-cont-qa.md +0 -526
- package/docs/plans/waves/reviews/wave-34-cont-qa.md +0 -100
- package/docs/plans/waves/reviews/wave-35-cont-qa.md +0 -145
- package/docs/plans/waves/reviews/wave-4-cont-qa.md +0 -47
- package/docs/plans/waves/reviews/wave-4-structure-proof.md +0 -69
- package/docs/plans/waves/reviews/wave-5-comment-proof.md +0 -158
- package/docs/plans/waves/reviews/wave-5-cont-qa.md +0 -68
- package/docs/plans/waves/reviews/wave-6-cont-qa.md +0 -416
- package/docs/plans/waves/reviews/wave-6-redline-proof.md +0 -130
- package/docs/plans/waves/reviews/wave-7-cont-qa.md +0 -82
- package/docs/plans/waves/reviews/wave-7-ooxml-compliance.md +0 -85
- package/docs/plans/waves/reviews/wave-7-preservation-proof.md +0 -119
- package/docs/plans/waves/reviews/wave-7-trust-ux.md +0 -87
- package/docs/plans/waves/reviews/wave-8-accessibility-and-design.md +0 -128
- package/docs/plans/waves/reviews/wave-8-cont-qa.md +0 -92
- package/docs/plans/waves/reviews/wave-8-live-proof.md +0 -140
- package/docs/plans/waves/reviews/wave-8-security.md +0 -47
- package/docs/plans/waves/reviews/wave-9-editor-embedding.md +0 -39
- package/docs/plans/waves/reviews/wave-9-fixture-runner.md +0 -56
- package/docs/plans/waves/reviews/wave-9-live-proof.md +0 -105
- package/docs/plans/waves/reviews/wave-9-usability-and-performance.md +0 -152
- package/docs/plans/waves/specs/README.md +0 -5
- package/docs/plans/waves/specs/wave-1-component-boundaries.md +0 -322
- package/docs/plans/waves/specs/wave-1-ooxml-contracts.md +0 -323
- package/docs/plans/waves/specs/wave-1-review-and-ui-contracts.md +0 -339
- package/docs/plans/waves/specs/wave-1-runtime-contracts.md +0 -509
- package/docs/plans/waves/wave-19.md +0 -341
- package/docs/plans/waves/wave-20.md +0 -308
- package/docs/plans/waves/wave-21.md +0 -289
- package/docs/plans/waves/wave-22.md +0 -221
- package/docs/plans/waves/wave-23.md +0 -295
- package/docs/plans/waves/wave-24.md +0 -286
- package/docs/plans/waves/wave-25.md +0 -313
- package/docs/plans/waves/wave-26.md +0 -300
- package/docs/plans/waves/wave-27.md +0 -299
- package/docs/plans/waves/wave-28.md +0 -368
- package/docs/plans/waves/wave-29.md +0 -303
- package/docs/plans/waves/wave-30.md +0 -307
- package/docs/plans/waves/wave-31.md +0 -231
- package/docs/plans/waves/wave-32.md +0 -152
- package/docs/plans/waves/wave-33.md +0 -147
- package/docs/plans/waves/wave-34.md +0 -148
- package/docs/plans/waves/wave-35.md +0 -141
- package/docs/plans/waves/wave-36.md +0 -146
- package/docs/plans/xlsx/README.md +0 -14
- package/docs/plans/xlsx/xlsx-fixture-corpus-and-certification-plan.md +0 -126
- package/docs/reference/cli-reference.md +0 -600
- package/docs/reference/coordination-and-closure.md +0 -487
- package/docs/reference/deep-research-report (15).md +0 -25
- package/docs/reference/docx/README.md +0 -10
- package/docs/reference/legal-checklist.md +0 -445
- package/docs/reference/live-proof-waves.md +0 -199
- package/docs/reference/ooxml-compliance.md +0 -129
- package/docs/reference/ooxml-feature-parity-matrix.md +0 -172
- package/docs/reference/platform/shared-ooxml-platform-guidance.md +0 -77
- package/docs/reference/prototype-agent-prompt-legal-fidelity.md +0 -155
- package/docs/reference/public-api.md +0 -456
- package/docs/reference/repository-guidance.md +0 -58
- package/docs/reference/runtime-config/README.md +0 -182
- package/docs/reference/runtime-config/claude.md +0 -110
- package/docs/reference/runtime-config/codex.md +0 -82
- package/docs/reference/runtime-config/opencode.md +0 -93
- package/docs/reference/sample-waves.md +0 -105
- package/docs/reference/skills.md +0 -237
- package/docs/reference/templates/AGENTS.md +0 -78
- package/docs/reference/templates/HEARTBEAT.md +0 -7
- package/docs/reference/templates/IDENTITY.md +0 -23
- package/docs/reference/templates/SOUL.md +0 -36
- package/docs/reference/templates/TOOLS.md +0 -40
- package/docs/reference/templates/USER.md +0 -17
- package/docs/reference/wave-control.md +0 -184
- package/docs/reference/wave-planning-lessons.md +0 -167
- package/docs/reference/word-review-editor-frontend-architecture.md +0 -479
- package/docs/reference/word-review-editor-ux-guide.md +0 -253
- package/docs/reference/xlsx/xlsx-ooxml-compliance.md +0 -137
- package/docs/research/agent-context-sources.md +0 -178
- package/docs/research/coordination-failure-review.md +0 -290
- package/docs/research/docx-react-component/Canonical Document Schema Specification for a React-based Word-compatible Editor.md +0 -2317
- package/docs/research/docx-react-component/Feature Compatibility Matrix for a React Word Compatible Legal Editor v1.md +0 -219
- package/docs/research/docx-react-component/React Component Architecture and Front-End Structure Specification for a Word-Compatible Legal Review Editor.md +0 -1112
- package/docs/research/docx-react-component/document_compatibility_and_testing_spec.md +0 -751
- package/docs/research/xlsx/raw/README.md +0 -13
- package/docs/roadmap.md +0 -174
- package/docs/superpowers/plans/2026-03-28-harness-control-bar.md +0 -677
- package/docs/superpowers/specs/2026-03-28-harness-control-bar-design.md +0 -274
- package/docs/xlsx-react/README.md +0 -38
- package/docs/xlsx-react/agent-llm-interaction-layer-docx-xlsx.md +0 -621
- package/docs/xlsx-react/canonical-workbook-model-and-commands.md +0 -948
- package/docs/xlsx-react/shared-openxml-editor-platform-docx-xlsx.md +0 -228
- package/docs/xlsx-react/spreadsheet-editor-component-architecture.md +0 -809
- package/docs/xlsx-react/spreadsheet-editor-frontend-architecture.md +0 -537
- package/docs/xlsx-react/spreadsheet-editor-ux-guide.md +0 -520
- package/docs/xlsx-react/xlsx-editor-research-pack.md +0 -871
- package/docs/xlsx-react/xlsx-fixture-corpus-and-certification-plan.md +0 -436
- package/docs/xlsx-react/xlsx-ooxml-compliance.md +0 -320
- package/examples/README.md +0 -16
- package/memory/MEMORY.md +0 -24
- package/pnpm-workspace.yaml +0 -4
- package/scripts/check-no-authored-js.sh +0 -13
- package/scripts/context7-api-check.sh +0 -65
- package/scripts/context7-export-env.sh +0 -42
- package/scripts/run-context7-mcp.sh +0 -8
- package/scripts/run-workspace-tests.sh +0 -15
- package/scripts/start-wave-10-local.sh +0 -189
- package/scripts/wave-agent-attach.sh +0 -47
- package/scripts/wave-auto-answer.sh +0 -118
- package/scripts/wave-dashboard-attach.sh +0 -13
- package/scripts/wave-launch.sh +0 -273
- package/scripts/wave-overnight-supervisor.sh +0 -145
- package/scripts/wave-status.sh +0 -379
- package/scripts/wave-watch.sh +0 -231
- package/services/README.md +0 -17
- package/services/openxml-validator/Dockerfile +0 -29
- package/services/openxml-validator/OpenXmlValidator.Api.csproj +0 -12
- package/services/openxml-validator/Program.cs +0 -436
- package/services/openxml-validator/README.md +0 -152
- package/services/openxml-validator/railway.json +0 -16
- package/services/react-word-editor/.tmp-a4/src/api/public-types.ts +0 -318
- package/services/react-word-editor/.tmp-a4/src/ui/WordReviewEditor.tsx +0 -1302
- package/services/react-word-editor/.tmp-a4/src/ui/editor-surface/editor-surface.tsx +0 -546
- package/services/react-word-editor/.tmp-a4/test/ui/word-review-editor.test.tsx +0 -146
- package/services/react-word-editor/.tmp-a4-build/src/api/public-types.js +0 -2
- package/services/react-word-editor/.tmp-a4-build/src/ui/WordReviewEditor.js +0 -818
- package/services/react-word-editor/.tmp-a4-build/src/ui/editor-surface/editor-surface.js +0 -229
- package/services/react-word-editor/.tmp-a4-build/test/ui/word-review-editor.test.js +0 -121
- package/services/react-word-editor/.tmp-wave-4-a3-tsconfig.json +0 -21
- package/services/react-word-editor/.tmp-wave-4-a3-tsconfig.tsbuildinfo +0 -1
- package/services/react-word-editor/Dockerfile +0 -26
- package/services/react-word-editor/README.md +0 -254
- package/services/react-word-editor/app/api/certification/route.ts +0 -79
- package/services/react-word-editor/app/api/demo-sessions/route.ts +0 -109
- package/services/react-word-editor/app/api/deploy-health/route.ts +0 -23
- package/services/react-word-editor/app/api/exports/[exportId]/route.ts +0 -34
- package/services/react-word-editor/app/api/exports/route.ts +0 -81
- package/services/react-word-editor/app/api/fixtures/[fixtureId]/run/route.ts +0 -100
- package/services/react-word-editor/app/api/health/route.ts +0 -70
- package/services/react-word-editor/app/api/runs/[runId]/route.ts +0 -36
- package/services/react-word-editor/app/api/scenarios/[scenarioId]/run/route.ts +0 -85
- package/services/react-word-editor/app/api/sessions/[sessionId]/route.ts +0 -199
- package/services/react-word-editor/app/api/sessions/[sessionId]/source/route.ts +0 -45
- package/services/react-word-editor/app/api/uploads/route.ts +0 -70
- package/services/react-word-editor/app/api/validate/route.ts +0 -310
- package/services/react-word-editor/app/certification/[runId]/page.tsx +0 -14
- package/services/react-word-editor/app/certification/page.tsx +0 -32
- package/services/react-word-editor/app/dashboard/page.tsx +0 -7
- package/services/react-word-editor/app/demo/page.tsx +0 -30
- package/services/react-word-editor/app/demo/prototype-client.tsx +0 -1080
- package/services/react-word-editor/app/editor/[sessionId]/page.tsx +0 -33
- package/services/react-word-editor/app/fixtures/page.tsx +0 -7
- package/services/react-word-editor/app/globals.css +0 -121
- package/services/react-word-editor/app/layout.tsx +0 -32
- package/services/react-word-editor/app/page.tsx +0 -30
- package/services/react-word-editor/app/runs/[runId]/page.tsx +0 -34
- package/services/react-word-editor/app/wave-10-word-review/page.tsx +0 -7
- package/services/react-word-editor/components/harness-control-bar.tsx +0 -289
- package/services/react-word-editor/components/harness-editor-session-client.tsx +0 -1214
- package/services/react-word-editor/components/harness-workspace-page.tsx +0 -715
- package/services/react-word-editor/components/reduced-motion-toggle.tsx +0 -79
- package/services/react-word-editor/components/workspace-certification-panel.tsx +0 -307
- package/services/react-word-editor/lib/certification-bundle.ts +0 -796
- package/services/react-word-editor/lib/certification-store.ts +0 -661
- package/services/react-word-editor/lib/demo-fixtures.test.mjs +0 -195
- package/services/react-word-editor/lib/demo-fixtures.ts +0 -1519
- package/services/react-word-editor/lib/editor-session-summary.test.mjs +0 -68
- package/services/react-word-editor/lib/editor-session-summary.ts +0 -14
- package/services/react-word-editor/lib/editor-session.ts +0 -228
- package/services/react-word-editor/lib/exports-route.test.mjs +0 -32
- package/services/react-word-editor/lib/harness-client.ts +0 -347
- package/services/react-word-editor/lib/harness-config.json +0 -30
- package/services/react-word-editor/lib/harness-config.test.mjs +0 -31
- package/services/react-word-editor/lib/harness-config.ts +0 -21
- package/services/react-word-editor/lib/harness-editor-datastore.test.mjs +0 -220
- package/services/react-word-editor/lib/harness-editor-datastore.ts +0 -161
- package/services/react-word-editor/lib/private-mode.test.mjs +0 -42
- package/services/react-word-editor/lib/private-mode.ts +0 -61
- package/services/react-word-editor/lib/regression-report.test.mjs +0 -352
- package/services/react-word-editor/lib/regression-report.ts +0 -896
- package/services/react-word-editor/lib/run-artifacts.ts +0 -934
- package/services/react-word-editor/lib/run-history.ts +0 -755
- package/services/react-word-editor/lib/scenario-artifacts.test.mjs +0 -41
- package/services/react-word-editor/lib/scenario-artifacts.ts +0 -44
- package/services/react-word-editor/lib/storage.ts +0 -953
- package/services/react-word-editor/lib/validator-client.test.mjs +0 -54
- package/services/react-word-editor/lib/validator-client.ts +0 -95
- package/services/react-word-editor/lib/workspace-navigation.ts +0 -79
- package/services/react-word-editor/middleware.ts +0 -35
- package/services/react-word-editor/next-env.d.ts +0 -6
- package/services/react-word-editor/next.config.mjs +0 -15
- package/services/react-word-editor/package.json +0 -38
- package/services/react-word-editor/postcss.config.mjs +0 -8
- package/services/react-word-editor/railway.json +0 -21
- package/services/react-word-editor/scripts/wave-10-certification.mjs +0 -101
- package/services/react-word-editor/scripts/wave-9-live-usability-pilot.mjs +0 -911
- package/services/react-word-editor/tsconfig.json +0 -39
- package/services/react-word-editor/tsconfig.tsbuildinfo +0 -1
- package/skills/README.md +0 -48
- package/skills/domain-docx-compatibility/SKILL.md +0 -44
- package/skills/domain-docx-compatibility/skill.json +0 -19
- package/skills/domain-editor-architecture/SKILL.md +0 -49
- package/skills/domain-editor-architecture/skill.json +0 -19
- package/skills/domain-legal-review/SKILL.md +0 -39
- package/skills/domain-legal-review/skill.json +0 -19
- package/skills/provider-aws/SKILL.md +0 -117
- package/skills/provider-aws/adapters/claude.md +0 -1
- package/skills/provider-aws/adapters/codex.md +0 -1
- package/skills/provider-aws/references/service-verification.md +0 -39
- package/skills/provider-aws/skill.json +0 -54
- package/skills/provider-custom-deploy/SKILL.md +0 -64
- package/skills/provider-custom-deploy/skill.json +0 -50
- package/skills/provider-docker-compose/SKILL.md +0 -96
- package/skills/provider-docker-compose/adapters/local.md +0 -1
- package/skills/provider-docker-compose/skill.json +0 -53
- package/skills/provider-github-release/SKILL.md +0 -121
- package/skills/provider-github-release/adapters/claude.md +0 -1
- package/skills/provider-github-release/adapters/codex.md +0 -1
- package/skills/provider-github-release/skill.json +0 -55
- package/skills/provider-kubernetes/SKILL.md +0 -143
- package/skills/provider-kubernetes/adapters/claude.md +0 -1
- package/skills/provider-kubernetes/adapters/codex.md +0 -1
- package/skills/provider-kubernetes/references/kubectl-patterns.md +0 -58
- package/skills/provider-kubernetes/skill.json +0 -52
- package/skills/provider-railway/SKILL.md +0 -123
- package/skills/provider-railway/adapters/claude.md +0 -1
- package/skills/provider-railway/adapters/codex.md +0 -1
- package/skills/provider-railway/adapters/local.md +0 -1
- package/skills/provider-railway/adapters/opencode.md +0 -1
- package/skills/provider-railway/references/verification-commands.md +0 -39
- package/skills/provider-railway/skill.json +0 -71
- package/skills/provider-ssh-manual/SKILL.md +0 -97
- package/skills/provider-ssh-manual/skill.json +0 -54
- package/skills/repo-coding-rules/SKILL.md +0 -55
- package/skills/repo-coding-rules/skill.json +0 -34
- package/skills/role-cont-eval/SKILL.md +0 -91
- package/skills/role-cont-eval/adapters/codex.md +0 -1
- package/skills/role-cont-eval/skill.json +0 -36
- package/skills/role-cont-qa/SKILL.md +0 -100
- package/skills/role-cont-qa/adapters/claude.md +0 -1
- package/skills/role-cont-qa/skill.json +0 -36
- package/skills/role-deploy/SKILL.md +0 -97
- package/skills/role-deploy/skill.json +0 -36
- package/skills/role-design/SKILL.md +0 -50
- package/skills/role-design/skill.json +0 -36
- package/skills/role-documentation/SKILL.md +0 -76
- package/skills/role-documentation/skill.json +0 -36
- package/skills/role-implementation/SKILL.md +0 -45
- package/skills/role-implementation/skill.json +0 -36
- package/skills/role-infra/SKILL.md +0 -81
- package/skills/role-infra/skill.json +0 -36
- package/skills/role-integration/SKILL.md +0 -91
- package/skills/role-integration/skill.json +0 -36
- package/skills/role-planner/SKILL.md +0 -39
- package/skills/role-planner/skill.json +0 -21
- package/skills/role-research/SKILL.md +0 -65
- package/skills/role-research/skill.json +0 -36
- package/skills/role-security/SKILL.md +0 -60
- package/skills/role-security/skill.json +0 -36
- package/skills/runtime-claude/SKILL.md +0 -66
- package/skills/runtime-claude/skill.json +0 -36
- package/skills/runtime-codex/SKILL.md +0 -58
- package/skills/runtime-codex/skill.json +0 -36
- package/skills/runtime-local/SKILL.md +0 -46
- package/skills/runtime-local/skill.json +0 -36
- package/skills/runtime-opencode/SKILL.md +0 -58
- package/skills/runtime-opencode/skill.json +0 -36
- package/skills/signal-hygiene/SKILL.md +0 -51
- package/skills/signal-hygiene/skill.json +0 -20
- package/skills/tui-design/SKILL.md +0 -77
- package/skills/tui-design/references/tui-design.md +0 -259
- package/skills/tui-design/skill.json +0 -36
- package/skills/wave-core/SKILL.md +0 -141
- package/skills/wave-core/references/marker-syntax.md +0 -70
- package/skills/wave-core/skill.json +0 -35
- package/test/README.md +0 -16
- package/test/core/formatting-commands.test.ts +0 -285
- package/test/core/image-commands.test.ts +0 -298
- package/test/core/mapping.test.ts +0 -186
- package/test/core/text-commands.test.ts +0 -176
- package/test/fixtures/docx/F01-basic-contract.docx +0 -0
- package/test/fixtures/docx/F01-basic-contract.md +0 -33
- package/test/fixtures/docx/F02-headings-styles.docx +0 -0
- package/test/fixtures/docx/F02-headings-styles.md +0 -33
- package/test/fixtures/docx/F03-legal-outline-numbering.docx +0 -0
- package/test/fixtures/docx/F03-legal-outline-numbering.md +0 -34
- package/test/fixtures/docx/F04-restart-numbering-schedules.docx +0 -0
- package/test/fixtures/docx/F04-restart-numbering-schedules.md +0 -33
- package/test/fixtures/docx/F05-table-heavy-agreement.docx +0 -0
- package/test/fixtures/docx/F05-table-heavy-agreement.md +0 -34
- package/test/fixtures/docx/F06-merged-cells-signature-table.docx +0 -0
- package/test/fixtures/docx/F06-merged-cells-signature-table.md +0 -34
- package/test/fixtures/docx/F07-inline-images-exhibit.docx +0 -0
- package/test/fixtures/docx/F07-inline-images-exhibit.md +0 -34
- package/test/fixtures/docx/F08-hyperlinks.docx +0 -0
- package/test/fixtures/docx/F08-hyperlinks.md +0 -33
- package/test/fixtures/docx/F09-comments-single-paragraph.docx +0 -0
- package/test/fixtures/docx/F09-comments-single-paragraph.md +0 -33
- package/test/fixtures/docx/F10-threaded-comments-resolve.docx +0 -0
- package/test/fixtures/docx/F10-threaded-comments-resolve.md +0 -33
- package/test/fixtures/docx/F11-redlines-basic.docx +0 -0
- package/test/fixtures/docx/F11-redlines-basic.md +0 -33
- package/test/fixtures/docx/F12-redlines-paragraph-joins-splits.docx +0 -0
- package/test/fixtures/docx/F12-redlines-paragraph-joins-splits.md +0 -33
- package/test/fixtures/docx/F13-comments-on-deleted-text.docx +0 -0
- package/test/fixtures/docx/F13-comments-on-deleted-text.md +0 -33
- package/test/fixtures/docx/F14-revisions-in-tables-and-lists.docx +0 -0
- package/test/fixtures/docx/F14-revisions-in-tables-and-lists.md +0 -33
- package/test/fixtures/docx/F15-sections-headers-footers.docx +0 -0
- package/test/fixtures/docx/F15-sections-headers-footers.md +0 -33
- package/test/fixtures/docx/F16-footnotes-endnotes.docx +0 -0
- package/test/fixtures/docx/F16-footnotes-endnotes.md +0 -33
- package/test/fixtures/docx/F17-fields-and-toc.docx +0 -0
- package/test/fixtures/docx/F17-fields-and-toc.md +0 -33
- package/test/fixtures/docx/F18-content-controls-template.docx +0 -0
- package/test/fixtures/docx/F18-content-controls-template.md +0 -33
- package/test/fixtures/docx/F19-custom-xml-doc-assembly.docx +0 -0
- package/test/fixtures/docx/F19-custom-xml-doc-assembly.md +0 -35
- package/test/fixtures/docx/F20-unknown-ooxml-and-alternatecontent.docx +0 -0
- package/test/fixtures/docx/F20-unknown-ooxml-and-alternatecontent.md +0 -33
- package/test/fixtures/docx/F21-malformed-broken-docx.docx +0 -0
- package/test/fixtures/docx/F21-malformed-broken-docx.md +0 -33
- package/test/fixtures/docx/README.md +0 -74
- package/test/fixtures/docx/certification-manifest.json +0 -104
- package/test/fixtures/docx/fixtures.manifest.json +0 -196
- package/test/fixtures/encrypted-docx/README.md +0 -27
- package/test/fixtures/encrypted-docx/certification-manifest.json +0 -9
- package/test/fixtures/encrypted-docx/fixtures.manifest.json +0 -47
- package/test/fixtures/scenarios/docx/README.md +0 -25
- package/test/fixtures/scenarios/docx/S01-sow-template.docx +0 -0
- package/test/fixtures/scenarios/docx/S01-sow-template.md +0 -30
- package/test/fixtures/scenarios/docx/S02-bw-partner-user-licence-agreement-redlines.docx +0 -0
- package/test/fixtures/scenarios/docx/S02-bw-partner-user-licence-agreement-redlines.md +0 -32
- package/test/fixtures/scenarios/docx/scenario-manifest.json +0 -53
- package/test/formats/xlsx/io/xlsx-import.test.ts +0 -766
- package/test/formats/xlsx/model/workbook.test.ts +0 -669
- package/test/helpers/dom-setup.ts +0 -124
- package/test/io/comment-roundtrip.test.ts +0 -272
- package/test/io/complex-content-roundtrip.test.ts +0 -632
- package/test/io/docx-compatibility-regression.test.ts +0 -199
- package/test/io/docx-session.test.ts +0 -1495
- package/test/io/footnotes-roundtrip.test.ts +0 -318
- package/test/io/headers-footers-roundtrip.test.ts +0 -547
- package/test/io/numbering-roundtrip.test.ts +0 -234
- package/test/io/package-reader.test.ts +0 -199
- package/test/io/paragraph-properties-roundtrip.test.ts +0 -129
- package/test/io/preserved-package-roundtrip.test.ts +0 -365
- package/test/io/property-completeness.test.ts +0 -292
- package/test/io/revision-roundtrip.test.ts +0 -347
- package/test/io/structural-blocks.test.ts +0 -202
- package/test/io/table-media-roundtrip.test.ts +0 -448
- package/test/io/table-properties-roundtrip.test.ts +0 -569
- package/test/io/table-roundtrip.test.ts +0 -302
- package/test/io/text-roundtrip.test.ts +0 -344
- package/test/model/canonical-document.test.ts +0 -285
- package/test/preservation/opaque-fragment-store.test.ts +0 -121
- package/test/preservation/package-preservation.test.ts +0 -395
- package/test/preservation/store.test.ts +0 -84
- package/test/review/comment-remapping.test.ts +0 -220
- package/test/review/comment-store.test.ts +0 -180
- package/test/review/move-revisions.test.ts +0 -143
- package/test/review/property-change-revisions.test.ts +0 -225
- package/test/review/revision-actions.test.ts +0 -330
- package/test/review/revision-store.test.ts +0 -193
- package/test/runtime/session-capabilities.test.ts +0 -260
- package/test/runtime/table-commands.test.ts +0 -356
- package/test/runtime/table-schema.test.ts +0 -221
- package/test/runtime/tracked-changes-toggle.test.ts +0 -107
- package/test/ui/comment-review-surface.test.tsx +0 -114
- package/test/ui/reduced-motion-toggle.test.tsx +0 -137
- package/test/ui/word-review-editor.imported-scenarios.test.tsx +0 -169
- package/test/ui/word-review-editor.interaction.test.tsx +0 -1198
- package/test/ui/word-review-editor.test.js +0 -188
- package/test/ui/word-review-editor.test.tsx +0 -280
- package/test/ui-tailwind/search-plugin.test.ts +0 -286
- package/test/validation/compatibility-engine.test.ts +0 -336
- package/test/validation/compatibility-report.test.ts +0 -189
- package/test/validation/low-priority-word-surfaces.test.ts +0 -282
- package/test/validation/malformed-doc.test.ts +0 -113
- package/test-results/.last-run.json +0 -4
- package/wave.config.json +0 -406
|
@@ -1,537 +0,0 @@
|
|
|
1
|
-
# Spreadsheet Editor — Frontend Architecture
|
|
2
|
-
|
|
3
|
-
This research paper is source material.
|
|
4
|
-
|
|
5
|
-
Canonical repo-aligned planned doc:
|
|
6
|
-
|
|
7
|
-
- `docs/architecture/xlsx/spreadsheet-editor-frontend-architecture.md`
|
|
8
|
-
|
|
9
|
-
## Interpretation of the problem
|
|
10
|
-
|
|
11
|
-
You’re building an XLSX sibling to an existing React OOXML DOCX editor, and you want comparable architectural rigor and product honesty: one embeddable React component, a runtime-owned canonical workbook state, and a typed public API surface. The UI must be a projection of runtime state—React is a subscriber and dispatcher only—mirroring the runtime/UI boundary and “render snapshot vs persisted snapshot” split used in the DOCX editor architecture.
|
|
12
|
-
|
|
13
|
-
The central correctness constraints are: treat `.xlsx` as an OOXML/Open Packaging Conventions (OPC) package (parts + relationships + content types), not as “some XML files”; ensure all mutations flow through commands → transactions → commit; never silently drop unsupported-but-preservable content; and make host behavior the ultimate spec (exported files reopen in modern Excel without repair prompts or silent, *supported-content* loss).
|
|
14
|
-
|
|
15
|
-
This document therefore defines an implementation-ready frontend architecture: module boundaries, runtime state model, command/transaction pipeline, virtualization strategy, selection + decoration model, theming, trust surfaces, accessibility, responsive behavior, test matrices, fixtures, and release gates—explicitly distinguishing spec-level correctness from observed Excel behavior.
|
|
16
|
-
|
|
17
|
-
## Research plan
|
|
18
|
-
|
|
19
|
-
The research focused on five non-negotiable information needs.
|
|
20
|
-
|
|
21
|
-
First, mirror proven architectural seams from the DOCX editor: runtime contracts, render-snapshot vs persisted-snapshot boundary, module dependency rules, preservation rules, capability derivation, and UX composition patterns.
|
|
22
|
-
|
|
23
|
-
Second, establish normative package-level truths: OPC’s content types stream, relationships parts, part naming/relationship discovery model, and markup compatibility (forward-compatibility) mechanisms that affect “preserve unknown content” design.
|
|
24
|
-
|
|
25
|
-
Third, establish SpreadsheetML core structures needed for safe import → edit → export: workbook/worksheets part relationships, shared strings, styles part semantics, merged-cell semantics, and calculation-related parts.
|
|
26
|
-
|
|
27
|
-
Fourth, collect observed Excel behavior and practical constraints that affect editor honesty and export safety (e.g., calculation chain being a cache, and “recalculate on open” settings).
|
|
28
|
-
|
|
29
|
-
Fifth, define interaction and platform constraints for a grid editor: accessibility expectations for a spreadsheet-like grid, clipboard event boundaries, and performance implications of Excel’s grid limits (over 17 billion addressable cells).
|
|
30
|
-
|
|
31
|
-
## Findings
|
|
32
|
-
|
|
33
|
-
**Normative: `.xlsx` is an OPC package, not “XML files.”** OPC requires a content types stream (`[Content_Types].xml`) mapping part names/extensions to MIME content types, and relationship parts (e.g., `/_rels/.rels` and per-part `*_rels/*.rels`) used to discover and traverse parts via relationship graphs. The canonical implication for an editor is that correctness is primarily **package-level**: you must preserve/repair relationships, content type overrides, and untouched parts, not only rewrite `xl/worksheets/sheet1.xml`.
|
|
34
|
-
|
|
35
|
-
**Normative: markup compatibility exists to support forward compatibility.** ISO/OOXML markup compatibility defines conventions like “ignorable namespaces,” “process content,” and “must understand,” enabling newer producers and older consumers to interoperate without losing essential data. For an editor, this means unknown/extensible markup is not exceptional; it’s expected—and must be preserved with explicit user-facing classification rather than dropped or flattened.
|
|
36
|
-
|
|
37
|
-
**SpreadsheetML structure is workbook-centric with per-sheet parts.** Microsoft’s Open XML guidance describes a SpreadsheetML document as a workbook (`<workbook/>`) referencing sheets (`<sheets/>` / `<sheet/>`), with a distinct XML part per worksheet. This maps cleanly to runtime design: workbook metadata and cross-sheet registries (styles, shared strings, name definitions, calculation settings) belong at the workbook layer; sheet grids are separate sparse stores, loaded and rendered independently.
|
|
38
|
-
|
|
39
|
-
**Shared strings and styles are global performance/consistency structures.** SpreadsheetML often stores repeated strings in a shared string table (`sharedStrings.xml`), with cells referencing strings by index; Excel typically writes a shared string table, but valid documents can also use inline strings in sheet cells. Cell formatting is stored primarily in a workbook-level Styles part (`styles.xml`) that contains collections for number formats, fonts, fills, borders, and cell format records—separate from sheet content—so the editor must treat styles as a global catalog with stable indices and preserve unknown style subtrees.
|
|
40
|
-
|
|
41
|
-
**Merged cells have “top-left owns value” semantics that affect rendering and editing.** The SpreadsheetML merge model expresses merged ranges via `mergeCells/mergeCell ref="A1:B2"`; the merged range’s content and formatting are stored in the top-left cell, and that reality must be enforced by the editor’s canonical model and UI hit-testing.
|
|
42
|
-
|
|
43
|
-
**Calculation chain is a cache; it’s not required for correctness, and it’s commonly inconsistent in the wild.** Microsoft’s Office file format specs describe the calculation chain as an application-specific cache that can be rebuilt and even recommends packages not contain it; it must appear at most once if present and is the target of an implicit relationship from the workbook. The Open XML SDK includes an explicit helper to ignore missing `CalculationChainPart` relationships—strong evidence you must tolerate “workbook has relationship but part missing” scenarios without failing import.
|
|
44
|
-
|
|
45
|
-
**Excel’s grid limits force virtualization and “sparse truth.”** Excel supports 1,048,576 rows and 16,384 columns per sheet, i.e., an address space far beyond what any DOM-based “render the grid” approach can manage. Any serious editor must: (a) store sheets sparsely, (b) virtualize both axes, and (c) avoid React-per-cell ownership of canonical cell state.
|
|
46
|
-
|
|
47
|
-
**Excel has two comment systems with different UX expectations.** Excel distinguishes threaded comments (discussion-oriented) from notes (legacy, annotation-oriented). This matters for format scope: if you can’t safely round-trip *both* comment systems, you must treat the unsupported one as preserve-only (display/lock/warn) rather than “best-effort edit” that risks rewriting incompatible parts.
|
|
48
|
-
|
|
49
|
-
**Accessibility for a spreadsheet UI maps to the WAI-ARIA grid pattern.** W3C ARIA guidance explicitly calls out grids as suitable for spreadsheet-like applications and describes required keyboard interaction and focus-management properties (single tab stop into the grid, arrow navigation, home/end/page keys, selection expansion). This pushes architecture toward a single focusable grid surface with roving internal focus and an imperative interaction layer that coordinates selection, editing mode, and announcements.
|
|
50
|
-
|
|
51
|
-
**Clipboard integration is constrained by browser event APIs.** Clipboard operations flow through `copy/cut/paste` events, where `ClipboardEvent.clipboardData` exposes a `DataTransfer` object for reading/writing MIME-typed payloads. Consequently, spreadsheet clipboard boundaries must be defined in terms of `text/plain` and (optionally) `text/html` payloads, with strict sanitization and explicit “blocked/preserve-only” behavior when formats can’t be interpreted safely.
|
|
52
|
-
|
|
53
|
-
## Recommended design / decisions
|
|
54
|
-
|
|
55
|
-
**Adopt the DOCX editor’s hard boundary: runtime owns truth; React subscribes via an external-store interface.** Implement `SpreadsheetRuntime` as the single mutation authority and make the React component a projection and command dispatcher only, using the `subscribe/getSnapshot` pattern that React formalizes via `useSyncExternalStore`.
|
|
56
|
-
|
|
57
|
-
**Preserve the “two snapshots” discipline: render snapshot vs persisted snapshot.** Maintain (a) `RuntimeRenderSnapshot` for UI convenience and command enablement and (b) `PersistedWorkbookSnapshot` as the sole durable host artifact, mirroring the DOCX editor contract. This prevents React-friendly denormalizations (e.g., flattened visible cells) from becoming accidental persistence truth.
|
|
58
|
-
|
|
59
|
-
**Make OPC package preservation a first-class subsystem, not an import/export afterthought.** Treat import as “package → canonical workbook + preservation manifest + compatibility report,” and export as “canonical diffs → regenerate owned parts + reattach preserved parts + validate.” This directly mirrors the DOCX editor’s component boundary rules and explicit preservation subsystem.
|
|
60
|
-
|
|
61
|
-
**Define an explicit response model per feature region: preserve, lock, warn, block, fail.** Keep the DOCX editor’s taxonomy (`supported-roundtrip`, `preserve-only`, `unsupported-fatal`) as the underlying classification and expose it through UI surfaces and export gates. This yields predictable behavior: preserve-only content is retained and visible but non-editable; unsupported-fatal blocks export (or even blocks editing) with explicit reporting.
|
|
62
|
-
|
|
63
|
-
**Choose an imperative grid surface for performance and correctness, with React rendering only chrome and overlays.** Given Excel’s grid limits and ARIA grid keyboard requirements, the central grid should be driven by a framework-agnostic `GridSurfaceController` that handles scrolling, hit-testing, selection, editing mode, and clipboard, while React renders (a) the container layout, (b) sheet tabs, (c) formula bar/name box, (d) side panels, and (e) lightweight overlay layers.
|
|
64
|
-
|
|
65
|
-
**Virtualization must support variable row heights and column widths.** SpreadsheetML supports per-row and per-column sizing (and merges complicate layout), so implement bi-directional virtualization using prefix-sum structures (Fenwick tree / segment tree) for fast “pixel offset → row index” mapping and overscan. This is required to stay responsive as sheet sizes approach Excel’s limits and as users scroll rapidly.
|
|
66
|
-
|
|
67
|
-
**Treat calculation/calcChain as a compatibility boundary, not “just compute.”** Normatively, `calcChain` is at most one part and is a cache that can be rebuilt; practically, files may contain broken calcChain relationships, so import must tolerate those. Export policy should default to not maintaining `calcChain` (or regenerating only when fully correct) and instead rely on workbook calculation settings (e.g., `calcPr` flags) to force recalculation on open when your runtime cannot guarantee cached results; this must be labeled as observed Excel behavior and gated by tests.
|
|
68
|
-
|
|
69
|
-
**Merged cells must be enforced at the model and UI layers.** Canonical sheet state must encode merge regions as a sheet-level structure; editing and selection logic must map all cells in a merge to the merge’s anchor cell (top-left semantics) and block unsafe operations that would split a merge without explicit user intent.
|
|
70
|
-
|
|
71
|
-
**Comments and notes: be honest, pick a v1 authoring target, and preserve the rest.** Excel’s UX and semantics differ substantially between threaded comments and notes. If you cannot safely author both formats end-to-end, explicitly designate one as `supported-roundtrip` and the other as `preserve-only` with display/lock/warn behavior, plus a health panel explanation.
|
|
72
|
-
|
|
73
|
-
**Session capability derivation must be pure and runtime-driven.** Mirror the DOCX editor’s `deriveCapabilities()` approach: compute `SessionCapabilities` solely from the render snapshot + host props (permissions), and never let UI components invent capability state locally.
|
|
74
|
-
|
|
75
|
-
## Risks and open questions
|
|
76
|
-
|
|
77
|
-
**Formula correctness is the biggest “don’t lie” cliff.** Spreadsheet formulas include shared formulas, array formulas, data tables, and table formulas; even the Open XML types describe shared formula grouping semantics via `t="shared"` and `si` indices. If the runtime cannot (a) parse formulas, (b) update dependencies and references under structural edits, and (c) export without corrupting shared-formula groups, you must classify formula editing as preserve-only (or unsupported-fatal for certain constructs). The same applies to recalculation flags: turning on `fullCalcOnLoad` is a common pragmatic strategy, but it is not a substitute for correct reference rewriting.
|
|
78
|
-
|
|
79
|
-
**OPC/package preservation is easy to get subtly wrong.** Even small relationship or content type mistakes can trigger Excel “repair” prompts or silent removal of parts. OPC’s discovery model and MCE’s forward-compatibility constructs imply you will see unknown parts/markup routinely; designing preservation late will force destructive export logic.
|
|
80
|
-
|
|
81
|
-
**Comments format split is a product decision with long tail.** Excel’s own guidance frames threaded comments and notes as distinct features with different UI behaviors and capabilities. Supporting only one for authoring is defensible, but you must invest in first-class preserve-only UI, otherwise users will feel “content disappeared” even if it’s technically preserved.
|
|
82
|
-
|
|
83
|
-
**Large-grid performance failures will surface as UX correctness bugs.** With a 1,048,576 × 16,384 address space, selection, scrolling, and hit-testing must not be O(N) in row/col count, and React must not re-render the world on scroll. This is architectural: if you start with React-per-cell, you will end up rewriting the core renderer.
|
|
84
|
-
|
|
85
|
-
**Open questions that must be resolved before committing to v1 scope gates:**
|
|
86
|
-
- Which Excel feature set is “supported-roundtrip” vs “preserve-only” vs “unsupported-fatal” for import → edit → export → reopen? This must be codified as a capability matrix and enforced by validation + export gates.
|
|
87
|
-
- Do you require in-browser formula evaluation, or is “edit formulas + force recalc on open” acceptable for your product tier? If the latter, you must still correctly rewrite references under structural edits or block those edits.
|
|
88
|
-
- Which comment system is the authoring target? Threaded comments are the modern default in many Excel contexts, but notes have simpler semantics.
|
|
89
|
-
|
|
90
|
-
## Concrete deliverable in the requested format
|
|
91
|
-
|
|
92
|
-
This section is the repo-ready architecture specification for implementing the spreadsheet editor UX and runtime as **one embeddable React component** with a **runtime-owned canonical workbook state**, **command/transaction commits**, and **package-first OOXML preservation**.
|
|
93
|
-
|
|
94
|
-
### Rendering stack
|
|
95
|
-
|
|
96
|
-
**Goals:** keep the grid fast, keep React honest, keep accessibility tractable, and keep theming portable.
|
|
97
|
-
|
|
98
|
-
**Stack recommendation:**
|
|
99
|
-
- React shell: layout composition, panels, toolbar/formula bar, tabs, dialogs, theming provider.
|
|
100
|
-
- Imperative grid surface: one focusable “grid viewport” element implementing ARIA grid keyboard behavior (roving focus, editing mode) and managing virtualization/core interaction.
|
|
101
|
-
- Overlay layers: selection rectangle(s), active cell outline, range highlights, comment indicators, fill-handle, drag selection preview.
|
|
102
|
-
- Styling: CSS custom properties (tokens) scoped under the component root; optional shadow-root isolation in later phases (same overall approach as the DOCX editor frontend architecture).
|
|
103
|
-
|
|
104
|
-
### Directory structure
|
|
105
|
-
|
|
106
|
-
Mirror the DOCX editor’s module boundary discipline (api/model/core/io/preservation/validation/runtime/ui), but specialize “core” into spreadsheet domains (grid, formula, styles).
|
|
107
|
-
|
|
108
|
-
```text
|
|
109
|
-
src/
|
|
110
|
-
api/ # public contract types only (no runtime imports)
|
|
111
|
-
model/ # canonical workbook model + scalar types (JSON-serializable)
|
|
112
|
-
core/
|
|
113
|
-
commands/ # command handlers -> transactions
|
|
114
|
-
transactions/ # step types, mapping, commit invariants
|
|
115
|
-
selection/ # selection + anchor models (cell/range)
|
|
116
|
-
grid-math/ # A1 addressing, row/col index math, merge math
|
|
117
|
-
styles/ # style catalog + resolution
|
|
118
|
-
formulas/ # formula AST, reference rewriting, dependency graph (scoped)
|
|
119
|
-
io/
|
|
120
|
-
opc/ # package reader/writer (zip, [Content_Types], rels)
|
|
121
|
-
xlsx/ # SpreadsheetML parse/serialize (workbook, sheets, sst, styles)
|
|
122
|
-
normalize/ # translate OOXML -> canonical model + preservation capture
|
|
123
|
-
export/ # canonical model -> SpreadsheetML + package patch plan
|
|
124
|
-
preservation/
|
|
125
|
-
store/ # preserved parts, rels, unknown markup, fragment registry
|
|
126
|
-
mce/ # markup compatibility handling (mc:Ignorable etc) policy
|
|
127
|
-
validation/
|
|
128
|
-
compatibility/ # feature classifier + report builder
|
|
129
|
-
excel/ # Excel-focused structural checks + export gates
|
|
130
|
-
runtime/
|
|
131
|
-
spreadsheet-runtime.ts # orchestrator: load/import/export, commands, undo/redo
|
|
132
|
-
session-capabilities.ts # deriveCapabilities(snapshot, props)
|
|
133
|
-
scheduler.ts # yielding, staging, budgets
|
|
134
|
-
ui/
|
|
135
|
-
react/ # React shell components (tabs, bars, panels) no “truth”
|
|
136
|
-
headless/ # framework-agnostic interaction models (clipboard parsing, etc.)
|
|
137
|
-
grid-surface/ # imperative surface controller + adapters
|
|
138
|
-
grid-surface-controller.ts
|
|
139
|
-
virtualization.ts
|
|
140
|
-
dom-adapter.ts
|
|
141
|
-
aria-grid.ts
|
|
142
|
-
test/
|
|
143
|
-
fixtures/
|
|
144
|
-
xlsx/ # source Excel files (golden fixtures)
|
|
145
|
-
snapshots/ # persisted snapshots (golden JSON)
|
|
146
|
-
export/ # expected exported artifacts / normalization
|
|
147
|
-
harness/
|
|
148
|
-
excel-open-notes/ # manual reopen notes & screenshots (release gate evidence)
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Dependency rules should match DOCX boundaries: `src/api` imports nothing; `src/model` imports only `src/api`; `src/ui` must not import `src/io/preservation/validation`; only `runtime` orchestrates them.
|
|
152
|
-
|
|
153
|
-
### Component hierarchy
|
|
154
|
-
|
|
155
|
-
The React component hierarchy must not imply ownership of workbook truth; it should be “UI shell around runtime snapshots,” similar to the DOCX editor’s tailwind architecture composition.
|
|
156
|
-
|
|
157
|
-
```text
|
|
158
|
-
<SpreadsheetEditor /> (public component)
|
|
159
|
-
<EditorThemeRoot> (CSS vars + dark/high-contrast toggles)
|
|
160
|
-
<TopBar>
|
|
161
|
-
<NameBox /> (A1/name input; transient input state only)
|
|
162
|
-
<FormulaBar /> (transient text+IME state; commits via runtime)
|
|
163
|
-
<Toolbar /> (command dispatch only)
|
|
164
|
-
<MainArea>
|
|
165
|
-
<GridViewportShell>
|
|
166
|
-
<GridSurfaceHost /> (mount point for imperative GridSurfaceController)
|
|
167
|
-
<GridOverlays /> (React overlay render from snapshot+selection)
|
|
168
|
-
<RightRail> (optional)
|
|
169
|
-
<HealthPanel /> (preserve-only + blocked UI)
|
|
170
|
-
<CommentsPanel /> (notes/comments list; uses runtime projections)
|
|
171
|
-
<NameManagerPanel /> (optional; driven by runtime state)
|
|
172
|
-
<SheetTabs /> (sheet switching/rename/add; command dispatch)
|
|
173
|
-
<StatusBar /> (dirty/export blocked/latency budgets)
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### Data flow
|
|
177
|
-
|
|
178
|
-
**One-way control flow is mandatory:**
|
|
179
|
-
1) React inputs (keyboard/mouse/paste/UI controls) call runtime entry points.
|
|
180
|
-
2) Runtime executes command → builds transaction → commits → remaps anchors.
|
|
181
|
-
3) Runtime notifies subscribers (React) by publishing a new immutable render snapshot.
|
|
182
|
-
4) React re-renders chrome and overlays; the grid surface reconciles visible cells using the snapshot and its own transient viewport state.
|
|
183
|
-
|
|
184
|
-
Use the external store subscription pattern: `useSyncExternalStore(runtime.subscribe, runtime.getRenderSnapshot)`.
|
|
185
|
-
|
|
186
|
-
### Editing model
|
|
187
|
-
|
|
188
|
-
**Core principle:** spreadsheet editing is not rich text. The canonical modellable actions are **cell/range mutations** and **structural sheet mutations**, and they must be captured as transactional steps with remapping and undo/redo semantics.
|
|
189
|
-
|
|
190
|
-
**Editing states (runtime-owned where it matters):**
|
|
191
|
-
- `selection`: active cell + selection ranges + editing mode (`view` vs `edit`).
|
|
192
|
-
- `editBuffer` (transient): current in-progress cell editor text/IME composition; this may live in UI as transient, but the runtime must be the authority on when a buffer becomes a committed value/formula. (Same concept as “UI local state is transient,” used in the DOCX frontend architecture.)
|
|
193
|
-
- `gridViewport` (transient UI runtime): scroll offsets, overscan window; must not duplicate workbook state.
|
|
194
|
-
|
|
195
|
-
**Commit semantics:**
|
|
196
|
-
- Typing in the grid in “view mode” starts an editor buffer for the active cell; buffer is owned by a `CellEditorController` associated with the imperative surface, but commits exclusively via `runtime.dispatch(command)`.
|
|
197
|
-
- Enter commits and moves selection (down by default); Tab commits and moves right; Escape cancels buffer without state change.
|
|
198
|
-
- Formula bar editing uses the same buffer/commit path; it should not bypass grid editing rules.
|
|
199
|
-
|
|
200
|
-
### Command → transaction → commit architecture
|
|
201
|
-
|
|
202
|
-
Mirror the DOCX runtime’s “every mutating entry point routes through command → transaction → mapping → remap → commit → notify” rule, but adapt mapping to grid coordinates and sheet topology.
|
|
203
|
-
|
|
204
|
-
#### Public runtime signatures (sketch)
|
|
205
|
-
|
|
206
|
-
```ts
|
|
207
|
-
export interface SpreadsheetEditorProps {
|
|
208
|
-
workbookId: string;
|
|
209
|
-
currentUser?: { userId: string; displayName: string };
|
|
210
|
-
|
|
211
|
-
initialXlsx?: Uint8Array | ArrayBuffer;
|
|
212
|
-
initialSnapshot?: PersistedWorkbookSnapshot;
|
|
213
|
-
|
|
214
|
-
readOnly?: boolean;
|
|
215
|
-
|
|
216
|
-
onEvent?: (e: SpreadsheetEditorEvent) => void;
|
|
217
|
-
onWarning?: (w: EditorWarning) => void;
|
|
218
|
-
onError?: (err: EditorError) => void;
|
|
219
|
-
|
|
220
|
-
theme?: Partial<SpreadsheetThemeTokens>;
|
|
221
|
-
colorScheme?: "light" | "dark" | "system";
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export interface SpreadsheetEditorRef {
|
|
225
|
-
focusGrid(): void;
|
|
226
|
-
|
|
227
|
-
undo(): void;
|
|
228
|
-
redo(): void;
|
|
229
|
-
|
|
230
|
-
exportXlsx(options?: ExportXlsxOptions): Promise<ExportResult>;
|
|
231
|
-
getSnapshot(): PersistedWorkbookSnapshot;
|
|
232
|
-
|
|
233
|
-
getCompatibilityReport(): CompatibilityReport;
|
|
234
|
-
getWarnings(): EditorWarning[];
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
This intentionally matches the DOCX contract style: uncontrolled by default, replace-on-change allowed only as full runtime reload; persisted snapshot is host artifact; render snapshot is internal.
|
|
239
|
-
|
|
240
|
-
#### Canonical transaction step types (minimum viable)
|
|
241
|
-
|
|
242
|
-
Transactions must be deterministic and must carry a **mapping** that can remap:
|
|
243
|
-
- selection anchors (cell/range),
|
|
244
|
-
- comments anchors (cell/range),
|
|
245
|
-
- preservation bindings (parts tied to a sheet/range),
|
|
246
|
-
- named ranges (if you support authoring them).
|
|
247
|
-
|
|
248
|
-
```ts
|
|
249
|
-
type SheetId = string;
|
|
250
|
-
|
|
251
|
-
type GridCoord = { row: number; col: number }; // 1-based (Excel semantics)
|
|
252
|
-
type GridRef = { sheetId: SheetId; at: GridCoord };
|
|
253
|
-
type GridRange = { sheetId: SheetId; from: GridCoord; to: GridCoord };
|
|
254
|
-
|
|
255
|
-
type TransactionStep =
|
|
256
|
-
| { type: "cell.setValue"; ref: GridRef; value: CellValue }
|
|
257
|
-
| { type: "cell.setFormula"; ref: GridRef; formula: FormulaText; cachedValue?: CellValue }
|
|
258
|
-
| { type: "cell.setStyle"; range: GridRange; xfId: number } // style index into style catalog
|
|
259
|
-
| { type: "sheet.insertRows"; sheetId: SheetId; atRow: number; count: number }
|
|
260
|
-
| { type: "sheet.deleteRows"; sheetId: SheetId; atRow: number; count: number }
|
|
261
|
-
| { type: "sheet.insertCols"; sheetId: SheetId; atCol: number; count: number }
|
|
262
|
-
| { type: "sheet.deleteCols"; sheetId: SheetId; atCol: number; count: number }
|
|
263
|
-
| { type: "range.move"; from: GridRange; toTopLeft: GridCoord; mode: "move" | "copy" }
|
|
264
|
-
| { type: "merge.add"; sheetId: SheetId; ref: GridRange }
|
|
265
|
-
| { type: "merge.remove"; sheetId: SheetId; ref: GridRange };
|
|
266
|
-
|
|
267
|
-
type GridMapping = {
|
|
268
|
-
mapSheetId?(sheetId: SheetId): SheetId; // for sheet reorder/id changes if needed
|
|
269
|
-
mapCoord(sheetId: SheetId, coord: GridCoord): GridCoord | "detached";
|
|
270
|
-
mapRange(sheetId: SheetId, range: GridRange): GridRange | "detached";
|
|
271
|
-
};
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
**Key invariant:** commit must remap anchors before notifying subscribers (same as DOCX). Detached anchors must not be silently deleted; they become inspectable “detached” anchors tied to a warning entry.
|
|
275
|
-
|
|
276
|
-
### Selection and decoration model
|
|
277
|
-
|
|
278
|
-
Selection must match spreadsheet expectations and ARIA grid navigation semantics.
|
|
279
|
-
|
|
280
|
-
**Selection model (runtime-owned):**
|
|
281
|
-
- `activeCell`: exactly one cell (sheetId + row/col).
|
|
282
|
-
- `selectionRanges`: 1+ rectangular ranges (start with one; multi-range optional).
|
|
283
|
-
- `mode`: `"view"` | `"edit"` | `"formulaRefPick"` (when editing formula and selecting ranges to insert references).
|
|
284
|
-
- `viewportFocus`: last focused region (`grid`, `formulaBar`, `nameBox`, `sheetTabs`, `rail`). This is *UI transient* but should be fed into keyboard routing.
|
|
285
|
-
|
|
286
|
-
**Decoration sources:**
|
|
287
|
-
- merge highlights (range boxes),
|
|
288
|
-
- referenced range highlights (during formula edit),
|
|
289
|
-
- error/warning cell markers (compatibility/preservation),
|
|
290
|
-
- comment/note indicators, with hover overlays,
|
|
291
|
-
- selection border, fill handle, active cell outline.
|
|
292
|
-
|
|
293
|
-
**Implementation rule:** decorations must be computed from runtime state and remapped through transactions, not cached as per-cell arrays in React. (This mirrors the DOCX “decorations computed from anchor overlap” model.)
|
|
294
|
-
|
|
295
|
-
### Viewport virtualization and overscan strategy
|
|
296
|
-
|
|
297
|
-
Excel’s sheet size makes virtualization mandatory.
|
|
298
|
-
|
|
299
|
-
**Core strategy:**
|
|
300
|
-
- Maintain row height and column width models as compact structures:
|
|
301
|
-
- defaults + sparse overrides for changed rows/cols.
|
|
302
|
-
- Use prefix-sum trees for fast conversions:
|
|
303
|
-
- `pixelY -> rowIndex`, `rowIndex -> pixelY`,
|
|
304
|
-
- `pixelX -> colIndex`, `colIndex -> pixelX`.
|
|
305
|
-
- Virtualize both axes:
|
|
306
|
-
- compute visible row/col window from scroll offsets,
|
|
307
|
-
- apply overscan (e.g., +4 rows above/below, +2 cols left/right) tuned for wheel/trackpad.
|
|
308
|
-
- Render only:
|
|
309
|
-
- visible cell rectangles in the viewport,
|
|
310
|
-
- visible row headers and column headers,
|
|
311
|
-
- visible merged-cell “top-left” cells as single layout objects spanning multiple rows/cols.
|
|
312
|
-
|
|
313
|
-
**Overscan policy (implementation-ready default):**
|
|
314
|
-
- Base overscan on scroll velocity:
|
|
315
|
-
- slow scroll: `overscanRows=4`, `overscanCols=2`,
|
|
316
|
-
- fast scroll (velocity threshold): `overscanRows=20`, `overscanCols=8`,
|
|
317
|
-
- during inertial scroll: pause expensive recalculation (styles, text metrics) until settle, but keep selection rendering correct.
|
|
318
|
-
|
|
319
|
-
### Sheet tabs
|
|
320
|
-
|
|
321
|
-
Sheet tabs are a structural surface: changing sheet order/name must go through commands and must update workbook-level registries (defined names scope, styles references, etc.). SpreadsheetML stores each worksheet as a separate part referenced by the workbook; the runtime must treat sheets as first-class objects with stable IDs.
|
|
322
|
-
|
|
323
|
-
**Tab operations (commands):**
|
|
324
|
-
- activate sheet,
|
|
325
|
-
- add sheet,
|
|
326
|
-
- rename sheet,
|
|
327
|
-
- reorder sheets,
|
|
328
|
-
- delete sheet (must be gated: if sheet has preserve-only content tied to it, deletion is destructive and must warn/block).
|
|
329
|
-
|
|
330
|
-
### Formula bar and name box
|
|
331
|
-
|
|
332
|
-
**Formula bar (recommended):** This is essential for Excel-like workflows: it provides a stable edit surface for long formulas and prevents “edit-in-cell only” UX traps.
|
|
333
|
-
|
|
334
|
-
**Name box (recommended):** It supports jumping to A1 references and using defined names; Microsoft’s guidance explicitly describes naming and navigating using the Name Box for defined names.
|
|
335
|
-
|
|
336
|
-
**Architecture rule:** both inputs maintain only transient text state; commit happens via runtime commands:
|
|
337
|
-
- `selection.setActiveCell` (jump),
|
|
338
|
-
- `name.define` / `name.rename` (if supported),
|
|
339
|
-
- `cell.commitFormulaOrValue`.
|
|
340
|
-
|
|
341
|
-
### Active-cell renderer and range highlight model
|
|
342
|
-
|
|
343
|
-
**Active cell** is an overlay box with:
|
|
344
|
-
- focus outline (high-contrast safe),
|
|
345
|
-
- fill handle (optional v1; if unsupported, hide rather than fake).
|
|
346
|
-
|
|
347
|
-
**Range highlights** (especially for formula reference picking) must:
|
|
348
|
-
- render multiple colored range outlines,
|
|
349
|
-
- be non-color dependent for accessibility (e.g., dashed vs solid patterns), aligning with ARIA grid expectations that focus and selection are perceivable.
|
|
350
|
-
|
|
351
|
-
### Row/column header behavior
|
|
352
|
-
|
|
353
|
-
Row/column headers are their own interactive surfaces:
|
|
354
|
-
- click row header selects the row range,
|
|
355
|
-
- click column header selects the column range,
|
|
356
|
-
- drag resize modifies row height/column width via commands.
|
|
357
|
-
|
|
358
|
-
Keyboard shortcuts like “select row/column” are part of ARIA grid guidance and spreadsheet expectation; implement them in the grid surface controller, not as ad hoc React key handlers.
|
|
359
|
-
|
|
360
|
-
### Merged-cell rendering
|
|
361
|
-
|
|
362
|
-
Merged cells are not just a view concern:
|
|
363
|
-
- hit-testing any cell inside a merge maps to the merge anchor cell,
|
|
364
|
-
- editing is allowed only through the anchor cell,
|
|
365
|
-
- splitting merges must be an explicit command.
|
|
366
|
-
|
|
367
|
-
OOXML semantics explicitly state merged ranges are expressed in `mergeCells` and that formatting/content is stored in the top-left cell.
|
|
368
|
-
|
|
369
|
-
### Comments/notes overlays
|
|
370
|
-
|
|
371
|
-
Excel distinguishes threaded comments and notes in user-facing behavior. To avoid lying, implement **one authoring surface** first (recommended: Notes as simpler annotation semantics), and treat the other as preserve-only:
|
|
372
|
-
- preserve underlying parts,
|
|
373
|
-
- render an indicator in the grid,
|
|
374
|
-
- allow viewing (read-only),
|
|
375
|
-
- lock editing with a clear warning.
|
|
376
|
-
|
|
377
|
-
### Health panel for preserve-only and blocked states
|
|
378
|
-
|
|
379
|
-
The right rail must include a **Health** panel (same conceptual surface as the DOCX editor) that lists:
|
|
380
|
-
- `preserve-only` features encountered (with affected sheet/range anchors),
|
|
381
|
-
- `unsupported-fatal` blockers,
|
|
382
|
-
- warnings that explain why certain regions are locked.
|
|
383
|
-
|
|
384
|
-
This panel must drive user trust: it is where “preserved, locked, warned, export blocked” becomes explicit and auditable.
|
|
385
|
-
|
|
386
|
-
### Performance implications of very large grids
|
|
387
|
-
|
|
388
|
-
**Hard constraints:** Excel’s sheet size is enormous; you cannot render or store dense grids.
|
|
389
|
-
|
|
390
|
-
**Performance budgets (v1 defaults you can enforce in CI):**
|
|
391
|
-
- scroll frame budget: <16ms for overlay-only updates,
|
|
392
|
-
- selection movement: <30ms p95,
|
|
393
|
-
- paste of 10k cells: staged, cancelable, with progress UI,
|
|
394
|
-
- initial import: staged with yielding and progressive sheet availability (open workbook quickly, lazy-load sheet XML as user selects tabs).
|
|
395
|
-
|
|
396
|
-
### Clipboard/paste UI boundaries
|
|
397
|
-
|
|
398
|
-
Clipboard integration must be implemented at the grid surface layer using `copy/cut/paste` events and `ClipboardEvent.clipboardData` / `DataTransfer`.
|
|
399
|
-
|
|
400
|
-
**Supported clipboard formats (v1):**
|
|
401
|
-
- Export on copy:
|
|
402
|
-
- `text/plain`: TSV with `\t` and `\n`,
|
|
403
|
-
- optional `text/html`: `<table>` representation for richer interop (only if you can safely generate and parse).
|
|
404
|
-
- Import on paste:
|
|
405
|
-
- prefer `text/html` table when present and trusted,
|
|
406
|
-
- fallback to `text/plain` TSV.
|
|
407
|
-
|
|
408
|
-
**Explicit boundaries:**
|
|
409
|
-
- If pasted payload implies constructs you cannot represent (e.g., embedded objects, images, rich cell formatting), either:
|
|
410
|
-
- paste values only and warn, or
|
|
411
|
-
- block paste with a clear explanation (depending on host policy).
|
|
412
|
-
|
|
413
|
-
### Dark mode/high contrast rules for grid-heavy interfaces
|
|
414
|
-
|
|
415
|
-
Use token-based theming (CSS variables) scoped at the editor root with `.dark` and `data-high-contrast` toggles, following the DOCX editor’s portable theme approach.
|
|
416
|
-
|
|
417
|
-
Grid-heavy special rules:
|
|
418
|
-
- selection and active-cell indicators must not rely on color alone:
|
|
419
|
-
- use border styles, thickness, and patterns.
|
|
420
|
-
- comment indicators must remain visible in dark mode and high contrast, with a non-color cue (corner notch + tooltip).
|
|
421
|
-
|
|
422
|
-
### Review / trust surfaces
|
|
423
|
-
|
|
424
|
-
Trust surfaces are not optional:
|
|
425
|
-
- status bar always shows:
|
|
426
|
-
- dirty state,
|
|
427
|
-
- export blocked/not blocked,
|
|
428
|
-
- preserve-only count,
|
|
429
|
-
- last validation timestamp.
|
|
430
|
-
- Health panel and inline lock cards:
|
|
431
|
-
- “Preserved for Excel round-trip”
|
|
432
|
-
- “Editing blocked: unsupported feature”
|
|
433
|
-
- Export modal:
|
|
434
|
-
- shows compatibility report summary and explicit risk state before producing bytes.
|
|
435
|
-
|
|
436
|
-
### Accessibility
|
|
437
|
-
|
|
438
|
-
Implement a single tabbable grid root with internal roving focus and keyboard navigation per the W3C grid pattern guidance.
|
|
439
|
-
|
|
440
|
-
Minimum required behavior:
|
|
441
|
-
- one tab stop into the grid, arrow navigation across cells,
|
|
442
|
-
- Home/End and Page keys per grid guidance,
|
|
443
|
-
- Enter/F2 toggles “actionable/edit mode” inside a cell editor,
|
|
444
|
-
- screen-reader announcements for active cell address, value/formula, and selection changes (use `aria-live` politely throttled).
|
|
445
|
-
|
|
446
|
-
### Responsive behavior
|
|
447
|
-
|
|
448
|
-
Follow the proven pattern from the DOCX editor shell:
|
|
449
|
-
- below a width threshold, collapse the right rail into a toggle,
|
|
450
|
-
- keep sheet tabs horizontally scrollable,
|
|
451
|
-
- keep formula bar compact with an “expand” affordance.
|
|
452
|
-
|
|
453
|
-
### Public API alignment
|
|
454
|
-
|
|
455
|
-
Align with the DOCX component’s principles: single component entry, typed props + ref, persisted snapshot as the only durable state artifact, and an event stream for telemetry and host workflows.
|
|
456
|
-
|
|
457
|
-
### Migration path if replacing an older implementation
|
|
458
|
-
|
|
459
|
-
Adopt the DOCX editor’s migration playbook:
|
|
460
|
-
- dual implementation period behind a host switch,
|
|
461
|
-
- same public API surface while swapping internal renderer/runtime,
|
|
462
|
-
- deprecate legacy entry point only after fixture + reopen gates pass.
|
|
463
|
-
|
|
464
|
-
For product honesty, track maturity levels using a component cutover matrix style (inventoried → contract-frozen → repo-landed → baseline-proved → …) and require proof artifacts for each promotion.
|
|
465
|
-
|
|
466
|
-
### Session capability model
|
|
467
|
-
|
|
468
|
-
Implement `deriveCapabilities(renderSnapshot, props)` as a pure function, matching the DOCX editor’s approach.
|
|
469
|
-
|
|
470
|
-
```ts
|
|
471
|
-
export interface SessionCapabilities {
|
|
472
|
-
phase: "loading" | "ready" | "diagnostics" | "error";
|
|
473
|
-
canEdit: boolean;
|
|
474
|
-
canUndo: boolean;
|
|
475
|
-
canRedo: boolean;
|
|
476
|
-
|
|
477
|
-
canCopy: boolean;
|
|
478
|
-
canPaste: boolean;
|
|
479
|
-
|
|
480
|
-
canEditFormulas: boolean; // false if formula support is preserve-only
|
|
481
|
-
canExport: boolean; // false if export blocked
|
|
482
|
-
exportBlocked: boolean;
|
|
483
|
-
|
|
484
|
-
preserveOnlyCount: number;
|
|
485
|
-
unsupportedFatalCount: number;
|
|
486
|
-
}
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
### Spreadsheet-specific capability classification (v1 recommendation)
|
|
490
|
-
|
|
491
|
-
Use three classes for machine-enforced honesty.
|
|
492
|
-
|
|
493
|
-
- **supported-roundtrip:** features the runtime can import, edit safely, export, and reopen without repair prompts (must be proven with fixtures + Excel reopen gates).
|
|
494
|
-
- **preserve-only:** features preserved as opaque parts/markup with display/lock/warn; no attempted semantic rewrite.
|
|
495
|
-
- **unsupported-fatal:** features that block export (and possibly block editing) because safe round-trip cannot be guaranteed.
|
|
496
|
-
|
|
497
|
-
Concrete v1 suggestions grounded in available spec evidence:
|
|
498
|
-
- `calcChain`: treat as non-essential cache; tolerate missing/inconsistent parts and prefer not maintaining it.
|
|
499
|
-
- merges: can be supported-roundtrip if you implement correct top-left semantics.
|
|
500
|
-
- styles: support a conservative subset and preserve unknown `extLst` and style entries; this is feasible because styles are centralized in the Styles part.
|
|
501
|
-
- threaded comments vs notes: pick one authoring target; preserve the other.
|
|
502
|
-
|
|
503
|
-
### Test matrix, fixture plan, and release gates
|
|
504
|
-
|
|
505
|
-
**You cannot claim Excel compatibility without fixture-driven proof.** The DOCX editor’s plan explicitly ties maturity promotions to fixture proof and validator runs; reuse that discipline.
|
|
506
|
-
|
|
507
|
-
**Core fixture classes (minimum):**
|
|
508
|
-
- **P00 package integrity:** `[Content_Types].xml` + rels traversal, unknown parts preserved, relationship round-trip.
|
|
509
|
-
- **S00 shared strings:** import/export shared strings and rich text in shared strings if present.
|
|
510
|
-
- **ST00 styles:** style catalog preservation + a supported subset applied to cells.
|
|
511
|
-
- **M00 merges:** merged ranges render/edit/export correctly (top-left semantics).
|
|
512
|
-
- **C00 calculation:** formulas present + calc settings; calcChain tolerated or omitted; reopen behavior documented.
|
|
513
|
-
- **CM00 comments:** notes and threaded comments present; whichever is preserve-only is verified as preserved and not rewritten.
|
|
514
|
-
- **LG00 large grid:** synthetic workbook near Excel limits (sparse) to validate virtualization and performance budgets.
|
|
515
|
-
|
|
516
|
-
**Release gates (hard, not aspirational):**
|
|
517
|
-
- Automated:
|
|
518
|
-
- package integrity validation (relationships resolvable; content types consistent),
|
|
519
|
-
- deterministic persisted snapshot serialization (stable ordering),
|
|
520
|
-
- command/transaction invariants (no UI mutation, remap always before notify),
|
|
521
|
-
- performance smoke for scrolling and paste.
|
|
522
|
-
- Semi-automated:
|
|
523
|
-
- Open XML SDK-based structural validation in CI (used as validator, not shipped), mirroring the DOCX “validator service” approach.
|
|
524
|
-
- Manual:
|
|
525
|
-
- reopen in current Excel desktop and Excel web for every release-gate fixture; record “no repair prompt / no silent supported-content loss” notes per fixture. (This mirrors the DOCX project’s explicit manual Word certification gates.)
|
|
526
|
-
|
|
527
|
-
## Sources
|
|
528
|
-
|
|
529
|
-
The existing DOCX editor repository provides the architectural baseline for runtime/UI separation, command→transaction discipline, preservation boundaries, capability derivation, and migration patterns, including the frozen runtime contract and component boundary rules.
|
|
530
|
-
|
|
531
|
-
Normative/primary packaging and compatibility grounding comes from OPC and markup compatibility descriptions and references to ISO/IEC 29500 and ECMA-376, including the ECMA-376 standard landing page and the Library of Congress format descriptions for OPC and MCE/OOXML.
|
|
532
|
-
|
|
533
|
-
SpreadsheetML structural and element semantics are supported by Microsoft’s Open XML documentation and Open XML SDK API references, including shared strings, workbook/sheet structure, styles part semantics, merged cells, and calculation chain/calcPr properties.
|
|
534
|
-
|
|
535
|
-
Observed Excel behavior and practical export strategies for recalculation settings are referenced separately from normative rules, using public discussions and SDK attribute documentation (explicitly treated as “observed behavior,” not standard text).
|
|
536
|
-
|
|
537
|
-
Accessibility and platform constraints are grounded in W3C ARIA grid guidance, React’s external store subscription API, and MDN clipboard event documentation.
|