`, doExample: `// ✅ DO: Use v-model for two-way binding const search = ref('');
`, dontExample: `// ❌ DON'T: Mix v-model with manual events const search = ref('');
// Confusing`, }, angular: { framework: 'angular', code: `import { Component } from '@angular/core'; // import removed @Component({ selector: 'app-search', template: \`
Clear
\`, standalone: true, imports: [FormsModule] }) export class SearchComponent { search = ''; handleSearch() { // Debounced search logic } }`, doExample: `// ✅ DO: Use [(ngModel)] for two-way binding search = '';
`, dontExample: `// ❌ DON'T: Manual event handling with ngModel
`, }, svelte: { framework: 'svelte', code: `
{#if search}
search = ''}> Clear
{/if}
`, doExample: `// ✅ DO: Use bind:value for two-way binding let search = '';
`, dontExample: `// ❌ DON'T: Manual value binding without reactivity let search = '';
search = e.target.value} />`, }, }), []); const handleCopy = useCallback(async () => { const currentCode = codeBlocks[activeFramework]?.code || ''; try { await navigator.clipboard.writeText(currentCode); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = currentCode; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); setCopied(true); setTimeout(() => setCopied(false), 2000); } }, [activeFramework, codeBlocks]); const currentCode = codeBlocks[activeFramework]; useEffect(() => { setPlaygroundValue(''); }, [activeFramework]); return (
{/* Header */}
Search Input Component
Usage example with best practices
setShowDoDont(!showDoDont)} className={`px-3 py-1.5 text-xs rounded border transition-colors ${ showDoDont ? 'bg-[#C9A84C]/20 border-[#C9A84C] text-[#C9A84C]' : 'bg-transparent border-[#F5F5F0]/20 text-[#F5F5F0]/60' }`} > Do / Don't
{/* Framework Tabs */}
{frameworks.map((fw) => (
setActiveFramework(fw.id)} className={`px-4 py-2 text-sm rounded-t transition-all ${ activeFramework === fw.id ? 'bg-[#C9A84C]/10 text-[#C9A84C] border-b-2 border-[#C9A84C]' : 'text-[#F5F5F0]/50 hover:text-[#F5F5F0]/80 hover:bg-[#F5F5F0]/5' }`} > {fw.label}
))}
{/* Main Content Grid */}
{/* Code Block */}
Code
{copied ? ( <>
Copied > ) : ( <>
Copy > )}
{currentCode?.code}
{/* Live Playground */}
Live Playground
Interactive demo
setPlaygroundValue(e.target.value)} placeholder="Type to search..." className="w-full bg-[#0A0A0A] border border-[#F5F5F0]/20 text-[#F5F5F0] px-4 py-3 rounded-lg focus:outline-none focus:border-[#C9A84C] focus:ring-1 focus:ring-[#C9A84C]/30 placeholder-[#F5F5F0]/30 transition-all" /> {playgroundValue && (
setPlaygroundValue('')} className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F5F5F0]/40 hover:text-[#C9A84C] transition-colors" >
)}
{playgroundValue && (
Searching for:
{playgroundValue}
)} {!playgroundValue && (
Start typing to see the component in action
)}
{/* Do / Don't Section */} {showDoDont && (
React.createElement('div', { style: { color: '#888', fontSize: 14 } }, 'Preview unavailable')); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(React.createElement(ComponentToRender));