Pages
Contents
Guide
Installation
| npm install @xpulse/theme --registry=https://npm.xpulse.one |
Usage
When @xpulse/theme is installed and started by @xpulse/app, a single
minified CSS bundle is served at /_theme/css/xpulse.css. All themes
(dark, light, and any app overrides) are included in that one file.
Recommended β use template methods in your layout:
| {% themeAssets() %} |
This renders the bundle link, the anti-FOUC inline script, and the browser runtime script. Add the switcher separately if needed:
| {% themeSwitcher() %} |
JavaScript
@xpulse/theme works without any required runtime JavaScript.
Most use cases rely only on:
- HTML structure
- CSS classes (
xpulse-*) --xpulse-*custom properties
JavaScript is only needed as an optional behavior layer, for example:
- Theme switching via
/_theme/theme.js - Live
:roottoken demos viathemeTokenEditor() - Active TOC highlighting on scroll
- Copy-to-clipboard for code blocks
What The Package Provides
- Built-in themes at
public/css/themes/(dark, light) - Base CSS at
public/css/base.css - Component CSS at
public/css/components/ - A single HTTP bundle:
GET /_theme/css/xpulse.css - Browser runtime:
GET /_theme/theme.js - No manual theme registration required
Using A Custom App Theme
Create a file in your app under src/themes/:
| /* src/themes/app.css */ |
| .xpulse-shell { |
| width: min(1100px, calc(100% - 32px)); |
| margin: 32px auto; |
| } |
Important:
- Do not
@importthe base theme βapp.csscontains only local overrides - The file is appended to the end of the bundle
themeAssets()also injectsapp.cssas a separate<link>so that changes take effect in development without a cache rebuild
Theme Switcher
| {% themeAssets() %} |
| {% themeSwitcher() %} |
theme.allow and theme.default in xpulse.json control the switcher:
| { |
| "theme": { |
| "default": "dark", |
| "allow": ["dark", "light"] |
| } |
| } |
allow |
Result |
|---|---|
[] or not set |
All discovered themes are allowed |
["dark", "light"] |
Compact moon/sun toggle button |
["dark", "light", "high-contrast"] |
Select dropdown |
["dark"] |
No switcher rendered |
Caching
The CSS bundle is cached at var/cache/theme/xpulse.css on first start and
read directly from there on subsequent starts.
- In dev mode (
NODE_ENV !== 'production') the cache is always skipped - Use
theme.init({ force: true })to bypass the cache manually - TTL and enabled state are configurable via
xpulse.json:
| { |
| "theme": { |
| "cache": { |
| "enabled": true, |
| "ttl": 0 |
| } |
| } |
| } |
ttl: 0 means no expiry. ttl: 3600 invalidates the cache after 1 hour.
Component Class Naming
CSS classes from @xpulse/theme follow the xpulse-* prefix and BEM:
.xpulse-box/.xpulse-box--header/.xpulse-box--content.xpulse-brand/.xpulse-brand__title.xpulse-nav__item--depth-1.xpulse-button--primary/.xpulse-button--secondary
Related CSS variables use the --xpulse-* prefix.