Add Export

This commit is contained in:
Jeremy Thomas
2024-06-27 02:00:43 +01:00
parent 762926d492
commit 96de5b2f45
7 changed files with 532 additions and 6 deletions

View File

@@ -0,0 +1,152 @@
:root {
--gh-dark: #25292e;
--gh-dimmed: #6a737d;
--gh-text: #e1e4e8;
--gh-red: #f97583;
--gh-orange: #ffab70;
--gh-yellow: #ffea7f;
--gh-green: #85e89d;
--gh-blue: #79b8ff;
--gh-blue-light: #9ecbff;
--gh-purple: #b392f0;
--gh-pink: #f692ce;
/*
"black": "#1b1f23",
"white": "#fff",
"gray": ["#fafbfc", "#f6f8fa", "#e1e4e8", "#d1d5da", "#959da5", "#6a737d", "#586069", "#444d56", "#2f363d", "#24292e"],
"blue": ["#f1f8ff", "#dbedff", "#c8e1ff", "#79b8ff", "#2188ff", "#0366d6", "#005cc5", "#044289", "#032f62", "#05264c"],
"green": ["#f0fff4", "#dcffe4", "#bef5cb", "#85e89d", "#34d058", "#28a745", "#22863a", "#176f2c", "#165c26", "#144620"],
"yellow": ["#fffdef", "#fffbdd", "#fff5b1", "#ffea7f", "#ffdf5d", "#ffd33d", "#f9c513", "#dbab09", "#b08800", "#735c0f"],
"orange": ["#fff8f2", "#ffebda", "#ffd1ac", "#ffab70", "#fb8532", "#f66a0a", "#e36209", "#d15704", "#c24e00", "#a04100"],
"red": ["#ffeef0", "#ffdce0", "#fdaeb7", "#f97583", "#ea4a5a", "#d73a49", "#cb2431", "#b31d28", "#9e1c23", "#86181d"],
"purple": ["#f5f0ff", "#e6dcfd", "#d1bcf9", "#b392f0", "#8a63d2", "#6f42c1", "#5a32a3", "#4c2889", "#3a1d6e", "#29134e"],
"pink": ["#ffeef8", "#fedbf0", "#f9b3dd", "#f692ce", "#ec6cb9", "#ea4aaa", "#d03592", "#b93a86", "#99306f", "#6d224f"]
*/
}
.prismjs {
color: var(--gh-text);
font-size: 0.875em;
position: relative;
> code {
--lang: "Code";
--language: var(--brand);
background-color: var(--gh-dark);
border-radius: 0;
display: block;
font-size: 1rem;
overflow: auto;
padding: 1em 1.25em;
margin: 0.5rem -0.5rem;
}
& > .language-css {
--lang: "CSS";
--language: var(--gh-blue);
}
& > .language-html {
--lang: "HTML";
--language: var(--gh-orange);
}
.token {
/* CSS */
&.color {
&.hexcode {
color: var(--gh-pink);
}
}
&.comment {
color: var(--gh-dimmed);
}
&.function {
color: var(--gh-yellow);
}
&.number {
color: var(--gh-green);
}
&.property {
color: var(--gh-blue);
}
&.punctuation {
color: var(--gh-dimmed);
}
&.selector {
color: var(--gh-green);
&.attribute {
color: var(--gh-pink);
&.attr-name {
color: var(--gh-orange);
}
&.punctuation {
color: var(--gh-dimmed);
}
}
&.class {
color: var(--gh-purple);
}
&.combinator {
color: var(--gh-pink);
}
&.pseudo-class {
color: var(--gh-purple);
}
&.punctuation {
color: var(--gh-dimmed);
}
}
&.atrule {
color: var(--gh-purple);
}
&.string {
color: var(--gh-blue);
}
&.unit {
color: var(--gh-red);
}
&.variable {
color: var(--gh-orange);
}
/* HTML */
&.tag {
color: var(--gh-green);
&.attr-name {
color: var(--gh-blue);
}
&.attr-value {
color: var(--gh-purple);
}
&.punctuation {
color: var(--gh-dimmed);
&.attr-equals {
color: var(--gh-pink);
}
}
}
}
}

View File

@@ -1,6 +1,7 @@
import { createContext, useEffect, useRef, useState } from "react";
import classNames from "classnames";
import "../../../../css/bulma.css";
import "./App.css";
import cn from "./App.module.css";
import { CSSVAR_KEYS } from "./constants";
@@ -42,6 +43,7 @@ import Footer from "./pages/layout/Footer";
import Hero from "./pages/layout/Hero";
import Media from "./pages/layout/Media";
import Section from "./pages/layout/Section";
import Export from "./components/Export";
const SUFFIX_TO_KIND = {
"-h": "hue",
@@ -91,6 +93,8 @@ const PAGE_TO_COMPONENT = {
hero: <Hero />,
media: <Media />,
section: <Section />,
// Export
export: <Export />,
};
const TAB_IDS = [
"Global Variables",
@@ -99,6 +103,7 @@ const TAB_IDS = [
"Form",
"Grid",
"Layout",
"Export",
];
const PAGE_IDS = {
"Global Variables": [
@@ -135,6 +140,7 @@ const PAGE_IDS = {
Form: ["control", "input", "file"],
Grid: ["columns", "grid"],
Layout: ["footer", "hero", "media", "section"],
Export: ["export"],
};
export const CustomizerContext = createContext({
@@ -153,8 +159,8 @@ function App() {
const initialContext = {
isOpen: true,
cssvars: {},
currentTab: "Global Variables",
currentPage: "delete",
currentTab: "Export",
currentPage: "export",
getVar: (id) => {
return context.cssvars[id];
},
@@ -255,11 +261,27 @@ function App() {
const cssvars = {};
const allKeys = Object.values(PAGE_IDS)
.flat()
.map((pageId) => CSSVAR_KEYS[pageId])
.map((pageId) => {
if (!(pageId in CSSVAR_KEYS)) {
return;
}
return CSSVAR_KEYS[pageId];
})
.flat();
const allKeyIds = allKeys.map((i) => i.id);
const allKeyIds = allKeys.map((i) => {
if (!i) {
return;
}
return i.id;
});
allKeyIds.map((key) => {
if (!key) {
return;
}
let original;
let scope = ":root";

View File

@@ -0,0 +1,66 @@
import { useContext, useEffect, useState } from "react";
import { CustomizerContext } from "../App";
import Highlighter from "components/Highlighter";
import cn from "./Export.module.css";
function Export() {
const { cssvars } = useContext(CustomizerContext);
const [css, setCSS] = useState("");
useEffect(() => {
const rules = {};
Object.values(cssvars).forEach((cssvar) => {
const { id, current, start, scope, unit } = cssvar;
if (current == start) {
return;
}
const computedValue = `${current}${unit}`;
const declaration = `--bulma-${id}: ${computedValue};\n`;
if (scope in rules) {
rules[scope].push(declaration);
} else {
rules[scope] = [declaration];
}
});
let content = "";
for (const [key, arr] of Object.entries(rules)) {
content += `${key} {\n`;
arr.forEach((item) => (content += ` ${item}`));
content += `}\n\n`;
}
setCSS(content);
}, [cssvars]);
return (
<div className={cn.main}>
{css ? (
<>
<div className={cn.explanation}>
Insert this CSS <em>after</em> importing Bulma.
</div>
<Highlighter PreTag="div" language="css">
{css.trim()}
</Highlighter>
</>
) : (
<div className={cn.explanation}>
Customize CSS variables in the other pages and come back here to find
the generated CSS.
</div>
)}
</div>
);
}
export default Export;

View File

@@ -0,0 +1,7 @@
.main {
padding: 0.5rem;
}
.explanation {
padding: 0 1rem 0.5rem;
}

View File

@@ -0,0 +1,15 @@
import PropTypes from "prop-types";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
const Highlighter = ({ ...rest }) => {
return (
<SyntaxHighlighter style={atomOneDark} useInlineStyles={false} {...rest} />
);
};
Highlighter.propTypes = {
code: PropTypes.string,
};
export default Highlighter;