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 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-odontogram

v0.5.5

Published

dental chart for selecting teeth

Readme

🦷 react-odontogram

npm version npm downloads Storybook codecov

A modern, interactive React Odontogram component for dental chart visualization and data collection. Built with SVG and React hooks — fully customizable, accessible, and designed for clinical or academic applications.


🖼️ Preview

| Light Mode | Dark Mode | | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | | Light preview | Dark preview |


🧩 Demo

👉 Live Preview: https://biomathcode.github.io/react-odontogram


📦 Installation

# Using npm
npm install react-odontogram

# Using pnpm
pnpm add react-odontogram

# Using yarn
yarn add react-odontogram

Make sure you have react and react-dom installed as peer dependencies.


🚀 Quick Start

import { Odontogram } from "react-odontogram";
import "react-odontogram/style.css";

export default function App() {
  const handleChange = (selectedTeeth) => {
    console.log(selectedTeeth);
    /*
      Example output:
      [
        {
          "id": "teeth-21",
          "notations": {
            "fdi": "21",
            "universal": "9",
            "palmer": "1UL"
          },
          "type": "Central Incisor"
        },
        {
          "id": "teeth-12",
          "notations": {
            "fdi": "12",
            "universal": "7",
            "palmer": "2UR"
          },
          "type": "Lateral Incisor"
        }
      ]
    */
  };

  return <Odontogram onChange={handleChange} />;
}

🧠 onChange Return Type

The onChange callback returns an array of selected teeth objects:

type ToothDetail = {
  id: string;
  notations: {
    fdi: string;
    universal: string;
    palmer: string;
  };
  type: string;
};

Example JSON output:

[
  {
    "id": "teeth-21",
    "notations": {
      "fdi": "21",
      "universal": "9",
      "palmer": "1UL"
    },
    "type": "Central Incisor"
  },
  {
    "id": "teeth-12",
    "notations": {
      "fdi": "12",
      "universal": "7",
      "palmer": "2UR"
    },
    "type": "Lateral Incisor"
  }
]

⚙️ Props

| Prop | Type | Default | Description | | --- | --- | --- | --- | | defaultSelected | string[] | [] | Tooth IDs selected on first render. | | singleSelect | boolean | false | Allow selecting only one tooth at a time (clicking the selected tooth clears it). | | onChange | (selectedTeeth: ToothDetail[]) => void | — | Called whenever selection changes. | | name | string | "teeth" | Name used for hidden form input. | | className | string | "" | Additional class for wrapper customization. | | theme | "light" \| "dark" | "light" | Applies built-in light/dark palette. | | colors | { darkBlue?: string; baseBlue?: string; lightBlue?: string } | {} | Override palette colors. | | notation | "FDI" \| "Universal" \| "Palmer" | "FDI" | Display notation in native tooth titles/tooltips. | | tooltip | { placement?: Placement; margin?: number; content?: ReactNode \| ((payload?: ToothDetail) => ReactNode) } | { placement: "top", margin: 10 } | Tooltip behavior and custom content renderer. | | showTooltip | boolean | true | Enables/disables tooltip rendering. | | showHalf | "full" \| "upper" \| "lower" | "full" | Render full chart or only upper/lower arches. | | maxTeeth | number | 8 | Number of teeth per quadrant (for baby/mixed dentition views). | | teethConditions | ToothConditionGroup[] | undefined | Colorize specific teeth by condition. | | readOnly | boolean | false | Disable interactions and selection changes. | | showLabels | boolean | false | Show the condition legend under the chart. | | layout | "circle" \| "square" | "circle" | Render classic arch layout or square/row layout. | | styles | React.CSSProperties | undefined | Inline styles applied to the root container. |

Placement values:

type Placement =
  | "top"
  | "top-start"
  | "top-end"
  | "right"
  | "right-start"
  | "right-end"
  | "bottom"
  | "bottom-start"
  | "bottom-end"
  | "left"
  | "left-start"
  | "left-end";

teethConditions shape:

type ToothConditionGroup = {
  label: string;
  teeth: string[]; // e.g. ["teeth-11", "teeth-12"]
  outlineColor: string;
  fillColor: string;
};

🧩 Common Recipes

1) Render a custom tooltip

import { Odontogram } from "react-odontogram";
import "react-odontogram/style.css";

export default function CustomTooltipExample() {
  return (
    <Odontogram
      tooltip={{
        placement: "top",
        content: (payload) => (
          <div style={{ minWidth: 140 }}>
            <strong>Tooth {payload?.notations.fdi}</strong>
            <div>{payload?.type}</div>
            <small>Universal: {payload?.notations.universal}</small>
          </div>
        ),
      }}
    />
  );
}

2) Change theme and colors

import { Odontogram } from "react-odontogram";
import "react-odontogram/style.css";

export default function ThemeExample() {
  return (
    <Odontogram
      className="my-odontogram"
      theme="dark"
      colors={{
        darkBlue: "#7c9cff",
        baseBlue: "#c7d2fe",
        lightBlue: "#4f46e5",
      }}
    />
  );
}
.my-odontogram {
  --odontogram-tooltip-bg: #0f172a;
  --odontogram-tooltip-fg: #f8fafc;
}

3) Show teethConditions (with legend)

import { Odontogram } from "react-odontogram";
import "react-odontogram/style.css";

const conditions = [
  {
    label: "caries",
    teeth: ["teeth-16", "teeth-26", "teeth-36"],
    fillColor: "#ef4444",
    outlineColor: "#b91c1c",
  },
  {
    label: "filling",
    teeth: ["teeth-14", "teeth-24"],
    fillColor: "#60a5fa",
    outlineColor: "#1d4ed8",
  },
];

export default function ConditionsExample() {
  return <Odontogram teethConditions={conditions} showLabels readOnly />;
}

4) Adjust tooltip position

import { Odontogram } from "react-odontogram";
import "react-odontogram/style.css";

export default function TooltipPositionExample() {
  return (
    <Odontogram
      tooltip={{
        placement: "right-start", // try: top, right, bottom-end, left-start...
        margin: 18, // larger = farther from tooth, smaller = closer
      }}
    />
  );
}

🦷 Tooth Data Model

Each tooth is internally defined in a structured format:

{
  name: "1",
  type: "Central Incisor",
  outlinePath: "...",
  shadowPath: "...",
  lineHighlightPath: "..."
}

This makes it easy to extend or customize if you fork the library.


🧪 Development

Run locally:

git clone https://github.com/biomathcode/react-odontogram.git
cd react-odontogram
pnpm install
pnpm dev

To preview Storybook:

pnpm storybook

🪶 License

MIT © biomathcode


💬 Feedback

If this library helps your dental project, please ⭐ the repo or open issues/PRs for enhancements!