JSPM

@hemicycle/react

0.1.5
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q47756F
  • License MIT

Core Hemicycle layout computations

Package Exports

  • @hemicycle/react
  • @hemicycle/react/package.json

Readme

@hemicycle/react

npm version License: MIT Node.js >=18

React component for rendering parliament-style hemicycle seat charts.

@hemicycle/react is the React wrapper around @hemicycle/vanilla. Drop in a <Hemicycle> component, pass your seat data as props, and get a fully rendered SVG chart that re-renders reactively on changes.


Features

  • Single <Hemicycle> component — configure layout and data entirely through props
  • Per-seat React wrappers — wrap any seat with a custom React node (tooltips, popovers, links, etc.)
  • Per-seat SVG props — attach onClick, aria-*, data-*, and any other SVG attributes to individual seats
  • All @hemicycle/vanilla options — shapes (arc, rect, circle), aisles, mirroring, radii, and more
  • TypeScript generics — type your seat data end-to-end with HemicycleProps<T>

Installation

npm install @hemicycle/react

Requires React ≥ 18 and Node.js ≥ 18.


Quick Start

import { Hemicycle } from "@hemicycle/react";

export function ParliamentChart() {
  return (
    <Hemicycle
      rows={7}
      totalSeats={577}
      innerRadius={40}
      outerRadius={95}
      width={800}
      height={420}
    />
  );
}

API

<Hemicycle>

All props are optional. Accepts all @hemicycle/vanilla config options plus:

Prop Type Description
data HemicycleData<T>[] Seat data array (see below)
svgProps React.SVGProps<SVGSVGElement> Extra props forwarded to the root <svg> element
seatConfig SeatConfig<T> Default visual style and behavior for all seats

SeatConfig<T>

Extends the vanilla SeatConfig (shape, color, borderRadius, radius) with two React-specific additions:

Option Type Description
wrapper (content, data) => ReactNode Wraps each seat's <path> in a custom React node
props React.SVGProps<SVGPathElement> Default SVG props applied to every seat <path>

Seat data

Each item in the data array identifies a seat by index or by coordinates, exactly as in @hemicycle/core, and may include a per-seat seatConfig to override styles and behavior for that seat:

type HemicycleData<T> = T &
  ({ idx: number } | { rowIndex: number; seatIndex: number }) & {
    seatConfig?: SeatConfig<T>;
  };

Per-seat seatConfig is merged on top of the global seatConfig prop, so you only need to specify what differs.


Examples

Coloring seats by party

const members = [
  { idx: 0, party: "Left", color: "#e63946" },
  { idx: 1, party: "Center", color: "#457b9d" },
  // ...
];

<Hemicycle
  rows={7}
  totalSeats={577}
  data={members.map((m) => ({
    idx: m.idx,
    party: m.party,
    seatConfig: { color: m.color },
  }))}
/>;

Clickable seats with tooltips

<Hemicycle
  rows={5}
  totalSeats={100}
  data={seats.map((seat) => ({
    idx: seat.idx,
    seatConfig: {
      color: seat.partyColor,
      props: {
        onClick: () => setSelected(seat),
        style: { cursor: "pointer" },
      },
      wrapper: (content, data) => (
        <Tooltip key={data?.idx} label={data?.party}>
          {content}
        </Tooltip>
      ),
    },
  }))}
/>

Custom SVG container props

<Hemicycle
  rows={5}
  totalSeats={100}
  svgProps={{
    className: "my-chart",
    "aria-label": "Parliament seating chart",
    style: { maxWidth: "100%" },
  }}
/>

Typed seat data

type Member = {
  name: string;
  party: string;
};

const data: HemicycleData<Member>[] = members.map((m) => ({
  idx: m.seatNumber,
  name: m.name,
  party: m.party,
  seatConfig: { color: m.partyColor },
}));

<Hemicycle<Member> data={data} rows={7} totalSeats={577} />;

Seat Shapes

Shape Description
arc Curved wedge following the concentric arc of the row (default)
rect Rectangle aligned to the seat's arc midpoint
circle Circle centered at the seat's midpoint


Contributing

Bug reports and pull requests are welcome on GitHub.


Support


Maintainer

Gabriel Vidalgvidalayrinhac@gmail.com


License

MIT