From b80504ae0026adc64416f55843d466ceebfb0e02 Mon Sep 17 00:00:00 2001 From: akhilmhdh Date: Thu, 19 Jan 2023 21:07:44 +0530 Subject: [PATCH] feat(ui): implemented new input component --- .../src/components/v2/Input/Input.stories.tsx | 66 ++++++++++++ frontend/src/components/v2/Input/Input.tsx | 102 ++++++++++++++++++ frontend/src/components/v2/Input/index.tsx | 2 + 3 files changed, 170 insertions(+) create mode 100644 frontend/src/components/v2/Input/Input.stories.tsx create mode 100644 frontend/src/components/v2/Input/Input.tsx create mode 100644 frontend/src/components/v2/Input/index.tsx diff --git a/frontend/src/components/v2/Input/Input.stories.tsx b/frontend/src/components/v2/Input/Input.stories.tsx new file mode 100644 index 000000000..288805b21 --- /dev/null +++ b/frontend/src/components/v2/Input/Input.stories.tsx @@ -0,0 +1,66 @@ +import { faEye, faMailBulk } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { Input } from './Input'; + +const meta: Meta = { + title: 'Components/Input', + component: Input, + tags: ['v2'], + argTypes: { + isRounded: { + defaultValue: true, + type: 'boolean' + }, + placeholder: { + defaultValue: 'Type anything', + type: 'string' + } + } +}; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args +export const Filled: Story = { + args: {} +}; + +export const Outline: Story = { + args: { + variant: 'outline' + } +}; + +export const Plain: Story = { + args: { + variant: 'plain' + } +}; + +export const Error: Story = { + args: { + isError: true + } +}; + +export const AutoWidth: Story = { + args: { + isFullWidth: false, + className: 'w-auto' + } +}; + +export const RightIcon: Story = { + args: { + rightIcon: + } +}; + +export const LeftIcon: Story = { + args: { + leftIcon: + } +}; diff --git a/frontend/src/components/v2/Input/Input.tsx b/frontend/src/components/v2/Input/Input.tsx new file mode 100644 index 000000000..e7b63e3ad --- /dev/null +++ b/frontend/src/components/v2/Input/Input.tsx @@ -0,0 +1,102 @@ +import { forwardRef, InputHTMLAttributes, ReactNode } from 'react'; +import { cva, VariantProps } from 'cva'; +import { twMerge } from 'tailwind-merge'; + +type Props = { + placeholder?: string; + isFullWidth?: boolean; + isRequired?: boolean; + leftIcon?: ReactNode; + rightIcon?: ReactNode; +}; + +const inputVariants = cva( + 'input w-full py-2 text-gray-400 placeholder-gray-500 placeholder-opacity-50', + { + variants: { + size: { + xs: ['text-xs'], + sm: ['text-sm'], + md: ['text-md'], + lg: ['text-lg'] + }, + isRounded: { + true: ['rounded-md'], + false: '' + }, + variant: { + filled: ['bg-bunker-800', 'text-gray-400'], + outline: ['bg-transparent'], + plain: 'bg-transparent outline-none' + }, + isError: { + true: 'focus:ring-red/50 placeholder-red-300', + false: 'focus:ring-primary/50' + } + }, + compoundVariants: [] + } +); + +const inputParentContainerVariants = cva('inline-flex items-center border relative', { + variants: { + isRounded: { + true: ['rounded-md'], + false: '' + }, + isError: { + true: 'border-red', + false: 'border-mineshaft-400' + }, + isFullWidth: { + true: 'w-full', + false: '' + }, + variant: { + filled: ['bg-bunker-800', 'text-gray-400'], + outline: ['bg-transparent'], + plain: 'border-none' + } + } +}); + +export type InputProps = Omit, 'size'> & + VariantProps & + Props; + +export const Input = forwardRef( + ( + { + className, + isRounded = true, + isFullWidth = true, + isError = false, + isRequired, + leftIcon, + rightIcon, + variant = 'filled', + size = 'md', + ...props + }, + ref + ): JSX.Element => { + return ( +
+ {leftIcon && {leftIcon}} + + {rightIcon && {rightIcon}} +
+ ); + } +); + +Input.displayName = 'Input'; diff --git a/frontend/src/components/v2/Input/index.tsx b/frontend/src/components/v2/Input/index.tsx new file mode 100644 index 000000000..803d2fbab --- /dev/null +++ b/frontend/src/components/v2/Input/index.tsx @@ -0,0 +1,2 @@ +export type { InputProps } from './Input'; +export { Input } from './Input';