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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@seatmaps.com/react-lib

v3.0.66

Published

Jets seatmap react library.

Downloads

639

Readme

OpenSSF Scorecard

Seatmap integration and communication

This document describes how to integrate the JetsSeatMap lib (further "seatmap") into any React.js application. Also, communication between the seatmap and a parent layer that embeds seatmap (further just "parent layer").

 

Installation

There are 2 ways to install the lib:

  • using npm version
  • using self-hosted version

Self-hosted version

Need to clone this repository and install dependencies:

npm i

Here you have 2 options:

  1. rename .env-sample to .env. Also, you need to get the APP_ID and PRIVATE_KEY from the Quicket GmbH support team and put them into fields in .env file.
  2. or directly change config-mock.js:
  apiUrl: process.env.JETS_BASE_API_URL,
  apiAppId: process.env.JETS_APP_ID,
  apiKey: process.env.JETS_PRIVATE_KEY,

replace reading of env-variables with your credentials.

Run storybook:

npm run dev

By default, you will see a loading progress bar - just input your flight parameters and press INIT SEAT MAP.

Now, you can customize the source code of the library and apply your CSS styles.

Before use, you have to build lib:

npm run build-lib

After that, you can publish the library to a new or already existing github repository, or publish it to your NPM account.

To connect the library to the project, you need to run:

npm install name-of-your-lib-variation

or include this string into your package.json dependencies if you use the github repo:

"jets-seatmap-react-lib": "git+ssh://[email protected]/path-to-your-repo.git#branch"

 

Integration

This section explains how to integrate seatmap into a React.js application.

Create your config and embed seatmap into your component page via <JetsSeatMap> tag:

<JetsSeatMap
  flight={flight_data}
  availability={availability_data}
  passengers={passengers_data}
  config={config_data}
  currentDeckIndex={deckIndex}            // could be used to specify rendered deck or to switch decks on the fly from external UI
  onSeatMapInited={seatMapInitedHandler}
  onSeatSelected={seatSelectedHandler}
  onSeatUnselected={seatUnselectedHandler}
  onLayoutUpdated={layoutUpdatedHandler}
  onTooltipRequested={tooltipRequestedHandler}
/>

 

Properties

The flight prop is required.

 

Flight

This prop is required. It provides the data about cabin class, airline code, arrival, departure etc.

Interface, describing data types:

interface IFlight {
  id: string;
  airlineCode: string;
  flightNo: string;
  departureDate: string;
  departure: string;
  arrival: string;
  cabinClass: string;
  passengerType?: string;
  planeCode?: number;
  startRow?: string; // string [ 3 .. 24 ] characters
  endRow?: string; // string [ 3 .. 24 ] characters
  exitRowsLeft?: number[]; // restriction by exit rows numbers
  exitRowsRight?: number[]; // restriction by exit rows numbers
}

Example of data seatmap receives:

{
  id: '1111',
  airlineCode: 'BA',
  flightNo: '106',
  departureDate: '2023-09-28',
  departure: 'DXB',
  arrival: 'LHR',
  cabinClass: 'E',
  passengerType: 'ADT',
  planeCode: null,
};

Cabin class vslues: E - economy, P - economy premium, B - business, F - first, A - whole plane

The departure and arrival fields' values must be valid IATA airport codes. The departureDate field must be a valid ISO date in the yyyy-mm-dd format.

startRow - first of available row numbers and its letters, colon as divider, upper case, e.g. 10 or 10:ABCDEF. If the startRow parameter is set, endRow also needs to be set, otherwise, it will be ignored. endRow - last of available row numbers and its letters, colon as divider, upper case, e.g. 32 or 32:ACDF. If the endRow parameter is set, startRow also needs to be set, otherwise, it will be ignored.

Also, it is possible to define flexible start/end rows params: "startRow":"1:?FL","endRow":"18:?AL" - here ?FL means row's letters includes FL, AFL will match, ACFJL not

exitRowsLeft and exitRowsRight are optional fields that allow you to specify restrictions for aircraft based on exit row numbers. These fields accept arrays of numbers, where each number corresponds to an exit row number.

For example:

exitRowsLeft: [10, 20], // Restricts seats near exit rows 10 and 20 on the left side of the plane
exitRowsRight: [10, 20], // Restricts seats near exit rows 15 and 25 on the right side of the plane

If these fields are provided, the API will try to find a seat map with such exit rows. It is acceptable to populate just one field, exitRowsLeft or exitRowsRight, with just 1 number of exit row.

 

Availability

The availability property is array of objects and describes which seats are able for passengers. You can pass it asynchronously or not pass at all, it is optional.

Interface, describing data types:

interface IIncomingSeat {
  currency: string;
  label: string;
  price: number;
  color?: string;                                 // color of the seat
  onlyForPassengerType?: TPassengerType[];
  additionalProps?: TAdditionalProp[];            // additionalProps from individual seats would exted the list of seat's features
                                                  // up to 12 features and props could be displayed in tooltip for a seat 
}

type TSeatAvailability = IIncomingSeat[];

type TAdditionalProp = {
   label: String; 
   icon: String;            // suported icons are ["+", "-", "dot", "wifi", "movie", "power"], "dot' is default
}

Example of data seatmap receives:

[
  {
    currency: 'USD',
    label: '*',               // properties from wildcard would be used to replace unspecified properties for individual seats
    price: 33,
    onlyForPassengerType: ['ADT', 'CHD', 'INF'],
    additionalProps: [        // additionalProps from wildcard would be merged with specified additionalProps for individual seats (applied to all seats)
      { label: 'Test prop for all', icon: 'dot' },
      { label: 'Another test prop for all', icon: 'wifi' },
    ],
    color: 'lightgrey'        // all the seats that don't have individual colors set will be colored with wildcard color value
  },
  {
    currency: 'USD',
    label: '20E',
    price: 33,
    onlyForPassengerType: ['ADT', 'CHD', 'INF'],
    additionalProps: [        
      { label: 'Clear air', icon: null, cssClass: 'clear-air-style' },
      { label: 'USB plug', icon: 'power' },
    ],
    color: 'green'            // individual seat's color
  },
  {
    currency: 'USD',
    label: '20K',
    price: 33,
    onlyForPassengerType: 'ADT',
  },
  {
    currency: 'USD',
    label: '21F',
    price: 13,
    onlyForPassengerType: ['ADT', 'CHD', 'INF'],
  },
  {
    currency: 'USD',
    label: '31B',
    price: 13,
    onlyForPassengerType: ['CHD', 'INF'],
  },
];

You can pass seat with label "*". This label works like all selector for seats. In the example below, all seats with classCode equals "E" will be enabled with price of 50. However next seat configuration "12F" will override price and set it to 75. You can pass seat with price 0. Also you can pass seat without price field and it would be the same as pass it with 0 value.

If onlyForPassengerType field is empty or doesn't exist, then it has no restrictions value by default.

Coloring seats tip: color field has the next set of priorities: individual > wildcard > internal. If wildcard color is present - it's highly recommended to add color property to all individual seats for visual distinction.

All additionalProps can have property cssClassthat will be assigned to the container, icon and label. For example, if cssClass: 'cssClass: 'clear-air-style'' in the HTML you will have 3 additional CSS classes:

  • clear-air-style - class of seat feature container
  • clear-air-style-icon - class of seat feature icon
  • clear-air-style-label- class of seat feature label

These CSS classes can be defined at the host level CSS.

Max count of visible seat features/props = 12.

 

Passengers

The passengers property is an array of objects and describes the passengers for seating according to the cabin map. You can pass it asynchronously or not pass it at all, it is optional. If you don't pass the passengers list - seat selection will not work.

Interface, describing data types:

interface IPassenger {
  readonly id: string;
  seat: ISeat;
  passengerType?: TPassengerType;
  passengerLabel?: string;
  passengerColor?: string;
}

interface ISeat {
  price: number;
  seatLabel: string;
}

type TAllocatablePassengers = IPassenger[];

type TPassengerType = 'ADT' | 'CHD' | 'INF';

Example of data seatmap receives:

[
      {
        "id": "1",
        "seat": null
      },
      {
        "id": "2",
        "seat": {
          "price": 0,
          "seatLabel": "12F"
        },
        "passengerLabel": "Alex",
        "passengerColor": "brown",
        "readOnly": true
      },
      {
        "id": "3",
        "passengerType": "CHD",
        "seat": null
        "passengerLabel": "John Snow",
        "passengerColor": "#ccc",
      }
    ]

Or even like this:

{
  "data": {
    "passengers": [
      { "id": "1" },
      { "id": "2" },
      { "id": "3" }
    ]
  },
  "type": "SYNC_PASSENGERS"
}

seat, passengerType, passengerLabel and passengerColor are not required fields.

If you do not pass passengerType, passengerLabel and passengerColor fields, the values will be set by default.

Please note that the seatmap identifies how many passengers to allocate by the length of the passengers array. Therefore, for example, to allocate 2 passengers without any predefined seat or its type, passengers array shall contain 2 items.

For passengers with property readOnly: true, it is not possible to unselect assigned seat.

 

Config

The config property describes the basic configuration of the seat map.

Interface, describing data types:

interface IConfig {
  width: number;
  lang: string;
  units: TUnit;
  apiUrl: string;
  apiAppId: string;
  apiKey: string;
  colorTheme: IColorTheme;
}

type TUnit = 'metric' | 'imperials';

type TLang = 'CN' | 'DE' | 'EN' | 'ES' | 'PL' | 'RU' | 'AR' | 'CS' | 'FR' | 'PT' | 'UK' | 'IT' | 'JA' | 'KO' | 'TR' | 'PT-BR';

Minimal config could look like this:

width: 400;
lang: 'EN';
units: 'metric';
apiUrl: 'PROVIDED_API_URL',               
apiAppId: 'PROVIDED_APP_ID',
apiKey: 'PROVIDED_API_KEY',

The full config looks like this:


{
  width: 400,                               // width of seatmap, height will be dynamic and depends on amount of decks/rows in decks
                                            // if `horizontal` flag is set to true - height and width will swap around (height being static)
  lang: 'EN',                                            
  horizontal: true,                         // should seatmap be rendered horizontally or vertically
  rightToLeft: false,                       // changes tooltip text alignment (and decks placement) for RTL languages support
  visibleFuselage: true,                    // should nose and tail graphics be rendered
  visibleWings: false,                      // should position of wings be shown (helps to see how far/close they are from/to certain seats)
  visibleCabinTitles: true,                 // should cabin titles be rendered
  customCabinTitles: { F: 'First', B: 'Business', P: 'Premium', E: 'Economy' }, // optional, to override default cabin titles, defaults: F: 'First class', B: 'Business class', P: 'Premium class', E: 'Economy class',

  builtInDeckSelector: false,               // if there's only one deck on the flight it doesn't do anything
                                            // if there's more it's possible to render all decks at once or only one with ability to switch them
  singleDeckMode: true,                     // if false, double-deck mode enabled - to show 2 decks at a time, without deck switcher

  builtInTooltip: true,                     // see `onTooltipRequested` section
  externalPassengerManagement: false,       // see `onTooltipRequested` section
  tooltipOnHover: false,                    // see `onTooltipRequested` section

  visibleSeatPriceLabels: false,             // should seat price labels be rendered
  currencySign: '$',                        // сurrency sign that will be displayed in the seat price label. It will also be displayed in the price in the tooltip. Only 1 character is allowed, if the length of the passed value is longer it will be truncated

  scaleType: 'zoom',                        // type of scaling applied to adjust to the desired width of the rendered seat map: `zoom` | `scale`, FF supports `scale` only

  apiUrl: 'PROVIDED_API_URL',               
  apiAppId: 'PROVIDED_APP_ID',
  apiKey: 'PROVIDED_API_KEY',
  apiAuthorizationScheme: 'Bearer',            // authorization scheme to be sent in API client requests 'Authorization' header (default: 'Bearer', e.g. 'Authorization: Bearer {apiKey}')
  apiMetadata: {                            // any proprietary data to be passed in the POST request to /flight/features/plane/seatmap (e.g. for custom monitoring)
    'PROPRIETARY_KEY': 'PROPRIETARY_VALUE',
    ...
  }
  
  hiddenSeatFeatures: ['limitedRecline', 'getColdByExit', 'doNotRecline', 'wingInWindow', 'nearLavatory', 'nearGalley'], // to exclude some seat features from the built-in tooltip, all seat features are still available within the `onTooltipRequested` event

  colorTheme: {                             // most values are CSS-compatible
    seatMapBackgroundColor: 'white',        

    deckLabelTitleColor: 'white',
    deckHeightSpacing: 100,                 // additional space on both ends of a deck (for aesthetics only)

    wingsWidth: 50,                          
    deckSeparation: 0,

    floorColor: 'rgb(30,60,90)',            // color of decks floor
    seatLabelColor: 'white',
    seatStrokeColor: 'rgb(237, 237, 237)',
    seatStrokeWidth: 1,
    seatArmrestColor: '#cccccc',
    notAvailableSeatsColor: 'lightgray',    // fill color for seats that are not available, applied when seat `availability` has been set

    bulkBaseColor : 'dimgrey',              // colors for bulks 
    bulkCutColor : 'lightgrey',
    bulkIconColor: 'darkslategray',
    bulkFloorIconColor: 'lightgrey',

    defaultPassengerBadgeColor: 'darkred',
    defaultPassengerBadgeLabelColor: '#fff', 
    defaultPassengerBadgeBorderColor: '#fff',
    fontFamily: 'Montserrat, sans-serif',

    tooltipBackgroundColor: 'rgb(255,255,255)',
    tooltipHeaderColor: '#4f6f8f',
    tooltipBorderColor: 'rgb(255,255,255)',
    tooltipFontColor: '#4f6f8f',
    tooltipIconColor: '#4f6f8f',            // applied to measurements icons, feature icons have set colors
    tooltipIconBorderColor: '#4f6f8f',
    tooltipIconBackgroundColor: '#fff',
    tooltipSelectButtonTextColor: '#fff',
    tooltipSelectButtonBackgroundColor: 'rgb(42, 85, 128)',
    tooltipCancelButtonTextColor: '#fff',
    tooltipCancelButtonBackgroundColor: 'rgb(55, 55, 55)',

    deckSelectorStrokeColor: '#fff',
    deckSelectorFillColor: 'rgba(55, 55, 55, 0.5)',
    deckSelectorSize: 25,

    fuselageStrokeWidth: 16,                // surrounds the whole plane including tail\nose if enabled (min = 10, max = 18)

    fuselageFillColor: 'lightgrey',
    fuselageStrokeColor: 'darkgrey',

    fuselageWindowsColor: 'darkgrey',
    fuselageWingsColor: 'rgba(55, 55, 55, 0.5)',
    fuselageNoseType: 'by-type', // 'default' to use basic nose section, 'by-type' - to use nose section designed for specific aircraft model 

    exitIconUrlLeft: 'https://panorama.quicket.io/icons/exit-left.svg', // URL to override built-in left exit icon, optional
    exitIconUrlRight: 'https://panorama.quicket.io/icons/exit-right.svg', // URL to override built-in right exit icon, optional

    cabinTitlesWidth: 80,
    cabinTitlesHighlightColors: { F: '#BDB76B', B: '#FF8C00', P: '#8FBC8F', E: '#1E90FF' },
    cabinTitlesLabelColor: '#00BFFF',

    customSeatColorRanges: [                    // optional: define color ranges for seat scoring (1-10)
      {
        color: 'red',                           // CSS-compatible color value
        range: [1, 3.99]                       // score range [min, max] (inclusive)
      },
      {
        color: 'yellow',
        range: [4, 7.99]
      },
      {
        color: 'green',
        range: [8, 10]
      }
    ],
  },
};

To override exits, you need to set both fields in the config - exitIconUrlLeft && exitIconUrlRight + define CSS style for exits:

.deck-exit__image {
  /* custom size, for instance */
  width: 72px; 
  height: 72px;
}

If you will not pass optional config params, then the properties will be set with default values.

The seatmap supports dynamic seat coloring based on score values. When a seat has a score field and customSeatColorRanges is defined in the colorTheme, the seat will be colored according to the score value.

Behavior:

  • If seat has a score value and customSeatColorRanges is defined → seat is colored based on the first matching range
  • If no matching range found → falls back to the seat's original color property
  • Scores outside 1-10 range are ignored
  • Overlapping ranges use the first matching range

Priority order: Score-based color > Original seat color > Default color

 

seatJumpTo

This property allows you to open a tooltip for any seat by its label. Once the prop is provided, the view will be moved to the particular seat and the tooltip will be automatically opened. This will also automatically trigger the onTooltipRequested method.

The property is optional. You can pass it asynchronously or not pass it at all.

interface ISeatJumpToData {
  seatLabel: string;
}

Example of use:

{
  seatLabel: '22D'
}

 

onSeatMapInited

This event fires up when seatmap (DOM tree, content) is initialized. It provides internal data such as

interface ISeat {
  currency: string;
  label: string;
  price: number;
}

interface IAvailableSeatsData {
  availableSeats: ISeat[]
};
interface IMediaData {
  photoData: IPhotoData[];
  panoData: IPanoData[];
}

interface IPhotoData {
  file: string;
  thumb: string;
  size: ISize;
  thumbSize: ISize;
  description: string;
}

interface IPanoData {
  file: string;
  rawFile: string;
  thumb: string;
  thumbSize: ISize;
  description: string;
}

interface ISize {
  w: number;
  h: number;
}
interface IInitialLayoutData {
  availabilityData: IAvailableSeatsData;     // reflects what seats are available for passengers
  currentDeckIndex: number;     // shows current deck if "builtInDeckSelector" flag is set in config, otherwise 0
  decksCount: number;           // number of decks available for provided flight
  heightInPx: number;           // sum of lengths of all elements of the plane (decks, fuselage, separators) using internal units. Multiply by "scaleFactor" to get real pixel value on screen
  scaleFactor: number;          // scale applied to fit into provided boundaries
  widthInPx: number;            // outer width of the plane. CAUTION: if "horizontal" flag is set - height and width are swapped around to reflect that
  media: IMediaData;            // contains media data for the aircraft cabin
  error: string;                // error message if not possible to build a seat map
}

 

onLayoutUpdated

Event is fired after onSeatMapInited and on every deck switch if builtInDeckSelector flag is set to true in config and more than one deck available. See onSeatMapInited above

interface iLayoutData {
  currentDeckIndex: number;     
  decksCount: number;           
  heightInPx: number;           // when fired after deck switch - reflects the size of plane with current deck visible, not total length 
  scaleFactor: number;          
  widthInPx: number;            
}

 

onTooltipRequested

Event is fired when user clicks a seat or puts cursor over it (if tooltipOnHover flag is set to true in config).

If builtInTooltip flag is set to false - native tooltip will not show up and custom tooltip could be shown based on the event's data.

If tooltipOnHover flag is set to true user will be able to select/deselect seats by clicking it even if builtInTooltip is set to false. To disable it completely set externalPassengerManagement to true

Most usefult behaviors could be covered like this:

| builtInTooltip | tooltipOnHover | externalPassengerManagement | result | | :--------------: | :--------------: | :---------------------------: | ------------------------------------------------------------------- | | true | false | false | native tooltip on click, select seat with tooltip buttons | true | true | false | native tooltip on hover, select seat by clicking on seat | false | true | false | no tooltip shown, select seat by clicking on it | false | true | true | no tooltip, select/deselect must be treated externally

interface iTooltipData {
  element: HTMLElement;       // HTML element of clicked/hovered seat, may be used for tooltip positioning
  event: DOMEvent;            // DOM event for more precise coordinates processing
  seat: ISeatData             // detailed seat info, see below
}

interface ISeatData {
  additionalProps: ISeatFeature[]   // additional props for seat converted to ISeatFeature, see Availability section 
  uniqId: string;
  color: string;                    // how seat is shown on seatmap
  features: ISeatFeature[];         // seat features like wifi, leg room, etc
  letter: string;                   // letter in the row
  measurements: IMeasurement[];     // shown in tooltip
  status: string;                   // is seat available or not, see Availability section
  type: string;                     // in most cases just "seat"
  label: string;                    // includes row number and letter
  classType: string;                // Economy, Business, etc
  classCode: string;                // short for classType
  rowName: string;                  // if rows inside current cabin class have special marks - it would be here ("World Traveller" as an example)
  seatType: string;                 // format is "classCode-number", number indicates specific code of a seat in class
  currency: string;                 // currency symbol or code
  price: string;                    // represents a string of the following format: `${currency} ${priceValue}`
  priceValue: number;               // price amount in numbers
}

interface ISeatFeature {
  icon: string;           // SVG icon for the feature
  title: string;          // generic name for the feature
  uniqId: string;
  value: string;          // text shown in tooltip
  key: string;            // used to get translated "value" (i18n)
}

// similar to ISeatFeature but uses different icons and displayed separately in the tooltip
interface IMeasurement {
  icon: string;           // SVG icon for the measurement
  title: string;          // name like "Pitch", "Recline"
  uniqId: string;
  value: string;          // value shown in tooltip
}

Hint: use Element.getBoundingClientRect to align custom tooltip to the selected seat.

 

onSeatSelected

This event fires up when seat is selected. It provides the array of passengers with seat occupancy data. Only when externalPassengerManagement=false in config.

Interface, describing data types:

interface IPassenger {
  readonly id: string;
  seat: ISeat;
  passengerType?: TPassengerType;
  passengerLabel?: string;
  passengerColor?: string;
}

interface ISeat {
  price: string;
  seatLabel: string;
  priceValue: number;
  currency: string;
}

 

onSeatUnselected

This event fires up when seat is unselected. It provides the array of passengers with seat occupancy data.

interface IPassenger {
  readonly id: string;
  seat: ISeat;
  passengerType?: TPassengerType;
  passengerLabel?: string;
  passengerColor?: string;
}

interface ISeat {
  price: string;
  seatLabel: string;
  priceValue: number;
  currency: string;
}

 

onSeatMouseLeave

This event fires up when cursor leave seat boudaries. It provides the same data like onTooltipRequested.

onSeatMouseClick

This event is triggered when the mouse is clicked on the seat, but only externalPassengerManagement == true && tooltipOnHover == true. It provides the same data like onTooltipRequested.

 

onAvailabilityApplied

This event is triggered when the Availability param is applied. It provides the lists of existing and non-existing seat labels.

interface IExistingSeatsLabelsInfo {
  existingSeatLabels: string[];
  nonExistingSeatLabels: string[];
}

 

Advanced: Overriding Components

An optional componentOverrides object can be passed into <JetsSeatMap /> to override either the <JetsSeat /> component or the <JetsNotInit /> (loading state before seat map is initialized), or the <JetsTooltip /> component.

Note: If you override <JetsSeat /> or <JetsTooltip />, you will need to build the corresponding component and ensure that all interaction events are handled correctly.

To ensure consistent behaviour of the <JetsTooltip />, the following methods must be used: onTooltipClose, onSeatSelect, onSeatUnselect. In case your tooltip is used only to show seat info onSeatSelect and onSeatUnselect can be ignored.

const componentOverrides = {
  JetsSeat: MyCustomJetsSeat,
  JetsTooltip: MyCustomJetsTooltip,
  JetsTooltipView: MyCustomJetsTooltipView,
  JetsNotInit: MyCustomLoader,
};

<JetsSeatMap
  ...
  componentOverrides={componentOverrides}
  ...
/>

JetsTooltip vs JetsTooltipView

JetsTooltipView is an alternative way of implementing a custom Tooltip component by passing the required props instead of needing to rely on the internal JetsContext or calculating render attributes such as position and orientation.

Note: To prevent errors ensure elementRef is added as a ref to the root element in you custom implementation.

interface IJetsTooltipView {
  colorTheme: IColorTheme;
  data: ISeatData;
  elementRef: React.RefObject<React.ReactNode>;
  featureListStyle: Partial<CSSStyleDeclaration>;
  finalListOfFeatures: ISeatFeature[];
  headerStyle: Partial<CSSStyleDeclaration>;
  isSeatSelectDisabled: boolean;
  params: {
    isHorizontal: boolean;
    tooltipOnHover: boolean;
  };
  passengerLabel: string;
  pointerStyle: Partial<CSSStyleDeclaration>;
  pointerStyleHorizontal: Partial<CSSStyleDeclaration>;
  shouldHideButtons: boolean;
  rootStyle: Partial<CSSStyleDeclaration>;
  onSeatSelect: (data: ISeatData) => void;
  onSeatUnselect: (data: ISeatData) => void;
  onTooltipClose: (data: ISeatData, element: HTMLElement, event: React.EventHandler<any>) => void;
}