From 61010cbcabdd9b2b48fb2117744409f07e04845d Mon Sep 17 00:00:00 2001 From: geekysilento Date: Sat, 16 Mar 2024 22:50:00 +0545 Subject: [PATCH 1/7] feat: clean genericInputs --- components/inputs/Checkbox.tsx | 38 + components/inputs/Visualizer.tsx | 236 ++ components/inputs/date-time.tsx | 32 + components/inputs/date.tsx | 31 + components/inputs/email.tsx | 30 + components/inputs/fileUpload.tsx | 21 + components/inputs/multiSelectItem.tsx | 48 + components/inputs/numberfield.tsx | 29 + components/inputs/radioItems.tsx | 50 + components/inputs/selectIItem.tsx | 55 + components/inputs/telephone.tsx | 32 + components/inputs/text.tsx | 31 + components/inputs/textAreaField.tsx | 46 + components/inputs/time.tsx | 24 + components/ui/badge.tsx | 36 + components/ui/calendar.tsx | 72 + components/ui/checkbox.tsx | 30 + components/ui/command.tsx | 155 ++ components/ui/dialog.tsx | 122 + components/ui/dropdown-menu.tsx | 205 ++ components/ui/form.tsx | 177 ++ components/ui/input.tsx | 103 + components/ui/label.tsx | 26 + components/ui/multiselect.tsx | 486 ++++ components/ui/popover.tsx | 33 + components/ui/radio-group.tsx | 44 + components/ui/select.tsx | 163 ++ components/ui/textarea.tsx | 23 + package-lock.json | 3025 +++++++++++++++++++++---- package.json | 22 +- 30 files changed, 5031 insertions(+), 394 deletions(-) create mode 100644 components/inputs/Checkbox.tsx create mode 100644 components/inputs/Visualizer.tsx create mode 100644 components/inputs/date-time.tsx create mode 100644 components/inputs/date.tsx create mode 100644 components/inputs/email.tsx create mode 100644 components/inputs/fileUpload.tsx create mode 100644 components/inputs/multiSelectItem.tsx create mode 100644 components/inputs/numberfield.tsx create mode 100644 components/inputs/radioItems.tsx create mode 100644 components/inputs/selectIItem.tsx create mode 100644 components/inputs/telephone.tsx create mode 100644 components/inputs/text.tsx create mode 100644 components/inputs/textAreaField.tsx create mode 100644 components/inputs/time.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/calendar.tsx create mode 100644 components/ui/checkbox.tsx create mode 100644 components/ui/command.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/dropdown-menu.tsx create mode 100644 components/ui/form.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/multiselect.tsx create mode 100644 components/ui/popover.tsx create mode 100644 components/ui/radio-group.tsx create mode 100644 components/ui/select.tsx create mode 100644 components/ui/textarea.tsx diff --git a/components/inputs/Checkbox.tsx b/components/inputs/Checkbox.tsx new file mode 100644 index 00000000..b4feeeb1 --- /dev/null +++ b/components/inputs/Checkbox.tsx @@ -0,0 +1,38 @@ +'use client'; + +import { Checkbox } from '~/components/ui/checkbox'; + +import { Label } from '../ui/label'; +import { type GenericProps } from './radioItems'; + +interface CheckboxProps extends GenericProps { + defaultChecked?: boolean; + onChange?: (value: boolean) => void; + value?: boolean; +} +const CheckboxGeneric = ({ ...props }: CheckboxProps) => { + return ( +
+ + {props.required && *} +
+ + +
+

+ {props.errorMsg} +

+
+ ); +}; + +export default CheckboxGeneric; diff --git a/components/inputs/Visualizer.tsx b/components/inputs/Visualizer.tsx new file mode 100644 index 00000000..fc5321aa --- /dev/null +++ b/components/inputs/Visualizer.tsx @@ -0,0 +1,236 @@ +'use client'; + +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from 'react-hook-form'; +import * as z from 'zod'; + +import { Button } from '../ui/button'; +import { + Form, + FormControl, + FormField, + FormItem, + FormMessage, +} from '../ui/form'; +import CheckboxGeneric from './Checkbox'; +import DateField from './date'; +import DateTimeField from './date-time'; +import EmailField from './email'; +import FileUpload from './fileUpload'; +import MultiSelectDropdown from './multiSelectItem'; +import NumberField from './numberfield'; +import RadioGeneric from './radioItems'; +import SelectDropdown from './selectIItem'; +import PhoneField from './telephone'; +import TextField from './text'; +import TextAreaGeneric from './textAreaField'; +import TimeField from './time'; + +export default function Visualizer() { + const schema = z.object({ + email: z.string().email('Invalid email address'), + name: z.string().min(3, 'Name must be at least 3 characters long'), + phone: z.coerce.number(), + number: z.coerce.number(), + textarea: z.string(), + file: z.any(), + checkbox: z.boolean(), + dateTime: z.string(), + date: z.string(), + time: z.string(), + select: z.string(), + radio: z.string(), + multiselect: z.string().array(), + }); + const form = useForm>({ + resolver: zodResolver(schema), + }); + + const items = ['item1', 'item2', 'item3', 'item4', 'item5']; + + const onSubmit = (values: z.infer) => { + try { + console.log('Form data:', values); + } catch (error) { + console.error(error); + } + }; + + return ( +
+ + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + + + + ); +} diff --git a/components/inputs/date-time.tsx b/components/inputs/date-time.tsx new file mode 100644 index 00000000..518197a1 --- /dev/null +++ b/components/inputs/date-time.tsx @@ -0,0 +1,32 @@ +'use client'; +import React, { forwardRef } from 'react'; +import { FaRegCalendarAlt } from 'react-icons/fa'; + +import { Input, type InputProps } from '../ui/input'; + +const DateTimeField = forwardRef( + ( + { label = 'Date & Time', placeholder = 'Enter Date & Time', ...props }, + ref + ) => { + return ( + { + props.onChange?.({ + target: { value: event.target.value + ':00Z' }, + } as React.ChangeEvent); + }} + /> + ); + } +); +DateTimeField.displayName = 'DateTimeField'; + +export default DateTimeField; diff --git a/components/inputs/date.tsx b/components/inputs/date.tsx new file mode 100644 index 00000000..e509f011 --- /dev/null +++ b/components/inputs/date.tsx @@ -0,0 +1,31 @@ +'use client'; +import { MdOutlineDateRange } from 'react-icons/md'; +import { forwardRef } from 'react'; + +import { Input, type InputProps } from '../ui/input'; + +const DateField = forwardRef(function DateField( + { + label = 'Date', + placeholder = 'Enter your Date', + LeftChild = MdOutlineDateRange, + ...props + }: InputProps, + ref +) { + return ( + + ); +}); + +DateField.displayName = 'DateField'; + +export default DateField; diff --git a/components/inputs/email.tsx b/components/inputs/email.tsx new file mode 100644 index 00000000..360abbb7 --- /dev/null +++ b/components/inputs/email.tsx @@ -0,0 +1,30 @@ +'use client'; +import { MdOutlineEmail } from 'react-icons/md'; +import { forwardRef } from 'react'; + +import { Input, type InputProps } from '../ui/input'; + +const EmailField = forwardRef(function EmailField( + { + label = 'Email', + placeholder = 'Enter your Email', + LeftChild = MdOutlineEmail, + ...props + }: InputProps, + ref +) { + return ( + + ); +}); + +EmailField.displayName = 'EmailField'; + +export default EmailField; diff --git a/components/inputs/fileUpload.tsx b/components/inputs/fileUpload.tsx new file mode 100644 index 00000000..f1f22d54 --- /dev/null +++ b/components/inputs/fileUpload.tsx @@ -0,0 +1,21 @@ +'use client'; +import React, { forwardRef } from 'react'; + +import { Input, type InputProps } from '~/components/ui/input'; + +const FileUpload = forwardRef( + ({ label = 'Upload File', ...props }, ref) => { + return ( + + ); + } +); +FileUpload.displayName = 'FileUpload'; +export default FileUpload; diff --git a/components/inputs/multiSelectItem.tsx b/components/inputs/multiSelectItem.tsx new file mode 100644 index 00000000..9a5516e5 --- /dev/null +++ b/components/inputs/multiSelectItem.tsx @@ -0,0 +1,48 @@ +import { forwardRef, type ForwardRefExoticComponent } from 'react'; + +import { Label } from '../ui/label'; +import MultipleSelector, { + type MultipleSelectorProps, + type MultipleSelectorRef, +} from '../ui/multiselect'; +import { type GenericProps } from './radioItems'; + +interface ListProps extends GenericProps, MultipleSelectorProps { + items: string[]; +} + +const MultiSelectDropdown: ForwardRefExoticComponent = forwardRef< + MultipleSelectorRef, + ListProps +>((props, ref) => { + return ( +
+ + {props.required && *} + {props.description && ( +

+ {props.description} +

+ )} + + no results found. +

+ } + /> +

+ {props.errorMsg} +

+
+ ); +}); + +MultiSelectDropdown.displayName = 'MultiSelectDropdown'; +export default MultiSelectDropdown; diff --git a/components/inputs/numberfield.tsx b/components/inputs/numberfield.tsx new file mode 100644 index 00000000..562763bc --- /dev/null +++ b/components/inputs/numberfield.tsx @@ -0,0 +1,29 @@ +'use client'; +import React, { forwardRef } from 'react'; +import { AiOutlineNumber } from 'react-icons/ai'; + +import { Input, type InputProps } from '../ui/input'; + +const NumberField = forwardRef( + ({ label = 'Number', placeholder = 'Enter a Number', ...props }, ref) => { + const handleInputChange = (event: React.ChangeEvent) => { + const inputValue = event.target.value.replace(/\D/g, ''); + event.target.value = inputValue; + }; + + return ( + + ); + } +); +NumberField.displayName = 'NumberField'; + +export default NumberField; diff --git a/components/inputs/radioItems.tsx b/components/inputs/radioItems.tsx new file mode 100644 index 00000000..310617c7 --- /dev/null +++ b/components/inputs/radioItems.tsx @@ -0,0 +1,50 @@ +'use client'; + +import { Label } from '../ui/label'; +import { RadioGroup, RadioGroupItem } from '../ui/radio-group'; + +export interface GenericProps { + name?: string; + label?: string; + description?: string; + required?: boolean; + errorMsg?: string; + disabled?: boolean; + inputClassName?: string; + className?: string; +} +interface ListProps extends GenericProps { + items: string[]; + onChange?: (value: string) => void; + value?: string; +} + +const RadioGeneric = ({ items, ...props }: ListProps) => { + return ( +
+ + {props.required && *} + + {items.map((item) => ( +
+ + +
+ ))} +
+

+ {props.errorMsg} +

+
+ ); +}; + +RadioGeneric.displayName = 'RadioGeneric'; + +export default RadioGeneric; diff --git a/components/inputs/selectIItem.tsx b/components/inputs/selectIItem.tsx new file mode 100644 index 00000000..c03989e9 --- /dev/null +++ b/components/inputs/selectIItem.tsx @@ -0,0 +1,55 @@ +'use client'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '~/components/ui/select'; + +import { Label } from '../ui/label'; +import { type GenericProps } from './radioItems'; + +interface ListProps extends GenericProps { + items: string[]; + onChange?: (value: string) => void; + value?: string; +} + +const SelectDropdown = ({ items, ...props }: ListProps) => { + return ( +
+ + {props.required && *} + {props.description && ( +

+ {props.description} +

+ )} + +

+ {props.errorMsg} +

+
+ ); +}; + +SelectDropdown.displayName = 'SelectDropdown'; + +export default SelectDropdown; diff --git a/components/inputs/telephone.tsx b/components/inputs/telephone.tsx new file mode 100644 index 00000000..acb5931b --- /dev/null +++ b/components/inputs/telephone.tsx @@ -0,0 +1,32 @@ +'use client'; +import React, { forwardRef } from 'react'; +import { AiOutlinePhone } from 'react-icons/ai'; + +import { Input, type InputProps } from '../ui/input'; + +const PhoneField = forwardRef( + ({ label = 'Phone', placeholder = 'Enter your Number', ...props }, ref) => { + const handleInputChange = (event: React.ChangeEvent) => { + const inputValue = event.target.value.replace(/\D/g, ''); + const truncatedValue = inputValue.slice(0, 10); + event.target.value = truncatedValue; + props.onChange?.(event); + }; + + return ( + + ); + } +); +PhoneField.displayName = 'PhoneField'; + +export default PhoneField; diff --git a/components/inputs/text.tsx b/components/inputs/text.tsx new file mode 100644 index 00000000..53edf035 --- /dev/null +++ b/components/inputs/text.tsx @@ -0,0 +1,31 @@ +'use client'; + +import { PiTextT } from 'react-icons/pi'; +import { forwardRef } from 'react'; + +import { Input, type InputProps } from '../ui/input'; + +const TextField = forwardRef(function TextField( + { + label = 'Text', + placeholder = 'Enter your text', + LeftChild = PiTextT, + ...props + }, + ref +) { + return ( + + ); +}); + +TextField.displayName = 'TextField'; + +export default TextField; // Export the component diff --git a/components/inputs/textAreaField.tsx b/components/inputs/textAreaField.tsx new file mode 100644 index 00000000..e2e1fae5 --- /dev/null +++ b/components/inputs/textAreaField.tsx @@ -0,0 +1,46 @@ +'use client'; + +import React from 'react'; + +import { Label } from '../ui/label'; +import { type GenericProps } from './radioItems'; +import { Textarea } from '../ui/textarea'; + +interface TextFieldProps extends GenericProps { + placeholder?: string; +} +const TextAreaGeneric = React.forwardRef( + ( + { + placeholder = 'Enter text', + label = 'TextArea', + ...props + }: TextFieldProps, + ref + ) => { + return ( +
+ + {props.required && *} + {props.description && ( +

+ {props.description} +

+ )} +