smart_seat_selector 0.1.0 copy "smart_seat_selector: ^0.1.0" to clipboard
smart_seat_selector: ^0.1.0 copied to clipboard

A universal grid-based seat selection widget for Flutter supporting Cinemas, Buses, Flights, and Event halls with zoom and pan interaction.

Smart Seat Selector #

A universal grid-based seat selection widget for Flutter β€” supporting Cinemas, Buses, Flights, and Event venues with multi-seat types, per-type pricing, zoom & pan, animated selection, tooltips, and a live summary bar.

pub.dev v0.1.0 License: MIT Flutter


Features #

🎭 Multi-seat types Economy, Business, VIP, Wheelchair β€” each with its own color, icon, shape, and price
πŸ’° Live pricing totalPrice getter updates in real time as seats are selected
🎨 Per-type styling Rounded-rect, circle, or stadium shape; custom icon per type
πŸ’¬ Rich tooltips Long-press any seat to see its label, type, status, and price
✨ Animations Scale bounce on selection + ink ripple on tap
🏷️ Row & column headers Auto-aligned A–Z row labels and 1–N column numbers
πŸ“Š Summary bar Sticky bottom bar with selected seats, labels, total price, and confirm button
πŸ—ΊοΈ Legend widget Auto-generated color legend that always matches your config
πŸ” Zoom & pan Built-in InteractiveViewer for large seat maps
🧠 Smart controller selectRow(), selectByType(), selectAll(), clearSelection()
πŸ”’ Safe state Deep-copied immutable grid β€” external mutations can't corrupt state

Installation #

dependencies:
  smart_seat_selector: ^0.1.0
import 'package:smart_seat_selector/smart_seat_selector.dart';

Quick start #

1 β€” Define your grid #

Use the Seat factory helpers to build a TypedSeatGrid:

final TypedSeatGrid grid = [
  // Row A β€” VIP front row
  [Seat.vip(), Seat.vip(), Seat.gap(), Seat.gap(), Seat.vip(), Seat.vip()],
  // Row B β€” Business
  [Seat.business(), Seat.business(booked: true), Seat.gap(), Seat.gap(), Seat.business(), Seat.business()],
  // Row C β€” Economy
  [Seat.economy(), Seat.economy(), Seat.gap(), Seat.gap(), Seat.economy(), Seat.economy()],
  // Row D β€” Economy + accessible bays
  [Seat.wheelchair(), Seat.economy(), Seat.gap(), Seat.gap(), Seat.economy(), Seat.wheelchair()],
];

Every cell is a SeatMeta β€” combining a SeatState (available / booked / disabled / gap) with a SeatType (economy / business / vip / wheelchair).

2 β€” Create a controller #

late SeatController _controller;

@override
void initState() {
  super.initState();
  _controller = SeatController(
    seatGrid: grid,
    maxSelection: 4,
    prices: const {
      SeatType.economy:    10.0,
      SeatType.business:   25.0,
      SeatType.vip:        60.0,
      SeatType.wheelchair:  0.0,
    },
  );
}

@override
void dispose() {
  _controller.dispose(); // always dispose
  super.dispose();
}

3 β€” Render the layout #

SeatLayout(
  controller: _controller,
  seatConfig: const SeatLayoutConfig(
    seatSize: 40,
    showRowLabels: true,
    showColLabels: true,
    showTooltip: true,
    enableAnimations: true,
  ),
  onSeatStateChanged: (List<SeatPoint> selected) {
    print('Selected: $selected');
    print('Total: \$${_controller.totalPriceFormatted}');
  },
)

4 β€” Add a legend and summary bar #

Column(
  children: [
    Expanded(
      child: SeatLayout(controller: _controller, seatConfig: config),
    ),
    SeatLegend(config: config),                          // color legend
    SeatSummaryBar(                                       // live bottom bar
      controller: _controller,
      config: config,
      confirmLabel: 'Book Tickets',
      onConfirm: (seats) => print('Booking $seats'),
    ),
  ],
)

Seat types #

Four built-in types, each with a ready-to-use preset:

Type Preset Shape Icon Default price
SeatType.economy SeatTypeConfig.defaultEconomy Rounded rect β€” free
SeatType.business SeatTypeConfig.defaultBusiness Rounded rect star_border_rounded $25
SeatType.vip SeatTypeConfig.defaultVip Stadium (pill) workspace_premium_rounded $60
SeatType.wheelchair SeatTypeConfig.defaultWheelchair Circle accessible_rounded free

Custom type config #

Override any preset or create your own:

SeatLayoutConfig(
  typeConfigs: {
    SeatType.economy: const SeatTypeConfig(
      label: 'Standard',
      price: 8.0,
      availableColor: Color(0xFFE8EAF6),
      selectedColor: Color(0xFF3949AB),
      selectionBorderColor: Color(0xFF1A237E),
    ),
    SeatType.vip: const SeatTypeConfig(
      label: 'Premium',
      price: 45.0,
      shape: SeatShape.stadium,
      icon: Icons.star_rounded,
      availableColor: Color(0xFFFFF8E1),
      selectedColor: Color(0xFFF57F17),
      selectionBorderColor: Color(0xFFE65100),
    ),
  },
)

Migrating from v0.0.x #

If you have an existing integer grid, use the fromInts factory β€” no grid rewrite needed:

// Old code
controller = SeatController(seatGrid: myIntGrid, maxSelection: 3);

// New code β€” drop-in replacement
controller = SeatController.fromInts(seatGrid: myIntGrid, maxSelection: 3);

All seats default to SeatType.economy. You can then migrate rows to typed grids incrementally.


API reference #

SeatController #

Member Description
SeatController({seatGrid, maxSelection, prices, initialSelection}) Main constructor β€” accepts TypedSeatGrid
SeatController.fromInts({seatGrid, ...}) Legacy factory β€” accepts List<List<int>>
selectedSeats β†’ Set<SeatPoint> Currently selected seats (unmodifiable)
selectedCount β†’ int Number of selected seats
isMaxReached β†’ bool Whether maxSelection has been hit
totalPrice β†’ double Sum of prices for selected seats
totalPriceFormatted β†’ String e.g. "42.00"
getState(row, col) β†’ SeatState Current state (selection overrides stored state)
getType(row, col) β†’ SeatType Seat class at that cell
getSeatMeta(row, col) β†’ SeatMeta Full metadata for a cell
toggleSeat(row, col) Select / deselect a seat
selectSeats(List<SeatPoint>) Bulk select by coordinate
selectRow(int row) Select all available seats in a row
selectByType(SeatType) Select all available seats of a given type
selectAll() Select all available seats up to maxSelection
clearSelection() Deselect everything
dispose() Always call in your State.dispose()

SeatLayoutConfig #

Property Type Default Description
seatSize double 40.0 Width & height of each seat
gapSize double 10.0 Spacing between seats
typeConfigs Map<SeatType, SeatTypeConfig> All 4 presets Per-type visual & pricing config
showRowLabels bool false A, B, C… labels on the left
showColLabels bool false 1, 2, 3… numbers on the top
enableAnimations bool true Scale bounce + ripple
showTooltip bool true Long-press tooltip
availableColor Color #E0E0E0 Fallback available color
bookedColor Color #BDBDBD Fallback booked color
selectedColor Color #4CAF50 Fallback selected color
disabledColor Color #EEEEEE Disabled seat color
selectionBorderColor Color #2E7D32 Fallback selection border
borderRadius BorderRadius 8.0 Corner radius for rounded-rect seats
labelStyle TextStyle? null Override seat label text style

SeatTypeConfig #

Property Type Description
label String Display name in legend and tooltip
price double Per-seat price (used by totalPrice)
currencySymbol String Shown in tooltip, default $
availableColor Color? Override for available state
bookedColor Color? Override for booked state
selectedColor Color? Override for selected state
selectionBorderColor Color? Override for selection border
shape SeatShape roundedRect / circle / stadium
icon IconData? Icon drawn inside the seat
iconOnly bool Hide label, show only icon

Seat factory helpers #

Seat.gap()                        // aisle cell
Seat.economy()                    // available economy
Seat.economy(booked: true)        // booked economy
Seat.business()
Seat.vip()
Seat.wheelchair()
Seat.available(type: SeatType.vip, id: 'VIP-3')   // with backend id
Seat.gridFromInts(myIntGrid)      // convert legacy int grid

Widgets #

Widget Description
SeatLayout Main grid widget β€” scrollable, zoomable, animated
SeatLegend Color swatch row matching your SeatLayoutConfig
SeatSummaryBar Sticky bottom bar with count, labels, price, confirm button

License #

MIT β€” see LICENSE.

2
likes
160
points
99
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A universal grid-based seat selection widget for Flutter supporting Cinemas, Buses, Flights, and Event halls with zoom and pan interaction.

Repository (GitHub)
View/report issues

Topics

#booking #cinema #widget #seat-selector #seat-picker

License

MIT (license)

Dependencies

flutter

More

Packages that depend on smart_seat_selector