Skip to content

Design tokens, seat styles · Anywhere

@openseat/theme-default

Default design tokens and seat state styles for OpenSeat.

Default design tokens for OpenSeat: the canvas theme (seats, zones, stages, dividers) and the interface tokens shared by the editor and your own pages.

  • 8 functions
  • 11 interfaces
  • 3 types
  • 6 constants
  • MIT
npm i @openseat/theme-default
first npm release pending

Install commands show the public npm names. The first npm release is pending; the packages are free and MIT licensed.

Import
import {
  createTheme,
  defaultTheme,
  resolveSeatStyle,
  uiTokens,
} from "@openseat/theme-default";
import type { Theme } from "@openseat/theme-default";

Functions8

function

accessibleGlyphColourOn

The accessible-seat pictogram colour for a seat filled with fill: the theme's accessibleGlyph or accessibleGlyphOnDark, whichever contrasts more. Fills that are not #rrggbb get accessibleGlyph.

function accessibleGlyphColourOn(
  theme: Theme,
  fill: string,
): string;

Parameters

ParameterTypeDescription
themeTheme
fillstring

Returns

string

@openseat/theme-default/src/index.ts

function

contrastRatio

WCAG contrast ratio between two #rrggbb colours (1 to 21).

function contrastRatio(a: string, b: string): number;

Parameters

ParameterTypeDescription
astring
bstring

Returns

number

@openseat/theme-default/src/index.ts

function

createTheme

Returns a complete theme with overrides applied over base (the default theme unless given).

function createTheme(
  overrides?: ThemeOverrides,
  base?: Theme,
): Theme;

Parameters

ParameterTypeDescription
overridesoptionalThemeOverrides

Default {}

baseoptionalTheme

Default defaultTheme

Returns

Example

theme.tsx
import { createTheme } from "@openseat/theme-default";
import { BookingMap } from "@openseat/react";
import type { LayoutDocument } from "@openseat/core";

// Canvas tokens: deep-merged over the default theme, never mutated.
const theme = createTheme({
  fontFamily: "Geist, system-ui, sans-serif",
  canvas: { background: "#FFFFFF" },
  seat: { selected: { fill: "#4F46E5", stroke: "#3730A3" } },
});

export const Buyer = ({ layout }: { layout: LayoutDocument }) => <BookingMap layout={layout} theme={theme} />;

Recipe: theming tokens

@openseat/theme-default/src/index.ts

function

relativeLuminance

WCAG relative luminance of a #rrggbb colour.

function relativeLuminance(hex: string): number;

Parameters

ParameterTypeDescription
hexstring

Returns

number

@openseat/theme-default/src/index.ts

function

resolveSeatStyle

Resolves the style for a seat. Category colours only apply to available seats, so unavailable seats always look unavailable regardless of category.

function resolveSeatStyle(
  theme: Theme,
  state: SeatVisualState,
  categoryColour?: string,
): SeatStateStyle;

Parameters

ParameterTypeDescription
themeTheme
stateSeatVisualState
categoryColouroptionalstring

Returns

@openseat/theme-default/src/index.ts

function

shade

Lightens (amount > 0) or darkens (amount < 0) a #rrggbb colour. Other colour formats are returned unchanged.

function shade(hex: string, amount: number): string;

Parameters

ParameterTypeDescription
hexstring
amountnumber

Returns

string

@openseat/theme-default/src/index.ts

function

uiTokenCssVariables

The tokens as CSS custom properties: --os-ui-<name> for colours, --os-ui-radius-<size>, --os-ui-shadow-<size>, --os-ui-font-<name> and --os-ui-tap-target. Set them on :root (or any container) to theme the chrome.

function uiTokenCssVariables(
  tokens?: UiTokens,
): Record<string, string>;

Parameters

ParameterTypeDescription
tokensoptionalUiTokens

Default uiTokens

tokens takes UiTokens:

  • colour { readonly bg: string; readonly surface: string; readonly surfaceMuted: string; readonly border: string; readonly borderStrong: string; readonly text: string; readonly textMuted: string; readonly accent: string; readonly accentHover: string; readonly onAccent: string; readonly accentSoft: string; readonly success: string; readonly successSoft: string; readonly warning: string; readonly warningSoft: string; readonly d …
  • radius { readonly sm: string; readonly md: string; readonly lg: string; readonly pill: string; }
  • shadow { readonly sm: string; readonly md: string; readonly lg: string; }
  • font { readonly family: string; readonly numeric: string; readonly sizeSm: string; readonly sizeMd: string; readonly sizeLg: string; readonly sizeXl: string; }
  • tapTarget number

Returns

Record<string, string>

@openseat/theme-default/src/index.ts

function

zonePaint

Paint of an available zone in its tier colour tint, as in a venue zone map: the tint mixed toward white by theme.zone.fillMix as an opaque fill, the tint itself as the outline (theme.zone.strokeWidth wide), and the tint darkened by theme.zone.labelDarken for the label, darkened further (toward black) until it reaches 4.5:1 contrast on the fill; on a fill too dark for that (a theme mixing little toward white) the label is lightened instead, so the label always has 4.5:1 contrast. A tint that is not a hex colour is used as the outline over the theme's GA fill, with the theme's label colour.

function zonePaint(tint: string, theme?: Theme): ZonePaint;

Parameters

ParameterTypeDescription
tintstring
themeoptionalTheme

Default defaultTheme

Returns

@openseat/theme-default/src/index.ts

Interfaces11

interface

AreaStyle

interface AreaStyle

Members

MemberTypeDescription
fillstring
strokestring
strokeWidthnumber
labelColourstring

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

DividerStyle

Floor dividers: a thin line (a path with a caption) broken around a small letter-spaced caption.

interface DividerStyle

Members

MemberTypeDescription
strokestring
strokeWidthnumber

Line width: in screen pixels on a buyer's map (it stays visible zoomed out), in layout units when editing.

captionColourstring
captionSizenumber

Caption font size when the path has no captionSize.

letterSpacingnumber

Caption letter spacing, in em.

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

OutlineStyle

interface OutlineStyle

Members

MemberTypeDescription
strokestring
strokeWidthnumber
dashreadonly number[]

Dash pattern in screen pixels. Empty for a solid line.

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

SeatStateStyle

interface SeatStateStyle

Members

MemberTypeDescription
fillstring
strokestring
strokeWidthnumber
opacitynumber
markerSeatMarker
markerColourstring
labelstring

Human-readable name used in legends and accessible text.

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

SoldOutStyle

A zone, area or table that is sold out: light grey with grey text and no tint.

interface SoldOutStyle

Members

MemberTypeDescription
fillstring
strokestring
labelColourstring

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

StageLabelStyle

How a stage's label is typeset: upper-case, letter-spaced and lightly weighted, like venue signage.

interface StageLabelStyle

Members

MemberTypeDescription
letterSpacingnumber

Extra space between letters, in em.

uppercaseboolean
fontStylestring

CSS font weight or style ("500", "bold", "normal").

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

StageStyle

Stage paint: an area style plus the corner rounding of a rectangular stage without its own cornerRadius.

interface StageStyle extends AreaStyle

Extends AreaStyle

Members

MemberTypeDescription
cornerRadiusFractionnumber

Default corner radius of a rect (and thrust) stage, × the shorter side of its box.

fillstring

From AreaStyle

strokestring

From AreaStyle

strokeWidthnumber

From AreaStyle

labelColourstring

From AreaStyle

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

Theme

interface Theme

Members

MemberTypeDescription
fontFamilystring
canvas{ readonly background: string; readonly grid: string; readonly bounds: string; }
seat{ readonly [S in SeatVisualState]: SeatStateStyle; }
useCategoryColoursboolean

When true, available seats are filled with their category colour (when the category defines one) instead of the available fill.

seatLabel{ readonly colour: string; readonly fontSize: number; }
rowLabel{ readonly colour: string; readonly fontSize: number; }
hoverOutlineStyle
focusOutlineStyle
selectionOutlineStyle
marquee{ readonly fill: string; readonly stroke: string; }
guide{ readonly stroke: string; }
sectionAreaStyle
polygonAreaStyle
tableAreaStyle
boothAreaStyle
stageStageStyle

Stages: a soft light-grey rounded box with a thin border and a muted label.

stageLabelStageLabelStyle
zoneZoneStyle
soldOutSoldOutStyle
dividerDividerStyle
footnoteColourstring

Colour of footnotes ("All the sections are seated").

entranceAreaStyle
aisle{ readonly fill: string; }
path{ readonly stroke: string; }
label{ readonly colour: string; }
issueOutlineStyle

Outline drawn around objects with validation issues (edit mode).

venue{ readonly fill: string; readonly stroke: string; readonly labelColour: string; }

The venue outline (layout.venue), drawn beneath every object.

ga{ readonly fill: string; readonly stroke: string; readonly labelColour: string; }

General-admission areas.

grid{ readonly stroke: string; readonly majorStroke: string; }

Edit-mode grid lines: majorStroke every fifth line.

handle{ readonly fill: string; readonly stroke: string; }

Vertex and row-extension handles.

focalPoint{ readonly stroke: string; }

Edit-mode marker of layout.focalPoint.

seatMark{ readonly stroke: string; }

Ring drawn around seats tagged "marked", in edit mode only.

fieldMarking{ readonly red: string; readonly blue: string; }

Field markings drawn inside a stage with markings (rink, court, pitch): the rink's red and blue lines. Other lines contrast with the stage fill.

dimOpacitynumber

Opacity of objects outside the focused scope (0..1).

accessibleGlyphstring

Colour of the wheelchair pictogram and companion mark drawn on accessible seats, and of the ring that replaces them when seats are tiny on screen. Used on light seat fills; see Theme.accessibleGlyphOnDark.

accessibleGlyphOnDarkstring

Colour of the accessible-seat pictogram on dark seat fills (selected, or a dark category colour). accessibleGlyphColourOn picks between the two.

notForSalestring

Fill of GA areas, booths and tables drawn in the "blocked" (Not for sale) state. They also carry a diagonal hatch, so the state does not rely on colour.

notForSaleHatchstring

Colour of the diagonal hatch drawn over not-for-sale areas, booths and tables.

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

UiTokens

Design tokens for the interface around the map, so hosts and the playground share one visual system: colours, corner radii, shadows, type and the minimum touch target. uiTokenCssVariables turns them into CSS custom properties (--os-ui-accent, --os-ui-radius-md, …).

interface UiTokens

Members

MemberTypeDescription
colour{ readonly bg: string; readonly surface: string; readonly surfaceMuted: string; readonly border: string; readonly borderStrong: string; readonly text: string; readonly textMuted: string; readonly accent: string; readonly accentHover: string; readonly onAccent: string; readonly accentSoft: string; readonly success: string; readonly successSoft: string; readonly warning: string; readonly warningSoft: string; readonly d …(shortened)
radius{ readonly sm: string; readonly md: string; readonly lg: string; readonly pill: string; }
shadow{ readonly sm: string; readonly md: string; readonly lg: string; }
font{ readonly family: string; readonly numeric: string; readonly sizeSm: string; readonly sizeMd: string; readonly sizeLg: string; readonly sizeXl: string; }
tapTargetnumber

Smallest touch target, in CSS pixels (WCAG 2.5.5 and platform guidance: 44px).

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

ZonePaint

How a zone is painted: its opaque fill, outline and label colour.

interface ZonePaint

Members

MemberTypeDescription
fillstring
strokestring
strokeWidthnumber
labelColourstring

At least 4.5:1 contrast on fill (for a #rrggbb or #rgb tint).

Every member is readonly.

@openseat/theme-default/src/index.ts

interface

ZoneStyle

Zones: places sold by quantity (GA areas and sections shown as zones). A zone is filled with its tier colour mixed toward white, outlined in the full colour, and labelled in a dark shade of it (see zonePaint).

interface ZoneStyle

Members

MemberTypeDescription
fillMixnumber

How far the tint is mixed toward white for the fill (0 = the tint, 1 = white).

strokeWidthnumber

Outline width: in screen pixels on a buyer's map (it stays visible zoomed out), in layout units when editing.

labelDarkennumber

How far the tint is darkened for the label (raised further when needed for 4.5:1 contrast).

cornerRadiusFallbacknumber

Corner radius of a zone section without its own cornerRadius.

uppercaseboolean

Zone labels are drawn upper-case.

Every member is readonly.

@openseat/theme-default/src/index.ts

Types3

type

SeatMarker

A mark drawn inside the seat. States must not rely on colour alone, so unavailable states carry a shape cue as well.

type SeatMarker = "none" | "check" | "dot" | "cross" | "dash";

@openseat/theme-default/src/index.ts

type

SeatVisualState

Visual states a seat can be drawn in. These are presentation states, not inventory truth: the booking layer maps host-supplied statuses onto them.

type SeatVisualState =
  "available" | "selected" | "held" | "booked" | "blocked";

@openseat/theme-default/src/index.ts

type

ThemeOverrides

Recursive partial used for theme overrides. Arrays are replaced, not merged.

type ThemeOverrides<T = Theme> = {
  -readonly [K in keyof T]?: T[K] extends readonly unknown[]
    ? T[K]
    : T[K] extends object
      ? ThemeOverrides<T[K]>
      : T[K];
};

@openseat/theme-default/src/index.ts

Constants6

const

ACCESSIBLE_SEAT_LABEL

Legend label for seats with the wheelchair flag (and the pictogram drawn on them).

const ACCESSIBLE_SEAT_LABEL = "Accessible seat"

@openseat/theme-default/src/index.ts

const

COMPANION_SEAT_LABEL

Legend label for companion seats (the small companion mark).

const COMPANION_SEAT_LABEL = "Companion seat"

@openseat/theme-default/src/index.ts

const

defaultTheme

Neutral palette. State colours were chosen so that available, selected and held remain distinguishable for the common colour-vision deficiencies, and booked/blocked carry a cross marker as a non-colour cue.

const defaultTheme: Theme

@openseat/theme-default/src/index.ts

const

LEGEND_LABELS

Legend labels for the marks and states drawn beside the per-state seat styles.

const LEGEND_LABELS: {
  readonly available: "Available";
  readonly accessible: "Accessible seat";
  readonly companion: "Companion seat";
  readonly notForSale: "Not for sale";
  readonly reserved: "Reserved";
  readonly soldOut: "Sold out";
}

@openseat/theme-default/src/index.ts

const

SEAT_VISUAL_STATES

const SEAT_VISUAL_STATES: readonly SeatVisualState[]

@openseat/theme-default/src/index.ts

const

uiTokens

const uiTokens: UiTokens

@openseat/theme-default/src/index.ts