JSPM

blocx-drawer

1.3.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q38596F
  • License MIT

A modern, feature-rich drawer component for React/Next.js with swipe gestures, 3-mode system (normal/expanded/minimized), focus management, smooth animations, and multiple styling options (CSS/Tailwind/SCSS)

Package Exports

  • blocx-drawer
  • blocx-drawer/dist/index.esm.js
  • blocx-drawer/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (blocx-drawer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Blocx Drawer

A modern, feature-rich drawer component for React/Next.js applications. Built with TypeScript and designed for mobile-first experiences.

✨ Features

  • 🎯 4-Direction Support: Left, right, top, bottom drawers
  • 📱 Mobile Optimized: Touch gestures, swipe to close, proper iOS handling
  • 🎨 3-Mode System: Normal, expanded, and minimized states (top/bottom only)
  • Accessibility: Focus trapping, ARIA support, keyboard navigation
  • 🎭 Smooth Animations: GPU-accelerated, configurable transitions
  • 📏 5 Size Options: s, m, l, xl, fullscreen
  • 🎛️ Highly Configurable: Backdrop, dismissible, swipe gestures
  • 📦 Zero Dependencies: Self-contained, no external dependencies
  • 🔧 TypeScript: Full type safety and IntelliSense support

📦 Installation

npm install blocx-drawer
npx blocx-setup

After installation, run npx blocx-setup to choose your preferred styling option:

🎨 Blocx Drawer Setup
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Choose your preferred styling option:

1. 📝 CSS (Default - Recommended)
2. 🎨 Tailwind CSS  
3. ⚙️  SCSS with Design Tokens

Enter your choice (1-3) or press Enter for default CSS:

🎨 Styling Options

Blocx Drawer provides three styling options to fit your project's needs:

Self-contained CSS with CSS custom properties for easy theming.

// Import the component (CSS is automatically included)
import { Drawer } from 'blocx-drawer';

Option 2: Tailwind CSS

If you're using Tailwind CSS, import the Tailwind-specific styles:

import { Drawer } from 'blocx-drawer';
// Import Tailwind styles instead of default CSS
import 'blocx-drawer/styles/blocx-drawer-tailwind.css';

Option 3: SCSS with Design Tokens

For projects using SCSS, import the SCSS version with design tokens:

import { Drawer } from 'blocx-drawer';
// Import SCSS version (requires SCSS compiler)
import 'blocx-drawer/styles/blocx-drawer.scss';

🚀 Quick Start

import React, { useState } from 'react';
import { 
  Drawer, 
  DrawerHeader, 
  DrawerBody, 
  DrawerFooter,
  DrawerTitle,
  DrawerDescription 
} from 'blocx-drawer';

function App() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div>
      <button onClick={() => setIsOpen(true)}>
        Open Drawer
      </button>

      <Drawer
        open={isOpen}
        onClose={() => setIsOpen(false)}
        side="right"
        size="m"
      >
        <DrawerHeader>
          <DrawerTitle>Settings</DrawerTitle>
          <DrawerDescription>
            Manage your account settings and preferences
          </DrawerDescription>
        </DrawerHeader>

        <DrawerBody>
          <p>Drawer content goes here...</p>
        </DrawerBody>

        <DrawerFooter>
          <button onClick={() => setIsOpen(false)}>
            Close
          </button>
        </DrawerFooter>
      </Drawer>
    </div>
  );
}

🎛️ Props Reference

Drawer Props

Prop Type Default Description
open boolean - Required. Controls drawer visibility
onClose () => void - Required. Called when drawer should close
side 'left' | 'right' | 'top' | 'bottom' 'left' Drawer position
size 's' | 'm' | 'l' | 'xl' | 'fullscreen' 'm' Drawer size
dismissible boolean true Allow closing with ESC key or backdrop click
swipeToClose boolean true Enable swipe gestures to close
backdrop boolean true Show backdrop overlay
trapFocus boolean true Trap focus within drawer
expandMode boolean false Enable expand to fullscreen (top/bottom only)
minimizeMode boolean false Enable minimize to header only (top/bottom only)
bottomOffset number 0 Bottom offset in pixels (useful for nav bars)
onMinimize () => void - Called when drawer is minimized
onRestore () => void - Called when drawer is restored from minimized

Component Props

All sub-components (DrawerHeader, DrawerBody, DrawerFooter, DrawerTitle, DrawerDescription) accept standard HTML props for their respective elements.

DrawerBody

Prop Type Default Description
scrollable boolean true Enable internal scrolling

📐 Size Guide

Size Left/Right Width Top/Bottom Height
s 78vw (max 340px) 55vh
m 86vw (max 420px) 65vh
l 92vw (max 520px) 75vh
xl 96vw (max 680px) 88vh
fullscreen 100vw 100vh

🎯 Advanced Examples

Bottom Drawer with 3-Mode System

<Drawer
  open={isOpen}
  onClose={() => setIsOpen(false)}
  side="bottom"
  size="m"
  expandMode={true}
  minimizeMode={true}
  onMinimize={() => console.log('Minimized!')}
  onRestore={() => console.log('Restored!')}
>
  <DrawerHeader>
    <DrawerTitle>Music Player</DrawerTitle>
  </DrawerHeader>
  
  <DrawerBody>
    {/* This drawer can be:
        - Normal: Default size
        - Expanded: Drag up to expand to nearly fullscreen
        - Minimized: Drag down to minimize to header only */}
    <div>Player controls and playlist...</div>
  </DrawerBody>
</Drawer>

Non-scrollable Content

<Drawer open={isOpen} onClose={() => setIsOpen(false)}>
  <DrawerHeader>
    <DrawerTitle>Image Viewer</DrawerTitle>
  </DrawerHeader>
  
  <DrawerBody scrollable={false}>
    {/* Content here won't scroll - all gestures control the drawer */}
    <img src="large-image.jpg" alt="Full size image" />
  </DrawerBody>
</Drawer>

Custom Styling

<Drawer
  open={isOpen}
  onClose={() => setIsOpen(false)}
  className="custom-drawer"
  panelClassName="custom-panel"
  backdropClassName="custom-backdrop"
>
  <DrawerHeader>
    <DrawerTitle as="h1">Custom Styled Drawer</DrawerTitle>
  </DrawerHeader>
  
  <DrawerBody>
    <p>Apply your own CSS classes for custom styling</p>
  </DrawerBody>
</Drawer>

🎨 Styling

The component includes comprehensive CSS with CSS custom properties for easy theming:

/* Example: Dark mode customization */
.custom-drawer {
  --panel-bg: #1f2937;
  --panel-color: #f9fafb;
  --panel-border: 1px solid rgba(255, 255, 255, 0.2);
  --backdrop-bg: rgba(0, 0, 0, 0.75);
}

📱 Mobile Behavior

  • Touch Gestures: Natural swipe gestures on mobile devices
  • iOS Safari: Proper viewport handling and safe area support
  • Overscroll Prevention: Prevents page bounce while allowing drawer scrolling
  • Focus Management: Proper focus handling for screen readers
  • Keyboard Navigation: Full keyboard support with Tab trapping

🎯 Gesture System

Left/Right Drawers

  • Swipe towards edge: Close drawer
  • Swipe from edge: Elastic resistance effect
  • Velocity detection: Fast swipes trigger immediate close

Top/Bottom Drawers (3-Mode System)

  • Normal Mode:

    • Drag down (bottom) / up (top): Close or minimize
    • Drag up (bottom) / down (top): Expand (if enabled)
  • Expanded Mode:

    • Drag down (bottom) / up (top): Shrink to normal or close
  • Minimized Mode:

    • Drag up (bottom) / down (top): Restore to normal
    • Drag down (bottom) / up (top): Close

⚡ Performance

  • GPU Acceleration: Hardware-accelerated animations
  • Containment: CSS containment for optimal rendering
  • Lazy Portal: Portal created only when needed
  • Event Optimization: Efficient touch/pointer event handling
  • Bundle Size: ~15KB gzipped (component + styles)

🔧 Browser Support

  • Chrome/Edge: ✅ Full support
  • Safari: ✅ Full support (including iOS)
  • Firefox: ✅ Full support
  • IE11: ❌ Not supported (uses modern CSS features)

📄 License

MIT © Alex Trick (https://mrtrick.me)

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.