ThemeEditor: add hue sliders
This commit is contained in:
parent
faf513c049
commit
2505f622e2
2 changed files with 42 additions and 7 deletions
|
@ -1,7 +1,9 @@
|
|||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { HStack } from 'soapbox/components/ui';
|
||||
import { HStack, Stack, Slider } from 'soapbox/components/ui';
|
||||
import { usePrevious } from 'soapbox/hooks';
|
||||
import { compareId } from 'soapbox/utils/comparators';
|
||||
import { hueShift } from 'soapbox/utils/theme';
|
||||
|
||||
import Color from './color';
|
||||
|
||||
|
@ -18,6 +20,9 @@ interface IPalette {
|
|||
const Palette: React.FC<IPalette> = ({ palette, onChange }) => {
|
||||
const tints = Object.keys(palette).sort(compareId);
|
||||
|
||||
const [hue, setHue] = useState(0);
|
||||
const lastHue = usePrevious(hue);
|
||||
|
||||
const handleChange = (tint: string) => {
|
||||
return (color: string) => {
|
||||
onChange({
|
||||
|
@ -27,12 +32,27 @@ const Palette: React.FC<IPalette> = ({ palette, onChange }) => {
|
|||
};
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const delta = hue - (lastHue || 0);
|
||||
|
||||
const adjusted = Object.entries(palette).reduce<ColorGroup>((result, [tint, hex]) => {
|
||||
result[tint] = hueShift(hex, delta * 360);
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
onChange(adjusted);
|
||||
}, [hue]);
|
||||
|
||||
return (
|
||||
<HStack className='w-full h-8 rounded-md overflow-hidden'>
|
||||
{tints.map(tint => (
|
||||
<Color color={palette[tint]} onChange={handleChange(tint)} />
|
||||
))}
|
||||
</HStack>
|
||||
<Stack className='w-full'>
|
||||
<HStack className='h-8 rounded-md overflow-hidden'>
|
||||
{tints.map(tint => (
|
||||
<Color color={palette[tint]} onChange={handleChange(tint)} />
|
||||
))}
|
||||
</HStack>
|
||||
|
||||
<Slider value={hue} onChange={setHue} />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -116,3 +116,18 @@ export const colorsToCss = (colors: TailwindColorPalette): string => {
|
|||
export const generateThemeCss = (soapboxConfig: SoapboxConfig): string => {
|
||||
return colorsToCss(soapboxConfig.colors.toJS() as TailwindColorPalette);
|
||||
};
|
||||
|
||||
const hexToHsl = (hex: string): Hsl | null => {
|
||||
const rgb = hexToRgb(hex);
|
||||
return rgb ? rgbToHsl(rgb) : null;
|
||||
};
|
||||
|
||||
export const hueShift = (hex: string, delta: number): string => {
|
||||
const { h, s, l } = hexToHsl(hex)!;
|
||||
|
||||
return hslToHex({
|
||||
h: (h + delta) % 360,
|
||||
s,
|
||||
l,
|
||||
});
|
||||
};
|
Loading…
Reference in a new issue