Skip to content

Latest commit

 

History

History
121 lines (78 loc) · 5.72 KB

File metadata and controls

121 lines (78 loc) · 5.72 KB

Contributing to @eigenpal/docx-editor-react

Thanks for your interest in contributing! This guide will help you get started.

Prerequisites

Development Setup

# Clone the repo
git clone https://github.com/eigenpal/docx-editor.git
cd docx-editor

# Install dependencies
bun install

# Start the dev server
bun run dev
# Open http://localhost:5173

Working on the parser, serializer, or layout engine? bun run reference:fetch pulls the gitignored ECMA-376 PDFs and supplementary ZIPs (~58 MB). The handwritten quick-refs and XSD schemas under reference/ stay committed.

Running Tests

# Type checking (fast, run often)
bun run typecheck

# Unit tests
bun test

# E2E tests (requires Playwright browsers)
npx playwright install --with-deps chromium
npx playwright test --timeout=30000 --workers=4

# Single test file
npx playwright test e2e/tests/formatting.spec.ts --timeout=30000

Code Style

The project uses ESLint and Prettier with pre-commit hooks (Husky + lint-staged), so formatting is handled automatically on commit.

# Manual lint/format
bun run lint:fix
bun run format

Contributor License Agreement

Contributors are required to sign our Contributor License Agreement. The CLA assistant will leave a comment on your first pull request with signing instructions — one short comment, about 30 seconds. That signature covers all of your future contributions.

Making Changes

  1. Fork the repository and create a branch from main
  2. Read the code before modifying it — understand the dual rendering system (see Architecture)
  3. Make your changes — keep them focused and minimal
  4. Add/update tests for your changes (see e2e/ for E2E tests)
  5. Verify everything works:
    bun run typecheck && bun test && bun run build:packages
  6. Submit a PR against main — the CLA bot will prompt you on your first one

Architecture Overview

The editor has two rendering systems:

  • Hidden ProseMirror — the real editing state (selection, undo/redo, keyboard input)
  • Visible Pages (layout-painter) — what the user sees, rebuilt from PM state on every change

See docs/ARCHITECTURE.md for the full architecture and CLAUDE.md for the agent-facing quick reference (also useful for humans).

Public API Surface

Every published package's @public exports are locked in docs/api/<pkg-slug>/<entry>.api.md snapshots generated by API Extractor. CI runs bun run api:check and fails on undocumented drift.

If you change a @public symbol — or add a new one — regenerate and commit the snapshot:

bun run --filter '@eigenpal/docx-editor-<pkg>' build
bun run api:extract
git add docs/api/<pkg-slug>/

The CI error message points at the source file for each drifted entry, so the fix is mechanical. Full details live in CLAUDE.md under "Public API surface".

Adding a DocxEditorProps field or DocxEditorRef method to either adapter also requires updating scripts/parity/parity.contract.json — the cross-adapter parity contract that tracks which fields are shared, deliberately Vue-deferred, or Vue-exclusive. bun run check:parity-contract (also run in CI) fails until the contract acknowledges the new symbol. The error message names the symbol and tells you which bucket to add it to.

Adding a new Vue composable: declare a Use<Name>Return interface and annotate the function's return type with it. Without the annotation the snapshot recursively inlines core's internal types into Vue's public surface.

Adding a new published package: edit scripts/lib/packages.mjs (one entry — name, root, slug, tsconfig, build hint). Add matching api:extract / api:check scripts in the new package's package.json delegating to ../../scripts/api-extractor.mjs --package <name>. Then run bun run api:extract && bun run docs:json to generate snapshots.

Consumer-facing JSON docs (docs/json/)

The same @public surface is also emitted as structured JSON for downstream docs sites: bun run docs:json writes docs/json/<pkg-slug>/<subpath>.json per published subpath, plus a root docs/json/index.json. The JSON is gitignored — downstream sites (e.g. docx-editor-page) clone the repo and run the script themselves. CI runs bun run docs:json as a smoke test so generator breakage surfaces in this repo, not in the consumer's build.

Adapter Parity

The editor ships first-party adapters for React (packages/react) and Vue (packages/vue). Both share @eigenpal/docx-editor-core, which owns the parser, ProseMirror schema, layout engine, layout bridge (page mapping, footnote convergence, header/footer measurement), and serializer. Adapters only own their framework-specific shell, components, and lifecycle wiring.

When you touch layout, parsing, or rendering logic, put it in core, not in an adapter. If you copy a 30-line helper from React to Vue, you've created a divergence trap. The footnote convergence loop (stabilizeFootnoteLayout in packages/core/src/layout-bridge/footnoteLayout.ts) is the canonical example: one helper, both adapters call it.

Parity smoke tests live under e2e/tests/parity/smoke/ and run each spec against both demos. Add one when you fix a bug that could plausibly affect rendering on either side.

Reporting Bugs

Open an issue at github.com/eigenpal/docx-editor/issues with:

  • Steps to reproduce
  • Expected vs actual behavior
  • Attach a .docx file if relevant (remove sensitive content first)

License

By contributing, you agree that your contributions will be licensed under the MIT License.