@kmanueldc/vue-odontogram 0.1.1
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/LICENSE +21 -0
- package/README.md +720 -0
- package/THIRD_PARTY_NOTICES.md +37 -0
- package/dist/catalogs/nts-peru.d.ts +277 -0
- package/dist/components/ConditionLabels.vue.d.ts +40 -0
- package/dist/components/FindingPrimitives.vue.d.ts +6 -0
- package/dist/components/Odontogram.vue.d.ts +131 -0
- package/dist/components/OdontogramTooltip.vue.d.ts +82 -0
- package/dist/components/SurfaceDiagrams.vue.d.ts +33 -0
- package/dist/components/SurfaceGuide.vue.d.ts +47 -0
- package/dist/components/Tooth.vue.d.ts +56 -0
- package/dist/components/ToothInspector.vue.d.ts +57 -0
- package/dist/composables/useOdontogram.d.ts +43 -0
- package/dist/composables/useToothSelection.d.ts +11 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/permanent-horizontal.d.ts +8 -0
- package/dist/data/permanent.d.ts +8 -0
- package/dist/data/primary-horizontal.d.ts +19 -0
- package/dist/data/primary.d.ts +14 -0
- package/dist/index.d.ts +26 -0
- package/dist/types/findings.d.ts +154 -0
- package/dist/types/geometry.d.ts +18 -0
- package/dist/types/odontogram.d.ts +119 -0
- package/dist/types/surfaces.d.ts +21 -0
- package/dist/utils/anchors.d.ts +37 -0
- package/dist/utils/compositions.d.ts +41 -0
- package/dist/utils/dentition-layout.d.ts +27 -0
- package/dist/utils/finding-records.d.ts +82 -0
- package/dist/utils/findings.d.ts +74 -0
- package/dist/utils/labels.d.ts +4 -0
- package/dist/utils/layout.d.ts +19 -0
- package/dist/utils/mixed-layout.d.ts +20 -0
- package/dist/utils/navigation.d.ts +11 -0
- package/dist/utils/notation.d.ts +26 -0
- package/dist/utils/numbers.d.ts +28 -0
- package/dist/utils/primary-horizontal-layout.d.ts +13 -0
- package/dist/utils/primary-layout.d.ts +34 -0
- package/dist/utils/quadrants.d.ts +6 -0
- package/dist/utils/state-marks.d.ts +35 -0
- package/dist/utils/surfaces.d.ts +118 -0
- package/dist/utils/svg-geometry.d.ts +36 -0
- package/dist/utils/tooth-frames.d.ts +51 -0
- package/dist/vue-odontogram.css +1 -0
- package/dist/vue-odontogram.js +3202 -0
- package/dist/vue-odontogram.umd.cjs +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
# vue-odontogram
|
|
2
|
+
|
|
3
|
+
Componente Vue 3 para visualizar y seleccionar dientes mediante SVG e identificadores FDI. Renderiza dentición permanente y primaria; la geometría primaria actual es provisional y solo sirve para desarrollo visual.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @kmanueldc/vue-odontogram
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Importa los estilos del paquete:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import '@kmanueldc/vue-odontogram/style.css'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Uso básico
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import { ref } from 'vue'
|
|
22
|
+
import { Odontogram } from '@kmanueldc/vue-odontogram'
|
|
23
|
+
import '@kmanueldc/vue-odontogram/style.css'
|
|
24
|
+
|
|
25
|
+
const selectedTeeth = ref<string[]>([])
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<Odontogram v-model="selectedTeeth" />
|
|
30
|
+
</template>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`v-model` contiene IDs FDI puros, por ejemplo `['11', '12', '26']`.
|
|
34
|
+
|
|
35
|
+
## Denticiones
|
|
36
|
+
|
|
37
|
+
### Permanente
|
|
38
|
+
|
|
39
|
+
La dentición permanente es el valor por defecto y muestra 32 piezas FDI `11–48`.
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<Odontogram v-model="selectedTeeth" dentition="permanent" />
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Primaria
|
|
46
|
+
|
|
47
|
+
La dentición primaria muestra 20 piezas FDI. Su dataset SVG está marcado como **provisional**, no cuenta con validación odontológica y no debe emplearse para diagnóstico, tratamiento ni representación clínica definitiva.
|
|
48
|
+
|
|
49
|
+
```vue
|
|
50
|
+
<script setup lang="ts">
|
|
51
|
+
import { ref } from 'vue'
|
|
52
|
+
|
|
53
|
+
const selectedPrimary = ref(['51', '52', '65'])
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<Odontogram v-model="selectedPrimary" dentition="primary" />
|
|
58
|
+
</template>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Cuadrante | Piezas FDI temporales |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| Superior derecha | `51–55` |
|
|
64
|
+
| Superior izquierda | `61–65` |
|
|
65
|
+
| Inferior izquierda | `71–75` |
|
|
66
|
+
| Inferior derecha | `81–85` |
|
|
67
|
+
|
|
68
|
+
Cada cuadrante contiene incisivo central, incisivo lateral, canino, primer molar temporal y segundo molar temporal. No se reutilizan premolares permanentes como molares temporales.
|
|
69
|
+
|
|
70
|
+
### Mixta
|
|
71
|
+
|
|
72
|
+
`dentition="mixed"` dibuja juntas las piezas permanentes y las temporales, como en la ficha de odontograma de la NTS. La prop `teeth` indica qué piezas están en boca; sin ella se muestran las 52.
|
|
73
|
+
|
|
74
|
+
```vue
|
|
75
|
+
<script setup lang="ts">
|
|
76
|
+
import { ref } from 'vue'
|
|
77
|
+
|
|
78
|
+
// Ocho años: primeros molares e incisivos permanentes, caninos y molares temporales.
|
|
79
|
+
const teeth = [
|
|
80
|
+
'16', '12', '11', '21', '22', '26', '36', '32', '31', '41', '42', '46',
|
|
81
|
+
'55', '54', '53', '63', '64', '65', '75', '74', '73', '83', '84', '85',
|
|
82
|
+
]
|
|
83
|
+
const selectedTeeth = ref<string[]>([])
|
|
84
|
+
</script>
|
|
85
|
+
|
|
86
|
+
<template>
|
|
87
|
+
<Odontogram v-model="selectedTeeth" dentition="mixed" layout="horizontal" :teeth="teeth" show-numbers />
|
|
88
|
+
</template>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **`horizontal`:** cuatro filas, de arriba abajo `18–28`, `55–65`, `85–75` y `48–38`. Las filas temporales están escaladas para que cada molar temporal quede alineado con el premolar que lo reemplaza (55 bajo 15) y comparten la línea media.
|
|
92
|
+
- **`arch`:** las arcadas temporales, a menor escala, dentro de las permanentes.
|
|
93
|
+
|
|
94
|
+
Las piezas conservan su ID FDI, así que `v-model`, `v-model:surfaces`, `toothStates`, `findings`, `conditions`, los eventos y `notation` funcionan igual que en las otras denticiones. Una fila es una arcada de una dentición: la navegación con `↑`/`↓` pasa por las cuatro filas, y los hallazgos de tramo o entre dos piezas deben estar en la misma fila. Las formas temporales son las mismas del dataset primario **provisional**.
|
|
95
|
+
|
|
96
|
+
`teeth` también filtra las denticiones `permanent` y `primary`. Los IDs que no pertenecen a la dentición se ignoran con un aviso en consola.
|
|
97
|
+
|
|
98
|
+
## Layouts
|
|
99
|
+
|
|
100
|
+
Los layouts cambian solamente la presentación: nunca modifican IDs FDI, selección, condiciones ni eventos.
|
|
101
|
+
|
|
102
|
+
| Dentición | Layouts disponibles | Nota |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| Permanente | `arch`, `horizontal` | Ambos usan datasets SVG permanentes propios. |
|
|
105
|
+
| Primaria | `arch`, `horizontal` | Ambos usan datasets SVG pediátricos propios y **provisionales**. |
|
|
106
|
+
| Mixta | `arch`, `horizontal` | Combina ambos datasets; `horizontal` sigue las filas de la ficha NTS. Ver [Mixta](#mixta). |
|
|
107
|
+
|
|
108
|
+
```vue
|
|
109
|
+
<Odontogram layout="arch" />
|
|
110
|
+
<Odontogram layout="horizontal" dentition="permanent" />
|
|
111
|
+
<Odontogram layout="arch" dentition="primary" />
|
|
112
|
+
<Odontogram layout="horizontal" dentition="primary" />
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Primary Horizontal usa un segundo dataset y composición pediátricos propios. Ambos layouts Primary son provisionales, se destinan a desarrollo visual y no representan anatomía validada.
|
|
116
|
+
|
|
117
|
+
## Selección y condiciones
|
|
118
|
+
|
|
119
|
+
La selección usa los mismos IDs FDI en ambas denticiones. Se puede limitar a una pieza con `singleSelect` y definir condiciones por ID:
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<Odontogram
|
|
123
|
+
v-model="selectedPrimary"
|
|
124
|
+
dentition="primary"
|
|
125
|
+
:conditions="[
|
|
126
|
+
{
|
|
127
|
+
label: 'observation',
|
|
128
|
+
teeth: ['51', '65'],
|
|
129
|
+
fillColor: '#fbbf24',
|
|
130
|
+
outlineColor: '#b45309',
|
|
131
|
+
},
|
|
132
|
+
]"
|
|
133
|
+
show-labels
|
|
134
|
+
show-tooltip
|
|
135
|
+
/>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Cada pieza muestra una sola condición: si un ID aparece en varios grupos, se aplica el **último** grupo de `conditions`.
|
|
139
|
+
|
|
140
|
+
## Props principales
|
|
141
|
+
|
|
142
|
+
| Prop | Tipo | Valor por defecto | Descripción |
|
|
143
|
+
| --- | --- | --- | --- |
|
|
144
|
+
| `modelValue` | `string[]` | `[]` | IDs FDI seleccionados; se usa con `v-model`. |
|
|
145
|
+
| `teeth` | `string[]` | todas | IDs FDI de las piezas que se dibujan. Pensada para la dentición mixta; ver [Mixta](#mixta). |
|
|
146
|
+
| `dentition` | `'permanent' \| 'primary' \| 'mixed'` | `'permanent'` | Conjunto de piezas que se renderiza. |
|
|
147
|
+
| `notation` | `ToothNotation` | `'FDI'` | `'FDI'`, `'Universal'` o `'Palmer'`. Solo cambia el texto mostrado; los IDs, `v-model` y eventos siguen en FDI. Ver [Notaciones](#notaciones). |
|
|
148
|
+
| `layout` | `OdontogramLayout` | `'arch'` | `'arch'` o `'horizontal'`, disponible para Permanent y Primary; el dataset Primary sigue siendo provisional. |
|
|
149
|
+
| `singleSelect` | `boolean` | `false` | Limita la selección a una pieza. |
|
|
150
|
+
| `disabled` | `boolean` | `false` | Deshabilita interacción y selección. |
|
|
151
|
+
| `showTooltip` | `boolean` | `true` | Activa el tooltip al pasar el cursor o enfocar una pieza con el teclado. |
|
|
152
|
+
| `showLabels` | `boolean` | `false` | Muestra la leyenda de condiciones. |
|
|
153
|
+
| `conditions` | `OdontogramCondition[]` | `undefined` | Colores y etiqueta por IDs FDI. |
|
|
154
|
+
| `labels` | `OdontogramLabelsInput` | textos en inglés | Traduce los textos visibles y accesibles. Ver [Textos e idioma](#textos-e-idioma). |
|
|
155
|
+
| `showNumbers` | `boolean` | `false` | Muestra el número FDI de cada pieza del lado oclusal: frente a la pieza, perpendicular al arco y hacia su interior en `arch`, y entre ambas filas en `horizontal`. |
|
|
156
|
+
| `toothStates` | `OdontogramToothStates` | `undefined` | Estado de presencia por ID FDI: `missing`, `extracted`, `implant` o `unerupted`; las piezas no indicadas son `present`. Ver [Estado de pieza](#estado-de-pieza). |
|
|
157
|
+
| `findings` | `OdontogramFinding[]` | `undefined` | Hallazgos clínicos (fractura, corona, prótesis…). Ver [Hallazgos](#hallazgos). |
|
|
158
|
+
| `findingCatalog` | `FindingCatalog` | `ntsPeruFindingCatalog` | Catálogo que define nombre, símbolo y color de cada código de hallazgo. |
|
|
159
|
+
| `showSurfaces` | `boolean` | `false` | Muestra el diagrama de 5 superficies junto a cada pieza. Ver [Superficies](#superficies). |
|
|
160
|
+
| `showSurfaceLetters` | `boolean` | `false` | Dibuja la letra de cada superficie (V, M, O/I, D, L/P) sobre los diagramas. |
|
|
161
|
+
| `surfaceShape` | `'square' \| 'circle'` | `'square'` | Forma del diagrama de superficies: cuadrado con trapecios o círculo con sectores. |
|
|
162
|
+
| `surfaces` | `OdontogramSurfaces` | `{}` | Superficies seleccionadas por ID FDI; se usa con `v-model:surfaces`. |
|
|
163
|
+
| `showHalf` | `OdontogramHalf` | `'full'` | `'full'`, `'upper'` o `'lower'`. Muestra una sola arcada y recorta el alto del `viewBox`; la selección de la arcada oculta se conserva. |
|
|
164
|
+
|
|
165
|
+
## Eventos
|
|
166
|
+
|
|
167
|
+
| Evento | Payload |
|
|
168
|
+
| --- | --- |
|
|
169
|
+
| `update:modelValue` | `string[]` con la nueva selección. |
|
|
170
|
+
| `change` | `string[]` con la nueva selección. |
|
|
171
|
+
| `tooth-click` | `ToothDefinition`, seguido de `string[]` con la selección. |
|
|
172
|
+
| `update:surfaces` | `OdontogramSurfaces` con las nuevas superficies seleccionadas. |
|
|
173
|
+
| `surface-click` | `ToothDefinition`, `ToothSurface` y `OdontogramSurfaces` resultante. |
|
|
174
|
+
|
|
175
|
+
## Estado de pieza
|
|
176
|
+
|
|
177
|
+
`toothStates` indica la presencia de cada pieza, indexada por ID FDI:
|
|
178
|
+
|
|
179
|
+
```vue
|
|
180
|
+
<Odontogram
|
|
181
|
+
v-model="selectedTeeth"
|
|
182
|
+
:tooth-states="{ 18: 'extracted', 28: 'missing', 36: 'implant', 48: 'unerupted' }"
|
|
183
|
+
show-labels
|
|
184
|
+
/>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
| Estado | Significado | Representación |
|
|
188
|
+
| --- | --- | --- |
|
|
189
|
+
| `present` | Pieza presente (por defecto). | Normal. |
|
|
190
|
+
| `missing` | Ausente (agenesia o causa desconocida). | Solo contorno punteado y atenuado. |
|
|
191
|
+
| `extracted` | Extraída. | Contorno punteado atenuado y una X. |
|
|
192
|
+
| `implant` | Reemplazada por un implante. | Pieza normal con un implante roscado encima. |
|
|
193
|
+
| `unerupted` | No erupcionada. | Pieza completa atenuada. |
|
|
194
|
+
|
|
195
|
+
El estado es independiente de la selección y de las condiciones: una pieza ausente sigue siendo seleccionable, enfocable y navegable (por ejemplo, para planificar un implante), y emite los mismos eventos. Las piezas ausentes no muestran el relleno de su condición.
|
|
196
|
+
|
|
197
|
+
El estado se añade al nombre accesible (`Tooth 18, Extracted`), aparece en el tooltip (`State: Extracted`) y en el slot `tooltip` como `state`. Con `show-labels`, la leyenda incluye los estados presentes en las piezas visibles. Cada pieza lleva el atributo `data-tooth-state` y la clase `odontogram-tooth--<estado>` para estilos propios; por ejemplo, para ocultar por completo las piezas ausentes:
|
|
198
|
+
|
|
199
|
+
```css
|
|
200
|
+
.odontogram-tooth--missing {
|
|
201
|
+
opacity: 0;
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Notaciones
|
|
206
|
+
|
|
207
|
+
`notation` cambia cómo se muestran los números en la dentición permanente y en la primaria. Solo afecta al texto: los IDs de `v-model`, `v-model:surfaces`, `toothStates`, `findings`, `conditions` y de los eventos, así como `data-tooth-id`, siguen siendo FDI.
|
|
208
|
+
|
|
209
|
+
```vue
|
|
210
|
+
<Odontogram v-model="selectedTeeth" notation="Universal" show-numbers />
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
| FDI | Universal | Palmer |
|
|
214
|
+
| --- | --- | --- |
|
|
215
|
+
| `18` … `11`, `21` … `28` | `1` … `8`, `9` … `16` | `8┘` … `1┘`, `└1` … `└8` |
|
|
216
|
+
| `48` … `41`, `31` … `38` | `32` … `25`, `24` … `17` | `8┐` … `1┐`, `┌1` … `┌8` |
|
|
217
|
+
| `55` … `51`, `61` … `65` | `A` … `E`, `F` … `J` | `E┘` … `A┘`, `└A` … `└E` |
|
|
218
|
+
| `85` … `81`, `71` … `75` | `T` … `P`, `O` … `K` | `E┐` … `A┐`, `┌A` … `┌E` |
|
|
219
|
+
|
|
220
|
+
- **Dónde se aplica:** números de `show-numbers`, `<title>` de cada pieza, tooltip (`Tooth: 8`) y nombres accesibles de piezas y superficies. El slot `tooltip` recibe `number` con el número mostrado, además de `tooth` (con su `id` FDI).
|
|
221
|
+
- **Palmer:** en los números del gráfico, la esquina del cuadrante se dibuja con líneas SVG. La línea horizontal mira a la otra arcada y la vertical a la línea media. En `<title>` y en el tooltip se usan caracteres de recuadro (`6┘`). En los nombres accesibles se usa la forma textual `UR6`, `ULA`, `LL4`, `LRD`, porque los lectores de pantalla no leen bien esos caracteres.
|
|
222
|
+
|
|
223
|
+
`formatToothNumber(toothId, notation, style?)` hace la misma conversión fuera del componente (`style: 'text'` para la forma `UR6`), y `getPalmerQuadrant(toothId)` devuelve el cuadrante (`'upper-right'`…).
|
|
224
|
+
|
|
225
|
+
## Superficies
|
|
226
|
+
|
|
227
|
+
Con `show-surfaces`, cada pieza muestra un diagrama de 5 superficies en su lado vestibular. La selección de superficies es independiente de la de piezas y se enlaza con `v-model:surfaces`:
|
|
228
|
+
|
|
229
|
+
```vue
|
|
230
|
+
<script setup lang="ts">
|
|
231
|
+
import { ref } from 'vue'
|
|
232
|
+
import { Odontogram, type OdontogramSurfaces } from '@kmanueldc/vue-odontogram'
|
|
233
|
+
|
|
234
|
+
const selectedTeeth = ref<string[]>([])
|
|
235
|
+
const surfaces = ref<OdontogramSurfaces>({ 16: ['occlusal', 'mesial'] })
|
|
236
|
+
</script>
|
|
237
|
+
|
|
238
|
+
<template>
|
|
239
|
+
<Odontogram v-model="selectedTeeth" v-model:surfaces="surfaces" show-surfaces />
|
|
240
|
+
</template>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
El modelo indexa por ID FDI la lista de superficies seleccionadas. Las claves (`ToothSurface`) son las mismas en todas las piezas y el nombre clínico se adapta a cada una:
|
|
244
|
+
|
|
245
|
+
| Clave | Nombre | Posición en el diagrama |
|
|
246
|
+
| --- | --- | --- |
|
|
247
|
+
| `vestibular` | Vestibular | Lado exterior del arco (labios o mejillas). |
|
|
248
|
+
| `mesial` | Mesial | Lado de la línea media. |
|
|
249
|
+
| `occlusal` | Oclusal; **incisal** en incisivos y caninos | Cuadrado central. |
|
|
250
|
+
| `distal` | Distal | Lado opuesto a la línea media. |
|
|
251
|
+
| `lingual` | Lingual; **palatino** en piezas superiores | Lado interior del arco o de la otra fila. |
|
|
252
|
+
|
|
253
|
+
El diagrama gira con la pieza, así que en `arch` sigue la curva del arco y en `horizontal` queda con vestibular arriba en la arcada superior y abajo en la inferior. Todos los diagramas tienen el mismo tamaño, proporcional a las piezas; el `viewBox` crece para incluirlos y las siglas y tramos de los hallazgos se desplazan más allá del diagrama.
|
|
254
|
+
|
|
255
|
+
Con `surface-shape="circle"`, el diagrama es un círculo dividido en cuatro sectores (vestibular, mesial, lingual y distal) más un círculo central (oclusal o incisal). Todo lo demás (selección, hallazgos, letras, guía) funciona igual con ambas formas.
|
|
256
|
+
|
|
257
|
+
Con `show-tooltip`, al pasar el cursor o enfocar una superficie se muestra su tooltip: pieza, superficie, su definición, los hallazgos de esa superficie y si está seleccionada. El slot `tooltip` recibe además `surface` y `surfaceName` (vacíos cuando el tooltip es de una pieza).
|
|
258
|
+
|
|
259
|
+
Cada superficie es un `checkbox` accesible (`Tooth 11, Incisal`) con `aria-checked`. Al hacer clic, o con `Enter`/`Espacio`, se emite `update:surfaces` con un modelo nuevo (las superficies en el orden de `toothSurfaces` y sin piezas vacías) y `surface-click`. Las piezas `missing` y `extracted` muestran el diagrama atenuado y no permiten seleccionar superficies; `disabled` bloquea todas.
|
|
260
|
+
|
|
261
|
+
Las superficies tienen su propia parada de tabulación: la última enfocada, la primera seleccionada o la primera superficie de la primera pieza.
|
|
262
|
+
|
|
263
|
+
| Tecla | Acción |
|
|
264
|
+
| --- | --- |
|
|
265
|
+
| `←` / `→`, `Inicio` / `Fin` | Misma superficie en la pieza anterior, siguiente, primera o última de la arcada, en el orden de pantalla. |
|
|
266
|
+
| `↑` / `↓` | Superficie anterior o siguiente de la pieza (vestibular, mesial, oclusal, distal, lingual). |
|
|
267
|
+
| `Enter` / `Espacio` | Selecciona o deselecciona la superficie. |
|
|
268
|
+
|
|
269
|
+
### Guía de superficies
|
|
270
|
+
|
|
271
|
+
`SurfaceGuide` es una referencia visual de las superficies de una pieza: un diagrama grande con las letras (V, M, O/I, D, L/P) y la lista de superficies con su nombre y su definición, adaptados a la pieza (incisal, palatina…). Al pasar el cursor o enfocar una superficie, se resalta en el diagrama y en la lista. Con `findings`, dibuja y lista los hallazgos de superficie de la pieza.
|
|
272
|
+
|
|
273
|
+
```vue
|
|
274
|
+
<script setup lang="ts">
|
|
275
|
+
import { computed, ref } from 'vue'
|
|
276
|
+
import { Odontogram, SurfaceGuide, toggleSurface, type OdontogramSurfaces } from '@kmanueldc/vue-odontogram'
|
|
277
|
+
|
|
278
|
+
const findings = ref([{ code: 'caries', teeth: ['36'], surfaces: ['mesial'] }])
|
|
279
|
+
const selectedTeeth = ref<string[]>(['36'])
|
|
280
|
+
const surfaces = ref<OdontogramSurfaces>({})
|
|
281
|
+
const toothId = computed(() => selectedTeeth.value.at(-1) ?? '16')
|
|
282
|
+
</script>
|
|
283
|
+
|
|
284
|
+
<template>
|
|
285
|
+
<Odontogram v-model="selectedTeeth" v-model:surfaces="surfaces" :findings="findings" show-surfaces />
|
|
286
|
+
<SurfaceGuide
|
|
287
|
+
:tooth-id="toothId"
|
|
288
|
+
:findings="findings"
|
|
289
|
+
:selected="surfaces[toothId]"
|
|
290
|
+
@surface-click="(surface) => (surfaces = toggleSurface(surfaces, toothId, surface))"
|
|
291
|
+
/>
|
|
292
|
+
</template>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
| Prop | Descripción |
|
|
296
|
+
| --- | --- |
|
|
297
|
+
| `toothId` | ID FDI de la pieza. |
|
|
298
|
+
| `findings` / `findingCatalog` | Hallazgos del gráfico; la guía dibuja y lista los de superficie de esta pieza. |
|
|
299
|
+
| `selected` | Superficies que se muestran seleccionadas. |
|
|
300
|
+
| `active` | Superficie resaltada; también se actualiza con el cursor y el foco (`update:active`). |
|
|
301
|
+
| `shape` | `'square'` o `'circle'`, como `surfaceShape` del odontograma. |
|
|
302
|
+
| `labels`, `notation`, `disabled` | Igual que en `Odontogram`. |
|
|
303
|
+
|
|
304
|
+
Emite `surface-click` con la superficie. La orientación es la de la ficha (la del layout `horizontal`): vestibular hacia fuera y mesial hacia la línea media.
|
|
305
|
+
|
|
306
|
+
`show-surface-letters` dibuja además las letras sobre los diagramas del propio odontograma.
|
|
307
|
+
|
|
308
|
+
### Registrar hallazgos por superficie (opción recomendada)
|
|
309
|
+
|
|
310
|
+
La forma recomendada combina el odontograma con el panel de la pieza (`ToothInspector`). Un clic en una superficie del gráfico selecciona la pieza y marca esa superficie en el panel; desde el panel se elige el hallazgo y su estado y se añade. Así se trabaja sobre el gráfico sin taparlo y se ve a la vez todo lo registrado en la pieza.
|
|
311
|
+
|
|
312
|
+
```vue
|
|
313
|
+
<script setup lang="ts">
|
|
314
|
+
import { computed, ref } from 'vue'
|
|
315
|
+
import {
|
|
316
|
+
addFinding,
|
|
317
|
+
removeSurfaceFinding,
|
|
318
|
+
Odontogram,
|
|
319
|
+
ToothInspector,
|
|
320
|
+
type OdontogramFinding,
|
|
321
|
+
type OdontogramSurfaces,
|
|
322
|
+
type ToothSurface,
|
|
323
|
+
} from '@kmanueldc/vue-odontogram'
|
|
324
|
+
|
|
325
|
+
const findings = ref<OdontogramFinding[]>([])
|
|
326
|
+
const selectedTeeth = ref<string[]>([])
|
|
327
|
+
const surfaces = ref<OdontogramSurfaces>({})
|
|
328
|
+
const toothId = computed(() => selectedTeeth.value[0])
|
|
329
|
+
|
|
330
|
+
// Un clic en una superficie selecciona su pieza; solo esa pieza conserva superficies elegidas.
|
|
331
|
+
function onSurfaceClick(tooth: { id: string }, _surface: ToothSurface, next: OdontogramSurfaces) {
|
|
332
|
+
selectedTeeth.value = [tooth.id]
|
|
333
|
+
surfaces.value = next[tooth.id] ? { [tooth.id]: next[tooth.id]! } : {}
|
|
334
|
+
}
|
|
335
|
+
</script>
|
|
336
|
+
|
|
337
|
+
<template>
|
|
338
|
+
<Odontogram
|
|
339
|
+
v-model="selectedTeeth"
|
|
340
|
+
v-model:surfaces="surfaces"
|
|
341
|
+
:findings="findings"
|
|
342
|
+
single-select
|
|
343
|
+
show-surfaces
|
|
344
|
+
@surface-click="onSurfaceClick"
|
|
345
|
+
/>
|
|
346
|
+
<ToothInspector
|
|
347
|
+
v-if="toothId"
|
|
348
|
+
:tooth-id="toothId"
|
|
349
|
+
:findings="findings"
|
|
350
|
+
:selected-surfaces="surfaces[toothId] ?? []"
|
|
351
|
+
@update:selected-surfaces="(chosen) => (surfaces = chosen.length ? { [toothId]: chosen } : {})"
|
|
352
|
+
@add-finding="(input) => (findings = addFinding(findings, input))"
|
|
353
|
+
@remove-finding="(removal) => (findings = removeSurfaceFinding(findings, removal))"
|
|
354
|
+
/>
|
|
355
|
+
</template>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
- **Registrar** caries en oclusal y distal de 36: clic en O y en D del gráfico, y "Add" en el panel.
|
|
359
|
+
- **Ver lo registrado:** el panel muestra todos los hallazgos de la pieza. Al pasar el cursor por una pieza, el tooltip resume sus hallazgos por superficie (`M Mesial: Caries…`), y al pasar por una superficie, los de esa superficie.
|
|
360
|
+
- **Alternativas:** el [menú de superficie](#menú-de-superficie) registra sin salir del gráfico, pero lo tapa y muestra una superficie a la vez. El panel también se puede usar solo, eligiendo las superficies en su propio diagrama.
|
|
361
|
+
- **Reglas clínicas:** la librería no decide qué se puede registrar; `addFinding` y `removeSurfaceFinding` solo actualizan la lista, y la aplicación valida y guarda.
|
|
362
|
+
|
|
363
|
+
### Menú de superficie
|
|
364
|
+
|
|
365
|
+
Con el slot `surface-menu`, un clic (o `Enter`/`Espacio`) sobre una superficie abre un menú flotante junto a ella en lugar de alternar la selección. La librería solo lo coloca y lo cierra; el contenido y el registro de hallazgos son de la aplicación:
|
|
366
|
+
|
|
367
|
+
```vue
|
|
368
|
+
<Odontogram :findings="findings" show-surfaces>
|
|
369
|
+
<template #surface-menu="{ toothId, surface, surfaceName, record, close }">
|
|
370
|
+
<strong>{{ toothId }} · {{ surfaceName }}</strong>
|
|
371
|
+
<button
|
|
372
|
+
v-for="entry in record.surfaces[surface]"
|
|
373
|
+
:key="entry.index"
|
|
374
|
+
@click="findings = removeSurfaceFinding(findings, { index: entry.index, toothId, surface })"
|
|
375
|
+
>
|
|
376
|
+
Quitar {{ entry.definition?.name }}
|
|
377
|
+
</button>
|
|
378
|
+
<button @click="findings = addSurfaceFinding(findings, { code: 'caries', toothId, surfaces: [surface] })">
|
|
379
|
+
Añadir caries
|
|
380
|
+
</button>
|
|
381
|
+
<button @click="close">Cerrar</button>
|
|
382
|
+
</template>
|
|
383
|
+
</Odontogram>
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
| Prop del slot | Descripción |
|
|
387
|
+
| --- | --- |
|
|
388
|
+
| `toothId`, `tooth` | Pieza (ID FDI y definición). |
|
|
389
|
+
| `surface`, `surfaceName` | Superficie y su nombre clínico en la pieza. |
|
|
390
|
+
| `record` | `ToothRecord` de la pieza; se actualiza cuando cambian los `findings`. |
|
|
391
|
+
| `close` | Cierra el menú y devuelve el foco a la superficie. |
|
|
392
|
+
|
|
393
|
+
El menú es un `dialog` accesible, se coloca debajo de la superficie (o encima si no cabe), enfoca su primer control y se cierra también con `Esc` o con un clic fuera. `surface-click` se sigue emitiendo. No se abre en gráficos `disabled` ni en piezas `missing` o `extracted`.
|
|
394
|
+
|
|
395
|
+
### Panel de la pieza
|
|
396
|
+
|
|
397
|
+
`ToothInspector` muestra todo lo registrado en una pieza y permite añadir y quitar hallazgos. No guarda nada: emite eventos y la aplicación decide:
|
|
398
|
+
|
|
399
|
+
```vue
|
|
400
|
+
<script setup lang="ts">
|
|
401
|
+
import { addFinding, removeSurfaceFinding, Odontogram, ToothInspector } from '@kmanueldc/vue-odontogram'
|
|
402
|
+
|
|
403
|
+
const selectedTeeth = ref<string[]>(['36'])
|
|
404
|
+
const findings = ref<OdontogramFinding[]>([])
|
|
405
|
+
</script>
|
|
406
|
+
|
|
407
|
+
<template>
|
|
408
|
+
<Odontogram v-model="selectedTeeth" :findings="findings" single-select show-surfaces />
|
|
409
|
+
<ToothInspector
|
|
410
|
+
v-if="selectedTeeth.length"
|
|
411
|
+
:tooth-id="selectedTeeth[0]"
|
|
412
|
+
:findings="findings"
|
|
413
|
+
@add-finding="(input) => (findings = addFinding(findings, input))"
|
|
414
|
+
@remove-finding="(removal) => (findings = removeSurfaceFinding(findings, removal))"
|
|
415
|
+
/>
|
|
416
|
+
</template>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
- **Cabecera:** pieza, tipo y estado (`toothStates`).
|
|
420
|
+
- **Diagrama:** el de la guía de superficies, sin la lista de texto. Un clic en una superficie la elige para el siguiente hallazgo.
|
|
421
|
+
- **Listas:** hallazgos por superficie y de la pieza completa, con su estado y un botón para quitarlos. Los tramos y los hallazgos entre dos piezas se muestran, pero se quitan desde sus propias piezas.
|
|
422
|
+
- **Formulario:** hallazgos del catálogo sobre superficies o en la pieza completa, con su estado.
|
|
423
|
+
|
|
424
|
+
Props: `toothId`, `findings`, `findingCatalog`, `toothStates`, `labels` (textos en `labels.inspector`), `notation`, `shape`, `disabled` (solo lectura) y `selectedSurfaces` (con `v-model:selected-surfaces`, para elegir las superficies desde el gráfico; ver la [opción recomendada](#registrar-hallazgos-por-superficie-opción-recomendada)).
|
|
425
|
+
|
|
426
|
+
### Registro por pieza
|
|
427
|
+
|
|
428
|
+
Para mostrar o editar lo registrado en una pieza (por ejemplo, desde un panel propio), la librería ofrece funciones puras sobre `findings`. No mutan la lista y no contienen reglas clínicas:
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { addSurfaceFinding, getToothRecord, removeSurfaceFinding } from '@kmanueldc/vue-odontogram'
|
|
432
|
+
|
|
433
|
+
const record = getToothRecord('36', findings.value)
|
|
434
|
+
record.surfaces.occlusal // hallazgos en la oclusal: [{ index, finding, definition, scope }]
|
|
435
|
+
record.tooth // pieza completa, entre dos piezas, tramos que la cubren
|
|
436
|
+
|
|
437
|
+
findings.value = addSurfaceFinding(findings.value, { code: 'caries', toothId: '36', surfaces: ['distal'] })
|
|
438
|
+
findings.value = removeSurfaceFinding(findings.value, { index: record.surfaces.occlusal[0].index, toothId: '36', surface: 'occlusal' })
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
- `addSurfaceFinding` fusiona las superficies en un hallazgo igual (mismo código, estado, tono y color) de esa misma pieza; si no existe, lo añade.
|
|
442
|
+
- `removeSurfaceFinding` quita una superficie, o todo el hallazgo de la pieza si no se indica `surface`. Divide los hallazgos compartidos con otras piezas.
|
|
443
|
+
|
|
444
|
+
Cuando varios rellenos (`fill`) caen en la misma superficie, se dibujan como franjas iguales, en el orden de la lista. Los contornos (`outline`) van siempre encima de los rellenos.
|
|
445
|
+
|
|
446
|
+
`toggleSurface(surfaces, toothId, surface)` aplica el mismo cambio fuera del componente y `getSurfaceName(surface, toothId)` devuelve el nombre clínico (`'incisal'`, `'palatal'`…).
|
|
447
|
+
|
|
448
|
+
## Hallazgos
|
|
449
|
+
|
|
450
|
+
`findings` registra hallazgos y tratamientos (incluidas las prótesis). Cada uno indica un código del catálogo, las piezas FDI y, si corresponde, las superficies y su estado. La librería solo dibuja: qué se puede planificar, cuándo un tratamiento queda realizado o qué color usar son reglas de la aplicación.
|
|
451
|
+
|
|
452
|
+
```vue
|
|
453
|
+
<Odontogram
|
|
454
|
+
show-surfaces
|
|
455
|
+
:findings="[
|
|
456
|
+
{ code: 'caries', teeth: ['26'], surfaces: ['occlusal', 'distal'] },
|
|
457
|
+
{ code: 'restoration', teeth: ['36'], surfaces: ['occlusal'], status: 'planned' },
|
|
458
|
+
{ code: 'extraction', teeth: ['48'], status: 'done' },
|
|
459
|
+
{ code: 'crown', teeth: ['14'], color: '#7c3aed' },
|
|
460
|
+
{ code: 'fracture', teeth: ['11'] },
|
|
461
|
+
{ code: 'crown', teeth: ['21'] },
|
|
462
|
+
{ code: 'diastema', teeth: ['11', '21'] },
|
|
463
|
+
{ code: 'migrated', teeth: ['24'], direction: 'distal' },
|
|
464
|
+
{ code: 'mobility', teeth: ['33'], label: 'M2' },
|
|
465
|
+
{ code: 'fixed-prosthesis', teeth: ['45', '47'] },
|
|
466
|
+
]"
|
|
467
|
+
show-labels
|
|
468
|
+
/>
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
| Campo | Descripción |
|
|
472
|
+
| --- | --- |
|
|
473
|
+
| `code` | Código del catálogo, p. ej. `fracture`. |
|
|
474
|
+
| `teeth` | IDs FDI. Los hallazgos de superficie y de pieza dibujan un símbolo por pieza; los de dos piezas (`diastema`, `transposition`) usan exactamente dos; los de tramo (prótesis, aparatos) cubren desde la primera hasta la última pieza de la misma arcada, incluso cruzando la línea media. |
|
|
475
|
+
| `surfaces` | Superficies (`ToothSurface[]`) de los hallazgos de superficie (`fill`, `outline`); sin indicar, todas. Los demás hallazgos lo ignoran. |
|
|
476
|
+
| `status` | `'existing'` (por defecto: presente en boca), `'planned'` (por hacer) o `'done'` (realizado). Los planificados se dibujan con trazo discontinuo y relleno más claro. |
|
|
477
|
+
| `tone` | `'good'` (azul) o `'bad'` (rojo). Por defecto: rojo si está `planned`, azul si está `done` y, si es `existing`, el del catálogo. |
|
|
478
|
+
| `color` | Cualquier color CSS; reemplaza a `tone`. |
|
|
479
|
+
| `label` | Reemplaza la sigla de los hallazgos de texto, p. ej. `M2` o `PC`. |
|
|
480
|
+
| `direction` | `'mesial'` o `'distal'` para la migración. |
|
|
481
|
+
|
|
482
|
+
Los hallazgos de superficie se dibujan sobre el [diagrama de superficies](#superficies), así que necesitan `show-surfaces`; sin él se omiten con un aviso en consola. El resto de símbolos se dibujan con los anchors, así que se adaptan a los cuatro layouts: las flechas oclusales apuntan a la otra arcada, las mesiales siguen el arco hacia la línea media y las siglas se ubican del lado vestibular (los números van del lado lingual). Los hallazgos no cambian la selección; se añaden al nombre accesible de la pieza, al tooltip (`Findings: …`, y `findings` en el slot) y, con `show-labels`, a la leyenda con su ícono. El texto incluye las superficies y el estado cuando no es `existing`, p. ej. `Restauración definitiva (Oclusal, Planned)`; los nombres de estado se traducen con `labels.findingStatuses`. Los códigos desconocidos o las piezas inválidas se omiten con un aviso en consola.
|
|
483
|
+
|
|
484
|
+
### Catálogo NTS Perú
|
|
485
|
+
|
|
486
|
+
`ntsPeruFindingCatalog` es el catálogo por defecto. Se basa en la Norma Técnica de Salud para el uso del odontograma del MINSA (NTS N.° 150-MINSA/2019/DGIESP) y cubre hallazgos de superficie, de pieza completa, siglas, entre dos piezas y de tramo. Los sellantes y las siglas de material de las restauraciones (AM, R, IV…) aún no están incluidos. Como la vista es oclusal y no tiene raíces, los hallazgos radiculares se muestran con su sigla.
|
|
487
|
+
|
|
488
|
+
> **Verificar antes de uso clínico:** los códigos, colores y siglas se transcribieron para desarrollo y deben contrastarse con el documento oficial vigente.
|
|
489
|
+
|
|
490
|
+
| Código | Nombre | Símbolo | Color |
|
|
491
|
+
| --- | --- | --- | --- |
|
|
492
|
+
| `caries` | Lesión de caries dental | Relleno de las superficies | Rojo |
|
|
493
|
+
| `restoration` | Restauración definitiva | Relleno de las superficies | Azul |
|
|
494
|
+
| `temporary-restoration` | Restauración temporal | Contorno de las superficies | Rojo |
|
|
495
|
+
| `extraction` | Extracción | Aspa sobre la pieza | Rojo (azul con `status: 'done'`) |
|
|
496
|
+
| `fracture` | Fractura | Línea sobre la pieza | Rojo |
|
|
497
|
+
| `crown` / `temporary-crown` | Corona definitiva / temporal | Circunferencia | Azul / rojo |
|
|
498
|
+
| `extruded` / `intruded` | Diente extruido / intruido | Flecha hacia / desde la otra arcada | Azul |
|
|
499
|
+
| `rotated` | Giroversión | Flecha curva | Azul |
|
|
500
|
+
| `migrated` | Migración | Flecha mesial o distal | Azul |
|
|
501
|
+
| `erupting` | Pieza dentaria en erupción | Zigzag con flecha | Azul |
|
|
502
|
+
| `supernumerary` | Supernumerario | `S` en circunferencia | Azul |
|
|
503
|
+
| `fusion` | Fusión | Dos circunferencias | Azul |
|
|
504
|
+
| `peg` | Diente en clavija | Triángulo | Azul |
|
|
505
|
+
| `implant` | Implante dental | `IMP` | Azul |
|
|
506
|
+
| `root-remnant` | Remanente radicular | `RR` | Rojo |
|
|
507
|
+
| `mobility` | Movilidad | `M1` (`label`: `M2`, `M3`…) | Rojo |
|
|
508
|
+
| `discolored` | Diente discrómico | `DIS` | Rojo |
|
|
509
|
+
| `ectopic` | Diente ectópico | `E` | Rojo |
|
|
510
|
+
| `impacted` / `semi-impacted` | Impactación / semi-impactación | `I` / `SI` | Rojo |
|
|
511
|
+
| `macrodontia` / `microdontia` | Macrodoncia / microdoncia | `MAC` / `MIC` | Azul |
|
|
512
|
+
| `worn` | Superficie desgastada | `DES` | Rojo |
|
|
513
|
+
| `pulp-treatment` | Tratamiento pulpar | `TC` (`label`: `PC`, `PP`) | Azul |
|
|
514
|
+
| `enamel-defect` | Defecto de desarrollo del esmalte | `HP` (`label`: `HM`, `O`, `FL`…) | Rojo |
|
|
515
|
+
| `diastema` | Diastema | `)(` entre dos piezas | Azul |
|
|
516
|
+
| `transposition` | Transposición | Flechas cruzadas entre dos piezas | Azul |
|
|
517
|
+
| `fixed-prosthesis` | Prótesis fija | Línea con topes en los extremos | Azul |
|
|
518
|
+
| `removable-prosthesis` / `complete-prosthesis` | Prótesis removible / total | Dos líneas paralelas | Azul |
|
|
519
|
+
| `fixed-orthodontic-appliance` | Aparato ortodóntico fijo | Línea con brackets | Azul |
|
|
520
|
+
| `removable-orthodontic-appliance` | Aparato ortodóntico removible | Línea en zigzag | Azul |
|
|
521
|
+
| `edentulous` | Edéntulo total | Línea sobre las piezas | Azul |
|
|
522
|
+
|
|
523
|
+
### Catálogos propios
|
|
524
|
+
|
|
525
|
+
Un catálogo es el registro de formas de dibujo: asocia cada código con un nombre, un símbolo genérico y un color por defecto (`tone`). Se puede extender o reemplazar el catálogo NTS, o crear uno para otra norma:
|
|
526
|
+
|
|
527
|
+
```ts
|
|
528
|
+
import { ntsPeruFindingCatalog, type FindingCatalog } from '@kmanueldc/vue-odontogram'
|
|
529
|
+
|
|
530
|
+
const catalog: FindingCatalog = {
|
|
531
|
+
...ntsPeruFindingCatalog,
|
|
532
|
+
sensitivity: { name: 'Sensibilidad', symbol: { kind: 'text', text: 'SEN' }, tone: 'bad' },
|
|
533
|
+
sealant: { name: 'Sellante', symbol: { kind: 'fill' }, tone: 'good' },
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Símbolos disponibles (`FindingSymbol['kind']`): de superficie `fill` (relleno) y `outline` (contorno); de pieza `line`, `cross`, `circle` (p. ej. corona), `double-circle`, `triangle`, `arrow` (con `direction`: `occlusal`, `apical`, `mesial`, `distal` o `auto`), `curved-arrow`, `zigzag`, `text` y `encircled-text` (con `text`); entre dos piezas `diastema` y `transposition`; de tramo `bridge`, `double-line`, `brackets`, `zigzag-line` y `center-line`.
|
|
538
|
+
|
|
539
|
+
## Teclado
|
|
540
|
+
|
|
541
|
+
El odontograma tiene una sola parada de tabulación: la última pieza enfocada o, si no hay, la primera seleccionada visible o la primera pieza renderizada.
|
|
542
|
+
|
|
543
|
+
| Tecla | Acción |
|
|
544
|
+
| --- | --- |
|
|
545
|
+
| `←` / `→` | Pieza anterior o siguiente de la misma arcada, en el orden en que se ve en pantalla. |
|
|
546
|
+
| `↑` / `↓` | Pieza más cercana de la arcada dibujada arriba o abajo. |
|
|
547
|
+
| `Inicio` / `Fin` | Primera o última pieza de la arcada. |
|
|
548
|
+
| `Enter` / `Espacio` | Selecciona o deselecciona la pieza. |
|
|
549
|
+
|
|
550
|
+
Moverse con el teclado muestra el tooltip de la pieza enfocada y no cambia la selección.
|
|
551
|
+
|
|
552
|
+
## Tooltip personalizado
|
|
553
|
+
|
|
554
|
+
El slot `tooltip` reemplaza el contenido por defecto y recibe `tooth`, `selected`, `condition`, `state`, `findings`, `number` (el número en la notación elegida) y `surfaceSummary` (los hallazgos de cada superficie; entonces `findings` solo lista los de la pieza completa). En el tooltip de una superficie recibe además `surface` y `surfaceName`, y `selected` y `findings` se refieren a esa superficie:
|
|
555
|
+
|
|
556
|
+
```vue
|
|
557
|
+
<Odontogram v-model="selectedTeeth" :conditions="conditions">
|
|
558
|
+
<template #tooltip="{ tooth, selected, condition }">
|
|
559
|
+
<strong>Pieza {{ tooth.id }}</strong>
|
|
560
|
+
<div v-if="condition">{{ condition.label }}</div>
|
|
561
|
+
<div>{{ selected ? 'Seleccionada' : 'Sin seleccionar' }}</div>
|
|
562
|
+
</template>
|
|
563
|
+
</Odontogram>
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## Overlay y anchors
|
|
567
|
+
|
|
568
|
+
Cada pieza tiene un *anchor*: su caja (`box`) y centro (`center`) en las coordenadas del `viewBox` del layout, con todos los transforms ya aplicados. El slot `overlay` se dibuja dentro del SVG, encima de las piezas, y recibe `anchors` (indexados por ID FDI), `viewBox`, `dentition` y `layout`. Sirve para números, símbolos o marcas sin leer el DOM:
|
|
569
|
+
|
|
570
|
+
```vue
|
|
571
|
+
<Odontogram v-model="selectedTeeth">
|
|
572
|
+
<template #overlay="{ anchors }">
|
|
573
|
+
<text
|
|
574
|
+
v-for="anchor in anchors"
|
|
575
|
+
:key="anchor.toothId"
|
|
576
|
+
:x="anchor.center.x"
|
|
577
|
+
:y="anchor.box.y + anchor.box.height + 12"
|
|
578
|
+
text-anchor="middle"
|
|
579
|
+
font-size="10"
|
|
580
|
+
>
|
|
581
|
+
{{ anchor.toothId }}
|
|
582
|
+
</text>
|
|
583
|
+
</template>
|
|
584
|
+
</Odontogram>
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
El grupo del overlay usa `pointer-events: none` para no bloquear los clics sobre las piezas; un elemento propio puede reactivarlos con `pointer-events: auto`.
|
|
588
|
+
|
|
589
|
+
Fuera de Vue (por ejemplo, para exportar o validar posiciones) se puede usar `getToothAnchors(dentition, layout)`, que devuelve la lista en orden de renderizado, y `getLayoutViewBox(dentition, layout)`. El cálculo es exacto para curvas y arcos SVG, no requiere DOM y coincide con el `getBBox()` del navegador.
|
|
590
|
+
|
|
591
|
+
## Textos e idioma
|
|
592
|
+
|
|
593
|
+
Los textos por defecto están en inglés. La prop `labels` acepta un objeto parcial; lo que no se indique conserva el valor de `defaultOdontogramLabels`:
|
|
594
|
+
|
|
595
|
+
```vue
|
|
596
|
+
<Odontogram
|
|
597
|
+
:labels="{
|
|
598
|
+
odontogram: 'Odontograma',
|
|
599
|
+
chartTitles: { permanent: 'odontograma permanente', primary: 'odontograma temporal' },
|
|
600
|
+
tooth: 'Pieza',
|
|
601
|
+
type: 'Tipo',
|
|
602
|
+
selected: 'Seleccionada',
|
|
603
|
+
yes: 'Sí',
|
|
604
|
+
no: 'No',
|
|
605
|
+
condition: 'Condición',
|
|
606
|
+
legend: 'Leyenda de condiciones',
|
|
607
|
+
toothTypes: { 'Central Incisor': 'Incisivo central', 'Primary Second Molar': 'Segundo molar temporal' },
|
|
608
|
+
state: 'Estado',
|
|
609
|
+
states: { missing: 'Ausente', extracted: 'Extraída', implant: 'Implante', unerupted: 'No erupcionada' },
|
|
610
|
+
findings: 'Hallazgos',
|
|
611
|
+
surfaces: 'Superficies dentales',
|
|
612
|
+
surfaceNames: { vestibular: 'Vestibular', mesial: 'Mesial', occlusal: 'Oclusal', incisal: 'Incisal', distal: 'Distal', lingual: 'Lingual', palatal: 'Palatino' },
|
|
613
|
+
surfaceDescriptions: { mesial: 'Superficie más cercana a la línea media de la boca.' },
|
|
614
|
+
surfaceGuide: 'Guía de superficies',
|
|
615
|
+
}"
|
|
616
|
+
/>
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
`tooth` también forma el nombre accesible de cada pieza (`Pieza 11`). Los tipos sin traducción en `toothTypes` se muestran con su nombre original.
|
|
620
|
+
|
|
621
|
+
## Tema
|
|
622
|
+
|
|
623
|
+
Los colores se ajustan con variables CSS sobre `.odontogram` o un ancestro:
|
|
624
|
+
|
|
625
|
+
| Variable | Valor por defecto | Uso |
|
|
626
|
+
| --- | --- | --- |
|
|
627
|
+
| `--odontogram-stroke-color` | `#8a98be` | Contorno de las piezas. |
|
|
628
|
+
| `--odontogram-selected-color` | `#c6ccf8` | Relleno de piezas seleccionadas y en hover. |
|
|
629
|
+
| `--odontogram-selected-stroke-color` | `#b8c0cc` | Contorno de piezas seleccionadas. |
|
|
630
|
+
| `--odontogram-focus-outline-color` | `rgb(184 167 232 / 70%)` | Contorno de foco del teclado. |
|
|
631
|
+
| `--odontogram-number-color` | `#64748b` | Números de `showNumbers`. |
|
|
632
|
+
| `--odontogram-number-selected-color` | `#4338ca` | Números de piezas seleccionadas (en negrita). |
|
|
633
|
+
| `--odontogram-absent-opacity` | `0.55` | Opacidad de piezas `missing` y `extracted`. |
|
|
634
|
+
| `--odontogram-unerupted-opacity` | `0.45` | Opacidad de piezas `unerupted`. |
|
|
635
|
+
| `--odontogram-extracted-color` | `#dc2626` | X de las piezas extraídas. |
|
|
636
|
+
| `--odontogram-implant-color` | `#0f766e` | Contorno del implante. |
|
|
637
|
+
| `--odontogram-implant-fill` | `#ccfbf1` | Relleno del implante. |
|
|
638
|
+
| `--odontogram-finding-good-color` | `#1d4ed8` | Hallazgos en buen estado o tratamiento realizado (azul). |
|
|
639
|
+
| `--odontogram-finding-bad-color` | `#dc2626` | Hallazgos en mal estado o pendientes (rojo). |
|
|
640
|
+
| `--odontogram-finding-planned-dasharray` | proporcional al trazo | Trazo discontinuo de los hallazgos `planned`. |
|
|
641
|
+
| `--odontogram-finding-planned-fill-opacity` | `0.45` | Opacidad del relleno de los hallazgos `planned`. |
|
|
642
|
+
| `--odontogram-surface-fill` | `#fff` | Relleno de las superficies sin seleccionar. |
|
|
643
|
+
| `--odontogram-surface-stroke-color` | `--odontogram-stroke-color` | Contorno del diagrama de superficies. |
|
|
644
|
+
| `--odontogram-surface-hover-color` | `--odontogram-selected-color` | Superficie bajo el cursor. |
|
|
645
|
+
| `--odontogram-surface-selected-color` | `#6366f1` | Superficies seleccionadas. |
|
|
646
|
+
| `--odontogram-surface-focus-color` | `#4338ca` | Contorno de la superficie enfocada con el teclado y resaltado de la guía. |
|
|
647
|
+
| `--odontogram-surface-letter-color` | `#334155` | Letras de las superficies (gráfico y guía). |
|
|
648
|
+
| `--odontogram-surface-guide-active-bg` | `#eef2ff` | Fondo de la superficie resaltada en la lista de la guía. |
|
|
649
|
+
| `--odontogram-surface-menu-bg` / `-fg` / `-border` | `#fff` / `#1e293b` / `#cbd5e1` | Fondo, texto y borde del menú de superficie. |
|
|
650
|
+
| `--odontogram-tooltip-bg` | `rgba(0, 0, 0, 0.85)` | Fondo del tooltip. |
|
|
651
|
+
| `--odontogram-tooltip-fg` | `#fff` | Texto del tooltip. |
|
|
652
|
+
|
|
653
|
+
```css
|
|
654
|
+
.mi-odontograma {
|
|
655
|
+
--odontogram-stroke-color: #475569;
|
|
656
|
+
--odontogram-selected-color: #bae6fd;
|
|
657
|
+
}
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
## Utilidades y tipos exportados
|
|
661
|
+
|
|
662
|
+
| Exportación | Descripción |
|
|
663
|
+
| --- | --- |
|
|
664
|
+
| `buildToothId(dentition, quadrant, position)` | Construye un ID FDI, p. ej. `buildToothId('primary', 8, 5) === '85'`. Los IDs son siempre FDI. |
|
|
665
|
+
| `formatToothNumber(toothId, notation, style?)` | Número de una pieza FDI en otra notación: `formatToothNumber('11', 'Universal') === '8'`, `formatToothNumber('55', 'Palmer', 'text') === 'URE'`. |
|
|
666
|
+
| `getPalmerQuadrant(toothId)` | Cuadrante Palmer de una pieza FDI. |
|
|
667
|
+
| `getQuadrant(dentition, arch, side)` | Cuadrante FDI de una arcada y lado del paciente. |
|
|
668
|
+
| `defaultOdontogramLabels` | Textos por defecto de la prop `labels`. |
|
|
669
|
+
| `getToothAnchors(dentition, layout)` | Caja y centro de cada pieza en coordenadas del `viewBox`. |
|
|
670
|
+
| `getLayoutViewBox(dentition, layout)` | `viewBox` de la composición como `{ x, y, width, height }`. |
|
|
671
|
+
| `toothStates` | Lista de todos los `ToothState`, en orden. |
|
|
672
|
+
| `ntsPeruFindingCatalog` | Catálogo de hallazgos basado en la NTS del MINSA (Perú). |
|
|
673
|
+
| `toothSurfaces` | Lista de todas las `ToothSurface`, en orden. |
|
|
674
|
+
| `addFinding(findings, input, catalog?)` | Añade un hallazgo a una pieza: fusiona superficies en los de superficie o añade uno de pieza completa. |
|
|
675
|
+
| `getToothType(toothId)` | Tipo de una pieza FDI, p. ej. `'First Molar'` para `16`. |
|
|
676
|
+
| `getToothRecord(toothId, findings, catalog?)` | Hallazgos de una pieza agrupados por superficie y de pieza completa. |
|
|
677
|
+
| `addSurfaceFinding(findings, input)` / `removeSurfaceFinding(findings, removal)` | Añaden o quitan un hallazgo de superficie y devuelven una lista `findings` nueva. |
|
|
678
|
+
| `toggleSurface(surfaces, toothId, surface)` | Devuelve un modelo de superficies nuevo con una superficie alternada. |
|
|
679
|
+
| `getSurfaceName(surface, toothId)` | Nombre clínico de una superficie en una pieza (`incisal`, `palatal`…). |
|
|
680
|
+
| `getFindingScope(symbol)` | `'surface'`, `'tooth'`, `'between'` o `'span'`: dónde se dibuja un símbolo. |
|
|
681
|
+
| `resolveFindingTone(finding, definition)` | Color por defecto (`'good'` o `'bad'`) de un hallazgo. |
|
|
682
|
+
| `findingStatuses` | Lista de todos los `FindingStatus`, en orden. |
|
|
683
|
+
| Tipos | `OdontogramFinding`, `FindingCatalog`, `FindingDefinition`, `FindingSymbol`, `FindingSymbolKind`, `FindingStatus`, `FindingDirection`, `FindingScope`, `NtsPeruFindingCode`, `ToothState`, `OdontogramToothStates`, `ToothAnchor`, `Box`, `Point`, `OdontogramHalf`, `Dentition`, `ToothNotation`, `OdontogramLayout`, `OdontogramCondition`, `OdontogramLabels`, `OdontogramLabelsInput`, `ToothDefinition`, `ToothShape`, `ToothType`, `ToothVisualCondition`, `ToothCondition`, `TooltipPlacement`, `DentalArch`, `DentalSide`. |
|
|
684
|
+
|
|
685
|
+
## Licencia y procedencia de los SVG
|
|
686
|
+
|
|
687
|
+
El código propio de `@kmanueldc/vue-odontogram` se distribuye bajo licencia MIT; consulta [LICENSE](LICENSE).
|
|
688
|
+
|
|
689
|
+
Las geometrías SVG permanentes de `src/data/permanent.ts` y `src/data/permanent-horizontal.ts` se portaron de [biomathcode/react-odontogram](https://github.com/biomathcode/react-odontogram), también bajo MIT © biomathcode. La atribución y la copia de esa licencia se conservan en [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
690
|
+
|
|
691
|
+
Los dos datasets pediátricos de cinco formas, `src/data/primary.ts` (Arch) y `src/data/primary-horizontal.ts` (Horizontal), son paths simplificados propios creados para prototipado. Son **provisionales**, no tienen validación odontológica y no deben emplearse para diagnóstico, tratamiento ni como representación clínica definitiva. Consulta [la nota de aproximación Arch](docs/primary-svg-approximation.md), [la aproximación Horizontal](docs/primary-horizontal-svg-approximation.md), [la composición Horizontal](docs/primary-horizontal-layout.md) y [el registro de fuentes](docs/primary-svg-sources.md) antes de redistribuirlos o considerarlos para uso clínico.
|
|
692
|
+
|
|
693
|
+
## Dentición mixta
|
|
694
|
+
|
|
695
|
+
Disponible con `dentition="mixed"` y `teeth`. Ver [Mixta](#mixta) y el [diseño de dentición mixta](docs/mixed-dentition.md).
|
|
696
|
+
|
|
697
|
+
## Playground
|
|
698
|
+
|
|
699
|
+
Para validar visualmente ambos conjuntos durante el desarrollo:
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
npm install
|
|
703
|
+
npm run dev:playground
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
El playground permite alternar Permanent/Primary/Mixed (con un ejemplo de ocho años), selección, tooltip, leyendas y los layouts compatibles. Incluye el ejemplo primario `["51", "52", "65"]`. La opción **Anchors** dibuja la caja y el número FDI de cada pieza mediante el slot `overlay`; **Numbers**, **Arches**, **States** y **Findings** prueban `showNumbers`, `showHalf`, `toothStates` y `findings`. El estado inicial se puede fijar por URL, por ejemplo `?dentition=primary&layout=horizontal&numbers&states&findings&half=upper&anchors`.
|
|
707
|
+
|
|
708
|
+
## Desarrollo
|
|
709
|
+
|
|
710
|
+
```bash
|
|
711
|
+
npm run test
|
|
712
|
+
npm run build
|
|
713
|
+
npm run build:playground
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|