fix: SSR-safe portals, deduplicate image validation, z-index custom properties, and misc hardening #206
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Addresses leftover PR feedback from the CitationDrawer redesign (#196). This PR hardens the component layer with SSR safety, deduplication, customizability, and code quality improvements across 7 files.
Changes
SSR-safe portal rendering: Added
getPortalContainer()utility that returnsdocument.bodyornullduring SSR. All threecreatePortalcall sites (CitationDrawer,CitationComponentImageOverlay,SourcesListComponent) now guard against missingdocument.bodyinstead of crashing during server-side rendering.Deduplicated image validation: Extracted
isValidProofImageSrc(),SAFE_DATA_IMAGE_PREFIXES, andTRUSTED_IMAGE_HOSTSfromCitationDrawer.tsxintoconstants.ts. Replaced the ~20-line inline duplicate inCitationDrawerTrigger.tsxwith a single function call. Both components now share the same validation logic from one canonical location.Z-index CSS custom properties: Replaced hardcoded Tailwind
z-[9998]/z-[9999]classes with CSS custom properties (--dc-z-popover,--dc-z-drawer-backdrop,--dc-z-drawer,--dc-z-image-overlay). Consumers can now override stacking order via CSS without forking components. Added a layering hierarchy table inconstants.tsdocumenting the z-index architecture.Dev-mode deprecation warnings: Added a module-level
Set-based "warn once" pattern toCitationComponentso deprecated prop warnings (interactionMode,eventHandlers.onClick+behaviorConfig.onClickconflict) only fire once per prop instead of on every render.Tooltip max-height constraint: Added
max-h-[50vh] overflow-y-autotoSourceTooltipinCitationDrawerTriggerto prevent unbounded growth with long source names or many citations.Magic numbers extracted: Moved
SPINNER_TIMEOUT_MSandHOVER_CLOSE_DELAY_MSto module-level named constants inCitationComponent.tsx. AddedICON_EXPANDED_MARGIN_PXandICON_COLLAPSED_MARGIN_PXinCitationDrawerTrigger.tsxreplacing inline6/-8values.requestAnimationFrame for focus timing:
ImageOverlayauto-focus now usesrequestAnimationFramewith proper cleanup viacancelAnimationFrame, ensuring the portal has been painted before focusing.Test plan
npx bun test src/__tests__/)npm run build)nullinstead of crashing whendocumentis undefined--dc-z-drawer: 50000in CSS should raise the drawer above other overlays