mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 06:45:46 +00:00
feat(FE-114): add inputPrefix and inputSuffix props for enhanced input customization
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { ChangeEvent } from 'react';
|
||||
import { ChangeEvent, ReactNode } from 'react';
|
||||
import { NumericFormat, OnValueChange } from 'react-number-format';
|
||||
import TextInput, { TextInputProps } from '@/components/input/TextInput';
|
||||
|
||||
@@ -12,6 +12,8 @@ interface NumberInputProps extends Omit<TextInputProps, 'type'> {
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
fixedDecimalScale?: boolean;
|
||||
inputPrefix?: ReactNode;
|
||||
inputSuffix?: ReactNode;
|
||||
}
|
||||
|
||||
const NumberInput = ({
|
||||
@@ -20,6 +22,8 @@ const NumberInput = ({
|
||||
decimalScale = 5,
|
||||
allowNegative = true,
|
||||
onChange,
|
||||
inputPrefix,
|
||||
inputSuffix,
|
||||
...restProps
|
||||
}: NumberInputProps) => {
|
||||
const valueChangeHandler: OnValueChange = (
|
||||
@@ -45,6 +49,8 @@ const NumberInput = ({
|
||||
onValueChange={valueChangeHandler}
|
||||
decimalScale={decimalScale}
|
||||
allowNegative={allowNegative}
|
||||
inputPrefix={inputPrefix}
|
||||
inputSuffix={inputSuffix}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -31,6 +31,8 @@ export interface TextInputProps {
|
||||
errorMessage?: string;
|
||||
startAdornment?: ReactNode;
|
||||
endAdornment?: ReactNode;
|
||||
inputPrefix?: ReactNode;
|
||||
inputSuffix?: ReactNode;
|
||||
onChange?: ChangeEventHandler<HTMLInputElement>;
|
||||
onBlur?: FocusEventHandler<HTMLInputElement>;
|
||||
}
|
||||
@@ -48,6 +50,8 @@ const TextInput = ({
|
||||
errorMessage,
|
||||
startAdornment,
|
||||
endAdornment,
|
||||
inputPrefix,
|
||||
inputSuffix,
|
||||
disabled = false,
|
||||
required = false,
|
||||
onChange,
|
||||
@@ -85,39 +89,113 @@ const TextInput = ({
|
||||
</label>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
'input h-12 px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all duration-200 bg-white',
|
||||
{
|
||||
'border-error': isError,
|
||||
'border-success!': isValid,
|
||||
},
|
||||
className?.inputWrapper
|
||||
)}
|
||||
>
|
||||
{startAdornment && startAdornment}
|
||||
{inputPrefix || inputSuffix ? (
|
||||
<div className='relative flex'>
|
||||
{inputPrefix && (
|
||||
<div
|
||||
className={cn(
|
||||
'inline-flex items-center px-4 py-2 border border-r-0 rounded-l-md transition-all duration-200',
|
||||
{
|
||||
'bg-gray-100 border-gray-300': !disabled,
|
||||
'bg-gray-50 border-gray-200': disabled,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{inputPrefix}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
type={type}
|
||||
id={name}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
disabled={disabled}
|
||||
className={cn('grow', className?.input)}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
<div
|
||||
className={cn(
|
||||
'input h-12 text-base font-normal leading-6 flex-1 rounded-lg! outline-none! transition-all duration-200 flex items-center bg-white',
|
||||
{
|
||||
'border-error': isError,
|
||||
'border-success!': isValid,
|
||||
'rounded-l-none!': inputPrefix,
|
||||
'rounded-r-none!': inputSuffix,
|
||||
'input-disabled': disabled,
|
||||
'cursor-not-allowed': disabled,
|
||||
'bg-gray-50': disabled,
|
||||
},
|
||||
className?.inputWrapper
|
||||
)}
|
||||
>
|
||||
{startAdornment && startAdornment}
|
||||
|
||||
{(isLoading || endAdornment) && (
|
||||
<div className='flex flex-row gap-2'>
|
||||
{isLoading && <span className='loading loading-spinner' />}
|
||||
<input
|
||||
type={type}
|
||||
id={name}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
disabled={disabled}
|
||||
className={cn('grow bg-transparent outline-none', {
|
||||
'cursor-not-allowed': disabled,
|
||||
'text-gray-500': disabled,
|
||||
}, className?.input)}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
|
||||
{endAdornment && endAdornment}
|
||||
{(isLoading || endAdornment) && (
|
||||
<div className='flex flex-row gap-2'>
|
||||
{isLoading && <span className='loading loading-spinner' />}
|
||||
|
||||
{endAdornment && endAdornment}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{inputSuffix && (
|
||||
<div
|
||||
className={cn(
|
||||
'inline-flex items-center px-4 py-2 border border-l-0 rounded-r-md transition-all duration-200',
|
||||
{
|
||||
'bg-gray-100 border-gray-300': !disabled,
|
||||
'bg-gray-50 border-gray-200': disabled,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{inputSuffix}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={cn(
|
||||
'input h-12 px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all duration-200 bg-white',
|
||||
{
|
||||
'border-error': isError,
|
||||
'border-success!': isValid,
|
||||
},
|
||||
className?.inputWrapper
|
||||
)}
|
||||
>
|
||||
{startAdornment && startAdornment}
|
||||
|
||||
<input
|
||||
type={type}
|
||||
id={name}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
disabled={disabled}
|
||||
className={cn('grow', className?.input)}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
|
||||
{(isLoading || endAdornment) && (
|
||||
<div className='flex flex-row gap-2'>
|
||||
{isLoading && <span className='loading loading-spinner' />}
|
||||
|
||||
{endAdornment && endAdornment}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isError && bottomLabel && (
|
||||
<p className='w-full text-sm opacity-60'>{bottomLabel}</p>
|
||||
|
||||
Reference in New Issue
Block a user