import React, { useEffect, useMemo, useState } from 'react'; import { type Field, FieldType } from '@prisma/client'; import { createPortal } from 'react-dom'; import { useElementBounds } from '@documenso/lib/client-only/hooks/use-element-bounds'; import { useFieldPageCoords } from '@documenso/lib/client-only/hooks/use-field-page-coords'; import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer'; import { isFieldUnsignedAndRequired } from '@documenso/lib/utils/advanced-fields-helpers'; import type { RecipientColorStyles } from '../../lib/recipient-colors'; import { cn } from '../../lib/utils'; export type FieldContainerPortalProps = { field: Field; className?: string; children: React.ReactNode; }; export function FieldContainerPortal({ field, children, className = '', }: FieldContainerPortalProps) { const alternativePortalRoot = document.getElementById('document-field-portal-root'); const coords = useFieldPageCoords(field); const $pageBounds = useElementBounds( `${PDF_VIEWER_PAGE_SELECTOR}[data-page-number="${field.page}"]`, ); const maxWidth = $pageBounds?.width ? $pageBounds.width - coords.x : undefined; const isCheckboxOrRadioField = field.type === 'CHECKBOX' || field.type === 'RADIO'; const style = useMemo(() => { const portalBounds = alternativePortalRoot?.getBoundingClientRect(); const bounds = { top: `${coords.y}px`, left: `${coords.x}px`, ...(!isCheckboxOrRadioField ? { height: `${coords.height}px`, width: `${coords.width}px`, } : { maxWidth: `${maxWidth}px`, }), }; if (portalBounds) { bounds.top = `${coords.y - portalBounds.top}px`; bounds.left = `${coords.x - portalBounds.left}px`; } return bounds; }, [coords, maxWidth, isCheckboxOrRadioField]); return createPortal(