Skip to content

fix(core): scoped .ep-root preflight reset for hosts without their own#1024

Open
jacobjove wants to merge 1 commit into
eigenpal:mainfrom
jacobjove:feat/scoped-preflight-reset
Open

fix(core): scoped .ep-root preflight reset for hosts without their own#1024
jacobjove wants to merge 1 commit into
eigenpal:mainfrom
jacobjove:feat/scoped-preflight-reset

Conversation

@jacobjove

@jacobjove jacobjove commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Split out of #790 as a standalone bug fix.

The library ships @tailwind utilities only (no preflight) by design, so it never resets a host app's styles. But in a host that supplies no reset of its own (e.g. a bare VS Code webview), nothing reproduced the button-relevant subset for the editor's own controls, so: Tailwind width-only border utilities rendered nothing (border-style defaults to none, so picker borders and toolbar dividers vanished), and <button>s inherited user-agent chrome with no pointer cursor.

This reproduces just that subset, scoped to .ep-root (universal border-style reset + button chrome/cursor neutralization), so it fixes the editor's controls without touching the host's styles. Documented in CLAUDE.md; changeset included.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

The library ships @tailwind utilities only (no preflight) so it never resets a host app's styles. In a host that supplies no reset of its own (e.g. a bare VS Code webview), Tailwind width-only border utilities rendered nothing (border-style defaults to none, so picker borders + toolbar dividers vanished) and buttons inherited user-agent chrome with no pointer cursor. Reproduce just the button-relevant subset, scoped to .ep-root, so it fixes the editor's own controls without touching the host's styles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docx-editor Ready Ready Preview, Comment Jun 24, 2026 4:24pm

Request Review

@eigenpal-release-pal

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅

Posted by the CLA bot.

@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a minimal scoped preflight subset to packages/core/src/styles/editor.css to fix two rendering failures in host apps that ship no CSS reset (e.g. bare VS Code webviews): invisible borders on Tailwind width-only utilities and UA button chrome leaking through ghost/borderless buttons. It also documents the full set of preflight-absence consequences in CLAUDE.md.

  • Border reset (border-width: 0; border-style: solid; border-color: currentColor on .ep-root * and pseudo-elements) mirrors Tailwind preflight's universal rule, scoped to .ep-root so host styles are untouched; later Tailwind utility classes and inline painter styles retain specificity priority.
  • Button reset (.ep-root button / .ep-root button:disabled) neutralises UA chrome and restores pointer cursor; the cursor-not-allowed utility override claim in the comment is incorrect — see the inline finding for specifics.
  • Changeset correctly targets @eigenpal/docx-editor-core at patch level with a consumer-facing summary.

Confidence Score: 3/5

The border reset and button chrome fix are sound and well-scoped; the one concrete defect is that the disabled-button cursor override promised in both the CSS comment and CLAUDE.md will silently fail for any component that applies plain cursor-not-allowed to a disabled button.

The fix itself (restoring border-style and neutralising button UA chrome) is correct and scoped safely to .ep-root. The specificity claim about cursor-not-allowed is wrong in both the CSS comment and the newly added CLAUDE.md note — .ep-root button:disabled at (0,2,1) beats .ep-root .cursor-not-allowed at (0,2,0), so any component that relies on the documented escape hatch will find its cursor override silently ignored. The CLAUDE.md note will persist and mislead future contributors.

The .ep-root button:disabled block in packages/core/src/styles/editor.css (lines 163–177) and the corresponding CLAUDE.md "No Tailwind preflight" bullet — both repeat the incorrect specificity claim about cursor-not-allowed.

Important Files Changed

Filename Overview
packages/core/src/styles/editor.css Adds a scoped preflight subset (universal border reset + button chrome/cursor reset) under .ep-root. Border specificity claims are correct; however the cursor-not-allowed specificity claim in the comment is wrong — .ep-root button:disabled (0,2,1) beats .ep-root .cursor-not-allowed (0,2,0), so the documented developer escape hatch doesn't work as described.
CLAUDE.md Adds detailed "No Tailwind preflight" pitfall entry covering borders, button chrome, box-sizing, and transform variables. The cursor-not-allowed note contains the same incorrect specificity claim as the CSS comment.
.changeset/scoped-preflight-reset.md Valid patch-level changeset for @eigenpal/docx-editor-core with a consumer-facing summary. Package name matches the published name exactly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Browser renders inside .ep-root] --> B{Host app provides\nCSS reset?}
    B -- Yes --> C[Host preflight covers border-style,\nbutton chrome, etc.]
    B -- No --> D[UA defaults apply:\nborder-style: none\nbutton UA chrome\ncursor: default on buttons]
    D --> E[New scoped preflight subset\nin editor.css]
    E --> F[.ep-root * universal rule\nborder-width:0 / border-style:solid\nborder-color:currentColor\nSpecificity: 0,1,0]
    E --> G[.ep-root button rule\nappearance:none / background:transparent\ncursor:pointer\nSpecificity: 0,1,1]
    E --> H[.ep-root button:disabled\ncursor:default\nSpecificity: 0,2,1]
    F --> I{Later rule applies?}
    I -- Tailwind utility .border-t = 0,2,0 --> J[Utility wins ✓]
    I -- Inline style from painter --> K[Inline style wins ✓]
    G --> L{cursor-not-allowed override?}
    L -- .ep-root .cursor-not-allowed = 0,2,0 --> M[button:disabled WINS ✗\nComment claim is wrong]
    L -- disabled:cursor-not-allowed variant = 0,3,0 --> N[Variant wins ✓]
Loading
%%{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
    A[Browser renders inside .ep-root] --> B{Host app provides\nCSS reset?}
    B -- Yes --> C[Host preflight covers border-style,\nbutton chrome, etc.]
    B -- No --> D[UA defaults apply:\nborder-style: none\nbutton UA chrome\ncursor: default on buttons]
    D --> E[New scoped preflight subset\nin editor.css]
    E --> F[.ep-root * universal rule\nborder-width:0 / border-style:solid\nborder-color:currentColor\nSpecificity: 0,1,0]
    E --> G[.ep-root button rule\nappearance:none / background:transparent\ncursor:pointer\nSpecificity: 0,1,1]
    E --> H[.ep-root button:disabled\ncursor:default\nSpecificity: 0,2,1]
    F --> I{Later rule applies?}
    I -- Tailwind utility .border-t = 0,2,0 --> J[Utility wins ✓]
    I -- Inline style from painter --> K[Inline style wins ✓]
    G --> L{cursor-not-allowed override?}
    L -- .ep-root .cursor-not-allowed = 0,2,0 --> M[button:disabled WINS ✗\nComment claim is wrong]
    L -- disabled:cursor-not-allowed variant = 0,3,0 --> N[Variant wins ✓]
Loading

Reviews (1): Last reviewed commit: "fix(core): scoped .ep-root preflight res..." | Re-trigger Greptile

Comment on lines +163 to +177
/* 2. Button chrome + cursor. Without preflight the browser's user-agent button
* styling (beveled border + gray gradient background) leaks through every
* borderless/ghost button, and buttons don't get the interactive pointer
* cursor preflight normally applies. Neutralize the chrome and restore the
* pointer; variants that set a background via `.bg-*` utilities still win on
* specificity, and `cursor-not-allowed` utilities still win for disabled. */
.ep-root button {
appearance: none;
-webkit-appearance: none;
background: transparent;
cursor: pointer;
}
.ep-root button:disabled {
cursor: default;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 cursor-not-allowed utility cannot override .ep-root button:disabled

The comment says "cursor-not-allowed utilities still win for disabled," but the specificity math is reversed. .ep-root button:disabled resolves to (0,2,1) — class + type + pseudo-class — while the Tailwind-scoped utility .ep-root .cursor-not-allowed is only (0,2,0). Any developer who adds the plain cursor-not-allowed class to a disabled button expecting to override the default cursor will be silently surprised; the rule introduced here always wins. The disabled:cursor-not-allowed variant (which appends its own :disabled pseudo-class to yield (0,3,0)) does beat it, but that nuance is absent from the comment here and from the identical claim added to CLAUDE.md. Either drop the cursor from .ep-root button:disabled (UA already resets :disabled cursor to default on the author-side cursor: pointer via the UA stylesheet cascade — but since .ep-root button has author specificity, it would still win there), or correct the comment to say disabled:cursor-not-allowed is required and plain cursor-not-allowed is insufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant