seat-picker
TypeScript icon, indicating that this package has built-in type declarations

0.0.13Β β€’Β PublicΒ β€’Β Published

πŸ“š 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

Package Sidebar

Install

npm i seat-picker

Weekly Downloads

36

Version

0.0.13

License

MIT

Unpacked Size

946 kB

Total Files

10

Last publish

Collaborators

  • chochodev