Skip to content

fix(admin): improve portable text editor controls#2064

Open
khoinguyenpham04 wants to merge 11 commits into
mainfrom
feat/tiptap-editor-refinements
Open

fix(admin): improve portable text editor controls#2064
khoinguyenpham04 wants to merge 11 commits into
mainfrom
feat/tiptap-editor-refinements

Conversation

@khoinguyenpham04

@khoinguyenpham04 khoinguyenpham04 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Makes the portable text editor easier and more reliable to use:

  • Centers the writing area and simplifies the responsive toolbar.
  • Adds clearer block insertion controls and a compact heading menu.
  • Prevents inline and table controls from clipping, overlapping the sticky toolbar, or appearing together.
  • Keeps slash commands and gutter insertion predictable across mouse, touch, and keyboard input.

This also improves keyboard navigation, screen-reader state, narrow-screen behavior, and RTL icon placement.

Related issue: N/A

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: N/A — this PR fixes existing editor behavior.

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: OpenCode (GPT-5.6 Sol), reviewed with Grok 4.5 Thinking High

Screenshots / test output

No screenshots included.

  • pnpm typecheck
  • pnpm lint
  • pnpm --filter @emdash-cms/admin test --run — 1,131 tests passed
  • Focused editor suites — 111 tests passed

Try this PR

Open a fresh playground →

A full working EmDash site, deployed from this branch. Each visit gets its own session-scoped sandbox: no login needed and no shared state. Try the admin, edit content, hit the public site.

Tracks feat/tiptap-editor-refinements. Updated automatically when the playground redeploys.

Copilot AI review requested due to automatic review settings July 15, 2026 16:37
@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 203c39b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
@emdash-cms/admin Patch
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/sandbox-workerd Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-cache 203c39b Jul 16 2026, 02:45 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-do 203c39b Jul 16 2026, 02:46 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-playground 203c39b Jul 16 2026, 02:44 PM

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond area/admin size/XL labels Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 2,226 lines across 13 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@pkg-pr-new

pkg-pr-new Bot commented Jul 15, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/admin@2064

@emdash-cms/auth

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/auth@2064

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/auth-atproto@2064

@emdash-cms/blocks

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/blocks@2064

@emdash-cms/cloudflare

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/cloudflare@2064

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/contentful-to-portable-text@2064

emdash

npm i https://pkg.pr.new/emdash-cms/emdash@2064

create-emdash

npm i https://pkg.pr.new/emdash-cms/emdash/create-emdash@2064

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/gutenberg-to-portable-text@2064

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-cli@2064

@emdash-cms/plugin-types

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-types@2064

@emdash-cms/registry-client

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/registry-client@2064

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/registry-lexicons@2064

@emdash-cms/registry-verification

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/registry-verification@2064

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/sandbox-workerd@2064

@emdash-cms/x402

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/x402@2064

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-ai-moderation@2064

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-atproto@2064

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-audit-log@2064

@emdash-cms/plugin-color

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-color@2064

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-embeds@2064

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-field-kit@2064

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-forms@2064

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-webhook-notifier@2064

commit: 203c39b

@emdashbot emdashbot Bot left a comment

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.

This PR is a well-scoped UI refinement of the TipTap portable-text editor: it centers the writing column, collapses headings into a dropdown, adds a coarse-pointer block inserter, fixes floating-menu collision logic, and hardens the gutter slash-menu keyboard/mouse flow. The change stays inside the admin package, doesn’t touch backend routes or storage, and includes extensive tests, so it fits EmDash’s architecture.

I read the full diff, the changed source files, and the related editor tests. The implementation is solid and the test coverage is good. I’m flagging a small but real AGENTS/localization violation (two unlocalized placeholder="https://..." examples in the DOM), plus two lower-severity suggestions for using Kumo consistently and exposing the slash-menu selection to screen readers.


Findings

  • [needs fixing] packages/admin/src/components/PortableTextEditor.tsx:3003

    The bubble-menu link input hard-codes "https://..." as a placeholder. This is user-facing English that bypasses Lingui extraction, violating the AGENTS.md rule that every admin UI string goes through Lingui.

    						placeholder={t`https://...`}
    
  • [needs fixing] packages/admin/src/components/PortableTextEditor.tsx:3564

    The toolbar link popover repeats the same unlocalized "https://..." placeholder. Wrap it with Lingui so it can be extracted with the rest of the admin catalog.

    									placeholder={t`https://...`}
    
  • [suggestion] packages/admin/src/components/editor/DragHandleWrapper.tsx:170

    The drag-handle control uses a hand-rolled <button> with Kumo-style tokens instead of the Kumo Button primitive. The sibling plus-button already uses Kumo Button, so this is inconsistent and duplicates styling logic. Prefer Kumo’s Button (or buttonVariants if the element absolutely must stay native). For example:

    					<Button
    						ref={handleRef}
    						type="button"
    						variant="ghost"
    						shape="square"
    						className={cn(
    							"h-6 w-6 flex-none rounded select-none",
    							"text-kumo-subtle/50 hover:text-kumo-subtle",
    							"hover:bg-kumo-tint/80 cursor-grab active:cursor-grabbing",
    							"transition-colors duration-100",
    							menuOpen && "text-kumo-subtle bg-kumo-tint",
    						)}
    						onClick={handleClick}
    						data-block-handle
    						aria-label={t`Block actions - drag to reorder, click for menu`}
    					>
    						<DotsSixVertical className="h-4 w-4" />
    					</Button>
    
  • [suggestion] packages/admin/src/components/PortableTextEditor.tsx:1352

    The slash command menu communicates the selected item only through the bg-kumo-tint color class. Since the PR explicitly mentions improving screen-reader state, expose the selected state with aria-current (or wrap the list in role="listbox" and use role="option" + aria-selected).

    					<button
    						key={item.id}
    						type="button"
    						data-index={index}
    						aria-current={index === state.selectedIndex ? "true" : undefined}
    						className={cn(
    

@github-actions

Copy link
Copy Markdown
Contributor

Overlapping PRs

This PR modifies files that are also changed by other open PRs:

This may cause merge conflicts or duplicated work. A maintainer will coordinate.

@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Jul 16, 2026
@khoinguyenpham04 khoinguyenpham04 added the bot:review Trigger an emdashbot code review on this PR label Jul 16, 2026

@emdashbot emdashbot Bot left a comment

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.

This PR remains a well-scoped UI refinement of the admin TipTap editor: it centers the writing column, collapses headings into a compact dropdown, adds a coarse-pointer block inserter, separates inline and table bubble menus, and hardens gutter slash-menu keyboard/mouse behavior. The change stays inside @emdash-cms/admin, touches no backend or storage code, and ships an extensive test suite plus a correct changeset.

I verified that the four findings from the prior review are all addressed in this revision:

  • Both "https://..." placeholders are now wrapped with Lingui (t\https://...``).
  • The drag-handle controls now render as Kumo Button primitives, with tests asserting data-kumo-component="Button".
  • The slash command menu exposes the selected item with aria-current="true" and also announces it to screen readers via a role="status" region.

The implementation is solid overall. I’m leaving one new low-severity comment: the table bubble menu introduces a Kumo Tooltip usage that doesn’t match the render-prop trigger pattern used everywhere else in the repo, so the hover tooltip likely fails to attach to the actual button.

Tests were not run per the static-review policy; the author reports the full admin suite (1,131 tests) and focused editor suites (111 tests) pass.

Comment thread packages/admin/src/components/PortableTextEditor.tsx Outdated
@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Jul 16, 2026
@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-rereview Author pushed changes since the last review labels Jul 16, 2026
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/awaiting-author Reviewed; waiting on the author to respond labels Jul 16, 2026
@ascorbic

Copy link
Copy Markdown
Collaborator
image Looks like a mistake here

@khoinguyenpham04

Copy link
Copy Markdown
Collaborator Author

image Looks like a mistake here

this is fixed now, thanks for flagging it

@masonjames

Copy link
Copy Markdown
Contributor

@khoinguyenpham04 Love it! Overall solid improvement 🙌

One interaction feels a bit off:
When I invoke the slash command and then hit tab the menu remains in focus and the cursor moves to the next available text window. We should probably either have the tab key move to the first item in the menu (require escape key to get out of the menu), or have the menu close automatically when you tab to the next menu.

Monosnap Personal EmDash Admin 2026-07-16 13-02-21(1)

@ascorbic ascorbic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks!

@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-rereview Author pushed changes since the last review labels Jul 16, 2026
@ascorbic

Copy link
Copy Markdown
Collaborator

Ah, good spot @masonjames

@khoinguyenpham04

Copy link
Copy Markdown
Collaborator Author

@masonjames thank you for reviewing it! I'm on to fixing it.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants