Repository navigation
Releases: ZoliQua/React-Advanced-Odontogram
Release list
v2.5.0
Added
-
Engine CodeSystem embedded in the FHIR export (issue #23 follow-up). The
Bundle now carries the engine's ownCodeSystemresource (canonical
…/fhir/CodeSystem/odontogram, placed right after the Patient) enumerating
every code the export can emit under the local system — finding types taken
straight from the clinical-axis registry, every enum value (repeated bare codes
such asnone/mesial/temporaryare merged, their alternative displays kept
as designations), the periodontal panel/index/qualifier codes, the 2017 stage/
grade/extent summaries and case-condition laterality. Validators can therefore
resolve the local codes from the Bundle itself instead of timing out on an
unpublished system. Opt out withincludeCodeSystem: falsein the FHIR export
options. The same resource is published asfhir/CodeSystem-odontogram.json
(npm run fhir:codesystemregenerates it; a test keeps it in step with the
generator, and a maximal-export test proves every emitted local code is
covered). Plugin-definedcustom-state:<pluginId>codes stay open-ended by
design. -
Guided tour: Diagnoses steps. Two new tour steps introduce the per-tooth
Diagnoses card and the Case / regional diagnoses pop-up button (18 steps in
total), in all 12 UI languages. -
README refresh in all 12 languages: the project logo at the top, a pointer
to the official Angular port (Angular Advanced Odontogram) under the API-docs
link, the author linked to LinkedIn in the license section, and the 2.5.0
features (Diagnoses card controls, the case-diagnoses pop-up, the official
NEAK BNO-10 titles, the validator-clean FHIR export with the embedded
CodeSystem). -
Dental diagnosis coding (DX-0 foundation). Charted findings now export as
FHIRConditionresources with a WHO ICD-10 base coding, plus an optional
pluggable national code pack (Settings → General → Diagnosis coding system;
ships WHO-only + BNO-10). DX-0 covers caries (K02) and refactors the perio
(K05) Condition to share the coding builder (default output unchanged). More
findings, the diagnosis picker, and further packs (US ICD-10-CM, SNOMED) follow
in later sub-projects. -
Dental diagnosis coding: charted findings (DX-1). Beyond caries, the FHIR
export now derives WHO ICD-10Conditions for pulp (K04.0/.1), apical
(K04.4-.9, radicular cyst K04.8), root caries (K02.2/.3), tooth wear (K03.0-.2,
.8), resorption (K03.3), calculus (K03.6), discoloration (K00.3/.8, K03.7),
tooth loss (K08.1) and retained root (K08.3) — one Condition per finding per
tooth, presence-gated. Fractures and peri-implant disease are not yet coded
(no WHO ICD-10 code). The active national pack (e.g. BNO-10) still overlays. -
Dental diagnosis coding: per-tooth picker + overrides (DX-2). A new
Diagnoses card lists a tooth's chart-derived ICD-10 diagnoses and lets the
clinician suppress one or add a tooth-level diagnosis the chart does not
represent; the effective coded set (derived − suppressed + added) drives the
FHIR export and the coded-diagnoses summary/tooltip. Payload 2.21 (additive
dxOverrides); the visual chart is unaffected. -
Guided intro tour, reworked and extended. The tour now steps with the left
and right arrow keys (a teardown bug used to unbind the keyboard handler after
the first step), targets the real restoration control instead of a control that
no longer exists, points the numbering step at Settings (where numbering now
lives) and the language step at the language menu, and grows from 12 to 16 steps
with new steps for root canal treatment and the periodontal view (it switches
into the periodontal view and back, and skips those steps when the periodontal
chart is turned off). The Intro toolbar icon is now a play in a circle. -
About and credits popup. A new toolbar button after Import opens an About
and credits dialog with a short program description, a contributor list that
links each person to their GitHub profile, the external libraries the app is
built with, an invitation to open a pull request, and a Star on GitHub badge. A
GitHub link is also added to the toolbar. Translated into all 12 UI languages. -
Community health files. Added
CODE_OF_CONDUCT.md,CONTRIBUTING.mdand
SECURITY.md, and a Credits section to every language README inlang/. -
Selectable tooth-anatomy profile (Settings → Odontogram → Tooth anatomy;
#18/#22). A new session-level setting chooses the tooth-anatomy profile:
classic (the default, unchanged) or measured. The measured profile
renders nine literature-measured tooth templates in a two-arch, per-tooth-width
layout (from the cognovis "candidate anatomy" work), switchable at runtime via
the shared session. Thetools/toothgenPython generator (dev-only, out of the
npm package) regenerates the measured drawings from their hand-authored source
SVGs. No payload/render change for the classic profile; goldens byte-identical.
Known limitation: the measured molar templates 17/46 omit ~16 milktooth /
pulp-inflammation layers, so those specific findings do not draw on those
positions in the measured profile. -
Composable UI: declarative control cards (issue #20, Tier 3). The control
cards are being converted from imperative id-bound wiring to self-contained
declarative React components (followingPerioSidebar), one per release step,
each reading engine state via a newuseEngineState()hook and writing through
new getters/selection-setters. Converted so far: the Orthodontics card
(OrthodonticsCard;getActiveOrtho(),setOrtho{Appliance,Drift,Vertical,Rotation}ForSelection)
the Statuses card body (StatusesCard;getEdentulous(),resetMouth(),
reusingsetEdentulous/applyPrimaryDentition/applyMixedDentition/getStatusExtras/applyStatusExtra)
— also fully declarativizing the Edentulous toggle (itsaria-pressednow derives
from state, replacing the delegated handler + imperative syncs) — and the
Caries card body (CariesCard+ a reusableSurfaceCrossper-surface grid
component;getActiveCaries()+ its selection setters), and the Fillings card
body (FillingsCard, reusingSurfaceCrosswith the recurrent-caries + defect
indicators and the simple/complex mode swap;getActiveFillings()+ its setters),
and the Root / periodontium card body (RootPeriodontiumCard;
getActiveRootPerio()+ its setters — pulp/endo optgroups with the endo↔pulpDx
exclusion, apical/resorption/mobility/peri-implant/calculus/mods; the 6-site
probing grid stays imperative for now), and the Tooth details card body
(ToothDetailsCard;getActiveToothDetails()+ its setters +resetTooth()—
base/substrate/restoration with per-tooth option lists and${type}|${material}
encode/decode, wear/discoloration, and the full row-visibility sweep incl. the
#extractionPlanRowreparenting). With this, all six control cards are
declarative:wireControls()/syncControlsFromState()no longer build or sync
any control card, and the imperativebuildSelectmachinery is removed (only the
carved-out 6-site perio probing grid remains imperative). Behavior and rendered
DOM are unchanged. No payload/FHIR/render change; all goldens byte-identical;
payload version unchanged. -
Composable UI: on-demand surfaces (issue #20, Tier 2). Control wiring is now
re-runnable / idempotent, so a surface can unmount and remount (e.g. mount on
demand in a drawer or tab) — the Tier 1 "mount every surface before init / hide
with CSS rather than unmount" constraint is lifted. New exportedrewireControls()
andrebuildGrid()let a remounting surface rebind its fresh DOM (surfaces do this
automatically on mount). Internally, per-element binding is deduplicated via a
WeakMapmarker (replacing the one-shotcontrolsWiredguard), and the three
former hide-instead-of-unmount workarounds (the control panel across the perio
view, the chart column in the Dental Chart segment, and the Status|Plan toggle) are
now real conditional mounts.OdontogramShell's default composition is unchanged
and still renders byte-identical DOM. No payload/FHIR/render change; all goldens
byte-identical; payload version unchanged. -
Composable UI surfaces (issue #20, Tier 1). The shell's four UI regions are
now exported as standalone components —OdontogramTopbar,
OdontogramChartSurface,ToothInfoSurface,ToothControlsSurface— that a
host can place in its own layout regions, together with a new
OdontogramProviderand auseOdontogramUi()hook (plus the
OdontogramUiContextValuetype) for building custom surfaces. All surfaces
share one package-owned session through the provider.OdontogramShellis
unchanged and remains the supported all-in-one component — it is now a thin
composition of these surfaces under the provider, and its rendered DOM is
byte-identical to before (frozen by a new shell DOM-parity test). Tier 1
keeps two documented constraints (one provider per document; surfaces mounted
beforeinitOdontogram()and hidden with CSS rather than unmounted); later
tiers lift them. Session/composition only — no payload/FHIR/render change;
SVG-fingerprint, FHIR-golden, and roundtrip fixtures byte-identical; payload
version unchanged. -
Fillings settings as controlled props (issue #17).
<OdontogramShell>
now accepts the four fillings-tab settings as optional props —
fillingComplexity?: "complex" | "simple",
fillingDefectEnabled?: boolean,
fillingMaterialAvailability?: Record<string, boolean>(over
"amalgam" | "composite" | "gic" | "temporary", unknown keys ignored), and
fissureSealingEnabled?: boolean— plus their write-back callbacks
onFillingComplexityChange(v),onFillingDefectEnabledChange(v),
onFillingMaterialAvailabilityChange(material, enabled)(...
v2.4.0
React Advanced Odontogram v2.4.0
Added
- Opt-in localStorage persistence —
enablePersistence/disablePersistence/clearPersistedState/isPersistenceEnabled; disabled by default, size-guarded, never throws. Saves are debounced (an edit burst coalesces into one write). - FHIR: deciduous ISO 3950 tooth codes for milk teeth (51-85), with lossless import mapping.
- FHIR: ICDAS/CARS scoring coding on caries components (ICDAS on primary surfaces, CARS on recurrent).
- Settings panel reorganization (General / Odontogram / Periodontal Chart / Tooth details / Caries / Fillings / Export Settings) plus new availability controls, on-screen tooth spacing/number size, selection colour/border, and a new Fillings tab.
- Collapsible panel state + API —
getCollapsedCards/isCardCollapsed/setCollapsedCard/toggleCollapsedCard; session-only UI state, not serialized to the payload. - CSP meta tag injected into the demo production build.
Changed
- Export Settings now apply to the PNG/JPG/SVG image exports, not just the PDF report.
- Fissure sealing is now offered on premolars as well as molars.
- Idempotent session-flag setters (no redundant re-render when the value is unchanged).
Fixed
- The grouped dentition-summary table is now legible in dark mode.
Security
- Plugin
renderSvg()output is sanitized with DOMPurify before insertion; structural (non-regex) unwrap closes an</svg>-breakout gap. - SNOMED dev server hardened;
npm auditdev-dependency vulnerabilities fixed (0 remaining).
Docs
- Codebase-wide comment cleanup; full pt-br and fr README re-translations.
Full details in CHANGELOG.md.
v2.3.0 — Multilingual PDF report, perio/odontogram sync
See CHANGELOG.md [2.3.0] for full details.
Highlights:
- Multilingual PDF report: bundled Unicode fonts (Latin/Cyrillic + lazy-loaded Arabic & Chinese) so every UI language renders correctly, colour themes, grouped dentition-summary table, computed age, footer.
- Periodontal chart now syncs with the odontogram: missing teeth draw no crown, primary teeth use deciduous artwork; tooth-spacing distortion fixed.
- Dynamic perio abbreviation glossary; findings/implants layout cleanup.
- Dev: ESLint config usable again (ignores dist/docs), dead code removed.
v2.2.0
Published on npm: react-advanced-odontogram@2.2.0 (with build provenance).
```bash
npm install react-advanced-odontogram react react-dom
```
Added
- French (
fr) UI language — 12 UI languages total (machine-translated, native-speaker review pending). Contributed by @yassine-bhn (#13, closes #12). - Expanded public API — state hydration & lifecycle now exported:
initOdontogram/destroyOdontogram,getStatusChart/getPlanChart/setPlanChart,getChartMode/setChartMode,getPlanChanges,exportStatus/importStatus,openPerioOverlay/closePerioOverlay/isPerioOverlayOpen,hasAnyPerioData,exportPdf/exportPerioImage/exportPerioSvg,setNumberingSystem. Contributed by @odontodev (#14).
Security
- jspdf 4.1.0 → 4.2.1 — resolves 3 high-severity advisories (SNYK-JS-JSPDF-15322679 / -15322681 / -15322684). Based on Snyk PR #11.
Changed
- README restructured for npm: per-language documentation links at the top (English first, then alphabetical); demo & API links on separate lines; fixed the demo URL.
📚 API docs: https://zoliqua.github.io/React-Odontogram-Modul/ · 📓 CHANGELOG
v2.1.0
Published on npm: react-advanced-odontogram@2.1.0 (with build provenance).
```bash
npm install react-advanced-odontogram react react-dom
```
Changed (packaging — no runtime behavior/API/payload change)
- Dependency diet: removed unused
react-router-dom,react-hook-form,nanoid; the only runtime dependency is nowjspdf. jspdflazy-loaded via dynamicimport()on the PDF-export path — it (and html2canvas/dompurify) stays out of consumers' main bundle.- Single bundled
index.d.ts(api-extractor) instead of 37 per-file.d.ts— cleaner types, resolves under node16/nodenext. - npm-friendly README with absolute image URLs (images now render on npmjs.com); full English/Spanish docs moved to
lang/README-en.md/lang/README-es.md.
📚 API docs: https://zoliqua.github.io/React-Odontogram-Modul/ · 📓 CHANGELOG
v2.0.2
Published on npm: react-odontogram-modul@2.0.2 (with build provenance).
```bash
npm install react-odontogram-modul react react-dom
```
Changed
- Docs: every language README now shows a language-specific Overview screenshot and a periodontal-chart screenshot above the periodontal-charting feature (11 languages).
- Source: added the author name-tag header to every
.ts/.tsxfile (comment-only — no behavior change). - API docs: project renamed to React Odontogram Module; TypeDoc regenerated.
📚 API docs: https://zoliqua.github.io/React-Odontogram-Modul/
📓 Full changelog: CHANGELOG.md
v2.0.1
Published on npm: react-odontogram-modul@2.0.1 (with build provenance).
```bash
npm install react-odontogram-modul react react-dom
```
Changed
- Docs: added a live npm version badge (shields.io → npmjs.com) to every language README, placed just before the MIT license badge. Regenerated the TypeDoc API docs. No code, API, behavior, or payload change.
📚 API docs: https://zoliqua.github.io/React-Odontogram-Modul/
📓 Full changelog: CHANGELOG.md
This is the first release published through the automated tag-triggered publish.yml workflow (npm publish + provenance). v2.0.0 was the initial npm publication as `react-odontogram-modul` (major distribution-model release: React → peerDependency, ESM-only, self-contained inlined SVG assets, separate `style.css`).
v1.10.0 — Tooth information panel, crown-prep type & multilingual docs
First tagged release since v1.4.2 — version 1.10.0 also brings everything developed across 1.5.0 – 1.9.0. See CHANGELOG.md for full details.
✨ Highlights (1.10.0)
- 📋 Tooth information panel — a live textual summary of the whole chart: tooth counts, present/missing lists, and Caries (incl. secondary) / Fillings / Root canals / Prosthetics / Implants (only when present) / periodontal status. Shown by default; toggleable in the Settings menu. Plural-aware phrasing per language.
- New public API:
getOdontogramSummary()(structured, localized summary) andonStateChange(callback)(subscribe to state changes; returns an unsubscribe function). - Dynamic topbar subtitle reflecting the current language, numbering system, and light/dark mode.
crownprep("Prepared for crown") as a permanent-tooth crown material — moved from the Base dropdown into the Crown dropdown; mirrors the "broken" crown behavior. Crown list reordered withradixfirst; default staysnatural(Full crown).- Multilingual README overhaul —
README.mdnow holds English + Spanish, with standalone per-language files underlang/(de, hu, it, sk, pl, ru), all translated from the English base.
🛠️ Fixes
- Global visibility toggles (wisdom/occlusal/bone/pulp/edentulous) and card collapse now use delegated listeners, surviving React StrictMode's double mount instead of cancelling themselves out — this also restored the periodontal/periapical inflammation buttons.
- Inflammation glyph z-order: when
endo-resectionand/orendo-resorptionis active together with an inflammation glyph, the inflammation group is lifted above the tooth group (keeping the lower-jaw mirror transform) so the glyph stays visible. - Re-normalized the tooth 14 SVG to the current layer format; calculus row spacing; no tooth-base gloss on broken/radix crowns.
📦 Also included since v1.4.2
- 1.9.0 — Unified topbar icon row; optional ICDAS II per-surface caries scoring (0–6).
- 1.8.0 / 1.8.1 — Clinical marking layers (calculus, root resorption, secondary caries, typed periapical lesions: granuloma / cyst / abscess); native SVG export; per-surface caries depth.
- 1.7.0 — Consolidated Export / Import dropdowns; HL7 FHIR R4 import (round-trip); phased progress overlay; 12-step interactive intro tour.
- 1.6.0 — Cross/plus surface selection UI (B/M/O/D/L); per-surface restoration materials (mixed fillings); PNG/JPG export.
- 1.5.0 — HL7 FHIR R4 export (per-tooth Observations, ISO 3950 coding, hybrid local + SNOMED); MIT license; English default language.
🧪 Quality
- 202 automated tests (Vitest) across 16 test files.
- TypeScript strict build; TypeDoc API documentation.
Full changelog: https://github.com/ZoliQua/React-Odontogram-Modul/blob/v1.10.0/CHANGELOG.md
Compare: v1.4.2...v1.10.0
v1.4.2 — Per-Tooth Notes System
What's New
Per-Tooth Notes
- Double-click any tooth tile to open a note editor popover
- Popover positioned near the tooth with viewport clamping
- Save and Delete buttons for note management
- Note icon (📝) displayed next to the tooth number in label cells
- Note text shown in hover tooltips with 📝 prefix
- Touch support: "Note" button in the zoom popover on touch devices
- Read-only mode guard: editor does not open in read-only mode
Togglable via Prop
- New
enableNotesprop on theAppcomponent (default:false) - New
setNotesEnabled(value)/getNotesEnabled()API functions - Notes are opt-in — host app controls whether notes are available
JSON Export/Import
- Notes included in JSON export (optional field, only when non-empty)
- Notes restored on JSON import
- JSON version bumped to 1.3 (backward compatible)
New i18n Keys
note.title,note.save,note.delete,note.placeholder— all 8 languages (HU/EN/DE/ES/IT/SK/PL/RU)
Testing
- 2 new tests for note i18n — 163 total tests across 9 files
- All tests passing
Full Changelog: v1.4.1...v1.4.2
v1.4.1 — Keyboard Accessibility, Read-only Mode & Selection Animations
What's New
Keyboard Accessibility (WCAG)
- ARIA
listbox/optionroles on the tooth grid and tiles aria-selectedsynced with selection state,aria-multiselectableon grid- Enter/Space to toggle tooth selection
- Arrow keys to navigate between teeth (Left/Right within row, Up/Down between arches)
- Escape to clear selection
:focus-visibleoutline styles in both light and dark mode- Hidden wisdom teeth are properly removed from tab order (
tabindex="-1",aria-hidden)
Read-only Mode
- New
readOnlyprop on theAppcomponent - New
setReadOnly(value)/getReadOnly()API functions - Disables all click, touch, and keyboard interactions
- Control panel dimmed with
opacity: 0.5andpointer-events: none - All tiles removed from tab order
- Ideal for print views, reports, and view-only displays
Selection Animations
- Pulsing dashed border via
::afterpseudo-element around selected teeth - Glowing drop-shadow effect on selected tooth SVGs
- Smooth
.25s easetransitions for selection/deselection - Full dark mode support with dedicated keyframes
prefers-reduced-motion: reduce— static fallback for motion-sensitive users
New i18n Keys
readOnly.labeladded to all 8 languages (HU/EN/DE/ES/IT/SK/PL/RU)
Testing
- 7 new tests in
a11y.test.ts— 161 total tests across 9 files - All tests passing
Full Changelog: v1.4.0...v1.4.1