feat(toolbar): flat single-surface styling, scoped preflight reset, and parity fixes#790
feat(toolbar): flat single-surface styling, scoped preflight reset, and parity fixes#790jacobjove wants to merge 16 commits into
Conversation
|
Someone is attempting to deploy a commit to the EigenPal Team on Vercel. A member of the Team first needs to authorize it. |
|
All contributors have signed the CLA ✍️ ✅ Posted by the CLA bot. |
a6571c2 to
20d89c5
Compare
Refresh the editor toolbar to a flat, single-surface design — borderless icon buttons, a blue-tint active state, a segmented font-size control, and consistent dividers/spacing — and add an AgentActivityIndicator component for AI-collaborator presence in the title-bar slot. React + Vue. Also reproduce the button-relevant subset of Tailwind preflight, scoped to .ep-root. The library ships without preflight (so it never resets a host app's styles); without it, host apps lacking their own reset get leftover user-agent button chrome, width-only border utilities that render nothing, no pointer cursor on buttons, and content-box inputs that resize on focus. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
20d89c5 to
0414e17
Compare
- Replace bare hex/rgba/named colors in the toolbar + agent-presence components with the existing --doc-* chrome tokens (surface, shadow, primary, text, border, bg-hover, text-subtle/-muted) so they re-theme under .ep-root.dark. Adds a constant --doc-on-agent token for the white foreground on the indigo agent badge (badge stays indigo in dark, so it must not invert). React + Vue. - Regenerate docs/api/docx-editor-react/ui.api.md for the ZoomControl props this PR added — api:check was missing them (would fail CI on merge).
… reset The library ships `@tailwind utilities` only (no preflight) so it never resets a host app's styles. Document the silent breakages in a host without its own reset (UA button chrome, no-op width-only borders, content-box inputs, var-dependent transform utilities) and the .ep-root scoped subset that mitigates them. Pairs with the editor.css preflight reset in eigenpal#790. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The api-extractor golden for @eigenpal/docx-editor-react drifted once main's toolchain bump changed how the AgentActivityIndicator return type resolves (react_jsx_runtime.JSX.Element -> React_2.JSX.Element). Regenerated on the merged state so api:check is green.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR delivers a flat toolbar redesign (white surface, leading-divider
Confidence Score: 4/5Safe to merge once the AgentActivityIndicator label strings are run through the i18n system. Both the React and Vue AgentActivityIndicator components render user-visible text ("is editing…" / "connected") as hardcoded English strings rather than using useTranslation. CLAUDE.md explicitly forbids this, and en.json has no keys for these phrases. Every other UI string added in this PR correctly uses t(), so the fix is straightforward — add two keys to en.json and wire useTranslation in both components. All previously flagged regressions (unforwarded activity prop, unused ZoomControl props, Vue font-size input, documentStyles, ARIA attributes) are resolved at HEAD. packages/react/src/components/DocxEditor/AgentActivityIndicator.tsx and packages/vue/src/components/DocxEditor/AgentActivityIndicator.vue — both need i18n wiring for the chip labels.
|
| Filename | Overview |
|---|---|
| packages/react/src/components/DocxEditor/AgentActivityIndicator.tsx | New component for AI-collaborator presence chip; hardcodes user-facing English labels instead of using t() — violates CLAUDE.md i18n rule |
| packages/vue/src/components/DocxEditor/AgentActivityIndicator.vue | Vue port of the React presence chip; same hardcoded English label strings as the React version, missing useTranslation |
| packages/core/src/styles/editor.css | Adds scoped preflight subset, toolbar divider CSS, and agent-presence pulse animation; new --doc-agent-bg token has no dark-mode override (will be bright in dark mode) |
| packages/react/src/components/DocxEditor/DocxEditorToolbar.tsx | Switches trailing cluster from bare ToolbarSeparators to ToolbarGroups and forwards agentPanel.activity to AgentPanelToggle — previously flagged issues addressed |
| packages/react/src/components/Toolbar.tsx | Flat redesign: pill→borderless layout, ToolbarGroup leading-divider pattern, font-family and font-size split into separate groups, icon baseline nudges for underline/super/subscript |
| packages/vue/src/components/Toolbar.vue | Mirrors React flat redesign; restores editable font-size input via useToolbarFontSize, documentStyles forwarded to useParagraphStyleOptions, ARIA attributes preserved on all dropdown triggers |
| packages/react/src/components/ui/ZoomControl.tsx | Simplified to a pure Radix Select dropdown — removes unused minZoom/maxZoom/showButtons/persistZoom/storageKey props and stepper buttons as flagged in prior review |
| packages/core/tailwind-preset.cjs | Adds doc-separator, doc-agent, doc-agent-bg Tailwind colour utilities mapped to the new CSS tokens |
| packages/react/src/components/DocxEditor/AgentPanelToggle.tsx | Adds activity prop with awareness dot (steady or pulsing) — previously flagged forwarding gap resolved in DocxEditorToolbar |
| packages/vue/src/composables/useToolbarFontSize.ts | Font-size editing composable refactored to add snap-back for invalid input and applied-flag to avoid double-commit; well-tested |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Host as Host App
participant DocxEditorToolbar as DocxEditorToolbar
participant AgentPanelToggle as AgentPanelToggle
participant TitleBar as TitleBar (renderTitleBarRight)
participant AgentActivityIndicator as AgentActivityIndicator
Host->>DocxEditorToolbar: "agentPanel={activity:'editing', ...}"
DocxEditorToolbar->>AgentPanelToggle: "activity='editing'"
Note over AgentPanelToggle: pulsing dot on toggle button
Host->>TitleBar: renderTitleBarRight()
TitleBar->>AgentActivityIndicator: "activity='editing', agentName='Claude'"
Note over AgentActivityIndicator: chip: "Claude is editing" + pulse dot
%%{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"}}}%%
sequenceDiagram
participant Host as Host App
participant DocxEditorToolbar as DocxEditorToolbar
participant AgentPanelToggle as AgentPanelToggle
participant TitleBar as TitleBar (renderTitleBarRight)
participant AgentActivityIndicator as AgentActivityIndicator
Host->>DocxEditorToolbar: "agentPanel={activity:'editing', ...}"
DocxEditorToolbar->>AgentPanelToggle: "activity='editing'"
Note over AgentPanelToggle: pulsing dot on toggle button
Host->>TitleBar: renderTitleBarRight()
TitleBar->>AgentActivityIndicator: "activity='editing', agentName='Claude'"
Note over AgentActivityIndicator: chip: "Claude is editing" + pulse dot
Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile
# Conflicts: # packages/core/src/styles/editor.css # packages/react/src/components/Toolbar.tsx
Resolves the Greptile review on eigenpal#790 plus the merge conflict with main. React: - ZoomControl: remove 5 dead props (minZoom, maxZoom, showButtons, persistZoom, storageKey) that were declared but never consumed; drop the no-op values the Toolbar caller passed. Document `levels` as the single source of range (smallest/largest preset = bounds). - DocxEditorToolbar: forward agentPanel.activity to AgentPanelToggle so the awareness dot is reachable from the public <DocxEditor agentPanel> surface; add `activity` to AgentPanelOptions. - Select: SelectLabel uses text-doc-text-subtle (doc token) instead of hardcoded text-slate-500 so it survives dark mode. Vue (parity regressions vs main, restored): - Restore documentStyles prop + useParagraphStyleOptions so real document styles show in the style picker (not just static presets). - Restore the editable font-size <input> (direct text entry of arbitrary sizes) via useToolbarFontSize, replacing the display-only button. - Restore aria-expanded / aria-haspopup on the zoom, style, font, size, align, and spacing dropdown triggers. Merge: resolve conflicts in editor.css (keep both agent + scrollbar tokens; re-point light-theme --doc-toggle-active-* to the flat blue-tint so the redesign's active state lands through main's .ep-toolbar-toggle mechanism) and Toolbar.tsx (adopt main's CSS-class toggle states). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review follow-up on eigenpal#790. The restored size box is a persistent <input> with a one-way :value bind. On blur/Enter with empty or non-numeric input, commitFontSize applies nothing, so currentFontSize never changes and Vue's VDOM diff never re-patches the input — the typed garbage (e.g. "abc") lingers in the box while the document keeps its real size. Reset the DOM value to currentFontSize when nothing was applied; skip the reset on a valid commit so reactivity re-patches without a flash of the old value. Adds composable unit tests (commit half-points, clamp, snap-back, sizeTyped guard, preset pick). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # packages/react/src/components/Toolbar.tsx # packages/vue/src/components/Toolbar.vue
|
Merged For re-review: the earlier review (against @greptile review |
…t token
The presence chip rendered hardcoded English ('{name} is editing…' / '{name}
connected') as both visible text and aria-label, violating the i18n rule. Add
agentPanel.activityEditing/activityConnected keys and wire useTranslation in
both the React and Vue components. Also give --doc-agent / --doc-agent-bg a
dark-mode override so the chip isn't bright indigo on dark surfaces.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…al#790 review) Addresses the Greptile review on eigenpal#790: - Vue Toolbar: restore document-style picker (documentStyles prop + useParagraphStyleOptions), editable font-size entry (useToolbarFontSize), and aria-expanded/aria-haspopup on the dropdown triggers — all dropped by the flat redesign. Re-wires the two orphaned composables; the host already passed :document-styles. - DocxEditorToolbar: forward agentPanel.activity to AgentPanelToggle so the presence dot is reachable; add activity to AgentPanelOptions. - ZoomControl: drop the five never-read props (minZoom/maxZoom/showButtons/ persistZoom/storageKey) and the call-site that passed them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ze input, aria) Real-browser regression coverage for the restored Vue toolbar behaviors: style dropdown opens/lists/aria, and the font-size readout is an editable <input> that opens its preset list on focus. Green via the vue Playwright project against the live demo + demo.docx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… font-size input, aria)" This reverts commit 4acb2db.
…eigenpal#790 review)" This reverts commit 17efba9.
The main merge brought origin/main's documentFonts font-group in alongside the redesign's split font/size groups, pushing the file to 1001 lines and tripping the max-lines lint rule. Collapse a two-line comment back to one.
origin/main keeps the Font Family and Font Size pickers in a single ToolbarGroup; the flat-redesign branch had split them into two groups, which inserts a vertical divider between the family and size boxes and diverges from origin for no visual gain. Word places no divider there, and the Vue toolbar already puts the group divider before the font family box with none between family and size — so the single group also restores React/Vue parity. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the always-on input border boxes the flat redesign had put on the font-family / style / zoom dropdowns and the font-size stepper. Selectors now read borderless at rest with a hover wash (Select bordered defaults to false); the font-size stepper loses its segmented outer box, keeping a thin box on the editable value only. The active toggle is already the blue tint. Mirrored in the Vue toolbar for parity. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the flat toolbar from min-height 40px / py-1 to 34px / py-0.5 around the 28px buttons (2px slack), matching the compact Google Docs bar. Mirrored in Vue. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Superseded — this PR has been split into three cohesive, independently reviewable PRs and is being closed:
Together these cover the full diff that was here. Please review the three above instead. |
Aligns the editor toolbar's visual styling with the flat, single-surface look of the Word/Google-Docs bar (borderless icon buttons, blue-tint active state, consistent dividers, compact height), and folds in the fixes surfaced along the way.
Bug fix — scoped button preflight (
.ep-root). The library ships@tailwind utilitiesonly, no preflight, by design (so it never resets a host app's styles). But nothing reproduced the button-relevant subset for the editor's own controls, so in a host without its own reset: toolbar buttons inherited user-agent chrome, width-only border utilities rendered nothing (border-styledefaults tonone), buttons had no pointer cursor, and content-box inputs resized on focus. Now reproduced, scoped to.ep-root.Vue parity regressions restored.
documentStyles→useParagraphStyleOptions(real document styles in the style picker, not just static presets); the editable font-size<input>(arbitrary sizes by direct entry, replacing a display-only button);aria-expanded/aria-haspopupon the dropdown triggers.Dark mode + i18n. Toolbar and agent-chip colors moved off bare hex onto the existing
--doc-*chrome tokens so they re-theme under.ep-root.dark; theAgentActivityIndicatorlabels go throughuseTranslation.Additive —
AgentActivityIndicator. A small, opt-in component for AI-collaborator presence in the title-bar slot. Minor bump; nothing renders it unless a host opts in.React and Vue both updated; changeset included.