Fixed unstyled shade components in the standalone settings harness - #29358
Conversation
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
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe standalone settings app now imports Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
| 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

Problem
apps/admin-x-settingshas a standalone entry (src/main.tsx, used bypnpm dev:startand 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:
h-[1px] w-full bg-border) are never generated--border,--surface-*, …) come from@tryghost/shade/styles.css→theme-variables.css, which the standalone pipeline never loadsSo shade's Separator computes to 0 height / transparent background, and Playwright
toBeVisibleassertions fail on elements that are actually rendering. In production this never shows because settings is embedded inapps/admin, whosesrc/index.csspipeline scans shade and imports@tryghost/shade/styles.css.Fix
A standalone-only CSS entry,
src/styles/standalone.css:src/main.tsxnow imports this instead of./styles/index.css. Importing./index.cssfirst 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 howapps/admin/src/index.csscomposes shade (@import "@tryghost/shade/styles.css"+ a shade@sourcescan).postcss-import(which runs before@tailwindcss/postcssin this pipeline) dedupes the repeatedtailwindcss/theme.css/tailwindcss/utilities.cssimports, so utilities are still emitted exactly once — verified by grepping the dev-server-compiled CSS:.pointer-events-noneappears once,.bg-borderonce.Lane analysis — why the embedded pipeline is untouched
src/styles/index.csshas exactly two importers:src/main.tsxindex.html→main.tsx)src/index.tsxdist/admin-x-settings.js(CSS inlined viavite-plugin-css-injected-by-js; dist copied into Ghost admin assets byghost/admin/lib/asset-delivery)dist/admin-x-settings.jsis byte-identical before/after (shasum 1b05477e8e4fc9e579f0ee08d983e72dd1c560adboth)The embedded admin consumes settings through neither of these:
apps/admin/src/settings/settings.tsximports@tryghost/admin-x-settings/src/app(raw source, no CSS import), and all of its CSS comes fromapps/admin/src/index.css. Nothing inapps/adminreferencesstyles/index.cssor the newstandalone.css, so shade CSS cannot be double-included there.pnpm nx run @tryghost/admin:buildpasses and the built admin CSS contains a single.bg-border/.pointer-events-nonerule — 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):0px1pxrgba(0, 0, 0, 0)oklch(0.9474 0.0042 236.5)(gray-200)--borderon:rootoklch(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 CSSpnpm --filter @tryghost/admin-x-settings lint✅,test:unit(203 passed) ✅,build✅pnpm nx run @tryghost/admin:build✅