140 lines
4.4 KiB
TypeScript
140 lines
4.4 KiB
TypeScript
import React, { forwardRef } from "react";
|
|
import { Icons } from "../Icons";
|
|
|
|
export interface InputCompOneProps {
|
|
label?: string;
|
|
labelClass?: string;
|
|
labelSpan?: string;
|
|
labelSpanClass?: string;
|
|
floatLabel?: string;
|
|
placeholder?: string;
|
|
value?: string | any;
|
|
onChange?: (e:any) => any;
|
|
onInput?: (e:any) => any;
|
|
name: string;
|
|
tabIndex?: number;
|
|
ref?: React.RefObject<HTMLInputElement>;
|
|
selectValue?: string;
|
|
input?: boolean;
|
|
select?: boolean;
|
|
selectOptions?: {loading:boolean, data:{ value: string; label: string }[]};
|
|
inputType?: string;
|
|
inputClass?: string;
|
|
parentInputClass?: string;
|
|
selectClass?: string;
|
|
parentClass?: string;
|
|
maxLength?: number;
|
|
error?: string;
|
|
}
|
|
|
|
const InputCompOne = forwardRef<HTMLInputElement, InputCompOneProps>(
|
|
(
|
|
{
|
|
label,
|
|
labelClass,
|
|
labelSpan,
|
|
labelSpanClass,
|
|
floatLabel,
|
|
placeholder,
|
|
value,
|
|
onChange,
|
|
onInput,
|
|
name,
|
|
tabIndex,
|
|
selectValue,
|
|
input = false,
|
|
select = false,
|
|
selectOptions = {loading:false, data:[]},
|
|
inputType = "text",
|
|
inputClass,
|
|
parentInputClass,
|
|
selectClass,
|
|
parentClass,
|
|
maxLength,
|
|
error,
|
|
},
|
|
forwardedRef
|
|
) => {
|
|
return (
|
|
<div className={parentClass}>
|
|
{label && (
|
|
<label htmlFor={label ? label : floatLabel} className={`flex gap-2 items-center flex-wrap ${labelClass}`}>
|
|
{label}
|
|
{labelSpan && <span className={labelSpanClass}>{labelSpan}</span>}
|
|
{error && label && <span className='text-[10px] text-red-500'>{error}</span>}
|
|
</label>
|
|
)}
|
|
{input && (
|
|
<div className={`relative ${parentInputClass}`}>
|
|
<input
|
|
type={inputType}
|
|
placeholder={placeholder}
|
|
value={value}
|
|
onChange={onChange}
|
|
onInput={onInput}
|
|
name={name}
|
|
tabIndex={tabIndex}
|
|
ref={forwardedRef}
|
|
className={`px-4 ${floatLabel && 'peer pt-4 placeholder:text-transparent'} ${inputClass}`}
|
|
maxLength={maxLength}
|
|
id={label ? label : floatLabel}
|
|
/>
|
|
{floatLabel &&
|
|
<label
|
|
htmlFor={label ? label : floatLabel}
|
|
className={`flex items-center gap-2 cursor-pointer text-sm text-black/70 dark:text-white absolute left-4 top-0 translate-y-0 peer-focus:top-0 peer-focus:translate-y-0 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 transition-all duration-500`}
|
|
>
|
|
{floatLabel}
|
|
{error && floatLabel && !label && <span className='text-[10px] text-red-500'>{error}</span>}
|
|
</label>
|
|
}
|
|
</div>
|
|
)}
|
|
{select && (
|
|
<div className={`relative ${parentInputClass}`}>
|
|
<select
|
|
name={name}
|
|
id={label ? label : floatLabel}
|
|
value={selectValue}
|
|
className={`px-4 appearance-none ${floatLabel && 'peer pt-4'} ${selectClass}`}
|
|
onChange={onChange}
|
|
>
|
|
{selectOptions.loading ?
|
|
<option value=''>Loading</option>
|
|
: selectOptions.data.length ?
|
|
selectOptions.data.map(({ value, label }) => (
|
|
<option key={value} value={value}>
|
|
{label}
|
|
</option>
|
|
))
|
|
:
|
|
<option value=''>Not Found</option>
|
|
}
|
|
{/* {selectOptions.map(({ value, label }) => (
|
|
<option key={value} value={value}>
|
|
{label}
|
|
</option>
|
|
))} */}
|
|
</select>
|
|
{floatLabel &&
|
|
<label
|
|
htmlFor={label ? label : floatLabel}
|
|
className={`flex items-center gap-2 cursor-pointer text-sm text-black/70 dark:text-white absolute left-4 top-0 translate-y-0 peer-focus:top-0 peer-focus:translate-y-0 transition-all duration-500`}
|
|
>
|
|
{floatLabel}
|
|
{error && floatLabel && !label && <span className='text-[10px] text-red-500'>{error}</span>}
|
|
</label>
|
|
}
|
|
{/* select custon arrow */}
|
|
<div className='absolute right-4 top-1/2 -translate-y-1/2'>
|
|
<Icons name='arrow-down' />
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
export default InputCompOne;
|