Skip to content

Commit

Permalink
feat: add runtime theme tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
kripod committed Mar 21, 2020
1 parent d275129 commit 5c527f0
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 37 deletions.
15 changes: 10 additions & 5 deletions packages/example/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { graphql, useStaticQuery } from 'gatsby';
import { GlazeProvider } from 'glaze';
import React from 'react';
import { Helmet } from 'react-helmet';
import { TreatProvider } from 'react-treat';

import theme from '../gatsby-plugin-treat/theme.treat';
import staticThemeRef, {
runtimeTheme,
} from '../gatsby-plugin-treat/theme.treat';

export interface LayoutProps {
children: React.ReactNode;
Expand All @@ -30,12 +33,14 @@ export function Layout({ children }: LayoutProps): JSX.Element {
<meta name="description" content={data.site.siteMetadata.description} />
</Helmet>

<TreatProvider theme={theme}>
<header>{/* TODO */}</header>
<TreatProvider theme={staticThemeRef}>
<GlazeProvider runtimeTheme={runtimeTheme}>
<header>{/* TODO */}</header>

<main>{children}</main>
<main>{children}</main>

<footer>{/* TODO */}</footer>
<footer>{/* TODO */}</footer>
</GlazeProvider>
</TreatProvider>
</React.StrictMode>
);
Expand Down
8 changes: 5 additions & 3 deletions packages/example/src/gatsby-plugin-treat/theme.treat.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { defaultTheme } from 'glaze';
import { createTheme } from 'treat';
import { createTheme, defaultTheme } from 'glaze';

export default createTheme(defaultTheme);
const { staticThemeRef, runtimeTheme } = createTheme(defaultTheme);

export default staticThemeRef;
export { runtimeTheme };
29 changes: 29 additions & 0 deletions packages/glaze/src/GlazeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useContext } from 'react';

import { RuntimeTheme } from './theme';

export const GlazeContext = React.createContext<RuntimeTheme | undefined>(
undefined,
);

export interface GlazeProviderProps {
runtimeTheme: RuntimeTheme;
children: React.ReactNode;
}

export function GlazeProvider({
runtimeTheme,
children,
}: GlazeProviderProps): JSX.Element {
return (
<GlazeContext.Provider value={runtimeTheme}>
{children}
</GlazeContext.Provider>
);
}

export function useRuntimeTheme(): RuntimeTheme {
const theme = useContext(GlazeContext);
if (!theme) throw new Error('No glaze runtime theme provided');
return theme;
}
5 changes: 3 additions & 2 deletions packages/glaze/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { GlazeProvider, useRuntimeTheme } from './GlazeContext';
export { modularScale } from './scales';
export type { DefaultTheme, ScaleTokens } from './theme';
export { defaultTheme } from './theme';
export type { RuntimeTheme, ScaleTokens, Theme } from './theme';
export { createTheme, defaultTheme } from './theme';
export { default as useStyling } from './useStyling';
63 changes: 38 additions & 25 deletions packages/glaze/src/theme.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { CSSProperties } from 'react';
// eslint-disable-next-line import/no-unresolved
import { ThemeOrAny } from 'treat/theme';
import { createTheme as createStaticTheme, ThemeRef } from 'treat';

import { modularScale } from './scales';

export interface RuntimeTheme {
breakpoints: number[];
shorthands: { [key: string]: Array<keyof CSSProperties> };
aliases: {
[key: string]: keyof CSSProperties | keyof RuntimeTheme['shorthands'];
};
}

export interface ScaleTokens<T extends keyof CSSProperties> {
[key: string]: NonNullable<CSSProperties[T]>;
}

export interface DefaultTheme {
breakpoints: number[];
export interface Theme extends RuntimeTheme {
scales: {
spacing?: ScaleTokens<'margin'>;
size?: ScaleTokens<'width'>;
Expand All @@ -26,11 +32,18 @@ export interface DefaultTheme {
opacity?: ScaleTokens<'opacity'>;
zIndex?: ScaleTokens<'zIndex'>;
};
aliases: {
[key: string]: keyof CSSProperties | keyof ThemeOrAny['shorthands'];
resolvers: { [key in keyof CSSProperties]: keyof Theme['scales'] };
}

export function createTheme(
tokens: Theme,
localDebugName?: string,
): { staticThemeRef: ThemeRef; runtimeTheme: RuntimeTheme } {
const { breakpoints, shorthands, aliases } = tokens;
return {
staticThemeRef: createStaticTheme(tokens, localDebugName),
runtimeTheme: { breakpoints, shorthands, aliases },
};
shorthands: { [key: string]: Array<keyof CSSProperties> };
resolvers: { [key in keyof CSSProperties]: keyof ThemeOrAny['scales'] };
}

// TODO: symmetricScale()
Expand All @@ -56,7 +69,7 @@ const spacing = {
64: '16rem',
};

export const defaultTheme: DefaultTheme = {
export const defaultTheme: Theme = {
breakpoints: [640, 768, 1024, 1280],

scales: {
Expand Down Expand Up @@ -98,6 +111,22 @@ export const defaultTheme: DefaultTheme = {
},
},

shorthands: {
// TODO: Remove if widely supported by browsers
inset: ['top', 'right', 'bottom', 'left'],
insetX: ['left', 'right'],
insetY: ['top', 'bottom'],

// TODO: Remove if widely supported by browsers
size: ['width', 'height'],

paddingX: ['paddingLeft', 'paddingRight'],
paddingY: ['paddingTop', 'paddingBottom'],

marginX: ['marginLeft', 'marginRight'],
marginY: ['marginTop', 'marginBottom'],
},

aliases: {
p: 'padding',
px: 'paddingX',
Expand All @@ -120,22 +149,6 @@ export const defaultTheme: DefaultTheme = {
bg: 'background',
},

shorthands: {
// TODO: Remove if widely supported by browsers
inset: ['top', 'right', 'bottom', 'left'],
insetX: ['left', 'right'],
insetY: ['top', 'bottom'],

// TODO: Remove if widely supported by browsers
size: ['width', 'height'],

paddingX: ['paddingLeft', 'paddingRight'],
paddingY: ['paddingTop', 'paddingBottom'],

marginX: ['marginLeft', 'marginRight'],
marginY: ['marginTop', 'marginBottom'],
},

resolvers: {
top: 'spacing',
right: 'spacing',
Expand Down
4 changes: 2 additions & 2 deletions packages/glaze/src/treat.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DefaultTheme } from 'glaze';
import { Theme as GlazeTheme } from 'glaze';

declare module 'treat/theme' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Theme extends DefaultTheme {}
export interface Theme extends GlazeTheme {}
}

0 comments on commit 5c527f0

Please sign in to comment.