Skip to content

everweij/design-tokens-ts-styled-components

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Manage design tokens with TypeScript and styled-components

This repository contains the code I talked about in my blog-post Manage design tokens with TypeScript and styled-components.

Feel free to clone this repo and adjust it to your needs.

tsdx

This repo was created with the help of tsdx: Zero-config CLI for TypeScript package development

Getting Started

1. Adjust / complement the theme.ts file to your needs

Let's say you wanted to add box-shadow's:

// theme.ts

/**
 * A. Add tokens to your theme
 */
const theme = {
  // colors, spaces, ...etc

  shadow: {
    light: "1px 1px 1px 1px rgba(0, 0, 0, 0.1)",
    normal: "1px 1px 3px 1px rgba(0, 0, 0, 0.2)",
    strong: "1px 1px 5px 1px rgba(0, 0, 0, 0.3)"
  }
};

export default theme;

export type Theme = typeof theme;
export type ThemeProps = { theme?: Theme };

/**
 * B. Create a type from each token
 */

export type Shadow = keyof Theme["shadow"];

2. Create a 'getter'

// getters.ts

import { ThemeProps, Shadow } from "./theme";

function getTheme(props: ThemeProps) {
  return props.theme && props.theme.colors ? props.theme : defaultTheme;
}

export function getShadow(shadow: Shadow, props: ThemeProps) {
  return getTheme(props).shadow[shadow];
}

3. Create a 'selector'

// selectors.ts

import { ThemeProps } from "./theme";
// import the getter we've just created
import { getShadow } from "./getters";

// implementation skipped for brevity
function createSelector {};

export const shadow = createSelector(getShadow);

4. Complement the hook

// useTheme.tsx

// import the getter we've just created
import { getShadow } from "./getters";

export default function useTheme() {
  const theme = useContext(ThemeContext);

  return useMemo(() => {
    const themeProps = { theme };

    return {
      // other selectors here...

      shadow: partialGetter(getShadow, themeProps)
    };
  }, [theme]);
}

Usage

styled-components

import * as React from "react";
import * as ReactDOM from "react-dom";
import styled, { ThemeProvider } from "styled-components";
import { defaultTheme, theme } from "@company/theme";

const Test = styled.div`
  color: ${theme.color("grey", 9)};
  margin-top: ${theme.space(2)};
  box-shadow: ${theme.shadow("normal")};
`;

function App() {
  return (
    <ThemeProvider theme={defaultTheme}>
      <Test>Theme with styled-components!!!</Test>
    </ThemeProvider>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));

Hook

import * as React from "react";
import { useTheme } from "@company/theme";

function Test() {
  const theme = useTheme();

  return (
    <div
      style={{
        color: theme.color("grey", 9),
        marginTop: theme.space(2),
        boxShadow: theme.shadow("normal")
      }}
    >
      Theme with hooks!!!
    </div>
  );
}

About

Manage design tokens with typescript and styled-components

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published