nyuchimzizi
Mzizi — an open-architecture project of the Bundu Foundation, operated and developed by Nyuchi. Built on the Five African Minerals palette.
Built by Nyuchi Africav4.0.39
Universal freeform content creation component — the branded way to compose posts, updates, stories, and messages across the ecosystem. Combines text input, media attachment, mention tagging, and mineral-accented submit button. Used in Circles (posts), Pulse (updates), Campfire (messages), Novels (chapter drafts), and anywhere users create unstructured content. Distinct from nyuchi-create-listing which handles structured form-based creation.
View the full component source code below.
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { useNyuchiHarness } from "@/lib/harness"
/* ═══════════════════════════════════════════════════════════════
NYUCHI CONTENT COMPOSER — Universal Brand Component (Pre-Wired)
Freeform content creation for the ecosystem. The branded way
to write posts, status updates, comments, and stories.
Structured data creation uses nyuchi-create-listing instead.
Dynamic mineral accent via --brand-accent.
✅ HARNESS ✅ TOKENS ✅ STRICT MINERAL RULES ✅ TOUCH 48px+
═══════════════════════════════════════════════════════════════ */
interface NyuchiContentComposerProps {
/** Placeholder text */
placeholder?: string
/** Current user avatar URL */
avatarUrl?: string
/** Current user name */
userName?: string
/** Submit button label */
submitLabel?: string
/** Submit handler — receives the text content */
onSubmit?: (content: string) => void
/** Media attachment handler */
onAttachMedia?: () => void
/** Mention handler */
onMention?: () => void
/** Whether submission is in progress */
submitting?: boolean
/** Show media/mention toolbar */
showToolbar?: boolean
/** Compact inline mode (for comment replies) */
compact?: boolean
className?: string
}
export function NyuchiContentComposer({
placeholder = "What\u2019s on your mind?",
avatarUrl,
userName,
submitLabel = "Post",
onSubmit,
onAttachMedia,
onMention,
submitting = false,
showToolbar = true,
compact = false,
className,
}: NyuchiContentComposerProps) {
const { log, motion, LiveRegion } = useNyuchiHarness("content-composer")
const animStyle = React.useMemo(() => motion.prefersReduced ? {} : { animation: `nyuchi-fade-slide-up ${motion.enterDuration}ms ${motion.enterEasing} both` }, [motion])
const [text, setText] = React.useState("")
const handleSubmit = () => {
if (!text.trim() || submitting) return
onSubmit?.(text.trim())
setText("")
}
return (
<div
data-slot="nyuchi-content-composer" data-portal="https://design.nyuchi.com/components/nyuchi-content-composer"
className={cn(
"bg-card rounded-[var(--radius-lg,14px)] border border-border",
compact ? "p-3" : "p-4",
className
)}
>
<div className="flex gap-3">
{!compact && (
<div className="size-9 shrink-0 rounded-full bg-muted flex items-center justify-center text-xs font-bold text-muted-foreground overflow-hidden">
{avatarUrl
? <img src={avatarUrl} alt={userName || ""} className="size-full object-cover" />
: (userName?.charAt(0)?.toUpperCase() || "?")}
</div>
)}
<div className="flex-1 min-w-0 space-y-3">
<textarea aria-label="Compose content"
value={text}
onChange={e => setText(e.target.value)}
placeholder={placeholder}
rows={compact ? 1 : 3}
className={cn(
"w-full resize-none bg-transparent text-foreground placeholder:text-muted-foreground outline-none",
compact ? "text-sm" : "text-sm leading-relaxed"
)}
/>
<div className="flex items-center justify-between">
{showToolbar && (
<div className="flex items-center gap-1">
{onAttachMedia && (
<button onClick={onAttachMedia} className="flex size-9 items-center justify-center rounded-full text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary,#00B0FF)] min-h-[48px] hover:bg-muted hover:text-foreground transition-colors" aria-label="Attach media">
📷
</button>
)}
{onMention && (
<button onClick={onMention} className="flex size-9 items-center justify-center rounded-full text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary,#00B0FF)] min-h-[48px] hover:bg-muted hover:text-foreground transition-colors" aria-label="Mention someone">
@
</button>
)}
</div>
)}
<button
onClick={handleSubmit}
disabled={!text.trim() || submitting}
className={cn(
"h-10 rounded-full px-5 text-[13px] font-medium transition-opacity",
text.trim() && !submitting
? "bg-[var(--brand-accent,var(--color-malachite,#64FFDA))] text-[#0A0A0A] hover:opacity-80"
: "bg-muted text-muted-foreground cursor-not-allowed"
)}
>
{submitting ? "Posting\u2026" : submitLabel}
</button>
</div>
</div>
</div>
</div>
)
}
npx shadcn@latest add https://mzizi.dev/api/v1/ui/nyuchi-content-composerFetch this component's metadata and source code from the registry API.
/api/v1/ui/nyuchi-content-composer