Skip to content

Theming

Restyle GistUI with theme presets, tokens, CSS variables and style hooks, and make it work with Tailwind.

Updated View as Markdown

There are four levels of control, from least to most. Most apps stop at the second.

1. Presets

<GistUI library={ui} stream={stream} theme="system" color="violet" />
  • theme: "system" (default), "light" or "dark".
  • color: neutral, slate, stone, rose, pink, violet, indigo, blue, teal, green, orange, amber, red.

A program can pick its own accent with Page(…, accent:teal). Your tokens (below) override it.

Preview

Loading preview…

root = Grid(Box(Header("Teal", size:sm), Progress(64, "Progress"), Button("Action"), accent:teal, pad:md, surface:card, gap:md), Box(Header("Rose", size:sm), Progress(64, "Progress"), Button("Action"), accent:rose, pad:md, surface:card, gap:md), Box(Header("Amber", size:sm), Progress(64, "Progress"), Button("Action"), accent:amber, pad:md, surface:card, gap:md), cols:3)

2. Tokens from code

Tokens are scoped to one instance and override presets and model accents.

import { defineTheme } from "@gistui/react";

const brand = defineTheme({
  primary: "#0f766e",
  accent: "#0d9488",
  radius: 14,
  density: 0.9,
  font: "Geist, sans-serif",
  chart: ["#0d9488", "#f59e0b"],
});

<GistUI library={ui} tokens={brand} darkTokens={{ primary: "#2dd4bf", primaryFg: "#042f2e" }} stream={stream} />;

3. CSS variables and style hooks

Every token is a --gistui-* custom property, and you can set any of them in plain CSS:

.gistui {
  --gistui-radius: 6px;
  --gistui-font: "Geist", sans-serif;
}

Every component also carries attributes to select on:

[data-gistui="Card"] { box-shadow: 0 1px 2px rgb(0 0 0 / 0.06); }
[data-gistui="Tag"][data-tone="success"] { font-weight: 600; }
[data-gistui="Button"][data-v="primary"] { text-transform: uppercase; }
  • data-gistui="Name" on the root of each component.
  • data-v, data-tone, data-size for its variants.
  • data-gistui-color, data-gistui-radius, data-gistui-density on the container for presets.

All GistUI CSS is in @layer gistui. Unlayered CSS in your app wins without !important.

4. Your own components

When CSS is not enough, replace the component and keep its schema: Custom components.

With Tailwind

Tailwind’s reset and utilities are in cascade layers too. The order must be: reset, then GistUI, then utilities.

@layer theme, base, gistui, components, utilities;

@gistui/styles/styles.css declares that order itself, so import it before your Tailwind CSS:

import "@gistui/styles/styles.css";
import "./app.css"; // @import "tailwindcss";

Utility classes passed through classNames then win over component styles:

<GistUI library={ui} classNames={{ Card: "shadow-lg", Button: "rounded-full" }} stream={stream} />

Light and dark

theme="system" follows prefers-color-scheme. If your app has its own toggle, pass "light" or "dark" from it. These docs do exactly that for every live preview.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close