Sheet 5

PreviousNext

A sheet component with form validation and structured user registration

Docs
shadcn-studiocomponent

Preview

Loading preview…
registry/new-york/components/sheet/sheet-05.tsx
'use client'

import { CheckCheckIcon } from 'lucide-react'

import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import { z } from 'zod'

import { Alert, AlertTitle } from '@/registry/new-york/ui/alert'
import { Button } from '@/registry/new-york/ui/button'
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/registry/new-york/ui/form'
import { Input } from '@/registry/new-york/ui/input'
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger
} from '@/registry/new-york/ui/sheet'

const SheetWithFormDemo = () => {
  const FormSchema = z.object({
    firstName: z.string().min(1, 'First name is required').min(2, 'First name must be at least 2 characters'),
    lastName: z.string().min(1, 'Last name is required').min(2, 'Last name must be at least 2 characters'),
    email: z.string().min(1, 'Email is required').email({ message: 'Please enter a valid email address.' }),
    mobileNumber: z
      .number({ required_error: 'Mobile number is required', invalid_type_error: 'Please enter a valid number' })
      .int('Mobile number must be a whole number')
      .positive('Mobile number must be positive')
      .refine(val => val.toString().length === 10, 'Mobile number must be exactly 10 digits'),
    password: z.string().min(1, 'Password is required').min(8, 'Password must be at least 8 characters')
  })

  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      firstName: '',
      lastName: '',
      email: '',
      mobileNumber: undefined,
      password: ''
    }
  })

  const onSubmit = () => {
    toast.custom(() => (
      <Alert className='border-green-600 text-green-600 dark:border-green-400 dark:text-green-400'>
        <CheckCheckIcon />
        <AlertTitle>Account created successfully!</AlertTitle>
      </Alert>
    ))
  }

  return (
    <Sheet>
      <SheetTrigger asChild>
        <Button variant='outline'>Sign Up</Button>
      </SheetTrigger>
      <SheetContent>
        <SheetHeader>
          <SheetTitle className='text-center text-xl font-bold'>Sign Up</SheetTitle>
        </SheetHeader>
        <Form {...form}>
          <form onSubmit={form.handleSubmit(onSubmit)} className='w-full'>
            <div className='space-y-4 p-4 pt-0'>
              <FormField
                control={form.control}
                name='firstName'
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>First Name</FormLabel>
                    <FormControl>
                      <Input placeholder='First name' {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name='lastName'
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Last Name</FormLabel>
                    <FormControl>
                      <Input placeholder='Last name' {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name='email'
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Email</FormLabel>
                    <FormControl>
                      <Input placeholder='Email address' {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name='mobileNumber'
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Mobile Number</FormLabel>
                    <FormControl>
                      <Input
                        type='tel'
                        placeholder='8585858585'
                        value={field.value ? field.value.toString() : ''}
                        onChange={e => {
                          const value = e.target.value.replace(/[^\d]/g, '')

                          const limitedValue = value.slice(0, 10)

                          const numValue = limitedValue === '' ? undefined : parseInt(limitedValue, 10)

                          field.onChange(numValue)
                        }}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name='password'
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Password</FormLabel>
                    <FormControl>
                      <Input type='password' placeholder='Password' {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>
            <SheetFooter>
              <Button type='submit'>Create Account</Button>

              <SheetClose asChild>
                <Button variant='outline'>Close</Button>
              </SheetClose>
            </SheetFooter>
          </form>
        </Form>
      </SheetContent>
    </Sheet>
  )
}

export default SheetWithFormDemo

Installation

npx shadcn@latest add @shadcn-studio/sheet-05

Usage

import { Sheet05 } from "@/components/sheet-05"
<Sheet05 />