UNPKG

react-vite-themes

Version:

A test/experimental React theme system created for learning purposes. Features atomic design components, SCSS variables, and dark/light theme support. Not intended for production use.

39 lines (38 loc) 2.5 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React, { useState, useRef, useEffect } from 'react'; import { Input } from '../Input'; import { Icon } from '../Icon'; import { Button } from '../Button'; import './SearchBar.scss'; export const SearchBar = ({ placeholder = 'Search...', value, defaultValue, onSearch, onClear, onChange, loading = false, disabled = false, size = 'md', variant = 'default', showClearButton = true, debounceMs = 300, className = '', ...props }) => { const [inputValue, setInputValue] = useState(value || defaultValue || ''); const debounceTimeoutRef = useRef(undefined); // Update internal state when value prop changes useEffect(() => { if (value !== undefined) { setInputValue(value); } }, [value]); const handleInputChange = (newValue) => { setInputValue(newValue); onChange?.(newValue); // Debounce search if (debounceTimeoutRef.current) { clearTimeout(debounceTimeoutRef.current); } debounceTimeoutRef.current = setTimeout(() => { onSearch?.(newValue); }, debounceMs); }; const handleClear = () => { setInputValue(''); onChange?.(''); onClear?.(); onSearch?.(''); }; const handleSubmit = (e) => { e.preventDefault(); onSearch?.(inputValue); }; return (_jsx("form", { className: `search-bar search-bar--${size} search-bar--${variant} ${className}`, onSubmit: handleSubmit, ...props, children: _jsxs("div", { className: "search-bar__container", children: [_jsxs("div", { className: "search-bar__input-wrapper", children: [_jsx(Icon, { name: "search", className: "search-bar__search-icon", size: size === 'sm' ? 'sm' : size === 'lg' ? 'lg' : 'md' }), _jsx(Input, { type: "text", value: inputValue, onChange: handleInputChange, placeholder: placeholder, disabled: disabled, size: size, variant: variant, className: "search-bar__input", "aria-label": "Search", role: "searchbox" }), loading && (_jsx(Icon, { name: "spinner", className: "search-bar__loading-icon", size: size === 'sm' ? 'sm' : size === 'lg' ? 'lg' : 'md' }))] }), showClearButton && inputValue && !loading && (_jsx(Button, { type: "button", colorScheme: "ghost", size: size, onClick: handleClear, className: "search-bar__clear-button", "aria-label": "Clear search", children: _jsx(Icon, { name: "x", size: size === 'sm' ? 'sm' : size === 'lg' ? 'lg' : 'md' }) }))] }) })); };