mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
Merge pull request #236 from Zagrios/feature/add-hex-input-to-color-pickers
[feature] Add hex color input in color picker
This commit is contained in:
@@ -41,7 +41,7 @@ export const EditVersionModal: ModalComponent<{name: string, color: string}, {ve
|
||||
<div>
|
||||
<span className="block font-bold tracking-wide text-gray-800 dark:text-gray-200">{t("modals.clone-version.inputs.color.label")}</span>
|
||||
<div className="relative w-full h-7 mb-4 bg-light-main-color-1 dark:bg-main-color-1 flex justify-center rounded-md py-1 z-[1]">
|
||||
<SettingColorChooser color={color} onChange={setColor} pickerClassName="!h-32 !w-32"/>
|
||||
<SettingColorChooser color={color} onChange={setColor} pickerClassName="!h-28"/>
|
||||
<div className="absolute right-2 top-0 h-full flex items-center">
|
||||
<BsmButton onClick={resetColor} className="px-2 font-bold italic text-sm rounded-md" text="pages.settings.appearance.reset" withBar={false}/>
|
||||
</div>
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
import { useRef, useState } from "react";
|
||||
import { HexColorPicker } from "react-colorful";
|
||||
import { HexColorPicker, HexColorInput } from "react-colorful";
|
||||
import { motion, AnimatePresence } from "framer-motion"
|
||||
import { useClickOutside } from "renderer/hooks/use-click-outside.hook";
|
||||
import { BsmButton } from "../shared/bsm-button.component";
|
||||
|
||||
export default function SettingColorChooser({color, onChange, pickerClassName}: {color?: string, onChange?: (color: string) => void, pickerClassName?: string}) {
|
||||
|
||||
const [colorVisible, setColorVisible] = useState(false);
|
||||
const ref = useRef(null);
|
||||
useClickOutside(ref, (e) => setColorVisible(false));
|
||||
useClickOutside(ref, (e) => setColorVisible(() => false));
|
||||
|
||||
return (
|
||||
<div ref={ref} className="relative cursor-pointer mx-3 h-full aspect-square flex flex-col items-center">
|
||||
<div ref={ref} className="relative cursor-pointer mx-3 h-full aspect-square flex flex-col items-center z-[1]">
|
||||
<span className="z-[1] block h-full w-full border-2 border-white rounded-full" onClick={() => setColorVisible(!colorVisible)} style={{backgroundColor: color}}/>
|
||||
<AnimatePresence>
|
||||
{colorVisible &&
|
||||
<motion.div initial={{opacity: 0}} animate={{opacity: 1}} transition={{duration: .1}} exit={{opacity: 0}} className="absolute flex items-center justify-center translate-y-9 shadow-lg rounded-lg shadow-black">
|
||||
<div className="absolute w-2/4 aspect-square rotate-45 bg-light-main-color-3 dark:bg-main-color-3 -translate-y-12"/>
|
||||
<HexColorPicker color={color} onChange={onChange} className={pickerClassName} />
|
||||
<motion.div initial={{opacity: 0}} animate={{opacity: 1}} transition={{duration: .1}} exit={{opacity: 0}} className="absolute flex items-center grow-0 flex-col gap-2 justify-center translate-y-9 shadow-lg rounded-lg bg-light-main-color-3 dark:bg-main-color-3 shadow-black">
|
||||
<div className="absolute h-2/4 aspect-square rotate-45 bg-light-main-color-3 dark:bg-main-color-3 -translate-y-12"/>
|
||||
<HexColorPicker color={color} onChange={onChange} className={`${pickerClassName}`} />
|
||||
<div className="w-full max-w-full flex gap-2 px-1 pb-1">
|
||||
<HexColorInput color={color} onChange={onChange} placeholder="#FFFFFF" className="grow w-12 text-center uppercase z-10 rounded-md bg-light-main-color-1 dark:bg-main-color-1 text-main-color-1 dark:text-light-main-color-3 outline-none" prefixed/>
|
||||
<BsmButton className="grow shrink-0 rounded-md text-center" text="misc.apply" typeColor="primary" withBar={false} onClick={() => setColorVisible(() => false)}/>
|
||||
</div>
|
||||
</motion.div>
|
||||
}
|
||||
</AnimatePresence>
|
||||
|
||||
@@ -32,19 +32,22 @@ type Props = {
|
||||
export function BsmButton({className, style, imgClassName, iconClassName, icon, image, text, type, active, withBar = true, disabled, onClickOutside, onClick, typeColor, color, title, iconColor, textClassName}: Props) {
|
||||
|
||||
const t = useTranslation();
|
||||
const secondColor = useThemeColor("second-color");
|
||||
const {firstColor, secondColor} = useThemeColor();
|
||||
const ref = useRef(null);
|
||||
|
||||
useClickOutside(ref, onClickOutside);
|
||||
|
||||
const primaryColor = typeColor === "primary" ? useThemeColor("first-color") : typeColor === "secondary" ? secondColor : undefined;
|
||||
const primaryColor = typeColor === "primary" ? firstColor : typeColor === "secondary" ? secondColor : undefined;
|
||||
|
||||
const textColor = (() => {
|
||||
if(primaryColor){ return getCorrectTextColor(primaryColor); }
|
||||
if(primaryColor){
|
||||
console.log(getCorrectTextColor(primaryColor), text);
|
||||
return getCorrectTextColor(primaryColor);
|
||||
}
|
||||
return typeColor ? "white" : undefined;
|
||||
})();
|
||||
|
||||
const renderTypeColor = (() => {
|
||||
if(typeColor === "primary"){ return ""; }
|
||||
if(!typeColor){ return `bg-light-main-color-2 dark:bg-main-color-2 ${(!withBar && !disabled) && "hover:brightness-125"}`; }
|
||||
if(typeColor === "cancel"){ return "bg-gray-500"; }
|
||||
if(typeColor === "error"){ return "bg-red-500"; }
|
||||
|
||||
@@ -8,5 +8,5 @@ import Color from "color";
|
||||
export function getCorrectTextColor(bgHex: string): string{
|
||||
if(!bgHex){ return "#000"; }
|
||||
const color = Color(bgHex);
|
||||
return color.isLight() ? "#000" : "fff";
|
||||
return color.isLight() ? "#000" : "#fff";
|
||||
}
|
||||
@@ -1,44 +1,24 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { DefaultConfigKey } from "renderer/config/default-configuration.config";
|
||||
import { ConfigurationService } from "renderer/services/configuration.service";
|
||||
import { useObservable } from "./use-observable.hook";
|
||||
import { useService } from "./use-service.hook";
|
||||
import { of, throttleTime } from "rxjs";
|
||||
|
||||
export function useThemeColor(): {firstColor: string, secondColor: string};
|
||||
export function useThemeColor(themeColor: ThemeColor): string;
|
||||
export function useThemeColor(themeColor?: ThemeColor): string|{firstColor: string, secondColor: string}{
|
||||
const configService = ConfigurationService.getInstance();
|
||||
|
||||
if(themeColor){
|
||||
const [color, setColor] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
const sub = configService.watch<string>(themeColor).subscribe(color => {
|
||||
setColor(color);
|
||||
})
|
||||
return () => {
|
||||
sub.unsubscribe();
|
||||
}
|
||||
}, []);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
const [firstColor, setFirstColor] = useState("");
|
||||
const [secondColor, setSecondColor] = useState("");
|
||||
const configService = useService(ConfigurationService);
|
||||
|
||||
useEffect(() => {
|
||||
const sub1 = configService.watch<string>("first-color" as DefaultConfigKey).subscribe(color => {
|
||||
setFirstColor(color);
|
||||
});
|
||||
const sub2 = configService.watch<string>("second-color" as DefaultConfigKey).subscribe(color => {
|
||||
setSecondColor(color);
|
||||
});
|
||||
return () => {
|
||||
sub1.unsubscribe();
|
||||
sub2.unsubscribe();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const firstColor = useObservable(!themeColor ? configService.watch<string>("first-color" as DefaultConfigKey).pipe(throttleTime(16)) : configService.watch<string>(themeColor).pipe(throttleTime(16)));
|
||||
const secondColor = useObservable(!themeColor ? configService.watch<string>("second-color" as DefaultConfigKey).pipe(throttleTime(16)) : of(""));
|
||||
|
||||
return {firstColor, secondColor}
|
||||
if(themeColor){
|
||||
return firstColor;
|
||||
}
|
||||
|
||||
return {firstColor, secondColor}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user