44 lines
2.1 KiB
TypeScript
44 lines
2.1 KiB
TypeScript
import type { InputHTMLAttributes, ReactNode, SelectHTMLAttributes, TextareaHTMLAttributes } from "react";
|
|
import { IconButton } from "./Button.tsx";
|
|
import { IconChevronDown, IconClose, IconSearch } from "./icons.tsx";
|
|
|
|
type Size = { size?: "md" | "lg" };
|
|
const cx = (...a: Array<string | false | undefined>) => a.filter(Boolean).join(" ");
|
|
|
|
export function TextInput({ size = "md", className, ...rest }: Size & Omit<InputHTMLAttributes<HTMLInputElement>, "size">) {
|
|
return <input {...rest} className={cx("ui-input", `ui-input--${size}`, className)} />;
|
|
}
|
|
|
|
export function Textarea({ size = "md", className, ...rest }: Size & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "size">) {
|
|
return <textarea {...rest} className={cx("ui-input", "ui-textarea", `ui-input--${size}`, className)} />;
|
|
}
|
|
|
|
export function SearchInput({ value, onChange, label, placeholder }: { value: string; onChange(v: string): void; label: string; placeholder?: string }) {
|
|
return (
|
|
<span className="ui-search">
|
|
<span className="ui-search__icon" aria-hidden="true"><IconSearch /></span>
|
|
<input type="search" className="ui-input ui-input--md ui-search__input" aria-label={label} placeholder={placeholder}
|
|
value={value} onChange={(e) => onChange(e.target.value)} />
|
|
{value !== "" && <IconButton className="ui-search__clear" label="Очистить" icon={<IconClose />} onClick={() => onChange("")} />}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export function Select({ size = "md", className, children, ...rest }: Size & Omit<SelectHTMLAttributes<HTMLSelectElement>, "size">) {
|
|
return (
|
|
<span className={cx("ui-select", `ui-select--${size}`, className)}>
|
|
<select {...rest} className="ui-input ui-select__control">{children}</select>
|
|
<span className="ui-select__chevron" aria-hidden="true"><IconChevronDown /></span>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export function Checkbox({ label, className, ...rest }: { label: ReactNode } & Omit<InputHTMLAttributes<HTMLInputElement>, "type">) {
|
|
return (
|
|
<label className={cx("ui-check", className)}>
|
|
<input {...rest} type="checkbox" className="ui-check__box" />
|
|
<span>{label}</span>
|
|
</label>
|
|
);
|
|
}
|