Add Control vars

This commit is contained in:
Jeremy Thomas 2024-06-26 16:06:52 +01:00
parent 891e6e3cb7
commit 303da19588
14 changed files with 291 additions and 15 deletions

1
.gitignore vendored
View File

@ -17,5 +17,6 @@ test.css.map
_gh_pages _gh_pages
_site _site
dev dev
dist
node_modules node_modules
test/output/ test/output/

View File

@ -8,7 +8,7 @@
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<div class="is-hidden"> <div id="scope" class="is-hidden">
<div class="box"></div> <div class="box"></div>
<div class="content"></div> <div class="content"></div>
<div class="delete"></div> <div class="delete"></div>
@ -18,6 +18,14 @@
<div class="table"></div> <div class="table"></div>
<div class="tag"></div> <div class="tag"></div>
<div class="title"></div> <div class="title"></div>
<input class="input">
<div class="file"></div>
<div class="columns"></div>
<div class="grid"></div>
<div class="footer"></div>
<div class="hero"></div>
<div class="media"></div>
<div class="section"></div>
</div> </div>
<script type="module" src="/src/main.jsx"></script> <script type="module" src="/src/main.jsx"></script>
</body> </body>

View File

@ -1,4 +1,4 @@
import { createContext, useEffect, useState } from "react"; import { createContext, useEffect, useRef, useState } from "react";
import classNames from "classnames"; import classNames from "classnames";
import "../../../../css/bulma.css"; import "../../../../css/bulma.css";
@ -21,6 +21,15 @@ import Progress from "./pages/elements/Progress";
import Table from "./pages/elements/Table"; import Table from "./pages/elements/Table";
import Tag from "./pages/elements/Tag"; import Tag from "./pages/elements/Tag";
import Title from "./pages/elements/Title"; import Title from "./pages/elements/Title";
import Control from "./pages/form/Control";
import Input from "./pages/form/Input";
import File from "./pages/form/File";
import Columns from "./pages/grid/Columns";
import Grid from "./pages/grid/Grid";
import Footer from "./pages/layout/Footer";
import Hero from "./pages/layout/Hero";
import Media from "./pages/layout/Media";
import Section from "./pages/layout/Section";
const SUFFIX_TO_KIND = { const SUFFIX_TO_KIND = {
"-h": "hue", "-h": "hue",
@ -37,6 +46,7 @@ const PAGE_TO_COMPONENT = {
other: <Other />, other: <Other />,
generic: <Generic />, generic: <Generic />,
skeleton: <Skeleton />, skeleton: <Skeleton />,
// Elements
box: <Box />, box: <Box />,
content: <Content />, content: <Content />,
delete: <Delete />, delete: <Delete />,
@ -46,6 +56,18 @@ const PAGE_TO_COMPONENT = {
table: <Table />, table: <Table />,
tag: <Tag />, tag: <Tag />,
title: <Title />, title: <Title />,
// Form
control: <Control />,
input: <Input />,
file: <File />,
// Grid
columns: <Columns />,
grid: <Grid />,
// Layout
footer: <Footer />,
hero: <Hero />,
media: <Media />,
section: <Section />,
}; };
const PAGE_IDS = [ const PAGE_IDS = [
"colors", "colors",
@ -63,6 +85,15 @@ const PAGE_IDS = [
"table", "table",
"tag", "tag",
"title", "title",
"control",
"input",
"file",
"columns",
"grid",
"footer",
"hero",
"media",
"section",
]; ];
export const CustomizerContext = createContext({ export const CustomizerContext = createContext({
@ -74,6 +105,7 @@ export const CustomizerContext = createContext({
}); });
function App() { function App() {
const styleRef = useRef();
const initialContext = { const initialContext = {
cssvars: {}, cssvars: {},
currentPage: "delete", currentPage: "delete",
@ -90,15 +122,15 @@ function App() {
}, },
updateVar: (id, newValue) => { updateVar: (id, newValue) => {
setContext((context) => { setContext((context) => {
const { start, unit, scope } = context.cssvars[id]; // const { start, unit, scope } = context.cssvars[id];
const computedValue = `${newValue}${unit}`; // const computedValue = `${newValue}${unit}`;
const el = document.querySelector(scope); // const el = document.querySelector(`#scope ${scope}`);
if (start === newValue) { // if (start === newValue) {
el.style.removeProperty(`--bulma-${id}`); // el.style.removeProperty(`--bulma-${id}`);
} else { // } else {
el.style.setProperty(`--bulma-${id}`, computedValue); // el.style.setProperty(`--bulma-${id}`, computedValue);
} // }
return { return {
...context, ...context,
@ -134,6 +166,14 @@ function App() {
table: window.getComputedStyle(document.querySelector(".table")), table: window.getComputedStyle(document.querySelector(".table")),
tag: window.getComputedStyle(document.querySelector(".tag")), tag: window.getComputedStyle(document.querySelector(".tag")),
title: window.getComputedStyle(document.querySelector(".title")), title: window.getComputedStyle(document.querySelector(".title")),
file: window.getComputedStyle(document.querySelector(".file")),
input: window.getComputedStyle(document.querySelector(".input")),
columns: window.getComputedStyle(document.querySelector(".columns")),
grid: window.getComputedStyle(document.querySelector(".grid")),
footer: window.getComputedStyle(document.querySelector(".footer")),
hero: window.getComputedStyle(document.querySelector(".hero")),
media: window.getComputedStyle(document.querySelector(".media")),
section: window.getComputedStyle(document.querySelector(".section")),
}; };
const cssvars = {}; const cssvars = {};
@ -171,6 +211,30 @@ function App() {
} else if (key.startsWith("title")) { } else if (key.startsWith("title")) {
scope = ".title"; scope = ".title";
original = styles.title.getPropertyValue(`--bulma-${key}`); original = styles.title.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("file")) {
scope = ".file";
original = styles.file.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("input")) {
scope = ".input";
original = styles.input.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("columns")) {
scope = ".columns";
original = styles.columns.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("grid")) {
scope = ".grid";
original = styles.grid.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("footer")) {
scope = ".footer";
original = styles.footer.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("hero")) {
scope = ".hero";
original = styles.hero.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("media")) {
scope = ".media";
original = styles.media.getPropertyValue(`--bulma-${key}`);
} else if (key.startsWith("section")) {
scope = ".section";
original = styles.section.getPropertyValue(`--bulma-${key}`);
} else { } else {
original = styles.root.getPropertyValue(`--bulma-${key}`); original = styles.root.getPropertyValue(`--bulma-${key}`);
} }
@ -203,8 +267,42 @@ function App() {
}); });
}, []); }, []);
useEffect(() => {
const rules = {};
Object.values(context.cssvars).forEach((cssvar) => {
const { id, current, start, scope, unit } = cssvar;
if (current == start) {
return;
}
const computedValue = `${current}${unit}`;
const declaration = `--bulma-${id}: ${computedValue};`;
if (scope in rules) {
rules[scope].push(declaration);
} else {
rules[scope] = [declaration];
}
});
let content = "";
for (const [key, arr] of Object.entries(rules)) {
content += `${key} {`;
arr.forEach((item) => (content += item));
content += `}`;
}
if (styleRef) {
styleRef.current.innerHTML = content;
}
}, [context.cssvars]);
return ( return (
<CustomizerContext.Provider value={context}> <CustomizerContext.Provider value={context}>
<style ref={styleRef} />
<section className="section"> <section className="section">
<div className="buttons"> <div className="buttons">
{PAGE_IDS.map((pageId) => { {PAGE_IDS.map((pageId) => {

View File

@ -32,7 +32,7 @@
.background { .background {
border-radius: 0.25rem; border-radius: 0.25rem;
background-color: var(--bulma-background); background-color: var(--bulma-border);
height: 0.5rem; height: 0.5rem;
} }

View File

@ -522,6 +522,35 @@ export const CSSVAR_KEYS = {
description: "The subtitle strong elements font weight", description: "The subtitle strong elements font weight",
}, },
], ],
control: [
{ id: "control-radius", description: "The control elements border radius" },
{
id: "control-radius-small",
description: "The control elements small border radius",
},
{
id: "control-border-width",
description: "The control elements border width",
},
{ id: "control-height", description: "The control elements height" },
{
id: "control-line-height",
description: "The control elements line height",
},
{
id: "control-padding-vertical",
description: "The control elements vertical padding",
},
{
id: "control-padding-horizontal",
description: "The control elements horizontal padding",
},
{ id: "control-size", description: "The control elements font size" },
{
id: "control-focus-shadow-l",
description: "The control elements shadow Lightness when focused",
},
],
file: [ file: [
{ id: "file-radius", description: "The file element border radius" }, { id: "file-radius", description: "The file element border radius" },
{ {
@ -594,10 +623,6 @@ export const CSSVAR_KEYS = {
id: "input-border-style", id: "input-border-style",
description: "The input element main border style", description: "The input element main border style",
}, },
{
id: "input-border-width",
description: "The input element main border width",
},
{ {
id: "input-border-l", id: "input-border-l",
description: "The input element main border Lightness", description: "The input element main border Lightness",

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Control() {
const ids = CSSVAR_KEYS.control.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Control;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function File() {
const ids = CSSVAR_KEYS.file.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default File;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Input() {
const ids = CSSVAR_KEYS.input.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Input;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Columns() {
const ids = CSSVAR_KEYS.columns.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Columns;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Grid() {
const ids = CSSVAR_KEYS.grid.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Grid;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Footer() {
const ids = CSSVAR_KEYS.footer.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Footer;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Hero() {
const ids = CSSVAR_KEYS.hero.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Hero;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Media() {
const ids = CSSVAR_KEYS.media.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Media;

View File

@ -0,0 +1,16 @@
import VarItem from "components/VarItem";
import { CSSVAR_KEYS } from "root/constants";
function Section() {
const ids = CSSVAR_KEYS.section.map((i) => i.id);
return (
<div>
{ids.map((id) => {
return <VarItem key={id} id={id} />;
})}
</div>
);
}
export default Section;