'use client' import { useState, useSyncExternalStore } from 'react' import { Avatar, AvatarFallback, AvatarImage, Badge, BubbleChatClose, BubbleChatPreview, Button, ButtonGroup, ButtonGroupItem, Checkbox, ChevronDown, ChipDatePicker, Code, Combobox, Connections, Cursor, DocumentAttachment, Download, Duplicate, Expand, Eye, FolderCode, FolderPlus, Hand, HexSimple, Input, Key as KeyIcon, Label, Layout, Library, Loader, Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTabs, ModalTabsContent, ModalTabsList, ModalTabsTrigger, ModalTrigger, MoreHorizontal, NoWrap, PanelLeft, Play, PlayOutline, Popover, PopoverBackButton, PopoverContent, PopoverFolder, PopoverItem, PopoverScrollArea, PopoverSearch, PopoverSection, PopoverTrigger, Redo, Rocket, Slider, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TagInput, type TagItem, Textarea, TimePicker, ToastProvider, Tooltip, Trash, Trash2, toast, Undo, Wrap, ZoomIn, ZoomOut, } from '@sim/emcn' import { ArrowLeft, Folder, Moon, Sun } from 'lucide-react' import { notFound, useRouter } from 'next/navigation' import { env, isTruthy } from '@/lib/core/config/env' function Section({ title, children }: { title: string; children: React.ReactNode }) { return (

{title}

{children}
) } function VariantRow({ label, children }: { label: string; children: React.ReactNode }) { return (
{label}
{children}
) } const SAMPLE_CODE = `function greet(name) { console.log("Hello, " + name); return { success: true }; }` const SAMPLE_PYTHON = `def greet(name): print(f"Hello, {name}") return {"success": True}` const COMBOBOX_OPTIONS = [ { label: 'Option 1', value: 'opt1' }, { label: 'Option 2', value: 'opt2' }, { label: 'Option 3', value: 'opt3' }, ] const DARK_MODE_EVENT = 'playground:dark-mode-change' const subscribeToDarkMode = (onStoreChange: () => void) => { window.addEventListener(DARK_MODE_EVENT, onStoreChange) return () => window.removeEventListener(DARK_MODE_EVENT, onStoreChange) } const getDarkModeSnapshot = () => document.documentElement.classList.contains('dark') const getServerDarkModeSnapshot = () => false export default function PlaygroundPage() { const router = useRouter() const [comboboxValue, setComboboxValue] = useState('') const [switchValue, setSwitchValue] = useState(false) const [checkboxValue, setCheckboxValue] = useState(false) const [sliderValue, setSliderValue] = useState([50]) const [timeValue, setTimeValue] = useState('09:30') const isDarkMode = useSyncExternalStore( subscribeToDarkMode, getDarkModeSnapshot, getServerDarkModeSnapshot ) const [buttonGroupValue, setButtonGroupValue] = useState('curl') const [dateValue, setDateValue] = useState('') const [dateRangeStart, setDateRangeStart] = useState('') const [dateRangeEnd, setDateRangeEnd] = useState('') const [tagItems, setTagItems] = useState([ { value: 'user@example.com', isValid: true }, { value: 'invalid-email', isValid: false, error: 'Invalid email format' }, ]) const toggleDarkMode = () => { document.documentElement.classList.toggle('dark') window.dispatchEvent(new Event(DARK_MODE_EVENT)) } if (!isTruthy(env.NEXT_PUBLIC_ENABLE_PLAYGROUND)) { notFound() } return (
Go back
{isDarkMode ? 'Light mode' : 'Dark mode'}

EMCN Component Playground

All emcn UI components and their variants

{/* Toast */}
{/* Button */}
{/* ButtonGroup */}
cURL Python JavaScript Option 1 Option 2 Option 1 Option 2 Option 1 Option 2 Only Option
{/* Badge */}
Default Outline Type Green With Dot Red With Dot Blue With Dot Blue Secondary Purple Orange Amber Teal Cyan Gray Gray Secondary Small Medium Large
{/* Input */}
{/* TagInput */}
{ const isValid = value.includes('@') && value.includes('.') setTagItems((prev) => [...prev, { value, isValid }]) return isValid }} onRemove={(_, index) => { setTagItems((prev) => prev.filter((_, i) => i !== index)) }} placeholder='Enter emails...' placeholderWithTags='Add another' />
true} onRemove={() => {}} placeholder='Add tags' placeholderWithTags='Add another' triggerKeys={['Enter', ',']} />
false} onRemove={() => {}} placeholder='Disabled input' disabled />
{/* Textarea */}