Skip to content

Latest commit

 

History

179 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@askrjs/themes

CI npm version

CSS tokens and a styled component catalog for Askr apps.

@askrjs/themes is the visual companion to @askrjs/ui and @askrjs/charts. It owns the default theme and styled component catalog while behavior stays in @askrjs/ui and chart components stay in @askrjs/charts.

Install

npm install @askrjs/themes @askrjs/ui

Quick Start

Import the default theme CSS in your app stylesheet:

@import "@askrjs/themes/default";

Add the optional cat preset layer after the default theme when you want the curated preset family:

@import "@askrjs/themes/default";
@import "@askrjs/themes/presets";

For a small page that only uses individual controls, import their JavaScript and CSS independently instead of the full default theme:

import { Input } from "@askrjs/themes/input";
import { Label } from "@askrjs/themes/label";
import "@askrjs/themes/default/foundations.css";
import "@askrjs/themes/default/input.css";
import "@askrjs/themes/default/label.css";

The foundations entry contains tokens and base/reset styles. Component CSS entries contain only that component's styles. @askrjs/themes/default remains the batteries-included theme.

See Acknowledgements for the open-source projects that inspired parts of the design philosophy.

For documentation search and command launchers, use the accessible CommandPalette composition from @askrjs/themes/command; it owns themed presentation while @askrjs/ui supplies dialog focus and dismissal behavior.

Then set data-theme to tabby, ginger, tuxedo, calico, or torty. For picker/toggle composition, import CAT_THEME_OPTIONS and CAT_THEME_NAMES from @askrjs/themes/theme.

Then use the theme helpers and component catalog:

import { ThemeScope, ThemeToggle } from "@askrjs/themes/theme";
import { Button, ButtonGroup, Field, Input, InputGroup, Label } from "@askrjs/themes/components";

export function AppShell() {
  return (
    <ThemeScope>
      <ButtonGroup>
        <Button variant="primary">Save</Button>
        <ThemeToggle>{({ nextTheme }) => nextTheme}</ThemeToggle>
      </ButtonGroup>

      <Field>
        <Label for="workspace">Workspace</Label>
        <InputGroup>
          <Input id="workspace" name="workspace" />
        </InputGroup>
      </Field>
    </ThemeScope>
  );
}

SSR and SSG

Layout props on Block, Container, Grid, AspectRatio, and Skeleton produce CSP-compatible generated rules. Wrap the Askr document renderer so those rules are serialized into the initial document and adopted during hydration:

import type { DocumentRenderArgs } from "@askrjs/askr/ssg";
import { withThemeStyles } from "@askrjs/themes/ssr";

function renderDocument({ appHtml }: DocumentRenderArgs) {
  return `<!doctype html><html><head></head><body><div id="app">${appHtml}</div></body></html>`;
}

export const staticConfig = {
  // ...
  document: withThemeStyles(renderDocument),
};

The wrapper also applies context.cspNonce to the emitted style registry and requires the request-local style registrations provided by Askr 0.0.85 or newer. It fails clearly if generated classes and their registered rules ever diverge instead of emitting unstyled markup. Use the same wrapper for an SSR document callback.

What To Import

  • @askrjs/themes/components for the styled component catalog.
  • @askrjs/themes/<component> for package subpaths such as @askrjs/themes/button, @askrjs/themes/card, and @askrjs/themes/dialog.
  • @askrjs/themes/theme for ThemeScope, ThemePicker, ThemeToggle, and theme.
  • @askrjs/themes/ssr for the SSR/SSG generated-style document wrapper.
  • @askrjs/charts for charts; chart components are intentionally not exported from @askrjs/themes.

Styling-only compatibility wrappers

DataTable, ResizablePanelGroup, ResizablePanel, and ResizableHandle are styling-only catalog compatibility wrappers. Their names do not promise a data-grid or panel-resizing runtime:

  • DataTable provides a data-table container slot. It does not sort, filter, select, or paginate. Compose semantic Table or VirtualTable primitives from @askrjs/ui and keep data operations in application-owned state.
  • ResizablePanelGroup, ResizablePanel, and ResizableHandle provide layout and separator slots only. The group does not implement pointer or keyboard resizing, track dimensions, or provide the ARIA value state required by an interactive splitter.

These names remain exported for catalog compatibility. If an application needs real resize behavior today, supply the pointer, keyboard, sizing, and ARIA contract in application code or a dedicated behavior dependency. A future Askr resize primitive must be implemented and tested in @askrjs/ui before themes can compose and style it.

Theme Contract

  • Style public data-* hooks and token variables, not internal DOM structure.

  • Prefer token overrides before component overrides.

  • Keep selectors low specificity so downstream apps can customize them cleanly.

  • Use THEMING.md and docs/architecture.md for the full contract and package boundaries.

  • Use docs/component-anatomy.md for stable slot hooks and docs/customization.md for the KISS customization path.

  • Use docs/recipes.md for copyable login, admin shell, settings form, table, dropdown, and detail-page patterns.

  • Use visual-check.html for manual QA across light and dark modes.

About

Default theme tokens, styles, and component presets for Askr applications.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages