npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2026 – Pkg Stats / Ryan Hefner

seat-picker

v0.0.13

Published

> πŸ“š [Full Documentation & Live Demo](https://seat-picker-docs.vercel.app/)

Downloads

621

Readme

Seat Picker

πŸ“š Full Documentation & Live Demo

A flexible and customizable seating arrangement GUI component for React applications. This library provides an interactive canvas for creating and managing seat layouts, perfect for event venues, theaters, restaurants, and more.


✨ Features

Canvas Editing & Layout

  • Interactive Canvas: Drag, drop, and arrange seats, shapes, and text.
  • Multi-Select & Grouping: Select multiple objects to move, align, or edit as a group.
  • Grid Arrangement: Instantly arrange selected seats into a grid with adjustable rows, columns, and spacing.
  • Customizable Properties: Edit seat number, color, size, shape, and more from the sidebar.
  • Shape & Text Tools: Add rectangles, circles, and text labels to your layout.
  • Undo/Redo: Easily revert or reapply changes with keyboard shortcuts or toolbar buttons.
  • Delete, Copy, Cut, Paste: Full clipboard support for objects and groups.
  • Lock/Unlock Selection: Prevent accidental changes by locking selected objects.
  • Zoom & Pan: Zoom in/out (80%–120%) and pan to focus on any part of your layout.
  • Snap to Grid: Enable smart snapping for precise alignment.
  • Background Image: Upload a background image (e.g., venue map) and adjust its opacity.

Seat & Zone Management

  • Seat Attributes: Assign seat numbers, categories, prices, and status (available, sold, etc.).
  • Zone Management: Group seats into zones for pricing or sectioning.
  • Bulk Editing: Edit properties for multiple selected seats at once.

Export, Import, and Sharing

  • Export Layout: Save your seat map as a JSON file for backup or sharing.
  • Import Layout: Load a previously saved layout to continue editing.
  • Download: Download the current layout instantly from the toolbar.

Customer-Facing Features

  • Read-Only Viewer: Customers can view seat layouts without editing.
  • Drag & Drop Upload: Customers can upload a seat layout JSON to view and interact.
  • Seat Details Modal: Clicking a seat opens a modal with all details and purchase options.
  • Purchase Integration: Hook into seat actions (buy, reserve, etc.) with your own logic.
  • No Edit Mode: Customers cannot move, edit, or delete seats.

Developer Experience

  • TypeScript Support: Full typings for all components and props.
  • Customizable Styling: Easily override styles with your own CSS or Tailwind classes.
  • Composable Components: Use only what you need (e.g., just the renderer for read-only views).

πŸš€ Getting Started

Installation

npm install seat-picker
# or
yarn add seat-picker

πŸ› οΈ Usage (Admin/Editor)

import { SeatPicker } from 'seat-picker';

function App() {
  const handleChange = (layout) => {
    console.log('Layout updated:', layout);
  };

  const handleSave = (layout) => {
    console.log('Saving layout:', layout);
    // Save to your backend or file system
  };

  return (
    <SeatPicker
      onChange={handleChange}
      onSave={handleSave}
      style={{
        width: 800,
        height: 600,
        backgroundColor: '#f8fafc',
        showSeatNumbers: true,
        seatNumberStyle: {
          fontSize: 14,
          fill: '#222',
          fontWeight: 'bold',
        },
        seatStyle: {
          fill: 'transparent',
          stroke: 'black',
          strokeWidth: 1,
          radius: 10,
        },
      }}
      labels={{
        buyButton: 'Buy Seat',
        cancelButton: 'Cancel',
        seatNumber: 'Seat Number',
        category: 'Category',
        price: 'Price',
        status: 'Status',
      }}
    />
  );
}

Toolbar Actions

  • Open/Save/Download: Import/export layouts as JSON.
  • Select/Move: Use the pointer tool to select and move objects.
  • Add Seat/Shape/Text: Quickly add new elements to your layout.
  • Grid Tool: Arrange selected seats in a grid.
  • Undo/Redo: Step backward or forward through your changes.
  • Clipboard: Cut, copy, paste, and delete selected objects.
  • Zoom: Zoom in/out (80%–120%) and keep the layout centered.
  • Lock/Unlock: Lock selection to prevent changes.

Sidebar Actions

  • No Selection: See helpful tips and keyboard shortcuts.
  • Single Selection: Edit all properties of the selected object.
  • Multiple Selection: Edit properties in bulk and use the grid arrangement tool.

Keyboard Shortcuts

  • Ctrl+Z: Undo
  • Ctrl+Y: Redo
  • Del: Delete selected
  • Shift+Click: Multi-select
  • Ctrl+K: Open command palette

πŸ‘₯ Customer-Facing Seat Viewer

A dedicated, safe page for customers to view and purchase seats. This page is read-only and does not allow editing.

How to Use

  1. Start the development server:
    npm run dev
    # or
    yarn dev
  2. Visit the customer page:
  3. Upload a seat layout:
    • Drag and drop your exported seat JSON file onto the upload area, or click to browse and select the file.
    • Only JSON files exported from the admin/editor are supported.
  4. View and purchase seats:
    • The seat layout will be displayed on a canvas.
    • Click any seat to view its details in a modal.
    • Use the Buy or Cancel buttons in the modal (customize the buy logic as needed).
    • Seats and other objects are not editable or selectable by customers.

Customer Features

  • Drag & Drop Upload: Easily upload seat layouts by dragging your JSON file onto the upload area.
  • Modal Details: Clicking a seat opens a modal with seat number, category, price, status, and purchase options.
  • Read-Only: Customers cannot move, edit, or select seatsβ€”only view and purchase.

πŸ–ΌοΈ Rendering a Saved Layout (Read-Only)

You can render a saved seat layout in read-only mode using the provided SeatPicker component with the readOnly prop set to true. This is ideal for customer-facing pages or embeddable widgets where you want to display a seat map and allow seat selection/purchase, but prevent editing or uploading.

Example

import { SeatPicker } from 'seat-picker';

function CustomerView() {
  const [layout, setLayout] = useState(null);

  const handleSeatAction = (action, seat) => {
    console.log('Action:', action, 'on seat:', seat);
    // Implement your buy functionality here
  };

  return (
    <div className="min-h-screen bg-gray-100 p-8">
      <h1 className="mb-4 text-2xl font-bold">Customer Seat Viewer</h1>

      {/* Upload area for layout JSON */}
      <div className="mb-6">
        <div className="rounded-lg border-2 border-dashed border-gray-300 p-6">
          {/* Your file upload UI here */}
        </div>
      </div>

      {layout ? (
        <SeatPicker
          layout={layout}
          readOnly
          style={{
            width: 800,
            height: 600,
            backgroundColor: '#f8fafc',
            showSeatNumbers: true,
            seatNumberStyle: {
              fontSize: 14,
              fill: '#222',
              fontWeight: 'bold',
            },
            seatStyle: {
              fill: 'transparent',
              stroke: 'black',
              strokeWidth: 1,
              radius: 10,
            },
          }}
          labels={{
            buyButton: 'Buy Seat',
            cancelButton: 'Cancel',
            seatNumber: 'Seat Number',
            category: 'Category',
            price: 'Price',
            status: 'Status',
          }}
          onSeatAction={handleSeatAction}
        />
      ) : (
        <div className="rounded-lg border bg-white p-4 shadow">
          <div className="flex h-[600px] items-center justify-center text-gray-500">
            Please upload a seat layout file
          </div>
        </div>
      )}
    </div>
  );
}

βš™οΈ Props Reference & Customization

SeatPicker

| Prop | Type | Default | Description | | ------------------- | -------------------------------------------- | ------- | ---------------------------------------------------------------- | | width | number | 800 | Canvas width in pixels | | height | number | 600 | Canvas height in pixels | | layout | object | β€” | (Optional) Layout JSON to load (for editing an existing layout) | | initialSeats | Seat[] | [] | (Deprecated, use layout) Initial seats to render | | initialZones | Zone[] | [] | (Deprecated, use layout) Initial zones for grouping seats | | onChange | (layout: object) => void | β€” | Callback when the layout changes (add, move, edit, delete, etc.) | | onSave | (layout: object) => void | β€” | Callback when the user clicks the Save button | | onZoneChange | (zones: Zone[]) => void | β€” | Callback when zones change | | className | string | β€” | Additional CSS class name for the root container | | style | object | β€” | Additional inline styles or style overrides (see below) | | labels | object | β€” | Override default button/label text (see below) | | readOnly | boolean | false | If true, disables all editing and only allows viewing | | renderToolbar | (props) => ReactNode | β€” | Custom render function for the toolbar | | renderSidebar | () => ReactNode | β€” | Custom render function for the sidebar | | renderSeatDetails | ({ seat, onClose, onAction }) => ReactNode | β€” | Custom render function for the seat details modal | | onSeatClick | (seat: SeatData) => void | β€” | Callback when a seat is clicked (read-only mode) | | onSeatAction | (action: string, seat: SeatData) => void | β€” | Callback for seat actions (e.g., buy, reserve) |

Example: Customizing Style and Labels

<SeatPicker
  width={1000}
  height={700}
  style={{
    backgroundColor: '#fffbe6',
    seatNumberStyle: { fontSize: 16, fill: '#333' },
    seatStyle: { fill: '#e0e7ff', stroke: '#6366f1', radius: 12 },
  }}
  labels={{
    buyButton: 'Purchase',
    cancelButton: 'Back',
    seatNumber: 'No.',
    category: 'Section',
    price: 'Cost',
    status: 'Availability',
  }}
/>

Example: Custom Toolbar

<SeatPicker
  renderToolbar={({ onSave, onBgLayout }) => (
    <div>
      <button onClick={onSave}>Custom Save</button>
      <button onClick={onBgLayout}>Background</button>
      {/* ...add more custom controls */}
    </div>
  )}
/>

Example: Custom Sidebar

<SeatPicker
  renderSidebar={() => (
    <div>
      <h3>Custom Sidebar</h3>
      {/* Add your own controls or info */}
    </div>
  )}
/>

Example: Custom Seat Details Modal

<SeatPicker
  renderSeatDetails={({ seat, onClose, onAction }) => (
    <div>
      <h2>Seat {seat.number}</h2>
      <p>Price: {seat.price}</p>
      <button onClick={() => onAction('buy', seat)}>Buy</button>
      <button onClick={onClose}>Close</button>
    </div>
  )}
/>

SeatLayoutRenderer

| Prop | Type | Default | Description | | ------------------- | -------------------------------------------- | ------- | --------------------------------------------- | | layout | object | β€” | The seat layout JSON exported from the editor | | width | number | 800 | Canvas width in pixels | | height | number | 600 | Canvas height in pixels | | labels | object | β€” | Override default button/label text | | onSeatClick | (seat: SeatData) => void | β€” | Callback when a seat is clicked (read-only) | | onSeatAction | (action: string, seat: SeatData) => void | β€” | Callback for seat actions (e.g., buy) | | renderSeatDetails | ({ seat, onClose, onAction }) => ReactNode | β€” | Custom seat modal |

Example: Read-Only Renderer with Custom Modal

<SeatLayoutRenderer
  layout={seatLayoutJson}
  width={900}
  height={700}
  labels={{ buyButton: 'Book Now' }}
  renderSeatDetails={({ seat, onClose, onAction }) => (
    <div>
      <h2>VIP Seat {seat.number}</h2>
      <button onClick={() => onAction('buy', seat)}>Book</button>
      <button onClick={onClose}>Close</button>
    </div>
  )}
/>

Customization Tips

  • Styling:
    Use the style prop to override canvas, seat, and label styles. You can use Tailwind, CSS-in-JS, or plain CSS.
  • Labels:
    Pass a labels object to override any button or field text for localization or branding.
  • Component Composition:
    Use the renderToolbar, renderSidebar, and renderSeatDetails props to inject your own React components for a fully custom UI.
  • Callbacks:
    Use onChange, onSave, onSeatClick, and onSeatAction to hook into all user actions and integrate with your backend or analytics.

πŸ§‘β€πŸ’» Contributing

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

πŸ“„ License

MIT Β© Emmanuel Michael