feat: add spellCheck support to the editor#950
Conversation
The editor did not enable the browser-native spellchecker - no spellcheck attribute was set on the ProseMirror editable surface. Add a spellCheck prop (default true) that sets spellcheck on the body editable surface and keeps it in sync on change. React threads it through DocxEditor -> DocxEditorPagedArea -> PagedEditor -> HiddenProseMirror (mirroring readOnly); Vue exposes it via a useDocxEditor option and the DocxEditor.vue prop. Body editable only; header and footer chrome are untouched. Includes the parity-contract entry, regenerated API snapshots, and a changeset. Closes eigenpal#32
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ Posted by the CLA bot. |
Greptile SummaryAdds a
Confidence Score: 4/5Safe to merge; the change is additive with a sensible default and cannot break existing behaviour. Both React and Vue paths correctly seed the attribute at view construction and keep it live on prop changes. The only gap is the test suite, which only verifies the initial-render state and would not catch a regression in the dynamic prop-change effect. packages/react/src/components/DocxEditor/spellcheck.test.tsx — would benefit from a rerender test covering the prop-change effect path.
|
| Filename | Overview |
|---|---|
| packages/react/src/components/DocxEditor/HiddenProseMirror.tsx | Adds spellCheck prop: seeds the attribute in the ProseMirror attributes config at construction and keeps it in sync via a useEffect; pattern mirrors readOnly correctly. |
| packages/react/src/components/DocxEditor/spellcheck.test.tsx | Tests the static initial-render cases; missing a rerender test for the dynamic prop-change effect path. |
| packages/vue/src/composables/useDocxEditor.ts | Adds spellCheck as MaybeRef; seeds it in EditorView attributes and tracks changes via watch([() => unref(spellCheck), editorView]), matching the readOnly watcher pattern. |
| packages/vue/src/components/DocxEditor.vue | Adds spellCheck prop with withDefaults default of true; threads it into useDocxEditor as a computed ref, consistent with how readOnly is wired. |
| packages/react/src/components/DocxEditor.tsx | Adds spellCheck prop (default true) and threads it down through DocxEditorPagedArea, mirroring the readOnly propagation chain. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph React
A["DocxEditor\n(spellCheck prop, default true)"] --> B["DocxEditorPagedArea\n(spellCheck: boolean)"]
B --> C["PagedEditor\n(spellCheck?: boolean)"]
C --> D["HiddenProseMirror\n(attributes seed + useEffect sync)"]
end
subgraph Vue
E["DocxEditor.vue\n(withDefaults spellCheck: true)"] --> F["useDocxEditor()\nspellCheck: computed(() => props.spellCheck)"]
F --> G["new EditorView\n(attributes seed at construction)"]
F --> H["watch([unref(spellCheck), editorView])\nDOM setAttribute on change"]
end
D --> Z["view.dom spellcheck attr"]
G --> Z
H --> Z
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
subgraph React
A["DocxEditor\n(spellCheck prop, default true)"] --> B["DocxEditorPagedArea\n(spellCheck: boolean)"]
B --> C["PagedEditor\n(spellCheck?: boolean)"]
C --> D["HiddenProseMirror\n(attributes seed + useEffect sync)"]
end
subgraph Vue
E["DocxEditor.vue\n(withDefaults spellCheck: true)"] --> F["useDocxEditor()\nspellCheck: computed(() => props.spellCheck)"]
F --> G["new EditorView\n(attributes seed at construction)"]
F --> H["watch([unref(spellCheck), editorView])\nDOM setAttribute on change"]
end
D --> Z["view.dom spellcheck attr"]
G --> Z
H --> Z
Reviews (1): Last reviewed commit: "feat: add spellCheck support to the edit..." | Re-trigger Greptile
| describe('HiddenProseMirror spellcheck', () => { | ||
| test('enables the browser-native spellchecker by default', () => { | ||
| const dom = renderEditor({}); | ||
| expect(dom.getAttribute('spellcheck')).toBe('true'); | ||
| }); | ||
|
|
||
| test('disables the spellchecker when spellCheck is false', () => { | ||
| const dom = renderEditor({ spellCheck: false }); | ||
| expect(dom.getAttribute('spellcheck')).toBe('false'); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Missing test for dynamic prop-change
The suite only checks the attribute at initial render; the useEffect(() => { view.dom.setAttribute(...) }, [spellCheck]) path — which is the one that actually matters when a host app toggles the prop at runtime — is never exercised. If that effect were accidentally removed or had a stale closure, both static tests would still pass. A third test that renders with spellCheck={true}, then re-renders with spellCheck={false} (via rerender from RTL) and re-reads dom.getAttribute('spellcheck') would cover the dynamic case.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
I have read the CLA Document and I hereby sign the CLA |
|
!cla-check |
|
Hey @youdie006 Could you attach a short screen recording or screenshot showing the spellcheck actually rendering on the page? The wiring looks correct (prop threaded through both adapters, defaults right, parity contract + API snapshots updated, typecheck/test/parity all green), but I want to confirm the feature is visible to the user before merging. The |
Summary
The editor did not enable the browser-native spellchecker — no
spellcheckattribute was set on the ProseMirror editable surface (#32).Fix
Add a
spellCheckprop (defaulttrue) that setsspellcheckon the body editable surface and keeps it in sync on change.DocxEditor→DocxEditorPagedArea→PagedEditor→HiddenProseMirror, mirroring howreadOnlyflows.spellCheckoption onuseDocxEditor(with awithDefaultsdefault) and the public prop onDocxEditor.vue.Includes the parity-contract entry, regenerated API snapshots, and a changeset. Verified in both the React and Vue demos — the body editable shows
spellcheck="true", header/footer unaffected.Closes #32
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.