@@ -44,7 +44,7 @@ const EXAMPLE = `{
|
||||
}
|
||||
}`;
|
||||
|
||||
type ExportFormat = "w3c" | "css" | "sass" | "android" | "swift";
|
||||
type ExportFormat = "dtcg" | "css" | "sass" | "android" | "swift";
|
||||
|
||||
export function Workbench() {
|
||||
const [draft, setDraft] = useState(EXAMPLE);
|
||||
@@ -55,6 +55,7 @@ export function Workbench() {
|
||||
[documentText],
|
||||
);
|
||||
const [theme, setTheme] = useState("light");
|
||||
const [mode, setMode] = useState("default");
|
||||
const [setName, setSetName] = useState("core");
|
||||
const [selectedPath, setSelectedPath] = useState<string | null>(
|
||||
"color.brand",
|
||||
@@ -66,16 +67,16 @@ export function Workbench() {
|
||||
const [format, setFormat] = useState<ExportFormat>("css");
|
||||
const [filter, setFilter] = useState("");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const activeTheme = document.themes[theme]
|
||||
? theme
|
||||
: (Object.keys(document.themes)[0] ?? "default");
|
||||
const activeMode = document.modes[activeTheme]?.[mode]
|
||||
? mode
|
||||
: (Object.keys(document.modes[activeTheme] ?? {})[0] ?? "default");
|
||||
|
||||
const resolution = useMemo(
|
||||
() =>
|
||||
resolveTheme(
|
||||
document,
|
||||
document.themes[theme]
|
||||
? theme
|
||||
: (Object.keys(document.themes)[0] ?? "default"),
|
||||
),
|
||||
[document, theme],
|
||||
() => resolveTheme(document, activeTheme, activeMode),
|
||||
[document, activeTheme, activeMode],
|
||||
);
|
||||
const exported = useMemo(
|
||||
() => exportTokens(format, resolution.tokens),
|
||||
@@ -96,6 +97,7 @@ export function Workbench() {
|
||||
? setName
|
||||
: (Object.keys(parsed.sets)[0] ?? "default");
|
||||
setTheme(nextTheme);
|
||||
setMode(Object.keys(parsed.modes[nextTheme] ?? {})[0] ?? "default");
|
||||
setSetName(nextSet);
|
||||
setSelectedPath(null);
|
||||
setParseError("");
|
||||
@@ -231,6 +233,7 @@ export function Workbench() {
|
||||
ref={inputRef}
|
||||
className="sr-only"
|
||||
type="file"
|
||||
aria-label="Open design token JSON file"
|
||||
accept="application/json,.json"
|
||||
onChange={(event) => void importDocument(event.target.files?.[0])}
|
||||
/>
|
||||
@@ -336,9 +339,17 @@ export function Workbench() {
|
||||
{[
|
||||
"color",
|
||||
"dimension",
|
||||
"duration",
|
||||
"number",
|
||||
"string",
|
||||
"boolean",
|
||||
"fontFamily",
|
||||
"fontWeight",
|
||||
"cubicBezier",
|
||||
"strokeStyle",
|
||||
"border",
|
||||
"transition",
|
||||
"gradient",
|
||||
"typography",
|
||||
"shadow",
|
||||
"unknown",
|
||||
@@ -389,20 +400,42 @@ export function Workbench() {
|
||||
<label className="inline-label">
|
||||
Theme
|
||||
<select
|
||||
value={
|
||||
document.themes[theme] ? theme : Object.keys(document.themes)[0]
|
||||
}
|
||||
onChange={(event) => setTheme(event.target.value)}
|
||||
value={activeTheme}
|
||||
onChange={(event) => {
|
||||
const nextTheme = event.target.value;
|
||||
setTheme(nextTheme);
|
||||
setMode(
|
||||
Object.keys(document.modes[nextTheme] ?? {})[0] ?? "default",
|
||||
);
|
||||
}}
|
||||
>
|
||||
{Object.keys(document.themes).map((name) => (
|
||||
<option key={name}>{name}</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label className="inline-label">
|
||||
Mode
|
||||
<select
|
||||
value={activeMode}
|
||||
onChange={(event) => setMode(event.target.value)}
|
||||
>
|
||||
{Object.keys(document.modes[activeTheme] ?? { default: [] }).map(
|
||||
(name) => (
|
||||
<option key={name}>{name}</option>
|
||||
),
|
||||
)}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<p className="muted">
|
||||
Sets: {(document.themes[theme] ?? []).join(" → ") || "none"}. Later
|
||||
sets override matching paths.
|
||||
Sets:{" "}
|
||||
{(
|
||||
document.modes[activeTheme]?.[activeMode] ??
|
||||
document.themes[activeTheme] ??
|
||||
[]
|
||||
).join(" → ") || "none"}
|
||||
. Later sets override matching paths.
|
||||
</p>
|
||||
{resolution.diagnostics.length > 0 ? (
|
||||
<ul className="diagnostics">
|
||||
@@ -460,7 +493,7 @@ export function Workbench() {
|
||||
setFormat(event.target.value as ExportFormat)
|
||||
}
|
||||
>
|
||||
<option value="w3c">W3C-style JSON</option>
|
||||
<option value="dtcg">DTCG JSON</option>
|
||||
<option value="css">CSS variables</option>
|
||||
<option value="sass">Sass variables</option>
|
||||
<option value="android">Android XML</option>
|
||||
|
||||
Reference in New Issue
Block a user