material-you-react/src/primitive-components/text-field/text-field.tsx

102 lines
3.3 KiB
TypeScript
Raw Normal View History

2024-02-01 00:58:19 +03:00
'use client';
2024-02-01 15:23:59 +03:00
import { bool, oneOf, string } from 'prop-types';
import { TextFieldInterface } from './text-field.types';
2024-02-01 22:37:22 +03:00
import React, { FocusEvent, forwardRef, useState } from 'react';
2024-02-01 00:58:19 +03:00
export const TextField = forwardRef<HTMLInputElement, TextFieldInterface>(
(
{
variant = 'filled',
withAfterIcon,
withBeforeIcon,
supportingText,
...props
},
ref,
) => {
2024-02-01 21:24:37 +03:00
const [raised, setRaised] = useState<boolean>(!!props.placeholder);
2024-02-01 00:58:19 +03:00
2024-02-01 15:23:59 +03:00
const callback = (e: FocusEvent<HTMLInputElement>): void => {
2024-02-01 00:58:19 +03:00
if (
e.type === 'blur' &&
e.target.value.length === 0 &&
!props.placeholder
) {
setRaised(false);
} else if (e.type === 'focus') {
setRaised(true);
}
};
const iconStyles =
withBeforeIcon && withAfterIcon
? 'with-before-icon with-after-icon'
: withBeforeIcon
? 'with-before-icon'
: withAfterIcon
? 'with-after-icon'
: '';
return (
<span>
<div className={`m3 m3-text-field ${variant}`.trimEnd()}>
{variant === 'outlined' && (
<fieldset>
2024-02-01 22:37:22 +03:00
<legend className={raised ? 'raised' : ''}>
2024-02-01 00:58:19 +03:00
<span>Label</span>
</legend>
</fieldset>
)}
{withBeforeIcon && (
<span className={'m3-icon icon-before'}>
{withBeforeIcon && 'search'}
</span>
)}
<input
ref={ref}
{...props}
className={`${props.className ?? ''} ${iconStyles}`.trim()}
onBlur={event => {
callback(event);
if (props.onBlur) {
props.onBlur(event);
}
}}
onFocus={event => {
callback(event);
if (props.onFocus) {
props.onFocus(event);
}
}}
/>
<label className={raised ? 'raised' : ''}>
{props.children ?? 'Label'}
</label>
<span className={'m3-text-field-state-layer'} />
{withAfterIcon && (
<span className={'m3-icon'}>
{withAfterIcon && 'cancel'}
</span>
)}
</div>
{supportingText !== '' && (
<span className={'m3-text-field-supporting-text'}>
{supportingText}
</span>
)}
</span>
);
},
);
TextField.propTypes = {
children: string,
className: string,
placeholder: string,
2024-02-01 21:24:37 +03:00
withAfterIcon: bool,
withBeforeIcon: bool,
2024-02-01 00:58:19 +03:00
supportingText: string,
2024-02-01 21:24:37 +03:00
variant: oneOf(['filled', 'outlined']),
2024-02-01 00:58:19 +03:00
};