Create Context

This commit is contained in:
Jeremy Thomas
2024-06-25 03:59:13 +01:00
parent 34029baa2c
commit 0c9ae61698
7 changed files with 271 additions and 101 deletions

View File

@@ -0,0 +1,102 @@
import { useContext } from "react";
import PropTypes from "prop-types";
import Slider from "./Slider";
import cn from "./Color.module.css";
import { CustomizerContext } from "../App";
function Color({ color }) {
// const [hue, setHue] = useState(h.start);
// const [saturation, setSaturation] = useState(s.start);
// const [lightness, setLightness] = useState(l.start);
const { cssvars } = useContext(CustomizerContext);
const hName = `${color}-h`;
const sName = `${color}-s`;
const lName = `${color}-l`;
const h = cssvars[hName];
const s = cssvars[sName];
const l = cssvars[lName];
const mainStyle = {
"--h": `var(--bulma-${hName})`,
"--s": `var(--bulma-${sName})`,
"--l": `var(--bulma-${lName})`,
};
const name = color.charAt(0).toUpperCase() + color.slice(1);
const handleReset = (event) => {
event.preventDefault();
document.documentElement.style.removeProperty(`--bulma-${hName}`);
document.documentElement.style.removeProperty(`--bulma-${sName}`);
document.documentElement.style.removeProperty(`--bulma-${lName}`);
};
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>
<button className="button is-small" onClick={handleReset}>
Reset
</button>
</div>
<div className={cn.lines}>
<div className={cn.line}>
<p>Hue</p>
<Slider id={hName} kind="hue" color={color} />
<p>
<code>
{h.current}
{h.unit}
</code>
</p>
</div>
<div className={cn.line}>
<p>Saturation</p>
<Slider id={sName} kind="saturation" color={color} />
<p>
<code>
{s.current}
{s.unit}
</code>
</p>
</div>
<div className={cn.line}>
<p>Lightness</p>
<Slider id={lName} kind="lightness" color={color} />
<p>
<code>
{l.current}
{l.unit}
</code>
</p>
</div>
</div>
<div className={cn.side}>
<button className={`button is-${color}`}>{name}</button>
</div>
</div>
);
}
Color.propTypes = {
color: PropTypes.string,
h: PropTypes.string,
s: PropTypes.string,
l: PropTypes.string,
};
export default Color;

View File

@@ -0,0 +1,49 @@
.main {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
border-bottom: 1px solid var(--bulma-border);
padding: 1.25rem;
}
.side {
width: 15rem;
}
.swatch {
background-color: hsl(var(--h) var(--s) var(--l));
height: 1.25rem;
width: 1.25rem;
border-radius: 0.25rem;
flex-shrink: 0;
}
.name {
gap: 1rem;
display: flex;
align-items: center;
margin-bottom: 0.5rem;
}
.name p {
color: var(--bulma-text-strong);
font-size: 1.25em;
font-weight: 600;
}
.lines {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.line {
display: flex;
align-items: center;
gap: 1.5rem;
}
.line p {
color: var(--bulma-text-strong);
width: 6rem;
}

View File

@@ -1,8 +1,9 @@
import { useEffect, useRef, useState } from "react";
import { useContext, useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import cn from "./Slider.module.css";
import { CustomizerContext } from "../App";
const RANGES = {
hue: [0, 360, 1],
@@ -24,13 +25,14 @@ const valueToX = (value, width, min, max) => {
return Math.round(newValue);
};
function Slider({ id, color, kind, start, unit }) {
function Slider({ id, color, kind }) {
const { cssvars, updateVar } = useContext(CustomizerContext);
const { start, current, unit } = cssvars[id];
const [min, max] = RANGES[kind];
const sliderRef = useRef(null);
const handleRef = useRef(null);
const [value, setValue] = useState(start);
const [isMoving, setMoving] = useState(false);
const [x, setX] = useState(valueToX(start, 240, min, max));
@@ -51,9 +53,9 @@ function Slider({ id, color, kind, start, unit }) {
};
useEffect(() => {
const computedValue = `${value}${unit}`;
const computedValue = `${current}${unit}`;
if (value === start) {
if (current === start) {
document.documentElement.style.removeProperty(`--bulma-${id}`);
} else {
document.documentElement.style.setProperty(
@@ -61,14 +63,14 @@ function Slider({ id, color, kind, start, unit }) {
computedValue,
);
}
}, [id, start, unit, value]);
}, [current, id, start, unit]);
useEffect(() => {
const slider = sliderRef.current;
const sliderRect = slider.getBoundingClientRect();
const final = xToValue(x, sliderRect.width, min, max);
setValue(final);
}, [min, max, unit, x]);
updateVar(id, final);
}, [id, min, max, updateVar, unit, x]);
useEffect(() => {
const docMouseMove = (event) => {
@@ -153,6 +155,7 @@ Slider.propTypes = {
original: PropTypes.string,
start: PropTypes.number,
unit: PropTypes.string,
getValue: PropTypes.func,
};
export default Slider;