Fix Export

This commit is contained in:
Jeremy Thomas 2024-06-27 03:50:54 +01:00
parent 3c1e19a9ad
commit d3e01494db
4 changed files with 157 additions and 63 deletions

View File

@ -142,30 +142,31 @@ const PAGE_IDS = {
Layout: ["footer", "hero", "media", "section"], Layout: ["footer", "hero", "media", "section"],
Export: ["export"], Export: ["export"],
}; };
const LOCAL_STORAGE_KEY = "bulma-customizer-vars" const LOCAL_STORAGE_KEY = "bulma-customizer-vars";
export const CustomizerContext = createContext({ export const CustomizerContext = createContext({
isOpen: false, isOpen: false,
showExport: false,
cssvars: {}, cssvars: {},
saved: {}, saved: {},
currentTab: "", currentTab: "",
currentPage: "", currentPage: "",
showExport: false,
getVar: () => {}, getVar: () => {},
changeTab: () => {}, changeTab: () => {},
changePage: () => {}, changePage: () => {},
updateVar: () => {}, updateVar: () => {},
hideExport: () => {},
}); });
function App() { function App() {
const styleRef = useRef(); const styleRef = useRef();
const initialContext = { const initialContext = {
isOpen: true, isOpen: false,
showExport: false,
cssvars: {}, cssvars: {},
saved: {}, saved: {},
currentTab: "Global Variables", currentTab: "Global Variables",
currentPage: "colors", currentPage: "colors",
showExport: true,
getVar: (id) => { getVar: (id) => {
return context.cssvars[id]; return context.cssvars[id];
}, },
@ -199,6 +200,29 @@ function App() {
}; };
}); });
}, },
resetVars: () => {
setContext((context) => {
const cssvars = {};
for (const [key, value] of Object.entries(context.cssvars)) {
const item = { ...value, current: value.start };
cssvars[key] = item;
}
return {
...context,
cssvars,
};
});
},
hideExport: () => {
setContext((context) => {
return {
...context,
showExport: false,
};
});
},
}; };
const [context, setContext] = useState(() => { const [context, setContext] = useState(() => {
const saved = localStorage.getItem(LOCAL_STORAGE_KEY); const saved = localStorage.getItem(LOCAL_STORAGE_KEY);
@ -243,7 +267,7 @@ function App() {
showExport: !context.showExport, showExport: !context.showExport,
}; };
}); });
} };
// Get the computed styles of all cssvars // Get the computed styles of all cssvars
useEffect(() => { useEffect(() => {
@ -433,7 +457,7 @@ function App() {
// Update the styling when the cssvars change // Update the styling when the cssvars change
useEffect(() => { useEffect(() => {
const rules = {}; const rules = {};
const storedVars = {} const storedVars = {};
Object.values(context.cssvars).forEach((cssvar) => { Object.values(context.cssvars).forEach((cssvar) => {
const { id, current, start, scope, unit } = cssvar; const { id, current, start, scope, unit } = cssvar;
@ -470,7 +494,9 @@ function App() {
}, [context.cssvars]); }, [context.cssvars]);
// Computed values // Computed values
const isExportAvailable = Object.values(context.cssvars).some(item => item.current != item.start); // const isExportAvailable = Object.values(context.cssvars).some(
// (item) => item.current != item.start,
// );
// Styles // Styles
const tabsStyle = { const tabsStyle = {
@ -488,12 +514,15 @@ function App() {
const exportClass = classNames({ const exportClass = classNames({
[cn.button]: true, [cn.button]: true,
"button is-primary is-outlined": true, "is-hidden": !context.isOpen,
"button is-primary is-outlined": !context.showExport,
"button is-primary": context.showExport,
}); });
const buttonClass = classNames({ const buttonClass = classNames({
[cn.button]: true, [cn.button]: true,
"button is-primary": true, "button is-primary": !context.isOpen,
"button is-danger is-outlined": context.isOpen,
}); });
return ( return (
@ -502,44 +531,50 @@ function App() {
<style ref={styleRef} /> <style ref={styleRef} />
<div className={customizerClass}> <div className={customizerClass}>
{context.showExport ? PAGE_TO_COMPONENT.export : <> <div className={controlsClass}> {context.showExport ? (
<div className="select" style={tabsStyle}> PAGE_TO_COMPONENT.export
<select onChange={handleTabChange} value={context.currentTab}> ) : (
{TAB_IDS.map((tabId) => { <>
{" "}
<div className={controlsClass}>
<div className="select" style={tabsStyle}>
<select onChange={handleTabChange} value={context.currentTab}>
{TAB_IDS.map((tabId) => {
return (
<option key={tabId} value={tabId}>
{unslug(tabId)}
</option>
);
})}
</select>
</div>
{PAGE_IDS[context.currentTab].map((pageId) => {
const buttonClass = classNames({
button: true,
"is-primary": pageId === context.currentPage,
});
return ( return (
<option key={tabId} value={tabId}> <button
{unslug(tabId)} className={buttonClass}
</option> key={pageId}
onClick={(e) => handlePageChange(e, pageId)}
>
{unslug(pageId)}
</button>
); );
})} })}
</select> </div>
</div> {PAGE_TO_COMPONENT[context.currentPage]}
</>
{PAGE_IDS[context.currentTab].map((pageId) => { )}
const buttonClass = classNames({
button: true,
"is-primary": pageId === context.currentPage,
});
return (
<button
className={buttonClass}
key={pageId}
onClick={(e) => handlePageChange(e, pageId)}
>
{unslug(pageId)}
</button>
);
})}
</div>
{PAGE_TO_COMPONENT[context.currentPage]}</>}
</div> </div>
<div className={cn.buttons}> <div className={cn.buttons}>
{isExportAvailable && <button className={exportClass} onClick={handleExport}> <button className={exportClass} onClick={handleExport}>
Export Export
</button>} </button>
<button className={buttonClass} onClick={handleOpening}> <button className={buttonClass} onClick={handleOpening}>
{context.isOpen ? "Close Customizer" : "Open Customizer"} {context.isOpen ? "Close Customizer" : "Open Customizer"}

View File

@ -156,7 +156,7 @@ function Color({ color }) {
updateVar(cssvar.id, value); updateVar(cssvar.id, value);
}; };
if (!h) { if (!h || !s || !l) {
return; return;
} }

View File

@ -6,9 +6,37 @@ import Highlighter from "components/Highlighter";
import cn from "./Export.module.css"; import cn from "./Export.module.css";
function Export() { function Export() {
const { cssvars } = useContext(CustomizerContext); const { cssvars, resetVars, hideExport } = useContext(CustomizerContext);
const [css, setCSS] = useState(""); const [css, setCSS] = useState("");
const [copied, setCopied] = useState(false);
const handleReset = (event) => {
event.preventDefault();
if (window.confirm("Are you sure?")) {
resetVars();
}
};
const handleGo = (event) => {
event.preventDefault();
hideExport();
};
const copyToClipboard = async (event) => {
event.preventDefault();
try {
await navigator.clipboard.writeText(css);
setCopied(true);
window.setTimeout(() => {
setCopied(false);
}, 500);
} catch (err) {
console.error("Failed to copy!", err);
}
};
useEffect(() => { useEffect(() => {
const rules = {}; const rules = {};
@ -43,30 +71,53 @@ function Export() {
return ( return (
<div className={cn.main}> <div className={cn.main}>
{css ? ( <div className={cn.body}>
<> <p className="title is-5">Export</p>
<div className={cn.body}>
<p className="title is-5">Export</p>
<div className={cn.explanation}> {css ? (
<p>Insert this CSS <em>after</em> importing Bulma.</p> <div className={cn.explanation}>
<p>
Insert this CSS <em>after</em> importing Bulma.
</p>
<div className="buttons are-small"> <div className="buttons are-small">
<button className="button is-primary">Copy</button> {copied ? (
<button className="button is-danger is-outlined">Reset</button> <span className="button is-success">Copied!</span>
</div> ) : (
<button onClick={copyToClipboard} className="button is-primary">
Copy
</button>
)}
<button
onClick={handleReset}
className="button is-danger is-outlined"
>
Reset
</button>
</div> </div>
</div> </div>
) : (
<>
<div className={cn.explanation}>
<p>
Customize CSS variables in the other pages and come back here to
find the generated CSS.
</p>
</div>
<Highlighter PreTag="div" language="css"> <div className={cn.go}>
{css.trim()} <button className="button is-primary" onClick={handleGo}>
</Highlighter> Let&apos;s go!
</> </button>
) : ( </div>
<div className={cn.explanation}> </>
Customize CSS variables in the other pages and come back here to find )}
the generated CSS. </div>
</div>
{css && (
<Highlighter PreTag="div" language="css">
{css.trim()}
</Highlighter>
)} )}
</div> </div>
); );

View File

@ -3,11 +3,11 @@
} }
.body { .body {
padding: 0.5rem 1rem ; padding: 0.5rem 1rem;
} }
.body :global(.title) { .body :global(.title) {
margin-bottom: 0; margin-bottom: 0.25rem;
} }
.explanation { .explanation {
@ -15,7 +15,15 @@
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
p {
padding: 3px 0;
}
div { div {
flex-wrap: nowrap; flex-wrap: nowrap;
} }
} }
.go {
margin-top: 0.5rem;
}