mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-06-27 14:45:41 -04:00
do react types more better too 🧠
This commit is contained in:
@ -1,13 +1,11 @@
|
||||
import { env } from "@/lib/env";
|
||||
import { EyeIcon } from "lucide-react";
|
||||
import Link from "@/components/link";
|
||||
import { getFrontMatter, POSTS_DIR } from "@/lib/posts";
|
||||
import { getFrontMatter, POSTS_DIR, type FrontMatter } from "@/lib/posts";
|
||||
import { createMetadata } from "@/lib/metadata";
|
||||
import { formatDate, formatDateISO } from "@/lib/date";
|
||||
import authorConfig from "@/lib/config/author";
|
||||
import { getViews } from "@/lib/views";
|
||||
import type { ReactElement } from "react";
|
||||
import type { FrontMatter } from "@/lib/posts";
|
||||
|
||||
export const revalidate = 300; // 5 minutes
|
||||
|
||||
@ -33,7 +31,7 @@ const Page = async () => {
|
||||
});
|
||||
});
|
||||
|
||||
const sections: ReactElement[] = [];
|
||||
const sections: React.ReactNode[] = [];
|
||||
|
||||
Object.entries(postsByYear).forEach(([year, posts]) => {
|
||||
sections.push(
|
||||
|
@ -16,7 +16,7 @@ export const Terminal = () => (
|
||||
backgroundImage: `url(${backgroundImg.src})`,
|
||||
}}
|
||||
>
|
||||
<code className="border-ring block rounded-lg border border-solid bg-black/60 p-4 text-sm break-all text-white/90 backdrop-blur-xs backdrop-saturate-150">
|
||||
<code className="border-ring block rounded-lg border border-solid bg-black/60 p-4 text-sm break-all text-white/90 backdrop-blur-sm backdrop-saturate-150">
|
||||
<span style={{ color: "#f95757" }}>sundar</span>@<span style={{ color: "#3b9dd2" }}>google</span>:
|
||||
<span style={{ color: "#78df55" }}>~</span>$ <span style={{ color: "#d588fb" }}>mv</span> /root
|
||||
<a href="https://killedbygoogle.com/" style={{ color: "inherit" }} className="hover:no-underline">
|
||||
|
@ -1,9 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { ActivityCalendar } from "react-activity-calendar";
|
||||
import { ActivityCalendar, type Activity } from "react-activity-calendar";
|
||||
import { formatDate } from "@/lib/date";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import type { Activity } from "react-activity-calendar";
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@ -12,7 +10,7 @@ const Calendar = ({
|
||||
noun = "thing",
|
||||
className,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"div"> & {
|
||||
}: React.ComponentProps<"div"> & {
|
||||
data: Activity[];
|
||||
noun?: string;
|
||||
}) => {
|
||||
|
@ -3,7 +3,6 @@ import reactToText from "react-to-text";
|
||||
import { CodeIcon, TerminalIcon } from "lucide-react";
|
||||
import CopyButton from "@/components/copy-button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentProps, ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const CodeBlock = async ({
|
||||
showLineNumbers = false,
|
||||
@ -11,7 +10,7 @@ const CodeBlock = async ({
|
||||
className,
|
||||
children,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"pre"> & {
|
||||
}: React.ComponentProps<"pre"> & {
|
||||
showLineNumbers?: boolean;
|
||||
showCopyButton?: boolean;
|
||||
}) => {
|
||||
@ -24,7 +23,7 @@ const CodeBlock = async ({
|
||||
);
|
||||
}
|
||||
|
||||
const codeProps = children.props as ComponentProps<"code">;
|
||||
const codeProps = children.props as React.ComponentProps<"code">;
|
||||
const codeString = reactToText(codeProps.children).trim();
|
||||
|
||||
// the language set in the markdown is passed as a className
|
||||
@ -51,7 +50,7 @@ const CodeBlock = async ({
|
||||
dangerouslySetInnerHTML={{ __html: codeHighlighted }}
|
||||
/>
|
||||
{lang && (
|
||||
<span className="[&_svg]:stroke-primary/90 text-foreground/75 bg-muted/40 absolute top-0 left-0 z-10 flex items-center gap-[8px] rounded-tl-md rounded-br-lg border-r-2 border-b-2 px-[10px] py-[5px] font-mono text-xs font-medium tracking-wide uppercase backdrop-blur-xs select-none [&_svg]:size-[14px] [&_svg]:shrink-0">
|
||||
<span className="[&_svg]:stroke-primary/90 text-foreground/75 bg-muted/40 absolute top-0 left-0 z-10 flex items-center gap-[8px] rounded-tl-md rounded-br-lg border-r-2 border-b-2 px-[10px] py-[5px] font-mono text-xs font-medium tracking-wide uppercase backdrop-blur-sm select-none [&_svg]:size-[14px] [&_svg]:shrink-0">
|
||||
{["sh", "bash", "zsh"].includes(lang) ? (
|
||||
<>
|
||||
<TerminalIcon />
|
||||
@ -68,7 +67,7 @@ const CodeBlock = async ({
|
||||
{showCopyButton && (
|
||||
<CopyButton
|
||||
source={codeString}
|
||||
className="text-foreground/75 hover:text-primary bg-muted/40 absolute top-0 right-0 z-10 size-10 rounded-tr-md rounded-bl-lg border-b-2 border-l-2 p-0 backdrop-blur-xs select-none [&_svg]:my-auto [&_svg]:inline-block [&_svg]:size-4.5 [&_svg]:align-text-bottom"
|
||||
className="text-foreground/75 hover:text-primary bg-muted/40 absolute top-0 right-0 z-10 size-10 rounded-tr-md rounded-bl-lg border-b-2 border-l-2 p-0 backdrop-blur-sm select-none [&_svg]:my-auto [&_svg]:inline-block [&_svg]:size-4.5 [&_svg]:align-text-bottom"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -12,7 +12,6 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover
|
||||
import { MarkdownIcon } from "@/components/icons";
|
||||
import { useSession } from "@/lib/auth-client";
|
||||
import { createComment, updateComment } from "@/lib/server/comments";
|
||||
import type { FormEvent } from "react";
|
||||
|
||||
const CommentForm = ({
|
||||
slug,
|
||||
@ -36,7 +35,7 @@ const CommentForm = ({
|
||||
|
||||
const { data: session } = useSession();
|
||||
|
||||
const handleSubmit = (e: FormEvent) => {
|
||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!content.trim()) {
|
||||
|
@ -4,7 +4,6 @@ import { forwardRef, useState, useEffect } from "react";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { ClipboardIcon, CheckIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { Ref, ComponentPropsWithoutRef, ComponentRef, MouseEventHandler } from "react";
|
||||
|
||||
const CopyButton = (
|
||||
{
|
||||
@ -12,15 +11,15 @@ const CopyButton = (
|
||||
timeout = 2000,
|
||||
className,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"button"> & {
|
||||
}: React.ComponentProps<"button"> & {
|
||||
source: string;
|
||||
timeout?: number;
|
||||
},
|
||||
ref: Ref<ComponentRef<"button">>
|
||||
ref: React.Ref<React.ComponentRef<"button">>
|
||||
) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy: MouseEventHandler<ComponentRef<"button">> = (e) => {
|
||||
const handleCopy: React.MouseEventHandler<React.ComponentRef<"button">> = (e) => {
|
||||
// prevent unintentional double-clicks by unfocusing button
|
||||
e.currentTarget.blur();
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/* eslint-disable jsx-a11y/alt-text, @next/next/no-img-element */
|
||||
"use client";
|
||||
|
||||
import { ReactElement, Children, useState, useRef, useEffect } from "react";
|
||||
import { useState, useRef, useEffect, Children } from "react";
|
||||
import { getImageProps } from "next/image";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronsLeftRightIcon } from "lucide-react";
|
||||
|
||||
const ImageDiff = ({ children, className }: { children: ReactElement[]; className?: string }) => {
|
||||
const ImageDiff = ({ children, className }: { children: React.ReactElement[]; className?: string }) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [sliderPosition, setSliderPosition] = useState(50);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
@ -4,9 +4,8 @@ import Link from "@/components/link";
|
||||
import { NextjsIcon } from "@/components/icons";
|
||||
import { cn } from "@/lib/utils";
|
||||
import siteConfig from "@/lib/config/site";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Footer = ({ className, ...rest }: ComponentPropsWithoutRef<"footer">) => {
|
||||
const Footer = ({ className, ...rest }: React.ComponentProps<"footer">) => {
|
||||
return (
|
||||
<footer
|
||||
className={cn("text-foreground/85 text-[0.8rem] leading-loose md:flex md:flex-row md:justify-between", className)}
|
||||
|
@ -3,11 +3,10 @@ import Link from "@/components/link";
|
||||
import Menu from "@/components/layout/menu";
|
||||
import { cn } from "@/lib/utils";
|
||||
import siteConfig from "@/lib/config/site";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
import avatarImg from "@/app/avatar.jpg";
|
||||
|
||||
const Header = ({ className, ...rest }: ComponentPropsWithoutRef<"header">) => {
|
||||
const Header = ({ className, ...rest }: React.ComponentProps<"header">) => {
|
||||
return (
|
||||
<header className={cn("flex items-center justify-between", className)} {...rest}>
|
||||
<Link
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { isValidElement } from "react";
|
||||
import Link from "@/components/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import type { MenuItemConfig } from "@/lib/config/menu";
|
||||
|
||||
const MenuItem = ({
|
||||
text,
|
||||
@ -10,17 +9,17 @@ const MenuItem = ({
|
||||
current,
|
||||
className,
|
||||
...rest
|
||||
}: Omit<ComponentPropsWithoutRef<typeof Link>, "href"> &
|
||||
MenuItemConfig & {
|
||||
current?: boolean;
|
||||
}) => {
|
||||
const Icon = icon;
|
||||
|
||||
}: Omit<React.ComponentProps<typeof Link>, "href"> & {
|
||||
text?: string;
|
||||
href?: `/${string}`;
|
||||
icon?: React.ReactNode;
|
||||
current?: boolean;
|
||||
}) => {
|
||||
const item = (
|
||||
<>
|
||||
{Icon && <Icon className="stroke-foreground/85 block h-7 w-7 md:h-5 md:w-5" />}
|
||||
<div className="[&_svg]:stroke-foreground/85 inline-flex items-center [&_svg]:size-7 [&_svg]:md:size-5">
|
||||
{isValidElement(icon) && icon}
|
||||
{text && <span className="ml-3 text-sm leading-none font-medium tracking-wide max-md:sr-only">{text}</span>}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
|
||||
// allow both navigational links and/or other interactive react components (e.g. the theme toggle)
|
||||
@ -32,7 +31,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! inline-flex items-center p-2.5 hover:border-b-[3px] hover:no-underline data-current:border-b-[3px]",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
|
@ -4,37 +4,52 @@ import { useSelectedLayoutSegment } from "next/navigation";
|
||||
import MenuItem from "@/components/layout/menu-item";
|
||||
import ThemeToggle from "@/components/layout/theme-toggle";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { menuItems } from "@/lib/config/menu";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import { HomeIcon, PencilLineIcon, CodeXmlIcon, MailIcon } from "lucide-react";
|
||||
|
||||
const Menu = ({ className, ...rest }: ComponentPropsWithoutRef<"ul">) => {
|
||||
const menuItems: React.ComponentProps<typeof MenuItem>[] = [
|
||||
{
|
||||
text: "Home",
|
||||
href: "/",
|
||||
icon: <HomeIcon />,
|
||||
},
|
||||
{
|
||||
text: "Notes",
|
||||
href: "/notes",
|
||||
icon: <PencilLineIcon />,
|
||||
},
|
||||
{
|
||||
text: "Projects",
|
||||
href: "/projects",
|
||||
icon: <CodeXmlIcon />,
|
||||
},
|
||||
{
|
||||
text: "Contact",
|
||||
href: "/contact",
|
||||
icon: <MailIcon />,
|
||||
},
|
||||
{
|
||||
icon: <ThemeToggle />,
|
||||
},
|
||||
];
|
||||
|
||||
const Menu = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
const segment = useSelectedLayoutSegment() || "";
|
||||
|
||||
return (
|
||||
<ul
|
||||
className={cn(
|
||||
"flex max-w-2/3 flex-row justify-between md:max-w-none md:justify-end md:gap-4 max-sm:[&>li]:first-of-type:hidden",
|
||||
className
|
||||
)}
|
||||
<div
|
||||
className={cn("flex max-w-2/3 flex-row justify-between md:max-w-none md:justify-end md:gap-4", className)}
|
||||
{...rest}
|
||||
>
|
||||
{menuItems.map((item) => {
|
||||
{menuItems.map((item, index) => {
|
||||
const isCurrent = item.href?.split("/")[1] === segment;
|
||||
|
||||
return (
|
||||
<li className="inline-block" key={item.href}>
|
||||
<div className="mt-[3px] inline-block last:-mr-2.5 max-sm:first:hidden" key={index}>
|
||||
<MenuItem {...item} current={isCurrent} />
|
||||
</li>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
<li className="-mr-2.5 inline-block">
|
||||
<MenuItem
|
||||
// @ts-ignore
|
||||
icon={ThemeToggle}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
import Link from "@/components/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const PageTitle = ({
|
||||
canonical,
|
||||
className,
|
||||
children,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"h1"> & {
|
||||
}: React.ComponentProps<"h1"> & {
|
||||
canonical: string;
|
||||
}) => {
|
||||
return (
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
import { createContext, useEffect, useState } from "react";
|
||||
import { useLocalStorage, useMedia } from "react-use";
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
export const ThemeContext = createContext<{
|
||||
/**
|
||||
@ -19,7 +18,7 @@ export const ThemeContext = createContext<{
|
||||
});
|
||||
|
||||
// provider used once in _app.tsx to wrap entire app
|
||||
export const ThemeProvider = ({ children }: PropsWithChildren) => {
|
||||
export const ThemeProvider = ({ children }: React.PropsWithChildren) => {
|
||||
// keep track of if/when the user has set their theme *on this site*
|
||||
const [preferredTheme, setPreferredTheme] = useLocalStorage<string>("theme", undefined, { raw: true });
|
||||
// keep track of changes to the user's OS/browser dark mode setting
|
||||
|
@ -3,20 +3,23 @@
|
||||
import { useContext } from "react";
|
||||
import { MoonIcon, SunIcon } from "lucide-react";
|
||||
import { ThemeContext } from "@/components/layout/theme-context";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const ThemeToggle = ({ ...rest }: ComponentPropsWithoutRef<LucideIcon>) => {
|
||||
const ThemeToggle = ({ className, ...rest }: React.ComponentProps<"button">) => {
|
||||
const { theme, setTheme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
|
||||
aria-label="Toggle theme"
|
||||
className="hover:*:stroke-warning block cursor-pointer bg-transparent p-2.5 not-dark:[&_.lucide-moon]:hidden dark:[&_.lucide-sun]:hidden"
|
||||
className={cn(
|
||||
"hover:*:stroke-warning block cursor-pointer bg-transparent p-2.5 not-dark:[&_.lucide-moon]:hidden dark:[&_.lucide-sun]:hidden",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<SunIcon {...rest} />
|
||||
<MoonIcon {...rest} />
|
||||
<SunIcon />
|
||||
<MoonIcon />
|
||||
<span className="sr-only">Toggle theme</span>
|
||||
</button>
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import NextLink from "next/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Link = ({
|
||||
href,
|
||||
@ -10,7 +9,7 @@ const Link = ({
|
||||
dynamicOnHover,
|
||||
className,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof NextLink> & {
|
||||
}: React.ComponentProps<typeof NextLink> & {
|
||||
// https://github.com/vercel/next.js/pull/77866/files#diff-040f76a8f302dd3a8ec7de0867048475271f052b094cd73d2d0751b495c02f7dR30
|
||||
dynamicOnHover?: boolean;
|
||||
}) => {
|
||||
@ -27,7 +26,7 @@ const Link = ({
|
||||
className
|
||||
),
|
||||
...rest,
|
||||
} as ComponentPropsWithoutRef<"a">;
|
||||
} as React.ComponentProps<"a">;
|
||||
|
||||
// don't waste time with next's component if it's just an external link
|
||||
if (isExternal) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
// https://magicui.design/docs/components/marquee
|
||||
const Marquee = ({
|
||||
@ -7,7 +6,7 @@ const Marquee = ({
|
||||
className,
|
||||
children,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"div"> & {
|
||||
}: React.ComponentProps<"div"> & {
|
||||
reverse?: boolean;
|
||||
pauseOnHover?: boolean;
|
||||
repeat?: number;
|
||||
|
@ -1,9 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import TimeAgo from "react-timeago";
|
||||
import { type ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const RelativeTime = ({ ...rest }: ComponentPropsWithoutRef<typeof TimeAgo>) => {
|
||||
const RelativeTime = ({ ...rest }: React.ComponentProps<typeof TimeAgo>) => {
|
||||
return (
|
||||
<span suppressHydrationWarning>
|
||||
<TimeAgo {...rest} />
|
||||
|
3
components/third-party/codepen.tsx
vendored
3
components/third-party/codepen.tsx
vendored
@ -1,5 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const CodePen = ({
|
||||
username,
|
||||
@ -15,7 +14,7 @@ const CodePen = ({
|
||||
defaultTab?: string;
|
||||
preview?: boolean;
|
||||
editable?: boolean;
|
||||
} & ComponentPropsWithoutRef<"iframe">) => {
|
||||
} & React.ComponentProps<"iframe">) => {
|
||||
return (
|
||||
<iframe
|
||||
src={`https://codepen.io/${username}/embed/${id}/?${new URLSearchParams({
|
||||
|
3
components/third-party/gist.tsx
vendored
3
components/third-party/gist.tsx
vendored
@ -1,13 +1,12 @@
|
||||
import Link from "@/components/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Gist = async ({
|
||||
id,
|
||||
file,
|
||||
className,
|
||||
...rest
|
||||
}: { id: string; file?: string } & ComponentPropsWithoutRef<"iframe">) => {
|
||||
}: { id: string; file?: string } & React.ComponentProps<"iframe">) => {
|
||||
const iframeId = `gist-${id}${file ? `-${file}` : ""}`;
|
||||
|
||||
const scriptUrl = `https://gist.github.com/${id}.js${file ? `?file=${file}` : ""}`;
|
||||
|
3
components/third-party/youtube.tsx
vendored
3
components/third-party/youtube.tsx
vendored
@ -1,11 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import YouTubeEmbed from "react-lite-youtube-embed";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
// lite-youtube-embed CSS is imported in app/global.css to save a request
|
||||
|
||||
const YouTube = ({ ...rest }: Omit<ComponentPropsWithoutRef<typeof YouTubeEmbed>, "title">) => {
|
||||
const YouTube = ({ ...rest }: Omit<React.ComponentProps<typeof YouTubeEmbed>, "title">) => {
|
||||
return <YouTubeEmbed cookie={false} containerElement="div" title="" {...rest} />;
|
||||
};
|
||||
|
||||
|
@ -3,21 +3,20 @@
|
||||
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const AlertDialog = ({ ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Root>) => {
|
||||
const AlertDialog = ({ ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) => {
|
||||
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...rest} />;
|
||||
};
|
||||
|
||||
const AlertDialogTrigger = ({ ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Trigger>) => {
|
||||
const AlertDialogTrigger = ({ ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) => {
|
||||
return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...rest} />;
|
||||
};
|
||||
|
||||
const AlertDialogPortal = ({ ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Portal>) => {
|
||||
const AlertDialogPortal = ({ ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) => {
|
||||
return <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...rest} />;
|
||||
};
|
||||
|
||||
const AlertDialogOverlay = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>) => {
|
||||
const AlertDialogOverlay = ({ className, ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) => {
|
||||
return (
|
||||
<AlertDialogPrimitive.Overlay
|
||||
data-slot="alert-dialog-overlay"
|
||||
@ -30,7 +29,7 @@ const AlertDialogOverlay = ({ className, ...rest }: ComponentPropsWithoutRef<typ
|
||||
);
|
||||
};
|
||||
|
||||
const AlertDialogContent = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>) => {
|
||||
const AlertDialogContent = ({ className, ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Content>) => {
|
||||
return (
|
||||
<AlertDialogPortal>
|
||||
<AlertDialogOverlay />
|
||||
@ -46,7 +45,7 @@ const AlertDialogContent = ({ className, ...rest }: ComponentPropsWithoutRef<typ
|
||||
);
|
||||
};
|
||||
|
||||
const AlertDialogHeader = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const AlertDialogHeader = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return (
|
||||
<div
|
||||
data-slot="alert-dialog-header"
|
||||
@ -56,7 +55,7 @@ const AlertDialogHeader = ({ className, ...rest }: ComponentPropsWithoutRef<"div
|
||||
);
|
||||
};
|
||||
|
||||
const AlertDialogFooter = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const AlertDialogFooter = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return (
|
||||
<div
|
||||
data-slot="alert-dialog-footer"
|
||||
@ -66,7 +65,7 @@ const AlertDialogFooter = ({ className, ...rest }: ComponentPropsWithoutRef<"div
|
||||
);
|
||||
};
|
||||
|
||||
const AlertDialogTitle = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>) => {
|
||||
const AlertDialogTitle = ({ className, ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) => {
|
||||
return (
|
||||
<AlertDialogPrimitive.Title
|
||||
data-slot="alert-dialog-title"
|
||||
@ -79,7 +78,7 @@ const AlertDialogTitle = ({ className, ...rest }: ComponentPropsWithoutRef<typeo
|
||||
const AlertDialogDescription = ({
|
||||
className,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>) => {
|
||||
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) => {
|
||||
return (
|
||||
<AlertDialogPrimitive.Description
|
||||
data-slot="alert-dialog-description"
|
||||
@ -89,11 +88,11 @@ const AlertDialogDescription = ({
|
||||
);
|
||||
};
|
||||
|
||||
const AlertDialogAction = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>) => {
|
||||
const AlertDialogAction = ({ className, ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Action>) => {
|
||||
return <AlertDialogPrimitive.Action className={cn(buttonVariants(), className)} {...rest} />;
|
||||
};
|
||||
|
||||
const AlertDialogCancel = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>) => {
|
||||
const AlertDialogCancel = ({ className, ...rest }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) => {
|
||||
return <AlertDialogPrimitive.Cancel className={cn(buttonVariants({ variant: "outline" }), className)} {...rest} />;
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const AspectRatio = ({ ...rest }: ComponentPropsWithoutRef<typeof AspectRatioPrimitive.Root>) => {
|
||||
const AspectRatio = ({ ...rest }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) => {
|
||||
return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...rest} />;
|
||||
};
|
||||
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Avatar = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>) => {
|
||||
const Avatar = ({ className, ...rest }: React.ComponentProps<typeof AvatarPrimitive.Root>) => {
|
||||
return (
|
||||
<AvatarPrimitive.Root
|
||||
data-slot="avatar"
|
||||
@ -14,13 +13,13 @@ const Avatar = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AvatarPr
|
||||
);
|
||||
};
|
||||
|
||||
const AvatarImage = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>) => {
|
||||
const AvatarImage = ({ className, ...rest }: React.ComponentProps<typeof AvatarPrimitive.Image>) => {
|
||||
return (
|
||||
<AvatarPrimitive.Image data-slot="avatar-image" className={cn("aspect-square size-full", className)} {...rest} />
|
||||
);
|
||||
};
|
||||
|
||||
const AvatarFallback = ({ className, ...rest }: ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>) => {
|
||||
const AvatarFallback = ({ className, ...rest }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) => {
|
||||
return (
|
||||
<AvatarPrimitive.Fallback
|
||||
data-slot="avatar-fallback"
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
export const badgeVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
||||
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive overflow-hidden",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@ -26,7 +25,7 @@ const Badge = ({
|
||||
variant,
|
||||
asChild = false,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"span"> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) => {
|
||||
}: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) => {
|
||||
const Comp = asChild ? Slot : "span";
|
||||
|
||||
return <Comp data-slot="badge" className={cn(badgeVariants({ variant }), className)} {...rest} />;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
export const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
@ -37,7 +36,7 @@ const Button = ({
|
||||
size,
|
||||
asChild = false,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<"button"> &
|
||||
}: React.ComponentProps<"button"> &
|
||||
VariantProps<typeof buttonVariants> & {
|
||||
asChild?: boolean;
|
||||
}) => {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Card = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const Card = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return (
|
||||
<div
|
||||
data-slot="card"
|
||||
@ -11,7 +10,7 @@ const Card = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
);
|
||||
};
|
||||
|
||||
const CardHeader = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const CardHeader = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return (
|
||||
<div
|
||||
data-slot="card-header"
|
||||
@ -24,15 +23,15 @@ const CardHeader = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) =>
|
||||
);
|
||||
};
|
||||
|
||||
const CardTitle = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const CardTitle = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return <div data-slot="card-title" className={cn("leading-none font-semibold", className)} {...rest} />;
|
||||
};
|
||||
|
||||
const CardDescription = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const CardDescription = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return <div data-slot="card-description" className={cn("text-muted-foreground text-sm", className)} {...rest} />;
|
||||
};
|
||||
|
||||
const CardAction = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const CardAction = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return (
|
||||
<div
|
||||
data-slot="card-action"
|
||||
@ -42,11 +41,11 @@ const CardAction = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) =>
|
||||
);
|
||||
};
|
||||
|
||||
const CardContent = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const CardContent = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return <div data-slot="card-content" className={cn("px-6", className)} {...rest} />;
|
||||
};
|
||||
|
||||
const CardFooter = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const CardFooter = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return <div data-slot="card-footer" className={cn("flex items-center px-6 [.border-t]:pt-6", className)} {...rest} />;
|
||||
};
|
||||
|
||||
|
@ -3,17 +3,16 @@
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const DropdownMenu = ({ ...rest }: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root>) => {
|
||||
const DropdownMenu = ({ ...rest }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) => {
|
||||
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...rest} />;
|
||||
};
|
||||
|
||||
const DropdownMenuPortal = ({ ...rest }: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Portal>) => {
|
||||
const DropdownMenuPortal = ({ ...rest }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) => {
|
||||
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...rest} />;
|
||||
};
|
||||
|
||||
const DropdownMenuTrigger = ({ ...rest }: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>) => {
|
||||
const DropdownMenuTrigger = ({ ...rest }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) => {
|
||||
return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...rest} />;
|
||||
};
|
||||
|
||||
@ -21,7 +20,7 @@ const DropdownMenuContent = ({
|
||||
className,
|
||||
sideOffset = 4,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>) => {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) => {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
@ -37,7 +36,7 @@ const DropdownMenuContent = ({
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownMenuGroup = ({ ...rest }: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Group>) => {
|
||||
const DropdownMenuGroup = ({ ...rest }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) => {
|
||||
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...rest} />;
|
||||
};
|
||||
|
||||
@ -46,7 +45,7 @@ const DropdownMenuItem = ({
|
||||
inset,
|
||||
variant = "default",
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
||||
inset?: boolean;
|
||||
variant?: "default" | "destructive";
|
||||
}) => {
|
||||
@ -69,7 +68,7 @@ const DropdownMenuCheckboxItem = ({
|
||||
children,
|
||||
checked,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>) => {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) => {
|
||||
return (
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
@ -90,7 +89,7 @@ const DropdownMenuCheckboxItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownMenuRadioGroup = ({ ...rest }: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioGroup>) => {
|
||||
const DropdownMenuRadioGroup = ({ ...rest }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) => {
|
||||
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...rest} />;
|
||||
};
|
||||
|
||||
@ -98,7 +97,7 @@ const DropdownMenuRadioItem = ({
|
||||
className,
|
||||
children,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>) => {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) => {
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
@ -122,7 +121,7 @@ const DropdownMenuLabel = ({
|
||||
className,
|
||||
inset,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
||||
inset?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
@ -138,7 +137,7 @@ const DropdownMenuLabel = ({
|
||||
const DropdownMenuSeparator = ({
|
||||
className,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>) => {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) => {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
data-slot="dropdown-menu-separator"
|
||||
@ -148,7 +147,7 @@ const DropdownMenuSeparator = ({
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownMenuShortcut = ({ className, ...rest }: ComponentPropsWithoutRef<"span">) => {
|
||||
const DropdownMenuShortcut = ({ className, ...rest }: React.ComponentProps<"span">) => {
|
||||
return (
|
||||
<span
|
||||
data-slot="dropdown-menu-shortcut"
|
||||
@ -158,7 +157,7 @@ const DropdownMenuShortcut = ({ className, ...rest }: ComponentPropsWithoutRef<"
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownMenuSub = ({ ...rest }: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Sub>) => {
|
||||
const DropdownMenuSub = ({ ...rest }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) => {
|
||||
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...rest} />;
|
||||
};
|
||||
|
||||
@ -167,7 +166,7 @@ const DropdownMenuSubTrigger = ({
|
||||
inset,
|
||||
children,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||
inset?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
@ -189,7 +188,7 @@ const DropdownMenuSubTrigger = ({
|
||||
const DropdownMenuSubContent = ({
|
||||
className,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>) => {
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) => {
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
data-slot="dropdown-menu-sub-content"
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Input = ({ className, type, ...props }: ComponentPropsWithoutRef<"input">) => {
|
||||
const Input = ({ className, type, ...props }: React.ComponentProps<"input">) => {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Label = ({ className, ...rest }: ComponentPropsWithoutRef<typeof LabelPrimitive.Root>) => {
|
||||
const Label = ({ className, ...rest }: React.ComponentProps<typeof LabelPrimitive.Root>) => {
|
||||
return (
|
||||
<LabelPrimitive.Root
|
||||
data-slot="label"
|
||||
|
@ -2,13 +2,12 @@
|
||||
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Popover = ({ ...rest }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>) => {
|
||||
const Popover = ({ ...rest }: React.ComponentProps<typeof PopoverPrimitive.Root>) => {
|
||||
return <PopoverPrimitive.Root data-slot="popover" {...rest} />;
|
||||
};
|
||||
|
||||
const PopoverTrigger = ({ ...rest }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>) => {
|
||||
const PopoverTrigger = ({ ...rest }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) => {
|
||||
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...rest} />;
|
||||
};
|
||||
|
||||
@ -17,7 +16,7 @@ const PopoverContent = ({
|
||||
align = "center",
|
||||
sideOffset = 4,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>) => {
|
||||
}: React.ComponentProps<typeof PopoverPrimitive.Content>) => {
|
||||
return (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
@ -34,7 +33,7 @@ const PopoverContent = ({
|
||||
);
|
||||
};
|
||||
|
||||
const PopoverAnchor = ({ ...rest }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Anchor>) => {
|
||||
const PopoverAnchor = ({ ...rest }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) => {
|
||||
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...rest} />;
|
||||
};
|
||||
|
||||
|
@ -2,14 +2,13 @@
|
||||
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const ScrollArea = ({ className, children, ...rest }: ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>) => {
|
||||
const ScrollArea = ({ className, children, ...rest }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) => {
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root data-slot="scroll-area" className={cn("relative", className)} {...rest}>
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
data-slot="scroll-area-viewport"
|
||||
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
||||
className="focus-visible:ring-ring/50 size-full rounded-[inherit] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
||||
>
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
@ -23,13 +22,13 @@ const ScrollBar = ({
|
||||
className,
|
||||
orientation = "vertical",
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) => {
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) => {
|
||||
return (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
data-slot="scroll-area-scrollbar"
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"flex touch-none p-px transition-colors select-none",
|
||||
"flex touch-none p-px select-none",
|
||||
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
|
||||
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
|
||||
className
|
||||
|
@ -2,14 +2,13 @@
|
||||
|
||||
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Separator = ({
|
||||
className,
|
||||
orientation = "horizontal",
|
||||
decorative = true,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>) => {
|
||||
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) => {
|
||||
return (
|
||||
<SeparatorPrimitive.Root
|
||||
data-slot="separator-root"
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Skeleton = ({ className, ...rest }: ComponentPropsWithoutRef<"div">) => {
|
||||
const Skeleton = ({ className, ...rest }: React.ComponentProps<"div">) => {
|
||||
return <div data-slot="skeleton" className={cn("bg-accent animate-pulse rounded-md", className)} {...rest} />;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Textarea = ({ className, ...props }: ComponentPropsWithoutRef<"textarea">) => {
|
||||
const Textarea = ({ className, ...props }: React.ComponentProps<"textarea">) => {
|
||||
return (
|
||||
<textarea
|
||||
data-slot="textarea"
|
||||
|
@ -2,16 +2,12 @@
|
||||
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const TooltipProvider = ({
|
||||
delayDuration = 0,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>) => {
|
||||
const TooltipProvider = ({ delayDuration = 0, ...rest }: React.ComponentProps<typeof TooltipPrimitive.Provider>) => {
|
||||
return <TooltipPrimitive.Provider data-slot="tooltip-provider" delayDuration={delayDuration} {...rest} />;
|
||||
};
|
||||
|
||||
const Tooltip = ({ ...rest }: ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>) => {
|
||||
const Tooltip = ({ ...rest }: React.ComponentProps<typeof TooltipPrimitive.Root>) => {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<TooltipPrimitive.Root data-slot="tooltip" {...rest} />
|
||||
@ -19,7 +15,7 @@ const Tooltip = ({ ...rest }: ComponentPropsWithoutRef<typeof TooltipPrimitive.R
|
||||
);
|
||||
};
|
||||
|
||||
const TooltipTrigger = ({ ...rest }: ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>) => {
|
||||
const TooltipTrigger = ({ ...rest }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) => {
|
||||
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...rest} />;
|
||||
};
|
||||
|
||||
@ -28,7 +24,7 @@ const TooltipContent = ({
|
||||
sideOffset = 0,
|
||||
children,
|
||||
...rest
|
||||
}: ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>) => {
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Content>) => {
|
||||
return (
|
||||
<TooltipPrimitive.Portal>
|
||||
<TooltipPrimitive.Content
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Video = ({
|
||||
src,
|
||||
@ -7,7 +6,7 @@ const Video = ({
|
||||
className,
|
||||
children,
|
||||
...rest
|
||||
}: Omit<Partial<ComponentPropsWithoutRef<"video">>, "src"> & {
|
||||
}: Omit<Partial<React.ComponentProps<"video">>, "src"> & {
|
||||
src: string | string[] | undefined;
|
||||
}) => {
|
||||
return (
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { env } from "@/lib/env";
|
||||
import { Feed } from "feed";
|
||||
import { Feed, type Item as FeedItem } from "feed";
|
||||
import { getFrontMatter, getContent } from "@/lib/posts";
|
||||
import siteConfig from "@/lib/config/site";
|
||||
import authorConfig from "@/lib/config/author";
|
||||
import type { Item as FeedItem } from "feed";
|
||||
|
||||
import ogImage from "@/app/opengraph-image.jpg";
|
||||
|
||||
|
@ -1,30 +0,0 @@
|
||||
import { HomeIcon, PencilLineIcon, CodeXmlIcon, MailIcon, type LucideIcon } from "lucide-react";
|
||||
|
||||
export type MenuItemConfig = {
|
||||
text?: string;
|
||||
href?: `/${string}`;
|
||||
icon?: LucideIcon;
|
||||
};
|
||||
|
||||
export const menuItems: MenuItemConfig[] = [
|
||||
{
|
||||
text: "Home",
|
||||
href: "/",
|
||||
icon: HomeIcon,
|
||||
},
|
||||
{
|
||||
text: "Notes",
|
||||
href: "/notes",
|
||||
icon: PencilLineIcon,
|
||||
},
|
||||
{
|
||||
text: "Projects",
|
||||
href: "/projects",
|
||||
icon: CodeXmlIcon,
|
||||
},
|
||||
{
|
||||
text: "Contact",
|
||||
href: "/contact",
|
||||
icon: MailIcon,
|
||||
},
|
||||
];
|
@ -1,7 +1,6 @@
|
||||
import { env } from "@/lib/env";
|
||||
import siteConfig from "@/lib/config/site";
|
||||
import authorConfig from "@/lib/config/author";
|
||||
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const defaultMetadata: Metadata = {
|
||||
|
@ -8,9 +8,7 @@ import Tweet from "@/components/third-party/tweet";
|
||||
import YouTube from "@/components/third-party/youtube";
|
||||
import Gist from "@/components/third-party/gist";
|
||||
import CodePen from "@/components/third-party/codepen";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import type { MDXComponents } from "mdx/types";
|
||||
|
||||
export const useMDXComponents = (components: MDXComponents): MDXComponents => {
|
||||
|
@ -37,9 +37,9 @@ After converting a few more components, I started to feel better and better each
|
||||
|
||||
Don't get me wrong, I still think the syntax Tailwind forces you to write is an abomination. **But honestly, so was my CSS.**
|
||||
|
||||
Maybe that's on me, or maybe not, but my primary reason to hate on Tailwind for years — _"it makes my HTML/JSX ugly and design doesn't belong sprinkled throughout a markup language"_ — just flew out the window either way. Sure, I tried to make my CSS consistent and logical, making tons of variables for colors and sizes and border radii. But that wasn't nearly as comforting as being certain that `w-12` will **always** be twice the width of `w-6` no matter how badly I mess things up.
|
||||
Maybe that's on me, or maybe not, but my primary reason to hate on Tailwind for years — _"it makes my HTML/JSX ugly and design doesn't belong sprinkled throughout a markup language"_ — just flew out the window either way. Sure, I tried to make my CSS consistent and logical, making tons of variables for colors and sizes and border radii. But that wasn't nearly as comforting as being certain that `w–12` will **always** be twice the width of `w–6` no matter how badly I mess things up.
|
||||
|
||||
And on top of all of the AI tools mentioned above being Tailwind experts, the [IDE support](https://tailwindcss.com/docs/editor-setup) is also excellent. One click to install the official [IntelliSense extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) for VS Code, and suddenly everywhere I wrote <span style={{ color: "#38bdf8" }}>`text-sky-400`</span> throughout my code had a lovely little light blue square next to it. The official [Prettier extension](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) ensures the order of class names doesn't cause unexpected specificity problems from a rule four layers up overriding a rule you thought you were currently looking at — historically my biggest painpoint of CSS by far.
|
||||
And on top of all of the AI tools mentioned above being Tailwind experts, the [IDE support](https://tailwindcss.com/docs/editor-setup) is also excellent. One click to install the official [IntelliSense extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) for VS Code, and suddenly everywhere I wrote <span style={{ color: "#00bcff" }}>`text–sky–400`</span> throughout my code had a lovely little light blue square next to it. The official [Prettier extension](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) ensures the order of class names doesn't cause unexpected specificity problems from a rule four layers up overriding a rule you thought you were currently looking at — historically my biggest painpoint of CSS by far.
|
||||
|
||||
All of these tools together actually made the [process](https://github.com/jakejarvis/jarv.is/pull/2387) of revamping this site oddly fun. It shined a spotlight on a lot of issues I had no idea were there — especially by forcing me to think ["mobile-first"](https://tailwindcss.com/docs/responsive-design#working-mobile-first) — and gave me an opportunity to put a new coat of paint on a design I haven't made major changes to [since my last blog post](/notes/hugo-to-nextjs)...three years ago.
|
||||
|
||||
|
Reference in New Issue
Block a user