← Components/Overlays

BottomSheet

bottomsheet-1779361465732.tsx
'use client';

import { useState } from 'react';

interface BottomSheetProps {
  isOpen: boolean;
  onClose: () => void;
}

const BottomSheet = ({ isOpen, onClose }: BottomSheetProps) => {
  const [isDragging, setIsDragging] = useState(false);
  const [offset, setOffset] = useState(0);

  const handleDrag = (e: React.TouchEvent<HTMLDivElement> | React.MouseEvent<HTMLDivElement>) => {
    if (e.type === 'touchmove') {
      const touch = e.touches[0];
      setOffset(touch.clientY);
    } else if (e.type === 'mousemove') {
      setOffset(e.clientY);
    }
  };

  const handleDragEnd = () => {
    if (offset > window.innerHeight / 2) {
      onClose();
    }
    setIsDragging(false);
  };

  return (
    <>
      {isOpen && (
        <div
          className="fixed top-0 left-0 z-50 w-full h-full bg-zinc-900 bg-opacity-50"
          onClick={onClose}
        />
      )}
      <div
        className={`fixed bottom-0 w-full max-h-screen overflow-hidden bg-zinc-950 transition-transform duration-300 ease-out ${
          isOpen ? 'translate-y-0' : 'translate-y-full'
        }`}
        style={{
          boxShadow: '0px -10px 20px rgba(0, 0, 0, 0.2)',
          WebkitBoxShadow: '0px -10px 20px rgba(0, 0, 0, 0.2)',
        }}
      >
        <div
          className="h-6 w-full bg-zinc-950 cursor-pointer"
          onTouchStart={() => setIsDragging(true)}
          onTouchMove={(e) => handleDrag(e)}
          onTouchEnd={handleDragEnd}
          onMouseDown={() => setIsDragging(true)}
          onMouseMove={(e) => handleDrag(e)}
          onMouseUp={handleDragEnd}
        >
          <div className="h-1 w-20 mx-auto bg-c9a84c rounded-full" />
        </div>
        <div className="p-4">
          <h2 className="text-lg font-bold text-c9a84c mb-2">Bottom Sheet Title</h2>
          <p className="text-sm text-zinc-400">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet nulla auctor, vestibulum magna sed, convallis ex.
          </p>
        </div>
      </div>
    </>
  );
};

export default BottomSheet;

Component info

CategoryOverlays
Frameworkreact
TierFREE
Views0
Copies0

About

Mobile-style bottom sheet drawer

More from Overlays

import React, { useState } from 'react';
import './SlideDrawer.css';

interface SlideDrawerProps {
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
}

const SlideDrawer: React.FC<SlideDrawerProps> = ({ isOpen, onClose, children 
SlideDrawer
Overlays
import React, { useState } from 'react';

interface ContextMenuProps {
  children: React.ReactNode;
}

const ContextMenu: React.FC<ContextMenuProps> = ({ children }) => {
  const [showMenu, setShowMenu] = useState(false);
  const [x, setX] = useState
ContextMenu
Overlays
'use client';

import React, { useState } from 'react';

interface AlertDialogProps {
  isOpen: boolean;
  onClose: () => void;
  onConfirm: () => void;
  title: string;
  description: string;
}

const AlertDialog: React.FC<AlertDialogProps> = ({
  i
AlertDialog
Overlays
'use client';

import { useState, useEffect } from 'react';

interface Command {
  id: number;
  title: string;
  description: string;
}

const commands: Command[] = [
  { id: 1, title: 'New File', description: 'Create a new file' },
  { id: 2, title
CommandPalette
Overlays