@alfadocs/ui-kit 0.69.0 → 0.70.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.
Files changed (261) hide show
  1. package/dist/_chunks/{agenda-card-BxSFkqgY.js → agenda-card-BQ-IKAru.js} +2 -2
  2. package/dist/_chunks/{agenda-tray-g0kg7HwB.js → agenda-tray-CGXRk58j.js} +2 -2
  3. package/dist/_chunks/{ai-consent-banner-CXlsNX1c.js → ai-consent-banner-Be-h9mRI.js} +3 -3
  4. package/dist/_chunks/ai-tools-rail-B5NEghsp.js +511 -0
  5. package/dist/_chunks/{alert-_mUKLmwA.js → alert-CHYZ96tR.js} +150 -96
  6. package/dist/_chunks/{anamnesis-card-DRmE24OQ.js → anamnesis-card-DvYCa16e.js} +2 -2
  7. package/dist/_chunks/anatomy-scheme-CJB6dI6p.js +2445 -0
  8. package/dist/_chunks/annotation-marker-qt5R9WZX.js +120 -0
  9. package/dist/_chunks/{antenatal-schedule-timeline-35ebkcZT.js → antenatal-schedule-timeline-CwXrQRm1.js} +2 -2
  10. package/dist/_chunks/appointment-card-C06aZqA7.js +310 -0
  11. package/dist/_chunks/appointment-timeline-BJM0S_Fg.js +386 -0
  12. package/dist/_chunks/appointment-tray-DRRw5ROi.js +193 -0
  13. package/dist/_chunks/{audio-recorder-DYXXnGug.js → audio-recorder-Cpdk5qpQ.js} +2 -2
  14. package/dist/_chunks/{badge-CqGsX32l.js → badge-DCOqV9mI.js} +32 -27
  15. package/dist/_chunks/{bishop-score-PJI3AXzA.js → bishop-score-DnYWtZa_.js} +2 -2
  16. package/dist/_chunks/{bmi-calculator-BZtIJ53x.js → bmi-calculator-zjeY4E7J.js} +2 -2
  17. package/dist/_chunks/{booking-C3VqFReX.js → booking-DUBI0oqt.js} +4 -4
  18. package/dist/_chunks/{care-plan-card-CvFGXa2z.js → care-plan-card-C5sTfY9G.js} +5 -5
  19. package/dist/_chunks/{care-plan-entry-card-C3E_gClk.js → care-plan-entry-card-CXnxGCWA.js} +5 -5
  20. package/dist/_chunks/care-plan-header-BUwqDTtz.js +206 -0
  21. package/dist/_chunks/clinical-note-card-BUvNMNGL.js +436 -0
  22. package/dist/_chunks/{contact-profile-card-Dramqa9C.js → contact-profile-card-DDPwRFiP.js} +2 -2
  23. package/dist/_chunks/control-room-rail-Y8ryLYsP.js +229 -0
  24. package/dist/_chunks/{cycle-calculator-DmRGJNaT.js → cycle-calculator-CCmPwcBl.js} +2 -2
  25. package/dist/_chunks/{dependent-selector-CG_FOHya.js → dependent-selector-DUV4thxX.js} +2 -2
  26. package/dist/_chunks/{document-scanner-CTubA0-N.js → document-scanner-C_AxLooF.js} +3 -3
  27. package/dist/_chunks/{due-date-calculator-BTmsIQqD.js → due-date-calculator-Brdj-euS.js} +3 -3
  28. package/dist/_chunks/editable-currency-cell-renderer-C9twtALM.js +328 -0
  29. package/dist/_chunks/email-input-DJ7EXklP.js +397 -0
  30. package/dist/_chunks/{entity-card-COhmqHly.js → entity-card-9_62gY7l.js} +38 -20
  31. package/dist/_chunks/entity-summary-BxRjFh_4.js +138 -0
  32. package/dist/_chunks/{fetal-weight-CRz7KE2D.js → fetal-weight-DNCkyeVo.js} +2 -2
  33. package/dist/_chunks/field-value-NXYczdpO.js +415 -0
  34. package/dist/_chunks/{file-upload-5ScQd4fE.js → file-upload-DwZcAK8D.js} +2 -1
  35. package/dist/_chunks/{freemium-paywall-DZ2mBS3w.js → freemium-paywall-WYlNO7yT.js} +2 -2
  36. package/dist/_chunks/{gestational-age-calculator-BleUdhbI.js → gestational-age-calculator-CF2ISaYQ.js} +3 -3
  37. package/dist/_chunks/hash-CysBBS_N.js +17 -0
  38. package/dist/_chunks/{hcg-doubling-CnjDXX6U.js → hcg-doubling-C7bmuaU3.js} +2 -2
  39. package/dist/_chunks/{actions-cell-renderer-DrcaxB0w.js → link-cell-renderer-CTXqtXV-.js} +715 -592
  40. package/dist/_chunks/lock-CKOIn0IK.js +15 -0
  41. package/dist/_chunks/{marketplace-app-shell-6T9W4Knl.js → marketplace-app-shell-Skhfp6vK.js} +3 -3
  42. package/dist/_chunks/notes-panel-ay8_lPrA.js +158 -0
  43. package/dist/_chunks/{notification-card-BiESdm8q.js → notification-card-D2jiKSJJ.js} +27 -23
  44. package/dist/_chunks/{notification-tray-Btb9oQeZ.js → notification-tray-AEun6DN2.js} +2 -2
  45. package/dist/_chunks/{operator-hero-CP2Nhupm.js → operator-hero-CR0Rqh4-.js} +3 -3
  46. package/dist/_chunks/patient-details-Dlhqb5ig.js +675 -0
  47. package/dist/_chunks/{patient-search-CBC_ySF6.js → patient-search-Be6cLrHR.js} +2 -2
  48. package/dist/_chunks/patient-summary-card-WySCMwwA.js +437 -0
  49. package/dist/_chunks/patient-table-CHxf3Oqk.js +1110 -0
  50. package/dist/_chunks/{payment-form-DvjwYVIT.js → payment-form-CxqIXqw7.js} +2 -2
  51. package/dist/_chunks/{payment-request-card-DioWKBUq.js → payment-request-card-BcZJwu9z.js} +125 -136
  52. package/dist/_chunks/{pdf-viewer-D6BPfW2D.js → pdf-viewer-QfebdLOd.js} +192 -214
  53. package/dist/_chunks/{periodontal-chart-card-BuDEMbHE.js → periodontal-chart-card-hRRJY1NN.js} +2 -2
  54. package/dist/_chunks/{practice-results-KrTHqZua.js → practice-results-C6qDfxos.js} +3 -3
  55. package/dist/_chunks/{pregnancy-dating-DORUAOHB.js → pregnancy-dating-CRVWswD-.js} +3 -3
  56. package/dist/_chunks/{pregnancy-weight-gain-DVz4rr7-.js → pregnancy-weight-gain-BUNpTsH-.js} +2 -2
  57. package/dist/_chunks/radiograph-panel.agent-CAX-C3g3.js +558 -0
  58. package/dist/_chunks/{rich-text-editor-BsV7zUdg.js → rich-text-editor-DlCqPixb.js} +410 -394
  59. package/dist/_chunks/{sign-document-B4DeRhTe.js → sign-document-By6hMOra.js} +2 -2
  60. package/dist/_chunks/{stepper-accordion-Dki6r9ZE.js → stepper-accordion-DC-H-8v4.js} +38 -48
  61. package/dist/_chunks/tab-bar-Bv9nGNdO.js +262 -0
  62. package/dist/_chunks/tooth-scheme-BhQoPNBD.js +2131 -0
  63. package/dist/_chunks/{transaction-chip-DK84XCBU.js → transaction-chip-CscoQbxF.js} +88 -61
  64. package/dist/_chunks/use-clamp-overflow-DQE2kwZ9.js +20 -0
  65. package/dist/_chunks/use-overflow-collapse-BIOzKbni.js +32 -0
  66. package/dist/_chunks/use-persistent-state-nZwZAnE9.js +24 -0
  67. package/dist/_chunks/{warning-stack-BsgaEbL8.js → warning-stack--sTrrBDA.js} +86 -101
  68. package/dist/_chunks/{workflow-map-Bdam9pGp.js → workflow-map-Dy8mLCqF.js} +3 -3
  69. package/dist/_chunks/zoom-out-CgVtf2Wx.js +29 -0
  70. package/dist/agent/index.js +5 -4
  71. package/dist/agent/types.d.ts +19 -2
  72. package/dist/agent-catalog.json +1253 -86
  73. package/dist/agent-i18n/en.json +108 -6
  74. package/dist/components/_shared/entity-card/entity-card.d.ts +6 -0
  75. package/dist/components/_shared/entity-card/index.d.ts +1 -1
  76. package/dist/components/_shared/field-value.d.ts +21 -0
  77. package/dist/components/_shared/field-visibility-cog.d.ts +20 -0
  78. package/dist/components/_shared/field-visibility.d.ts +36 -0
  79. package/dist/components/_shared/patient-fields.d.ts +119 -0
  80. package/dist/components/agenda-card/index.js +1 -1
  81. package/dist/components/agenda-tray/index.js +1 -1
  82. package/dist/components/ai-consent-banner/index.js +1 -1
  83. package/dist/components/ai-tools-rail/ai-tools-rail.d.ts +75 -0
  84. package/dist/components/ai-tools-rail/index.js +1 -1
  85. package/dist/components/alert/alert.d.ts +5 -0
  86. package/dist/components/alert/index.js +1 -1
  87. package/dist/components/anamnesis-card/index.js +1 -1
  88. package/dist/components/anatomy-scheme/anatomy-face-paths.d.ts +15 -0
  89. package/dist/components/anatomy-scheme/anatomy-muscle-paths.d.ts +20 -0
  90. package/dist/components/anatomy-scheme/anatomy-scheme-data.d.ts +121 -0
  91. package/dist/components/anatomy-scheme/anatomy-scheme.agent.d.ts +6 -0
  92. package/dist/components/anatomy-scheme/anatomy-scheme.d.ts +69 -0
  93. package/dist/components/anatomy-scheme/index.d.ts +6 -0
  94. package/dist/components/anatomy-scheme/index.js +17 -0
  95. package/dist/components/annotation-marker/annotation-marker.d.ts +33 -0
  96. package/dist/components/annotation-marker/index.d.ts +3 -0
  97. package/dist/components/annotation-marker/index.js +7 -0
  98. package/dist/components/appointment-card/appointment-card.d.ts +25 -1
  99. package/dist/components/appointment-card/index.js +6 -5
  100. package/dist/components/appointment-timeline/appointment-timeline.agent.d.ts +4 -0
  101. package/dist/components/appointment-timeline/appointment-timeline.d.ts +66 -0
  102. package/dist/components/appointment-timeline/index.d.ts +4 -0
  103. package/dist/components/appointment-timeline/index.js +6 -0
  104. package/dist/components/audio-recorder/index.js +1 -1
  105. package/dist/components/badge/badge.d.ts +6 -2
  106. package/dist/components/badge/index.js +1 -1
  107. package/dist/components/bishop-score/index.js +1 -1
  108. package/dist/components/bmi-calculator/index.js +1 -1
  109. package/dist/components/booking/index.js +1 -1
  110. package/dist/components/care-plan-card/index.js +1 -1
  111. package/dist/components/care-plan-entry-card/index.js +1 -1
  112. package/dist/components/care-plan-header/care-plan-header.agent.d.ts +4 -0
  113. package/dist/components/care-plan-header/care-plan-header.d.ts +100 -0
  114. package/dist/components/care-plan-header/index.d.ts +4 -0
  115. package/dist/components/care-plan-header/index.js +6 -0
  116. package/dist/components/clinical-note-card/clinical-note-card.d.ts +21 -1
  117. package/dist/components/clinical-note-card/index.js +1 -1
  118. package/dist/components/contact-profile-card/index.js +1 -1
  119. package/dist/components/control-room-rail/control-room-context.d.ts +53 -0
  120. package/dist/components/control-room-rail/control-room-rail.d.ts +35 -0
  121. package/dist/components/control-room-rail/index.d.ts +5 -0
  122. package/dist/components/control-room-rail/index.js +9 -0
  123. package/dist/components/cycle-calculator/index.js +1 -1
  124. package/dist/components/data-table/cell-renderers/actions-cell-renderer.d.ts +18 -0
  125. package/dist/components/data-table/index.d.ts +1 -1
  126. package/dist/components/data-table/index.js +32 -31
  127. package/dist/components/dependent-selector/index.js +1 -1
  128. package/dist/components/document-scanner/index.js +1 -1
  129. package/dist/components/due-date-calculator/index.js +2 -2
  130. package/dist/components/email-input/index.js +1 -1
  131. package/dist/components/entity-summary/entity-summary.d.ts +43 -0
  132. package/dist/components/entity-summary/index.d.ts +3 -0
  133. package/dist/components/entity-summary/index.js +5 -0
  134. package/dist/components/fetal-weight/index.js +1 -1
  135. package/dist/components/file-upload/index.js +1 -1
  136. package/dist/components/freemium-paywall/index.js +1 -1
  137. package/dist/components/gestational-age-calculator/index.js +1 -1
  138. package/dist/components/hcg-doubling/index.js +1 -1
  139. package/dist/components/index.d.ts +9 -0
  140. package/dist/components/notes-panel/index.d.ts +3 -0
  141. package/dist/components/notes-panel/index.js +5 -0
  142. package/dist/components/notes-panel/notes-panel.d.ts +64 -0
  143. package/dist/components/notification-card/index.js +1 -1
  144. package/dist/components/notification-tray/index.js +1 -1
  145. package/dist/components/operator-hero/index.js +1 -1
  146. package/dist/components/patient-details/index.d.ts +5 -0
  147. package/dist/components/patient-details/index.js +6 -0
  148. package/dist/components/patient-details/patient-details.agent.d.ts +4 -0
  149. package/dist/components/patient-details/patient-details.d.ts +96 -0
  150. package/dist/components/patient-search/index.js +1 -1
  151. package/dist/components/patient-summary-card/index.js +1 -1
  152. package/dist/components/patient-summary-card/patient-summary-card.d.ts +40 -1
  153. package/dist/components/patient-table/columns.d.ts +69 -40
  154. package/dist/components/patient-table/index.d.ts +2 -6
  155. package/dist/components/patient-table/index.js +8 -9
  156. package/dist/components/patient-table/patient-table.d.ts +38 -4
  157. package/dist/components/patient-table/types.d.ts +52 -2
  158. package/dist/components/patient-table/use-responsive-columns.d.ts +8 -6
  159. package/dist/components/payment-card/index.js +1 -1
  160. package/dist/components/payment-form/index.js +1 -1
  161. package/dist/components/pdf-viewer/index.js +1 -1
  162. package/dist/components/periodontal-chart-card/index.js +1 -1
  163. package/dist/components/practice-results/index.js +1 -1
  164. package/dist/components/pregnancy-dating/index.js +1 -1
  165. package/dist/components/pregnancy-weight-gain/index.js +1 -1
  166. package/dist/components/radiograph-panel/index.d.ts +4 -0
  167. package/dist/components/radiograph-panel/index.js +7 -0
  168. package/dist/components/radiograph-panel/radiograph-panel.agent.d.ts +13 -0
  169. package/dist/components/radiograph-panel/radiograph-panel.d.ts +36 -0
  170. package/dist/components/rich-text-editor/index.js +1 -1
  171. package/dist/components/sidebar/index.js +1 -1
  172. package/dist/components/sign-document/index.js +1 -1
  173. package/dist/components/stepper-accordion/index.js +1 -1
  174. package/dist/components/tab-bar/index.js +1 -1
  175. package/dist/components/tab-bar/tab-bar.d.ts +18 -1
  176. package/dist/components/tooth-scheme/index.d.ts +2 -2
  177. package/dist/components/tooth-scheme/index.js +30 -23
  178. package/dist/components/tooth-scheme/tooth-data.d.ts +112 -1
  179. package/dist/components/tooth-scheme/tooth-scheme.agent.d.ts +2 -2
  180. package/dist/components/tooth-scheme/tooth-scheme.d.ts +75 -11
  181. package/dist/components/transaction-chip/index.js +1 -1
  182. package/dist/components/transaction-chip/transaction-chip.d.ts +2 -2
  183. package/dist/components/warning-stack/index.js +1 -1
  184. package/dist/components/warning-stack/warning-stack.d.ts +10 -7
  185. package/dist/components/workflow/index.js +1 -1
  186. package/dist/hooks/index.d.ts +1 -0
  187. package/dist/hooks/index.js +24 -22
  188. package/dist/hooks/use-clamp-overflow.d.ts +19 -0
  189. package/dist/hooks/use-overflow-collapse.d.ts +46 -0
  190. package/dist/hooks/use-persistent-state.d.ts +7 -1
  191. package/dist/hooks/use-scroll-overflow.d.ts +36 -0
  192. package/dist/i18n/locales/ar.d.ts +308 -24
  193. package/dist/i18n/locales/ar.js +322 -27
  194. package/dist/i18n/locales/de.d.ts +308 -24
  195. package/dist/i18n/locales/de.js +322 -27
  196. package/dist/i18n/locales/el.d.ts +308 -24
  197. package/dist/i18n/locales/el.js +322 -27
  198. package/dist/i18n/locales/en.d.ts +309 -32
  199. package/dist/i18n/locales/en.js +323 -35
  200. package/dist/i18n/locales/es.d.ts +308 -24
  201. package/dist/i18n/locales/es.js +322 -27
  202. package/dist/i18n/locales/fr.d.ts +308 -24
  203. package/dist/i18n/locales/fr.js +322 -27
  204. package/dist/i18n/locales/hi.d.ts +308 -24
  205. package/dist/i18n/locales/hi.js +322 -27
  206. package/dist/i18n/locales/it.d.ts +308 -24
  207. package/dist/i18n/locales/it.js +322 -27
  208. package/dist/i18n/locales/ja.d.ts +308 -24
  209. package/dist/i18n/locales/ja.js +322 -27
  210. package/dist/i18n/locales/nl.d.ts +308 -24
  211. package/dist/i18n/locales/nl.js +322 -27
  212. package/dist/i18n/locales/pl.d.ts +308 -24
  213. package/dist/i18n/locales/pl.js +322 -27
  214. package/dist/i18n/locales/pt.d.ts +308 -24
  215. package/dist/i18n/locales/pt.js +322 -27
  216. package/dist/i18n/locales/ro.d.ts +308 -24
  217. package/dist/i18n/locales/ro.js +322 -27
  218. package/dist/i18n/locales/ru.d.ts +308 -24
  219. package/dist/i18n/locales/ru.js +322 -27
  220. package/dist/i18n/locales/sq.d.ts +308 -24
  221. package/dist/i18n/locales/sq.js +322 -27
  222. package/dist/i18n/locales/sv.d.ts +308 -24
  223. package/dist/i18n/locales/sv.js +322 -27
  224. package/dist/i18n/locales/tr.d.ts +308 -24
  225. package/dist/i18n/locales/tr.js +322 -27
  226. package/dist/i18n/locales/zh.d.ts +308 -24
  227. package/dist/i18n/locales/zh.js +322 -27
  228. package/dist/index.js +672 -623
  229. package/dist/locales/ar.json +311 -27
  230. package/dist/locales/de.json +311 -27
  231. package/dist/locales/el.json +311 -27
  232. package/dist/locales/en.json +311 -27
  233. package/dist/locales/es.json +311 -27
  234. package/dist/locales/fr.json +311 -27
  235. package/dist/locales/hi.json +311 -27
  236. package/dist/locales/it.json +311 -27
  237. package/dist/locales/ja.json +311 -27
  238. package/dist/locales/nl.json +311 -27
  239. package/dist/locales/pl.json +311 -27
  240. package/dist/locales/pt.json +311 -27
  241. package/dist/locales/ro.json +311 -27
  242. package/dist/locales/ru.json +311 -27
  243. package/dist/locales/sq.json +311 -27
  244. package/dist/locales/sv.json +311 -27
  245. package/dist/locales/tr.json +311 -27
  246. package/dist/locales/zh.json +311 -27
  247. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  248. package/dist/tokens.css +1 -1
  249. package/package.json +37 -1
  250. package/dist/_chunks/ai-tools-rail-BA_sqy1A.js +0 -373
  251. package/dist/_chunks/appointment-tray-CZtvtaH-.js +0 -431
  252. package/dist/_chunks/clinical-note-card-DqQYf_D4.js +0 -333
  253. package/dist/_chunks/editable-currency-cell-renderer-kgqp_mIw.js +0 -448
  254. package/dist/_chunks/email-input-B_Y55f5G.js +0 -396
  255. package/dist/_chunks/patient-summary-card-B836_fDB.js +0 -435
  256. package/dist/_chunks/patient-table-CDuosVru.js +0 -889
  257. package/dist/_chunks/tab-bar-B1ovILzh.js +0 -105
  258. package/dist/_chunks/tooth-scheme-yBr53cvv.js +0 -1330
  259. package/dist/_chunks/use-persistent-state-i23OWy6G.js +0 -24
  260. package/dist/components/patient-table/cell-renderers/contact-cell.d.ts +0 -45
  261. package/dist/components/patient-table/cell-renderers/patient-identity-cell.d.ts +0 -26
@@ -1,1330 +0,0 @@
1
- import { jsx as u, jsxs as j } from "react/jsx-runtime";
2
- import { forwardRef as Lt, useState as q, useRef as le, useEffect as re, useMemo as Le, useCallback as R, useImperativeHandle as It } from "react";
3
- import * as B from "@radix-ui/react-tooltip";
4
- import { c as V } from "./index-D2ZczOXr.js";
5
- import { useTranslation as ot } from "react-i18next";
6
- import { u as Ct } from "./registry-DvAUVLHh.js";
7
- import { I as At } from "./icon-button-LqoiKcUN.js";
8
- import { P as Ie } from "./popover-B2qCDhJC.js";
9
- import { S as Ot } from "./select-DMLG44F5.js";
10
- import { S as kt } from "./switch-OILsBLWo.js";
11
- import { S as Dt } from "./settings-ca2Yi9R8.js";
12
- const G = {
13
- type: "string",
14
- description: "FDI tooth id, e.g. '11'–'48' permanent, '51'–'85' primary."
15
- }, ue = {
16
- enum: [
17
- "caries",
18
- "filled",
19
- "crowned",
20
- "temporaryCrown",
21
- "bridge",
22
- "missing",
23
- "implant",
24
- "implantExtraction",
25
- "stub",
26
- "destroyed",
27
- "rootCanal"
28
- ]
29
- }, Mt = {
30
- enum: ["mesial", "distal", "occlusal", "buccal", "lingual"]
31
- }, _t = {
32
- id: "tooth-scheme",
33
- // pick — focus/select a tooth (`focus_tooth`, transient, not persisted);
34
- // set_value / edit_inline — `set_finding` records a finding and marks the
35
- // affected surfaces (set-surface), `remove_finding` clears one;
36
- // view_change — the side/plan projection + dentition are view props.
37
- capabilities: ["pick", "set_value", "edit_inline", "view_change"],
38
- state: {
39
- chart: {
40
- type: "object",
41
- descriptionKey: "ui.agent.toothScheme.state.chart",
42
- description: "Current dental chart — findings (and marked surfaces) keyed by FDI id.",
43
- read: (t) => t.getChart()
44
- },
45
- chartedTeeth: {
46
- type: "string[]",
47
- descriptionKey: "ui.agent.toothScheme.state.chartedTeeth",
48
- description: "FDI ids of every tooth carrying at least one finding.",
49
- read: (t) => Object.keys(t.getChart())
50
- }
51
- },
52
- actions: {
53
- focus_tooth: {
54
- safety: "read",
55
- argsType: "{ id: FdiId }",
56
- argsSchema: {
57
- type: "object",
58
- properties: { id: G },
59
- required: ["id"]
60
- },
61
- idempotent: !0,
62
- descriptionKey: "ui.agent.toothScheme.actions.focusTooth",
63
- description: "Move focus to a specific tooth by FDI id.",
64
- invoke: (t, n) => {
65
- t.focusTooth(n.id);
66
- }
67
- },
68
- get_tooth: {
69
- safety: "read",
70
- argsType: "{ id: FdiId }",
71
- argsSchema: {
72
- type: "object",
73
- properties: { id: G },
74
- required: ["id"]
75
- },
76
- returns: "ToothCondition[]",
77
- returnsSchema: { type: "array", items: ue },
78
- idempotent: !0,
79
- descriptionKey: "ui.agent.toothScheme.actions.getTooth",
80
- description: "Read the findings recorded on one tooth (FDI id).",
81
- invoke: (t, n) => t.getTooth(n.id)
82
- },
83
- teeth_with: {
84
- safety: "read",
85
- argsType: "{ condition: ToothCondition }",
86
- argsSchema: {
87
- type: "object",
88
- properties: { condition: ue },
89
- required: ["condition"]
90
- },
91
- returns: "FdiId[]",
92
- returnsSchema: { type: "array", items: G },
93
- idempotent: !0,
94
- descriptionKey: "ui.agent.toothScheme.actions.teethWith",
95
- description: "List the FDI ids of every tooth carrying a given finding (e.g. all teeth with caries).",
96
- invoke: (t, n) => t.teethWith(n.condition)
97
- },
98
- set_finding: {
99
- safety: "write",
100
- argsType: "{ id: FdiId; condition: ToothCondition; surfaces?: Surface[] }",
101
- argsSchema: {
102
- type: "object",
103
- properties: {
104
- id: G,
105
- condition: ue,
106
- surfaces: { type: "array", items: Mt }
107
- },
108
- required: ["id", "condition"]
109
- },
110
- idempotent: !0,
111
- descriptionKey: "ui.agent.toothScheme.actions.setFinding",
112
- description: "Record a finding on a tooth (crown, implant, root canal, caries, …). Optionally mark the affected surfaces for a surface finding.",
113
- invoke: (t, n) => {
114
- t.setFinding(n.id, n.condition, n.surfaces);
115
- }
116
- },
117
- remove_finding: {
118
- safety: "write",
119
- argsType: "{ id: FdiId; condition: ToothCondition }",
120
- argsSchema: {
121
- type: "object",
122
- properties: { id: G, condition: ue },
123
- required: ["id", "condition"]
124
- },
125
- idempotent: !0,
126
- descriptionKey: "ui.agent.toothScheme.actions.removeFinding",
127
- description: "Remove a single finding from a tooth.",
128
- invoke: (t, n) => {
129
- t.removeFinding(n.id, n.condition);
130
- }
131
- },
132
- clear_tooth: {
133
- safety: "destructive",
134
- argsType: "{ id: FdiId }",
135
- argsSchema: {
136
- type: "object",
137
- properties: { id: G },
138
- required: ["id"]
139
- },
140
- idempotent: !0,
141
- descriptionKey: "ui.agent.toothScheme.actions.clearTooth",
142
- description: "Clear every finding from a tooth.",
143
- invoke: (t, n) => {
144
- t.clearTooth(n.id);
145
- }
146
- }
147
- },
148
- domHooks: {
149
- root: { attr: "data-component", value: "tooth-scheme" },
150
- instanceId: {
151
- attr: "data-component-id",
152
- sourceProp: "id",
153
- description: "Sourced from the id prop."
154
- },
155
- item: {
156
- attr: "data-fdi",
157
- description: "Each rendered tooth `<g>` carries its FDI id as `data-fdi`. The `data-projection` attribute on the root exposes the side/plan view."
158
- }
159
- }
160
- }, De = [
161
- // upper
162
- "18",
163
- "17",
164
- "16",
165
- "15",
166
- "14",
167
- "13",
168
- "12",
169
- "11",
170
- "21",
171
- "22",
172
- "23",
173
- "24",
174
- "25",
175
- "26",
176
- "27",
177
- "28",
178
- // lower
179
- "48",
180
- "47",
181
- "46",
182
- "45",
183
- "44",
184
- "43",
185
- "42",
186
- "41",
187
- "31",
188
- "32",
189
- "33",
190
- "34",
191
- "35",
192
- "36",
193
- "37",
194
- "38"
195
- ], Me = [
196
- // upper
197
- "55",
198
- "54",
199
- "53",
200
- "52",
201
- "51",
202
- "61",
203
- "62",
204
- "63",
205
- "64",
206
- "65",
207
- // lower
208
- "85",
209
- "84",
210
- "83",
211
- "82",
212
- "81",
213
- "71",
214
- "72",
215
- "73",
216
- "74",
217
- "75"
218
- ];
219
- function Et(t) {
220
- return t <= 2 ? "incisor" : t === 3 ? "canine" : t <= 5 ? "premolar" : "molar";
221
- }
222
- function Nt(t) {
223
- return t <= 2 ? "incisor" : t === 3 ? "canine" : "molar";
224
- }
225
- function Rt(t, n) {
226
- const i = (t - 1) % 4 + 1;
227
- return `${i === 1 ? "UR" : i === 2 ? "UL" : i === 3 ? "LL" : "LR"}${n}`;
228
- }
229
- function jt(t, n) {
230
- switch (t) {
231
- case 1:
232
- return String(1 + (8 - n));
233
- case 2:
234
- return String(8 + n);
235
- case 3:
236
- return String(17 + (8 - n));
237
- case 4:
238
- return String(24 + n);
239
- default:
240
- return "";
241
- }
242
- }
243
- function Ft(t, n) {
244
- const i = "ABCDEFGHIJKLMNOPQRST";
245
- let r = -1;
246
- switch (t) {
247
- case 5:
248
- r = 0 + (5 - n);
249
- break;
250
- case 6:
251
- r = 5 + (n - 1);
252
- break;
253
- case 7:
254
- r = 10 + (5 - n);
255
- break;
256
- case 8:
257
- r = 15 + (n - 1);
258
- break;
259
- default:
260
- r = -1;
261
- }
262
- return r >= 0 ? i[r] : "";
263
- }
264
- function qt(t) {
265
- const n = Number(t[0]), i = Number(t[1]), r = n >= 5, l = r ? Nt(i) : Et(i), m = n === 1 || n === 2 || n === 5 || n === 6 ? "upper" : "lower", $ = n === 1 || n === 4 || n === 5 || n === 8 ? "right" : "left", v = r ? Ft(n, i) : jt(n, i), f = Rt(n, i);
266
- return {
267
- fdi: t,
268
- universal: v,
269
- palmer: f,
270
- quadrant: n,
271
- positionInQuadrant: i,
272
- anatomy: l,
273
- arch: m,
274
- side: $,
275
- dentition: r ? "primary" : "permanent"
276
- };
277
- }
278
- const F = [
279
- ...De,
280
- ...Me
281
- ].reduce((t, n) => (t[n] = qt(n), t), {}), Ht = Object.fromEntries(
282
- Object.entries(F).map(([t, n]) => [t, n.universal])
283
- ), Wt = Object.fromEntries(
284
- Object.entries(F).map(([t, n]) => [t, n.palmer])
285
- );
286
- function Ee(t) {
287
- return t.dentition !== "primary" ? t.fdi : `${t.quadrant - 4}${t.positionInQuadrant}`;
288
- }
289
- const Ut = 0.72, gn = {
290
- caries: "--destructive",
291
- filled: "--info",
292
- crowned: "--warning",
293
- temporaryCrown: "--warning",
294
- bridge: "--primary",
295
- missing: "--muted-foreground",
296
- implant: "--accent",
297
- implantExtraction: "--accent",
298
- stub: "--muted-foreground",
299
- destroyed: "--destructive",
300
- rootCanal: "--primary"
301
- }, he = {
302
- caries: "var(--destructive)",
303
- filled: "var(--info)",
304
- crowned: "var(--warning)",
305
- temporaryCrown: "var(--warning)",
306
- bridge: "var(--primary)",
307
- missing: "var(--muted-foreground)",
308
- implant: "var(--accent)",
309
- implantExtraction: "var(--accent)",
310
- stub: "var(--muted-foreground)",
311
- destroyed: "var(--destructive)",
312
- rootCanal: "var(--primary)"
313
- }, _e = {
314
- crowned: { folder: "crown", resolve: "per-fdi" },
315
- temporaryCrown: { folder: "temporaryCrown", resolve: "per-fdi" },
316
- bridge: { folder: "replacement", resolve: "per-fdi" },
317
- destroyed: { folder: "destroyed", resolve: "per-fdi" },
318
- implant: { folder: "implant", resolve: "general" },
319
- implantExtraction: { folder: "implantExtraction", resolve: "general" },
320
- stub: { folder: "stub", resolve: "general" },
321
- rootCanal: { folder: "rootTreatment", resolve: "rct" }
322
- };
323
- function it(t, n, i) {
324
- const r = t.arch === "upper" ? "top" : "bottom", l = `${n}/side/${i.folder}/${r}`;
325
- if (i.resolve === "general") return `${l}/general.webp`;
326
- const m = Ee(t);
327
- return i.resolve === "rct" ? `${l}/${m}/full.webp` : `${l}/${m}.webp`;
328
- }
329
- const Kt = {
330
- mesial: "mesial",
331
- distal: "distal",
332
- occlusal: "occlusal",
333
- buccal: "vestibular",
334
- lingual: "oral"
335
- }, Pt = {
336
- caries: "caries",
337
- filled: "filling"
338
- };
339
- function Zt(t, n, i, r) {
340
- const l = t.arch === "upper" ? "top" : "bottom";
341
- return `${n}/plan/${i}/${l}/${Ee(t)}-${Kt[r]}.webp`;
342
- }
343
- function Ce(t) {
344
- return t.anatomy === "molar" || t.anatomy === "premolar" ? ["top", "bottom", "left", "right", "center"] : ["top", "bottom", "left", "right"];
345
- }
346
- function Xe(t, n) {
347
- if (n === "center") return "occlusal";
348
- if (n === "top") return t.arch === "upper" ? "buccal" : "lingual";
349
- if (n === "bottom") return t.arch === "upper" ? "lingual" : "buccal";
350
- const i = t.quadrant <= 4 ? t.quadrant : t.quadrant - 4, r = i === 1 || i === 4;
351
- return n === "left" ? r ? "distal" : "mesial" : r ? "mesial" : "distal";
352
- }
353
- const Je = (t) => Math.round(t * 100) / 100;
354
- function Vt(t, n, i) {
355
- const { x: r, y: l, w: m, h: $ } = n, v = r + m, f = l + $, a = (A, M) => `${Je(A)} ${Je(M)}`;
356
- if (!i) {
357
- const A = r + m / 2, M = l + $ / 2;
358
- switch (t) {
359
- case "top":
360
- return `M ${a(r, l)} L ${a(v, l)} L ${a(A, M)} Z`;
361
- case "bottom":
362
- return `M ${a(r, f)} L ${a(v, f)} L ${a(A, M)} Z`;
363
- case "left":
364
- return `M ${a(r, l)} L ${a(A, M)} L ${a(r, f)} Z`;
365
- case "right":
366
- return `M ${a(v, l)} L ${a(A, M)} L ${a(v, f)} Z`;
367
- default:
368
- return "";
369
- }
370
- }
371
- const y = r + m * 0.3, T = l + $ * 0.3, C = r + m * 0.7, g = l + $ * 0.7;
372
- switch (t) {
373
- case "center":
374
- return `M ${a(y, T)} L ${a(C, T)} L ${a(C, g)} L ${a(y, g)} Z`;
375
- case "top":
376
- return `M ${a(r, l)} L ${a(v, l)} L ${a(C, T)} L ${a(y, T)} Z`;
377
- case "bottom":
378
- return `M ${a(r, f)} L ${a(v, f)} L ${a(C, g)} L ${a(y, g)} Z`;
379
- case "left":
380
- return `M ${a(r, l)} L ${a(y, T)} L ${a(y, g)} L ${a(r, f)} Z`;
381
- case "right":
382
- return `M ${a(v, l)} L ${a(C, T)} L ${a(C, g)} L ${a(v, f)} Z`;
383
- default:
384
- return "";
385
- }
386
- }
387
- const Ae = 5, et = 40, K = 4, H = 36, st = 62;
388
- function at(t, n, i = "default", r = "side") {
389
- const l = t.arch === "upper" ? "top" : "bottom";
390
- return `${n}/${r}/${i}/${l}/${Ee(t)}.webp`;
391
- }
392
- function Yt(t, n = st) {
393
- const i = t === "primary" ? Me : t === "mixed" ? [...De, ...Me] : De, r = [], l = [];
394
- for (const g of i)
395
- F[g].arch === "upper" ? r.push(g) : l.push(g);
396
- const m = H + Ae, $ = Math.max(r.length, l.length), v = $ > 0 ? $ * m - Ae : 0;
397
- function f(g, A) {
398
- const M = g.length > 0 ? g.length * m - Ae : 0, me = (v - M) / 2;
399
- return g.map((d, pe) => {
400
- const oe = F[d];
401
- return {
402
- fdi: d,
403
- meta: oe,
404
- x: me + pe * m,
405
- y: A
406
- };
407
- });
408
- }
409
- const a = f(r, 0), y = f(l, n + et), T = v > 0 ? v : $ * m, C = n * 2 + et;
410
- return { teeth: [...a, ...y], width: T, height: C };
411
- }
412
- function tt(t, n) {
413
- switch (n) {
414
- case "universal":
415
- return Ht[t] ?? t;
416
- case "palmer":
417
- return Wt[t] ?? t;
418
- case "fdi":
419
- default:
420
- return t;
421
- }
422
- }
423
- function vn() {
424
- return {};
425
- }
426
- function nt(t) {
427
- const n = {};
428
- for (const [i, r] of Object.entries(t))
429
- !r || r.length === 0 || (n[i] = { conditions: r, surfaces: [] });
430
- return n;
431
- }
432
- const zt = V(
433
- [
434
- "ds:tooth-scheme-alfadocs",
435
- "ds:flex ds:flex-col",
436
- "ds:gap-[var(--spacing-sm)]",
437
- "ds:bg-[var(--background)] ds:text-[var(--foreground)]",
438
- // Block-level flex column so the SVG's w-full can grow to fill the frame.
439
- // min-w-fit on the SVG floors it at natural size, so narrow frames scroll
440
- // here rather than shrinking the per-tooth hit target below the 44px floor.
441
- "ds:max-w-full ds:overflow-x-auto",
442
- // When the scroll container itself is the tab stop (display mode, see
443
- // scrollTabIndex) it needs a focus ring. Use an outline (not box-shadow):
444
- // forced-colors / high-contrast mode zeroes box-shadow, which would leave
445
- // HCM keyboard users with no visible focus. outline survives, and the
446
- // CanvasText fallback repaints it in the system palette.
447
- "ds:outline-none",
448
- "ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid",
449
- "ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]",
450
- "ds:forced-colors:focus-visible:outline-[CanvasText]"
451
- ].join(" ")
452
- ), Bt = V(
453
- [
454
- "ds:block",
455
- "ds:w-full ds:min-w-fit ds:h-auto",
456
- "ds:text-[var(--foreground)]"
457
- ].join(" ")
458
- ), Gt = V(
459
- [
460
- "ds:group ds:cursor-pointer",
461
- "ds:focus:outline-none",
462
- "ds:transition-[fill,stroke,opacity] ds:duration-[var(--animation-duration)]",
463
- "ds:motion-reduce:transition-none"
464
- ].join(" ")
465
- ), Qt = V(
466
- [
467
- "ds:flex ds:flex-wrap ds:items-center",
468
- "ds:gap-[var(--spacing-sm)]",
469
- "type-meta ds:text-[var(--muted-foreground)]"
470
- ].join(" ")
471
- ), Xt = V(
472
- ["ds:inline-flex ds:items-center", "ds:gap-[var(--spacing-xs)]"].join(" ")
473
- ), Jt = V(["ds:sr-only"].join(" ")), en = V(
474
- [
475
- "ds:cursor-pointer ds:outline-none",
476
- "ds:fill-transparent ds:stroke-transparent",
477
- "ds:transition-[fill] ds:duration-[var(--animation-duration)]",
478
- "ds:motion-reduce:transition-none",
479
- "ds:hover:fill-[color-mix(in_srgb,var(--accent)_18%,transparent)]",
480
- "ds:focus-visible:fill-[color-mix(in_srgb,var(--accent)_22%,transparent)]",
481
- "ds:focus-visible:stroke-[var(--ring)]",
482
- "ds:forced-colors:focus-visible:stroke-[CanvasText]"
483
- ].join(" ")
484
- );
485
- function Oe(t) {
486
- return t.value !== void 0;
487
- }
488
- function fe() {
489
- return { conditions: [], surfaces: [] };
490
- }
491
- function rt(t, n) {
492
- const i = t ?? [];
493
- return n ? i.includes(n) ? i.filter((r) => r !== n) : [...i, n] : i.length === 0 ? ["caries"] : [];
494
- }
495
- function tn(t, n, i) {
496
- var l;
497
- return i ? ((l = {
498
- top: { ArrowDown: "center" },
499
- bottom: { ArrowUp: "center" },
500
- left: { ArrowRight: "center" },
501
- right: { ArrowLeft: "center" },
502
- center: {
503
- ArrowUp: "top",
504
- ArrowDown: "bottom",
505
- ArrowLeft: "left",
506
- ArrowRight: "right"
507
- }
508
- }[t]) == null ? void 0 : l[n]) ?? t : n === "ArrowUp" ? "top" : n === "ArrowDown" ? "bottom" : n === "ArrowLeft" ? "left" : n === "ArrowRight" ? "right" : t;
509
- }
510
- const nn = [
511
- "caries",
512
- "filled",
513
- "crowned",
514
- "temporaryCrown",
515
- "bridge",
516
- "rootCanal",
517
- "implant",
518
- "implantExtraction",
519
- "stub",
520
- "destroyed",
521
- "missing"
522
- ];
523
- function rn({
524
- condition: t,
525
- assetBaseUrl: n
526
- }) {
527
- const i = F[16], r = _e[t], l = t === "missing", m = t === "caries" || t === "filled", $ = 36 * 0.9, v = 62 * 0.9, f = (36 - $) / 2, a = (62 - v) / 2;
528
- return /* @__PURE__ */ j(
529
- "svg",
530
- {
531
- width: "22",
532
- height: "38",
533
- viewBox: "0 0 36 62",
534
- "aria-hidden": "true",
535
- className: "ds:block ds:shrink-0",
536
- children: [
537
- /* @__PURE__ */ u(
538
- "image",
539
- {
540
- href: at(i, n),
541
- x: f,
542
- y: a,
543
- width: $,
544
- height: v,
545
- preserveAspectRatio: "xMidYMid meet",
546
- opacity: l ? 0.25 : 1
547
- }
548
- ),
549
- r ? /* @__PURE__ */ u(
550
- "image",
551
- {
552
- href: it(i, n, r),
553
- x: f,
554
- y: a,
555
- width: $,
556
- height: v,
557
- preserveAspectRatio: "xMidYMid meet"
558
- }
559
- ) : null,
560
- m ? /* @__PURE__ */ u(
561
- "rect",
562
- {
563
- x: 3,
564
- y: 2,
565
- width: 30,
566
- height: 58,
567
- fill: "none",
568
- stroke: he[t],
569
- strokeWidth: 2,
570
- strokeDasharray: t === "filled" ? "4 2" : void 0,
571
- rx: 6
572
- }
573
- ) : null,
574
- l ? /* @__PURE__ */ u(
575
- "path",
576
- {
577
- d: "M7 9 L29 53 M29 9 L7 53",
578
- stroke: he.missing,
579
- strokeWidth: 2,
580
- fill: "none"
581
- }
582
- ) : null
583
- ]
584
- }
585
- );
586
- }
587
- function on({ assetBaseUrl: t }) {
588
- const { t: n } = ot();
589
- return /* @__PURE__ */ j(
590
- "section",
591
- {
592
- "aria-label": n("toothScheme.legendLabel"),
593
- "data-testid": "tooth-scheme-legend",
594
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:rounded-[var(--radius-md)] ds:bg-[var(--card)] ds:border ds:border-[color:var(--card-border)] ds:p-[var(--spacing-sm)] ds:shadow-[var(--shadow-card)] ds:[.theme-accessible_&]:border-2",
595
- children: [
596
- /* @__PURE__ */ u("span", { className: "type-eyebrow ds:text-[color:var(--muted-foreground)]", children: n("toothScheme.legendLabel") }),
597
- /* @__PURE__ */ u("ul", { className: Qt(), children: nn.map((i) => /* @__PURE__ */ j(
598
- "li",
599
- {
600
- className: Xt(),
601
- "data-condition": i,
602
- "data-testid": `tooth-scheme-legend-item-${i}`,
603
- children: [
604
- /* @__PURE__ */ u(rn, { condition: i, assetBaseUrl: t }),
605
- /* @__PURE__ */ u("span", { children: n(`toothScheme.condition.${i}`) })
606
- ]
607
- },
608
- i
609
- )) })
610
- ]
611
- }
612
- );
613
- }
614
- function ke({
615
- label: t,
616
- value: n,
617
- options: i,
618
- onValueChange: r,
619
- container: l
620
- }) {
621
- return /* @__PURE__ */ j("div", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]", children: [
622
- /* @__PURE__ */ u(
623
- "span",
624
- {
625
- "aria-hidden": "true",
626
- className: "type-label ds:text-[color:var(--muted-foreground)]",
627
- children: t
628
- }
629
- ),
630
- /* @__PURE__ */ u(
631
- Ot,
632
- {
633
- size: "md",
634
- "aria-label": t,
635
- value: n,
636
- options: i,
637
- onValueChange: r,
638
- container: l
639
- }
640
- )
641
- ] });
642
- }
643
- const ct = Lt(
644
- ({
645
- id: t,
646
- dentition: n = "permanent",
647
- numbering: i = "fdi",
648
- mode: r = "interactive",
649
- projection: l = "side",
650
- value: m,
651
- defaultValue: $,
652
- onChange: v,
653
- onSelect: f,
654
- conditions: a,
655
- activeCondition: y,
656
- assetBaseUrl: T = "/toothscheme/teeth",
657
- legend: C = !1,
658
- controls: g = !1,
659
- ariaLabel: A,
660
- className: M
661
- }, me) => {
662
- const { t: d } = ot(), [pe, oe] = q(n), [dt, Ne] = q(i), [lt, Re] = q(l), [ut, je] = q(C), [ge, ft] = q(null), Q = g ? pe : n, X = g ? dt : i, Fe = g ? ut : C, ie = g ? lt : l, W = ie === "plan" ? "plan" : "side", qe = ie === "both", He = le(g);
663
- re(() => {
664
- g && !He.current && (oe(n), Ne(i), Re(l), je(C)), He.current = g;
665
- }, [g, n, i, l, C]);
666
- const [ht, We] = q(() => m !== void 0 ? m : $ !== void 0 ? $ : a ? nt(a) : {}), p = Oe({ value: m }) ? m : ht;
667
- re(() => {
668
- Oe({ value: m }) || a !== void 0 && We(nt(a));
669
- }, [a, m]);
670
- const _ = W === "plan" ? 44 : st, J = Le(
671
- () => Yt(Q, _),
672
- [Q, _]
673
- ), P = Le(() => J.teeth.map((e) => e.fdi), [J]), ve = P[0], [se, Y] = q(ve);
674
- re(() => {
675
- (!se || !P.includes(se)) && Y(ve);
676
- }, [ve, se, P]);
677
- const [mt, z] = q(""), be = le(null), O = R(
678
- (e) => {
679
- Oe({ value: m }) || We(e), v == null || v(e);
680
- },
681
- [v, m]
682
- ), E = R((e) => {
683
- const o = be.current;
684
- if (!o) return;
685
- const s = o.querySelector(`g[data-fdi="${e}"]`);
686
- s && (s.focus(), Y(e));
687
- }, []), N = W === "plan" && r === "interactive" && (y === "caries" || y === "filled"), [S, ee] = q(null);
688
- re(() => {
689
- (!N || S && !P.includes(S.fdi)) && ee(null);
690
- }, [N, S, P]);
691
- const Ue = R((e, o) => {
692
- var c;
693
- const s = (c = be.current) == null ? void 0 : c.querySelector(
694
- `path[data-fdi="${e}"][data-zone="${o}"]`
695
- );
696
- s == null || s.focus();
697
- }, []), ye = le(null);
698
- re(() => {
699
- S ? Ue(S.fdi, S.zone) : ye.current && E(ye.current.fdi), ye.current = S;
700
- }, [S, Ue, E]);
701
- const pt = R(
702
- (e, o) => {
703
- const s = p[e];
704
- return !!(s && s.surfaces.includes(o) && s.conditions.includes(y));
705
- },
706
- [p, y]
707
- ), Ke = R(
708
- (e, o) => {
709
- o && o.conditions.length > 0 ? z(
710
- d("toothScheme.selected", {
711
- id: e,
712
- conditions: o.conditions.map((s) => d(`toothScheme.condition.${s}`)).join(", ")
713
- })
714
- ) : z(d("toothScheme.deselected", { id: e }));
715
- },
716
- [d]
717
- ), we = R(
718
- (e, o) => {
719
- if (!N) return;
720
- const s = y, c = p[e] ?? fe(), x = c.surfaces.includes(o), L = c.conditions.includes(s);
721
- let b, w;
722
- x && L ? (b = c.surfaces.filter((Z) => Z !== o), w = b.length === 0 ? c.conditions.filter((Z) => Z !== s) : c.conditions) : (b = x ? c.surfaces : [...c.surfaces, o], w = L ? c.conditions : [...c.conditions, s]);
723
- const I = { ...p };
724
- w.length === 0 && b.length === 0 ? delete I[e] : I[e] = { ...c, conditions: w, surfaces: b }, O(I), Ke(e, I[e]), f == null || f(e);
725
- },
726
- [
727
- N,
728
- y,
729
- p,
730
- O,
731
- Ke,
732
- f
733
- ]
734
- ), xe = R((e) => {
735
- const o = F[e];
736
- o && (Y(e), ee({ fdi: e, zone: Ce(o)[0] }));
737
- }, []), gt = R(
738
- (e, o, s) => {
739
- const c = F[o];
740
- if (c)
741
- switch (e.key) {
742
- case "ArrowUp":
743
- case "ArrowDown":
744
- case "ArrowLeft":
745
- case "ArrowRight": {
746
- e.preventDefault(), e.stopPropagation();
747
- const x = Ce(c).includes("center"), L = tn(s, e.key, x);
748
- L !== s && ee({ fdi: o, zone: L });
749
- return;
750
- }
751
- case " ":
752
- case "Enter": {
753
- e.preventDefault(), e.stopPropagation(), we(o, Xe(c, s));
754
- return;
755
- }
756
- case "Escape": {
757
- e.preventDefault(), e.stopPropagation(), ee(null);
758
- return;
759
- }
760
- default:
761
- return;
762
- }
763
- },
764
- [we]
765
- ), vt = le(null), $e = Le(
766
- () => ({
767
- focusTooth: (e) => {
768
- E(e);
769
- },
770
- getChart: () => p,
771
- getTooth: (e) => {
772
- var o;
773
- return ((o = p[e]) == null ? void 0 : o.conditions) ?? [];
774
- },
775
- teethWith: (e) => Object.entries(p).filter(([, o]) => o.conditions.includes(e)).map(([o]) => o),
776
- setFinding: (e, o, s) => {
777
- const c = p[e] ?? fe();
778
- if (c.conditions.includes(o) && !s) return;
779
- const x = {
780
- ...p,
781
- [e]: {
782
- ...c,
783
- conditions: c.conditions.includes(o) ? c.conditions : [...c.conditions, o],
784
- surfaces: s ?? c.surfaces
785
- }
786
- };
787
- O(x);
788
- },
789
- removeFinding: (e, o) => {
790
- const s = p[e];
791
- if (!s || !s.conditions.includes(o)) return;
792
- const c = s.conditions.filter((L) => L !== o), x = { ...p };
793
- c.length === 0 ? delete x[e] : x[e] = { ...s, conditions: c }, O(x);
794
- },
795
- clearTooth: (e) => {
796
- if (!p[e]) return;
797
- const o = { ...p };
798
- delete o[e], O(o);
799
- }
800
- }),
801
- [p, O, E]
802
- );
803
- It(me, () => $e, [$e]), Ct(_t, $e, t);
804
- const bt = R(
805
- (e, o) => {
806
- var L;
807
- if (r !== "interactive") return;
808
- const s = F[o];
809
- if (!s) return;
810
- const c = P, x = c.indexOf(o);
811
- switch (e.key) {
812
- case "ArrowRight": {
813
- e.preventDefault();
814
- const b = Math.min(c.length - 1, x + 1);
815
- E(c[b]);
816
- return;
817
- }
818
- case "ArrowLeft": {
819
- e.preventDefault();
820
- const b = Math.max(0, x - 1);
821
- E(c[b]);
822
- return;
823
- }
824
- case "ArrowUp":
825
- case "ArrowDown": {
826
- e.preventDefault();
827
- const w = {
828
- 1: 4,
829
- 4: 1,
830
- 2: 3,
831
- 3: 2,
832
- 5: 8,
833
- 8: 5,
834
- 6: 7,
835
- 7: 6
836
- }[s.quadrant];
837
- if (!w) return;
838
- const I = `${w}${s.positionInQuadrant}`;
839
- c.includes(I) && E(I);
840
- return;
841
- }
842
- case "Home": {
843
- e.preventDefault();
844
- const b = c.filter(
845
- (w) => F[w].quadrant === s.quadrant
846
- );
847
- b.length > 0 && E(b[0]);
848
- return;
849
- }
850
- case "End": {
851
- e.preventDefault();
852
- const b = c.filter(
853
- (w) => F[w].quadrant === s.quadrant
854
- );
855
- b.length > 0 && E(b[b.length - 1]);
856
- return;
857
- }
858
- case " ":
859
- case "Enter": {
860
- if (e.preventDefault(), N) {
861
- xe(o);
862
- return;
863
- }
864
- const b = (L = p[o]) == null ? void 0 : L.conditions, w = rt(b, y), I = { ...p };
865
- w.length === 0 ? (delete I[o], z(d("toothScheme.deselected", { id: o }))) : (I[o] = {
866
- ...p[o] ?? fe(),
867
- conditions: w
868
- }, z(
869
- d("toothScheme.selected", {
870
- id: o,
871
- conditions: w.map((Z) => d(`toothScheme.condition.${Z}`)).join(", ")
872
- })
873
- )), O(I), f == null || f(o);
874
- return;
875
- }
876
- default:
877
- return;
878
- }
879
- },
880
- [
881
- y,
882
- p,
883
- O,
884
- xe,
885
- E,
886
- r,
887
- f,
888
- N,
889
- d,
890
- P
891
- ]
892
- ), yt = R(
893
- (e) => {
894
- var x;
895
- if (r !== "interactive") return;
896
- Y(e);
897
- const o = (x = p[e]) == null ? void 0 : x.conditions, s = rt(o, y), c = { ...p };
898
- s.length === 0 ? (delete c[e], z(d("toothScheme.deselected", { id: e }))) : (c[e] = {
899
- ...p[e] ?? fe(),
900
- conditions: s
901
- }, z(
902
- d("toothScheme.selected", {
903
- id: e,
904
- conditions: s.map((L) => d(`toothScheme.condition.${L}`)).join(", ")
905
- })
906
- )), O(c), f == null || f(e);
907
- },
908
- [y, p, O, r, f, d]
909
- ), Pe = J.width + 4, Ze = J.height + 4, Se = A ?? d("toothScheme.ariaLabel"), Ve = qe ? `${Se} — ${d("toothScheme.view.side")}` : Se, wt = r === "interactive" ? void 0 : 0;
910
- return /* @__PURE__ */ u(B.Provider, { delayDuration: 200, children: /* @__PURE__ */ j(
911
- "div",
912
- {
913
- ref: vt,
914
- role: "region",
915
- "aria-label": Ve,
916
- tabIndex: wt,
917
- className: [zt(), M].filter(Boolean).join(" "),
918
- "data-component": "tooth-scheme",
919
- "data-component-id": t,
920
- "data-testid": "tooth-scheme-root",
921
- "data-dentition": Q,
922
- "data-numbering": X,
923
- "data-mode": r,
924
- "data-projection": W,
925
- "data-view-mode": ie,
926
- children: [
927
- g ? /* @__PURE__ */ u(
928
- "div",
929
- {
930
- className: "ds:flex ds:w-full ds:justify-end",
931
- "data-testid": "tooth-scheme-controls",
932
- children: /* @__PURE__ */ j(Ie.Root, { children: [
933
- /* @__PURE__ */ u(Ie.Trigger, { asChild: !0, children: /* @__PURE__ */ u(
934
- At,
935
- {
936
- size: "sm",
937
- intent: "outline",
938
- icon: /* @__PURE__ */ u(Dt, { "aria-hidden": "true" }),
939
- "aria-label": d("toothScheme.options.label"),
940
- tooltip: d("toothScheme.options.label")
941
- }
942
- ) }),
943
- /* @__PURE__ */ u(
944
- Ie.Content,
945
- {
946
- ref: ft,
947
- align: "end",
948
- size: "md",
949
- "aria-label": d("toothScheme.options.label"),
950
- children: /* @__PURE__ */ j("div", { className: "ds:flex ds:w-[var(--popover-size-sm)] ds:max-w-full ds:flex-col ds:gap-[var(--spacing-md)]", children: [
951
- /* @__PURE__ */ u("div", { className: "ds:flex ds:border-b ds:border-[color:var(--border)] ds:pb-[var(--spacing-sm)] ds:[&>*]:w-full ds:[&>*]:justify-between", children: /* @__PURE__ */ u(
952
- kt,
953
- {
954
- label: d("toothScheme.options.legend"),
955
- labelSide: "start",
956
- checked: Fe,
957
- onCheckedChange: je
958
- }
959
- ) }),
960
- /* @__PURE__ */ u(
961
- ke,
962
- {
963
- container: ge,
964
- label: d("toothScheme.options.dentition"),
965
- value: Q,
966
- onValueChange: (e) => oe(e),
967
- options: [
968
- {
969
- value: "permanent",
970
- label: d("toothScheme.dentition.permanent")
971
- },
972
- {
973
- value: "primary",
974
- label: d("toothScheme.dentition.primary")
975
- },
976
- {
977
- value: "mixed",
978
- label: d("toothScheme.dentition.mixed")
979
- }
980
- ]
981
- }
982
- ),
983
- /* @__PURE__ */ u(
984
- ke,
985
- {
986
- container: ge,
987
- label: d("toothScheme.options.numbering"),
988
- value: X,
989
- onValueChange: (e) => Ne(e),
990
- options: [
991
- {
992
- value: "fdi",
993
- label: d("toothScheme.numbering.fdi")
994
- },
995
- {
996
- value: "universal",
997
- label: d("toothScheme.numbering.universal")
998
- },
999
- {
1000
- value: "palmer",
1001
- label: d("toothScheme.numbering.palmer")
1002
- }
1003
- ]
1004
- }
1005
- ),
1006
- /* @__PURE__ */ u(
1007
- ke,
1008
- {
1009
- container: ge,
1010
- label: d("toothScheme.options.view"),
1011
- value: ie,
1012
- onValueChange: (e) => Re(e),
1013
- options: [
1014
- {
1015
- value: "side",
1016
- label: d("toothScheme.view.side")
1017
- },
1018
- {
1019
- value: "plan",
1020
- label: d("toothScheme.view.occlusal")
1021
- },
1022
- {
1023
- value: "both",
1024
- label: d("toothScheme.view.both")
1025
- }
1026
- ]
1027
- }
1028
- )
1029
- ] })
1030
- }
1031
- )
1032
- ] })
1033
- }
1034
- ) : null,
1035
- /* @__PURE__ */ u(
1036
- "svg",
1037
- {
1038
- ref: be,
1039
- viewBox: `0 0 ${Pe} ${Ze}`,
1040
- width: Pe,
1041
- height: Ze,
1042
- className: Bt(),
1043
- role: "group",
1044
- "aria-label": Ve,
1045
- focusable: "false",
1046
- "data-testid": "tooth-scheme-svg",
1047
- xmlns: "http://www.w3.org/2000/svg",
1048
- children: J.teeth.map((e) => {
1049
- var Qe;
1050
- const o = p[e.fdi], s = (Qe = o == null ? void 0 : o.conditions) == null ? void 0 : Qe[0], c = d(
1051
- `toothScheme.anatomy.${e.meta.anatomy}`
1052
- ), x = s ? `, ${d(`toothScheme.condition.${s}`)}` : "", L = d("toothScheme.toothLabel", {
1053
- id: tt(e.fdi, X),
1054
- anatomy: c,
1055
- conditionSuffix: x
1056
- }), b = r === "interactive" ? S ? -1 : e.fdi === se ? 0 : -1 : void 0, w = (o == null ? void 0 : o.conditions) ?? [], I = w.includes("missing"), Z = w.map((h) => ({
1057
- condition: h,
1058
- spec: _e[h]
1059
- })).filter(
1060
- (h) => !!h.spec
1061
- ), Te = w.find(
1062
- (h) => h !== "missing" && !_e[h]
1063
- ), Ye = Te ? he[Te] : void 0, xt = s ? `${c} · ${d(`toothScheme.condition.${s}`)}` : c, ze = tt(e.fdi, X), $t = at(
1064
- e.meta,
1065
- T,
1066
- "default",
1067
- W
1068
- ), St = W === "plan" ? w.flatMap((h) => {
1069
- const D = Pt[h];
1070
- return D ? ((o == null ? void 0 : o.surfaces) ?? []).map((de) => ({
1071
- key: `${h}-${de}`,
1072
- url: Zt(
1073
- e.meta,
1074
- T,
1075
- D,
1076
- de
1077
- )
1078
- })) : [];
1079
- }) : [], Be = (e.meta.dentition === "primary" ? Ut : 1) * 0.9, te = H * Be, ne = _ * Be, ae = (H - te) / 2, ce = (_ - ne) / 2, k = N && (S == null ? void 0 : S.fdi) === e.fdi, Ge = N ? Ce(e.meta) : [], Tt = Ge.includes("center");
1080
- return /* @__PURE__ */ j(B.Root, { children: [
1081
- /* @__PURE__ */ u(B.Trigger, { asChild: !0, children: /* @__PURE__ */ j(
1082
- "g",
1083
- {
1084
- "data-fdi": e.fdi,
1085
- "data-anatomy": e.meta.anatomy,
1086
- "data-arch": e.meta.arch,
1087
- "data-side": e.meta.side,
1088
- "data-quadrant": e.meta.quadrant,
1089
- "data-condition": s ?? "none",
1090
- "data-testid": `tooth-${e.fdi}`,
1091
- transform: `translate(${e.x}, ${e.y})`,
1092
- tabIndex: b,
1093
- role: k ? "group" : r === "interactive" ? "button" : "img",
1094
- "aria-label": L,
1095
- "aria-pressed": k ? void 0 : r === "interactive" ? s !== void 0 : void 0,
1096
- className: Gt(),
1097
- onClick: k ? void 0 : r === "interactive" ? N ? () => xe(e.fdi) : () => yt(e.fdi) : void 0,
1098
- onFocus: () => Y(e.fdi),
1099
- onKeyDown: k ? void 0 : (h) => bt(h, e.fdi),
1100
- children: [
1101
- /* @__PURE__ */ u(
1102
- "rect",
1103
- {
1104
- x: -K,
1105
- y: -K,
1106
- width: H + K * 2,
1107
- height: _ + K * 2,
1108
- fill: "transparent"
1109
- }
1110
- ),
1111
- /* @__PURE__ */ u(
1112
- "image",
1113
- {
1114
- href: $t,
1115
- x: ae,
1116
- y: ce,
1117
- width: te,
1118
- height: ne,
1119
- preserveAspectRatio: "xMidYMid meet",
1120
- opacity: I ? 0.25 : 1,
1121
- "aria-hidden": "true"
1122
- }
1123
- ),
1124
- W === "side" ? Z.map(({ condition: h, spec: D }) => /* @__PURE__ */ u(
1125
- "image",
1126
- {
1127
- href: it(
1128
- e.meta,
1129
- T,
1130
- D
1131
- ),
1132
- x: ae,
1133
- y: ce,
1134
- width: te,
1135
- height: ne,
1136
- preserveAspectRatio: "xMidYMid meet",
1137
- "aria-hidden": "true",
1138
- pointerEvents: "none"
1139
- },
1140
- h
1141
- )) : null,
1142
- W === "plan" ? St.map(({ key: h, url: D }) => /* @__PURE__ */ u(
1143
- "image",
1144
- {
1145
- href: D,
1146
- x: ae,
1147
- y: ce,
1148
- width: te,
1149
- height: ne,
1150
- preserveAspectRatio: "xMidYMid meet",
1151
- "aria-hidden": "true",
1152
- pointerEvents: "none"
1153
- },
1154
- h
1155
- )) : null,
1156
- N ? Ge.map((h) => {
1157
- const D = Xe(e.meta, h), de = pt(e.fdi, D);
1158
- return /* @__PURE__ */ u(
1159
- "path",
1160
- {
1161
- d: Vt(
1162
- h,
1163
- { x: ae, y: ce, w: te, h: ne },
1164
- Tt
1165
- ),
1166
- "data-fdi": e.fdi,
1167
- "data-zone": h,
1168
- "data-surface": D,
1169
- "data-testid": `tooth-${e.fdi}-zone-${h}`,
1170
- role: k ? "button" : void 0,
1171
- tabIndex: k ? (S == null ? void 0 : S.zone) === h ? 0 : -1 : void 0,
1172
- "aria-label": k ? d("toothScheme.toothLabel", {
1173
- id: ze,
1174
- anatomy: d(
1175
- `toothScheme.surface.${D}`
1176
- ),
1177
- conditionSuffix: ""
1178
- }) : void 0,
1179
- "aria-pressed": k ? de : void 0,
1180
- strokeWidth: "var(--focus-ring-width)",
1181
- className: en(),
1182
- onClick: (U) => {
1183
- U.stopPropagation(), k || Y(e.fdi), we(e.fdi, D);
1184
- },
1185
- onKeyDown: k ? (U) => gt(
1186
- U,
1187
- e.fdi,
1188
- h
1189
- ) : void 0,
1190
- onFocus: k ? () => ee(
1191
- (U) => U && U.fdi === e.fdi && U.zone === h ? U : { fdi: e.fdi, zone: h }
1192
- ) : void 0
1193
- },
1194
- h
1195
- );
1196
- }) : null,
1197
- W === "side" && Ye ? /* @__PURE__ */ u(
1198
- "rect",
1199
- {
1200
- x: 3,
1201
- y: 2,
1202
- width: H - 6,
1203
- height: _ - 4,
1204
- fill: "none",
1205
- stroke: Ye,
1206
- strokeWidth: "2",
1207
- strokeDasharray: Te === "filled" ? "4 2" : void 0,
1208
- rx: "6",
1209
- pointerEvents: "none"
1210
- }
1211
- ) : null,
1212
- I ? /* @__PURE__ */ u(
1213
- "path",
1214
- {
1215
- d: `M7 9 L${H - 7} ${_ - 9} M${H - 7} 9 L7 ${_ - 9}`,
1216
- stroke: he.missing,
1217
- strokeWidth: "2",
1218
- fill: "none",
1219
- pointerEvents: "none"
1220
- }
1221
- ) : null,
1222
- /* @__PURE__ */ u(
1223
- "rect",
1224
- {
1225
- x: -K,
1226
- y: -K,
1227
- width: H + K * 2,
1228
- height: _ + K * 2,
1229
- fill: "none",
1230
- stroke: "var(--ring)",
1231
- strokeWidth: "var(--focus-ring-width)",
1232
- className: [
1233
- "ds:opacity-0",
1234
- "ds:group-focus-visible:opacity-100",
1235
- "ds:forced-colors:stroke-[CanvasText]"
1236
- ].join(" "),
1237
- "data-testid": `tooth-${e.fdi}-focus-ring`,
1238
- pointerEvents: "none",
1239
- rx: "4"
1240
- }
1241
- ),
1242
- /* @__PURE__ */ u(
1243
- "text",
1244
- {
1245
- x: H / 2,
1246
- y: e.meta.arch === "upper" ? _ + 12 : -4,
1247
- textAnchor: "middle",
1248
- fontSize: "10",
1249
- fill: "var(--muted-foreground)",
1250
- className: "ds:select-none",
1251
- "aria-hidden": "true",
1252
- children: ze
1253
- }
1254
- )
1255
- ]
1256
- }
1257
- ) }),
1258
- /* @__PURE__ */ u(B.Portal, { children: /* @__PURE__ */ j(
1259
- B.Content,
1260
- {
1261
- side: "top",
1262
- sideOffset: 6,
1263
- className: "ds:z-[var(--z-tooltip)] ds:rounded-[var(--radius-sm)] ds:bg-[var(--foreground)] ds:text-[var(--background)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:pt-[calc(var(--spacing-xs)/2)] ds:pb-[calc(var(--spacing-xs)/2)] ds:text-[length:var(--font-size-xs)]",
1264
- children: [
1265
- xt,
1266
- /* @__PURE__ */ u(B.Arrow, { className: "ds:fill-[var(--foreground)]" })
1267
- ]
1268
- }
1269
- ) })
1270
- ] }, e.fdi);
1271
- })
1272
- }
1273
- ),
1274
- qe ? /* @__PURE__ */ u(
1275
- ct,
1276
- {
1277
- projection: "plan",
1278
- dentition: Q,
1279
- numbering: X,
1280
- mode: r,
1281
- value: p,
1282
- onChange: O,
1283
- activeCondition: y,
1284
- assetBaseUrl: T,
1285
- ariaLabel: `${Se} — ${d("toothScheme.view.occlusal")}`
1286
- }
1287
- ) : null,
1288
- Fe ? /* @__PURE__ */ u(on, { assetBaseUrl: T }) : null,
1289
- /* @__PURE__ */ u(
1290
- "div",
1291
- {
1292
- className: Jt(),
1293
- "aria-live": "polite",
1294
- "aria-atomic": "true",
1295
- "data-testid": "tooth-scheme-live",
1296
- children: mt
1297
- }
1298
- )
1299
- ]
1300
- }
1301
- ) });
1302
- }
1303
- );
1304
- ct.displayName = "ToothScheme";
1305
- export {
1306
- he as C,
1307
- F,
1308
- De as P,
1309
- Kt as S,
1310
- ct as T,
1311
- Pt as a,
1312
- _e as b,
1313
- gn as c,
1314
- Wt as d,
1315
- Ht as e,
1316
- Me as f,
1317
- nt as g,
1318
- it as h,
1319
- vn as i,
1320
- Yt as j,
1321
- _t as k,
1322
- tt as l,
1323
- Xe as m,
1324
- Ce as n,
1325
- zt as r,
1326
- Zt as s,
1327
- at as t,
1328
- Vt as z
1329
- };
1330
- //# sourceMappingURL=tooth-scheme-yBr53cvv.js.map