100%

Canvas

Select Seated section in Drawing Tools, then click the canvas to place a section.

Getting started

Install dependencies and run the demo from the monorepo root:

pnpm install
pnpm dev

Import the editor in your Next.js or React app:

import {
  FloorPlanEditor,
  createEmptyFloorPlan,
} from "@ticketss/floor-plan-editor";
import "@ticketss/floor-plan-editor/styles/tokens.css";

Full install and publish steps — expanded in later milestones.

Package API

PropTypeDescription
valueFloorPlanDocumentControlled floor plan state
onChange(doc) => voidCalled when the document changes
isDarkModebooleanSets data-theme="dark" on editor root
langen | ar | pt | es | fa | frUI language (fallback en)
stylesFloorPlanEditorStylesOptional per-component chrome overrides (M11)

Peer dependencies: react, react-dom

FloorPlanDocument

Single JSON blob for save/load. Top-level fields: schemaVersion, id, title, updatedAt, canvas, nodes, tiers, holds, optional selection.

import { createEmptyFloorPlan } from "@ticketss/floor-plan-editor";

const doc = createEmptyFloorPlan({ title: "Main Hall" });

See docs/floor-plan-json-schema-reference.md in the repo for the full schema.

Entity examples and validation — documented in schema reference.

Entities & commerce

EntityTierHold
TableWhole tableWhole table
G.A. AreaWhole zoneWhole zone
Seated section seatsPer seatPer seat
Image, Text, Shape

Drawing tools and property panels — M2–M9.

Design tokens

Chrome UI uses CSS variables from Ticketss main.scss, shipped as @ticketss/floor-plan-editor/styles/tokens.css. Toggle theme with isDarkMode on the editor.

Figma implementations must map colors to var(--*) tokens, not raw hex. See docs/design-tokens.md for the mapping checklist.

Full token table — in design-tokens.md.

Style customization

Pass styles to override chrome colors, backgrounds, and typography per component key. Canvas entities stay in value.nodes.

<FloorPlanEditor
  value={doc}
  onChange={setDoc}
  styles={{
    topBar: { backgroundColor: "#1a1a2e", color: "#eee" },
    topBarTitle: { fontFamily: "Georgia, serif", fontSize: 20, fontWeight: 700 },
  }}
/>

Component key reference, live playground — M11.

Live JSON output

Current value from the editor above:

{
  "schemaVersion": 1,
  "id": "fp_demo",
  "title": "Floor plan editor",
  "updatedAt": "2026-01-01T00:00:00.000Z",
  "canvas": {
    "width": 4000,
    "height": 3000,
    "gridSize": 20,
    "zoom": 1,
    "viewport": {
      "x": 0,
      "y": 0
    }
  },
  "nodes": [],
  "tiers": [],
  "holds": [],
  "selection": []
}

Host integration

Controlled component pattern for your app state or future API:

const [doc, setDoc] = useState(() => createEmptyFloorPlan());

<FloorPlanEditor value={doc} onChange={setDoc} isDarkMode={dark} lang="en" />

// Future: await api.putFloorPlan(eventId, doc);

Save in the editor (v1): alert + console.log(value) — wired in M1.