1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2026-06-05 19:15:30 -04:00

do tailwind more smarter 🧠

This commit is contained in:
2025-05-19 16:27:10 -04:00
parent 2796ce189b
commit 51708c9b17
12 changed files with 88 additions and 144 deletions
+4 -7
View File
@@ -92,6 +92,7 @@ const ImageDiff = ({ children, className }: { children: ReactElement[]; classNam
onTouchMove={handleTouchMove}
onKeyDown={handleKeyDown}
className={cn("relative isolate w-full max-w-full overflow-hidden select-none", className)}
style={{ ["--slider-position" as string]: `${sliderPosition}%` }}
role="slider"
aria-label="Image comparison slider"
aria-valuemin={0}
@@ -105,23 +106,19 @@ const ImageDiff = ({ children, className }: { children: ReactElement[]; classNam
</div>
{/* Before image (clipped with width based on slider position) */}
<div className="absolute top-0 left-0 h-full overflow-hidden" style={{ width: `${sliderPosition}%` }}>
<div className="absolute top-0 left-0 h-full w-[var(--slider-position)] overflow-hidden">
<img {...beforeImageProps} className="h-full w-full object-cover object-top-left" />
</div>
{/* Divider line */}
<div
className="bg-muted-foreground absolute top-0 bottom-0 w-1 -translate-x-1/2 drop-shadow-md"
style={{ left: `${sliderPosition}%` }}
/>
<div className="bg-muted-foreground absolute top-0 bottom-0 left-[var(--slider-position)] w-1 -translate-x-1/2 drop-shadow-md" />
{/* Slider handle */}
<div
onMouseDown={handleMouseDown}
onTouchStart={handleMouseDown}
onTouchEnd={handleMouseUp}
className="bg-muted absolute top-1/2 flex h-10 w-10 -translate-x-1/2 -translate-y-1/2 cursor-ew-resize touch-none items-center justify-center rounded-full border-2 drop-shadow-md"
style={{ left: `${sliderPosition}%` }}
className="bg-muted absolute top-1/2 left-[var(--slider-position)] flex h-10 w-10 -translate-x-1/2 -translate-y-1/2 cursor-ew-resize touch-none items-center justify-center rounded-full border-2 drop-shadow-md"
aria-hidden="true"
>
<ChevronsLeftRightIcon className="text-foreground/70 size-6" />
+2 -2
View File
@@ -26,7 +26,7 @@ const Footer = ({ className, ...rest }: ComponentPropsWithoutRef<"footer">) => {
<div>
Made with{" "}
<HeartIcon className="animate-heartbeat stroke-destructive fill-destructive mx-[1px] inline size-4 align-text-top" />{" "}
<HeartIcon className="animate-heartbeat stroke-destructive fill-destructive mx-px inline size-4 align-text-top" />{" "}
and{" "}
<Link
href="https://nextjs.org/"
@@ -34,7 +34,7 @@ const Footer = ({ className, ...rest }: ComponentPropsWithoutRef<"footer">) => {
aria-label="Next.js"
className="text-foreground/85 hover:text-foreground/60 hover:no-underline"
>
<NextjsIcon className="mx-[1px] inline size-4 align-text-top" />
<NextjsIcon className="mx-px inline size-4 align-text-top" />
</Link>
.{" "}
<Link
+1 -1
View File
@@ -32,7 +32,7 @@ const MenuItem = ({
aria-label={text}
data-current={current || undefined}
className={cn(
"text-foreground/85 hover:border-ring data-current:border-primary/40! -mb-[3px] inline-flex items-center p-2.5 hover:border-b-[3px] hover:no-underline data-current:border-b-[3px]",
"text-foreground/85 hover:border-ring data-current:border-primary/40! mb-[-3px] inline-flex items-center p-2.5 hover:border-b-[3px] hover:no-underline data-current:border-b-[3px]",
className
)}
{...rest}
+1 -1
View File
@@ -11,7 +11,7 @@ const PageTitle = ({
canonical: string;
}) => {
return (
<h1 className={cn("mt-0 mb-6 text-left text-3xl font-medium -tracking-[0.015em] lowercase", className)} {...rest}>
<h1 className={cn("mt-0 mb-6 text-left text-3xl font-medium tracking-[-0.015em] lowercase", className)} {...rest}>
<Link
href={canonical}
className="before:text-muted-foreground before:-mr-0.5 before:tracking-widest before:content-['\002E\002F'] hover:no-underline"
-50
View File
@@ -1,50 +0,0 @@
import { cn } from "@/lib/utils";
import type { ComponentPropsWithoutRef } from "react";
const Loading = ({
width = 40,
boxes = 3,
timing = 0.1,
className,
style,
...rest
}: ComponentPropsWithoutRef<"div"> & {
width?: number; // of entire container, in pixels
boxes?: number; // total number of boxes (default: 3)
timing?: number; // staggered timing between each box's pulse, in seconds (default: 0.1s)
}) => {
// each box is just an empty div
const divs = [];
// allow a custom number of pulsing boxes (defaults to 3)
for (let i = 0; i < boxes; i++) {
// width of each box correlates with number of boxes (with a little padding)
// each individual box's animation has a staggered start in corresponding order
divs.push(
<div
key={i}
className="bg-ring inline-block h-full"
style={{
width: `${width / (boxes + 1)}px`,
animationDelay: `${i * timing}s`,
}}
/>
);
}
return (
<div
className={cn("inline-block text-center", className)}
style={{
width: `${width}px`,
height: `${width / 2}px`,
...style,
}}
{...rest}
>
{divs}
</div>
);
};
export default Loading;
+1 -5
View File
@@ -4,17 +4,14 @@ import type { ComponentPropsWithoutRef } from "react";
const CodePen = ({
username,
id,
height = 500,
defaultTab = "html",
preview = true,
editable = false,
style,
className,
...rest
}: {
username: string;
id: string;
height?: number;
defaultTab?: string;
preview?: boolean;
editable?: boolean;
@@ -26,8 +23,7 @@ const CodePen = ({
preview: `${!!preview}`,
editable: `${!!editable}`,
})}`}
style={{ height: `${height}px`, ...style }}
className={cn("w-full overflow-hidden border-none", className)}
className={cn("h-[500px] w-full overflow-hidden border-none", className)}
{...rest}
/>
);