Skip to content

Instantly share code, notes, and snippets.

@catorch
Created October 19, 2023 18:13
Show Gist options
  • Save catorch/de39adb37539bf4c0a8deae2eb9d09d2 to your computer and use it in GitHub Desktop.
Save catorch/de39adb37539bf4c0a8deae2eb9d09d2 to your computer and use it in GitHub Desktop.
Current GeneratorDropdown and GeneratorFormInput components styles with error state
import React, { ChangeEvent, useState, FC } from 'react';
interface OptionType {
value: string;
label: string;
}
interface DropdownProps {
options: OptionType[];
value: string;
onChange: (value: string) => void;
isError?: boolean;
errorMessage?: string;
id?: string;
}
const GeneratorDropdown: FC<DropdownProps> = ({
options,
value,
onChange,
isError = false,
errorMessage = "This field is required",
id,
}) => {
const handleDropdownChange = (e: ChangeEvent<HTMLSelectElement>) => {
onChange(e.target.value);
};
return (
<div>
<div className="relative">
<select
id={id}
value={value}
onChange={handleDropdownChange}
className={`h-[42px] text-sm py-1 px-4 w-full border border-gray-200 ${isError ? 'border-red-500 focus:border-red-500' : 'border border-solid'} bg-gray-75 rounded-md text-md focus:outline-none focus-visible:border-primary-400 focus:ring-primary-400 dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400`}
>
{options.map(option => (
<option key={option.value} value={option.value}>{option.label}</option>
))}
</select>
{isError &&
<div className="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-8">
<svg className="h-5 w-5 text-red-500" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z" />
</svg>
</div>
}
</div>
{isError && <p className="text-sm text-red-500 mt-2">{errorMessage}</p>}
</div>
);
};
export default GeneratorDropdown;
import React, { ChangeEvent, FC } from 'react';
interface GeneratorFormInputProps {
value: string;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
placeholder?: string;
type?: string;
id?: string;
name?: string;
isError?: boolean;
errorMessage?: string;
label?: string;
[key: string]: any;
}
const GeneratorFormInput: FC<GeneratorFormInputProps> = ({
value,
onChange,
placeholder = "",
type = "text",
id,
name,
isError = false,
errorMessage = "This field is required",
label = "",
...restProps
}) => {
const baseInputClass = "h-[42px] mt-4 py-3 px-4 block w-full rounded-md text-sm dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400";
const errorInputClass = "border border-solid border-red-500 focus:border-red-500 focus:outline-none focus:ring-0";
const defaultInputClass = "border border-gray-200 border-solid bg-gray-75 focus:outline-none focus-visible:border-primary-400 focus:ring-primary-400";
// className="mt-4 py-2.5 px-4 w-full border border-solid bg-gray-75 rounded-md text-md focus:outline-none focus-visible:border-primary-400 focus:ring-primary-400 dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400"
return (
<div>
{label && <label htmlFor={id} className="block text-sm font-medium mb-2 dark:text-white">{label}</label>}
<div className="relative">
<input
value={value}
onChange={onChange}
type={type}
id={id}
name={name}
className={`${baseInputClass} ${isError ? errorInputClass : defaultInputClass}`}
placeholder={placeholder}
{...restProps}
/>
{isError &&
<div className="absolute inset-y-0 right-0 flex items-center pointer-events-none pr-3">
<svg className="h-5 w-5 text-red-500" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
</svg>
</div>
}
</div>
{isError && errorMessage && <p className="text-sm text-red-500 mt-2" id={`${id}-helper`}>{errorMessage}</p>}
</div>
);
};
export default GeneratorFormInput;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment