Repository Public
1'use client';2import * as React from 'react';3import { cn } from '@/lib/cn';45const base =6 'w-full rounded-sm border border-line-2 bg-surface px-3 text-[13px] text-text placeholder:text-muted transition-colors duration-150 hover:border-line-3 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent/15 focus-visible:outline-none disabled:opacity-50 aria-[invalid=true]:border-error';78export const Input = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(function Input({ className, ...props }, ref) {9 return <input ref={ref} className={cn(base, 'h-8 pointer-coarse:h-12 pointer-coarse:rounded-[14px]', className)} {...props} />;10});11export const Textarea = React.forwardRef<HTMLTextAreaElement, React.TextareaHTMLAttributes<HTMLTextAreaElement>>(function Textarea({ className, ...props }, ref) {12 return <textarea ref={ref} className={cn(base, 'min-h-20 py-2', className)} {...props} />;13});1415export function Field({ label, hint, error, children, className }: { label: string; hint?: React.ReactNode; error?: string | null; children: React.ReactElement<{ id?: string; 'aria-invalid'?: boolean; 'aria-describedby'?: string }>; className?: string }) {16 const id = React.useId();17 const descId = `${id}-d`;18 return (19 <div className={cn('flex flex-col gap-1.5', className)}>20 <label htmlFor={id} className="text-xs font-medium text-text-2">21 {label}22 </label>23 {React.cloneElement(children, { id, 'aria-invalid': error ? true : undefined, 'aria-describedby': hint || error ? descId : undefined })}24 {(error || hint) && (25 <p id={descId} className={cn('text-xs', error ? 'text-error' : 'text-muted')} role={error ? 'alert' : undefined}>26 {error || hint}27 </p>28 )}29 </div>30 );31}32