← Components/Overlays

DrawerPanel

drawerpanel-1779378412789.tsx
'use client'
import { useState, useEffect } from 'react'

const notifications = [
  { id: 1, type: 'šŸŽ‰', title: 'New component published', time: '2m ago', read: false },
  { id: 2, type: 'šŸ’°', title: 'Pro subscription active', time: '1h ago', read: false },
  { id: 3, type: '⚔', title: 'Wave 4 generation complete', time: '3h ago', read: true },
  { id: 4, type: 'šŸ‘„', title: '142 new users joined', time: '1d ago', read: true },
  { id: 5, type: 'šŸ“ˆ', title: 'Revenue milestone: €10k', time: '2d ago', read: true },
]

export default function DrawerPanel() {
  const [open, setOpen] = useState(false)
  const unread = notifications.filter(n => !n.read).length

  useEffect(() => {
    if (open) document.body.style.overflow = 'hidden'
    else document.body.style.overflow = ''
    return () => { document.body.style.overflow = '' }
  }, [open])

  return (
    <div style={{ padding: 48, background: '#0A0A0A', display: 'flex', justifyContent: 'center', minHeight: 300 }}>
      <button onClick={() => setOpen(true)} style={{
        background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.1)',
        color: '#F5F5F0', padding: '12px 20px', borderRadius: 8, cursor: 'pointer',
        display: 'flex', alignItems: 'center', gap: 10, fontSize: 14, fontWeight: 500, position: 'relative',
      }}>
        šŸ”” Notifications
        {unread > 0 && (
          <span style={{ background: '#ef4444', color: '#fff', fontSize: 11, fontWeight: 700, padding: '1px 6px', borderRadius: 10, position: 'absolute', top: -4, right: -4 }}>{unread}</span>
        )}
      </button>

      {/* Backdrop */}
      {open && (
        <div onClick={() => setOpen(false)} style={{
          position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.6)',
          backdropFilter: 'blur(4px)', zIndex: 100,
        }} />
      )}

      {/* Drawer */}
      <div style={{
        position: 'fixed', top: 0, right: 0, bottom: 0, width: 360,
        background: '#111', borderLeft: '1px solid rgba(255,255,255,0.08)',
        zIndex: 101, transform: open ? 'translateX(0)' : 'translateX(100%)',
        transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ padding: '20px 24px', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <div style={{ color: '#F5F5F0', fontWeight: 700, fontSize: 16 }}>Notifications</div>
            <div style={{ color: '#555', fontSize: 13, marginTop: 2 }}>{unread} unread</div>
          </div>
          <button onClick={() => setOpen(false)} style={{ background: 'rgba(255,255,255,0.06)', border: 'none', color: '#aaa', width: 32, height: 32, borderRadius: 8, cursor: 'pointer', fontSize: 16 }}>āœ•</button>
        </div>

        <div style={{ flex: 1, overflowY: 'auto', padding: '8px 0' }}>
          {notifications.map(n => (
            <div key={n.id} style={{
              padding: '14px 24px', borderBottom: '1px solid rgba(255,255,255,0.04)',
              background: n.read ? 'transparent' : 'rgba(201,168,76,0.04)',
              display: 'flex', gap: 12, alignItems: 'flex-start',
            }}>
              <span style={{ fontSize: 20, flexShrink: 0 }}>{n.type}</span>
              <div style={{ flex: 1 }}>
                <div style={{ color: n.read ? '#aaa' : '#F5F5F0', fontSize: 14, fontWeight: n.read ? 400 : 500 }}>{n.title}</div>
                <div style={{ color: '#555', fontSize: 12, marginTop: 2 }}>{n.time}</div>
              </div>
              {!n.read && <div style={{ width: 6, height: 6, borderRadius: '50%', background: '#C9A84C', flexShrink: 0, marginTop: 4 }} />}
            </div>
          ))}
        </div>

        <div style={{ padding: '16px 24px', borderTop: '1px solid rgba(255,255,255,0.06)' }}>
          <button style={{ width: '100%', background: 'rgba(255,255,255,0.06)', border: 'none', color: '#aaa', padding: '10px', borderRadius: 8, cursor: 'pointer', fontSize: 14 }}>
            Mark all as read
          </button>
        </div>
      </div>
    </div>
  )
}

Component info

CategoryOverlays
Frameworkreact
TierFREE
Views1
Copies0

About

Slide-in drawer panel from right with backdrop blur and close on outside click

More from Overlays

'use client';

import { useState } from 'react';

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

const BottomSheet = ({ isOpen, onClose }: BottomSheetProps) => {
  const [isDragging, setIsDragging] = useState(false);
  cons
BottomSheet
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