feat(config): brand_href + dark/light code themes — the knobs API sites shim today#32
Merged
Merged
Conversation
Three config knobs replace what sites (zazu/app-4) shim by subclassing DocsUI::Shell today: - c.brand_href (default "/") — the topbar brand link target. Shell#topbar reads it, so pointing the brand at /docs is one line, not a copy-pasted #topbar subclass. - c.code_theme_dark (default nil) — a second Rouge theme for DARK daisyUI themes. nil keeps the single-theme behavior byte-for-byte (backwards compatible). When set, DocsUI::Code additionally emits that theme's CSS scoped under [data-theme=X] .code-highlight for each shipped dark theme, so code blocks stay readable when the switcher flips dark — CSS-only, no JS, no flash (daisyUI's [data-theme] selector out-specifies the base). - c.dark_themes (default DEFAULT_DARK_THEMES, the built-in daisyUI dark names) — which themes count as dark. Intersected with c.themes at render time (#dark_themes_shipped) so only shipped themes emit CSS. Overridable for custom dark themes. code_theme_dark_class mirrors code_theme_class (String/Class/nil). ## Test Coverage - configuration_spec: brand_href default/override; code_theme_dark nil default + override; code_theme_dark_class String/Class/nil; dark_themes frozen default + override; dark_themes_shipped intersection + order + empty - shell_spec: brand link href defaults to "/" and follows config - code_spec: dark CSS scoped per shipped dark theme; non-shipped dark theme excluded; base rule coexists; byte-identical regression guard when nil ## Dogfood + docs - docs/ initializer: Github (light) + Monokai (dark) so the restyle is visible across all 9 themes - README: the three knobs documented; theme-sync invariant noted unaffected (Rouge CSS is inline, not Tailwind) - install generator template: the knobs added as commented examples ## Verification - [x] bundle exec rspec — 252 examples, 0 failures; Configuration 100% covered - [x] bundle exec rubocop — no offenses Closes #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three config knobs replace the workarounds sites (zazu/app-4) shim by subclassing
DocsUI::Shelltoday — the app-4Shellsubclass shrinks to nothing once these land.c.brand_href"/"Shell#topbarreads it, so pointing the brand at/docsis one line — not a copy-pasted#topbarsubclass (flagged fragile in app-4's own comments).c.code_theme_darknilnilkeeps the single-theme behavior byte-for-byte (backwards compatible). When set,DocsUI::Codealso emits that theme's CSS scoped under[data-theme=X] .code-highlightfor each shipped dark theme, so code blocks stay readable when the switcher flips dark.c.dark_themesDEFAULT_DARK_THEMES(the built-in daisyUI dark names)c.themesat render time (#dark_themes_shipped) so only shipped themes emit CSS. Overridable for custom dark themes (e.g.%w[zazu-dark]).code_theme_dark_classmirrorscode_theme_class(String / Class / nil).Why CSS-only, no JS
The base (light) theme is emitted un-scoped; the dark theme is scoped under
[data-theme=X]. daisyUI's[data-theme]selector is more specific than the un-scoped base rule, so the theme switcher restyles code blocks with no JavaScript and no flash. Rouge CSS is inlined per block (not part of the Tailwind build), so the theme-sync invariant is unaffected — acode_theme_darkdoesn't need a CSS rebuild.Test Coverage
brand_hrefdefault/override;code_theme_darknil default + override;code_theme_dark_classString/Class/nil;dark_themesfrozen default + override;dark_themes_shippedintersection + declaration order + empty case"/"and followsconfig.brand_hrefsynthwavewhen unshipped) excluded; base rule coexists with dark rules; byte-identical regression guard whencode_theme_darkis nilDogfood + docs
docs/initializer configured withGithub(light) +Monokai(dark) so the light↔dark restyle is visible across all 9 themesdocs_kit:installanddocs-kit newboth surface them)Verification
bundle exec rspec— 252 examples, 0 failures;Configuration100% coveredbundle exec rubocop— no offensesthemes: %w[light dark synthwave retro dracula]the emitted dark scopes are exactlydark,synthwave,dracula;light/retroexcluded; base rule presentOut of scope
fix/csp-nonce-shell, DocsUI::Shell inline scripts are not nonce-aware — blocked under a nonce-based CSP #2)DocsUI::CodeCloses #16