Skip to content

Commit

Permalink
adjust hex values
Browse files Browse the repository at this point in the history
  • Loading branch information
nikk15 committed Aug 8, 2023
1 parent c48ef3b commit e81e8ea
Showing 1 changed file with 49 additions and 11 deletions.
60 changes: 49 additions & 11 deletions admin/src/react-components/ThemeBuilder/ThemeBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ import { CategoryE } from '@mozilla/lilypad-ui';
import { NotificationTypesE } from '@mozilla/lilypad-ui';
import { NotificationLocationE } from '@mozilla/lilypad-ui';

type themeT = {
name: string,
variables: Record<string, string>,
id: string;
default?: boolean
}

type ThemeBuilderP = {
config: Record<string, any>,
onGlobalChange: (path:string, val: string) => void,
onSave: (e:React.SyntheticEvent) => void,
setState: (state:Record<string, any>) => void,
path: string,
disableSave: boolean,
}

const success: NewNotificationT = {
title: "",
description: "Copied them JSON to clipboard!",
Expand All @@ -16,9 +32,9 @@ const success: NewNotificationT = {
};
const error: NewNotificationT = {...success, type: NotificationTypesE.ERROR, description: "Unable to copy JSON to clipboard."}

const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSave}) => {
const [themes, setThemes] =useState(JSON.parse(config?.hubs?.theme?.themes))
const [selectedTheme, setSelectedTheme] = useState(themes.find(theme => !!theme?.default) || themes[0])
const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSave}:ThemeBuilderP) => {
const [themes, setThemes] =useState<themeT[]>(JSON.parse(config?.hubs?.theme?.themes))
const [selectedTheme, setSelectedTheme] = useState<themeT>(themes.find(theme => !!theme?.default) || themes[0])
const [jsonInput, setJsonInput] = useState("")
const [jsonError, setJsonError] = useState("")
const formattedThemes = useMemo(() => themes.map(theme => ({title: theme.name, value: theme.id})), [themes, config]);
Expand All @@ -28,24 +44,24 @@ const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSa
console.log(config)
}, [config])

const onThemeSelect = e => {
const onThemeSelect = (e: React.SyntheticEvent<HTMLInputElement>) => {
e.preventDefault()
setSelectedTheme(themes.find(theme => theme.id === e.target.value))
}

const onSubmit = e => {
const onSubmit = (e: React.SyntheticEvent) => {
onSave(e)
setThemes(prevState => [...prevState.filter(theme => theme.id !== selectedTheme.id), selectedTheme])
}

const onVariableChange = (e, key )=> {
const onVariableChange = (e:React.ChangeEvent<HTMLInputElement>, key:string )=> {
e.preventDefault()
e.persist()
setSelectedTheme(prevState => ({...prevState, variables: {...prevState.variables, [key]: e.target.value}}))
onGlobalChange(path, JSON.stringify([...themes.filter(theme => theme.id !== selectedTheme.id), {...selectedTheme, variables: {...selectedTheme.variables, [key]: e.target.value}}]))
}

const onNameChange = (e )=> {
const onNameChange = (e:React.ChangeEvent<HTMLInputElement> )=> {
e.preventDefault()
e.persist()
setSelectedTheme(prevState => ({...prevState, name: e.target.value}))
Expand All @@ -70,7 +86,7 @@ const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSa
setSelectedTheme(newTheme)
}

const deleteTheme = e => {
const deleteTheme = (e:React.SyntheticEvent) => {
onGlobalChange(path, JSON.stringify(themes.filter(theme => theme.id !== selectedTheme.id)))
setThemes(prevState => prevState.filter(theme => theme.id !== selectedTheme.id))
setSelectedTheme(themes[0])
Expand All @@ -87,7 +103,7 @@ const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSa
});
}

const importThemeFromJson = e => {
const importThemeFromJson = (e:React.SyntheticEvent) => {
e.preventDefault()
const newTheme = e.target[0].value;
setSelectedTheme(JSON.parse(newTheme))
Expand Down Expand Up @@ -124,18 +140,40 @@ const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSa
return true
}

const adjustHexColor = (hex:string, percent:number) => {
// Validate input
if (!/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex)) {
throw new Error("Invalid hex color code");
}

// Convert hex to RGB
let r = parseInt(hex.slice(1, 3), 16);
let g = parseInt(hex.slice(3, 5), 16);
let b = parseInt(hex.slice(5), 16);

// Calculate lighten or darken values. A negative percent darkens.
r = Math.min(255, r + Math.round(255 * (percent / 100)));
g = Math.min(255, g + Math.round(255 * (percent / 100)));
b = Math.min(255, b + Math.round(255 * (percent / 100)));

// Convert back to hex
const newHex = `#${(r << 16 | g << 8 | b).toString(16).padStart(6, '0')}`;

return newHex;
}

// edit name and validate no duplicates
// add new theme
// duplicate theme
// generate id from theme name???
// copy json
// import theme from json - validate and populate missing variables
// delete theme
// calculate darkness or lightness from states

// import theme from web url?? - validate and populate missing variables
// select from github themes
// populate with defaults
// calculate darkness or lightness from states

return (
<div>
Expand All @@ -151,7 +189,7 @@ const ThemeBuilder = ({config, onGlobalChange, onSave, path, setState, disableSa
<form onSubmit={onSubmit} >
<Input label="Name" name="Name" value={selectedTheme.name} onChange={onNameChange} placeholder="Name your theme" />
{Object.entries(selectedTheme.variables).map(([key, value]) => {
return <Input key={key} label={key} name={key} value={value} onChange={e => onVariableChange(e, key)}/>
return <Input key={key} label={key} name={key} value={value} onChange={e => onVariableChange(e, key)} placeholder={''}/>
})}
<Button type="submit" text="Submit" label="Submit" disabled={disableSave}/>
</form>
Expand Down

0 comments on commit e81e8ea

Please sign in to comment.