109 lines
2.3 KiB
TypeScript
109 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import type { ReactNode } from "react";
|
|
import { CircleHelp } from "lucide-react";
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
import { Label } from "@/components/ui/label";
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipTrigger,
|
|
} from "@/components/ui/tooltip";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type AdminFieldLabelProps = {
|
|
htmlFor: string;
|
|
children: ReactNode;
|
|
helpText?: string;
|
|
helpAriaLabel?: string;
|
|
className?: string;
|
|
};
|
|
|
|
type AdminHelpIconProps = {
|
|
helpText: string;
|
|
helpAriaLabel: string;
|
|
helpId: string;
|
|
};
|
|
|
|
type AdminHelpTextProps = AdminHelpIconProps & {
|
|
children: ReactNode;
|
|
className?: string;
|
|
};
|
|
|
|
export function AdminHelpIcon({
|
|
helpText,
|
|
helpAriaLabel,
|
|
helpId,
|
|
}: AdminHelpIconProps): React.ReactElement {
|
|
return (
|
|
<Tooltip>
|
|
<TooltipTrigger
|
|
render={
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="icon-xs"
|
|
className="text-muted-foreground"
|
|
aria-label={helpAriaLabel}
|
|
data-field-help={helpId}
|
|
/>
|
|
}
|
|
>
|
|
<CircleHelp aria-hidden="true" />
|
|
</TooltipTrigger>
|
|
<TooltipContent
|
|
side="top"
|
|
align="start"
|
|
className="max-w-80 whitespace-normal text-left leading-relaxed"
|
|
>
|
|
<p>{helpText}</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
);
|
|
}
|
|
|
|
export function AdminHelpText({
|
|
children,
|
|
helpText,
|
|
helpAriaLabel,
|
|
helpId,
|
|
className,
|
|
}: AdminHelpTextProps): React.ReactElement {
|
|
return (
|
|
<span className={cn("inline-flex items-center gap-1", className)}>
|
|
<span>{children}</span>
|
|
<AdminHelpIcon helpText={helpText} helpAriaLabel={helpAriaLabel} helpId={helpId} />
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export function AdminFieldLabel({
|
|
htmlFor,
|
|
children,
|
|
helpText,
|
|
helpAriaLabel,
|
|
className,
|
|
}: AdminFieldLabelProps): React.ReactElement {
|
|
if (!helpText) {
|
|
return (
|
|
<Label htmlFor={htmlFor} className={className}>
|
|
{children}
|
|
</Label>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center gap-1">
|
|
<Label htmlFor={htmlFor} className={className}>
|
|
{children}
|
|
</Label>
|
|
<AdminHelpIcon
|
|
helpText={helpText}
|
|
helpAriaLabel={helpAriaLabel ?? String(children)}
|
|
helpId={htmlFor}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|