Skip to content

Commit

Permalink
Merge pull request #809 from deepfence/ui-v2-update-textinput
Browse files Browse the repository at this point in the history
update textinput component styles
  • Loading branch information
manV authored Jan 16, 2023
2 parents 44024e3 + 085f5c4 commit a61e90f
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const Login = () => {
placeholder="name@example.com"
sizing="sm"
name="email"
color={data?.fieldErrors?.email ? 'error' : 'default'}
/>
{data?.fieldErrors?.email && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand All @@ -47,6 +48,7 @@ export const Login = () => {
placeholder="••••••••"
sizing="sm"
name="password"
color={data?.fieldErrors?.password ? 'error' : 'default'}
/>
{data?.fieldErrors?.password && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const RegisterUser = () => {
placeholder="First Name"
sizing="sm"
name="firstName"
color={data?.fieldErrors?.firstName ? 'error' : 'default'}
/>
{data?.fieldErrors?.firstName && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand All @@ -48,6 +49,7 @@ export const RegisterUser = () => {
sizing="sm"
name="lastName"
className="mt-4"
color={data?.fieldErrors?.lastName ? 'error' : 'default'}
/>
{data?.fieldErrors?.lastName && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand All @@ -61,6 +63,7 @@ export const RegisterUser = () => {
sizing="sm"
name="email"
className="mt-4"
color={data?.fieldErrors?.email ? 'error' : 'default'}
/>
{data?.fieldErrors?.email && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand All @@ -74,6 +77,7 @@ export const RegisterUser = () => {
sizing="sm"
name="password"
className="mt-4"
color={data?.fieldErrors?.password ? 'error' : 'default'}
/>
{data?.fieldErrors?.password && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand All @@ -87,6 +91,7 @@ export const RegisterUser = () => {
sizing="sm"
name="confirmPassword"
className="mt-4"
color={data?.fieldErrors?.confirmPassword ? 'error' : 'default'}
/>
{data?.fieldErrors?.confirmPassword && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand All @@ -100,6 +105,7 @@ export const RegisterUser = () => {
sizing="sm"
name="company"
className="mt-4"
color={data?.fieldErrors?.company ? 'error' : 'default'}
/>
{data?.fieldErrors?.company && (
<p className={`mt-1.5 ${Typography.size.sm} text-red-500`}>
Expand Down
2 changes: 1 addition & 1 deletion deepfence_frontend/packages/tailwind-preset/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ module.exports = {
600: '#4B5563',
700: '#374151',
800: '#1F2937',
900: '#111928',
900: '#111827',
},
red: {
50: '#FDF2F2',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,27 @@ import cx from 'classnames';
import { FC } from 'react';
import { twMerge } from 'tailwind-merge';

import { Typography } from '@/components/typography/Typography';

export type ColorType = 'default' | 'error' | 'success';
export type SizeType = 'sm' | 'md';

type Props = {
text: string;
color: ColorType;
sizing?: SizeType;
className?: string;
};

export const classes = {
color: {
default: 'border-gray-300 text-gray-500',
error: 'border-red-500 text-red-700',
success: 'border-green-500 text-green-700',
},
size: {
sm: `${Typography.size.sm}`,
md: `${Typography.size.base}`,
default: 'text-gray-500 dark:text-gray-400',
error: 'text-red-600 dark:text-red-600',
success: 'text-green-600 dark:text-green-600',
},
};

export const HelperText: FC<Props> = ({ text, sizing = 'sm', color, className }) => {
export const HelperText: FC<Props> = ({ text, color, className }) => {
return (
<p
className={twMerge(
cx(
`${Typography.weight.normal} ${classes.color[color]}`,
`${classes.size[sizing]}`,
),
cx('leading-tight text-sm fornt-normal', `${classes.color[color]}`),
className,
)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ export const WithStartIcon = Template.bind({});
WithStartIcon.args = {
placeholder: 'test@deepfence.io',
startIcon: <AiOutlineMail />,
disabled: false,
};

export const LargeInput = Template.bind({});
LargeInput.args = {
placeholder: 'test@deepfence.io',
startIcon: <AiOutlineMail />,
sizing: 'md',
sizing: 'lg',
};

export const WithLabel = Template.bind({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import { IconContext } from 'react-icons';
import { twMerge } from 'tailwind-merge';

import HelperText from '@/components/input/HelperText';
import { Typography } from '@/components/typography/Typography';

export type SizeType = 'sm' | 'md';
export type SizeType = 'sm' | 'md' | 'lg';
export type ColorType = 'default' | 'error' | 'success';

export interface TextInputProps
Expand All @@ -27,50 +26,106 @@ type IconProps = {
id?: string;
color?: ColorType;
sizing?: SizeType;
disabled?: boolean;
};

export const classes = {
export const inputClasses = {
color: {
default: cx(
'border-gray-300 text-gray-500',
'focus:border-blue-600 focus:text-gray-900',
'dark:border-gray-600 dark:text-gray-400',
'dark:focus:border-blue-800 dark:focus:text-white dark:active:text-white',
// ring styles
'ring-gray-300 focus:ring-blue-600',
'dark:ring-gray-600 dark:focus:ring-blue-600',
// bg styles
'bg-gray-50',
'dark:bg-gray-700',
// placeholder styles
'placeholder-gray-500 disabled:placeholder-gray-400',
'dark:placeholder-gray-400 dark:disabled:placeholder-gray-500',
// text styles
'text-gray-900 disabled:text-gray-700',
'dark:text-white dark:disabled:text-gray-200',
),
error: cx(
// ring styles
'ring-red-200 focus:ring-red-500',
'dark:ring-red-800 dark:focus:ring-red-500',
// bg styles
'bg-red-50',
'dark:bg-gray-700',
// placeholder styles
'placeholder-red-400 disabled:placeholder-red-300',
'dark:placeholder-red-700 dark:disabled:placeholder-red-800',
// text styles
'text-red-700 disabled:text-red-500',
'dark:text-red-500 dark:disabled:text-red-700',
),
error: cx('border-red-500', 'focus:border-red-500'),
success: cx(
'border-green-500 text-green-700',
'focus:border-green-500 focus:text-green-500',
// ring styles
'ring-green-300 focus:ring-green-500',
'dark:ring-green-800 dark:focus:ring-green-500',
// bg styles
'bg-green-50',
'dark:bg-gray-700',
// placeholder styles
'placeholder-green-400 disabled:placeholder-green-300',
'dark:placeholder-green-700 dark:disabled:placeholder-green-800',
// text styles
'text-green-700 disabled:text-green-500',
'dark:text-green-500 dark:disabled:text-green-700',
),
},
size: {
sm: `${Typography.size.sm} p-3`,
md: `${Typography.size.base} py-3.5 px-4`,
sm: `text-sm px-4 py-2`,
md: `text-sm leading-tight px-4 py-3`,
lg: `text-base px-4 py-3.5`,
},
};

const iconClasses = {
color: {
default: {
enabled: cx('text-gray-500', 'dark:text-gray-400'),
disabled: cx('text-gray-400', 'dark:text-gray-500'),
},
error: {
enabled: cx('text-red-400', 'dark:text-red-700'),
disabled: cx('text-red-300', 'dark:text-red-800'),
},
success: {
enabled: cx('text-green-400', 'dark:text-green-700'),
disabled: cx('text-green-300', 'dark:text-green-800'),
},
},
size: {
sm: `w-4 h-4`,
md: `w-4 h-4`,
lg: `w-5 h-5`,
},
};

const COLOR_DEFAULT = 'default';
const SIZE_DEFAULT = 'sm';
const SIZE_DEFAULT = 'md';

export const LeftIcon = ({
icon,
id,
color = COLOR_DEFAULT,
sizing = SIZE_DEFAULT,
disabled,
}: IconProps) => {
return (
<span
className={cx(
'pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3',
'pointer-events-none absolute inset-y-0 left-0 flex items-center pl-4',
)}
data-testid={`textinput-start-icon-${id}`}
>
<IconContext.Provider
value={{
className: cx(`${classes.color[color]}`, {
'w-[18px] h-[18px]': sizing === 'sm',
'w-[20px] h-[20px]': sizing === 'md',
}),
className: cx(
`${iconClasses.color[color][disabled ? 'disabled' : 'enabled']}`,
`${iconClasses.size[sizing]}`,
),
}}
>
{icon}
Expand All @@ -84,20 +139,21 @@ export const RightIcon = ({
id,
color = COLOR_DEFAULT,
sizing = SIZE_DEFAULT,
disabled,
}: IconProps) => {
return (
<span
className={cx(
'pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3',
'pointer-events-none absolute inset-y-0 right-0 flex items-center pr-4',
)}
data-testid={`textinput-end-icon-${id}`}
>
<IconContext.Provider
value={{
className: cx(`${classes.color[color]}`, {
'w-[18px] h-[18px]': sizing === 'sm',
'w-[20px] h-[20px]': sizing === 'md',
}),
className: cx(
`${iconClasses.color[color][disabled ? 'disabled' : 'enabled']}`,
`${iconClasses.size[sizing]}`,
),
}}
>
{icon}
Expand Down Expand Up @@ -130,32 +186,42 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
{label && (
<LabelPrimitive.Root
htmlFor={_id}
className={cx(
`${Typography.weight.medium} ${Typography.size.sm} text-gray-900 dark:text-white`,
)}
className="text-sm font-medium text-gray-900 dark:text-white"
>
{required && <span>*</span>}
{label}
</LabelPrimitive.Root>
)}
<div className="relative">
{startIcon && (
<LeftIcon icon={startIcon} sizing={sizing} color={color} id={_id} />
<LeftIcon
icon={startIcon}
sizing={sizing}
color={color}
id={_id}
disabled={disabled}
/>
)}
{endIcon && (
<RightIcon
icon={endIcon}
sizing={sizing}
color={color}
id={_id}
disabled={disabled}
/>
)}
{endIcon && <RightIcon icon={endIcon} sizing={sizing} color={color} id={_id} />}
<input
className={cx(
'block w-full border box-border rounded-lg bg-gray-50 dark:bg-gray-700',
'block w-full ring-1 rounded-lg',
'font-normal',
'focus:outline-none',
`${classes.color[color]}`,
`${classes.size[sizing]}`,
`${Typography.weight.normal}`,
'disabled:cursor-not-allowed',
`${inputClasses.color[color]}`,
`${inputClasses.size[sizing]}`,
{
'disabled:cursor-not-allowed': disabled,
'pl-[38px]': startIcon,
[`${sizing === 'lg' ? 'pl-[48px]' : 'pl-[42px]'}`]: startIcon,
'pr-[38px]': endIcon,
'h-[42px]': sizing === 'sm',
'h-[52px]': sizing === 'md',
},
)}
disabled={disabled}
Expand All @@ -165,14 +231,7 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
{...rest}
/>
</div>
{helperText && (
<HelperText
sizing={sizing}
color={color}
text={helperText}
className="mb-2.5"
/>
)}
{helperText && <HelperText color={color} text={helperText} className="mb-2.5" />}
</div>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface TextInputAreaProps
color?: ColorType;
}

// TODO: use the same color classes as input
const classes = {
size: {
sm: `${Typography.size.sm} p-3`,
Expand Down Expand Up @@ -76,14 +77,7 @@ export const TextInputArea = forwardRef<HTMLTextAreaElement, TextInputAreaProps>
{...rest}
/>
</div>
{helperText && (
<HelperText
sizing={sizing}
color={color}
text={helperText}
className="mb-2.5"
/>
)}
{helperText && <HelperText color={color} text={helperText} className="mb-2.5" />}
</div>
);
},
Expand Down

0 comments on commit a61e90f

Please sign in to comment.