🌐 Languages: 🇬🇧 English | 🇪🇸 Español | 🇩🇪 Deutsch | 🇭🇺 Magyar | 🇮🇹 Italiano | 🇸🇰 Slovenčina | 🇵🇱 Polski | 🇷🇺 Русский
This project is an interactive, browser-based odontogram editor that supports fast dental charting with a clean UI. It renders layered SVG tooth templates to represent restorations, caries, endodontic status, mobility, and other clinical details, while providing multi-select, selection filters, and predefined status presets.
🔗 Test URL: https://react-odontogram-modul.vercel.app/
- 🖱️ Fast selection and multi-select (CMD/CTRL + click)
- 🦷 Tooth types: permanent, primary (milk), implant, subgingival, missing
- 👑 Crown materials: natural (full crown), broken, prepared for crown, radix, e.max, zircon, metal-ceramic, temporary, telescope
- 🔩 Implant abutments: healing abutment, locator, locator with prosthesis, bar, bar with prosthesis
- 🌉 Bridge units: zircon, metal, temporary, removable, bar, bar with prosthesis
- 🔍 Caries charting on 6 surfaces: mesial, distal, buccal, lingual, occlusal, subcrown
- 🪥 Filling materials per surface: amalgam, composite, GIC, temporary
- 🏥 Endodontic states: medicinal filling, root canal filling, incomplete root filling, glass fiber post, metal post, resection, parapulpal pin
- ⚕️ Modifications: periapical inflammation (inside/outside), periodontal disease, mobility grades (M1/M2/M3)
- 🏷️ Special indicators: crown needed, crown replacement needed, missing closed gap, extraction plan, bruxism wear/neck wear, fissure sealing, contact point loss
- 👁️ Occlusal view, wisdom teeth, bone and pulp visibility toggles
- 🔢 12 selection filters (all, present, permanent, milk, implants, missing, upper/lower, front/molars)
- 📊 Predefined status presets (reset, primary dentition, mixed dentition, edentulous)
- 📦 34 predefined restoration templates (bridges, removable dentures, bar dentures with implants)
- 💾 Status export/import in JSON (version 1.3, with plugin custom states and per-tooth notes)
- 🔗 HL7 FHIR R4 export (collection Bundle of per-tooth Observations, ISO 3950 tooth coding, hybrid local+SNOMED codings)
- ✚ Cross/plus surface selection UI (B/M/O/D/L) for caries and fillings
- 🧱 Per-surface restoration materials (mixed fillings, e.g. buccal amalgam + distal composite)
- 🖼️ PNG/JPG/SVG image export of the chart (downloadable; PNG/JPG rasterized from vector SVG)
- 🦷 Secondary (recurrent) caries — auto-derived when caries overlaps a filling
- 🪨 Calculus, root resorption, and typed periapical lesions (granuloma / cyst / abscess)
- 📏 Per-surface caries depth (superficial / dentin / deep), or optional ICDAS II scoring (0–6) via
enableIcdas - 🧰 Unified topbar icon row with a Settings menu (numbering, notes, ICDAS, tooth information)
- 📋 Tooth information panel: live text summary of the whole chart (tooth counts, present/missing lists, caries incl. secondary, fillings, root canals, prosthetics, implants, periodontal status) — shown by default, toggleable in Settings
- 🗂️ Consolidated Export dropdown (Status JSON / FHIR / PNG / JPG)
- 📥 Import dropdown with FHIR import (round-trips exported Bundles)
- ⏳ Progress overlay during image export
- 🎓 12-step interactive intro tour
- 🔢 Three numbering systems (FDI, Universal, Palmer)
- 🌐 I18n (HU/EN/DE/ES/IT/SK/PL/RU) with language switcher (190+ translation keys per language)
- 🌗 Dark mode support with toggle button (standalone or controlled by parent app)
- 🎨 Custom theme configuration (
themeConfigprop) with CSS custom properties (--odon-*) - 📱 Mobile touch UX: tap-to-zoom popover, long-press context menu, pinch-to-zoom, WCAG 44px touch targets, arch toggle navigation
- 🔌 Custom SVG plugin system: inject visual overlays, per-tooth custom state, JSON export/import support
⚠️ State validation warnings for incompatible tooth state combinations- 🏷️ Automatic state tooltip on tooth tiles (shows all active states)
- ♿ Keyboard accessibility (WCAG): ARIA listbox/option roles, Enter/Space selection, arrow key navigation, focus-visible outlines
- 🔒 Read-only mode: disable all interactions for print/report/view use cases
- ✨ Selection animations: pulsing dashed border and glowing drop-shadow on selected teeth (with prefers-reduced-motion support)
- 📝 Per-tooth notes: double-click to add/edit notes, note icon next to tooth number, hover tooltip with note text, JSON export/import
- 🧪 202 automated tests (Vitest) across 16 test files covering numbering, translations, presets, i18n, App component, theme, touch, plugins and accessibility
- 📖 TypeDoc API documentation with JSDoc comments on all public exports (
npm run docs)
- 🦷 Odontogram grid and tooth tile UI
- 🎛️ Controls and status panel
- 🎨 SVG layering engine and templates
- 🔢 Tooth numbering and label mapping (FDI/Universal/Palmer)
- 🌐 Localization (HU/EN/DE/ES/IT/SK/PL/RU)
- 💾 Status export/import
- 📋 Status extras: predefined restoration templates
- 🎨 Theme configuration: customizable color palette via
--odon-*CSS properties - 📱 Mobile touch interactions (tap-to-zoom, long-press, pinch-to-zoom, arch toggle)
- 🔌 Custom SVG plugin system
⚠️ State validation and tooltip system- ♿ Keyboard accessibility and ARIA support
- 🔒 Read-only mode
- ✨ Selection animations
- 📝 Per-tooth notes system
- 🧪 Automated test suite (Vitest + Testing Library)
🔝 Topbar:
- Language switcher (HU/EN/DE/ES/IT/SK/PL/RU dropdown)
- Dark mode toggle button (sun/moon icon, switches between light and dark theme)
- Numbering system switcher (FDI/Universal/Palmer dropdown)
- Export Status / Import Status buttons
📊 Chart header:
- Occlusal view toggle
- Wisdom teeth visibility toggle
- Bone visibility toggle
- Pulp visibility toggle
- Clear selection button
🔍 Selection filters:
- Select All / All Present / Permanent / Milk / Implants / All Missing
- Select Upper / Upper Front 6 / Upper Molars
- Select Lower / Lower Front 6 / Lower Molars
📋 Status presets:
- Reset All (reset mouth)
- Primary Dentition
- Mixed Dentition
- Edentulous toggle
📦 Status extras dropdown:
- Upper/Lower zircon bridges (12-22, 13-23, 16-26, full arch)
- Upper/Lower metal bridges (12-22, 13-23, 16-26, full arch)
- Upper/Lower partial removable dentures
- Upper/Lower full removable dentures
- Upper/Lower bar dentures with implants
Tooth selection (base type):
| Value | Description |
|---|---|
none |
Missing tooth |
tooth-base |
Permanent tooth |
milktooth |
Primary (deciduous) tooth |
implant |
Dental implant |
tooth-under-gum |
Subgingival (unerupted) tooth |
Broken tooth variants:
tooth-broken-inicisal, tooth-broken-distal-inicisal, tooth-broken-distal, tooth-broken-mesial-distal-inicisal, tooth-broken-mesial-distal, tooth-broken-mesial-inicisal, tooth-broken-mesial, no-tooth-after-extraction
Crown materials (permanent teeth):
radix, natural (full crown, default), broken, crownprep (prepared for crown), emax, zircon, metal, temporary, telescope
Crown materials (implants):
natural (none), healing-abutment, zircon, metal, temporary, locator, locator-prosthesis, bar, bar-prosthesis
Bridge units:
none, removable, zircon, metal, temporary, bar, bar-prosthesis
Endodontic options (permanent teeth):
none, endo-medical-filling, endo-filling, endo-filling-incomplete, endo-glass-pin, endo-metal-pin
Endodontic options (milk teeth):
none, endo-medical-filling
Filling materials (permanent teeth):
amalgam, composite, gic, temporary
Filling materials (milk teeth):
composite, gic, temporary
Filling/caries surfaces:
mesial, distal, buccal, lingual, occlusal, subcrown (caries only)
Modifications:
inflammation (periapical), parodontal (periodontal), mobility (M1/M2/M3)
Periapical lesion type (qualifies inflammation):
none, granuloma, cyst, abscess
Caries depth (per surface): superficial / dentin / deep, or optional ICDAS II codes 0–6 when enableIcdas is set
Special indicators:
crownNeeded, crownReplace, missingClosed, extractionPlan, extractionWound, bridgePillar, fissureSealing, contactMesial, contactDistal, bruxismWear, bruxismNeckWear, pulpInflam, endoResection, rootResorption, calculus, parapulpalPin
Tooth templates (in src/assets/teeth-svgs/):
| Template | Teeth using it |
|---|---|
11.svg |
11, 12, 21, 22, 31, 32, 41, 42 (incisors) |
13.svg |
13, 23, 33, 43 (canines) |
14.svg / 14_occl.svg |
14, 15, 24, 25, 34, 35, 44, 45 (premolars) |
16.svg / 16_occl.svg |
16, 17, 18, 26, 27, 28, 36, 37, 38, 46, 47, 48 (molars) |
Templates are rotated 180 degrees for the lower jaw and mirrored horizontally for the left side.
Icon SVGs (in src/assets/icon-svgs/):
icon_8.svg (wisdom), icon_gum.svg (bone), icon_no_selection.svg (clear), icon_occl.svg (occlusal view), icon_pulp.svg (pulp)
FDI (ISO 3950): Adult teeth 11-18, 21-28, 31-38, 41-48. Primary teeth 51-55, 61-65, 71-75, 81-85.
Universal (USA): Adult teeth numbered 1-32. Primary teeth lettered A-T.
Palmer (Zsigmondy-Palmer): Quadrant + position format (e.g. UR-1, LL-5). Primary teeth use letters A-E per quadrant.
Development:
npm install
npm run devBuild:
npm run buildPreview:
npm run previewThe component can be embedded in any React app. Example:
import App from "./App";
export default function Host(){
return (
<App
language="en"
onLanguageChange={(lang) => console.log(lang)}
numberingSystem="FDI"
onNumberingChange={(system) => console.log(system)}
darkMode={false}
onDarkModeChange={(dark) => console.log(dark)}
/>
);
}Dark mode integration:
- Standalone mode: Omit
darkModeprop — the component manages its own theme state via the topbar toggle button and adds/removes the.darkclass on<html>. - Controlled mode: Pass
darkModeandonDarkModeChange— the parent app controls the theme. The toggle button still appears but callsonDarkModeChangeinstead of managing internal state. The parent is responsible for adding/removing the.darkclass on<html>.
Custom theme:
<App
themeConfig={{
colors: {
accent: '#e74c3c',
background: '#fafafa',
text: '#222222',
},
}}
/>Plugin integration:
import App, { type OdontogramPlugin, setPluginState } from "./App";
const myPlugin: OdontogramPlugin = {
id: "implant-brand",
label: { en: "Implant Brand", hu: "Implantátum márka" },
layer: "overlay",
renderSvg: (toothNo, _quadrant, state) => {
if (!state) return null;
return `<text x="16" y="60" font-size="6" fill="#3b7bff">${state}</text>`;
},
};
<App plugins={[myPlugin]} />
// Set plugin state for a tooth:
setPluginState(11, "implant-brand", "Straumann");npm run test # Run all 202 tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage reportnpm run docs # Generate TypeDoc docs in docs/Component props:
| Prop | Type | Default | Description |
|---|---|---|---|
language |
string |
'hu' |
UI language (hu/en/de/es/it/sk/pl/ru) |
onLanguageChange |
(lang) => void |
— | Callback when language changes |
numberingSystem |
string |
'FDI' |
Numbering system (FDI/Universal/Palmer) |
onNumberingChange |
(system) => void |
— | Callback when numbering changes |
darkMode |
boolean |
undefined |
Dark mode state. Omit for standalone mode. |
onDarkModeChange |
(dark) => void |
— | Callback when dark mode toggles. Required for controlled mode. |
themeConfig |
OdontogramThemeConfig |
undefined |
Custom color overrides via CSS custom properties (--odon-*). |
plugins |
OdontogramPlugin[] |
undefined |
Custom SVG plugins for visual overlays and per-tooth custom state. |
readOnly |
boolean |
undefined |
Disable all interactions (click, touch, keyboard). Useful for print/report views. |
enableNotes |
boolean |
undefined |
Enable per-tooth notes. Double-click a tooth to add/edit notes. |
Exported functions for external control:
| Function | Description |
|---|---|
initOdontogram() |
Initialize the engine and render all teeth |
destroyOdontogram() |
Clean up the engine and remove event listeners |
setNumberingSystem(system) |
Switch between FDI, Universal, Palmer |
clearSelection() |
Deselect all teeth |
setOcclusalVisible(on) |
Toggle occlusal view on/off |
setWisdomVisible(on) |
Show/hide wisdom teeth |
setShowBase(on) |
Show/hide bone layer |
setHealthyPulpVisible(on) |
Show/hide healthy pulp |
registerPlugins(plugins) |
Register custom SVG plugins |
setPluginState(toothNo, pluginId, value) |
Set a plugin's custom state for a tooth |
getPluginState(toothNo, pluginId) |
Get a plugin's custom state for a tooth |
getToothStateSummary(toothNo) |
Get localized summary of all active states |
getOdontogramSummary() |
Get a structured, localized text summary of the whole chart (counts, sections) |
onStateChange(callback) |
Subscribe to state changes; returns an unsubscribe function |
setReadOnly(value) |
Enable/disable read-only mode |
getReadOnly() |
Get current read-only state |
setNotesEnabled(value) |
Enable/disable per-tooth notes |
getNotesEnabled() |
Get current notes-enabled state |
exportFhir(options?) |
Export the chart as an HL7 FHIR R4 collection Bundle (JSON download). Optional { subject } reference; otherwise a placeholder Patient is embedded |
exportImage(format) |
Download the chart as an image — "png" or "jpg" |
exportSvg() |
Download the chart as a scalable SVG (vector) |
importFhirBundle(input) |
Import a FHIR R4 Bundle (object or JSON string) produced by this module |
setImportFormat(format) |
Set the next file import's parser — "status" or "fhir" |
startIntroTour() |
Launch the 12-step interactive intro tour |
The export creates a JSON file (version 1.3) containing:
Global fields:
wisdomVisible- wisdom teeth visibleshowBase- bone layer visibleocclusalVisible- occlusal view activeshowHealthyPulp- healthy pulp visibleedentulous- edentulous mode active
Per-tooth fields (32 teeth):
toothSelection- base tooth typecrownMaterial- crown/abutment materialbridgeUnit- bridge connector typeendo- endodontic statemods- modifications array (inflammation, parodontal)caries- active caries surfacesfillingMaterial- filling materialfillingSurfaces- filled surfacespulpInflam- pulp inflammation flagendoResection- apicoectomy flagfissureSealing- fissure sealant flagcontactMesial- mesial contact point losscontactDistal- distal contact point lossbruxismWear- occlusal bruxism wearbruxismNeckWear- cervical bruxism wearbrokenMesial,brokenIncisal,brokenDistal- fracture locationsextractionWound- post-extraction woundextractionPlan- planned extractionparapulpalPin- parapulpal pin flagbridgePillar- bridge abutment toothmobility- mobility grade (none/m1/m2/m3)crownNeeded- crown needed indicatorcrownReplace- crown replacement needed indicatormissingClosed- gap closed after extractioncustomStates- plugin custom states (object, keyed by plugin ID)note- per-tooth text note (string, optional — only present when non-empty)
src/App.tsx- shell UI, topbar controls, language/numbering/dark mode/theme/plugin switchersrc/odontogram.ts- SVG layering engine, tooth state management, touch interactions, plugin overlays, UI wiringsrc/plugin.ts-OdontogramPlugintype,PluginLayer,getQuadrant(),LAYER_Zz-index prioritiessrc/theme.ts-OdontogramThemeConfigtype andapplyThemeConfig()utilitysrc/status_extras.ts- 34 predefined restoration templates (bridges, dentures, bar constructions)src/i18n/- translations (HU/EN/DE/ES/IT/SK/PL/RU) and i18n hooksrc/utils/numbering.ts- FDI, Universal, Palmer numbering conversionsrc/__tests__/- Vitest test suite (202 tests across 16 files)src/assets/teeth-svgs/- SVG tooth templates (6 files: incisors, canines, premolars, molars + occlusal views)src/assets/icon-svgs/- toolbar icon SVGs (5 files)
- React 18 + Vite + TypeScript
- Tailwind CSS for UI styling
- SVG layering via DOM manipulation (non-React state for performance)
- Lightweight custom i18n system
- Vitest + Testing Library for automated tests
- TypeDoc for API documentation
- Vite path alias:
@mapped to./src
- SVG templates are loaded from
src/assets/teeth-svgsandsrc/assets/icon-svgs, so static hosting must serve the public folder. - The odontogram engine uses its own internal state (not React state) for performance and simplicity.
- Milk teeth have a reduced set of available materials (no amalgam fillings, no pin-based endo).
- Implant teeth have a different set of crown/abutment options than natural teeth.
If you use this module in your work, please cite it.
This version (v1.10.0):
Dul, Z. (2026). React Odontogram Modul (v1.10.0). Zenodo. https://doi.org/10.5281/zenodo.21156788
All versions (concept DOI): https://doi.org/10.5281/zenodo.21156787
Machine-readable citation metadata is in CITATION.cff.
Este proyecto es un editor de odontograma interactivo basado en navegador que permite un registro rápido del estado dental con una interfaz limpia. Renderiza plantillas SVG de dientes en capas para representar restauraciones, caries, estado endodóntico, movilidad y otros detalles clínicos, proporcionando selección múltiple, filtros de selección y estados predefinidos.
🔗 Test URL: https://react-odontogram-modul.vercel.app/
- 🖱️ Selección rápida y selección múltiple (CMD/CTRL + clic)
- 🦷 Tipos de dientes: permanente, primario (de leche), implante, subgingival, ausente
- 👑 Materiales de corona: natural (corona completa), fracturada, preparado para corona, radix, e.max, circonio, metal-cerámica, temporal, telescópica
- 🔩 Pilares de implante: pilar de cicatrización, localizador, localizador con prótesis, barra, barra con prótesis
- 🌉 Pónticos: circonio, metal, provisional, removible, barra, barra con prótesis
- 🔍 Registro de caries en 6 superficies: mesial, distal, bucal, lingual, oclusal, subcoronal
- 🪥 Materiales de obturación por superficie: amalgama, composite, ionómero de vidrio, temporal
- 🏥 Estados endodónticos: obturación medicinal, tratamiento de conductos, obturación incompleta, poste de fibra de vidrio, poste metálico, resección, pin parapulpar
- ⚕️ Modificaciones: inflamación periapical (interna/externa), enfermedad periodontal, grados de movilidad (M1/M2/M3)
- 🏷️ Indicadores especiales: corona necesaria, reemplazo de corona necesario, espacio cerrado, plan de extracción, desgaste por bruxismo/desgaste cervical, sellado de fisuras, pérdida de punto de contacto
- 👁️ Vista oclusal, muelas del juicio, visibilidad de hueso y pulpa
- 🔢 12 filtros de selección (todos, presentes, permanentes, de leche, implantes, ausentes, superior/inferior, frontales/molares)
- 📊 Estados predefinidos (restablecer, dentición primaria, dentición mixta, edéntulo)
- 📦 34 plantillas de restauración predefinidas (puentes, prótesis removibles, prótesis con barra e implantes)
- 💾 Exportación/importación de estado en JSON (versión 1.3, con estados personalizados de plugins y notas por diente)
- 🔗 Exportación HL7 FHIR R4 (Bundle de colección con Observations por diente, codificación dental ISO 3950, codificación híbrida local + SNOMED)
- ✚ Selección de superficies en cruz (B/M/O/D/L) para caries y obturaciones
- 🧱 Materiales de obturación por superficie (obturaciones mixtas, p. ej. bucal amalgama + distal composite)
- 🖼️ Exportación de imagen PNG/JPG/SVG del odontograma (descargable; PNG/JPG rasterizado desde SVG vectorial)
- 🦷 Caries secundaria — derivada automáticamente cuando la caries coincide con una obturación
- 🪨 Cálculo, reabsorción radicular y lesiones periapicales tipificadas (granuloma / quiste / absceso)
- 📏 Profundidad de caries por superficie (superficial / dentina / profunda), o puntuación ICDAS II opcional (0–6) con
enableIcdas - 🧰 Barra superior unificada de iconos con menú de Ajustes (numeración, notas, ICDAS, información dental)
- 📋 Panel de información dental: resumen de texto en vivo de todo el odontograma (recuentos de dientes, listas presentes/ausentes, caries incl. secundaria, obturaciones, endodoncias, prótesis, implantes, estado periodontal) — visible por defecto, conmutable en Ajustes
- 🗂️ Menú de exportación unificado (Estado JSON / FHIR / PNG / JPG)
- 📥 Menú de importación con importación FHIR (recupera Bundles exportados)
- ⏳ Superposición de progreso durante la exportación de imagen
- 🎓 Tour interactivo de introducción de 12 pasos
- 🔢 Tres sistemas de numeración (FDI, Universal, Palmer)
- 🌐 I18n (HU/EN/DE/ES/IT/SK/PL/RU) con selector de idioma (190+ claves de traducción por idioma)
- 🌗 Modo oscuro con botón de alternancia (independiente o controlado por la aplicación principal)
- 🎨 Configuración de tema personalizado (prop
themeConfig) con CSS custom properties (--odon-*) - 📱 UX táctil móvil: popover de zoom al tocar, menú contextual con pulsación larga, zoom con pellizco, áreas táctiles WCAG 44px, navegación por arcada
- 🔌 Sistema de plugins SVG personalizados: superposiciones visuales, estado personalizado por diente, soporte de exportación/importación JSON
⚠️ Validación de estado con advertencias para combinaciones incompatibles- 🏷️ Tooltip automático de estado en las losetas dentales (muestra todos los estados activos)
- ♿ Accesibilidad por teclado (WCAG): roles ARIA listbox/option, selección con Enter/Espacio, navegación con flechas, contornos focus-visible
- 🔒 Modo solo lectura: desactivar todas las interacciones para vistas de impresión/informes
- ✨ Animaciones de selección: borde punteado pulsante y sombra brillante en los dientes seleccionados
- 📝 Notas por diente: doble clic para añadir/editar notas, icono de nota junto al número de diente, tooltip con texto de nota, exportación/importación JSON
- 🧪 202 pruebas automatizadas (Vitest) para numeración, traducciones, plantillas, i18n, componente App, tema, táctil, plugins y accesibilidad
- 📖 Documentación API TypeDoc con comentarios JSDoc en todas las exportaciones públicas (
npm run docs)
- 🦷 Cuadrícula del odontograma e interfaz de mosaicos dentales
- 🎛️ Panel de controles y estado
- 🎨 Motor de capas SVG y plantillas
- 🔢 Numeración dental y mapeo de etiquetas (FDI/Universal/Palmer)
- 🌐 Localización (HU/EN/DE/ES/IT/SK/PL/RU)
- 💾 Exportación/importación de estado
- 📋 Extras de estado: plantillas de restauración predefinidas
- 🎨 Configuración de tema: paleta de colores personalizable mediante propiedades CSS
--odon-* - 📱 Interacciones táctiles móviles (zoom al tocar, pulsación larga, zoom con pellizco, alternador de arcada)
- 🔌 Sistema de plugins SVG personalizados
⚠️ Sistema de validación de estado y tooltips- ♿ Accesibilidad por teclado y soporte ARIA
- 🔒 Modo solo lectura
- ✨ Animaciones de selección
- 📝 Notas por diente
- 🧪 Suite de pruebas automatizadas (Vitest + Testing Library)
🔝 Barra superior:
- Selector de idioma (HU/EN/DE/ES/IT/SK/PL/RU desplegable)
- Botón de modo oscuro (icono sol/luna, alterna entre tema claro y oscuro)
- Selector de sistema de numeración (FDI/Universal/Palmer desplegable)
- Botones Exportar estado / Importar estado
📊 Encabezado del gráfico:
- Alternador de vista oclusal
- Alternador de visibilidad de muelas del juicio
- Alternador de visibilidad de hueso
- Alternador de visibilidad de pulpa
- Botón borrar selección
🔍 Filtros de selección:
- Seleccionar todos / Todos presentes / Permanentes / De leche / Implantes / Todos ausentes
- Superior / Superior 6 frontales / Molares superiores
- Inferior / Inferior 6 frontales / Molares inferiores
📋 Estados predefinidos:
- Restablecer todo (restablecer boca)
- Dentición primaria
- Dentición mixta
- Edéntulo alternador
📦 Desplegable de extras de estado:
- Puentes de circonio superiores/inferiores (12-22, 13-23, 16-26, arco completo)
- Puentes metálicos superiores/inferiores (12-22, 13-23, 16-26, arco completo)
- Prótesis parciales removibles superiores/inferiores
- Prótesis completas removibles superiores/inferiores
- Prótesis con barra superiores/inferiores con implantes
Selección de diente (tipo base):
| Valor | Descripción |
|---|---|
none |
Diente ausente |
tooth-base |
Diente permanente |
milktooth |
Diente primario (deciduo) |
implant |
Implante dental |
tooth-under-gum |
Diente subgingival (no erupcionado) |
Variantes de diente fracturado:
tooth-broken-inicisal, tooth-broken-distal-inicisal, tooth-broken-distal, tooth-broken-mesial-distal-inicisal, tooth-broken-mesial-distal, tooth-broken-mesial-inicisal, tooth-broken-mesial, no-tooth-after-extraction
Materiales de corona (dientes permanentes):
radix, natural (corona completa, predeterminado), broken, crownprep (preparado para corona), emax, zircon, metal, temporary, telescope
Materiales de corona (implantes):
natural (ninguno), healing-abutment, zircon, metal, temporary, locator, locator-prosthesis, bar, bar-prosthesis
Pónticos:
none, removable, zircon, metal, temporary, bar, bar-prosthesis
Opciones endodónticas (dientes permanentes):
none, endo-medical-filling, endo-filling, endo-filling-incomplete, endo-glass-pin, endo-metal-pin
Opciones endodónticas (dientes de leche):
none, endo-medical-filling
Materiales de obturación (dientes permanentes):
amalgam, composite, gic, temporary
Materiales de obturación (dientes de leche):
composite, gic, temporary
Superficies de obturación/caries:
mesial, distal, buccal, lingual, occlusal, subcrown (solo caries)
Modificaciones:
inflammation (periapical), parodontal (periodontal), mobility (M1/M2/M3)
Tipo de lesión periapical (califica inflammation):
none, granuloma, cyst, abscess
Profundidad de caries (por superficie): superficial / dentin / deep, o códigos ICDAS II opcionales 0–6 cuando enableIcdas está activado
Indicadores especiales:
crownNeeded, crownReplace, missingClosed, extractionPlan, extractionWound, bridgePillar, fissureSealing, contactMesial, contactDistal, bruxismWear, bruxismNeckWear, pulpInflam, endoResection, rootResorption, calculus, parapulpalPin
Plantillas dentales (src/assets/teeth-svgs/):
| Plantilla | Dientes que la usan |
|---|---|
11.svg |
11, 12, 21, 22, 31, 32, 41, 42 (incisivos) |
13.svg |
13, 23, 33, 43 (caninos) |
14.svg / 14_occl.svg |
14, 15, 24, 25, 34, 35, 44, 45 (premolares) |
16.svg / 16_occl.svg |
16, 17, 18, 26, 27, 28, 36, 37, 38, 46, 47, 48 (molares) |
Las plantillas se rotan 180 grados para la mandíbula inferior y se reflejan horizontalmente para el lado izquierdo.
SVGs de iconos (src/assets/icon-svgs/):
icon_8.svg (muela del juicio), icon_gum.svg (hueso), icon_no_selection.svg (borrar), icon_occl.svg (vista oclusal), icon_pulp.svg (pulpa)
FDI (ISO 3950): Dientes adultos 11-18, 21-28, 31-38, 41-48. Dientes primarios 51-55, 61-65, 71-75, 81-85.
Universal (EE.UU.): Dientes adultos numerados 1-32. Dientes primarios con letras A-T.
Palmer (Zsigmondy-Palmer): Formato cuadrante + posición (ej. UR-1, LL-5). Dientes primarios usan letras A-E por cuadrante.
Desarrollo:
npm install
npm run devBuild:
npm run buildVista previa:
npm run previewEl componente se puede integrar en cualquier aplicación React. Ejemplo:
import App from "./App";
export default function Host(){
return (
<App
language="es"
onLanguageChange={(lang) => console.log(lang)}
numberingSystem="FDI"
onNumberingChange={(system) => console.log(system)}
darkMode={false}
onDarkModeChange={(dark) => console.log(dark)}
/>
);
}Integración del modo oscuro:
- Modo independiente: Omitir la prop
darkMode— el componente gestiona su propio estado de tema a través del botón en la barra superior y añade/elimina la clase.darken<html>. - Modo controlado: Pasar
darkModeyonDarkModeChange— la aplicación principal controla el tema. El botón de alternancia sigue apareciendo pero llama aonDarkModeChangeen lugar de gestionar el estado interno. La aplicación principal es responsable de añadir/eliminar la clase.darken<html>.
Props del componente:
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
language |
string |
'hu' |
Idioma de la UI (hu/en/de/es/it/sk/pl/ru) |
onLanguageChange |
(lang) => void |
— | Callback cuando cambia el idioma |
numberingSystem |
string |
'FDI' |
Sistema de numeración (FDI/Universal/Palmer) |
onNumberingChange |
(system) => void |
— | Callback cuando cambia la numeración |
darkMode |
boolean |
undefined |
Estado del modo oscuro. Omitir para modo independiente. |
onDarkModeChange |
(dark) => void |
— | Callback al alternar modo oscuro. Requerido para modo controlado. |
themeConfig |
OdontogramThemeConfig |
undefined |
Personalización de colores mediante CSS custom properties (--odon-*). |
plugins |
OdontogramPlugin[] |
undefined |
Plugins SVG personalizados para superposiciones visuales y estado personalizado por diente. |
readOnly |
boolean |
undefined |
Desactivar todas las interacciones (clic, táctil, teclado). Útil para vistas de impresión/informes. |
enableNotes |
boolean |
undefined |
Activar notas por diente. Doble clic en un diente para añadir/editar notas. |
Funciones exportadas para control externo:
| Función | Descripción |
|---|---|
initOdontogram() |
Inicializar el motor y renderizar todos los dientes |
destroyOdontogram() |
Limpiar el motor y eliminar los event listeners |
setNumberingSystem(system) |
Cambiar entre FDI, Universal, Palmer |
clearSelection() |
Deseleccionar todos los dientes |
setOcclusalVisible(on) |
Alternar vista oclusal on/off |
setWisdomVisible(on) |
Mostrar/ocultar muelas del juicio |
setShowBase(on) |
Mostrar/ocultar capa de hueso |
setHealthyPulpVisible(on) |
Mostrar/ocultar pulpa sana |
registerPlugins(plugins) |
Registrar plugins SVG personalizados |
setPluginState(toothNo, pluginId, value) |
Establecer estado personalizado del plugin para un diente |
getPluginState(toothNo, pluginId) |
Obtener estado personalizado del plugin de un diente |
getToothStateSummary(toothNo) |
Obtener resumen localizado de todos los estados activos |
getOdontogramSummary() |
Obtener un resumen de texto estructurado y localizado de todo el odontograma (recuentos, secciones) |
onStateChange(callback) |
Suscribirse a los cambios de estado; devuelve una función para cancelar la suscripción |
setReadOnly(value) |
Activar/desactivar modo solo lectura |
getReadOnly() |
Obtener estado actual de solo lectura |
setNotesEnabled(value) |
Activar/desactivar notas por diente |
getNotesEnabled() |
Obtener estado actual de notas |
exportFhir(options?) |
Exportar el odontograma como Bundle de colección HL7 FHIR R4 (descarga JSON). Referencia { subject } opcional; si no, se incluye un Patient de marcador |
exportImage(format) |
Descargar el odontograma como imagen — "png" o "jpg" |
exportSvg() |
Descargar el odontograma como SVG escalable (vectorial) |
importFhirBundle(input) |
Importar un Bundle FHIR R4 (objeto o cadena JSON) producido por este módulo |
setImportFormat(format) |
Definir el parser de la próxima importación — "status" o "fhir" |
startIntroTour() |
Iniciar el tour interactivo de introducción de 12 pasos |
src/App.tsx- UI principal, controles de barra superior, selector de idioma/numeración/modo oscuro/temasrc/odontogram.ts- Motor de capas SVG, gestión de estado dental, cableado UIsrc/plugin.ts- tipoOdontogramPlugin,PluginLayer,getQuadrant(), prioridades ZLAYER_Zsrc/theme.ts- tipoOdontogramThemeConfigy funciónapplyThemeConfig()src/status_extras.ts- 34 plantillas de restauración predefinidas (puentes, prótesis, construcciones con barra)src/i18n/- traducciones (HU/EN/DE/ES/IT/SK/PL/RU) y hook i18nsrc/utils/numbering.ts- conversión de numeración FDI, Universal, Palmersrc/__tests__/- suite de pruebas Vitest (202 pruebas)src/assets/teeth-svgs/- plantillas SVG dentales (6 archivos: incisivos, caninos, premolares, molares + vistas oclusales)src/assets/icon-svgs/- SVGs de iconos de barra de herramientas (5 archivos)
- React 18 + Vite + TypeScript
- Tailwind CSS para estilos de UI
- Capas SVG mediante manipulación del DOM (no React state por rendimiento)
- Sistema i18n propio ligero
- Vitest + Testing Library para pruebas automatizadas
- TypeDoc para documentación de API
- Alias de ruta Vite:
@mapeado a./src
Si utilizas este módulo en tu trabajo, por favor cítalo.
Esta versión (v1.10.0):
Dul, Z. (2026). React Odontogram Modul (v1.10.0). Zenodo. https://doi.org/10.5281/zenodo.21156788
Todas las versiones (DOI de concepto): https://doi.org/10.5281/zenodo.21156787
Los metadatos de citación legibles por máquina están en CITATION.cff.
Created with ❤️ by Zoltan Dul (2026) Released under the MIT License.