"--bulma-tabs-link-active-color": "var(--bulma-primary)",
};
- const appClass = classNames({
- [cn.app]: true,
+ const customizerClass = classNames({
+ [cn.customizer]: true,
[cn.open]: context.isOpen,
});
return (
<CustomizerContext.Provider value={context}>
- <style ref={styleRef} />
-
- <div className={appClass}>
- <div className={cn.controls}>
- <div className="select" style={tabsStyle}>
- <select onChange={handleTabChange} value={context.currentTab}>
- {TAB_IDS.map((tabId) => {
- return (
- <option key={tabId} value={tabId}>
- <a>{unslug(tabId)}</a>
- </option>
- );
- })}
- </select>
+ <div className={cn.app}>
+ <style ref={styleRef} />
+
+ <div className={customizerClass}>
+ <div className={cn.controls}>
+ <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 (
+ <button
+ className={buttonClass}
+ key={pageId}
+ onClick={(e) => handlePageChange(e, pageId)}
+ >
+ {unslug(pageId)}
+ </button>
+ );
+ })}
</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>
- );
- })}
+ {PAGE_TO_COMPONENT[context.currentPage]}
</div>
- {PAGE_TO_COMPONENT[context.currentPage]}
+ <button className={buttonClass} onClick={handleOpening}>
+ {context.isOpen ? "Close Customizer" : "Open Customizer"}
+ </button>
</div>
-
- <button className={buttonClass} onClick={handleOpening}>
- {context.isOpen ? "Close Customizer" : "Open Customizer"}
- </button>
</CustomizerContext.Provider>
);
}
-import { useContext, useEffect, useState } from "react";
+import { useContext } from "react";
import PropTypes from "prop-types";
import Slider from "./Slider";
import { CustomizerContext } from "../App";
import classNames from "classnames";
-function hslToHex(h, s, l) {
+export function hslToHex(h, s, l) {
s /= 100;
l /= 100;
function Color({ color }) {
const { cssvars, updateVar } = useContext(CustomizerContext);
- const [hexValue, setHexValue] = useState("");
const hName = `${color}-h`;
const sName = `${color}-s`;
updateVar(l.id, lightness);
};
- const handleHexChange = (event) => {
- let value = event.target.value;
-
- if (value.startsWith("#")) {
- value = value.replace(/^#/, "");
- }
-
- setHexValue(value);
-
- const hexPattern = /^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/;
-
- if (!hexPattern.test(value) || value.length < 6) {
- return;
- }
-
- const { hue, saturation, lightness } = hexToHsl(value);
-
- updateVar(h.id, hue);
- updateVar(s.id, saturation);
- updateVar(l.id, lightness);
- };
-
const handleInputChange = (event, cssvar) => {
let value = event.target.value;
updateVar(cssvar.id, value);
};
- useEffect(() => {
- if (!h) {
- return;
- }
-
- const hex = hslToHex(h.current, s.current, l.current);
- setHexValue(hex);
- }, [h, s, l]);
-
if (!h) {
return;
}
return (
<div className={cn.main} style={mainStyle}>
<div className={cn.side}>
- <div className={cn.name}>
- <div className={cn.swatch} />
- <p>{name}</p>
- </div>
-
- <div className="buttons are-small">
+ <div className="buttons are-small is-float-right ml-2">
<button className="button" onClick={handleHexInput}>
Enter a Hex code
</button>
</button>
</div>
- <div className="is-hidden field has-addons">
- <p className="control">
- <span className="button is-static">#</span>
- </p>
- <p className="control">
- <input
- className="input"
- type="text"
- value={hexValue}
- onChange={handleHexChange}
- />
- </p>
- <p className="control">
- <span className="button is-icon">Copy</span>
- </p>
+ <div className={cn.name}>
+ <div className={cn.swatch} />
+ <p>{name}</p>
</div>
</div>
<div className={cn.lines}>
<div className={cn.line}>
- <p>Hue</p>
- <Slider id={hName} kind="hue" color={color} />
- <p className={cn.form}>
- <input
- type="text"
- className="input"
- value={Number(h.current)}
- onChange={(e) => handleInputChange(e, h)}
- size="3"
- />
- <span>{h.unit}</span>
- </p>
+ <p className={cn.label}>Hue</p>
+ <div className={cn.slider}>
+ <Slider id={hName} kind="hue" color={color} />
+ <p className={cn.form}>
+ <input
+ type="text"
+ className="input"
+ value={Number(h.current)}
+ onChange={(e) => handleInputChange(e, h)}
+ size="3"
+ />
+ <span>{h.unit}</span>
+ </p>
+ </div>
</div>
<div className={cn.line}>
- <p>Saturation</p>
- <Slider id={sName} kind="saturation" color={color} />
- <p className={cn.form}>
- <input
- type="text"
- className="input"
- value={Number(s.current)}
- onChange={(e) => handleInputChange(e, s)}
- size="3"
- />
- <span>{s.unit}</span>
- </p>
+ <p className={cn.label}>Saturation</p>
+ <div className={cn.slider}>
+ <Slider id={sName} kind="saturation" color={color} />
+ <p className={cn.form}>
+ <input
+ type="text"
+ className="input"
+ value={Number(s.current)}
+ onChange={(e) => handleInputChange(e, s)}
+ size="3"
+ />
+ <span>{s.unit}</span>
+ </p>
+ </div>
</div>
<div className={cn.line}>
- <p>Lightness</p>
- <Slider id={lName} kind="lightness" color={color} />
- <p className={cn.form}>
- <input
- type="text"
- className="input"
- value={Number(l.current)}
- onChange={(e) => handleInputChange(e, l)}
- size="3"
- />
- <span>{l.unit}</span>
- </p>
+ <p className={cn.label}>Lightness</p>
+ <div className={cn.slider}>
+ <Slider id={lName} kind="lightness" color={color} />
+ <p className={cn.form}>
+ <input
+ type="text"
+ className="input"
+ value={Number(l.current)}
+ onChange={(e) => handleInputChange(e, l)}
+ size="3"
+ />
+ <span>{l.unit}</span>
+ </p>
+ </div>
</div>
</div>
- <div className={cn.side}>
+ <div className={cn.example}>
<button className={`button is-${color}`}>{name}</button>
</div>
</div>