@mieweb/ui 0.11.0-dev.29 → 0.11.0-dev.30

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 (116) hide show
  1. package/MIGRATION.md +67 -0
  2. package/README.md +10 -0
  3. package/dist/EncounterMdyEditor-3SQY4MK2.js +286 -0
  4. package/dist/EncounterMdyEditor-3SQY4MK2.js.map +1 -0
  5. package/dist/EncounterMdyEditor-73PTTIRY.cjs +288 -0
  6. package/dist/EncounterMdyEditor-73PTTIRY.cjs.map +1 -0
  7. package/dist/chunk-25MPUVTM.js +339 -0
  8. package/dist/chunk-25MPUVTM.js.map +1 -0
  9. package/dist/{chunk-2VISTX7O.js → chunk-3NOVISM6.js} +3 -3
  10. package/dist/{chunk-2VISTX7O.js.map → chunk-3NOVISM6.js.map} +1 -1
  11. package/dist/{chunk-6GKIISNZ.cjs → chunk-3Y3ZCDNF.cjs} +176 -63
  12. package/dist/chunk-3Y3ZCDNF.cjs.map +1 -0
  13. package/dist/{chunk-AK4LHJPC.js → chunk-4JXO5JTE.js} +84 -3
  14. package/dist/chunk-4JXO5JTE.js.map +1 -0
  15. package/dist/chunk-4NB4WOGU.cjs +666 -0
  16. package/dist/chunk-4NB4WOGU.cjs.map +1 -0
  17. package/dist/{chunk-434L5RYF.js → chunk-4P27Y52M.js} +3 -3
  18. package/dist/{chunk-434L5RYF.js.map → chunk-4P27Y52M.js.map} +1 -1
  19. package/dist/{chunk-PRA2V5BP.cjs → chunk-5KGYTNOA.cjs} +7 -7
  20. package/dist/{chunk-PRA2V5BP.cjs.map → chunk-5KGYTNOA.cjs.map} +1 -1
  21. package/dist/chunk-5LNLB2XT.js +634 -0
  22. package/dist/chunk-5LNLB2XT.js.map +1 -0
  23. package/dist/chunk-5YOT4DVH.js +31 -0
  24. package/dist/chunk-5YOT4DVH.js.map +1 -0
  25. package/dist/chunk-7HFZL5V5.js +2425 -0
  26. package/dist/chunk-7HFZL5V5.js.map +1 -0
  27. package/dist/{chunk-XZNHS7YQ.cjs → chunk-7XC6E4BT.cjs} +3 -3
  28. package/dist/{chunk-XZNHS7YQ.cjs.map → chunk-7XC6E4BT.cjs.map} +1 -1
  29. package/dist/{chunk-JM4YFLO4.js → chunk-AIJYZP7M.js} +3 -3
  30. package/dist/{chunk-JM4YFLO4.js.map → chunk-AIJYZP7M.js.map} +1 -1
  31. package/dist/chunk-BBLEGF5L.js +66 -0
  32. package/dist/chunk-BBLEGF5L.js.map +1 -0
  33. package/dist/{chunk-MBDT2MGR.js → chunk-BIQIE3VW.js} +4 -4
  34. package/dist/{chunk-MBDT2MGR.js.map → chunk-BIQIE3VW.js.map} +1 -1
  35. package/dist/chunk-FSLI5IKP.cjs +54 -0
  36. package/dist/chunk-FSLI5IKP.cjs.map +1 -0
  37. package/dist/chunk-GADJASST.js +3 -0
  38. package/dist/chunk-GADJASST.js.map +1 -0
  39. package/dist/chunk-IXUIOR4K.cjs +2457 -0
  40. package/dist/chunk-IXUIOR4K.cjs.map +1 -0
  41. package/dist/chunk-K2BY7YPJ.cjs +4 -0
  42. package/dist/chunk-K2BY7YPJ.cjs.map +1 -0
  43. package/dist/{chunk-H3P7POFC.cjs → chunk-MA3Y6AYA.cjs} +3 -3
  44. package/dist/{chunk-H3P7POFC.cjs.map → chunk-MA3Y6AYA.cjs.map} +1 -1
  45. package/dist/chunk-QO4A6U73.cjs +342 -0
  46. package/dist/chunk-QO4A6U73.cjs.map +1 -0
  47. package/dist/{chunk-43QBEF6N.js → chunk-QR7B6UPR.js} +176 -63
  48. package/dist/chunk-QR7B6UPR.js.map +1 -0
  49. package/dist/chunk-SMPLM6K3.js +4107 -0
  50. package/dist/chunk-SMPLM6K3.js.map +1 -0
  51. package/dist/chunk-SV6YGK4U.cjs +88 -0
  52. package/dist/chunk-SV6YGK4U.cjs.map +1 -0
  53. package/dist/{chunk-MQ5WJ3NO.js → chunk-UDUYZDTA.js} +14 -72
  54. package/dist/chunk-UDUYZDTA.js.map +1 -0
  55. package/dist/{chunk-ZLBNYCYT.cjs → chunk-XPVQI3MM.cjs} +84 -3
  56. package/dist/chunk-XPVQI3MM.cjs.map +1 -0
  57. package/dist/{chunk-AQUHEKXL.cjs → chunk-XQHDQ64G.cjs} +4 -4
  58. package/dist/{chunk-AQUHEKXL.cjs.map → chunk-XQHDQ64G.cjs.map} +1 -1
  59. package/dist/chunk-Z2OOJGHL.cjs +4155 -0
  60. package/dist/chunk-Z2OOJGHL.cjs.map +1 -0
  61. package/dist/{chunk-QKW2QCGI.cjs → chunk-ZK2R6UGF.cjs} +13 -72
  62. package/dist/chunk-ZK2R6UGF.cjs.map +1 -0
  63. package/dist/components/ActionPlan/index.cjs +4 -4
  64. package/dist/components/ActionPlan/index.js +2 -2
  65. package/dist/components/AlertDialog/index.d.cts +1 -1
  66. package/dist/components/AlertDialog/index.d.ts +1 -1
  67. package/dist/components/EmailEditor/index.cjs +13 -12
  68. package/dist/components/EmailEditor/index.js +4 -3
  69. package/dist/components/MediaEditor/index.cjs +7 -7
  70. package/dist/components/MediaEditor/index.js +2 -2
  71. package/dist/components/RichTextEditor/index.cjs +5 -4
  72. package/dist/components/RichTextEditor/index.d.cts +34 -0
  73. package/dist/components/RichTextEditor/index.d.ts +34 -0
  74. package/dist/components/RichTextEditor/index.js +2 -1
  75. package/dist/components/SuperChat/index.cjs +10 -9
  76. package/dist/components/SuperChat/index.cjs.map +1 -1
  77. package/dist/components/SuperChat/index.js +2 -1
  78. package/dist/components/SuperChat/index.js.map +1 -1
  79. package/dist/components/Textarea/index.cjs +6 -5
  80. package/dist/components/Textarea/index.js +3 -2
  81. package/dist/esheet.cjs +4237 -25
  82. package/dist/esheet.cjs.map +1 -1
  83. package/dist/esheet.d.cts +753 -6
  84. package/dist/esheet.d.ts +753 -6
  85. package/dist/esheet.js +4099 -21
  86. package/dist/esheet.js.map +1 -1
  87. package/dist/index.cjs +204 -3072
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.d.cts +71 -9
  90. package/dist/index.d.ts +71 -9
  91. package/dist/index.js +38 -2968
  92. package/dist/index.js.map +1 -1
  93. package/dist/kerebron.cjs +7 -268
  94. package/dist/kerebron.cjs.map +1 -1
  95. package/dist/kerebron.d.cts +7 -1
  96. package/dist/kerebron.d.ts +7 -1
  97. package/dist/kerebron.js +6 -270
  98. package/dist/kerebron.js.map +1 -1
  99. package/dist/model-WFFZRQMY.js +18 -0
  100. package/dist/model-WFFZRQMY.js.map +1 -0
  101. package/dist/model-Y7WRIGGA.cjs +79 -0
  102. package/dist/model-Y7WRIGGA.cjs.map +1 -0
  103. package/dist/styles.css +1 -1
  104. package/dist/tailwind-preset.cjs +4 -4
  105. package/dist/tailwind-preset.js +1 -1
  106. package/package.json +30 -9
  107. package/dist/chunk-43QBEF6N.js.map +0 -1
  108. package/dist/chunk-6GKIISNZ.cjs.map +0 -1
  109. package/dist/chunk-AK4LHJPC.js.map +0 -1
  110. package/dist/chunk-MQ5WJ3NO.js.map +0 -1
  111. package/dist/chunk-QKW2QCGI.cjs.map +0 -1
  112. package/dist/chunk-SFSBYC46.js +0 -1596
  113. package/dist/chunk-SFSBYC46.js.map +0 -1
  114. package/dist/chunk-ZIJMLRI3.cjs +0 -1633
  115. package/dist/chunk-ZIJMLRI3.cjs.map +0 -1
  116. package/dist/chunk-ZLBNYCYT.cjs.map +0 -1
@@ -0,0 +1,666 @@
1
+ 'use strict';
2
+
3
+ var chunkGLG6UE2H_cjs = require('./chunk-GLG6UE2H.cjs');
4
+ var chunkFSLI5IKP_cjs = require('./chunk-FSLI5IKP.cjs');
5
+ var chunkMJWFNV3L_cjs = require('./chunk-MJWFNV3L.cjs');
6
+ var chunkGF2BE4FB_cjs = require('./chunk-GF2BE4FB.cjs');
7
+ var chunkCPDNX3LS_cjs = require('./chunk-CPDNX3LS.cjs');
8
+ var chunkL7L5S2HO_cjs = require('./chunk-L7L5S2HO.cjs');
9
+ var chunkZ3WMDVMR_cjs = require('./chunk-Z3WMDVMR.cjs');
10
+ var chunk7E46YDOT_cjs = require('./chunk-7E46YDOT.cjs');
11
+ var chunkANMX7YDL_cjs = require('./chunk-ANMX7YDL.cjs');
12
+ var chunkS5RVSXDV_cjs = require('./chunk-S5RVSXDV.cjs');
13
+ var jsxRuntime = require('react/jsx-runtime');
14
+ var React = require('react');
15
+
16
+ function _interopNamespace(e) {
17
+ if (e && e.__esModule) return e;
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
26
+ });
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+
34
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
35
+
36
+ function toolbarKeyNav(e) {
37
+ if (e.altKey || e.ctrlKey || e.metaKey) return;
38
+ if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return;
39
+ const buttons = Array.from(
40
+ e.currentTarget.querySelectorAll(
41
+ "button:not([disabled])"
42
+ )
43
+ );
44
+ const i = buttons.indexOf(document.activeElement);
45
+ if (i === -1 || buttons.length === 0) return;
46
+ e.preventDefault();
47
+ e.stopPropagation();
48
+ let key = e.key;
49
+ if (chunkZ3WMDVMR_cjs.isRtl(e.currentTarget)) {
50
+ if (key === "ArrowRight") key = "ArrowLeft";
51
+ else if (key === "ArrowLeft") key = "ArrowRight";
52
+ }
53
+ const next = key === "ArrowLeft" ? (i - 1 + buttons.length) % buttons.length : key === "ArrowRight" ? (i + 1) % buttons.length : key === "Home" ? 0 : buttons.length - 1;
54
+ buttons[next]?.focus();
55
+ }
56
+ var ALIGN = {
57
+ /** Vertically centered on the row's right edge (single-line rows). */
58
+ center: "pointer-fine:top-1/2 pointer-fine:end-0 pointer-fine:-translate-y-1/2",
59
+ /** Pinned near the row's top-right corner (multi-line rows). */
60
+ top: "pointer-fine:top-1.5 pointer-fine:end-1.5"
61
+ };
62
+ var REVEAL = {
63
+ row: chunkS5RVSXDV_cjs.cn(
64
+ "group-hover:pointer-events-auto group-hover:opacity-100",
65
+ "group-focus-within:pointer-events-auto group-focus-within:opacity-100",
66
+ "group-focus:pointer-events-auto group-focus:opacity-100"
67
+ ),
68
+ order: chunkS5RVSXDV_cjs.cn(
69
+ "group-hover/order:pointer-events-auto group-hover/order:opacity-100",
70
+ "group-focus-within/order:pointer-events-auto group-focus-within/order:opacity-100",
71
+ "group-focus/order:pointer-events-auto group-focus/order:opacity-100"
72
+ ),
73
+ grid: chunkS5RVSXDV_cjs.cn(
74
+ "[.wcdv-tr:hover_&]:pointer-events-auto [.wcdv-tr:hover_&]:opacity-100",
75
+ "[.wcdv-tr:focus-within_&]:pointer-events-auto [.wcdv-tr:focus-within_&]:opacity-100"
76
+ )
77
+ };
78
+ function RowActionToolbar({
79
+ label,
80
+ align = "center",
81
+ group = "row",
82
+ reveal = "hover",
83
+ className,
84
+ children
85
+ }) {
86
+ return /* @__PURE__ */ jsxRuntime.jsx(
87
+ "div",
88
+ {
89
+ role: "toolbar",
90
+ "aria-label": label,
91
+ onKeyDown: toolbarKeyNav,
92
+ className: chunkS5RVSXDV_cjs.cn(
93
+ "z-10 ms-auto flex items-center gap-0.5",
94
+ reveal === "hover" && [
95
+ "transition-opacity",
96
+ // Inside a grid cell the column already reserves the space, so the
97
+ // toolbar stays in flow — no absolute overlay. It keeps the card
98
+ // chrome, though: pair with a `sticky end-0` actions column and it
99
+ // floats over scrolled-under content at the grid's right edge.
100
+ group !== "grid" && [
101
+ "pointer-fine:absolute",
102
+ ALIGN[align],
103
+ "pointer-fine:bg-card pointer-fine:border-border pointer-fine:rounded-md pointer-fine:border pointer-fine:p-0.5 pointer-fine:shadow-sm"
104
+ ],
105
+ group === "grid" && "bg-card border-border rounded-md border p-0.5 shadow-sm",
106
+ "pointer-fine:pointer-events-none pointer-fine:opacity-0",
107
+ REVEAL[group],
108
+ "focus-within:pointer-events-auto focus-within:opacity-100"
109
+ ],
110
+ className
111
+ ),
112
+ children
113
+ }
114
+ );
115
+ }
116
+ function RowIconButton({
117
+ label,
118
+ icon: Icon,
119
+ onClick,
120
+ active,
121
+ expanded,
122
+ controls,
123
+ size = "md"
124
+ }) {
125
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkGLG6UE2H_cjs.Tooltip, { content: label, children: /* @__PURE__ */ jsxRuntime.jsx(
126
+ chunkANMX7YDL_cjs.Button,
127
+ {
128
+ type: "button",
129
+ variant: "ghost",
130
+ size: "icon",
131
+ "aria-label": label,
132
+ "aria-pressed": active,
133
+ "aria-expanded": expanded,
134
+ "aria-controls": controls,
135
+ onClick: (e) => {
136
+ e.stopPropagation();
137
+ onClick();
138
+ },
139
+ className: chunkS5RVSXDV_cjs.cn(
140
+ size === "sm" ? "h-7 w-7" : "h-8 w-8",
141
+ "shrink-0",
142
+ (active || expanded) && "bg-primary-50 text-primary-700 dark:bg-primary-950 dark:text-primary-400"
143
+ ),
144
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: size === "sm" ? 14 : 16 })
145
+ }
146
+ ) });
147
+ }
148
+ var GROUP_ORDER = [
149
+ {
150
+ key: "active",
151
+ label: "Active",
152
+ statuses: ["active", "recurrence", "relapse"]
153
+ },
154
+ { key: "inactive", label: "Inactive", statuses: ["inactive", "remission"] },
155
+ { key: "resolved", label: "Resolved", statuses: ["resolved"] }
156
+ ];
157
+ function concernGroupKey(concern) {
158
+ if (currentAssertion(concern)?.verificationStatus === "unconfirmed") {
159
+ return "unconfirmed";
160
+ }
161
+ return GROUP_ORDER.find((g) => g.statuses.includes(concern.clinicalStatus))?.key ?? "active";
162
+ }
163
+ var CONCERN_STATUS_LABELS = {
164
+ active: "Active",
165
+ recurrence: "Recurrence",
166
+ relapse: "Relapse",
167
+ inactive: "Inactive",
168
+ remission: "Remission",
169
+ resolved: "Resolved"
170
+ };
171
+ var CHANGE_TYPE_LABELS = {
172
+ refinement: "Refined",
173
+ revision: "Revised",
174
+ progression: "Progressed",
175
+ reattribution: "Re-attributed"
176
+ };
177
+ var DEFAULT_ACTIONS = [
178
+ "open",
179
+ "observe",
180
+ "refine",
181
+ "revise",
182
+ "resolve",
183
+ "relate",
184
+ "move-up",
185
+ "move-down"
186
+ ];
187
+ var ACTION_META = {
188
+ open: { label: "Open", icon: chunkL7L5S2HO_cjs.ExternalLink },
189
+ observe: { label: "Add observation (progress note)", icon: chunkL7L5S2HO_cjs.StickyNote },
190
+ refine: { label: "Refine (more specific)", icon: chunkL7L5S2HO_cjs.Pencil },
191
+ revise: { label: "Revise (prior was wrong)", icon: chunkL7L5S2HO_cjs.RefreshCw },
192
+ resolve: { label: "Resolve", icon: chunkL7L5S2HO_cjs.CheckCircle },
193
+ relate: { label: "Relate to another problem", icon: chunkL7L5S2HO_cjs.Link },
194
+ remove: { label: "Delete", icon: chunkL7L5S2HO_cjs.Trash2 },
195
+ "move-up": { label: "Move up (Alt+\u2191)", icon: chunkL7L5S2HO_cjs.ChevronUp },
196
+ "move-down": { label: "Move down (Alt+\u2193)", icon: chunkL7L5S2HO_cjs.ChevronDown }
197
+ };
198
+ var VERIFICATION_BADGE = {
199
+ unconfirmed: { label: "Unconfirmed", variant: "outline" },
200
+ provisional: { label: "Provisional", variant: "warning" },
201
+ differential: { label: "Differential", variant: "warning" },
202
+ confirmed: { label: "Confirmed", variant: "success" },
203
+ refuted: { label: "Refuted", variant: "secondary" },
204
+ "entered-in-error": { label: "Entered in error", variant: "secondary" }
205
+ };
206
+ function currentAssertion(concern) {
207
+ for (let i = concern.assertions.length - 1; i >= 0; i--) {
208
+ const a = concern.assertions[i];
209
+ if (a.verificationStatus !== "refuted" && a.verificationStatus !== "entered-in-error") {
210
+ return a;
211
+ }
212
+ }
213
+ return concern.assertions[concern.assertions.length - 1];
214
+ }
215
+ var UNCERTAIN_FIELD_LABELS = {
216
+ coding: "Coding",
217
+ onset: "Onset",
218
+ severity: "Severity",
219
+ laterality: "Laterality",
220
+ bodySite: "Body site"
221
+ };
222
+ function describeFieldUncertainty(field, f, m) {
223
+ const label = UNCERTAIN_FIELD_LABELS[field];
224
+ if (!f.known) {
225
+ const reason = f.reason === "asked-unknown" ? "asked \u2014 unknown" : (f.reason ?? "unknown").replace(/-/g, " ");
226
+ return `${m(label)}: ${m(reason)}${f.note ? ` (${f.note})` : ""}`;
227
+ }
228
+ return `${m(label)}: ${m("{confidence} confidence", {
229
+ confidence: m(f.confidence ?? "uncertain")
230
+ })}${f.note ? ` (${f.note})` : ""}`;
231
+ }
232
+ function CodingChips({ coding }) {
233
+ const m = chunkFSLI5IKP_cjs.useMessages();
234
+ if (!coding?.length) return null;
235
+ const icd = coding.filter((c) => c.system.startsWith("ICD"));
236
+ const inline = icd.length > 0 ? icd : coding.filter((c) => c.primary);
237
+ const label = inline.map((c) => c.code).join(", ");
238
+ return /* @__PURE__ */ jsxRuntime.jsx(
239
+ chunkGLG6UE2H_cjs.Tooltip,
240
+ {
241
+ content: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-col gap-0.5", children: coding.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
242
+ c.system,
243
+ " ",
244
+ c.code,
245
+ c.display ? ` \u2014 ${c.display}` : "",
246
+ c.primary ? m(" \xB7 primary") : "",
247
+ c.mappedFrom ? m(" \xB7 mapped from {source}", { source: c.mappedFrom }) : ""
248
+ ] }, `${c.system}:${c.code}`)) }),
249
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
250
+ "span",
251
+ {
252
+ tabIndex: 0,
253
+ className: "text-muted-foreground focus-visible:ring-ring rounded text-xs whitespace-nowrap focus-visible:ring-2 focus-visible:outline-none",
254
+ children: [
255
+ "(",
256
+ label || m("coded"),
257
+ ")"
258
+ ]
259
+ }
260
+ )
261
+ }
262
+ );
263
+ }
264
+ function concernHistoryContent(concern, m = (message) => message) {
265
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex max-w-xs flex-col gap-1", children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: m("History") }),
267
+ [...concern.assertions].reverse().map((a) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
268
+ a.date,
269
+ " \u2014 ",
270
+ a.text,
271
+ a.changeType ? ` (${m(CHANGE_TYPE_LABELS[a.changeType]).toLocaleLowerCase()})` : "",
272
+ a.verificationStatus === "refuted" ? ` \u2014 ${m("Refuted").toLocaleLowerCase()}` : ""
273
+ ] }, a.id)),
274
+ concern.observations && concern.observations.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
275
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 font-semibold", children: m("Observations") }),
276
+ [...concern.observations].reverse().slice(0, 3).map((o) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
277
+ o.date,
278
+ " \u2014 ",
279
+ o.text
280
+ ] }, o.id))
281
+ ] }),
282
+ (currentAssertion(concern)?.coding?.length ?? 0) > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
283
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 font-semibold", children: m("Coding") }),
284
+ currentAssertion(concern).coding.map((c) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
285
+ c.system,
286
+ " ",
287
+ c.code,
288
+ c.display ? ` \u2014 ${c.display}` : ""
289
+ ] }, `${c.system}:${c.code}`))
290
+ ] })
291
+ ] });
292
+ }
293
+ function UncertaintyBadge({
294
+ uncertainty
295
+ }) {
296
+ const m = chunkFSLI5IKP_cjs.useMessages();
297
+ if (!uncertainty) return null;
298
+ const fieldEntries = Object.entries(uncertainty.fields ?? {});
299
+ const overall = uncertainty.overall && uncertainty.overall !== "confirmed" ? uncertainty.overall : null;
300
+ if (!overall && fieldEntries.length === 0) return null;
301
+ const lines = [
302
+ ...overall ? [m("Overall certainty: {certainty}", { certainty: m(overall) })] : [],
303
+ ...fieldEntries.map(([field, f]) => describeFieldUncertainty(field, f, m))
304
+ ];
305
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkGLG6UE2H_cjs.Tooltip, { content: lines.join(" \xB7 "), children: /* @__PURE__ */ jsxRuntime.jsxs(chunk7E46YDOT_cjs.Badge, { variant: "warning", size: "sm", className: "gap-1", children: [
306
+ /* @__PURE__ */ jsxRuntime.jsx(chunkL7L5S2HO_cjs.HelpCircle, { size: 10 }),
307
+ overall ? m("{certainty} certainty", { certainty: m(overall) }) : m("{count} uncertain", { count: fieldEntries.length })
308
+ ] }) });
309
+ }
310
+ function AssertionTimeline({ concern }) {
311
+ const m = chunkFSLI5IKP_cjs.useMessages();
312
+ const items = [...concern.assertions].reverse();
313
+ return /* @__PURE__ */ jsxRuntime.jsx(
314
+ "ol",
315
+ {
316
+ "aria-label": m("Assertion history"),
317
+ className: "border-border ms-1.5 mt-2 space-y-2 border-s ps-4",
318
+ children: items.map((a) => {
319
+ const refuted = a.verificationStatus === "refuted" || a.verificationStatus === "entered-in-error";
320
+ const verification = VERIFICATION_BADGE[a.verificationStatus];
321
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "relative text-sm", children: [
322
+ /* @__PURE__ */ jsxRuntime.jsx(
323
+ "span",
324
+ {
325
+ "aria-hidden": true,
326
+ className: "bg-border absolute -start-5 top-1.5 h-2 w-2 rounded-full"
327
+ }
328
+ ),
329
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
330
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs tabular-nums", children: a.date }),
331
+ /* @__PURE__ */ jsxRuntime.jsx(
332
+ "span",
333
+ {
334
+ className: chunkS5RVSXDV_cjs.cn(
335
+ "text-foreground font-medium",
336
+ refuted && "text-muted-foreground line-through"
337
+ ),
338
+ children: a.text
339
+ }
340
+ ),
341
+ a.changeType && /* @__PURE__ */ jsxRuntime.jsx(chunk7E46YDOT_cjs.Badge, { variant: "secondary", size: "sm", children: m(CHANGE_TYPE_LABELS[a.changeType]) }),
342
+ /* @__PURE__ */ jsxRuntime.jsx(chunk7E46YDOT_cjs.Badge, { variant: verification.variant, size: "sm", children: m(verification.label) }),
343
+ /* @__PURE__ */ jsxRuntime.jsx(UncertaintyBadge, { uncertainty: a.uncertainty }),
344
+ /* @__PURE__ */ jsxRuntime.jsx(CodingChips, { coding: a.coding })
345
+ ] }),
346
+ a.note && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-0.5 text-xs", children: a.note })
347
+ ] }, a.id);
348
+ })
349
+ }
350
+ );
351
+ }
352
+ function ConcernRow({
353
+ concern,
354
+ actions,
355
+ inlineActions,
356
+ readOnly,
357
+ canReorder,
358
+ drag,
359
+ onAction
360
+ }) {
361
+ const m = chunkFSLI5IKP_cjs.useMessages();
362
+ const [expanded, setExpanded] = React__namespace.useState(false);
363
+ const current = currentAssertion(concern);
364
+ const hasHistory = concern.assertions.length > 1;
365
+ const visibleActions = actions.filter(
366
+ (a) => canReorder || a !== "move-up" && a !== "move-down"
367
+ );
368
+ const handleRowKeyDown = (e) => {
369
+ if (e.target !== e.currentTarget) return;
370
+ if (e.altKey && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
371
+ if (!canReorder) return;
372
+ e.preventDefault();
373
+ onAction?.(concern, e.key === "ArrowUp" ? "move-up" : "move-down");
374
+ } else if (e.key === "ArrowUp" || e.key === "ArrowDown") {
375
+ e.preventDefault();
376
+ const list = e.currentTarget.closest("ul");
377
+ if (!list) return;
378
+ const rows = Array.from(
379
+ list.querySelectorAll("li[data-concern-id]")
380
+ );
381
+ const i = rows.indexOf(e.currentTarget);
382
+ rows[e.key === "ArrowUp" ? Math.max(0, i - 1) : Math.min(rows.length - 1, i + 1)]?.focus();
383
+ } else if ((e.key === "Enter" || e.key === " ") && hasHistory) {
384
+ e.preventDefault();
385
+ setExpanded((v) => !v);
386
+ }
387
+ };
388
+ if (!current) return null;
389
+ return (
390
+ // Roving-focus row (WAI-ARIA listbox-like keyboard pattern): the row is a
391
+ // legitimate focus stop so ↑/↓ navigate rows, Enter toggles history, and
392
+ // Alt+↑/↓ reorders — required for 508 keyboard operability.
393
+ /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex */
394
+ /* @__PURE__ */ jsxRuntime.jsxs(
395
+ "li",
396
+ {
397
+ "data-slot": "clinical-list-row",
398
+ "data-concern-id": concern.concernId,
399
+ tabIndex: 0,
400
+ onKeyDown: handleRowKeyDown,
401
+ ...drag.rowProps(concern.concernId),
402
+ "aria-label": [
403
+ `${current.text}.`,
404
+ hasHistory ? m("Press Enter to toggle history.") : "",
405
+ canReorder ? m("Alt plus arrow keys to reorder.") : ""
406
+ ].filter(Boolean).join(" "),
407
+ className: chunkS5RVSXDV_cjs.cn(
408
+ "group border-border/60 relative border-b px-1 py-2",
409
+ "focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none",
410
+ drag.enabled && "cursor-grab active:cursor-grabbing",
411
+ chunkGF2BE4FB_cjs.dragIndicatorClasses(drag, concern.concernId)
412
+ ),
413
+ children: [
414
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-9 flex-wrap items-center gap-x-2 gap-y-1", children: [
415
+ drag.enabled ? /* @__PURE__ */ jsxRuntime.jsx(
416
+ chunkL7L5S2HO_cjs.GripVertical,
417
+ {
418
+ size: 14,
419
+ "aria-hidden": true,
420
+ className: "text-muted-foreground/50 shrink-0"
421
+ }
422
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/60 select-none", children: "\u2022" }),
423
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGLG6UE2H_cjs.Tooltip, { content: concernHistoryContent(concern, m), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium", children: current.text }) }),
424
+ /* @__PURE__ */ jsxRuntime.jsx(CodingChips, { coding: current.coding }),
425
+ current.verificationStatus !== "confirmed" && current.verificationStatus !== "unconfirmed" && /* @__PURE__ */ jsxRuntime.jsx(
426
+ chunk7E46YDOT_cjs.Badge,
427
+ {
428
+ variant: VERIFICATION_BADGE[current.verificationStatus].variant,
429
+ size: "sm",
430
+ children: m(VERIFICATION_BADGE[current.verificationStatus].label)
431
+ }
432
+ ),
433
+ /* @__PURE__ */ jsxRuntime.jsx(UncertaintyBadge, { uncertainty: current.uncertainty }),
434
+ concern.relationships?.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(chunk7E46YDOT_cjs.Badge, { variant: "outline", size: "sm", children: [
435
+ /* @__PURE__ */ jsxRuntime.jsx(chunkL7L5S2HO_cjs.Link, { size: 10, className: "me-1" }),
436
+ m(r.type.replace(/-/g, " ")),
437
+ r.display ? `: ${r.display}` : ""
438
+ ] }, `${r.type}:${r.concernId}`)),
439
+ hasHistory && /* @__PURE__ */ jsxRuntime.jsx(
440
+ chunkANMX7YDL_cjs.Button,
441
+ {
442
+ variant: "ghost",
443
+ size: "sm",
444
+ onClick: () => setExpanded((v) => !v),
445
+ "aria-expanded": expanded,
446
+ leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkL7L5S2HO_cjs.History, { size: 12 }),
447
+ rightIcon: expanded ? /* @__PURE__ */ jsxRuntime.jsx(chunkL7L5S2HO_cjs.ChevronUp, { size: 12 }) : /* @__PURE__ */ jsxRuntime.jsx(chunkL7L5S2HO_cjs.ChevronDown, { size: 12 }),
448
+ className: "text-muted-foreground h-auto px-1.5 py-0.5 text-xs",
449
+ children: m("{count} assertions", { count: concern.assertions.length })
450
+ }
451
+ ),
452
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
453
+ RowActionToolbar,
454
+ {
455
+ label: m("Actions for {name}", { name: current.text }),
456
+ align: "top",
457
+ reveal: inlineActions ? "always" : "hover",
458
+ children: visibleActions.map((action) => /* @__PURE__ */ jsxRuntime.jsx(
459
+ RowIconButton,
460
+ {
461
+ label: m(ACTION_META[action].label),
462
+ icon: ACTION_META[action].icon,
463
+ onClick: () => onAction?.(concern, action)
464
+ },
465
+ action
466
+ ))
467
+ }
468
+ )
469
+ ] }),
470
+ expanded && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
471
+ /* @__PURE__ */ jsxRuntime.jsx(AssertionTimeline, { concern }),
472
+ concern.observations && concern.observations.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ms-1.5 mt-2 ps-4", children: [
473
+ /* @__PURE__ */ jsxRuntime.jsx("h5", { className: "text-muted-foreground text-xs font-semibold tracking-wide uppercase", children: m("Observations") }),
474
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-label": m("Observations"), className: "mt-1 space-y-1", children: [...concern.observations].reverse().map((o) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-wrap gap-x-2 text-sm", children: [
475
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs tabular-nums", children: o.date }),
476
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground", children: o.text }),
477
+ o.author && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
478
+ "\u2014 ",
479
+ o.author
480
+ ] })
481
+ ] }, o.id)) })
482
+ ] })
483
+ ] })
484
+ ]
485
+ }
486
+ )
487
+ );
488
+ }
489
+ var ProblemList = React__namespace.forwardRef(
490
+ ({
491
+ concerns,
492
+ title = "Problem list",
493
+ onAction,
494
+ onAddProblem,
495
+ onReorder,
496
+ actions = DEFAULT_ACTIONS,
497
+ inlineActions = false,
498
+ readOnly = false,
499
+ emptyMessage = "No problems recorded.",
500
+ className,
501
+ "data-testid": dataTestId,
502
+ ...props
503
+ }, ref) => {
504
+ const m = chunkFSLI5IKP_cjs.useMessages();
505
+ const [draft, setDraft] = React__namespace.useState("");
506
+ const [announcement, setAnnouncement] = chunkCPDNX3LS_cjs.useLiveAnnouncement();
507
+ const submitDraft = () => {
508
+ const text = draft.trim();
509
+ if (!text) return;
510
+ onAddProblem?.(text);
511
+ setDraft("");
512
+ };
513
+ const moveConcern = React__namespace.useCallback(
514
+ (concern, dir) => {
515
+ if (!onReorder || readOnly) return;
516
+ const groupKey = concernGroupKey(concern);
517
+ const ids = concerns.map((c) => c.concernId);
518
+ const from = ids.indexOf(concern.concernId);
519
+ let to = from + dir;
520
+ while (to >= 0 && to < concerns.length && concernGroupKey(concerns[to]) !== groupKey) {
521
+ to += dir;
522
+ }
523
+ if (to < 0 || to >= concerns.length) return;
524
+ [ids[from], ids[to]] = [ids[to], ids[from]];
525
+ const current = currentAssertion(concern);
526
+ setAnnouncement(
527
+ m(dir === -1 ? "{name} moved up" : "{name} moved down", {
528
+ name: current?.text ?? concern.concernId
529
+ })
530
+ );
531
+ onReorder(ids);
532
+ },
533
+ [concerns, onReorder, readOnly, setAnnouncement, m]
534
+ );
535
+ const handleAction = React__namespace.useCallback(
536
+ (concern, action) => {
537
+ if (action === "move-up") moveConcern(concern, -1);
538
+ else if (action === "move-down") moveConcern(concern, 1);
539
+ else onAction?.(concern, action);
540
+ },
541
+ [moveConcern, onAction]
542
+ );
543
+ const groupById = React__namespace.useMemo(
544
+ () => new Map(
545
+ concerns.map((c) => [c.concernId, concernGroupKey(c)])
546
+ ),
547
+ [concerns]
548
+ );
549
+ const groupOf = React__namespace.useCallback(
550
+ (id) => groupById.get(id),
551
+ [groupById]
552
+ );
553
+ const drag = chunkGF2BE4FB_cjs.useDragReorder({
554
+ ids: concerns.map((c) => c.concernId),
555
+ onReorder: readOnly || !onReorder ? void 0 : (newIds) => {
556
+ setAnnouncement(m("Problem list reordered"));
557
+ onReorder(newIds);
558
+ },
559
+ canDropOn: (dragged, target) => groupOf(dragged) === groupOf(target)
560
+ });
561
+ const groups = [
562
+ {
563
+ key: "unconfirmed",
564
+ label: "Unconfirmed",
565
+ items: concerns.filter((c) => concernGroupKey(c) === "unconfirmed")
566
+ },
567
+ ...GROUP_ORDER.map(({ key, label }) => ({
568
+ key,
569
+ label,
570
+ items: concerns.filter((c) => concernGroupKey(c) === key)
571
+ }))
572
+ // Active stays visible as the empty state only when nothing is recorded
573
+ // at all — an empty Active section next to populated groups would
574
+ // misleadingly read "No problems recorded".
575
+ ].filter(
576
+ (g) => g.items.length > 0 || g.key === "active" && concerns.length === 0
577
+ );
578
+ return /* @__PURE__ */ jsxRuntime.jsxs(
579
+ chunkMJWFNV3L_cjs.Card,
580
+ {
581
+ ref,
582
+ padding: "none",
583
+ className: chunkS5RVSXDV_cjs.cn("w-full", className),
584
+ "data-testid": dataTestId,
585
+ ...props,
586
+ children: [
587
+ title !== null && /* @__PURE__ */ jsxRuntime.jsx(chunkMJWFNV3L_cjs.CardHeader, { className: "border-border bg-muted/50 border-b px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-foreground text-sm font-semibold tracking-wide uppercase", children: m(title) }) }),
588
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkMJWFNV3L_cjs.CardContent, { className: "space-y-6 px-4 py-4", children: [
589
+ groups.map(({ key, label, items }) => /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-label": m(label), children: [
590
+ /* @__PURE__ */ jsxRuntime.jsx(
591
+ "h4",
592
+ {
593
+ "data-slot": "clinical-list-heading",
594
+ className: "border-border text-foreground border-b pb-1 text-sm font-semibold tracking-wide uppercase",
595
+ children: m(label)
596
+ }
597
+ ),
598
+ items.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-1", children: items.map((concern) => /* @__PURE__ */ jsxRuntime.jsx(
599
+ ConcernRow,
600
+ {
601
+ concern,
602
+ actions,
603
+ inlineActions,
604
+ readOnly,
605
+ canReorder: drag.enabled,
606
+ drag,
607
+ onAction: handleAction
608
+ },
609
+ concern.concernId
610
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-2 text-sm", children: m(emptyMessage) })
611
+ ] }, key)),
612
+ !readOnly && onAddProblem && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
613
+ /* @__PURE__ */ jsxRuntime.jsx(
614
+ "input",
615
+ {
616
+ type: "text",
617
+ "data-slot": "input",
618
+ value: draft,
619
+ onChange: (e) => setDraft(e.target.value),
620
+ onKeyDown: (e) => {
621
+ if (e.key === "Enter") submitDraft();
622
+ },
623
+ placeholder: m("Add problem (name is enough)\u2026"),
624
+ "aria-label": m("Add problem"),
625
+ className: chunkS5RVSXDV_cjs.cn(
626
+ "border-border bg-background text-foreground placeholder:text-muted-foreground",
627
+ "h-8 flex-1 rounded-md border px-2.5 text-sm",
628
+ "focus:ring-ring focus:ring-2 focus:outline-none"
629
+ )
630
+ }
631
+ ),
632
+ /* @__PURE__ */ jsxRuntime.jsx(
633
+ chunkANMX7YDL_cjs.Button,
634
+ {
635
+ variant: "outline",
636
+ size: "sm",
637
+ onClick: submitDraft,
638
+ disabled: !draft.trim(),
639
+ leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkL7L5S2HO_cjs.Plus, { size: 12 }),
640
+ className: "h-8",
641
+ children: m("Add")
642
+ }
643
+ )
644
+ ] })
645
+ ] }),
646
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-live": "polite", className: "sr-only", children: announcement })
647
+ ]
648
+ }
649
+ );
650
+ }
651
+ );
652
+ ProblemList.displayName = "ProblemList";
653
+
654
+ exports.CHANGE_TYPE_LABELS = CHANGE_TYPE_LABELS;
655
+ exports.CONCERN_STATUS_LABELS = CONCERN_STATUS_LABELS;
656
+ exports.CodingChips = CodingChips;
657
+ exports.ProblemList = ProblemList;
658
+ exports.RowActionToolbar = RowActionToolbar;
659
+ exports.RowIconButton = RowIconButton;
660
+ exports.UncertaintyBadge = UncertaintyBadge;
661
+ exports.concernGroupKey = concernGroupKey;
662
+ exports.concernHistoryContent = concernHistoryContent;
663
+ exports.currentAssertion = currentAssertion;
664
+ exports.toolbarKeyNav = toolbarKeyNav;
665
+ //# sourceMappingURL=chunk-4NB4WOGU.cjs.map
666
+ //# sourceMappingURL=chunk-4NB4WOGU.cjs.map