Home

Awesome

<!-- markdownlint-disable MD026 MD033 MD041 --> <div align="center">

theme-in-css

npm npm-dl

</div>

Why?

Usage

First create your theme object, you can group theme variables by its function (color, spacing, etc). Think of it as design token

import { createTheme } from 'theme-in-css';

export const Theme = createTheme({
  color: {
    lightPrimary: '#fff',
    darkPrimary: '#000',
  },
  spacing: {
    xs: 2,
    s: 4,
    m: 8,
    l: 16,
    xl: 32,
  },
  typography: {
    family: {
      serif: 'Times New Roman',
      sans: 'Calibri',
      mono: 'Menlo',
    },
  }
});

// If you hate typing you can also use a shorter property name
// const t = createTheme({ c: { l1: '#fff', d1: '#000' } });

You can use any any UI libraries/framework that can define style in JS/TS, for example React and Lit.

// React
import React from 'react';
import { Theme } from './theme';

export default function Component() {
  // use css prop via emotion/styled-components
  // of course inline style works as well
  return (
    <div
      css={{
        backgroundColor: Theme.color.darkPrimary,
        color: Theme.color.lightPrimary,
        margin: Theme.spacing.m,
        fontFamily: Theme.typography.family.serif,
      }}
    >
      <h1>It works</h1>
    </div>
  );
}

// Lit
// You need to wrap Theme inside `unsafeCSS`
import { LitElement, html, css, unsafeCSS as cv } from 'lit';
import { Theme } from './theme';

export default class Component extends LitElement {
  static styles = css`
    div {
      background-color: ${cv(Theme.color.darkPrimary)};
      color: ${cv(Theme.color.lightPrimary)};
      margin: ${cv(Theme.spacing.m)};
      font-family: ${cv(Theme.typography.family.serif)};
    }
  `;

  render() {
    return html`
      <div>
        <h1>It works</h1>
      </div>
    `;
  }
}

CSS Integration

If you only create theme and use them in your app, you'll notice that your app now uses CSS variables to reference a value, but it doesn't work properly yet because you need to add the CSS into your stylesheet.

.css.string: string

theme-in-css provides .css.string property to dump all theme values as CSS properties. You can create 2 themes light and dark and output them in different style declaration, like this:

import { Theme, DarkTheme } from './theme';

const html = `
<!doctype head>
<html>
  <head>
    <style>
      :root {
        ${Theme.css.string}
      }

      @media (prefers-color-scheme: dark) {
        ${DarkTheme.css.string}
      }
    </style>
  </head>
  <body>
  </body>
</html>
`;

You can open example to see it in action.

.css.properties: Array<[key: string, value: string]>

You can also use .css.properties if you want to update the CSS custom property manually using JS.

const root = document.documentElement;

theme.css.properties.forEach(([key, value]) => {
  root.style.setProperty(key, value);
});

If you prefer Record<string, string> instead, you can use Object.fromEntries

const obj = Object.fromEntries(theme.css.properties);

License

MIT