Morph Surface

Morphing surface with smooth animations and customizable dimensions

Installation

pnpm dlx shadcn@latest add "https://vritti.thesatyajit.com/r/morph-surface"

Dependencies

pnpm add motion

Examples

Controlled

"use client"

import { useState } from "react"

import { MorphSurface } from "@/components/vritti/morph-surface"

export function MorphSurfaceControlledExample() {
  const [isControlledOpen, setIsControlledOpen] = useState(false)

  const handleSubmit = async (formData: FormData) => {
    const message = formData.get("message") as string
    console.log("Submitted message:", message)
    await new Promise((resolve) => setTimeout(resolve, 500))
  }

  return (
    <div className="flex flex-col items-center gap-4 min-h-[300px] p-8">
      <button
        type="button"
        onClick={() => setIsControlledOpen(!isControlledOpen)}
        className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors"
      >
        {isControlledOpen ? "Close" : "Open"} Morph Surface
      </button>
      <MorphSurface
        isOpen={isControlledOpen}
        onOpenChange={setIsControlledOpen}
        triggerLabel="Controlled"
        placeholder="This surface is controlled externally..."
        onSubmit={handleSubmit}
      />
    </div>
  )
}

Custom Dimensions

"use client"

import { MorphSurface } from "@/components/vritti/morph-surface"

export function MorphSurfaceCustomDimensionsExample() {
  return (
    <div className="flex justify-center items-center min-h-[300px] p-8">
      <MorphSurface
        collapsedWidth="auto"
        collapsedHeight={48}
        expandedWidth={400}
        expandedHeight={250}
        triggerLabel="Custom Size"
        placeholder="This surface is larger..."
      />
    </div>
  )
}

Custom Icon

"use client"

import { HelpCircle } from "lucide-react"

import { MorphSurface } from "@/components/vritti/morph-surface"

export function MorphSurfaceCustomIconExample() {
  const handleSubmit = async (formData: FormData) => {
    const message = formData.get("message") as string
    console.log("Submitted message:", message)
    await new Promise((resolve) => setTimeout(resolve, 500))
  }

  return (
    <div className="flex justify-center items-center min-h-[300px] p-8">
      <MorphSurface
        triggerLabel="Help"
        triggerIcon={<HelpCircle className="w-4 h-4" />}
        placeholder="How can we help you?"
        onSubmit={handleSubmit}
      />
    </div>
  )
}

Custom Labels

"use client"

import { MorphSurface } from "@/components/vritti/morph-surface"

export function MorphSurfaceCustomLabelsExample() {
  const handleSubmit = async (formData: FormData) => {
    const message = formData.get("message") as string
    console.log("Submitted message:", message)
    await new Promise((resolve) => setTimeout(resolve, 500))
  }

  return (
    <div className="flex justify-center items-center min-h-[300px] p-8">
      <MorphSurface
        triggerLabel="Send Feedback"
        placeholder="Share your thoughts..."
        onSubmit={handleSubmit}
        onSuccess={() => {
          console.log("Feedback submitted successfully!")
        }}
      />
    </div>
  )
}

Slow Animation

"use client"

import { MorphSurface } from "@/components/vritti/morph-surface"

export function MorphSurfaceSlowAnimationExample() {
  return (
    <div className="flex justify-center items-center min-h-[300px] p-8">
      <MorphSurface
        animationSpeed={2}
        triggerLabel="Slow Animation"
        placeholder="Animations are slower..."
      />
    </div>
  )
}