system-ui / theme-specification

A specification for defining theme objects & design tokens for use with UI components

Home Page:https://system-ui.com/theme

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeScript theme definition

djgrant opened this issue · comments

Would this be a good place to keep a TS definition for theme objects? This would be helpful when implementing a spec-compliant library and improve dev experience of existing libraries.

I hacked this up real quick for a side project I'm working on. It has some extra that's not standard so delete away!

interface ThemeUiSpec {
  borders?: { [name: string]: number }
  borderStyles?: { [name: string]: number }
  borderWidths?: { [name: string]: number }
  colors?:
    | { [name: string]: string }
    | { "modes"?: { [name: string]: string } }
  fonts?: { [name: string]: string }
  fontSizes?: { [name: string]: number }
  fontWeights?: { [name: string]: number }
  letterSpacings?: { [name: string]: number }
  lineHeights?: { [name: string]: number }
  radii?: { [name: string]: number }
  space?: { [name: string]: number }
  sizes?: { [name: string]: number }
  transitionDurations?: { [name: string]: number }
  transitionTiming?: {
    [name: string]: {
      "x1": number,
      "y1": number,
      "x2": number,
      "y2": number,
    }
  }
  zIndices?: { [name: string]: number }
}

An important question regarding this :

Can a value be an alias of another value ?

I mean :

colors: {
  red: '#F33',
  primary: 'red' <== what does it do ?
}

@cyrilchapon currently values in the theme scales cannot self-reference, so 'red' would be the CSS color keyword and not the value defined on the line above in your example ('#F33') – to make theme objects completely JSON-serializable in the future, we might want some mechanism to do that, but it doesn't currently work that way

@crswll very helpful, thanks! I am modifying it slightly for my use. I am using the 'styled-system' library, and I think the following interface is closer to what that library specifically uses (although I haven't tested it yet, and the library unfortunately isn't written in ts).

type ArrayStringNumber = (string|number)[];
type ObjStringNumber = {[key:string]: number | string};
type ArrayOrObjStringNumber = ArrayStringNumber|ObjStringNumber;
export type SimpleColors = {[key:string]:string};
export type NestedColors = {[key:string]:{[key:string]:string}};
export type Colors = SimpleColors|NestedColors;
export interface Theme {
    breakpoints: {[key: string]: number}|number[]
    borders?: ArrayOrObjStringNumber
    borderStyles?: { [key: string]: string }
    borderWidths?: ArrayOrObjStringNumber
    colors?: Colors
    fonts?: { [key: string]: string }
    fontSizes?: ArrayOrObjStringNumber
    fontWeights?: { [key: string]: number }|number[]
    letterSpacings?: ArrayOrObjStringNumber
    lineHeights?: ArrayOrObjStringNumber
    radii?: ArrayOrObjStringNumber
    space?: ArrayOrObjStringNumber
    sizes?: ArrayOrObjStringNumber
    transitionDurations?: { [key: string]: number }
    transitionTiming?: {
      [key: string]: {
        "x1": number,
        "y1": number,
        "x2": number,
        "y2": number,
      }
    }
    zIndices?: { [key: string]: number }
  }