mirror of https://github.com/acid-info/lsd.git
refactor: refactor textfield component
This commit is contained in:
parent
2b53c86608
commit
146337e8f4
|
@ -2,14 +2,13 @@ export const textFieldClasses = {
|
|||
root: `lsd-textField`,
|
||||
|
||||
input: `lsd-textField__input`,
|
||||
filled: `lsd-textField__icon`,
|
||||
icon: `lsd-textField__icon`,
|
||||
|
||||
supportingText: 'lsd-textField__supporting-text',
|
||||
supportingTextLarge: 'lsd-textField__supporting-text--large',
|
||||
supportingTextMedium: 'lsd-textField__supporting-text--medium',
|
||||
|
||||
disabled: `lsd-textField--disabled`,
|
||||
error: 'lsd-textField--error',
|
||||
|
||||
large: `lsd-textField--large`,
|
||||
medium: `lsd-textField--medium`,
|
||||
withIcon: `lsd-textField--with-icon`,
|
||||
|
|
|
@ -6,17 +6,25 @@ export const TextFieldStyles = css`
|
|||
width: auto;
|
||||
border-bottom: 1px solid rgb(var(--lsd-border-primary));
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.${textFieldClasses.root} > div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.${textFieldClasses.disabled} {
|
||||
opacity: 0.34;
|
||||
}
|
||||
|
||||
.${textFieldClasses.input} {
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 14px;
|
||||
color: rgb(var(--lsd-text-primary));
|
||||
background: none;
|
||||
width: inherit;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.${textFieldClasses.input}:hover {
|
||||
|
@ -28,19 +36,13 @@ export const TextFieldStyles = css`
|
|||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.${textFieldClasses.disabled} {
|
||||
cursor: default;
|
||||
opacity: 0.34;
|
||||
}
|
||||
|
||||
.${textFieldClasses.error} {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.${textFieldClasses.supportingText} {
|
||||
width: fit-content;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.${textFieldClasses.large} {
|
||||
|
@ -55,22 +57,12 @@ export const TextFieldStyles = css`
|
|||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
.${textFieldClasses.supportingTextLarge} {
|
||||
margin: 8px 14px;
|
||||
}
|
||||
|
||||
.${textFieldClasses.supportingTextMedium} {
|
||||
margin: 8px 12px;
|
||||
}
|
||||
|
||||
.${textFieldClasses.withIcon} {
|
||||
}
|
||||
|
||||
.${textFieldClasses.filled} {
|
||||
.${textFieldClasses.icon} {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
svg path {
|
||||
--lsd-icon-primary: var(--lsd-icon-primary);
|
||||
}
|
||||
align-items: center;
|
||||
}
|
||||
`
|
||||
|
|
|
@ -1,40 +1,51 @@
|
|||
import clsx from 'clsx'
|
||||
import React, { useState } from 'react'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { CheckIcon, CloseIcon, ErrorIcon } from '../Icons'
|
||||
import { Typography } from '../Typography'
|
||||
import { textFieldClasses } from './TextField.classes'
|
||||
|
||||
export type TextFieldProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
||||
export type TextFieldProps = Omit<
|
||||
React.HTMLAttributes<HTMLDivElement>,
|
||||
'onChange' | 'value'
|
||||
> & {
|
||||
size?: 'large' | 'medium'
|
||||
withIcon?: boolean
|
||||
error?: boolean
|
||||
disabled?: boolean
|
||||
supportingText?: string
|
||||
value?: string
|
||||
onChange?: (value: any) => void
|
||||
}
|
||||
|
||||
export const TextField: React.FC<TextFieldProps> & {
|
||||
classes: typeof textFieldClasses
|
||||
} = ({
|
||||
size = 'large',
|
||||
withIcon = 'false',
|
||||
supportingText = 'Supporting text',
|
||||
withIcon = false,
|
||||
supportingText,
|
||||
error = false,
|
||||
children,
|
||||
value,
|
||||
onChange,
|
||||
...props
|
||||
}) => {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const [inputValue, setInputValue] = useState<string>('')
|
||||
|
||||
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
|
||||
const handleChange = (e: React.FormEvent<HTMLInputElement>) => {
|
||||
const newValue = e.currentTarget.value
|
||||
if (onChange) onChange(newValue)
|
||||
setInputValue(newValue)
|
||||
}
|
||||
|
||||
const onCancel = () => {
|
||||
setInputValue('')
|
||||
if (typeof onChange !== 'undefined') onChange('')
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
props.className,
|
||||
textFieldClasses.root,
|
||||
|
@ -43,8 +54,9 @@ export const TextField: React.FC<TextFieldProps> & {
|
|||
withIcon && textFieldClasses.withIcon,
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
onChange={onChange}
|
||||
onChange={handleChange}
|
||||
className={clsx(
|
||||
textFieldClasses.input,
|
||||
error && textFieldClasses.error,
|
||||
|
@ -53,34 +65,30 @@ export const TextField: React.FC<TextFieldProps> & {
|
|||
{...props}
|
||||
/>
|
||||
{withIcon && error ? (
|
||||
<span className={textFieldClasses.filled} onClick={onCancel}>
|
||||
<ErrorIcon color="primary" className={textFieldClasses.filled} />
|
||||
<span className={textFieldClasses.icon} onClick={onCancel}>
|
||||
<ErrorIcon color="primary" className={textFieldClasses.icon} />
|
||||
</span>
|
||||
) : withIcon && !inputValue.length ? (
|
||||
<span className={textFieldClasses.filled}>
|
||||
<span className={textFieldClasses.icon}>
|
||||
<CheckIcon color="primary" />
|
||||
</span>
|
||||
) : withIcon && inputValue.length ? (
|
||||
<span className={textFieldClasses.filled} onClick={onCancel}>
|
||||
<span className={textFieldClasses.icon} onClick={onCancel}>
|
||||
<CloseIcon color="primary" />
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
{supportingText && (
|
||||
<div className={clsx(textFieldClasses.supportingText)}>
|
||||
<Typography
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
component="p"
|
||||
className={clsx(
|
||||
textFieldClasses.supportingText,
|
||||
size && size === 'large'
|
||||
? textFieldClasses.supportingTextLarge
|
||||
: textFieldClasses.supportingTextMedium,
|
||||
)}
|
||||
>
|
||||
{supportingText}
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue