Skip to content

Commit

Permalink
Merge pull request #201 from Willem-Jaap/preview-rework
Browse files Browse the repository at this point in the history
Preview rework
  • Loading branch information
Willem-Jaap authored Nov 10, 2024
2 parents 43c292d + 487df3e commit 7ccd709
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 121 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"dependencies": {
"@gsap/react": "^2.1.0",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@react-spring/web": "^9.7.3",
"@vercel/analytics": "^1.2.2",
Expand Down
53 changes: 53 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 23 additions & 39 deletions src/components/misc/actions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { useEffect } from 'react';
import { useState } from 'react';
import { CopyCheckIcon, CopyIcon } from 'lucide-react';
import Link from 'next/link';

import NumberInput from '~/components/form/number-input';
Expand All @@ -15,49 +16,15 @@ import {
DropdownMenuTrigger,
} from '~/components/ui/dropdown-menu';
import useSettings, { type Mode } from '~/hooks/useSettings';
import { getTailwindByValue, getTailwindValue } from '~/utils/getTailwindValue';
import { getTailwindByValue } from '~/utils/getTailwindValue';

const Actions = () => {
const { register, watch, getValues, setValue } = useSettings();
const [copied, setCopied] = useState(false);

const remify = (px: number) => px / 16;
const toFixed = (num: number) => parseFloat(num.toFixed(3));

const getValue = (value: number, mode: Mode) => {
if (mode === 'rem') {
return value;
}

if (mode === 'tailwind') {
return getTailwindValue(value);
}

return remify(value);
};

let maximumValue = remify(watch('maximumValue'));
let minimumValue = remify(watch('minimumValue'));
let maximumViewport = remify(watch('maximumViewport'));
let minimumViewport = remify(watch('minimumViewport'));

if (watch('mode') === 'rem') {
maximumValue = watch('maximumValue');
minimumValue = watch('minimumValue');
maximumViewport = watch('maximumViewport');
minimumViewport = watch('minimumViewport');
}

const slope = (maximumValue - minimumValue) / (maximumViewport - minimumViewport);
const intersection = maximumValue - slope * maximumViewport;

const mode = watch('mode');
const clamp = `clamp(${getValue(watch('minimumValue'), mode)}rem, ${toFixed(
intersection,
)}rem + ${toFixed(slope * 100)}vw, ${getValue(watch('maximumValue'), mode)}rem)`;

useEffect(() => {
setValue('clamp', clamp);
}, [clamp, setValue]);

const onModeChange = (mode: string) => {
const previousValue = getValues('mode');
Expand Down Expand Up @@ -97,6 +64,12 @@ const Actions = () => {
setValue('mode', mode as Mode);
};

const handleCopy = async () => {
await navigator.clipboard.writeText(watch('clamp'));
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

return (
<div className="flex h-full flex-col">
<div className="flex items-center justify-between gap-4 border-b border-b-neutral-200 p-5">
Expand Down Expand Up @@ -189,14 +162,25 @@ const Actions = () => {
</div>

<div className="flex flex-1 flex-col justify-between p-5">
<p className="mb-16 text-sm text-neutral-600">
<p className="mb-4 text-sm text-neutral-600">
The clamped value will be between {watch('minimumValue')}{' '}
{mode !== 'tailwind' && mode} and {watch('maximumValue')}{' '}
{mode !== 'tailwind' && mode}, applied linearly between the viewport sizes of{' '}
{watch('minimumViewport')} {mode !== 'tailwind' && mode} and{' '}
{watch('maximumViewport')} {mode !== 'tailwind' && mode}.
</p>
<p className="font-medium">{clamp}</p>
<div className="flex items-center justify-between gap-4">
<p className="font-medium">{watch('clamp')}</p>
<Button className="h-10 min-w-10 p-2" variant="outline" onClick={handleCopy}>
{copied ? (
<span className="flex items-center gap-2 text-sm">
<CopyCheckIcon size={16} /> Copied
</span>
) : (
<CopyIcon size={16} />
)}
</Button>
</div>
</div>
</div>
);
Expand Down
16 changes: 16 additions & 0 deletions src/components/misc/preview-element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client';

import useSettings from '~/hooks/useSettings';

const PreviewElement = () => {
const { watch } = useSettings();

return (
<div
className="h-20 rounded-lg border border-dashed border-neutral-400 bg-neutral-200 px-2 py-1"
style={{ margin: `0 ${watch('clamp').replace('vw', '%')}` }}
/>
);
};

export default PreviewElement;
44 changes: 44 additions & 0 deletions src/components/misc/preview-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use client';

import { type Dispatch, type SetStateAction } from 'react';
import { type SpringRef } from '@react-spring/web';

import { Slider } from '~/components/ui/slider';

interface Props {
api: SpringRef<{
width: number;
}>;
percentage: number;
setPercentage: Dispatch<SetStateAction<number>>;
}

const PreviewHeader = ({ api, percentage, setPercentage }: Props) => {
const onChange = (values: number[]) => {
const [value] = values;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
api.start({ width: value });
setPercentage(value);
};

return (
<div className="flex w-full items-center justify-between gap-4 border-b border-b-neutral-100 p-5">
<h2 className="text-lg font-medium">Emulated screen width</h2>
<div className="flex items-center gap-4">
<Slider
className="w-40"
min={0}
max={100}
step={1}
defaultValue={[60]}
onValueChange={onChange}
/>
<div className="w-[calc(1.2rem_+_6ch)] rounded-lg border border-neutral-100 px-3 py-2 text-right font-medium text-neutral-600">
{Math.round((1920 / 100) * percentage)}px
</div>
</div>
</div>
);
};

export default PreviewHeader;
2 changes: 1 addition & 1 deletion src/components/misc/preview-mode-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const PreviewModeSelector = () => {
<Icon
name={`typography-${watch('previewMode') === 'container' ? 'dark' : 'light'}`}
/>
Font Resizing Mode
Font Sizing Mode
</button>
</div>
);
Expand Down
17 changes: 17 additions & 0 deletions src/components/misc/preview-text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import useSettings from '~/hooks/useSettings';

const PreviewText = () => {
const { watch } = useSettings();

return (
<div
className="h-20 rounded-lg border border-dashed border-neutral-400 bg-neutral-200 px-2 py-1"
style={{ margin: `0 ${watch('clamp').replace('vw', '%')}` }}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor
</div>
);
};

export default PreviewText;
Loading

0 comments on commit 7ccd709

Please sign in to comment.