Skip to main content

PostContent

Location: src/components/post-parts/PostContent.jsx

Overview

PostContent renders the text body of a post card. It handles content truncation for long posts and provides a "Quote this" popup on desktop when the user selects text (minimum 10 characters). This enables the "Build On" feature where users can reference specific passages from a post.

Truncation is based on non-whitespace character count rather than total length, ensuring fair treatment of posts with varied formatting.

Props

PropTypeRequiredDefaultDescription
contentstringYes--The post's text content
onQuotefunctionNo--Callback receiving selected text when user clicks "Quote this"

Constants

ConstantValueDescription
MAX_NON_SPACE_CHARS500Maximum non-whitespace characters before truncation
MIN_SELECTION_LENGTH10Minimum selected characters to show the quote popup

Key Behaviors

  • Smart Truncation: Counts only non-space characters (excluding spaces, newlines, tabs). When the limit is exceeded, content is cut at the 500th non-space character with a "..." indicator and a chevron arrow.
  • Text Selection Quote (Desktop Only): When the user selects 10+ characters within the content area, a floating "Quote this" popup appears at the selection position. Clicking it calls onQuote with the selected text.
  • Mobile Disabled: The quote popup is disabled on mobile via the useIsMobile hook, deferring to native text selection behavior.
  • Popup Positioning: The popup is positioned using fixed positioning based on the selection's bounding rect, centered horizontally.
  • Cleanup: The popup is dismissed when clicking outside it or making a new selection shorter than the minimum.

Usage

import PostContent from '@/components/post-parts/PostContent';

<PostContent
content={post.content}
onQuote={(selectedText) => handleQuote(selectedText)}
/>
  • Post -- Parent component that renders PostContent
  • PostDetail -- Full post view (renders content directly, not via this component)

Last updated: 2026-02-07