Layout: ["footer", "hero", "media", "section"],
Export: ["export"],
};
-const LOCAL_STORAGE_KEY = "bulma-customizer-vars"
+const LOCAL_STORAGE_KEY = "bulma-customizer-vars";
export const CustomizerContext = createContext({
isOpen: false,
+ showExport: false,
cssvars: {},
saved: {},
currentTab: "",
currentPage: "",
- showExport: false,
getVar: () => {},
changeTab: () => {},
changePage: () => {},
updateVar: () => {},
+ hideExport: () => {},
});
function App() {
const styleRef = useRef();
const initialContext = {
- isOpen: true,
+ isOpen: false,
+ showExport: false,
cssvars: {},
saved: {},
currentTab: "Global Variables",
currentPage: "colors",
- showExport: true,
getVar: (id) => {
return context.cssvars[id];
},
};
});
},
+ 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 saved = localStorage.getItem(LOCAL_STORAGE_KEY);
showExport: !context.showExport,
};
});
- }
+ };
// Get the computed styles of all cssvars
useEffect(() => {
// Update the styling when the cssvars change
useEffect(() => {
const rules = {};
- const storedVars = {}
+ const storedVars = {};
Object.values(context.cssvars).forEach((cssvar) => {
const { id, current, start, scope, unit } = cssvar;
}, [context.cssvars]);
// 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
const tabsStyle = {
const exportClass = classNames({
[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({
[cn.button]: true,
- "button is-primary": true,
+ "button is-primary": !context.isOpen,
+ "button is-danger is-outlined": context.isOpen,
});
return (
<style ref={styleRef} />
<div className={customizerClass}>
- {context.showExport ? PAGE_TO_COMPONENT.export : <> <div className={controlsClass}>
- <div className="select" style={tabsStyle}>
- <select onChange={handleTabChange} value={context.currentTab}>
- {TAB_IDS.map((tabId) => {
+ {context.showExport ? (
+ PAGE_TO_COMPONENT.export
+ ) : (
+ <>
+ {" "}
+ <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 (
- <option key={tabId} value={tabId}>
- {unslug(tabId)}
- </option>
+ <button
+ className={buttonClass}
+ key={pageId}
+ onClick={(e) => handlePageChange(e, pageId)}
+ >
+ {unslug(pageId)}
+ </button>
);
})}
- </select>
- </div>
-
- {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>
+ {PAGE_TO_COMPONENT[context.currentPage]}
+ </>
+ )}
</div>
<div className={cn.buttons}>
- {isExportAvailable && <button className={exportClass} onClick={handleExport}>
+ <button className={exportClass} onClick={handleExport}>
Export
- </button>}
+ </button>
<button className={buttonClass} onClick={handleOpening}>
{context.isOpen ? "Close Customizer" : "Open Customizer"}
import cn from "./Export.module.css";
function Export() {
- const { cssvars } = useContext(CustomizerContext);
+ const { cssvars, resetVars, hideExport } = useContext(CustomizerContext);
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(() => {
const rules = {};
return (
<div className={cn.main}>
- {css ? (
- <>
- <div className={cn.body}>
- <p className="title is-5">Export</p>
-
- <div className={cn.explanation}>
- <p>Insert this CSS <em>after</em> importing Bulma.</p>
-
- <div className="buttons are-small">
- <button className="button is-primary">Copy</button>
- <button className="button is-danger is-outlined">Reset</button>
- </div>
+ <div className={cn.body}>
+ <p className="title is-5">Export</p>
+
+ {css ? (
+ <div className={cn.explanation}>
+ <p>
+ Insert this CSS <em>after</em> importing Bulma.
+ </p>
+
+ <div className="buttons are-small">
+ {copied ? (
+ <span className="button is-success">Copied!</span>
+ ) : (
+ <button onClick={copyToClipboard} className="button is-primary">
+ Copy
+ </button>
+ )}
+ <button
+ onClick={handleReset}
+ className="button is-danger is-outlined"
+ >
+ Reset
+ </button>
</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">
- {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 className={cn.go}>
+ <button className="button is-primary" onClick={handleGo}>
+ Let's go!
+ </button>
+ </div>
+ </>
+ )}
+ </div>
+
+ {css && (
+ <Highlighter PreTag="div" language="css">
+ {css.trim()}
+ </Highlighter>
)}
</div>
);