-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Remove redundant files * Add utilities * Add VariableGenerator component * Implement new create * Expose api * Update tsconfig * Update version * Update next config * Update dev environment
- Loading branch information
Showing
20 changed files
with
349 additions
and
338 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
"use client"; | ||
|
||
import * as React from "react"; | ||
import { VariantSelector } from "./theming"; | ||
|
||
type Props = { | ||
children?: React.ReactNode; | ||
}; | ||
|
||
const Tokens = (props: Props) => { | ||
const { children } = props; | ||
|
||
return <VariantSelector variant="light">{children}</VariantSelector>; | ||
}; | ||
|
||
export default Tokens; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,64 @@ | ||
import { createTheming, defaultCssVariableGenerator } from "../lib"; | ||
import { create } from "../lib"; | ||
|
||
export const theme = { | ||
colors: { | ||
primary: { | ||
base: "1", | ||
hover: "2", | ||
active: "3", | ||
disabled: "4", | ||
}, | ||
secondary: { | ||
base: "5", | ||
hover: "6", | ||
active: "7", | ||
disabled: "8", | ||
const variants = { | ||
dark: { | ||
colors: { | ||
primary: { | ||
base: "d1", | ||
hover: "d2", | ||
active: "d3", | ||
disabled: "d4", | ||
}, | ||
secondary: { | ||
base: "d5", | ||
hover: "d6", | ||
active: "d7", | ||
disabled: "d8", | ||
}, | ||
neutral: { | ||
text: { | ||
base: "d9", | ||
secondary: "d10", | ||
tertiary: "d11", | ||
}, | ||
background: { | ||
base: "d12", | ||
container: "d13", | ||
elevated: "d14", | ||
}, | ||
}, | ||
}, | ||
neutral: { | ||
text: { | ||
base: "9", | ||
secondary: "10", | ||
tertiary: "11", | ||
boolean: true, | ||
}, | ||
light: { | ||
colors: { | ||
primary: { | ||
base: "l1", | ||
hover: "l2", | ||
active: "l3", | ||
disabled: "l4", | ||
}, | ||
background: { | ||
base: "12", | ||
container: "13", | ||
elevated: "14", | ||
secondary: { | ||
base: "l5", | ||
hover: "l6", | ||
active: "l7", | ||
disabled: "l8", | ||
}, | ||
neutral: { | ||
text: { | ||
base: "l9", | ||
secondary: "l10", | ||
tertiary: "l11", | ||
}, | ||
background: { | ||
base: "l12", | ||
container: "l13", | ||
elevated: "l14", | ||
}, | ||
}, | ||
}, | ||
boolean: false, | ||
}, | ||
dark: 1, | ||
}; | ||
|
||
const tokenFamilyNameMap: Record<keyof typeof theme, string> = { | ||
colors: "color", | ||
dark: "dark", | ||
}; | ||
|
||
export const { ThemeProvider, useTheme, getVariablesAsStyles } = createTheming( | ||
theme, | ||
{ | ||
initializeVariablesOnHTMLRoot: true, | ||
cssVariableGenerator: (tokenFamilyKey, tokenPath, tokenValue) => | ||
defaultCssVariableGenerator( | ||
tokenFamilyNameMap[tokenFamilyKey].toLowerCase(), | ||
tokenPath, | ||
tokenValue, | ||
), | ||
}, | ||
); | ||
export const { VariantSelector, useTokens } = create(variants); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import * as React from "react"; | ||
import { generateCssVariables, getCSSVariablesAsInlineStyle } from "./utils"; | ||
|
||
export type Props = { | ||
children?: React.ReactNode; | ||
tokens: Record<string, unknown>; | ||
variant: string; | ||
disableCSSVariableGeneration: boolean; | ||
cssVariableGenerator: (context: { | ||
tokenFamilyKey: string; | ||
tokenKey: string; | ||
tokenPath: string; | ||
tokenValue: unknown; | ||
}) => { variableName: string; variableValue: string } | null; | ||
}; | ||
|
||
export type CSSVariableGenerator = NonNullable<Props["cssVariableGenerator"]>; | ||
export type GeneratedCSSVariable = ReturnType<CSSVariableGenerator>; | ||
export type GeneratedCSSVariables = Array<GeneratedCSSVariable>; | ||
|
||
const VariableGenerator = (props: Props) => { | ||
const { | ||
children, | ||
tokens, | ||
variant, | ||
disableCSSVariableGeneration, | ||
cssVariableGenerator, | ||
} = props; | ||
|
||
const cssVariables = React.useMemo<GeneratedCSSVariables>( | ||
() => | ||
disableCSSVariableGeneration | ||
? [] | ||
: generateCssVariables(tokens, cssVariableGenerator), | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[variant, disableCSSVariableGeneration], | ||
); | ||
|
||
const cssVariableProps = React.useMemo<React.CSSProperties>( | ||
() => | ||
disableCSSVariableGeneration | ||
? {} | ||
: getCSSVariablesAsInlineStyle(cssVariables), | ||
[cssVariables, disableCSSVariableGeneration], | ||
); | ||
|
||
return ( | ||
<div | ||
data-name="VariantGenerator" | ||
data-variant={variant} | ||
style={cssVariableProps} | ||
> | ||
{children} | ||
</div> | ||
); | ||
}; | ||
|
||
export default VariableGenerator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export { | ||
default, | ||
type CSSVariableGenerator, | ||
type GeneratedCSSVariable, | ||
type Props, | ||
} from "./VariableGenerator"; | ||
export { | ||
defaultCSSVariableGenerator, | ||
generateCssVariables, | ||
getCSSVariablesAsInlineStyle, | ||
} from "./utils"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { isPlainObject } from "../utils"; | ||
import type { | ||
CSSVariableGenerator, | ||
GeneratedCSSVariable, | ||
GeneratedCSSVariables, | ||
Props, | ||
} from "./VariableGenerator"; | ||
|
||
export const defaultCSSVariableGenerator: CSSVariableGenerator = context => { | ||
const { tokenFamilyKey, tokenPath, tokenValue } = context; | ||
|
||
if (!["string", "number"].includes(typeof tokenValue)) return null; | ||
|
||
const pathString = tokenPath.replaceAll(".", "-").toLowerCase(); | ||
const name = `${tokenFamilyKey.toLowerCase()}${pathString.length > 0 ? "-" : ""}${pathString}`; | ||
|
||
const value = | ||
typeof tokenValue === "number" ? `${tokenValue}px` : String(tokenValue); | ||
|
||
return { | ||
variableName: name, | ||
variableValue: value, | ||
}; | ||
}; | ||
|
||
export const generateCssVariables = ( | ||
tokens: Props["tokens"], | ||
generate: CSSVariableGenerator, | ||
): GeneratedCSSVariables => { | ||
const variables: GeneratedCSSVariables[] = []; | ||
|
||
const recurse = ( | ||
parent: Record<string, unknown>, | ||
path: string[], | ||
): GeneratedCSSVariables => { | ||
const cssVariables = Object.entries(parent).reduce( | ||
(result, currentEntry) => { | ||
const [tokenKey, tokenValue] = currentEntry; | ||
const newPath = [...path, tokenKey]; | ||
|
||
if (!isPlainObject(tokenValue)) { | ||
const generatedCSSVariable: GeneratedCSSVariable = generate({ | ||
tokenFamilyKey: newPath[0] ?? tokenKey, | ||
tokenPath: newPath.slice(1).join("."), | ||
tokenKey, | ||
tokenValue, | ||
}); | ||
|
||
result.push(generatedCSSVariable); | ||
|
||
return result; | ||
} | ||
|
||
return recurse(tokenValue, newPath); | ||
}, | ||
[] as GeneratedCSSVariables, | ||
); | ||
|
||
variables.push(cssVariables); | ||
|
||
return cssVariables; | ||
}; | ||
|
||
recurse(tokens, []); | ||
|
||
return variables.flat(); | ||
}; | ||
|
||
export const getCSSVariablesAsInlineStyle = ( | ||
variables: GeneratedCSSVariables, | ||
) => { | ||
const inlineStyle = variables.reduce( | ||
(result, variable) => { | ||
if (variable) { | ||
result[`--${variable.variableName}`] = variable.variableValue; | ||
} | ||
|
||
return result; | ||
}, | ||
{} as Record<string, string>, | ||
); | ||
|
||
return inlineStyle; | ||
}; |
Oops, something went wrong.