Skip to content

Fixed unstyled shade components in the standalone settings harness - #29358

Merged
9larsons merged 1 commit into
mainfrom
slars/settings-standalone-shade-css
Jul 15, 2026
Merged

Fixed unstyled shade components in the standalone settings harness#29358
9larsons merged 1 commit into
mainfrom
slars/settings-standalone-shade-css

Conversation

@9larsons

Copy link
Copy Markdown
Contributor

Problem

apps/admin-x-settings has a standalone entry (src/main.tsx, used by pnpm dev:start and the Playwright acceptance harness) whose CSS pipeline — src/styles/index.css@source-scans admin-x-settings, admin-x-design-system and admin-x-framework sources, but never @tryghost/shade. 26 settings files already import shade components (email-design Dialog/ColorPicker fields, membership Banner/Button, welcome-email Separator/Tabs/Switch, …).

In the standalone harness those components render with no generated utility classes and no shade theme tokens:

  • utilities used only inside shade component sources (e.g. Separator's h-[1px] w-full bg-border) are never generated
  • shade's runtime semantic variables (--border, --surface-*, …) come from @tryghost/shade/styles.csstheme-variables.css, which the standalone pipeline never loads

So shade's Separator computes to 0 height / transparent background, and Playwright toBeVisible assertions fail on elements that are actually rendering. In production this never shows because settings is embedded in apps/admin, whose src/index.css pipeline scans shade and imports @tryghost/shade/styles.css.

Fix

A standalone-only CSS entry, src/styles/standalone.css:

@import './index.css';
@import '@tryghost/shade/styles.css';

@source "../../../shade/src/**/*.{js,ts,jsx,tsx}";

src/main.tsx now imports this instead of ./styles/index.css. Importing ./index.css first keeps the harness's existing cascade byte-for-byte (design-system preflight, theme, utilities insertion point, settings overrides), then layers on shade's additions — mirroring how apps/admin/src/index.css composes shade (@import "@tryghost/shade/styles.css" + a shade @source scan).

postcss-import (which runs before @tailwindcss/postcss in this pipeline) dedupes the repeated tailwindcss/theme.css / tailwindcss/utilities.css imports, so utilities are still emitted exactly once — verified by grepping the dev-server-compiled CSS: .pointer-events-none appears once, .bg-border once.

Lane analysis — why the embedded pipeline is untouched

src/styles/index.css has exactly two importers:

Importer Lane Affected?
src/main.tsx standalone dev server + acceptance harness (index.htmlmain.tsx) yes — this is the fix
src/index.tsx vite library build → dist/admin-x-settings.js (CSS inlined via vite-plugin-css-injected-by-js; dist copied into Ghost admin assets by ghost/admin/lib/asset-delivery) no — entry graph unchanged; dist/admin-x-settings.js is byte-identical before/after (shasum 1b05477e8e4fc9e579f0ee08d983e72dd1c560ad both)

The embedded admin consumes settings through neither of these: apps/admin/src/settings/settings.tsx imports @tryghost/admin-x-settings/src/app (raw source, no CSS import), and all of its CSS comes from apps/admin/src/index.css. Nothing in apps/admin references styles/index.css or the new standalone.css, so shade CSS cannot be double-included there. pnpm nx run @tryghost/admin:build passes and the built admin CSS contains a single .bg-border / .pointer-events-none rule — no duplicated Tailwind utilities.

Verification

Probe: a temporary Playwright spec opened the welcome-email customize modal in the harness and measured the shade Separator (shrink-0 bg-border h-[1px] w-full):

before after
computed height 0px 1px
computed background rgba(0, 0, 0, 0) oklch(0.9474 0.0042 236.5) (gray-200)
--border on :root (empty) oklch(94.74% 0.0042 236.5)
  • pnpm --filter @tryghost/admin-x-settings test:acceptance (full suite): 251 passed, 2 skipped, 0 failed — no test fallout from the newly generated CSS
  • pnpm --filter @tryghost/admin-x-settings lint ✅, test:unit (203 passed) ✅, build
  • pnpm nx run @tryghost/admin:build

no ref

- the standalone entry (dev:start + Playwright acceptance) compiled its CSS
  from src/styles/index.css, which scans admin-x-settings, admin-x-design-system
  and admin-x-framework sources but never @tryghost/shade — so utilities used
  only inside shade components (e.g. Separator's h-[1px] bg-border) were never
  generated, and shade's runtime theme variables (--border etc.) were undefined;
  shade components rendered with zero dimensions and no colors
- in production this never shows because settings is embedded in apps/admin,
  whose CSS entry @source-scans shade and imports @tryghost/shade/styles.css
- added a standalone-only CSS entry that layers shade on top of the existing
  stylesheet, mirroring how apps/admin composes it; styles/index.css itself is
  untouched because the library build (src/index.tsx) inlines it into the dist
  bundle via vite-plugin-css-injected-by-js, and shade CSS must not ride along
  where the embedded pipeline already provides it
- postcss-import dedupes the repeated tailwindcss/utilities.css import, so
  utilities are still emitted exactly once and existing cascade order in the
  harness is unchanged
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7abfe326-d1bb-461d-b794-58c8227df913

📥 Commits

Reviewing files that changed from the base of the PR and between 46a900e and 06c3f10.

📒 Files selected for processing (2)
  • apps/admin-x-settings/src/main.tsx
  • apps/admin-x-settings/src/styles/standalone.css

Walkthrough

The standalone settings app now imports standalone.css instead of index.css. The new stylesheet imports the existing local styles, imports @tryghost/shade/styles.css, and configures Shade source scanning for shared JavaScript and TypeScript files.

Possibly related PRs

  • TryGhost/Ghost#29331: Updates the same standalone stylesheet wiring and related Tailwind source scanning.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: adding Shade support to the standalone settings harness.
Description check ✅ Passed The description directly explains the standalone CSS fix for Shade components and is on-topic.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch slars/settings-standalone-shade-css

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jul 15, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 06c3f10

Command Status Duration Result
nx run @tryghost/admin-x-settings:test:acceptance ✅ Succeeded 9m 55s View ↗
nx run-many -t test:unit -p @tryghost/admin-x-s... ✅ Succeeded 2m 40s View ↗
nx run @tryghost/admin:test:acceptance ✅ Succeeded 1m 16s View ↗
nx run ghost-monorepo:lint:boundaries ✅ Succeeded 15s View ↗
nx run-many -t lint -p @tryghost/admin-x-settin... ✅ Succeeded 50s View ↗
nx run @tryghost/admin:build ✅ Succeeded 50s View ↗
nx run-many --target=build --projects=tag:publi... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-07-15 17:15:12 UTC

@9larsons
9larsons merged commit 8424edb into main Jul 15, 2026
43 checks passed
@9larsons
9larsons deleted the slars/settings-standalone-shade-css branch July 15, 2026 17:33
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