mirror of
https://github.com/hanzoai/sign.git
synced 2026-10-21 01:21:51 +00:00
The suppression count for this work is `git grep -c` over '@ts-ignore', '@ts-expect-error', 'as any', 'as unknown as', ': any' and eslint-disable. Three comments added in it matched as prose: a quoted index signature in the v1 contract, "over: any string" in the upload test and "has any meta" in the field tooltip. They say the same thing in words that do not match, so the counts read 10 `as any` and 8 `: any`, as before this work. Co-authored-by: Hanzo Dev <[email protected]>
84 lines
2.2 KiB
TypeScript
84 lines
2.2 KiB
TypeScript
import type { Field } from '@prisma/client';
|
|
import { TooltipArrow } from '@radix-ui/react-tooltip';
|
|
import type { VariantProps } from 'class-variance-authority';
|
|
import { cva } from 'class-variance-authority';
|
|
import { createPortal } from 'react-dom';
|
|
|
|
import { useFieldPageCoords } from '@hanzo/esign-lib/client-only/hooks/use-field-page-coords';
|
|
|
|
import { cn } from '../..//lib/utils';
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipProvider,
|
|
TooltipTrigger,
|
|
} from '../..//primitives/tooltip';
|
|
|
|
const tooltipVariants = cva('font-semibold', {
|
|
variants: {
|
|
color: {
|
|
default: 'border-2 fill-white',
|
|
warning: 'border-0 bg-foreground fill-foreground text-background',
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
color: 'default',
|
|
},
|
|
});
|
|
|
|
interface FieldToolTipProps extends VariantProps<typeof tooltipVariants> {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
// Only whether the field carries meta decides the tooltip, so the meta may be unparsed.
|
|
field: Pick<
|
|
Field,
|
|
'id' | 'inserted' | 'positionX' | 'positionY' | 'width' | 'height' | 'page'
|
|
> & {
|
|
fieldMeta: unknown;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Renders a tooltip for a given field.
|
|
*/
|
|
export function FieldToolTip({ children, color, className = '', field }: FieldToolTipProps) {
|
|
const coords = useFieldPageCoords(field);
|
|
|
|
const onTooltipContentClick = () => {
|
|
const $fieldEl = document.querySelector<HTMLButtonElement>(`#field-${field.id} > button`);
|
|
|
|
if ($fieldEl) {
|
|
$fieldEl.click();
|
|
}
|
|
};
|
|
|
|
return createPortal(
|
|
<div
|
|
id="field-tooltip"
|
|
className={cn('pointer-events-none absolute')}
|
|
style={{
|
|
top: `${coords.y}px`,
|
|
left: `${coords.x}px`,
|
|
height: `${coords.height}px`,
|
|
width: `${coords.width}px`,
|
|
}}
|
|
>
|
|
<TooltipProvider>
|
|
<Tooltip delayDuration={0} open={!field.inserted || !field.fieldMeta}>
|
|
<TooltipTrigger className="absolute inset-0 w-full"></TooltipTrigger>
|
|
|
|
<TooltipContent
|
|
className={tooltipVariants({ color, className })}
|
|
sideOffset={2}
|
|
onClick={onTooltipContentClick}
|
|
>
|
|
{children}
|
|
<TooltipArrow />
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
</div>,
|
|
document.body,
|
|
);
|
|
}
|