Skip to content

Commit

Permalink
feat: add copy value as rem
Browse files Browse the repository at this point in the history
  • Loading branch information
dotRarufu committed Jan 5, 2025
1 parent d2f8fdf commit 8e79867
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 49 deletions.
12 changes: 9 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import Header from "./components/Header";
import Difference from "./components/Difference";
import About from "./components/About";
import { Factor, generateFactorValues } from "./utils/utils";
import { convertToRem, Factor, generateFactorValues } from "./utils/utils";
import Dropdown from "./components/Dropdown";
import { useCopyToClipboard } from "react-use";
import toast, { Toaster } from "react-hot-toast";
Expand All @@ -22,6 +22,7 @@ const App = () => {
const [selectedValue, setSelectedValue] = useState<number | null>(null);
const [factors, setFactors] = useState(defaultFactors);
const [isDivisibleBy4, setIsDivisibleBy4] = useState(true);
const [isCopiedAsRem, setIsCopiedAsRem] = useState(true);

useToastLimit();
const [clipboardState, copyToClipboard] = useCopyToClipboard();
Expand All @@ -34,7 +35,10 @@ const App = () => {
const changeFactor = (f: Factor) => setFactor(f);
const selectValue = (n: number) => () => {
setSelectedValue(n);
copyToClipboard(n.toString());

const value = isCopiedAsRem ? convertToRem(n, base) : n.toString();

copyToClipboard(value);
if (clipboardState.error) {
toast.error("Failed to copy");

Expand All @@ -47,8 +51,10 @@ const App = () => {
changeFactor(f);
};

const changeSettings = (isDivisibleBy4: boolean) =>
const changeSettings = (isDivisibleBy4: boolean, isCopiedAsRem: boolean) => {
setIsCopiedAsRem(isCopiedAsRem);
setIsDivisibleBy4(isDivisibleBy4);
};

const globalContextValues = {
factors,
Expand Down
160 changes: 115 additions & 45 deletions src/components/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,64 +28,134 @@ const variant: Variants = {

const Settings = () => {
const { changeSettings } = useContext(GlobalContext)!;
const [isChecked, setIsChecked] = useState(true);
const backgroundControl = useAnimationControls();
const [isDivisibleBy4, setIsDivisibleBy4] = useState(true);
const [isCopiedAsRem, setIsCopiedAsRem] = useState(true);
const divisibleBy4BackgroundControl = useAnimationControls();
const copyAsRemBackgroundControl = useAnimationControls();

useEffect(() => {
backgroundControl.start(isChecked ? "visible" : "invisible");
changeSettings(isChecked);
}, [backgroundControl, changeSettings, isChecked]);
divisibleBy4BackgroundControl.start(
isDivisibleBy4 ? "visible" : "invisible",
);
changeSettings(isDivisibleBy4, isCopiedAsRem);
}, [
changeSettings,
divisibleBy4BackgroundControl,
isCopiedAsRem,
isDivisibleBy4,
]);

useEffect(() => {
copyAsRemBackgroundControl.start(isCopiedAsRem ? "visible" : "invisible");
changeSettings(isDivisibleBy4, isCopiedAsRem);
}, [
changeSettings,
copyAsRemBackgroundControl,
isCopiedAsRem,
isDivisibleBy4,
]);

return (
<div className="flex flex-col sm:flex-row">
<h2 className="mb-[0.5rem] min-w-[8rem] text-secondary-text sm:mb-[0]">
<div className="w-fit">Settings</div>
</h2>

<div className="flex w-full max-w-[320px] gap-[0.5rem]">
<div className="relative flex h-fit items-center overflow-clip rounded-inner border border-primary-color-500">
<motion.div
variants={variant}
className="border-primar-color-500 absolute left-1/2 top-1/2 -z-[1] aspect-square w-full -translate-x-1/2 -translate-y-1/2"
animate={backgroundControl}
<div className="flex flex-col gap-[0.75rem]">
<div className="flex w-full max-w-[320px] gap-[0.5rem]">
<div className="relative flex h-fit items-center overflow-clip rounded-inner border border-primary-color-500">
<motion.div
variants={variant}
className="border-primar-color-500 absolute left-1/2 top-1/2 -z-[1] aspect-square w-full -translate-x-1/2 -translate-y-1/2"
animate={divisibleBy4BackgroundControl}
style={{
backgroundColor: isDivisibleBy4
? colors["primary-color-500"]
: "transparent",
}}
/>

<input
id="isDivisibleBy4"
name="isDivisibleBy4"
checked={isDivisibleBy4}
onChange={(e) => setIsDivisibleBy4(e.currentTarget.checked)}
className="relative z-[2] aspect-square h-[1.25rem] cursor-pointer appearance-none"
type="checkbox"
/>
<AnimatePresence>
{isDivisibleBy4 && (
<motion.span
variants={variant}
initial="invisible"
animate="visible"
exit="invisible"
className="absolute left-1/2 top-1/2 -z-[1] -translate-x-1/2 -translate-y-1/2"
>
<Check />
</motion.span>
)}
</AnimatePresence>
</div>
<label
htmlFor="isDivisibleBy4"
className="cursor-pointer transition-colors"
style={{
backgroundColor: isChecked
? colors["primary-color-500"]
: "transparent",
color: colors[isDivisibleBy4 ? "primary-text" : "secondary-text"],
}}
/>
>
Divisible by 4
</label>
</div>

<input
id="isDivisibleBy4"
name="isDivisibleBy4"
checked={isChecked}
onChange={(e) => setIsChecked(e.currentTarget.checked)}
className="relative z-[2] aspect-square h-[1.25rem] cursor-pointer appearance-none"
type="checkbox"
/>
<AnimatePresence>
{isChecked && (
<motion.span
variants={variant}
initial="invisible"
animate="visible"
exit="invisible"
className="absolute left-1/2 top-1/2 -z-[1] -translate-x-1/2 -translate-y-1/2"
>
<Check />
</motion.span>
)}
</AnimatePresence>
<div className="flex w-full max-w-[320px] gap-[0.5rem]">
<div className="relative flex h-fit items-center overflow-clip rounded-inner border border-primary-color-500">
<motion.div
variants={variant}
className="border-primar-color-500 absolute left-1/2 top-1/2 -z-[1] aspect-square w-full -translate-x-1/2 -translate-y-1/2"
animate={copyAsRemBackgroundControl}
style={{
backgroundColor: isCopiedAsRem
? colors["primary-color-500"]
: "transparent",
}}
/>

<input
id="isCopiedAsRem"
name="isCopiedAsRem"
checked={isCopiedAsRem}
onChange={(e) => {
const nextState = e.currentTarget.checked;
setIsCopiedAsRem(nextState);
}}
className="relative z-[2] aspect-square h-[1.25rem] cursor-pointer appearance-none"
type="checkbox"
/>
<AnimatePresence>
{isCopiedAsRem && (
<motion.span
variants={variant}
initial="invisible"
animate="visible"
exit="invisible"
className="absolute left-1/2 top-1/2 -z-[1] -translate-x-1/2 -translate-y-1/2"
>
<Check />
</motion.span>
)}
</AnimatePresence>
</div>
<label
htmlFor="isCopiedAsRem"
className="cursor-pointer transition-colors"
style={{
color: colors[isCopiedAsRem ? "primary-text" : "secondary-text"],
}}
>
Copy value as rem
</label>
</div>
<label
htmlFor="isDivisibleBy4"
className="cursor-pointer transition-colors"
style={{
color: colors[isChecked ? "primary-text" : "secondary-text"],
}}
>
Divisible by 4
</label>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/contexts/globalContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type GlobalContextValues = {
selectedValue: number | null;
base: number;
changeBase: (n: number | null) => void;
changeSettings: (isDivisibleBy4: boolean) => void;
changeSettings: (isDivisibleBy4: boolean, isCopiedAsRem: boolean) => void;
};

const GlobalContext = createContext<GlobalContextValues | null>(null);
Expand Down
5 changes: 5 additions & 0 deletions src/utils/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,8 @@ export const getLowestRatio = (value1: number, value2: number): string => {
};

export const roundOff = (n: number) => Math.round(n);

export const roundToDecimal = (value: number, decimals: number): number => {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
};
5 changes: 5 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
isOdd,
nearestDivisibleBy4,
roundOff,
roundToDecimal,
roundToNearestHundredth,
} from "./math";

Expand Down Expand Up @@ -89,3 +90,7 @@ export const generateFactorValues = (

return [...removeDuplicates];
};

export const convertToRem = (number: number, base: number) => {
return roundToDecimal(number / base, 4) + "rem";
};

0 comments on commit 8e79867

Please sign in to comment.