mirror of
https://github.com/jgthms/bulma.git
synced 2024-11-14 11:14:24 +00:00
Fix styling
This commit is contained in:
parent
bb62f531e1
commit
762926d492
@ -7,16 +7,6 @@
|
||||
<title>Vite + React</title>
|
||||
<style type="text/css">
|
||||
#bulma-customizer-app {
|
||||
background: var(--bulma-body-background-color);
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid var(--bulma-border);
|
||||
bottom: 1rem;
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
top: 1rem;
|
||||
width: 33rem;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -42,7 +32,7 @@
|
||||
<table class="table"></table>
|
||||
<div class="tag"></div>
|
||||
<div class="title"></div>
|
||||
<input class="input">
|
||||
<input class="input" />
|
||||
<div class="file"></div>
|
||||
<div class="columns"></div>
|
||||
<div class="grid"></div>
|
||||
|
@ -413,8 +413,8 @@ function App() {
|
||||
"--bulma-tabs-link-active-color": "var(--bulma-primary)",
|
||||
};
|
||||
|
||||
const appClass = classNames({
|
||||
[cn.app]: true,
|
||||
const customizerClass = classNames({
|
||||
[cn.customizer]: true,
|
||||
[cn.open]: context.isOpen,
|
||||
});
|
||||
|
||||
@ -425,46 +425,48 @@ function App() {
|
||||
|
||||
return (
|
||||
<CustomizerContext.Provider value={context}>
|
||||
<style ref={styleRef} />
|
||||
<div className={cn.app}>
|
||||
<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={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>
|
||||
);
|
||||
}
|
||||
|
@ -3,15 +3,31 @@
|
||||
--var-item-slider-width: 30rem;
|
||||
--var-item-padding: 1rem;
|
||||
--var-item-gap: 1rem;
|
||||
bottom: 1rem;
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
top: 1rem;
|
||||
width: 33rem;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.customizer {
|
||||
background: var(--bulma-background);
|
||||
border-radius: 0.5rem;
|
||||
transform-origin: bottom right;
|
||||
transition-duration: 300ms;
|
||||
transition-property: opacity, transform;
|
||||
transform: scale(0.9);
|
||||
transform: scale(0.98) translate(2px, 2px);
|
||||
margin-bottom: 4rem;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.open {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@ -19,11 +35,11 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
bottom: 1.5rem;
|
||||
right: 1.5rem;
|
||||
position: fixed;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useContext } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import Slider from "./Slider";
|
||||
@ -7,7 +7,7 @@ import cn from "./Color.module.css";
|
||||
import { CustomizerContext } from "../App";
|
||||
import classNames from "classnames";
|
||||
|
||||
function hslToHex(h, s, l) {
|
||||
export function hslToHex(h, s, l) {
|
||||
s /= 100;
|
||||
l /= 100;
|
||||
|
||||
@ -102,7 +102,6 @@ function hexToHsl(hex) {
|
||||
|
||||
function Color({ color }) {
|
||||
const { cssvars, updateVar } = useContext(CustomizerContext);
|
||||
const [hexValue, setHexValue] = useState("");
|
||||
|
||||
const hName = `${color}-h`;
|
||||
const sName = `${color}-s`;
|
||||
@ -152,42 +151,11 @@ function Color({ color }) {
|
||||
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;
|
||||
}
|
||||
@ -205,12 +173,7 @@ function Color({ color }) {
|
||||
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>
|
||||
@ -225,72 +188,66 @@ function Color({ color }) {
|
||||
</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>
|
||||
|
@ -1,17 +1,9 @@
|
||||
.main {
|
||||
background-color: var(--bulma-body-background-color);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--var-item-gap);
|
||||
box-shadow: 0 0 0 1px var(--bulma-border);
|
||||
border-top: 1px solid var(--bulma-border);
|
||||
padding: var(--var-item-padding);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.side {
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
background-color: hsl(var(--h) var(--s) var(--l));
|
||||
height: 1.25rem;
|
||||
@ -42,13 +34,23 @@
|
||||
|
||||
.line {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
gap: 0 1.5rem;
|
||||
}
|
||||
|
||||
.line p {
|
||||
color: var(--bulma-text-strong);
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 1.5rem;
|
||||
}
|
||||
|
||||
.form {
|
||||
@ -56,6 +58,7 @@
|
||||
align-items: center;
|
||||
font-family: var(--bulma-family-code);
|
||||
gap: 0.25em;
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.form input {
|
||||
@ -71,3 +74,7 @@
|
||||
.form span {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.example {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
@ -67,11 +67,14 @@ function Slider({ id, color }) {
|
||||
// }, [current, id, start, unit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMoving) {
|
||||
return;
|
||||
}
|
||||
const slider = sliderRef.current;
|
||||
const sliderRect = slider.getBoundingClientRect();
|
||||
const final = xToValue(x, sliderRect.width, min, max);
|
||||
updateVar(id, final);
|
||||
}, [id, min, max, updateVar, x]);
|
||||
}, [id, isMoving, min, max, updateVar, x]);
|
||||
|
||||
useEffect(() => {
|
||||
const newX = valueToX(current, 360, min, max);
|
||||
|
@ -1,7 +1,6 @@
|
||||
.main {
|
||||
background-color: var(--bulma-body-background-color);
|
||||
gap: var(--var-item-gap);
|
||||
box-shadow: 0 0 0 1px var(--bulma-border);
|
||||
border-top: 1px solid var(--bulma-border);
|
||||
padding: var(--var-item-padding);
|
||||
transition-property: background-color;
|
||||
transition-duration: var(--bulma-duration);
|
||||
|
Loading…
Reference in New Issue
Block a user