odontogram-view 0.1.0
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 +42 -0
- package/dist/index.cjs +23 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1199 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/components/Odontogram/Odontogram.d.ts +2 -0
- package/dist/lib/components/Quadrant/Quadrant.d.ts +15 -0
- package/dist/lib/components/Toolbar/Toolbar.d.ts +7 -0
- package/dist/lib/components/Tooth/Tooth.d.ts +14 -0
- package/dist/lib/components/Tooth/ToothSurface.d.ts +14 -0
- package/dist/lib/components/Tooth/toothGeometry.d.ts +18 -0
- package/dist/lib/constants.d.ts +27 -0
- package/dist/lib/types.d.ts +57 -0
- package/dist/lib/utils/odontogram.d.ts +8 -0
- package/dist/styles.css +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# odontogram-view
|
|
2
|
+
|
|
3
|
+
Librería reusable para React que renderiza un odontograma clínico editable con dentición permanente, temporal y mixta.
|
|
4
|
+
|
|
5
|
+
## Desarrollo
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Build
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm run build
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Uso
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { Odontogram } from "odontogram-view";
|
|
22
|
+
import "odontogram-view/styles.css";
|
|
23
|
+
|
|
24
|
+
const initialValue = [
|
|
25
|
+
{
|
|
26
|
+
tooth: "26",
|
|
27
|
+
surfaces: {
|
|
28
|
+
O: ["CARIES"]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
tooth: "11",
|
|
33
|
+
conditions: ["CROWN"]
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export function Example() {
|
|
38
|
+
const [data, setData] = useState(initialValue);
|
|
39
|
+
|
|
40
|
+
return <Odontogram value={data} onChange={setData} dentition="mixed" />;
|
|
41
|
+
}
|
|
42
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react");var Y={exports:{}},S={};/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-jsx-runtime.production.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/var ne;function fe(){if(ne)return S;ne=1;var t=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function n(o,a,l){var u=null;if(l!==void 0&&(u=""+l),a.key!==void 0&&(u=""+a.key),"key"in a){l={};for(var m in a)m!=="key"&&(l[m]=a[m])}else l=a;return a=l.ref,{$$typeof:t,type:o,key:u,ref:a!==void 0?a:null,props:l}}return S.Fragment=r,S.jsx=n,S.jsxs=n,S}var I={};/**
|
|
10
|
+
* @license React
|
|
11
|
+
* react-jsx-runtime.development.js
|
|
12
|
+
*
|
|
13
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14
|
+
*
|
|
15
|
+
* This source code is licensed under the MIT license found in the
|
|
16
|
+
* LICENSE file in the root directory of this source tree.
|
|
17
|
+
*/var ae;function ve(){return ae||(ae=1,process.env.NODE_ENV!=="production"&&(function(){function t(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===q?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Q:return"Fragment";case T:return"Profiler";case N:return"StrictMode";case V:return"Suspense";case z:return"SuspenseList";case j:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case A:return"Portal";case R:return e.displayName||"Context";case d:return(e._context.displayName||"Context")+".Consumer";case O:var s=e.render;return e=e.displayName,e||(e=s.displayName||s.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case G:return s=e.displayName||null,s!==null?s:t(e.type)||"Memo";case p:s=e._payload,e=e._init;try{return t(e(s))}catch{}}return null}function r(e){return""+e}function n(e){try{r(e);var s=!1}catch{s=!0}if(s){s=console;var v=s.error,b=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return v.call(s,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",b),r(e)}}function o(e){if(e===Q)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===p)return"<...>";try{var s=t(e);return s?"<"+s+">":"<...>"}catch{return"<...>"}}function a(){var e=B.A;return e===null?null:e.getOwner()}function l(){return Error("react-stack-top-frame")}function u(e){if(Z.call(e,"key")){var s=Object.getOwnPropertyDescriptor(e,"key").get;if(s&&s.isReactWarning)return!1}return e.key!==void 0}function m(e,s){function v(){K||(K=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",s))}v.isReactWarning=!0,Object.defineProperty(e,"key",{get:v,configurable:!0})}function y(){var e=t(this.type);return ee[e]||(ee[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function _(e,s,v,b,D,J){var x=v.ref;return e={$$typeof:M,type:e,key:s,props:v,_owner:b},(x!==void 0?x:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:y}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:D}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:J}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function h(e,s,v,b,D,J){var x=s.children;if(x!==void 0)if(b)if(ue(x)){for(b=0;b<x.length;b++)E(x[b]);Object.freeze&&Object.freeze(x)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else E(x);if(Z.call(s,"key")){x=t(e);var C=Object.keys(s).filter(function(pe){return pe!=="key"});b=0<C.length?"{key: someKey, "+C.join(": ..., ")+": ...}":"{key: someKey}",oe[x+b]||(C=0<C.length?"{"+C.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
18
|
+
let props = %s;
|
|
19
|
+
<%s {...props} />
|
|
20
|
+
React keys must be passed directly to JSX without using spread:
|
|
21
|
+
let props = %s;
|
|
22
|
+
<%s key={someKey} {...props} />`,b,x,C,x),oe[x+b]=!0)}if(x=null,v!==void 0&&(n(v),x=""+v),u(s)&&(n(s.key),x=""+s.key),"key"in s){v={};for(var H in s)H!=="key"&&(v[H]=s[H])}else v=s;return x&&m(v,typeof e=="function"?e.displayName||e.name||"Unknown":e),_(e,x,v,a(),D,J)}function E(e){k(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===p&&(e._payload.status==="fulfilled"?k(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function k(e){return typeof e=="object"&&e!==null&&e.$$typeof===M}var w=f,M=Symbol.for("react.transitional.element"),A=Symbol.for("react.portal"),Q=Symbol.for("react.fragment"),N=Symbol.for("react.strict_mode"),T=Symbol.for("react.profiler"),d=Symbol.for("react.consumer"),R=Symbol.for("react.context"),O=Symbol.for("react.forward_ref"),V=Symbol.for("react.suspense"),z=Symbol.for("react.suspense_list"),G=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),j=Symbol.for("react.activity"),q=Symbol.for("react.client.reference"),B=w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,Z=Object.prototype.hasOwnProperty,ue=Array.isArray,X=console.createTask?console.createTask:function(){return null};w={react_stack_bottom_frame:function(e){return e()}};var K,ee={},re=w.react_stack_bottom_frame.bind(w,l)(),te=X(o(l)),oe={};I.Fragment=Q,I.jsx=function(e,s,v){var b=1e4>B.recentlyCreatedOwnerStacks++;return h(e,s,v,!1,b?Error("react-stack-top-frame"):re,b?X(o(e)):te)},I.jsxs=function(e,s,v){var b=1e4>B.recentlyCreatedOwnerStacks++;return h(e,s,v,!0,b?Error("react-stack-top-frame"):re,b?X(o(e)):te)}})()),I}var se;function me(){return se||(se=1,process.env.NODE_ENV==="production"?Y.exports=fe():Y.exports=ve()),Y.exports}var i=me();const de={1:"incisor",2:"incisor",3:"canine",4:"premolar",5:"premolar",6:"molar",7:"molar",8:"molar"},be={1:"incisor",2:"incisor",3:"canine",4:"molar",5:"molar"},xe={11:1,12:1,13:1,14:2,15:1,16:3,17:3,18:3,21:1,22:1,23:1,24:2,25:1,26:3,27:3,28:3,31:1,32:1,33:1,34:1,35:1,36:2,37:2,38:2,41:1,42:1,43:1,44:1,45:1,46:2,47:2,48:2,51:1,52:1,53:1,54:3,55:3,61:1,62:1,63:1,64:3,65:3,71:1,72:1,73:1,74:2,75:2,81:1,82:1,83:1,84:2,85:2},he=(t,r,n)=>{const o=xe[t]??1;return r==="incisor"?{centerLabel:"I",roots:o,surfaces:5,crownWidth:32,crownHeight:42,rootStyle:"single"}:r==="canine"?{centerLabel:"I",roots:o,surfaces:5,crownWidth:36,crownHeight:44,rootStyle:"singleLong"}:r==="premolar"?{centerLabel:"O",roots:o,surfaces:5,crownWidth:42,crownHeight:42,rootStyle:o===2?"double":"single"}:{centerLabel:"O",roots:o,surfaces:5,crownWidth:48,crownHeight:42,rootStyle:o===3||n==="upper"?"triple":"double"}},g=(t,r,n,o)=>{const a=o==="permanent"?de:be;return r.map(l=>{const u=a[l],m=`${t}${l}`;return{id:m,type:u,arch:n,dentition:o,label:m,visual:he(m,u,n)}})},Qe=g(1,[8,7,6,5,4,3,2,1],"upper","permanent"),ye=g(2,[1,2,3,4,5,6,7,8],"upper","permanent"),Te=g(4,[8,7,6,5,4,3,2,1],"lower","permanent"),_e=g(3,[1,2,3,4,5,6,7,8],"lower","permanent"),Ee=g(5,[5,4,3,2,1],"upper","primary"),ke=g(6,[1,2,3,4,5],"upper","primary"),we=g(8,[5,4,3,2,1],"lower","primary"),Re=g(7,[1,2,3,4,5],"lower","primary"),P={upper:[...Qe,...ye],lower:[...Te,..._e]},L={upper:[...Ee,...ke],lower:[...we,...Re]},ce=[{id:"upper-permanent",label:"Superior permanente",teeth:P.upper},{id:"upper-primary",label:"Superior temporal",teeth:L.upper},{id:"lower-primary",label:"Inferior temporal",teeth:L.lower},{id:"lower-permanent",label:"Inferior permanente",teeth:P.lower}],F=[{id:"CARIES",label:"Caries",color:"#ef4444",scope:"both"},{id:"CROWN",label:"Corona",color:"#f59e0b",scope:"both"},{id:"EXTRACTION",label:"Extracción",color:"#7c3aed",scope:"both"},{id:"IMPLANT",label:"Implante",color:"#2563eb",scope:"both"},{id:"FRACTURE",label:"Fractura",color:"#fb7185",scope:"both"},{id:"RESIN",label:"Resina",color:"#10b981",scope:"both"},{id:"ENDO",label:"Endodoncia",color:"#0f172a",scope:"both"},{id:"MISSING",label:"Ausente",color:"#64748b",scope:"both"},{id:"SEALANT",label:"Sellante",color:"#14b8a6",scope:"both"}],Oe=new Map(F.map(t=>[t.id,t])),$=(t=[])=>Array.from(new Set(t)),U=t=>[...t].sort((r,n)=>r.localeCompare(n)),le=(t=[])=>{const r={};return t.forEach(n=>{r[n.tooth]={tooth:n.tooth,conditions:n.conditions?U($(n.conditions)):void 0,surfaces:n.surfaces?Object.fromEntries(Object.entries(n.surfaces).map(([o,a])=>[o,a!=null&&a.length?U($(a)):void 0]).filter(([,o])=>!!(o!=null&&o.length))):void 0}}),r},ge=t=>Object.values(t).filter(Boolean).map(r=>{var o;const n={tooth:r.tooth};return(o=r==null?void 0:r.conditions)!=null&&o.length&&(n.conditions=r.conditions),r!=null&&r.surfaces&&Object.keys(r.surfaces).length>0&&(n.surfaces=r.surfaces),n}).filter(r=>{var n;return((n=r.conditions)==null?void 0:n.length)||Object.keys(r.surfaces??{}).length}).sort((r,n)=>r.tooth.localeCompare(n.tooth)),W=t=>{var a;const r=t.surfaces?Object.fromEntries(Object.entries(t.surfaces).filter(([,l])=>!!(l!=null&&l.length))):void 0,n=!!((a=t.conditions)!=null&&a.length),o=!!(r&&Object.keys(r).length>0);if(!(!n&&!o))return{tooth:t.tooth,conditions:n?t.conditions:void 0,surfaces:o?r:void 0}},Ne=(t,r,n,o)=>{var y;if(!Oe.get(o))return t;const l=t[r]??{},u=((y=l.surfaces)==null?void 0:y[n])??[],m={tooth:r,conditions:l.conditions,surfaces:{...l.surfaces??{},[n]:U($([...u,o]))}};return{...t,[r]:W(m)}},je=(t,r,n)=>{const o=t[r]??{},a={tooth:r,surfaces:o.surfaces,conditions:U($([...o.conditions??[],n]))};return{...t,[r]:W(a)}},Me=(t,r,n)=>{var l,u;const o=t[r];if(!((u=(l=o==null?void 0:o.surfaces)==null?void 0:l[n])!=null&&u.length))return t;const a={...o.surfaces??{}};return delete a[n],{...t,[r]:W({tooth:r,conditions:o.conditions,surfaces:a})}},Ce=(t,r)=>{if(!t[r])return t;const o=W({tooth:r,conditions:void 0,surfaces:void 0});if(!o){const a={...t};return delete a[r],a}return{...t,[r]:o}},ie=t=>{var r;return((r=F.find(n=>n.id===t))==null?void 0:r.color)??"#dbe4ea"},Ae=f.memo(function({surface:r,label:n,path:o,textX:a,textY:l,condition:u,onApply:m,onClear:y,disabled:_}){return i.jsxs("g",{children:[i.jsx("path",{d:o,fill:ie(u),stroke:"#1f2937",strokeWidth:1.4,strokeLinejoin:"round",className:_?"":"ov-cursor-pointer ov-transition-opacity hover:ov-opacity-85",onClick:_?void 0:()=>m(r),onContextMenu:_?void 0:h=>{h.preventDefault(),y(r)}}),i.jsx("text",{x:a,y:l,textAnchor:"middle",className:"ov-pointer-events-none ov-select-none ov-fill-slate-700 ov-text-[10px] ov-font-semibold",children:n})]})}),c=(...t)=>`${t.join(" ")} Z`,Se=t=>{const r=c("M 21 20","Q 31 13 41 20","Q 47 27 45 38","Q 43 50 31 55","Q 19 50 17 38","Q 15 27 21 20"),n=[{key:"V",label:"V",path:c("M 21 20","Q 31 14 41 20","Q 39 26 36 30","Q 31 32 26 30","Q 23 26 21 20"),text:{x:31,y:25}},{key:"M",label:"M",path:c("M 17 38","Q 17 28 21 20","Q 23 26 26 30","Q 25 39 26 47","Q 20 46 17 38"),text:{x:22,y:38}},{key:t,label:t,path:c("M 26 30","Q 31 26 36 30","Q 39 38 36 46","Q 31 51 26 46","Q 23 38 26 30"),text:{x:31,y:40}},{key:"D",label:"D",path:c("M 45 38","Q 45 28 41 20","Q 39 26 36 30","Q 37 39 36 47","Q 42 46 45 38"),text:{x:40,y:38}},{key:"L",label:"L",path:c("M 24 45","Q 31 54 38 45","Q 42 47 45 38","Q 43 54 31 59","Q 19 54 17 38","Q 20 47 24 45"),text:{x:31,y:55}}];return{crownOutline:r,crownCap:r,rootPaths:[c("M 27 54","Q 31 58 35 54","Q 38 65 36 84","Q 34 100 31 112","Q 28 100 26 84","Q 24 65 27 54")],surfaces:n}},Ie=()=>{const t=c("M 24 23","Q 31 12 38 23","Q 44 31 42 41","Q 40 52 31 58","Q 22 52 20 41","Q 18 31 24 23"),r=[{key:"V",label:"V",path:c("M 24 23","Q 31 13 38 23","Q 36 29 35 31","Q 31 34 27 31","Q 26 29 24 23"),text:{x:31,y:26}},{key:"M",label:"M",path:c("M 20 41","Q 20 31 24 23","Q 26 29 27 31","Q 26 40 27 49","Q 22 47 20 41"),text:{x:23,y:40}},{key:"I",label:"I",path:c("M 27 31","Q 31 28 35 31","Q 37 40 35 48","Q 31 53 27 48","Q 25 40 27 31"),text:{x:31,y:40}},{key:"D",label:"D",path:c("M 42 41","Q 42 31 38 23","Q 36 29 35 31","Q 36 40 35 49","Q 40 47 42 41"),text:{x:39,y:40}},{key:"L",label:"L",path:c("M 25 47","Q 31 56 37 47","Q 40 49 42 41","Q 40 54 31 60","Q 22 54 20 41","Q 22 49 25 47"),text:{x:31,y:55}}];return{crownOutline:t,crownCap:t,rootPaths:[c("M 27 58","Q 31 62 35 58","Q 39 73 37 92","Q 35 112 31 122","Q 27 112 25 92","Q 23 73 27 58")],surfaces:r}},Pe=()=>{const t=c("M 20 20","Q 31 15 42 20","Q 48 28 46 39","Q 44 52 31 57","Q 18 52 16 39","Q 14 28 20 20"),r=[{key:"V",label:"V",path:c("M 20 20","Q 31 14 42 20","Q 39 28 36 31","Q 31 33 26 31","Q 23 28 20 20"),text:{x:31,y:25}},{key:"M",label:"M",path:c("M 16 39","Q 15 29 20 20","Q 23 28 26 31","Q 24 40 26 49","Q 20 48 16 39"),text:{x:22,y:40}},{key:"O",label:"O",path:c("M 26 31","Q 31 27 36 31","Q 39 39 36 48","Q 31 52 26 48","Q 23 39 26 31"),text:{x:31,y:40}},{key:"D",label:"D",path:c("M 46 39","Q 47 29 42 20","Q 39 28 36 31","Q 38 40 36 49","Q 42 48 46 39"),text:{x:40,y:40}},{key:"L",label:"L",path:c("M 24 47","Q 31 56 38 47","Q 43 49 46 39","Q 44 54 31 59","Q 18 54 16 39","Q 19 49 24 47"),text:{x:31,y:56}}];return{crownOutline:t,crownCap:t,rootPaths:[c("M 22 57","Q 25 60 28 57","Q 28 71 25 90","Q 23 101 20 109","Q 17 99 17 86","Q 17 71 22 57"),c("M 34 57","Q 37 60 40 57","Q 45 71 45 86","Q 45 99 42 109","Q 39 101 37 90","Q 34 71 34 57")],surfaces:r}},Le=t=>{const r=c("M 16 22","Q 31 13 46 22","Q 52 32 49 43","Q 46 56 31 61","Q 16 56 13 43","Q 10 32 16 22"),n=[{key:"V",label:"V",path:c("M 16 22","Q 31 12 46 22","Q 42 31 38 34","Q 31 36 24 34","Q 20 31 16 22"),text:{x:31,y:26}},{key:"M",label:"M",path:c("M 13 43","Q 11 32 16 22","Q 20 31 24 34","Q 22 44 24 53","Q 17 52 13 43"),text:{x:21,y:43}},{key:"O",label:"O",path:c("M 24 34","Q 31 29 38 34","Q 41 43 38 52","Q 31 56 24 52","Q 21 43 24 34"),text:{x:31,y:43}},{key:"D",label:"D",path:c("M 49 43","Q 51 32 46 22","Q 42 31 38 34","Q 40 44 38 53","Q 45 52 49 43"),text:{x:41,y:43}},{key:"L",label:"L",path:c("M 22 51","Q 31 62 40 51","Q 46 52 49 43","Q 46 58 31 64","Q 16 58 13 43","Q 16 52 22 51"),text:{x:31,y:60}}],o=t==="upper"?[c("M 17 61","Q 20 64 23 61","Q 24 73 22 91","Q 20 103 17 111","Q 14 101 14 88","Q 14 73 17 61"),c("M 28 61","Q 31 65 34 61","Q 36 76 35 96","Q 34 111 31 122","Q 28 111 27 96","Q 26 76 28 61"),c("M 39 61","Q 42 64 45 61","Q 48 73 48 88","Q 48 101 45 111","Q 42 103 40 91","Q 38 73 39 61")]:[c("M 22 61","Q 26 64 29 61","Q 29 76 26 96","Q 24 109 20 118","Q 17 107 17 92","Q 17 75 22 61"),c("M 33 61","Q 36 64 40 61","Q 45 75 45 92","Q 45 107 42 118","Q 38 109 36 96","Q 33 76 33 61")];return{crownOutline:r,crownCap:r,rootPaths:o,surfaces:n}},De=t=>t.type==="incisor"?Se(t.visual.centerLabel):t.type==="canine"?Ie():t.type==="premolar"?Pe():Le(t.arch),Ye={sm:{wrapper:"ov-min-w-[64px] ov-gap-0.5",label:"ov-text-[11px]",svg:"ov-h-[124px] ov-w-[62px]"},md:{wrapper:"ov-min-w-[74px] ov-gap-0.5",label:"ov-text-xs",svg:"ov-h-[138px] ov-w-[98px]"},lg:{wrapper:"ov-min-w-[84px] ov-gap-0.5",label:"ov-text-sm",svg:"ov-h-[154px] ov-w-[108px]"}},$e=f.memo(function({definition:r,record:n,editable:o,selectedCondition:a,size:l,onApplySurface:u,onApplyTooth:m,onClearSurface:y,onClearTooth:_}){const h=Ye[l],E=f.useMemo(()=>De(r),[r]),k=(n==null?void 0:n.conditions)??[],w=f.useMemo(()=>k.length?ie(k[0]):"#f8fafc",[k]),M=f.useMemo(()=>r.type==="incisor"?"ov-border-sky-100":r.type==="canine"?"ov-border-amber-100":r.type==="premolar"?"ov-border-emerald-100":"ov-border-rose-100",[r.type]),A=f.useCallback(d=>u(r.id,d,a),[r.id,u,a]),Q=f.useCallback(d=>y(r.id,d),[r.id,y]),N=f.useCallback(()=>{m(r.id,a)},[r.id,m,a]),T=f.useCallback(()=>{_(r.id)},[r.id,_]);return i.jsxs("div",{className:["ov-flex ov-flex-col ov-items-center",M,h.wrapper].join(" "),children:[i.jsx("span",{className:["ov-font-semibold ov-text-clinic-700",h.label].join(" "),children:r.label}),i.jsxs("svg",{viewBox:"0 0 62 128",className:h.svg,children:[E.rootPaths.map((d,R)=>i.jsx("path",{d,fill:w,stroke:"#1f2937",strokeWidth:1.4,strokeLinejoin:"round",className:o?"ov-cursor-pointer ov-transition-opacity hover:ov-opacity-85":"",onClick:o?N:void 0,onContextMenu:o?O=>{O.preventDefault(),T()}:void 0},`${r.id}-root-${R}`)),i.jsx("path",{d:E.crownCap,fill:w,stroke:"#1f2937",strokeWidth:1.6}),E.surfaces.map(d=>{var R,O;return i.jsx(Ae,{surface:d.key,label:d.label,path:d.path,textX:d.text.x,textY:d.text.y,condition:(O=(R=n==null?void 0:n.surfaces)==null?void 0:R[d.key])==null?void 0:O[0],onApply:A,onClear:Q,disabled:!o},`${r.id}-${d.key}`)}),i.jsx("path",{d:E.crownOutline,fill:"none",stroke:"#0f172a",strokeWidth:1.6,strokeLinejoin:"round",className:o?"ov-cursor-pointer":"",onClick:o?N:void 0,onContextMenu:o?d=>{d.preventDefault(),T()}:void 0})]})]})}),Ue=f.memo(function({teeth:r,records:n,editable:o,selectedCondition:a,size:l,onApplySurface:u,onApplyTooth:m,onClearSurface:y,onClearTooth:_}){return i.jsx("section",{children:i.jsx("div",{className:"ov-overflow-x-auto ov-pb-1",children:i.jsx("div",{className:"ov-flex ov-min-w-max ov-justify-center ov-gap-0.5",children:r.map(h=>i.jsx($e,{definition:h,record:n[h.id],editable:o,selectedCondition:a,size:l,onApplySurface:u,onApplyTooth:m,onClearSurface:y,onClearTooth:_},h.id))})})})}),Fe=f.memo(function({selectedCondition:r,onSelect:n}){return i.jsxs("div",{className:"ov-rounded-3xl ov-border ov-border-slate-200 ov-bg-white ov-p-4 ov-shadow-panel",children:[i.jsxs("div",{className:"ov-mb-3 ov-flex ov-items-center ov-justify-between ov-gap-3",children:[i.jsxs("div",{children:[i.jsx("p",{className:"ov-text-xs ov-font-semibold ov-uppercase ov-tracking-[0.22em] ov-text-clinic-600",children:"Estados clínicos"}),i.jsx("p",{className:"ov-text-sm ov-text-slate-500",children:"Click izquierdo aplica. Click derecho limpia solo la pieza o superficie elegida."})]}),i.jsxs("div",{className:"ov-rounded-full ov-bg-clinic-50 ov-px-3 ov-py-1 ov-text-xs ov-font-medium ov-text-clinic-700",children:["Activo: ",r]})]}),i.jsx("div",{className:"ov-flex ov-flex-wrap ov-gap-2",children:F.map(o=>{const a=o.id===r;return i.jsxs("button",{type:"button",onClick:()=>n(o.id),className:["ov-flex ov-items-center ov-gap-2 ov-rounded-full ov-border ov-px-3 ov-py-2 ov-text-sm ov-transition",a?"ov-border-clinic-700 ov-bg-clinic-900 ov-text-white":"ov-border-slate-200 ov-bg-slate-50 ov-text-slate-700 hover:ov-border-clinic-400 hover:ov-bg-white"].join(" "),children:[i.jsx("span",{className:"ov-h-3 ov-w-3 ov-rounded-full ov-border ov-border-white/40",style:{backgroundColor:o.color}}),i.jsx("span",{children:o.label})]},o.id)})})]})}),We="CARIES",Ve=f.memo(function({value:r,defaultValue:n,onChange:o,dentition:a="mixed",selectedCondition:l,onSelectedConditionChange:u,editable:m=!0,size:y="md",className:_,theme:h}){const E=typeof r<"u",[k,w]=f.useState(()=>le(n)),[M,A]=f.useState(We),Q=f.useMemo(()=>E?le(r):k,[k,E,r]),N=l??M,T=f.useCallback(p=>{E||w(p),o==null||o(ge(p))},[E,o]),d=f.useCallback(p=>{l||A(p),u==null||u(p)},[u,l]),R=f.useCallback((p,j,q)=>{T(Ne(Q,p,j,q))},[Q,T]),O=f.useCallback((p,j)=>{T(je(Q,p,j))},[Q,T]),V=f.useCallback((p,j)=>{T(Me(Q,p,j))},[Q,T]),z=f.useCallback(p=>{T(Ce(Q,p))},[Q,T]),G=f.useMemo(()=>a==="permanent"?[{id:"permanent-upper",label:"Superior permanente",teeth:P.upper},{id:"permanent-lower",label:"Inferior permanente",teeth:P.lower}]:a==="primary"?[{id:"primary-upper",label:"Superior temporal",teeth:L.upper},{id:"primary-lower",label:"Inferior temporal",teeth:L.lower}]:[...ce],[a]);return i.jsx("div",{className:["ov-odontogram ov-w-full ov-max-w-full ov-overflow-hidden ov-rounded-[28px] ov-border ov-border-slate-200 ov-bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.98),_rgba(240,248,249,0.98)_40%,_rgba(229,239,241,1)_100%)] ov-p-4 ov-text-slate-900 ov-shadow-panel md:ov-p-6",_??""].join(" "),style:h==null?void 0:h.panelStyle,onContextMenu:p=>{p.preventDefault()},children:i.jsxs("div",{className:"ov-space-y-5",children:[i.jsx(Fe,{selectedCondition:N,onSelect:d}),i.jsx("div",{className:"ov-overflow-x-auto ov-overflow-y-hidden",children:i.jsx("div",{className:"ov-grid ov-min-w-max ov-gap-5",children:G.map(p=>i.jsx(Ue,{label:p.label,teeth:p.teeth,records:Q,editable:m,selectedCondition:N,size:y,onApplySurface:R,onApplyTooth:O,onClearSurface:V,onClearTooth:z},p.id))})})]})})});exports.CLINICAL_CONDITIONS=F;exports.MIXED_DENTITION_LAYOUT=ce;exports.Odontogram=Ve;exports.PERMANENT_DENTITION_LAYOUT=P;exports.PRIMARY_DENTITION_LAYOUT=L;
|
|
23
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/react/cjs/react-jsx-runtime.development.js","../node_modules/react/jsx-runtime.js","../src/lib/constants.ts","../src/lib/utils/odontogram.ts","../src/lib/components/Tooth/ToothSurface.tsx","../src/lib/components/Tooth/toothGeometry.ts","../src/lib/components/Tooth/Tooth.tsx","../src/lib/components/Quadrant/Quadrant.tsx","../src/lib/components/Toolbar/Toolbar.tsx","../src/lib/components/Odontogram/Odontogram.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","import type { ConditionDefinition, ToothDefinition, ToothType, ToothVisualConfig } from \"./types\";\n\nconst PERMANENT_SURFACE_MAP: Record<number, ToothType> = {\n 1: \"incisor\",\n 2: \"incisor\",\n 3: \"canine\",\n 4: \"premolar\",\n 5: \"premolar\",\n 6: \"molar\",\n 7: \"molar\",\n 8: \"molar\"\n};\n\nconst PRIMARY_SURFACE_MAP: Record<number, ToothType> = {\n 1: \"incisor\",\n 2: \"incisor\",\n 3: \"canine\",\n 4: \"molar\",\n 5: \"molar\"\n};\n\nconst ROOT_COUNT_BY_TOOTH: Record<string, 1 | 2 | 3> = {\n \"11\": 1,\n \"12\": 1,\n \"13\": 1,\n \"14\": 2,\n \"15\": 1,\n \"16\": 3,\n \"17\": 3,\n \"18\": 3,\n \"21\": 1,\n \"22\": 1,\n \"23\": 1,\n \"24\": 2,\n \"25\": 1,\n \"26\": 3,\n \"27\": 3,\n \"28\": 3,\n \"31\": 1,\n \"32\": 1,\n \"33\": 1,\n \"34\": 1,\n \"35\": 1,\n \"36\": 2,\n \"37\": 2,\n \"38\": 2,\n \"41\": 1,\n \"42\": 1,\n \"43\": 1,\n \"44\": 1,\n \"45\": 1,\n \"46\": 2,\n \"47\": 2,\n \"48\": 2,\n \"51\": 1,\n \"52\": 1,\n \"53\": 1,\n \"54\": 3,\n \"55\": 3,\n \"61\": 1,\n \"62\": 1,\n \"63\": 1,\n \"64\": 3,\n \"65\": 3,\n \"71\": 1,\n \"72\": 1,\n \"73\": 1,\n \"74\": 2,\n \"75\": 2,\n \"81\": 1,\n \"82\": 1,\n \"83\": 1,\n \"84\": 2,\n \"85\": 2\n};\n\nconst visualConfigByType = (\n toothId: string,\n type: ToothType,\n arch: \"upper\" | \"lower\"\n): ToothVisualConfig => {\n const rootCount = ROOT_COUNT_BY_TOOTH[toothId] ?? 1;\n\n if (type === \"incisor\") {\n return {\n centerLabel: \"I\",\n roots: rootCount,\n surfaces: 5,\n crownWidth: 32,\n crownHeight: 42,\n rootStyle: \"single\"\n };\n }\n\n if (type === \"canine\") {\n return {\n centerLabel: \"I\",\n roots: rootCount,\n surfaces: 5,\n crownWidth: 36,\n crownHeight: 44,\n rootStyle: \"singleLong\"\n };\n }\n\n if (type === \"premolar\") {\n return {\n centerLabel: \"O\",\n roots: rootCount,\n surfaces: 5,\n crownWidth: 42,\n crownHeight: 42,\n rootStyle: rootCount === 2 ? \"double\" : \"single\"\n };\n }\n\n return {\n centerLabel: \"O\",\n roots: rootCount,\n surfaces: 5,\n crownWidth: 48,\n crownHeight: 42,\n rootStyle: rootCount === 3 ? \"triple\" : arch === \"upper\" ? \"triple\" : \"double\"\n };\n};\n\nconst buildQuadrant = (\n quadrant: number,\n toothNumbers: number[],\n arch: \"upper\" | \"lower\",\n dentition: \"permanent\" | \"primary\"\n): ToothDefinition[] => {\n const typeMap = dentition === \"permanent\" ? PERMANENT_SURFACE_MAP : PRIMARY_SURFACE_MAP;\n\n return toothNumbers.map((position) => {\n const type = typeMap[position];\n const toothId = `${quadrant}${position}`;\n return {\n id: toothId,\n type,\n arch,\n dentition,\n label: toothId,\n visual: visualConfigByType(toothId, type, arch)\n };\n });\n};\n\nconst upperPermanentLeft = buildQuadrant(1, [8, 7, 6, 5, 4, 3, 2, 1], \"upper\", \"permanent\");\nconst upperPermanentRight = buildQuadrant(2, [1, 2, 3, 4, 5, 6, 7, 8], \"upper\", \"permanent\");\nconst lowerPermanentLeft = buildQuadrant(4, [8, 7, 6, 5, 4, 3, 2, 1], \"lower\", \"permanent\");\nconst lowerPermanentRight = buildQuadrant(3, [1, 2, 3, 4, 5, 6, 7, 8], \"lower\", \"permanent\");\n\nconst upperPrimaryLeft = buildQuadrant(5, [5, 4, 3, 2, 1], \"upper\", \"primary\");\nconst upperPrimaryRight = buildQuadrant(6, [1, 2, 3, 4, 5], \"upper\", \"primary\");\nconst lowerPrimaryLeft = buildQuadrant(8, [5, 4, 3, 2, 1], \"lower\", \"primary\");\nconst lowerPrimaryRight = buildQuadrant(7, [1, 2, 3, 4, 5], \"lower\", \"primary\");\n\nexport const PERMANENT_DENTITION_LAYOUT = {\n upper: [...upperPermanentLeft, ...upperPermanentRight],\n lower: [...lowerPermanentLeft, ...lowerPermanentRight]\n};\n\nexport const PRIMARY_DENTITION_LAYOUT = {\n upper: [...upperPrimaryLeft, ...upperPrimaryRight],\n lower: [...lowerPrimaryLeft, ...lowerPrimaryRight]\n};\n\nexport const MIXED_DENTITION_LAYOUT = [\n {\n id: \"upper-permanent\",\n label: \"Superior permanente\",\n teeth: PERMANENT_DENTITION_LAYOUT.upper\n },\n {\n id: \"upper-primary\",\n label: \"Superior temporal\",\n teeth: PRIMARY_DENTITION_LAYOUT.upper\n },\n {\n id: \"lower-primary\",\n label: \"Inferior temporal\",\n teeth: PRIMARY_DENTITION_LAYOUT.lower\n },\n {\n id: \"lower-permanent\",\n label: \"Inferior permanente\",\n teeth: PERMANENT_DENTITION_LAYOUT.lower\n }\n] as const;\n\nexport const CLINICAL_CONDITIONS: ConditionDefinition[] = [\n { id: \"CARIES\", label: \"Caries\", color: \"#ef4444\", scope: \"both\" },\n { id: \"CROWN\", label: \"Corona\", color: \"#f59e0b\", scope: \"both\" },\n { id: \"EXTRACTION\", label: \"Extracción\", color: \"#7c3aed\", scope: \"both\" },\n { id: \"IMPLANT\", label: \"Implante\", color: \"#2563eb\", scope: \"both\" },\n { id: \"FRACTURE\", label: \"Fractura\", color: \"#fb7185\", scope: \"both\" },\n { id: \"RESIN\", label: \"Resina\", color: \"#10b981\", scope: \"both\" },\n { id: \"ENDO\", label: \"Endodoncia\", color: \"#0f172a\", scope: \"both\" },\n { id: \"MISSING\", label: \"Ausente\", color: \"#64748b\", scope: \"both\" },\n { id: \"SEALANT\", label: \"Sellante\", color: \"#14b8a6\", scope: \"both\" }\n];\n","import { CLINICAL_CONDITIONS } from \"../constants\";\nimport type {\n ConditionDefinition,\n OdontogramChange,\n ToothCondition,\n ToothRecord,\n ToothStateMap,\n ToothSurface\n} from \"../types\";\n\nconst conditionMap = new Map<ToothCondition, ConditionDefinition>(\n CLINICAL_CONDITIONS.map((condition) => [condition.id, condition])\n);\n\nconst dedupe = (conditions: ToothCondition[] = []) => Array.from(new Set(conditions));\n\nconst sortConditions = (conditions: ToothCondition[]) =>\n [...conditions].sort((left, right) => left.localeCompare(right));\n\nexport const normalizeChanges = (value: OdontogramChange = []): ToothStateMap => {\n const normalized: ToothStateMap = {};\n\n value.forEach((record) => {\n normalized[record.tooth] = {\n tooth: record.tooth,\n conditions: record.conditions ? sortConditions(dedupe(record.conditions)) : undefined,\n surfaces: record.surfaces\n ? Object.fromEntries(\n Object.entries(record.surfaces)\n .map(([surface, conditions]) => [\n surface,\n conditions?.length ? sortConditions(dedupe(conditions)) : undefined\n ])\n .filter(([, conditions]) => Boolean(conditions?.length))\n ) as ToothRecord[\"surfaces\"]\n : undefined\n };\n });\n\n return normalized;\n};\n\nexport const serializeChanges = (state: ToothStateMap): OdontogramChange =>\n Object.values(state)\n .filter(Boolean)\n .map((record) => {\n const nextRecord: ToothRecord = { tooth: record!.tooth };\n\n if (record?.conditions?.length) {\n nextRecord.conditions = record.conditions;\n }\n\n if (record?.surfaces && Object.keys(record.surfaces).length > 0) {\n nextRecord.surfaces = record.surfaces;\n }\n\n return nextRecord;\n })\n .filter((record) => record.conditions?.length || Object.keys(record.surfaces ?? {}).length)\n .sort((left, right) => left.tooth.localeCompare(right.tooth));\n\nconst cleanupRecord = (record: ToothRecord): ToothRecord | undefined => {\n const surfaces = record.surfaces\n ? Object.fromEntries(\n Object.entries(record.surfaces).filter(([, conditions]) => Boolean(conditions?.length))\n )\n : undefined;\n\n const hasToothConditions = Boolean(record.conditions?.length);\n const hasSurfaceConditions = Boolean(surfaces && Object.keys(surfaces).length > 0);\n\n if (!hasToothConditions && !hasSurfaceConditions) {\n return undefined;\n }\n\n return {\n tooth: record.tooth,\n conditions: hasToothConditions ? record.conditions : undefined,\n surfaces: hasSurfaceConditions ? (surfaces as ToothRecord[\"surfaces\"]) : undefined\n };\n};\n\nexport const applySurfaceCondition = (\n state: ToothStateMap,\n tooth: string,\n surface: ToothSurface,\n condition: ToothCondition\n): ToothStateMap => {\n const definition = conditionMap.get(condition);\n if (!definition) {\n return state;\n }\n\n const current = state[tooth] ?? { tooth };\n const currentSurfaceValues = current.surfaces?.[surface] ?? [];\n const nextRecord: ToothRecord = {\n tooth,\n conditions: current.conditions,\n surfaces: {\n ...(current.surfaces ?? {}),\n [surface]: sortConditions(dedupe([...currentSurfaceValues, condition]))\n }\n };\n\n return {\n ...state,\n [tooth]: cleanupRecord(nextRecord)\n };\n};\n\nexport const applyToothCondition = (\n state: ToothStateMap,\n tooth: string,\n condition: ToothCondition\n): ToothStateMap => {\n const current = state[tooth] ?? { tooth };\n const nextRecord: ToothRecord = {\n tooth,\n surfaces: current.surfaces,\n conditions: sortConditions(dedupe([...(current.conditions ?? []), condition]))\n };\n\n return {\n ...state,\n [tooth]: cleanupRecord(nextRecord)\n };\n};\n\nexport const clearSurfaceCondition = (\n state: ToothStateMap,\n tooth: string,\n surface: ToothSurface\n): ToothStateMap => {\n const current = state[tooth];\n if (!current?.surfaces?.[surface]?.length) {\n return state;\n }\n\n const nextSurfaces = { ...(current.surfaces ?? {}) };\n delete nextSurfaces[surface];\n\n return {\n ...state,\n [tooth]: cleanupRecord({\n tooth,\n conditions: current.conditions,\n surfaces: nextSurfaces\n })\n };\n};\n\nexport const clearToothCondition = (state: ToothStateMap, tooth: string): ToothStateMap => {\n const current = state[tooth];\n if (!current) {\n return state;\n }\n\n const nextRecord = cleanupRecord({\n tooth,\n conditions: undefined,\n surfaces: undefined\n });\n\n if (!nextRecord) {\n const nextState = { ...state };\n delete nextState[tooth];\n return nextState;\n }\n\n return {\n ...state,\n [tooth]: nextRecord\n };\n};\n\nexport const getConditionColor = (condition?: ToothCondition) =>\n CLINICAL_CONDITIONS.find((item) => item.id === condition)?.color ?? \"#dbe4ea\";\n","import { memo } from \"react\";\nimport { getConditionColor } from \"../../utils/odontogram\";\nimport type { ToothCondition, ToothSurface as ToothSurfaceType } from \"../../types\";\n\ntype ToothSurfaceProps = {\n surface: ToothSurfaceType;\n label: string;\n path: string;\n textX: number;\n textY: number;\n condition?: ToothCondition;\n onApply: (surface: ToothSurfaceType) => void;\n onClear: (surface: ToothSurfaceType) => void;\n disabled?: boolean;\n};\n\nexport const ToothSurface = memo(function ToothSurface({\n surface,\n label,\n path,\n textX,\n textY,\n condition,\n onApply,\n onClear,\n disabled\n}: ToothSurfaceProps) {\n return (\n <g>\n <path\n d={path}\n fill={getConditionColor(condition)}\n stroke=\"#1f2937\"\n strokeWidth={1.4}\n strokeLinejoin=\"round\"\n className={disabled ? \"\" : \"ov-cursor-pointer ov-transition-opacity hover:ov-opacity-85\"}\n onClick={disabled ? undefined : () => onApply(surface)}\n onContextMenu={\n disabled\n ? undefined\n : (event) => {\n event.preventDefault();\n onClear(surface);\n }\n }\n />\n <text\n x={textX}\n y={textY}\n textAnchor=\"middle\"\n className=\"ov-pointer-events-none ov-select-none ov-fill-slate-700 ov-text-[10px] ov-font-semibold\"\n >\n {label}\n </text>\n </g>\n );\n});\n","import type { ToothDefinition, ToothSurface } from \"../../types\";\n\ntype GeometrySurface = {\n key: ToothSurface;\n label: string;\n path: string;\n text: { x: number; y: number };\n};\n\ntype ToothGeometry = {\n crownOutline: string;\n crownCap: string;\n rootPaths: string[];\n surfaces: GeometrySurface[];\n};\n\nconst quad = (x1: number, y1: number, cx: number, cy: number, x2: number, y2: number) =>\n `M ${x1} ${y1} Q ${cx} ${cy} ${x2} ${y2}`;\n\nconst closed = (...segments: string[]) => `${segments.join(\" \")} Z`;\n\nconst buildIncisorGeometry = (centerLabel: \"I\" | \"O\"): ToothGeometry => {\n const crownOutline = closed(\n \"M 21 20\",\n \"Q 31 13 41 20\",\n \"Q 47 27 45 38\",\n \"Q 43 50 31 55\",\n \"Q 19 50 17 38\",\n \"Q 15 27 21 20\"\n );\n\n const surfaces: GeometrySurface[] = [\n {\n key: \"V\",\n label: \"V\",\n path: closed(\n \"M 21 20\",\n \"Q 31 14 41 20\",\n \"Q 39 26 36 30\",\n \"Q 31 32 26 30\",\n \"Q 23 26 21 20\"\n ),\n text: { x: 31, y: 25 }\n },\n {\n key: \"M\",\n label: \"M\",\n path: closed(\n \"M 17 38\",\n \"Q 17 28 21 20\",\n \"Q 23 26 26 30\",\n \"Q 25 39 26 47\",\n \"Q 20 46 17 38\"\n ),\n text: { x: 22, y: 38 }\n },\n {\n key: centerLabel,\n label: centerLabel,\n path: closed(\n \"M 26 30\",\n \"Q 31 26 36 30\",\n \"Q 39 38 36 46\",\n \"Q 31 51 26 46\",\n \"Q 23 38 26 30\"\n ),\n text: { x: 31, y: 40 }\n },\n {\n key: \"D\",\n label: \"D\",\n path: closed(\n \"M 45 38\",\n \"Q 45 28 41 20\",\n \"Q 39 26 36 30\",\n \"Q 37 39 36 47\",\n \"Q 42 46 45 38\"\n ),\n text: { x: 40, y: 38 }\n },\n {\n key: \"L\",\n label: \"L\",\n path: closed(\n \"M 24 45\",\n \"Q 31 54 38 45\",\n \"Q 42 47 45 38\",\n \"Q 43 54 31 59\",\n \"Q 19 54 17 38\",\n \"Q 20 47 24 45\"\n ),\n text: { x: 31, y: 55 }\n }\n ];\n\n return {\n crownOutline,\n crownCap: crownOutline,\n rootPaths: [\n closed(\n \"M 27 54\",\n \"Q 31 58 35 54\",\n \"Q 38 65 36 84\",\n \"Q 34 100 31 112\",\n \"Q 28 100 26 84\",\n \"Q 24 65 27 54\"\n )\n ],\n surfaces\n };\n};\n\nconst buildCanineGeometry = (): ToothGeometry => {\n const crownOutline = closed(\n \"M 24 23\",\n \"Q 31 12 38 23\",\n \"Q 44 31 42 41\",\n \"Q 40 52 31 58\",\n \"Q 22 52 20 41\",\n \"Q 18 31 24 23\"\n );\n\n const surfaces: GeometrySurface[] = [\n {\n key: \"V\",\n label: \"V\",\n path: closed(\n \"M 24 23\",\n \"Q 31 13 38 23\",\n \"Q 36 29 35 31\",\n \"Q 31 34 27 31\",\n \"Q 26 29 24 23\"\n ),\n text: { x: 31, y: 26 }\n },\n {\n key: \"M\",\n label: \"M\",\n path: closed(\n \"M 20 41\",\n \"Q 20 31 24 23\",\n \"Q 26 29 27 31\",\n \"Q 26 40 27 49\",\n \"Q 22 47 20 41\"\n ),\n text: { x: 23, y: 40 }\n },\n {\n key: \"I\",\n label: \"I\",\n path: closed(\n \"M 27 31\",\n \"Q 31 28 35 31\",\n \"Q 37 40 35 48\",\n \"Q 31 53 27 48\",\n \"Q 25 40 27 31\"\n ),\n text: { x: 31, y: 40 }\n },\n {\n key: \"D\",\n label: \"D\",\n path: closed(\n \"M 42 41\",\n \"Q 42 31 38 23\",\n \"Q 36 29 35 31\",\n \"Q 36 40 35 49\",\n \"Q 40 47 42 41\"\n ),\n text: { x: 39, y: 40 }\n },\n {\n key: \"L\",\n label: \"L\",\n path: closed(\n \"M 25 47\",\n \"Q 31 56 37 47\",\n \"Q 40 49 42 41\",\n \"Q 40 54 31 60\",\n \"Q 22 54 20 41\",\n \"Q 22 49 25 47\"\n ),\n text: { x: 31, y: 55 }\n }\n ];\n\n return {\n crownOutline,\n crownCap: crownOutline,\n rootPaths: [\n closed(\n \"M 27 58\",\n \"Q 31 62 35 58\",\n \"Q 39 73 37 92\",\n \"Q 35 112 31 122\",\n \"Q 27 112 25 92\",\n \"Q 23 73 27 58\"\n )\n ],\n surfaces\n };\n};\n\nconst buildPremolarGeometry = (): ToothGeometry => {\n const crownOutline = closed(\n \"M 20 20\",\n \"Q 31 15 42 20\",\n \"Q 48 28 46 39\",\n \"Q 44 52 31 57\",\n \"Q 18 52 16 39\",\n \"Q 14 28 20 20\"\n );\n\n const surfaces: GeometrySurface[] = [\n {\n key: \"V\",\n label: \"V\",\n path: closed(\n \"M 20 20\",\n \"Q 31 14 42 20\",\n \"Q 39 28 36 31\",\n \"Q 31 33 26 31\",\n \"Q 23 28 20 20\"\n ),\n text: { x: 31, y: 25 }\n },\n {\n key: \"M\",\n label: \"M\",\n path: closed(\n \"M 16 39\",\n \"Q 15 29 20 20\",\n \"Q 23 28 26 31\",\n \"Q 24 40 26 49\",\n \"Q 20 48 16 39\"\n ),\n text: { x: 22, y: 40 }\n },\n {\n key: \"O\",\n label: \"O\",\n path: closed(\n \"M 26 31\",\n \"Q 31 27 36 31\",\n \"Q 39 39 36 48\",\n \"Q 31 52 26 48\",\n \"Q 23 39 26 31\"\n ),\n text: { x: 31, y: 40 }\n },\n {\n key: \"D\",\n label: \"D\",\n path: closed(\n \"M 46 39\",\n \"Q 47 29 42 20\",\n \"Q 39 28 36 31\",\n \"Q 38 40 36 49\",\n \"Q 42 48 46 39\"\n ),\n text: { x: 40, y: 40 }\n },\n {\n key: \"L\",\n label: \"L\",\n path: closed(\n \"M 24 47\",\n \"Q 31 56 38 47\",\n \"Q 43 49 46 39\",\n \"Q 44 54 31 59\",\n \"Q 18 54 16 39\",\n \"Q 19 49 24 47\"\n ),\n text: { x: 31, y: 56 }\n }\n ];\n\n return {\n crownOutline,\n crownCap: crownOutline,\n rootPaths: [\n closed(\n \"M 22 57\",\n \"Q 25 60 28 57\",\n \"Q 28 71 25 90\",\n \"Q 23 101 20 109\",\n \"Q 17 99 17 86\",\n \"Q 17 71 22 57\"\n ),\n closed(\n \"M 34 57\",\n \"Q 37 60 40 57\",\n \"Q 45 71 45 86\",\n \"Q 45 99 42 109\",\n \"Q 39 101 37 90\",\n \"Q 34 71 34 57\"\n )\n ],\n surfaces\n };\n};\n\nconst buildMolarGeometry = (arch: \"upper\" | \"lower\"): ToothGeometry => {\n const crownOutline = closed(\n \"M 16 22\",\n \"Q 31 13 46 22\",\n \"Q 52 32 49 43\",\n \"Q 46 56 31 61\",\n \"Q 16 56 13 43\",\n \"Q 10 32 16 22\"\n );\n\n const surfaces: GeometrySurface[] = [\n {\n key: \"V\",\n label: \"V\",\n path: closed(\n \"M 16 22\",\n \"Q 31 12 46 22\",\n \"Q 42 31 38 34\",\n \"Q 31 36 24 34\",\n \"Q 20 31 16 22\"\n ),\n text: { x: 31, y: 26 }\n },\n {\n key: \"M\",\n label: \"M\",\n path: closed(\n \"M 13 43\",\n \"Q 11 32 16 22\",\n \"Q 20 31 24 34\",\n \"Q 22 44 24 53\",\n \"Q 17 52 13 43\"\n ),\n text: { x: 21, y: 43 }\n },\n {\n key: \"O\",\n label: \"O\",\n path: closed(\n \"M 24 34\",\n \"Q 31 29 38 34\",\n \"Q 41 43 38 52\",\n \"Q 31 56 24 52\",\n \"Q 21 43 24 34\"\n ),\n text: { x: 31, y: 43 }\n },\n {\n key: \"D\",\n label: \"D\",\n path: closed(\n \"M 49 43\",\n \"Q 51 32 46 22\",\n \"Q 42 31 38 34\",\n \"Q 40 44 38 53\",\n \"Q 45 52 49 43\"\n ),\n text: { x: 41, y: 43 }\n },\n {\n key: \"L\",\n label: \"L\",\n path: closed(\n \"M 22 51\",\n \"Q 31 62 40 51\",\n \"Q 46 52 49 43\",\n \"Q 46 58 31 64\",\n \"Q 16 58 13 43\",\n \"Q 16 52 22 51\"\n ),\n text: { x: 31, y: 60 }\n }\n ];\n\n const rootPaths =\n arch === \"upper\"\n ? [\n closed(\n \"M 17 61\",\n \"Q 20 64 23 61\",\n \"Q 24 73 22 91\",\n \"Q 20 103 17 111\",\n \"Q 14 101 14 88\",\n \"Q 14 73 17 61\"\n ),\n closed(\n \"M 28 61\",\n \"Q 31 65 34 61\",\n \"Q 36 76 35 96\",\n \"Q 34 111 31 122\",\n \"Q 28 111 27 96\",\n \"Q 26 76 28 61\"\n ),\n closed(\n \"M 39 61\",\n \"Q 42 64 45 61\",\n \"Q 48 73 48 88\",\n \"Q 48 101 45 111\",\n \"Q 42 103 40 91\",\n \"Q 38 73 39 61\"\n )\n ]\n : [\n closed(\n \"M 22 61\",\n \"Q 26 64 29 61\",\n \"Q 29 76 26 96\",\n \"Q 24 109 20 118\",\n \"Q 17 107 17 92\",\n \"Q 17 75 22 61\"\n ),\n closed(\n \"M 33 61\",\n \"Q 36 64 40 61\",\n \"Q 45 75 45 92\",\n \"Q 45 107 42 118\",\n \"Q 38 109 36 96\",\n \"Q 33 76 33 61\"\n )\n ];\n\n return {\n crownOutline,\n crownCap: crownOutline,\n rootPaths,\n surfaces\n };\n};\n\nexport const getToothGeometry = (definition: ToothDefinition): ToothGeometry => {\n if (definition.type === \"incisor\") {\n return buildIncisorGeometry(definition.visual.centerLabel);\n }\n\n if (definition.type === \"canine\") {\n return buildCanineGeometry();\n }\n\n if (definition.type === \"premolar\") {\n return buildPremolarGeometry();\n }\n\n return buildMolarGeometry(definition.arch);\n};\n","import { memo, useCallback, useMemo } from \"react\";\nimport { getConditionColor } from \"../../utils/odontogram\";\nimport { ToothSurface } from \"./ToothSurface\";\nimport { getToothGeometry } from \"./toothGeometry\";\nimport type { ToothCondition, ToothDefinition, ToothRecord, ToothSurface as ToothSurfaceType } from \"../../types\";\n\ntype ToothProps = {\n definition: ToothDefinition;\n record?: ToothRecord;\n editable: boolean;\n selectedCondition: ToothCondition;\n size: \"sm\" | \"md\" | \"lg\";\n onApplySurface: (tooth: string, surface: ToothSurfaceType, condition: ToothCondition) => void;\n onApplyTooth: (tooth: string, condition: ToothCondition) => void;\n onClearSurface: (tooth: string, surface: ToothSurfaceType) => void;\n onClearTooth: (tooth: string) => void;\n};\n\nconst sizeClassMap = {\n sm: {\n wrapper: \"ov-min-w-[64px] ov-gap-0.5\",\n label: \"ov-text-[11px]\",\n svg: \"ov-h-[124px] ov-w-[62px]\"\n },\n md: {\n wrapper: \"ov-min-w-[74px] ov-gap-0.5\",\n label: \"ov-text-xs\",\n svg: \"ov-h-[138px] ov-w-[98px]\"\n },\n lg: {\n wrapper: \"ov-min-w-[84px] ov-gap-0.5\",\n label: \"ov-text-sm\",\n svg: \"ov-h-[154px] ov-w-[108px]\"\n }\n} as const;\n\nexport const Tooth = memo(function Tooth({\n definition,\n record,\n editable,\n selectedCondition,\n size,\n onApplySurface,\n onApplyTooth,\n onClearSurface,\n onClearTooth\n}: ToothProps) {\n const sizeClasses = sizeClassMap[size];\n const geometry = useMemo(() => getToothGeometry(definition), [definition]);\n const toothConditions = record?.conditions ?? [];\n const toothFill = useMemo(\n () => (toothConditions.length ? getConditionColor(toothConditions[0]) : \"#f8fafc\"),\n [toothConditions]\n );\n\n const accentClass = useMemo(() => {\n if (definition.type === \"incisor\") {\n return \"ov-border-sky-100\";\n }\n if (definition.type === \"canine\") {\n return \"ov-border-amber-100\";\n }\n if (definition.type === \"premolar\") {\n return \"ov-border-emerald-100\";\n }\n return \"ov-border-rose-100\";\n }, [definition.type]);\n\n const handleApplySurface = useCallback(\n (surface: ToothSurfaceType) => onApplySurface(definition.id, surface, selectedCondition),\n [definition.id, onApplySurface, selectedCondition]\n );\n\n const handleClearSurface = useCallback(\n (surface: ToothSurfaceType) => onClearSurface(definition.id, surface),\n [definition.id, onClearSurface]\n );\n\n const handleApplyTooth = useCallback(() => {\n onApplyTooth(definition.id, selectedCondition);\n }, [definition.id, onApplyTooth, selectedCondition]);\n\n const handleClearTooth = useCallback(() => {\n onClearTooth(definition.id);\n }, [definition.id, onClearTooth]);\n\n return (\n <div className={[\"ov-flex ov-flex-col ov-items-center\", accentClass, sizeClasses.wrapper].join(\" \")}>\n <span className={[\"ov-font-semibold ov-text-clinic-700\", sizeClasses.label].join(\" \")}>\n {definition.label}\n </span>\n\n <svg viewBox=\"0 0 62 128\" className={sizeClasses.svg}>\n {geometry.rootPaths.map((root, index) => (\n <path\n key={`${definition.id}-root-${index}`}\n d={root}\n fill={toothFill}\n stroke=\"#1f2937\"\n strokeWidth={1.4}\n strokeLinejoin=\"round\"\n className={editable ? \"ov-cursor-pointer ov-transition-opacity hover:ov-opacity-85\" : \"\"}\n onClick={editable ? handleApplyTooth : undefined}\n onContextMenu={\n editable\n ? (event) => {\n event.preventDefault();\n handleClearTooth();\n }\n : undefined\n }\n />\n ))}\n\n <path d={geometry.crownCap} fill={toothFill} stroke=\"#1f2937\" strokeWidth={1.6} />\n\n {geometry.surfaces.map((surface) => (\n <ToothSurface\n key={`${definition.id}-${surface.key}`}\n surface={surface.key}\n label={surface.label}\n path={surface.path}\n textX={surface.text.x}\n textY={surface.text.y}\n condition={record?.surfaces?.[surface.key]?.[0]}\n onApply={handleApplySurface}\n onClear={handleClearSurface}\n disabled={!editable}\n />\n ))}\n\n <path\n d={geometry.crownOutline}\n fill=\"none\"\n stroke=\"#0f172a\"\n strokeWidth={1.6}\n strokeLinejoin=\"round\"\n className={editable ? \"ov-cursor-pointer\" : \"\"}\n onClick={editable ? handleApplyTooth : undefined}\n onContextMenu={\n editable\n ? (event) => {\n event.preventDefault();\n handleClearTooth();\n }\n : undefined\n }\n />\n </svg>\n </div>\n );\n});\n","import { memo } from \"react\";\nimport { Tooth } from \"../Tooth/Tooth\";\nimport type { ToothCondition, ToothDefinition, ToothStateMap, ToothSurface } from \"../../types\";\n\ntype QuadrantProps = {\n label: string;\n teeth: readonly ToothDefinition[];\n records: ToothStateMap;\n editable: boolean;\n selectedCondition: ToothCondition;\n size: \"sm\" | \"md\" | \"lg\";\n onApplySurface: (tooth: string, surface: ToothSurface, condition: ToothCondition) => void;\n onApplyTooth: (tooth: string, condition: ToothCondition) => void;\n onClearSurface: (tooth: string, surface: ToothSurface) => void;\n onClearTooth: (tooth: string) => void;\n};\n\nexport const Quadrant = memo(function Quadrant({\n teeth,\n records,\n editable,\n selectedCondition,\n size,\n onApplySurface,\n onApplyTooth,\n onClearSurface,\n onClearTooth\n}: QuadrantProps) {\n return (\n <section>\n <div className=\"ov-overflow-x-auto ov-pb-1\">\n <div className=\"ov-flex ov-min-w-max ov-justify-center ov-gap-0.5\">\n {teeth.map((definition) => (\n <Tooth\n key={definition.id}\n definition={definition}\n record={records[definition.id]}\n editable={editable}\n selectedCondition={selectedCondition}\n size={size}\n onApplySurface={onApplySurface}\n onApplyTooth={onApplyTooth}\n onClearSurface={onClearSurface}\n onClearTooth={onClearTooth}\n />\n ))}\n </div>\n </div>\n </section>\n );\n});\n","import { memo } from \"react\";\nimport { CLINICAL_CONDITIONS } from \"../../constants\";\nimport type { ToothCondition } from \"../../types\";\n\ntype ToolbarProps = {\n selectedCondition: ToothCondition;\n onSelect: (condition: ToothCondition) => void;\n};\n\nexport const Toolbar = memo(function Toolbar({ selectedCondition, onSelect }: ToolbarProps) {\n return (\n <div className=\"ov-rounded-3xl ov-border ov-border-slate-200 ov-bg-white ov-p-4 ov-shadow-panel\">\n <div className=\"ov-mb-3 ov-flex ov-items-center ov-justify-between ov-gap-3\">\n <div>\n <p className=\"ov-text-xs ov-font-semibold ov-uppercase ov-tracking-[0.22em] ov-text-clinic-600\">\n Estados clínicos\n </p>\n <p className=\"ov-text-sm ov-text-slate-500\">\n Click izquierdo aplica. Click derecho limpia solo la pieza o superficie elegida.\n </p>\n </div>\n <div className=\"ov-rounded-full ov-bg-clinic-50 ov-px-3 ov-py-1 ov-text-xs ov-font-medium ov-text-clinic-700\">\n Activo: {selectedCondition}\n </div>\n </div>\n\n <div className=\"ov-flex ov-flex-wrap ov-gap-2\">\n {CLINICAL_CONDITIONS.map((condition) => {\n const isActive = condition.id === selectedCondition;\n\n return (\n <button\n key={condition.id}\n type=\"button\"\n onClick={() => onSelect(condition.id)}\n className={[\n \"ov-flex ov-items-center ov-gap-2 ov-rounded-full ov-border ov-px-3 ov-py-2 ov-text-sm ov-transition\",\n isActive\n ? \"ov-border-clinic-700 ov-bg-clinic-900 ov-text-white\"\n : \"ov-border-slate-200 ov-bg-slate-50 ov-text-slate-700 hover:ov-border-clinic-400 hover:ov-bg-white\"\n ].join(\" \")}\n >\n <span\n className=\"ov-h-3 ov-w-3 ov-rounded-full ov-border ov-border-white/40\"\n style={{ backgroundColor: condition.color }}\n />\n <span>{condition.label}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n});\n","import { memo, useCallback, useMemo, useState } from \"react\";\nimport {\n MIXED_DENTITION_LAYOUT,\n PERMANENT_DENTITION_LAYOUT,\n PRIMARY_DENTITION_LAYOUT\n} from \"../../constants\";\nimport {\n applySurfaceCondition,\n applyToothCondition,\n clearSurfaceCondition,\n clearToothCondition,\n normalizeChanges,\n serializeChanges\n} from \"../../utils/odontogram\";\nimport { Quadrant } from \"../Quadrant/Quadrant\";\nimport { Toolbar } from \"../Toolbar/Toolbar\";\nimport type { OdontogramProps, ToothCondition, ToothStateMap, ToothSurface } from \"../../types\";\n\nconst DEFAULT_CONDITION: ToothCondition = \"CARIES\";\n\nexport const Odontogram = memo(function Odontogram({\n value,\n defaultValue,\n onChange,\n dentition = \"mixed\",\n selectedCondition,\n onSelectedConditionChange,\n editable = true,\n size = \"md\",\n className,\n theme\n}: OdontogramProps) {\n const isControlled = typeof value !== \"undefined\";\n const [internalState, setInternalState] = useState<ToothStateMap>(() =>\n normalizeChanges(defaultValue)\n );\n const [internalCondition, setInternalCondition] = useState<ToothCondition>(DEFAULT_CONDITION);\n\n const records = useMemo(\n () => (isControlled ? normalizeChanges(value) : internalState),\n [internalState, isControlled, value]\n );\n\n const activeCondition = selectedCondition ?? internalCondition;\n\n const updateRecords = useCallback(\n (nextState: ToothStateMap) => {\n if (!isControlled) {\n setInternalState(nextState);\n }\n\n onChange?.(serializeChanges(nextState));\n },\n [isControlled, onChange]\n );\n\n const selectCondition = useCallback(\n (condition: ToothCondition) => {\n if (!selectedCondition) {\n setInternalCondition(condition);\n }\n\n onSelectedConditionChange?.(condition);\n },\n [onSelectedConditionChange, selectedCondition]\n );\n\n const handleApplySurface = useCallback(\n (tooth: string, surface: ToothSurface, condition: ToothCondition) => {\n updateRecords(applySurfaceCondition(records, tooth, surface, condition));\n },\n [records, updateRecords]\n );\n\n const handleApplyTooth = useCallback(\n (tooth: string, condition: ToothCondition) => {\n updateRecords(applyToothCondition(records, tooth, condition));\n },\n [records, updateRecords]\n );\n\n const handleClearSurface = useCallback(\n (tooth: string, surface: ToothSurface) => {\n updateRecords(clearSurfaceCondition(records, tooth, surface));\n },\n [records, updateRecords]\n );\n\n const handleClearTooth = useCallback(\n (tooth: string) => {\n updateRecords(clearToothCondition(records, tooth));\n },\n [records, updateRecords]\n );\n\n const layout = useMemo(() => {\n if (dentition === \"permanent\") {\n return [\n { id: \"permanent-upper\", label: \"Superior permanente\", teeth: PERMANENT_DENTITION_LAYOUT.upper },\n { id: \"permanent-lower\", label: \"Inferior permanente\", teeth: PERMANENT_DENTITION_LAYOUT.lower }\n ];\n }\n\n if (dentition === \"primary\") {\n return [\n { id: \"primary-upper\", label: \"Superior temporal\", teeth: PRIMARY_DENTITION_LAYOUT.upper },\n { id: \"primary-lower\", label: \"Inferior temporal\", teeth: PRIMARY_DENTITION_LAYOUT.lower }\n ];\n }\n\n return [...MIXED_DENTITION_LAYOUT];\n }, [dentition]);\n\n return (\n <div\n className={[\n \"ov-odontogram ov-w-full ov-max-w-full ov-overflow-hidden ov-rounded-[28px] ov-border ov-border-slate-200 ov-bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.98),_rgba(240,248,249,0.98)_40%,_rgba(229,239,241,1)_100%)] ov-p-4 ov-text-slate-900 ov-shadow-panel md:ov-p-6\",\n className ?? \"\"\n ].join(\" \")}\n style={theme?.panelStyle}\n onContextMenu={(event) => {\n event.preventDefault();\n }}\n >\n <div className=\"ov-space-y-5\">\n <Toolbar selectedCondition={activeCondition} onSelect={selectCondition} />\n\n <div className=\"ov-overflow-x-auto ov-overflow-y-hidden\">\n <div className=\"ov-grid ov-min-w-max ov-gap-5\">\n {layout.map((section) => (\n <Quadrant\n key={section.id}\n label={section.label}\n teeth={section.teeth}\n records={records}\n editable={editable}\n selectedCondition={activeCondition}\n size={size}\n onApplySurface={handleApplySurface}\n onApplyTooth={handleApplyTooth}\n onClearSurface={handleClearSurface}\n onClearTooth={handleClearTooth}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","reactJsxRuntime_production","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","owner","debugStack","debugTask","refProp","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","isValidElement","object","React","require$$0","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","PERMANENT_SURFACE_MAP","PRIMARY_SURFACE_MAP","ROOT_COUNT_BY_TOOTH","visualConfigByType","toothId","arch","rootCount","buildQuadrant","quadrant","toothNumbers","dentition","typeMap","position","upperPermanentLeft","upperPermanentRight","lowerPermanentLeft","lowerPermanentRight","upperPrimaryLeft","upperPrimaryRight","lowerPrimaryLeft","lowerPrimaryRight","PERMANENT_DENTITION_LAYOUT","PRIMARY_DENTITION_LAYOUT","MIXED_DENTITION_LAYOUT","CLINICAL_CONDITIONS","conditionMap","condition","dedupe","conditions","sortConditions","left","right","normalizeChanges","normalized","record","surface","serializeChanges","state","nextRecord","_a","cleanupRecord","surfaces","hasToothConditions","hasSurfaceConditions","applySurfaceCondition","tooth","current","currentSurfaceValues","applyToothCondition","clearSurfaceCondition","_b","nextSurfaces","clearToothCondition","nextState","getConditionColor","item","ToothSurface","memo","label","path","textX","textY","onApply","onClear","disabled","jsx","event","closed","segments","buildIncisorGeometry","centerLabel","crownOutline","buildCanineGeometry","buildPremolarGeometry","buildMolarGeometry","rootPaths","getToothGeometry","definition","sizeClassMap","Tooth","editable","selectedCondition","size","onApplySurface","onApplyTooth","onClearSurface","onClearTooth","sizeClasses","geometry","useMemo","toothConditions","toothFill","accentClass","handleApplySurface","useCallback","handleClearSurface","handleApplyTooth","handleClearTooth","jsxs","root","index","Quadrant","teeth","records","Toolbar","onSelect","isActive","DEFAULT_CONDITION","Odontogram","defaultValue","onChange","onSelectedConditionChange","className","theme","isControlled","internalState","setInternalState","useState","internalCondition","setInternalCondition","activeCondition","updateRecords","selectCondition","layout","section"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { Odontogram } from './lib/components/Odontogram/Odontogram';
|
|
2
|
+
export type { OdontogramChange, OdontogramProps, ToothCondition, ToothRecord, ToothSurface, ToothType } from './lib/types';
|
|
3
|
+
export { CLINICAL_CONDITIONS, MIXED_DENTITION_LAYOUT, PERMANENT_DENTITION_LAYOUT, PRIMARY_DENTITION_LAYOUT } from './lib/constants';
|