82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState, type ReactNode } from "react";
|
|
import { IconInfoCircle } from "@tabler/icons-react";
|
|
import { Button } from "@kandev/ui/button";
|
|
import {
|
|
Drawer,
|
|
DrawerContent,
|
|
DrawerDescription,
|
|
DrawerHeader,
|
|
DrawerTitle,
|
|
DrawerTrigger,
|
|
} from "@kandev/ui/drawer";
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip";
|
|
import { useTouchDrawer } from "@/hooks/use-compact-task-chrome";
|
|
import { controlSizingClassName } from "@kandev/ui/control-sizing";
|
|
|
|
export function GitHubAccessHelp({
|
|
label,
|
|
title,
|
|
description,
|
|
content,
|
|
icon,
|
|
onOpen,
|
|
}: {
|
|
label: string;
|
|
title: string;
|
|
description: string;
|
|
content?: ReactNode;
|
|
icon?: ReactNode;
|
|
onOpen?: () => void;
|
|
}) {
|
|
const usesTouchDrawer = useTouchDrawer();
|
|
const [open, setOpen] = useState(false);
|
|
const handleDrawerOpenChange = (nextOpen: boolean) => {
|
|
setOpen(nextOpen);
|
|
if (nextOpen) onOpen?.();
|
|
};
|
|
const button = (
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="icon"
|
|
className={controlSizingClassName("icon", "shrink-0 cursor-pointer text-muted-foreground")}
|
|
aria-haspopup={usesTouchDrawer ? "dialog" : undefined}
|
|
aria-expanded={usesTouchDrawer ? open : undefined}
|
|
aria-label={label}
|
|
>
|
|
{icon ?? <IconInfoCircle className="h-4 w-4" />}
|
|
</Button>
|
|
);
|
|
const trigger = usesTouchDrawer ? (
|
|
<DrawerTrigger asChild>{button}</DrawerTrigger>
|
|
) : (
|
|
<Tooltip onOpenChange={(nextOpen) => nextOpen && onOpen?.()}>
|
|
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
<TooltipContent side="top" align="start" className="max-w-[320px] text-xs leading-relaxed">
|
|
{content ?? description}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
);
|
|
|
|
return (
|
|
<Drawer open={open} onOpenChange={handleDrawerOpenChange}>
|
|
{trigger}
|
|
<DrawerContent>
|
|
<DrawerHeader>
|
|
<DrawerTitle>{title}</DrawerTitle>
|
|
<DrawerDescription className={content ? "sr-only" : undefined}>
|
|
{description}
|
|
</DrawerDescription>
|
|
</DrawerHeader>
|
|
{content && (
|
|
<div className="max-h-[min(60dvh,32rem)] overflow-y-auto overscroll-contain px-4 pb-[calc(1rem+env(safe-area-inset-bottom))]">
|
|
{content}
|
|
</div>
|
|
)}
|
|
</DrawerContent>
|
|
</Drawer>
|
|
);
|
|
}
|