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 branded bottom action sheet for contextual actions on any content across the ecosystem. Share, save, report, copy link, block, follow — the standard set of actions available on listings, posts, profiles, and messages. Renders as a bottom sheet on mobile with mineral accent on destructive/primary actions. Composes sheet and share-dialog primitives.
No interactive demo is registered for this component yet — the source is shown directly.
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { useNyuchiHarness } from "@/lib/harness"
/* ═══════════════════════════════════════════════════════════════
NYUCHI ACTION SHEET — Universal Brand Component (Pre-Wired)
Contextual action sheet for any content in the ecosystem.
Renders as a bottom sheet on mobile, dropdown on desktop.
Dynamic mineral accent via --brand-accent.
✅ HARNESS ✅ TOKENS ✅ STRICT MINERAL RULES ✅ TOUCH 48px+
═══════════════════════════════════════════════════════════════ */
interface ActionItem {
/** Action identifier */
id: string
/** Display label */
label: string
/** Icon (emoji or component) */
icon?: React.ReactNode
/** Destructive actions show in red */
destructive?: boolean
/** Handler */
onSelect: () => void
}
interface NyuchiActionSheetProps {
/** Whether the sheet is open */
open: boolean
/** Close handler */
onClose: () => void
/** Title shown at the top */
title?: string
/** Action items */
actions: ActionItem[]
className?: string
}
export function NyuchiActionSheet({
open,
onClose,
title,
actions,
className,
}: NyuchiActionSheetProps) {
const { log, motion, LiveRegion } = useNyuchiHarness("action-sheet")
const animStyle = React.useMemo(() => motion.prefersReduced ? {} : { animation: `nyuchi-fade-slide-up ${motion.enterDuration}ms ${motion.enterEasing} both` }, [motion])
if (!open) return null
return (
<>
{/* Scrim */}
<div
className="fixed inset-0 z-50 bg-[var(--scrim,rgba(0,0,0,0.6))]"
onClick={onClose}
/>
{/* Sheet */}
<div
data-slot="nyuchi-action-sheet" data-portal="https://design.nyuchi.com/components/nyuchi-action-sheet" role="dialog" aria-label="Actions" aria-modal="true"
className={cn(
"fixed inset-x-0 bottom-0 z-50 rounded-t-[var(--radius-xl,17px)] bg-[var(--overlay,var(--card))] border-t border-border",
"pb-[env(safe-area-inset-bottom)] animate-in slide-in-from-bottom",
className
)}
>
{/* Handle bar */}
<div className="flex justify-center py-3">
<div className="h-1 w-10 rounded-full bg-muted-foreground/20" />
</div>
{title && (
<p className="px-5 pb-2 text-xs font-semibold text-muted-foreground uppercase tracking-wider">{title}</p>
)}
<div className="px-2 pb-2">
{actions.map((action) => (
<button
key={action.id}
onClick={() => { action.onSelect(); onClose() }}
className={cn(
"flex w-full items-center gap-3 rounded-[var(--radius-md,12px)] px-4 py-3.5 text-sm font-medium transition-colors",
"hover:bg-muted min-h-[48px]",
action.destructive ? "text-red-400" : "text-foreground"
)}
>
{action.icon && <span className="text-base">{action.icon}</span>}
{action.label}
</button>
))}
</div>
{/* Cancel button — always present */}
<div className="px-2 pb-3">
<button
onClick={onClose}
className="flex h-12 w-full items-center justify-center rounded-[var(--radius-md,12px)] bg-muted text-sm font-medium text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary,#00B0FF)] transition-colors hover:bg-muted/80"
>
Cancel
</button>
</div>
</div>
</>
)
}
The variants, sizes, and props surfaced by the registry. Each is sourced from the Supabase component_docs table.
Hit the registry API live and see the JSON the shadcn CLI consumes when it installs this component.
/api/v1/ui/nyuchi-action-sheetnpx shadcn@latest add https://mzizi.dev/api/v1/ui/nyuchi-action-sheet