react-odontogram 0.5.2 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -90,7 +90,7 @@ export default function App() {
90
90
  The `onChange` callback returns an **array of selected teeth objects**:
91
91
 
92
92
  ```ts
93
- type ToothSelection = {
93
+ type ToothDetail = {
94
94
  id: string;
95
95
  notations: {
96
96
  fdi: string;
@@ -133,16 +133,151 @@ Example JSON output:
133
133
  | Prop | Type | Default | Description |
134
134
  | --- | --- | --- | --- |
135
135
  | `defaultSelected` | `string[]` | `[]` | Tooth IDs selected on first render. |
136
- | `onChange` | `(selectedTeeth: ToothSelection[]) => void` | | Called whenever selection changes. |
136
+ | `singleSelect` | `boolean` | `false` | Allow selecting only one tooth at a time (clicking the selected tooth clears it). |
137
+ | `onChange` | `(selectedTeeth: ToothDetail[]) => void` | — | Called whenever selection changes. |
137
138
  | `name` | `string` | `"teeth"` | Name used for hidden form input. |
138
139
  | `className` | `string` | `""` | Additional class for wrapper customization. |
139
140
  | `theme` | `"light" \| "dark"` | `"light"` | Applies built-in light/dark palette. |
140
141
  | `colors` | `{ darkBlue?: string; baseBlue?: string; lightBlue?: string }` | `{}` | Override palette colors. |
141
142
  | `notation` | `"FDI" \| "Universal" \| "Palmer"` | `"FDI"` | Display notation in native tooth titles/tooltips. |
142
- | `tooltip` | `{ placement?: Placement; margin?: number; content?: ReactNode \| ((payload?: ToothSelection) => ReactNode) }` | `{ placement: "top", margin: 10 }` | Tooltip behavior and custom content renderer. |
143
+ | `tooltip` | `{ placement?: Placement; margin?: number; content?: ReactNode \| ((payload?: ToothDetail) => ReactNode) }` | `{ placement: "top", margin: 10 }` | Tooltip behavior and custom content renderer. |
143
144
  | `showTooltip` | `boolean` | `true` | Enables/disables tooltip rendering. |
144
145
  | `showHalf` | `"full" \| "upper" \| "lower"` | `"full"` | Render full chart or only upper/lower arches. |
145
146
  | `maxTeeth` | `number` | `8` | Number of teeth per quadrant (for baby/mixed dentition views). |
147
+ | `teethConditions` | `ToothConditionGroup[]` | `undefined` | Colorize specific teeth by condition. |
148
+ | `readOnly` | `boolean` | `false` | Disable interactions and selection changes. |
149
+ | `showLabels` | `boolean` | `false` | Show the condition legend under the chart. |
150
+ | `layout` | `"circle" \| "square"` | `"circle"` | Render classic arch layout or square/row layout. |
151
+ | `styles` | `React.CSSProperties` | `undefined` | Inline styles applied to the root container. |
152
+
153
+ `Placement` values:
154
+
155
+ ```ts
156
+ type Placement =
157
+ | "top"
158
+ | "top-start"
159
+ | "top-end"
160
+ | "right"
161
+ | "right-start"
162
+ | "right-end"
163
+ | "bottom"
164
+ | "bottom-start"
165
+ | "bottom-end"
166
+ | "left"
167
+ | "left-start"
168
+ | "left-end";
169
+ ```
170
+
171
+ `teethConditions` shape:
172
+
173
+ ```ts
174
+ type ToothConditionGroup = {
175
+ label: string;
176
+ teeth: string[]; // e.g. ["teeth-11", "teeth-12"]
177
+ outlineColor: string;
178
+ fillColor: string;
179
+ };
180
+ ```
181
+
182
+ ---
183
+
184
+ ## 🧩 Common Recipes
185
+
186
+ ### 1) Render a custom tooltip
187
+
188
+ ```tsx
189
+ import { Odontogram } from "react-odontogram";
190
+ import "react-odontogram/style.css";
191
+
192
+ export default function CustomTooltipExample() {
193
+ return (
194
+ <Odontogram
195
+ tooltip={{
196
+ placement: "top",
197
+ content: (payload) => (
198
+ <div style={{ minWidth: 140 }}>
199
+ <strong>Tooth {payload?.notations.fdi}</strong>
200
+ <div>{payload?.type}</div>
201
+ <small>Universal: {payload?.notations.universal}</small>
202
+ </div>
203
+ ),
204
+ }}
205
+ />
206
+ );
207
+ }
208
+ ```
209
+
210
+ ### 2) Change theme and colors
211
+
212
+ ```tsx
213
+ import { Odontogram } from "react-odontogram";
214
+ import "react-odontogram/style.css";
215
+
216
+ export default function ThemeExample() {
217
+ return (
218
+ <Odontogram
219
+ className="my-odontogram"
220
+ theme="dark"
221
+ colors={{
222
+ darkBlue: "#7c9cff",
223
+ baseBlue: "#c7d2fe",
224
+ lightBlue: "#4f46e5",
225
+ }}
226
+ />
227
+ );
228
+ }
229
+ ```
230
+
231
+ ```css
232
+ .my-odontogram {
233
+ --odontogram-tooltip-bg: #0f172a;
234
+ --odontogram-tooltip-fg: #f8fafc;
235
+ }
236
+ ```
237
+
238
+ ### 3) Show `teethConditions` (with legend)
239
+
240
+ ```tsx
241
+ import { Odontogram } from "react-odontogram";
242
+ import "react-odontogram/style.css";
243
+
244
+ const conditions = [
245
+ {
246
+ label: "caries",
247
+ teeth: ["teeth-16", "teeth-26", "teeth-36"],
248
+ fillColor: "#ef4444",
249
+ outlineColor: "#b91c1c",
250
+ },
251
+ {
252
+ label: "filling",
253
+ teeth: ["teeth-14", "teeth-24"],
254
+ fillColor: "#60a5fa",
255
+ outlineColor: "#1d4ed8",
256
+ },
257
+ ];
258
+
259
+ export default function ConditionsExample() {
260
+ return <Odontogram teethConditions={conditions} showLabels readOnly />;
261
+ }
262
+ ```
263
+
264
+ ### 4) Adjust tooltip position
265
+
266
+ ```tsx
267
+ import { Odontogram } from "react-odontogram";
268
+ import "react-odontogram/style.css";
269
+
270
+ export default function TooltipPositionExample() {
271
+ return (
272
+ <Odontogram
273
+ tooltip={{
274
+ placement: "right-start", // try: top, right, bottom-end, left-start...
275
+ margin: 18, // larger = farther from tooth, smaller = closer
276
+ }}
277
+ />
278
+ );
279
+ }
280
+ ```
146
281
 
147
282
  ---
148
283
 
package/dist/index.css CHANGED
@@ -1,2 +1,2 @@
1
1
  :root{--dark-blue: #3e5edc;--base-blue: #8a98be;--light-blue: #c6ccf8}#storybook-root{width:100%;height:100%}.dark-template{width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:#0b0d1a}.Odontogram{--odontogram-tooltip-bg: rgba(0, 0, 0, .85);--odontogram-tooltip-fg: #fff}.Odontogram.dark-theme{--odontogram-tooltip-bg: rgba(255, 255, 255, .95);--odontogram-tooltip-fg: #000}.Odontogram.dark-theme svg{--dark-blue: #aab6ff;--base-blue: #d0d5f6;--light-blue: #5361e6;background-color:#0b0d1a;color-scheme:dark;color:#e4e6ef}.Odontogram svg{color:var(--base-blue);fill:none;transition:all ease-in 125ms}.Odontogram[data-read-only=true]{pointer-events:none}.Odontogram svg path:nth-of-type(2){opacity:0;transition:all ease-in .2s}.Odontogram svg path[data-colored=true]{opacity:1!important;transition:none}.Odontogram g.selected path:nth-of-type(2){fill:var(--light-blue);opacity:1}.Odontogram g.selected path:first-of-type{transition:stroke 1s ease}.Odontogram g.selected:hover path:first-of-type{stroke:currentColor;stroke-width:1;stroke-linecap:round;stroke-dasharray:4 4;stroke-dashoffset:0;transition:stroke 5s ease;animation:dash-move 1s linear infinite;animation-delay:1s;filter:drop-shadow(0 0 8px currentColor);-webkit-filter:drop-shadow(0 0 8px currentColor)}@keyframes dash-move{to{stroke-dashoffset:8}}.Odontogram g.selected{transition:all .3s ease;color:var(--dark-blue)}.Odontogram g.selected path{stroke-width:1.5}.Odontogram g[class^=teeth-]:hover path:nth-of-type(2){fill:var(--light-blue);opacity:1}.odontogram-tooltip{box-shadow:0 2px 8px #00000026;backdrop-filter:blur(4px)}.Odontogram g[role=option]:focus-visible{outline:4px solid var(--dark-blue)!important}
2
- /*# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3N0eWxlcy5jc3MiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIjpyb290IHtcbiAgLS1kYXJrLWJsdWU6ICMzZTVlZGM7XG4gIC0tYmFzZS1ibHVlOiAjOGE5OGJlO1xuICAtLWxpZ2h0LWJsdWU6ICNjNmNjZjg7XG59XG5cbiNzdG9yeWJvb2stcm9vdCB7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5kYXJrLXRlbXBsYXRlIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGJhY2tncm91bmQtY29sb3I6ICMwYjBkMWE7XG59XG5cbi5PZG9udG9ncmFtIHtcbiAgLS1vZG9udG9ncmFtLXRvb2x0aXAtYmc6IHJnYmEoMCwgMCwgMCwgMC44NSk7XG4gIC0tb2RvbnRvZ3JhbS10b29sdGlwLWZnOiAjZmZmO1xufVxuXG4uT2RvbnRvZ3JhbS5kYXJrLXRoZW1lIHtcbiAgLS1vZG9udG9ncmFtLXRvb2x0aXAtYmc6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC45NSk7XG4gIC0tb2RvbnRvZ3JhbS10b29sdGlwLWZnOiAjMDAwO1xufVxuXG4uT2RvbnRvZ3JhbS5kYXJrLXRoZW1lIHN2ZyB7XG4gIC0tZGFyay1ibHVlOiAjYWFiNmZmO1xuICAtLWJhc2UtYmx1ZTogI2QwZDVmNjtcbiAgLS1saWdodC1ibHVlOiAjNTM2MWU2O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMGIwZDFhO1xuICBjb2xvci1zY2hlbWU6IGRhcms7XG4gIGNvbG9yOiAjZTRlNmVmO1xufVxuXG4uT2RvbnRvZ3JhbSBzdmcge1xuICBjb2xvcjogdmFyKC0tYmFzZS1ibHVlKTtcbiAgZmlsbDogbm9uZTtcbiAgdHJhbnNpdGlvbjogYWxsIGVhc2UtaW4gMTI1bXM7XG59XG5cbi5PZG9udG9ncmFtW2RhdGEtcmVhZC1vbmx5PVwidHJ1ZVwiXSAge1xucG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5PZG9udG9ncmFtIHN2ZyBwYXRoOm50aC1vZi10eXBlKDIpIHtcbiAgb3BhY2l0eTogMDtcbiAgdHJhbnNpdGlvbjogYWxsIGVhc2UtaW4gMjAwbXM7XG59XG5cbi5PZG9udG9ncmFtIHN2ZyBwYXRoW2RhdGEtY29sb3JlZD1cInRydWVcIl0ge1xuICBvcGFjaXR5OiAxICFpbXBvcnRhbnQ7XG4gIHRyYW5zaXRpb246IG5vbmU7XG59XG5cblxuXG4uT2RvbnRvZ3JhbSBnLnNlbGVjdGVkIHBhdGg6bnRoLW9mLXR5cGUoMikge1xuICBmaWxsOiB2YXIoLS1saWdodC1ibHVlKTtcbiAgb3BhY2l0eTogMTtcbn1cblxuLk9kb250b2dyYW0gZy5zZWxlY3RlZCBwYXRoOmZpcnN0LW9mLXR5cGUge1xuICB0cmFuc2l0aW9uOiBzdHJva2UgMXMgZWFzZTtcbn1cblxuLk9kb250b2dyYW0gZy5zZWxlY3RlZDpob3ZlciBwYXRoOmZpcnN0LW9mLXR5cGUge1xuICBzdHJva2U6IGN1cnJlbnRDb2xvcjtcbiAgc3Ryb2tlLXdpZHRoOiAxO1xuICBzdHJva2UtbGluZWNhcDogcm91bmQ7XG4gIHN0cm9rZS1kYXNoYXJyYXk6IDQgNDtcbiAgc3Ryb2tlLWRhc2hvZmZzZXQ6IDA7XG4gIHRyYW5zaXRpb246IHN0cm9rZSA1cyBlYXNlO1xuICBhbmltYXRpb246IGRhc2gtbW92ZSAxcyBsaW5lYXIgaW5maW5pdGU7XG4gIGFuaW1hdGlvbi1kZWxheTogMXM7XG4gIGZpbHRlcjogZHJvcC1zaGFkb3coMCAwIDhweCBjdXJyZW50Q29sb3IpO1xuICAtd2Via2l0LWZpbHRlcjogZHJvcC1zaGFkb3coMCAwIDhweCBjdXJyZW50Q29sb3IpO1xufVxuXG5Aa2V5ZnJhbWVzIGRhc2gtbW92ZSB7XG4gIHRvIHtcbiAgICBzdHJva2UtZGFzaG9mZnNldDogODtcbiAgfVxufVxuXG4uT2RvbnRvZ3JhbSBnLnNlbGVjdGVkIHtcbiAgdHJhbnNpdGlvbjogYWxsIDAuM3MgZWFzZTtcbiAgY29sb3I6IHZhcigtLWRhcmstYmx1ZSk7XG59XG5cbi5PZG9udG9ncmFtIGcuc2VsZWN0ZWQgcGF0aCB7XG4gIHN0cm9rZS13aWR0aDogMS41O1xufVxuXG4uT2RvbnRvZ3JhbSBnW2NsYXNzXj1cInRlZXRoLVwiXTpob3ZlciBwYXRoOm50aC1vZi10eXBlKDIpIHtcbiAgZmlsbDogdmFyKC0tbGlnaHQtYmx1ZSk7XG4gIG9wYWNpdHk6IDE7XG59XG5cbi5vZG9udG9ncmFtLXRvb2x0aXAge1xuICBib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLCAwLCAwLCAwLjE1KTtcbiAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDRweCk7XG59XG5cbi5PZG9udG9ncmFtIGdbcm9sZT1cIm9wdGlvblwiXTpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogNHB4IHNvbGlkIHZhcigtLWRhcmstYmx1ZSkgIWltcG9ydGFudDtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQUFBLE1BQ0UsYUFBYSxRQUNiLGFBQWEsUUFDYixjQUFjLE9BQ2hCLENBRUEsQ0FBQyxlQUNDLE1BQU8sS0FDUCxPQUFRLElBQ1YsQ0FFQSxDQUFDLGNBQ0MsTUFBTyxLQUNQLE9BQVEsS0FDUixRQUFTLEtBQ1QsZ0JBQWlCLE9BQ2pCLFlBQWEsT0FDYixpQkFBa0IsT0FDcEIsQ0FFQSxDQUFDLFdBQ0MseUJBQXlCLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FDdkMseUJBQXlCLElBQzNCLENBRUEsQ0FMQyxVQUtVLENBQUMsV0FDVix5QkFBeUIsS0FBSyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUM3Qyx5QkFBeUIsSUFDM0IsQ0FFQSxDQVZDLFVBVVUsQ0FMQyxXQUtXLElBQ3JCLGFBQWEsUUFDYixhQUFhLFFBQ2IsY0FBYyxRQUNkLGlCQUFrQixRQUNsQixhQUFjLEtBQ2QsTUFBTyxPQUNULENBRUEsQ0FuQkMsV0FtQlcsSUFDVixNQUFPLElBQUksYUFDWCxLQUFNLEtBQ04sV0FBWSxJQUFJLFFBQVEsS0FDMUIsQ0FFQSxDQXpCQyxVQXlCVSxDQUFDLHFCQUNaLGVBQWdCLElBQ2hCLENBRUEsQ0E3QkMsV0E2QlcsSUFBSSxJQUFJLGdCQUNsQixRQUFTLEVBQ1QsV0FBWSxJQUFJLFFBQVEsR0FDMUIsQ0FFQSxDQWxDQyxXQWtDVyxJQUFJLElBQUksQ0FBQyxtQkFDbkIsUUFBUyxZQUNULFdBQVksSUFDZCxDQUlBLENBekNDLFdBeUNXLENBQUMsQ0FBQyxTQUFTLElBQUksZ0JBQ3pCLEtBQU0sSUFBSSxjQUNWLFFBQVMsQ0FDWCxDQUVBLENBOUNDLFdBOENXLENBQUMsQ0FMQyxTQUtTLElBQUksZUFDekIsV0FBWSxPQUFPLEdBQUcsSUFDeEIsQ0FFQSxDQWxEQyxXQWtEVyxDQUFDLENBVEMsUUFTUSxPQUFPLElBQUksZUFDL0IsT0FBUSxhQUNSLGFBQWMsRUFDZCxlQUFnQixNQUNoQixpQkFBa0IsRUFBRSxFQUNwQixrQkFBbUIsRUFDbkIsV0FBWSxPQUFPLEdBQUcsS0FDdEIsVUFBVyxVQUFVLEdBQUcsT0FBTyxTQUMvQixnQkFBaUIsR0FDakIsT0FBUSxZQUFZLEVBQUUsRUFBRSxJQUFJLGNBQzVCLGVBQWdCLFlBQVksRUFBRSxFQUFFLElBQUksYUFDdEMsQ0FFQSxXQU5hLFVBT1gsR0FDRSxrQkFBbUIsQ0FDckIsQ0FDRixDQUVBLENBckVDLFdBcUVXLENBQUMsQ0E1QkMsU0E2QlosV0FBWSxJQUFJLElBQUssS0FDckIsTUFBTyxJQUFJLFlBQ2IsQ0FFQSxDQTFFQyxXQTBFVyxDQUFDLENBakNDLFNBaUNTLEtBQ3JCLGFBQWMsR0FDaEIsQ0FFQSxDQTlFQyxXQThFVyxDQUFDLENBQUMsY0FBZ0IsT0FBTyxJQUFJLGdCQUN2QyxLQUFNLElBQUksY0FDVixRQUFTLENBQ1gsQ0FFQSxDQUFDLG1CQUNDLFdBQVksRUFBRSxJQUFJLElBQUksVUFDdEIsZ0JBQWlCLEtBQUssSUFDeEIsQ0FFQSxDQXhGQyxXQXdGVyxDQUFDLENBQUMsWUFBYyxlQUMxQixRQUFTLElBQUksTUFBTSxJQUFJLHNCQUN6QiIsCiAgIm5hbWVzIjogW10KfQo= */
2
+ /*# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3N0eWxlcy5jc3MiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIjpyb290IHtcblx0LS1kYXJrLWJsdWU6ICMzZTVlZGM7XG5cdC0tYmFzZS1ibHVlOiAjOGE5OGJlO1xuXHQtLWxpZ2h0LWJsdWU6ICNjNmNjZjg7XG59XG5cbiNzdG9yeWJvb2stcm9vdCB7XG5cdHdpZHRoOiAxMDAlO1xuXHRoZWlnaHQ6IDEwMCU7XG59XG5cbi5kYXJrLXRlbXBsYXRlIHtcblx0d2lkdGg6IDEwMCU7XG5cdGhlaWdodDogMTAwJTtcblx0ZGlzcGxheTogZmxleDtcblx0anVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG5cdGFsaWduLWl0ZW1zOiBjZW50ZXI7XG5cdGJhY2tncm91bmQtY29sb3I6ICMwYjBkMWE7XG59XG5cbi5PZG9udG9ncmFtIHtcblx0LS1vZG9udG9ncmFtLXRvb2x0aXAtYmc6IHJnYmEoMCwgMCwgMCwgMC44NSk7XG5cdC0tb2RvbnRvZ3JhbS10b29sdGlwLWZnOiAjZmZmO1xufVxuXG4uT2RvbnRvZ3JhbS5kYXJrLXRoZW1lIHtcblx0LS1vZG9udG9ncmFtLXRvb2x0aXAtYmc6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC45NSk7XG5cdC0tb2RvbnRvZ3JhbS10b29sdGlwLWZnOiAjMDAwO1xufVxuXG4uT2RvbnRvZ3JhbS5kYXJrLXRoZW1lIHN2ZyB7XG5cdC0tZGFyay1ibHVlOiAjYWFiNmZmO1xuXHQtLWJhc2UtYmx1ZTogI2QwZDVmNjtcblx0LS1saWdodC1ibHVlOiAjNTM2MWU2O1xuXHRiYWNrZ3JvdW5kLWNvbG9yOiAjMGIwZDFhO1xuXHRjb2xvci1zY2hlbWU6IGRhcms7XG5cdGNvbG9yOiAjZTRlNmVmO1xufVxuXG4uT2RvbnRvZ3JhbSBzdmcge1xuXHRjb2xvcjogdmFyKC0tYmFzZS1ibHVlKTtcblx0ZmlsbDogbm9uZTtcblx0dHJhbnNpdGlvbjogYWxsIGVhc2UtaW4gMTI1bXM7XG59XG5cbi5PZG9udG9ncmFtW2RhdGEtcmVhZC1vbmx5PVwidHJ1ZVwiXSB7XG5cdHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuXG4uT2RvbnRvZ3JhbSBzdmcgcGF0aDpudGgtb2YtdHlwZSgyKSB7XG5cdG9wYWNpdHk6IDA7XG5cdHRyYW5zaXRpb246IGFsbCBlYXNlLWluIDIwMG1zO1xufVxuXG4uT2RvbnRvZ3JhbSBzdmcgcGF0aFtkYXRhLWNvbG9yZWQ9XCJ0cnVlXCJdIHtcblx0b3BhY2l0eTogMSAhaW1wb3J0YW50O1xuXHR0cmFuc2l0aW9uOiBub25lO1xufVxuXG4uT2RvbnRvZ3JhbSBnLnNlbGVjdGVkIHBhdGg6bnRoLW9mLXR5cGUoMikge1xuXHRmaWxsOiB2YXIoLS1saWdodC1ibHVlKTtcblx0b3BhY2l0eTogMTtcbn1cblxuLk9kb250b2dyYW0gZy5zZWxlY3RlZCBwYXRoOmZpcnN0LW9mLXR5cGUge1xuXHR0cmFuc2l0aW9uOiBzdHJva2UgMXMgZWFzZTtcbn1cblxuLk9kb250b2dyYW0gZy5zZWxlY3RlZDpob3ZlciBwYXRoOmZpcnN0LW9mLXR5cGUge1xuXHRzdHJva2U6IGN1cnJlbnRDb2xvcjtcblx0c3Ryb2tlLXdpZHRoOiAxO1xuXHRzdHJva2UtbGluZWNhcDogcm91bmQ7XG5cdHN0cm9rZS1kYXNoYXJyYXk6IDQgNDtcblx0c3Ryb2tlLWRhc2hvZmZzZXQ6IDA7XG5cdHRyYW5zaXRpb246IHN0cm9rZSA1cyBlYXNlO1xuXHRhbmltYXRpb246IGRhc2gtbW92ZSAxcyBsaW5lYXIgaW5maW5pdGU7XG5cdGFuaW1hdGlvbi1kZWxheTogMXM7XG5cdGZpbHRlcjogZHJvcC1zaGFkb3coMCAwIDhweCBjdXJyZW50Q29sb3IpO1xuXHQtd2Via2l0LWZpbHRlcjogZHJvcC1zaGFkb3coMCAwIDhweCBjdXJyZW50Q29sb3IpO1xufVxuXG5Aa2V5ZnJhbWVzIGRhc2gtbW92ZSB7XG5cdHRvIHtcblx0XHRzdHJva2UtZGFzaG9mZnNldDogODtcblx0fVxufVxuXG4uT2RvbnRvZ3JhbSBnLnNlbGVjdGVkIHtcblx0dHJhbnNpdGlvbjogYWxsIDAuM3MgZWFzZTtcblx0Y29sb3I6IHZhcigtLWRhcmstYmx1ZSk7XG59XG5cbi5PZG9udG9ncmFtIGcuc2VsZWN0ZWQgcGF0aCB7XG5cdHN0cm9rZS13aWR0aDogMS41O1xufVxuXG4uT2RvbnRvZ3JhbSBnW2NsYXNzXj1cInRlZXRoLVwiXTpob3ZlciBwYXRoOm50aC1vZi10eXBlKDIpIHtcblx0ZmlsbDogdmFyKC0tbGlnaHQtYmx1ZSk7XG5cdG9wYWNpdHk6IDE7XG59XG5cbi5vZG9udG9ncmFtLXRvb2x0aXAge1xuXHRib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLCAwLCAwLCAwLjE1KTtcblx0YmFja2Ryb3AtZmlsdGVyOiBibHVyKDRweCk7XG59XG5cbi5PZG9udG9ncmFtIGdbcm9sZT1cIm9wdGlvblwiXTpmb2N1cy12aXNpYmxlIHtcblx0b3V0bGluZTogNHB4IHNvbGlkIHZhcigtLWRhcmstYmx1ZSkgIWltcG9ydGFudDtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQUFBLE1BQ0MsYUFBYSxRQUNiLGFBQWEsUUFDYixjQUFjLE9BQ2YsQ0FFQSxDQUFDLGVBQ0EsTUFBTyxLQUNQLE9BQVEsSUFDVCxDQUVBLENBQUMsY0FDQSxNQUFPLEtBQ1AsT0FBUSxLQUNSLFFBQVMsS0FDVCxnQkFBaUIsT0FDakIsWUFBYSxPQUNiLGlCQUFrQixPQUNuQixDQUVBLENBQUMsV0FDQSx5QkFBeUIsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUN2Qyx5QkFBeUIsSUFDMUIsQ0FFQSxDQUxDLFVBS1UsQ0FBQyxXQUNYLHlCQUF5QixLQUFLLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQzdDLHlCQUF5QixJQUMxQixDQUVBLENBVkMsVUFVVSxDQUxDLFdBS1csSUFDdEIsYUFBYSxRQUNiLGFBQWEsUUFDYixjQUFjLFFBQ2QsaUJBQWtCLFFBQ2xCLGFBQWMsS0FDZCxNQUFPLE9BQ1IsQ0FFQSxDQW5CQyxXQW1CVyxJQUNYLE1BQU8sSUFBSSxhQUNYLEtBQU0sS0FDTixXQUFZLElBQUksUUFBUSxLQUN6QixDQUVBLENBekJDLFVBeUJVLENBQUMscUJBQ1gsZUFBZ0IsSUFDakIsQ0FFQSxDQTdCQyxXQTZCVyxJQUFJLElBQUksZ0JBQ25CLFFBQVMsRUFDVCxXQUFZLElBQUksUUFBUSxHQUN6QixDQUVBLENBbENDLFdBa0NXLElBQUksSUFBSSxDQUFDLG1CQUNwQixRQUFTLFlBQ1QsV0FBWSxJQUNiLENBRUEsQ0F2Q0MsV0F1Q1csQ0FBQyxDQUFDLFNBQVMsSUFBSSxnQkFDMUIsS0FBTSxJQUFJLGNBQ1YsUUFBUyxDQUNWLENBRUEsQ0E1Q0MsV0E0Q1csQ0FBQyxDQUxDLFNBS1MsSUFBSSxlQUMxQixXQUFZLE9BQU8sR0FBRyxJQUN2QixDQUVBLENBaERDLFdBZ0RXLENBQUMsQ0FUQyxRQVNRLE9BQU8sSUFBSSxlQUNoQyxPQUFRLGFBQ1IsYUFBYyxFQUNkLGVBQWdCLE1BQ2hCLGlCQUFrQixFQUFFLEVBQ3BCLGtCQUFtQixFQUNuQixXQUFZLE9BQU8sR0FBRyxLQUN0QixVQUFXLFVBQVUsR0FBRyxPQUFPLFNBQy9CLGdCQUFpQixHQUNqQixPQUFRLFlBQVksRUFBRSxFQUFFLElBQUksY0FDNUIsZUFBZ0IsWUFBWSxFQUFFLEVBQUUsSUFBSSxhQUNyQyxDQUVBLFdBTlksVUFPWCxHQUNDLGtCQUFtQixDQUNwQixDQUNELENBRUEsQ0FuRUMsV0FtRVcsQ0FBQyxDQTVCQyxTQTZCYixXQUFZLElBQUksSUFBSyxLQUNyQixNQUFPLElBQUksWUFDWixDQUVBLENBeEVDLFdBd0VXLENBQUMsQ0FqQ0MsU0FpQ1MsS0FDdEIsYUFBYyxHQUNmLENBRUEsQ0E1RUMsV0E0RVcsQ0FBQyxDQUFDLGNBQWdCLE9BQU8sSUFBSSxnQkFDeEMsS0FBTSxJQUFJLGNBQ1YsUUFBUyxDQUNWLENBRUEsQ0FBQyxtQkFDQSxXQUFZLEVBQUUsSUFBSSxJQUFJLFVBQ3RCLGdCQUFpQixLQUFLLElBQ3ZCLENBRUEsQ0F0RkMsV0FzRlcsQ0FBQyxDQUFDLFlBQWMsZUFDM0IsUUFBUyxJQUFJLE1BQU0sSUFBSSxzQkFDeEIiLAogICJuYW1lcyI6IFtdCn0K */
package/dist/index.d.mts CHANGED
@@ -43,6 +43,7 @@ interface TeethProps {
43
43
  interface OdontogramProps {
44
44
  name?: string;
45
45
  defaultSelected?: string[];
46
+ singleSelect?: boolean;
46
47
  onChange?: (selected: ToothDetail[]) => void;
47
48
  className?: string;
48
49
  selectedColor?: string;
@@ -61,7 +62,7 @@ interface OdontogramProps {
61
62
  teethConditions?: ToothConditionGroup[];
62
63
  readOnly?: boolean;
63
64
  showLabels?: boolean;
64
- layout?: 'circle' | 'square';
65
+ layout?: "circle" | "square";
65
66
  styles?: CSSProperties;
66
67
  }
67
68
  type ToothConditionGroup = {
@@ -71,8 +72,8 @@ type ToothConditionGroup = {
71
72
  fillColor: string;
72
73
  };
73
74
 
74
- type Layout = 'circle' | 'square';
75
- type ShowHalf = 'full' | 'upper' | 'lower';
75
+ type Layout = "circle" | "square";
76
+ type ShowHalf = "full" | "upper" | "lower";
76
77
  declare function getViewBox(layout: Layout, showHalf: ShowHalf): string;
77
78
  declare const Odontogram: FC<OdontogramProps>;
78
79
 
package/dist/index.d.ts CHANGED
@@ -43,6 +43,7 @@ interface TeethProps {
43
43
  interface OdontogramProps {
44
44
  name?: string;
45
45
  defaultSelected?: string[];
46
+ singleSelect?: boolean;
46
47
  onChange?: (selected: ToothDetail[]) => void;
47
48
  className?: string;
48
49
  selectedColor?: string;
@@ -61,7 +62,7 @@ interface OdontogramProps {
61
62
  teethConditions?: ToothConditionGroup[];
62
63
  readOnly?: boolean;
63
64
  showLabels?: boolean;
64
- layout?: 'circle' | 'square';
65
+ layout?: "circle" | "square";
65
66
  styles?: CSSProperties;
66
67
  }
67
68
  type ToothConditionGroup = {
@@ -71,8 +72,8 @@ type ToothConditionGroup = {
71
72
  fillColor: string;
72
73
  };
73
74
 
74
- type Layout = 'circle' | 'square';
75
- type ShowHalf = 'full' | 'upper' | 'lower';
75
+ type Layout = "circle" | "square";
76
+ type ShowHalf = "full" | "upper" | "lower";
76
77
  declare function getViewBox(layout: Layout, showHalf: ShowHalf): string;
77
78
  declare const Odontogram: FC<OdontogramProps>;
78
79