Skip to main content

Post

Location: src/components/Post.jsx

Overview

Post is the primary content display component for CommonPlace. It renders a single post card with intent-based visual styling, author information, content (text, images, drawings, magnetic poetry, voice, external clips), and interaction actions (save, share, respond, report). When a post is a share (is_share === true), it renders a SharedPostCard for the referenced content.

Intent styling applies CSS custom properties and classes derived from the author per-intent style preferences (surface, frame, font, emphasis, effects), giving each post a unique visual identity controlled by its creator rather than by algorithmic ranking.

Relevant Invariants

  • Invariant #4: "Intent Precedes Interpretation" -- Posts display their intent badge and styling, never ranked or scored.
  • Invariant #6: "No Public Comparative Metrics" -- No like counts, view counts, or ranking indicators.
  • Invariant #10: "Expressive Freedom Is Spatially Contained" -- Style customization is authored by the poster, contained to the post card.

Props

PropTypeRequiredDefaultDescription
postobjectYes--Post data including id, content, intent, user_id, profiles, post_images, etc.
sessionobjectYes--Supabase auth session
onUpdatefunctionNo--Callback after post update (edit/delete)
isSavedbooleanNofalseInitial saved state
onToggleSavefunctionNo--Callback when save state changes
savedDataobjectNo--Existing saved_posts record (note, shelf)
userShelvesarrayNo--User shelf list for save popover
onShelvesChangefunctionNo--Callback when shelves are modified
authorIntentStylesobjectNo--Intent-to-style map for this post's author (pre-scoped by Feed via authorIntentStyles[post.user_id])
hideSaveButtonbooleanNofalseHides the save action (used on SavedPage)
onShareToCirclefunctionNo--Callback to open share-to-circle modal

Key Behaviors

  • Intent Styling: Resolves DEFAULT_INTENT_STYLE merged with authorIntentStyles[post.intent] to compute surface, frame, font, emphasis, and effects CSS classes. The parent (Feed/SavedPage) passes the already-scoped per-author map, so Post accesses by intent key directly.
  • Editor Types: Renders different content views based on post.editor_type: simple (default text), longform (rich HTML), drawing (canvas image), magnetic_poetry (tile display).
  • Save Popover: Portal-based popover for shelf selection, note adding, and inline shelf creation.
  • Lightbox: Full-screen image viewing for post images.
  • Share Posts: When post.is_share is true, renders a SharedPostCard referencing the original.
  • Build-On: Supports build-on replies via useBuildOn hook.
  • Content Notes: Renders ContentNoteDisplay if the post has a content_note.
  • Voice: Renders VoicePlayer if post.voice_url is present.

Sub-components

ComponentLocationPurpose
PostHeadersrc/components/post-parts/PostHeader.jsxAuthor name, timestamp, intent label
PostContentsrc/components/post-parts/PostContent.jsxText/HTML content display
PostImagessrc/components/post-parts/PostImages.jsxImage grid with lightbox trigger
PostActionssrc/components/post-parts/PostActions.jsxRespond, save, share, report buttons
IntentBadgesrc/components/post-parts/IntentBadge.jsxCorner avatar + intent emoji badge
SavePopoversrc/components/post-parts/SavePopover.jsxSave-to-shelf popover
Lightboxsrc/components/post-parts/Lightbox.jsxFull-screen image viewer

Usage

import Post from '@/components/Post';

<Post
post={postData}
session={session}
onUpdate={refreshFeed}
authorIntentStyles={stylesMap}
/>

Last updated: 2026-02-07