"use client"; import { useState } from "react"; import RuleCard from "../components/RuleCard"; import Chip from "../components/Chip"; import MultiSelect from "../components/MultiSelect"; import Image from "next/image"; import { getAssetPath } from "../../lib/assetUtils"; interface ChipData { id: string; label: string; state: "Unselected" | "Selected" | "Custom"; palette: "Default" | "Inverse"; size: "S" | "M"; } // MultiSelect example component with state management function MultiSelectExample({ size }: { size: "S" | "M" }) { const [options, setOptions] = useState>([ { id: "1", label: "1 member", state: "Unselected" }, { id: "2", label: "2-10 members", state: "Unselected" }, { id: "3", label: "10-24 members", state: "Unselected" }, { id: "4", label: "24-64 members", state: "Unselected" }, { id: "5", label: "64-128 members", state: "Unselected" }, { id: "6", label: "125-1000 members", state: "Unselected" }, { id: "7", label: "1000+ members", state: "Unselected" }, ]); const handleChipClick = (chipId: string) => { setOptions((prev) => prev.map((opt) => opt.id === chipId ? { ...opt, state: opt.state === "Selected" ? "Unselected" : "Selected", } : opt ) ); }; const handleAddClick = () => { const newId = `custom-${Date.now()}`; setOptions((prev) => [ ...prev, { id: newId, label: "", state: "Custom" }, ]); }; const handleCustomConfirm = (chipId: string, value: string) => { setOptions((prev) => prev.map((opt) => opt.id === chipId ? { ...opt, label: value, state: "Selected" as const } : opt ) ); }; const handleCustomClose = (chipId: string) => { setOptions((prev) => prev.filter((opt) => opt.id !== chipId)); }; return (

{size === "S" ? "Small (S)" : "Medium (M)"}

); } export default function ComponentsPreview() { const [chipStates, setChipStates] = useState>({ "default-s": "Unselected", "default-m": "Unselected", "inverse-s": "Unselected", "inverse-m": "Unselected", }); // Manage custom chips separately const [customChips, setCustomChips] = useState([ { id: "custom-1", label: "", state: "Custom", palette: "Default", size: "S" }, { id: "custom-2", label: "", state: "Custom", palette: "Default", size: "M" }, ]); // RuleCard categories with chip options and state management const [ruleCardCategories, setRuleCardCategories] = useState; onChipClick?: (categoryName: string, chipId: string) => void; onAddClick?: (categoryName: string) => void; onCustomChipConfirm?: (categoryName: string, chipId: string, value: string) => void; onCustomChipClose?: (categoryName: string, chipId: string) => void; }>>([ { name: "Values", chipOptions: [ { id: "values-1", label: "Consciousness", state: "Unselected" }, { id: "values-2", label: "Ecology", state: "Unselected" }, { id: "values-3", label: "Abundance", state: "Unselected" }, { id: "values-4", label: "Art", state: "Unselected" }, { id: "values-5", label: "Decisiveness", state: "Unselected" }, ], onChipClick: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, state: opt.state === "Selected" ? "Unselected" : "Selected", } : opt ), } : cat ) ); }, onAddClick: (categoryName: string) => { const newId = `custom-${categoryName}-${Date.now()}`; setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: [ ...cat.chipOptions, { id: newId, label: "", state: "Custom" }, ], } : cat ) ); }, onCustomChipConfirm: (categoryName: string, chipId: string, value: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, label: value, state: "Selected" } : opt ), } : cat ) ); }, onCustomChipClose: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.filter((opt) => opt.id !== chipId), } : cat ) ); }, }, { name: "Communication", chipOptions: [ { id: "comm-1", label: "Signal", state: "Unselected" }, ], onChipClick: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, state: opt.state === "Selected" ? "Unselected" : "Selected", } : opt ), } : cat ) ); }, onAddClick: (categoryName: string) => { const newId = `custom-${categoryName}-${Date.now()}`; setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: [ ...cat.chipOptions, { id: newId, label: "", state: "Custom" }, ], } : cat ) ); }, onCustomChipConfirm: (categoryName: string, chipId: string, value: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, label: value, state: "Selected" } : opt ), } : cat ) ); }, onCustomChipClose: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.filter((opt) => opt.id !== chipId), } : cat ) ); }, }, { name: "Membership", chipOptions: [ { id: "membership-1", label: "Open Admission", state: "Unselected" }, ], onChipClick: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, state: opt.state === "Selected" ? "Unselected" : "Selected", } : opt ), } : cat ) ); }, onAddClick: (categoryName: string) => { const newId = `custom-${categoryName}-${Date.now()}`; setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: [ ...cat.chipOptions, { id: newId, label: "", state: "Custom" }, ], } : cat ) ); }, onCustomChipConfirm: (categoryName: string, chipId: string, value: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, label: value, state: "Selected" } : opt ), } : cat ) ); }, onCustomChipClose: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.filter((opt) => opt.id !== chipId), } : cat ) ); }, }, { name: "Decision-making", chipOptions: [ { id: "decision-1", label: "Lazy Consensus", state: "Unselected" }, { id: "decision-2", label: "Modified Consensus", state: "Unselected" }, ], onChipClick: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, state: opt.state === "Selected" ? "Unselected" : "Selected", } : opt ), } : cat ) ); }, onAddClick: (categoryName: string) => { const newId = `custom-${categoryName}-${Date.now()}`; setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: [ ...cat.chipOptions, { id: newId, label: "", state: "Custom" }, ], } : cat ) ); }, onCustomChipConfirm: (categoryName: string, chipId: string, value: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, label: value, state: "Selected" } : opt ), } : cat ) ); }, onCustomChipClose: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.filter((opt) => opt.id !== chipId), } : cat ) ); }, }, { name: "Conflict management", chipOptions: [ { id: "conflict-1", label: "Code of Conduct", state: "Unselected" }, { id: "conflict-2", label: "Restorative Justice", state: "Unselected" }, ], onChipClick: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, state: opt.state === "Selected" ? "Unselected" : "Selected", } : opt ), } : cat ) ); }, onAddClick: (categoryName: string) => { const newId = `custom-${categoryName}-${Date.now()}`; setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: [ ...cat.chipOptions, { id: newId, label: "", state: "Custom" }, ], } : cat ) ); }, onCustomChipConfirm: (categoryName: string, chipId: string, value: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.map((opt) => opt.id === chipId ? { ...opt, label: value, state: "Selected" } : opt ), } : cat ) ); }, onCustomChipClose: (categoryName: string, chipId: string) => { setRuleCardCategories((prev) => prev.map((cat) => cat.name === categoryName ? { ...cat, chipOptions: cat.chipOptions.filter((opt) => opt.id !== chipId), } : cat ) ); }, }, ]); return (

Component Preview

RuleCard and Chip component examples - states, palettes, sizes, and interactions

{/* Chip Component - Controls */}

Chip Component (Controls)

{/* Default palette */}

Default palette

setChipStates((prev) => ({ ...prev, "default-s": prev["default-s"] === "Selected" ? "Unselected" : "Selected", })) } /> setChipStates((prev) => ({ ...prev, "default-m": prev["default-m"] === "Selected" ? "Unselected" : "Selected", })) } /> {customChips .filter((chip) => chip.palette === "Default") .map((chip) => ( { e.stopPropagation(); setCustomChips((prev) => prev.map((c) => c.id === chip.id ? { ...c, label: value, state: "Selected" } : c ) ); }} onClose={(e) => { e.stopPropagation(); setCustomChips((prev) => prev.filter((c) => c.id !== chip.id)); }} onClick={(e) => { e.stopPropagation(); // Only toggle if the chip is in Selected or Unselected state (not Custom) if (chip.state === "Selected" || chip.state === "Unselected") { setCustomChips((prev) => prev.map((c) => c.id === chip.id ? { ...c, state: c.state === "Selected" ? "Unselected" : "Selected", } : c ) ); } }} /> ))} {/* Add new custom chip button - Ghost button style */}
{/* Inverse palette - on white background */}

Inverse palette (on white background)

setChipStates((prev) => ({ ...prev, "inverse-s": prev["inverse-s"] === "Selected" ? "Unselected" : "Selected", })) } /> setChipStates((prev) => ({ ...prev, "inverse-m": prev["inverse-m"] === "Selected" ? "Unselected" : "Selected", })) } />
{/* Collapsed State - Large */}

Collapsed State - Large (L)

console.log("Card clicked: Mutual Aid Mondays")} />
{/* Collapsed State - Medium */}

Collapsed State - Medium (M)

console.log("Card clicked: Mutual Aid Mondays")} />
{/* Expanded State - Large */}

Expanded State - Large (L)

console.log("Card clicked: Mutual Aid Mondays")} />
{/* Expanded State - Medium */}

Expanded State - Medium (M)

console.log("Card clicked: Mutual Aid Mondays")} />
{/* Different Background Colors */}

Different Background Colors

} onClick={() => console.log("Consensus clusters selected")} /> } onClick={() => console.log("Consensus selected")} />
{/* Logo Fallback */}

Logo Fallback (Community Initials)

console.log("Community Example selected")} />
{/* MultiSelect Component */}

MultiSelect Component (Controls)

{/* Small size */} {/* Medium size */}
); }