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.

67 lines (66 loc) 3.38 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React, { forwardRef, useState } from 'react'; import { Icon } from '../Icon'; export const Input = forwardRef(({ as = 'input', className = '', size = 'md', leftIcon, leftIconSize = 'sm', rightIcon, rightIconSize = 'sm', isRounded = false, showDateIcon = true, dateFormat = 'YYYY-MM-DD', minDate, maxDate, useCustomCalendar = false, showPasswordToggle = false, onChange, type, ...props }, ref) => { const Component = as; // Password toggle state const [showPassword, setShowPassword] = useState(false); // Determine if this is a password input const isPasswordInput = type === 'password'; const shouldShowPasswordToggle = isPasswordInput && showPasswordToggle; // Determine the effective type (password or text for toggle) const effectiveType = shouldShowPasswordToggle && showPassword ? 'text' : type; const sizeClasses = { sm: 'input-sm', md: 'input-md', lg: 'input-lg' }; // Auto-add calendar icon for date inputs if showDateIcon is true const isDateInput = type === 'date'; const shouldShowDateIcon = isDateInput && showDateIcon && !leftIcon; const effectiveLeftIcon = shouldShowDateIcon ? 'calendar' : leftIcon; // Determine effective right icon (password toggle takes precedence) const effectiveRightIcon = shouldShowPasswordToggle ? (showPassword ? 'eye-off' : 'eye') : rightIcon; const inputClasses = [ 'input', sizeClasses[size || 'md'], effectiveLeftIcon ? 'input-with-left-icon' : '', effectiveRightIcon ? 'input-with-right-icon' : '', isRounded ? 'input-rounded' : '', isDateInput ? 'input-date' : '', className ].filter(Boolean).join(' '); // Helper function to render icon const renderIcon = (icon, iconSize) => { if (typeof icon === 'string') { return _jsx(Icon, { name: icon, size: iconSize }); } return icon; }; // Handle file input state const handleChange = (event) => { if (type === 'file' && event.target instanceof HTMLInputElement) { const files = event.target.files; const hasFiles = files && files.length > 0; // Add or remove the has-files class if (hasFiles) { event.target.classList.add('has-files'); } else { event.target.classList.remove('has-files'); } } // Call the original onChange if provided if (onChange) { onChange(event); } }; // Handle password toggle const handlePasswordToggle = () => { setShowPassword(!showPassword); }; return (_jsxs("div", { className: "input-wrapper", children: [effectiveLeftIcon && (_jsx("div", { className: "input-left-icon", children: renderIcon(effectiveLeftIcon, leftIconSize) })), _jsx(Component, { ref: ref, className: inputClasses, type: effectiveType, onChange: handleChange, min: minDate, max: maxDate, ...props }), effectiveRightIcon && (_jsx("div", { className: `input-right-icon ${shouldShowPasswordToggle ? 'input-password-toggle' : ''}`, onClick: shouldShowPasswordToggle ? handlePasswordToggle : undefined, children: renderIcon(effectiveRightIcon, rightIconSize) }))] })); }); Input.displayName = 'Input';