Yong Tang 14ddef5c05
feat(gallery): add Style Detail Modal with phone UI controls preview (#155)
Click any StyleCard to open a full-screen modal showing the style applied
to 9 interactive phone UI controls (buttons, inputs, toggles, checkboxes,
radios, cards, badges, slider, nav bar) inside an iPhone mockup frame.

Co-authored-by: yongtang <jlinux@msn.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-01 08:29:30 +07:00

63 lines
1.8 KiB
TypeScript

"use client";
import { useEffect, useRef, useState } from "react";
interface SearchInputProps {
value: string;
onChange: (value: string) => void;
}
export function SearchInput({ value, onChange }: SearchInputProps) {
const [local, setLocal] = useState(value);
const timerRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
setLocal(value);
}, [value]);
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const v = e.target.value;
setLocal(v);
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => onChange(v), 300);
}
return (
<div className="relative">
<svg
className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
<input
type="text"
value={local}
onChange={handleChange}
placeholder="Search styles..."
className="w-full pl-10 pr-4 py-2.5 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent placeholder:text-gray-400"
/>
{local && (
<button
onClick={() => {
setLocal("");
onChange("");
}}
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
)}
</div>
);
}