Skip to content

fix(ai-moderation): style the category dialog with Kumo tokens - #3014

Open
DavidPivert wants to merge 2 commits into
emdash-cms:mainfrom
DavidPivert:fix/ai-moderation-dialog-styles
Open

fix(ai-moderation): style the category dialog with Kumo tokens#3014
DavidPivert wants to merge 2 commits into
emdash-cms:mainfrom
DavidPivert:fix/ai-moderation-dialog-styles

Conversation

@DavidPivert

@DavidPivert DavidPivert commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes the "Edit Category" / "Add Category" dialog on the AI Moderation settings page rendering with no background, drawn on top of the category list and unreadable.

The admin stylesheet (@emdash-cms/admin/dist/styles.css) is precompiled from the admin package and Kumo only; classes used by plugin admin modules are not scanned. The settings page relied on shadcn-style utilities (bg-background, bg-primary, text-primary-foreground, bg-muted, text-muted-foreground, resize-none) that produce no CSS at all, so only the bg-black/50 overlay was visible.

Changes in packages/plugins/ai-moderation/src/admin.tsx:

  • dialog panel → bg-kumo-elevated border-kumo-line; inputs → bg-kumo-base; hover/badge/test-result backgrounds → bg-kumo-fill / bg-kumo-tint; muted copy → text-kumo-subtle; resize-none → inline style={{ resize: "none" }}
  • the Save Settings, Analyze, Cancel and Save/Add buttons now use the Kumo Button component (primary / secondary, with loading for the async ones) instead of hand-rolled classes — same as plugin-forms

New test tests/admin-styles.test.ts scans admin.tsx for those absent utilities; it fails on main (6 cases) and passes with this change.

Closes #3013

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. — not applicable: no string added or changed; the plugin's existing strings are not wrapped either.
  • I have added and reviewed the user-facing changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/... — not a feature
  • I have included screenshots below if this PR changes the UI

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Code (Claude Fable 5.1), reviewed and verified by the submitter

Screenshots / test output

Before (0.37.0, @emdash-cms/plugin-ai-moderation 0.2.0): the overlay dims the page but the dialog has no panel — title, ID / Name / Description / Action fields and Cancel / Save are painted over the category rows.

Before: AI Moderation settings page, the Edit Category dialog is drawn transparently on top of the category list

After: the dialog sits on an opaque elevated panel with Kumo-styled fields, a primary Save and a secondary Cancel (captured on a production admin rendering the same Kumo utilities as this branch).

After: AI Moderation settings page, the Edit Category dialog on an opaque panel with readable fields and Kumo buttons

Test output:

 Test Files  4 passed (4)
      Tests  50 passed (50)

Same test file against main: Tests 6 failed | 44 passed (50).

The admin stylesheet is precompiled from the admin package and the Kumo
design system; classes used by plugin admin modules are not scanned. The
shadcn-style utilities the settings page relied on (bg-background,
bg-primary, text-primary-foreground, bg-muted, text-muted-foreground,
resize-none) therefore produced no CSS: the "Edit Category" dialog had
no background and was drawn over the category list, unreadable.

Switch the dialog panel, fields and secondary controls to Kumo utilities
(bg-kumo-elevated, bg-kumo-base, bg-kumo-fill, bg-kumo-tint,
text-kumo-subtle) and the primary/secondary action buttons to the Kumo
Button component, which also gives them a proper loading state.

Add a source-level test that fails when admin.tsx uses one of those
absent utilities, so the regression cannot come back silently.

Closes emdash-cms#3013
@changeset-bot

changeset-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bc36721

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

This PR includes changesets to release 1 package
Name Type
@emdash-cms/plugin-ai-moderation 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

@github-actions github-actions Bot added review/needs-review No maintainer or bot review yet area/plugins size/M labels Sep 10, 2026
@pkg-pr-new

pkg-pr-new Bot commented Sep 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

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

@emdash-cms/auth

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

@emdash-cms/auth-atproto

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

@emdash-cms/blocks

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

@emdash-cms/cloudflare

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

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

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

emdash

npm i https://pkg.pr.new/emdash@3014

create-emdash

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

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

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

@emdash-cms/plugin-cli

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

@emdash-cms/plugin-types

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

@emdash-cms/registry-client

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

@emdash-cms/registry-lexicons

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

@emdash-cms/registry-moderation

npm i https://pkg.pr.new/@emdash-cms/registry-moderation@3014

@emdash-cms/registry-verification

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

@emdash-cms/sandbox-workerd

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

@emdash-cms/x402

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

@emdash-cms/plugin-ai-moderation

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

@emdash-cms/plugin-atproto

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

@emdash-cms/plugin-audit-log

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

@emdash-cms/plugin-color

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

@emdash-cms/plugin-embeds

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

@emdash-cms/plugin-field-kit

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

@emdash-cms/plugin-forms

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

@emdash-cms/plugin-webhook-notifier

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

commit: bc36721

@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 takes the right approach for the reported bug: the admin stylesheet is built from the admin package and Kumo sources, so plugin JSX that relies on shadcn semantic utilities can end up unstyled. Replacing those utilities with Kumo tokens is consistent with AGENTS.md's styling rules, and converting the primary/async actions to the Kumo Button matches the sibling forms plugin.

The fix is mostly clean, but I found one concrete oversight: the StatusWidget link still uses text-primary, the same class family the PR is removing because it is not guaranteed to ship. That leaves a visible element that can render with the wrong color in light/dark mode. I also noted that the new style-guard test lists text-muted-foreground twice, and I left a suggestion about finishing the Kumo migration for the hand-rolled dialog, inputs, and icon buttons since this file is already being touched.


Findings

  • [needs fixing] packages/plugins/ai-moderation/src/admin.tsx:90

    The text-primary class is part of the shadcn semantic-utility family this PR is removing because it is not guaranteed to exist in the precompiled admin stylesheet. Leaving it on the "Configure moderation" link means that link can render with the wrong color (or no usable color) in light/dark mode, which is the same kind of visual defect the PR fixes elsewhere.

    Remove text-primary (or replace it with a verified Kumo token such as text-kumo-brand) and add text-primary to the test's disallowed-utility list so the regression test catches it.

    				<a
    					href="/_emdash/admin/plugins/ai-moderation/settings"
    					className="text-xs hover:underline"
    				>
    
  • [suggestion] packages/plugins/ai-moderation/tests/admin-styles.test.ts:21

    "text-muted-foreground" is listed twice in SHADCN_UTILITIES, so the same assertion runs redundantly. Remove the duplicate entry.

    	"text-muted-foreground",
    	"bg-secondary",
    
  • [suggestion] packages/plugins/ai-moderation/src/admin.tsx:117-119

    The dialog is still a hand-rolled fixed overlay with raw <input>, <select>, <textarea>, and plain <button> elements. AGENTS.md says to use Kumo components (Dialog, Input, Select, InputArea, Button) instead of rolling custom markup so the admin gets focus trapping, ARIA roles, and consistent styling for free. Since this PR is already restyling the dialog, consider migrating the dialog and its icon-action buttons to Kumo as a follow-up.

Review follow-up: the "Configure moderation" link in the dashboard widget
still used text-primary, from the same family of utilities the admin
stylesheet does not ship. Use text-kumo-brand instead, add text-primary
to the style-guard test, and remove a duplicated entry from that list.
@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review and removed review/needs-review No maintainer or bot review yet labels Sep 10, 2026
@DavidPivert

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Addressed in bc36721:

  • text-primary on the StatusWidget link → replaced with text-kumo-brand (verified present in the admin stylesheet), and text-primary added to the style-guard list so the test now catches it.
  • Duplicate text-muted-foreground in the test list → removed.

On the full Kumo migration (Dialog, Input, Select, InputArea, icon buttons): agreed that it is the right end state, but I kept this PR to the bug (missing CSS) so it stays a small, low-risk patch. Happy to send the migration as a follow-up PR once this one lands, unless you would rather have it here.

Plugin suite: 4 files, 50 tests green; tsgo, oxlint --type-aware --deny-warnings and oxfmt/prettier clean on the touched files.

Before/after screenshots will be added to the description shortly.

@DavidPivert

Copy link
Copy Markdown
Contributor Author

CI note: after bc36721 everything is green except Test Shard (1/4) (and the aggregate Tests). The failures are in apps/release-servicetest/release-intent-workflow.test.ts, eight ReleaseIntentWorkflow cases timing out at ~5 s (e.g. "uses a fresh permit and publication generation after each confirmed absence", "rechecks the attested workload against the active policy before create"). This PR does not touch that package.

The same shard failed on two unrelated branches yesterday (feat/plugin-storage-conditional-writes, codex/passkey-onboarding-ux), so it looks like a flaky suite rather than something introduced here. I cannot re-run failed jobs from a fork — could a maintainer trigger a re-run when convenient? Happy to push a rebase instead if you prefer.

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

Labels

area/plugins review/needs-rereview Author pushed changes since the last review size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

plugin-ai-moderation: "Edit Category" dialog renders transparent (shadcn utility classes missing from admin stylesheet)

1 participant