@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.
- package/MIGRATION.md +67 -0
- package/README.md +10 -0
- package/dist/EncounterMdyEditor-3SQY4MK2.js +286 -0
- package/dist/EncounterMdyEditor-3SQY4MK2.js.map +1 -0
- package/dist/EncounterMdyEditor-73PTTIRY.cjs +288 -0
- package/dist/EncounterMdyEditor-73PTTIRY.cjs.map +1 -0
- package/dist/chunk-25MPUVTM.js +339 -0
- package/dist/chunk-25MPUVTM.js.map +1 -0
- package/dist/{chunk-2VISTX7O.js → chunk-3NOVISM6.js} +3 -3
- package/dist/{chunk-2VISTX7O.js.map → chunk-3NOVISM6.js.map} +1 -1
- package/dist/{chunk-6GKIISNZ.cjs → chunk-3Y3ZCDNF.cjs} +176 -63
- package/dist/chunk-3Y3ZCDNF.cjs.map +1 -0
- package/dist/{chunk-AK4LHJPC.js → chunk-4JXO5JTE.js} +84 -3
- package/dist/chunk-4JXO5JTE.js.map +1 -0
- package/dist/chunk-4NB4WOGU.cjs +666 -0
- package/dist/chunk-4NB4WOGU.cjs.map +1 -0
- package/dist/{chunk-434L5RYF.js → chunk-4P27Y52M.js} +3 -3
- package/dist/{chunk-434L5RYF.js.map → chunk-4P27Y52M.js.map} +1 -1
- package/dist/{chunk-PRA2V5BP.cjs → chunk-5KGYTNOA.cjs} +7 -7
- package/dist/{chunk-PRA2V5BP.cjs.map → chunk-5KGYTNOA.cjs.map} +1 -1
- package/dist/chunk-5LNLB2XT.js +634 -0
- package/dist/chunk-5LNLB2XT.js.map +1 -0
- package/dist/chunk-5YOT4DVH.js +31 -0
- package/dist/chunk-5YOT4DVH.js.map +1 -0
- package/dist/chunk-7HFZL5V5.js +2425 -0
- package/dist/chunk-7HFZL5V5.js.map +1 -0
- package/dist/{chunk-XZNHS7YQ.cjs → chunk-7XC6E4BT.cjs} +3 -3
- package/dist/{chunk-XZNHS7YQ.cjs.map → chunk-7XC6E4BT.cjs.map} +1 -1
- package/dist/{chunk-JM4YFLO4.js → chunk-AIJYZP7M.js} +3 -3
- package/dist/{chunk-JM4YFLO4.js.map → chunk-AIJYZP7M.js.map} +1 -1
- package/dist/chunk-BBLEGF5L.js +66 -0
- package/dist/chunk-BBLEGF5L.js.map +1 -0
- package/dist/{chunk-MBDT2MGR.js → chunk-BIQIE3VW.js} +4 -4
- package/dist/{chunk-MBDT2MGR.js.map → chunk-BIQIE3VW.js.map} +1 -1
- package/dist/chunk-FSLI5IKP.cjs +54 -0
- package/dist/chunk-FSLI5IKP.cjs.map +1 -0
- package/dist/chunk-GADJASST.js +3 -0
- package/dist/chunk-GADJASST.js.map +1 -0
- package/dist/chunk-IXUIOR4K.cjs +2457 -0
- package/dist/chunk-IXUIOR4K.cjs.map +1 -0
- package/dist/chunk-K2BY7YPJ.cjs +4 -0
- package/dist/chunk-K2BY7YPJ.cjs.map +1 -0
- package/dist/{chunk-H3P7POFC.cjs → chunk-MA3Y6AYA.cjs} +3 -3
- package/dist/{chunk-H3P7POFC.cjs.map → chunk-MA3Y6AYA.cjs.map} +1 -1
- package/dist/chunk-QO4A6U73.cjs +342 -0
- package/dist/chunk-QO4A6U73.cjs.map +1 -0
- package/dist/{chunk-43QBEF6N.js → chunk-QR7B6UPR.js} +176 -63
- package/dist/chunk-QR7B6UPR.js.map +1 -0
- package/dist/chunk-SMPLM6K3.js +4107 -0
- package/dist/chunk-SMPLM6K3.js.map +1 -0
- package/dist/chunk-SV6YGK4U.cjs +88 -0
- package/dist/chunk-SV6YGK4U.cjs.map +1 -0
- package/dist/{chunk-MQ5WJ3NO.js → chunk-UDUYZDTA.js} +14 -72
- package/dist/chunk-UDUYZDTA.js.map +1 -0
- package/dist/{chunk-ZLBNYCYT.cjs → chunk-XPVQI3MM.cjs} +84 -3
- package/dist/chunk-XPVQI3MM.cjs.map +1 -0
- package/dist/{chunk-AQUHEKXL.cjs → chunk-XQHDQ64G.cjs} +4 -4
- package/dist/{chunk-AQUHEKXL.cjs.map → chunk-XQHDQ64G.cjs.map} +1 -1
- package/dist/chunk-Z2OOJGHL.cjs +4155 -0
- package/dist/chunk-Z2OOJGHL.cjs.map +1 -0
- package/dist/{chunk-QKW2QCGI.cjs → chunk-ZK2R6UGF.cjs} +13 -72
- package/dist/chunk-ZK2R6UGF.cjs.map +1 -0
- package/dist/components/ActionPlan/index.cjs +4 -4
- package/dist/components/ActionPlan/index.js +2 -2
- package/dist/components/AlertDialog/index.d.cts +1 -1
- package/dist/components/AlertDialog/index.d.ts +1 -1
- package/dist/components/EmailEditor/index.cjs +13 -12
- package/dist/components/EmailEditor/index.js +4 -3
- package/dist/components/MediaEditor/index.cjs +7 -7
- package/dist/components/MediaEditor/index.js +2 -2
- package/dist/components/RichTextEditor/index.cjs +5 -4
- package/dist/components/RichTextEditor/index.d.cts +34 -0
- package/dist/components/RichTextEditor/index.d.ts +34 -0
- package/dist/components/RichTextEditor/index.js +2 -1
- package/dist/components/SuperChat/index.cjs +10 -9
- package/dist/components/SuperChat/index.cjs.map +1 -1
- package/dist/components/SuperChat/index.js +2 -1
- package/dist/components/SuperChat/index.js.map +1 -1
- package/dist/components/Textarea/index.cjs +6 -5
- package/dist/components/Textarea/index.js +3 -2
- package/dist/esheet.cjs +4237 -25
- package/dist/esheet.cjs.map +1 -1
- package/dist/esheet.d.cts +753 -6
- package/dist/esheet.d.ts +753 -6
- package/dist/esheet.js +4099 -21
- package/dist/esheet.js.map +1 -1
- package/dist/index.cjs +204 -3072
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -9
- package/dist/index.d.ts +71 -9
- package/dist/index.js +38 -2968
- package/dist/index.js.map +1 -1
- package/dist/kerebron.cjs +7 -268
- package/dist/kerebron.cjs.map +1 -1
- package/dist/kerebron.d.cts +7 -1
- package/dist/kerebron.d.ts +7 -1
- package/dist/kerebron.js +6 -270
- package/dist/kerebron.js.map +1 -1
- package/dist/model-WFFZRQMY.js +18 -0
- package/dist/model-WFFZRQMY.js.map +1 -0
- package/dist/model-Y7WRIGGA.cjs +79 -0
- package/dist/model-Y7WRIGGA.cjs.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/package.json +30 -9
- package/dist/chunk-43QBEF6N.js.map +0 -1
- package/dist/chunk-6GKIISNZ.cjs.map +0 -1
- package/dist/chunk-AK4LHJPC.js.map +0 -1
- package/dist/chunk-MQ5WJ3NO.js.map +0 -1
- package/dist/chunk-QKW2QCGI.cjs.map +0 -1
- package/dist/chunk-SFSBYC46.js +0 -1596
- package/dist/chunk-SFSBYC46.js.map +0 -1
- package/dist/chunk-ZIJMLRI3.cjs +0 -1633
- package/dist/chunk-ZIJMLRI3.cjs.map +0 -1
- package/dist/chunk-ZLBNYCYT.cjs.map +0 -1
package/MIGRATION.md
CHANGED
|
@@ -3,6 +3,73 @@
|
|
|
3
3
|
Breaking-change recipes for `@mieweb/ui` consumers. Each section is anchored
|
|
4
4
|
so release notes and dev-console notices can deep-link to it.
|
|
5
5
|
|
|
6
|
+
## eSheet and EncounterVisit
|
|
7
|
+
|
|
8
|
+
The `@mieweb/ui/esheet` entry now includes EncounterVisit. Install matching
|
|
9
|
+
`@esheet/core`, `@esheet/fields`, `@esheet/renderer` and `@esheet/builder` versions
|
|
10
|
+
(0.0.6-17 or newer). They are optional peers because the default UI entry does
|
|
11
|
+
not use eSheet. The shared entry exports the builder even when your application
|
|
12
|
+
only renders visits, so all four peers must be present.
|
|
13
|
+
|
|
14
|
+
Builder and Renderer import their `@esheet/styles` dependency automatically.
|
|
15
|
+
Remove copied or aliased `renderer/src/index.output.css` and
|
|
16
|
+
`builder/src/index.output.css` files; one shared stylesheet replaces both.
|
|
17
|
+
An explicit CSS entry is available at `@esheet/styles/styles.css`. Continue
|
|
18
|
+
loading `@mieweb/ui/styles.css` for composed UI components.
|
|
19
|
+
|
|
20
|
+
EncounterVisit's RichEdit mode additionally requires the Kerebron peers
|
|
21
|
+
`@kerebron/editor`, `@kerebron/editor-kits`, `@kerebron/extension-basic-editor`
|
|
22
|
+
and `@kerebron/wasm` (tested together at 0.8.12). Import `@mieweb/ui/kerebron.css`
|
|
23
|
+
and serve `@kerebron/wasm/assets` at `/kerebron-wasm`. Apply the Kerebron patches
|
|
24
|
+
described by the RichEditor documentation for its toolbar and Markdown marks.
|
|
25
|
+
|
|
26
|
+
**Required for Kerebron 0.8.12:** configure the consuming application's package
|
|
27
|
+
manager to resolve every `prosemirror-view` dependency to **1.42.3**. Kerebron
|
|
28
|
+
pins 1.40.0, while the protected MDY link bridge uses 1.42.3. Two view instances
|
|
29
|
+
can make decorations incompatible and leave the older view's behavior active.
|
|
30
|
+
The overrides in this library's checkout do not propagate to installed apps.
|
|
31
|
+
|
|
32
|
+
For pnpm 10, add to the host's `pnpm-workspace.yaml`:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
overrides:
|
|
36
|
+
prosemirror-view: "1.42.3"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For npm, add to the host's `package.json`:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"overrides": {
|
|
44
|
+
"prosemirror-view": "1.42.3"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For Yarn, add to the host's `package.json`:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"resolutions": {
|
|
54
|
+
"prosemirror-view": "1.42.3"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If the host also declares `prosemirror-view` directly, pin that dependency to
|
|
60
|
+
1.42.3. Reinstall and inspect `pnpm why prosemirror-view`,
|
|
61
|
+
`npm ls prosemirror-view` or `yarn why prosemirror-view`: every resolved instance
|
|
62
|
+
must be 1.42.3. Keep this requirement until a tested Kerebron release shares the
|
|
63
|
+
same view version without an override.
|
|
64
|
+
|
|
65
|
+
**Recommended for EncounterVisit hosts:** resolve `js-yaml` to **4.3.2 or
|
|
66
|
+
newer**. `@mieweb/templit` 0.2.0 (a direct dependency used by
|
|
67
|
+
`renderEncounterMdy` for the document's YAML envelope) pins js-yaml 4.1.0,
|
|
68
|
+
which lacks the parser merge-limit hardening. This library's checkout applies
|
|
69
|
+
the override locally, but overrides do not propagate to installed apps — add
|
|
70
|
+
the same `js-yaml: ">=4.3.2"` override/resolution shown above for
|
|
71
|
+
`prosemirror-view`, until a Templit release ships the corrected parser.
|
|
72
|
+
|
|
6
73
|
## Textarea is rich text underneath (0.12.0)
|
|
7
74
|
|
|
8
75
|
**`Textarea` now renders `TextAreaRich`** (hidden toolbar, markdown block
|
package/README.md
CHANGED
|
@@ -161,6 +161,16 @@ you only install what you need:
|
|
|
161
161
|
Check the selected integration's dependencies before importing its entry point.
|
|
162
162
|
AGGrid is deprecated for new work; start with DataVis NITRO for tabular data.
|
|
163
163
|
|
|
164
|
+
`@mieweb/ui/esheet` requires matching `@esheet/core`, `@esheet/fields`,
|
|
165
|
+
`@esheet/renderer` and `@esheet/builder` optional peers (0.0.6-17 or newer).
|
|
166
|
+
Their shared `@esheet/styles` dependency supplies eSheet CSS automatically;
|
|
167
|
+
keep loading `@mieweb/ui/styles.css` for the composed controls. EncounterVisit's
|
|
168
|
+
RichEdit mode also needs the Kerebron peers, CSS and WASM assets. **With Kerebron
|
|
169
|
+
0.8.12, the host must override every `prosemirror-view` resolution to 1.42.3.**
|
|
170
|
+
The library's development override does not configure an installed consumer.
|
|
171
|
+
Follow the shipped [eSheet and EncounterVisit setup](https://github.com/mieweb/ui/blob/main/MIGRATION.md#esheet-and-encountervisit)
|
|
172
|
+
for the package-manager configuration and verification command.
|
|
173
|
+
|
|
164
174
|
## Explore and Compose Components
|
|
165
175
|
|
|
166
176
|
Open [the component explorer](https://ui.mieweb.org/). Storybook is the wrapper
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import './chunk-GADJASST.js';
|
|
2
|
+
import { useMessages } from './chunk-5YOT4DVH.js';
|
|
3
|
+
import { RichEditor, MDY_PROJECTION_META } from './chunk-25MPUVTM.js';
|
|
4
|
+
import './chunk-RUGHNFQG.js';
|
|
5
|
+
import './chunk-PX6F3LHL.js';
|
|
6
|
+
import { forwardRef, useState, useRef, useImperativeHandle, useMemo, useEffect } from 'react';
|
|
7
|
+
import { Extension } from '@kerebron/editor';
|
|
8
|
+
import { PluginKey, Plugin } from 'prosemirror-state';
|
|
9
|
+
import { DecorationSet, Decoration } from 'prosemirror-view';
|
|
10
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
function linkedFieldId(href, fieldIds) {
|
|
13
|
+
if (typeof href !== "string") return null;
|
|
14
|
+
const id = href.startsWith("mdy:") ? href.slice(4) : href.startsWith("#") ? href.slice(1) : "";
|
|
15
|
+
return fieldIds.has(id) ? id : null;
|
|
16
|
+
}
|
|
17
|
+
function getMdyFieldSpans(doc, fieldIds) {
|
|
18
|
+
const spans = [];
|
|
19
|
+
doc.descendants((node, pos) => {
|
|
20
|
+
if (!node.isInline) return;
|
|
21
|
+
const mark = node.marks.find((candidate) => candidate.type.name === "link");
|
|
22
|
+
let id = linkedFieldId(mark?.attrs.href, fieldIds);
|
|
23
|
+
const previous = spans[spans.length - 1];
|
|
24
|
+
if (!id && (node.type.name === "br" || node.type.name === "softbreak") && previous?.to === pos) {
|
|
25
|
+
let nextPos = pos + node.nodeSize;
|
|
26
|
+
let next = doc.nodeAt(nextPos);
|
|
27
|
+
while (next && (next.type.name === "br" || next.type.name === "softbreak")) {
|
|
28
|
+
nextPos += next.nodeSize;
|
|
29
|
+
next = doc.nodeAt(nextPos);
|
|
30
|
+
}
|
|
31
|
+
const nextMark = next?.marks.find(
|
|
32
|
+
(candidate) => candidate.type.name === "link"
|
|
33
|
+
);
|
|
34
|
+
if (linkedFieldId(nextMark?.attrs.href, fieldIds) === previous.id)
|
|
35
|
+
id = previous.id;
|
|
36
|
+
}
|
|
37
|
+
if (!id) return;
|
|
38
|
+
if (previous?.id === id && previous.to === pos) {
|
|
39
|
+
previous.to = pos + node.nodeSize;
|
|
40
|
+
} else {
|
|
41
|
+
spans.push({ id, from: pos, to: pos + node.nodeSize });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return spans;
|
|
45
|
+
}
|
|
46
|
+
function refreshMdyFieldProjections(editor, fields) {
|
|
47
|
+
const byId = new Map(fields.map((field) => [field.id, field.display]));
|
|
48
|
+
const state = editor.view.state;
|
|
49
|
+
const spans = getMdyFieldSpans(state.doc, new Set(byId.keys()));
|
|
50
|
+
const transaction = state.tr;
|
|
51
|
+
for (const span of spans.reverse()) {
|
|
52
|
+
const display = byId.get(span.id);
|
|
53
|
+
const current = state.doc.textBetween(span.from, span.to, "", "\n");
|
|
54
|
+
const oldMarks = state.doc.nodeAt(span.from)?.marks ?? [];
|
|
55
|
+
const link = oldMarks.find((mark) => mark.type.name === "link");
|
|
56
|
+
if (!link) continue;
|
|
57
|
+
const label = display.split(/\r?\n/).map(
|
|
58
|
+
(line) => line.replace(/&/g, "&").replace(/\$/g, "$").replace(/[\\[\]`*_~<>]/g, "\\$&")
|
|
59
|
+
).join("<br>");
|
|
60
|
+
const template = `[${label}](${link.attrs.href})`;
|
|
61
|
+
let looseBreak = false;
|
|
62
|
+
state.doc.nodesBetween(span.from, span.to, (node) => {
|
|
63
|
+
if ((node.type.name === "br" || node.type.name === "softbreak") && !node.marks.some((mark) => mark.type.name === "link"))
|
|
64
|
+
looseBreak = true;
|
|
65
|
+
});
|
|
66
|
+
if (current === display && !looseBreak && link.attrs.mdTemplate === template)
|
|
67
|
+
continue;
|
|
68
|
+
const marks = oldMarks.map(
|
|
69
|
+
(mark) => mark.type.name === "link" ? mark.type.create({ ...mark.attrs, mdTemplate: template }) : mark
|
|
70
|
+
);
|
|
71
|
+
const breakType = state.schema.nodes.br ?? state.schema.nodes.softbreak;
|
|
72
|
+
const replacement = [];
|
|
73
|
+
display.split(/\r?\n/).forEach((line, index) => {
|
|
74
|
+
if (index && breakType)
|
|
75
|
+
replacement.push(breakType.create(null, null, marks));
|
|
76
|
+
if (line) replacement.push(state.schema.text(line, marks));
|
|
77
|
+
});
|
|
78
|
+
transaction.replaceWith(span.from, span.to, replacement);
|
|
79
|
+
}
|
|
80
|
+
if (!transaction.docChanged) return false;
|
|
81
|
+
transaction.setMeta(MDY_PROJECTION_META, true);
|
|
82
|
+
transaction.setMeta("addToHistory", false);
|
|
83
|
+
editor.view.dispatch(transaction);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
function canEditMdyTransaction(transaction, fieldIds) {
|
|
87
|
+
if (!transaction.docChanged) return true;
|
|
88
|
+
for (let index = 0; index < transaction.steps.length; index += 1) {
|
|
89
|
+
const before = transaction.docs[index];
|
|
90
|
+
const after = transaction.docs[index + 1] ?? transaction.doc;
|
|
91
|
+
const map = transaction.steps[index].getMap();
|
|
92
|
+
const spans = getMdyFieldSpans(before, fieldIds);
|
|
93
|
+
const step = transaction.steps[index].toJSON();
|
|
94
|
+
if ((step.stepType === "addMark" || step.stepType === "removeMark") && step.mark?.type === "link" && spans.some((span) => step.from < span.to && step.to > span.from)) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const removed = /* @__PURE__ */ new Set();
|
|
98
|
+
let allowed = true;
|
|
99
|
+
map.forEach((oldStart, oldEnd, newStart, newEnd) => {
|
|
100
|
+
for (const span of spans) {
|
|
101
|
+
if (oldStart === oldEnd) {
|
|
102
|
+
if (oldStart > span.from && oldStart < span.to) allowed = false;
|
|
103
|
+
} else if (oldStart < span.to && oldEnd > span.from) {
|
|
104
|
+
if (oldStart <= span.from && oldEnd >= span.to && (newStart === newEnd || after.textBetween(newStart, newEnd) === "")) {
|
|
105
|
+
removed.add(span);
|
|
106
|
+
} else {
|
|
107
|
+
allowed = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
if (!allowed) return false;
|
|
113
|
+
const nextSpans = getMdyFieldSpans(after, fieldIds);
|
|
114
|
+
for (const span of spans) {
|
|
115
|
+
if (removed.has(span)) continue;
|
|
116
|
+
const from = map.map(span.from, 1);
|
|
117
|
+
const to = map.map(span.to, -1);
|
|
118
|
+
if (before.textBetween(span.from, span.to) !== after.textBetween(from, to) || !nextSpans.some(
|
|
119
|
+
(next) => next.id === span.id && next.from === from && next.to === to
|
|
120
|
+
)) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
var mdyPluginKey = new PluginKey("mdy-field-links");
|
|
128
|
+
function createMdyFieldPlugin(options) {
|
|
129
|
+
const activate = (id, event) => {
|
|
130
|
+
event.preventDefault();
|
|
131
|
+
if (!options.isDisabled?.()) options.onFieldActivate(id);
|
|
132
|
+
return true;
|
|
133
|
+
};
|
|
134
|
+
const targetId = (event) => {
|
|
135
|
+
const element = event.target;
|
|
136
|
+
const chip = element instanceof Element ? element.closest("[data-mdy-field]") : null;
|
|
137
|
+
const id = chip?.getAttribute("data-mdy-field");
|
|
138
|
+
return id && options.getFieldIds().has(id) ? id : null;
|
|
139
|
+
};
|
|
140
|
+
return new Plugin({
|
|
141
|
+
key: mdyPluginKey,
|
|
142
|
+
filterTransaction: (transaction) => transaction.getMeta(MDY_PROJECTION_META) === true || canEditMdyTransaction(transaction, options.getFieldIds()),
|
|
143
|
+
props: {
|
|
144
|
+
decorations: (state) => DecorationSet.create(
|
|
145
|
+
state.doc,
|
|
146
|
+
getMdyFieldSpans(state.doc, options.getFieldIds()).map(
|
|
147
|
+
(span) => Decoration.inline(span.from, span.to, {
|
|
148
|
+
class: "encounter-mdy-field",
|
|
149
|
+
"data-mdy-field": span.id,
|
|
150
|
+
role: "button",
|
|
151
|
+
tabindex: "0",
|
|
152
|
+
"aria-label": `Linked field: ${options.getFieldLabel?.(span.id) ?? span.id}. Activate to edit in the form.`,
|
|
153
|
+
"aria-disabled": options.isDisabled?.() ? "true" : "false",
|
|
154
|
+
style: "background:rgba(59,130,246,.12);border-radius:.2em;padding:0 .15em;cursor:pointer;text-decoration:underline;text-underline-offset:.15em"
|
|
155
|
+
})
|
|
156
|
+
)
|
|
157
|
+
),
|
|
158
|
+
handleDOMEvents: {
|
|
159
|
+
click: (_view, event) => {
|
|
160
|
+
const id = targetId(event);
|
|
161
|
+
return id ? activate(id, event) : false;
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
handleKeyDown: (view, event) => {
|
|
165
|
+
const focusedId = targetId(event);
|
|
166
|
+
if (focusedId && (event.key === "Enter" || event.key === " ")) {
|
|
167
|
+
return activate(focusedId, event);
|
|
168
|
+
}
|
|
169
|
+
if (event.key !== "Enter") return false;
|
|
170
|
+
const { from, to } = view.state.selection;
|
|
171
|
+
const span = getMdyFieldSpans(
|
|
172
|
+
view.state.doc,
|
|
173
|
+
options.getFieldIds()
|
|
174
|
+
).find((candidate) => from >= candidate.from && to <= candidate.to);
|
|
175
|
+
return span ? activate(span.id, event) : false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
var MdyFieldExtension = class extends Extension {
|
|
181
|
+
constructor(options) {
|
|
182
|
+
super();
|
|
183
|
+
this.options = options;
|
|
184
|
+
}
|
|
185
|
+
options;
|
|
186
|
+
name = "mdy-field-links";
|
|
187
|
+
getProseMirrorPlugins() {
|
|
188
|
+
return [createMdyFieldPlugin(this.options)];
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var MdyEditorKit = class {
|
|
192
|
+
constructor(options) {
|
|
193
|
+
this.options = options;
|
|
194
|
+
}
|
|
195
|
+
options;
|
|
196
|
+
name = "mdy-field-links";
|
|
197
|
+
getExtensions() {
|
|
198
|
+
return [new MdyFieldExtension(this.options)];
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
function createMdyEditorKit(options) {
|
|
202
|
+
return new MdyEditorKit(options);
|
|
203
|
+
}
|
|
204
|
+
var EncounterMdyEditor = forwardRef(function EncounterMdyEditor2({ body, fields = [], fieldIds, onChange, onFieldActivate, disabled = false }, ref) {
|
|
205
|
+
const m = useMessages();
|
|
206
|
+
const [editor, setEditor] = useState(null);
|
|
207
|
+
const [loadFailed, setLoadFailed] = useState(false);
|
|
208
|
+
const richEditor = useRef(null);
|
|
209
|
+
const status = useRef({ editor, loadFailed, body });
|
|
210
|
+
status.current = { editor, loadFailed, body };
|
|
211
|
+
const live = useRef({
|
|
212
|
+
fieldIds: new Set(fieldIds),
|
|
213
|
+
onFieldActivate,
|
|
214
|
+
disabled: disabled || loadFailed || editor === null
|
|
215
|
+
});
|
|
216
|
+
live.current = {
|
|
217
|
+
fieldIds: new Set(fieldIds ?? fields.map((field) => field.id)),
|
|
218
|
+
onFieldActivate,
|
|
219
|
+
disabled: disabled || loadFailed || editor === null
|
|
220
|
+
};
|
|
221
|
+
const fieldsRef = useRef(fields);
|
|
222
|
+
fieldsRef.current = fields;
|
|
223
|
+
useImperativeHandle(
|
|
224
|
+
ref,
|
|
225
|
+
() => ({
|
|
226
|
+
getContent: async () => {
|
|
227
|
+
if (status.current.loadFailed && !status.current.editor)
|
|
228
|
+
return status.current.body;
|
|
229
|
+
return richEditor.current ? richEditor.current.getContent() : status.current.body;
|
|
230
|
+
},
|
|
231
|
+
focus: () => {
|
|
232
|
+
if (!status.current.loadFailed) richEditor.current?.focus();
|
|
233
|
+
}
|
|
234
|
+
}),
|
|
235
|
+
[]
|
|
236
|
+
);
|
|
237
|
+
const editorKits = useMemo(
|
|
238
|
+
() => [
|
|
239
|
+
createMdyEditorKit({
|
|
240
|
+
getFieldIds: () => live.current.fieldIds,
|
|
241
|
+
getFieldLabel: (id) => fieldsRef.current.find((field) => field.id === id)?.label,
|
|
242
|
+
onFieldActivate: (id) => live.current.onFieldActivate(id),
|
|
243
|
+
isDisabled: () => live.current.disabled
|
|
244
|
+
})
|
|
245
|
+
],
|
|
246
|
+
[]
|
|
247
|
+
);
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
if (!editor) return;
|
|
250
|
+
const refresh = () => refreshMdyFieldProjections(editor, fieldsRef.current);
|
|
251
|
+
const loaded = () => refresh();
|
|
252
|
+
editor.addEventListener("doc:loaded", loaded);
|
|
253
|
+
refresh();
|
|
254
|
+
return () => editor.removeEventListener("doc:loaded", loaded);
|
|
255
|
+
}, [editor, fields]);
|
|
256
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
257
|
+
loadFailed && /* @__PURE__ */ jsx("p", { role: "alert", children: m(
|
|
258
|
+
"The narrative editor could not load. Your original document is preserved."
|
|
259
|
+
) }),
|
|
260
|
+
/* @__PURE__ */ jsx(
|
|
261
|
+
RichEditor,
|
|
262
|
+
{
|
|
263
|
+
ref: richEditor,
|
|
264
|
+
value: body,
|
|
265
|
+
onChange,
|
|
266
|
+
onError: () => {
|
|
267
|
+
status.current.loadFailed = true;
|
|
268
|
+
setLoadFailed(true);
|
|
269
|
+
},
|
|
270
|
+
onReady: (next) => {
|
|
271
|
+
status.current.editor = next;
|
|
272
|
+
setEditor(next);
|
|
273
|
+
},
|
|
274
|
+
disabled: disabled || loadFailed || editor === null,
|
|
275
|
+
"aria-label": m("Encounter narrative"),
|
|
276
|
+
editorKits,
|
|
277
|
+
className: "encounter-mdy-editor"
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
] });
|
|
281
|
+
});
|
|
282
|
+
EncounterMdyEditor.displayName = "EncounterMdyEditor";
|
|
283
|
+
|
|
284
|
+
export { EncounterMdyEditor };
|
|
285
|
+
//# sourceMappingURL=EncounterMdyEditor-3SQY4MK2.js.map
|
|
286
|
+
//# sourceMappingURL=EncounterMdyEditor-3SQY4MK2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/RichEditor/mdyEditorKit.ts","../src/components/EncounterVisit/EncounterMdyEditor.tsx"],"names":["EncounterMdyEditor"],"mappings":"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","file":"EncounterMdyEditor-3SQY4MK2.js","sourcesContent":["import { Extension, type CoreEditor, type EditorKit } from '@kerebron/editor';\nimport type { Node as ProseMirrorNode } from 'prosemirror-model';\nimport { Plugin, PluginKey, type Transaction } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport { MDY_PROJECTION_META } from './mdyTransaction';\nexport { MDY_PROJECTION_META } from './mdyTransaction';\n\nexport interface MdyEditorOptions {\n /** Only links to fields in the host's data index are protected. */\n getFieldIds: () => ReadonlySet<string>;\n getFieldLabel?: (id: string) => string | undefined;\n onFieldActivate: (id: string) => void;\n isDisabled?: () => boolean;\n}\n\nexport interface MdyFieldSpan {\n id: string;\n from: number;\n to: number;\n}\n\nexport interface MdyFieldProjection {\n id: string;\n display: string;\n label?: string;\n}\n\n/** MDY links have field semantics only when their target exists in the data. */\nfunction linkedFieldId(href: unknown, fieldIds: ReadonlySet<string>) {\n if (typeof href !== 'string') return null;\n const id = href.startsWith('mdy:')\n ? href.slice(4)\n : href.startsWith('#')\n ? href.slice(1)\n : '';\n return fieldIds.has(id) ? id : null;\n}\n\n/** Merge neighboring text nodes, including differently formatted link text. */\nexport function getMdyFieldSpans(\n doc: ProseMirrorNode,\n fieldIds: ReadonlySet<string>\n): MdyFieldSpan[] {\n const spans: MdyFieldSpan[] = [];\n doc.descendants((node, pos) => {\n if (!node.isInline) return;\n const mark = node.marks.find((candidate) => candidate.type.name === 'link');\n let id = linkedFieldId(mark?.attrs.href, fieldIds);\n const previous = spans[spans.length - 1];\n // Kerebron's inline-HTML parser imports <br> without the surrounding link\n // mark. Keep those breaks inside a single protected field projection.\n if (\n !id &&\n (node.type.name === 'br' || node.type.name === 'softbreak') &&\n previous?.to === pos\n ) {\n let nextPos = pos + node.nodeSize;\n let next = doc.nodeAt(nextPos);\n while (\n next &&\n (next.type.name === 'br' || next.type.name === 'softbreak')\n ) {\n nextPos += next.nodeSize;\n next = doc.nodeAt(nextPos);\n }\n const nextMark = next?.marks.find(\n (candidate) => candidate.type.name === 'link'\n );\n if (linkedFieldId(nextMark?.attrs.href, fieldIds) === previous.id)\n id = previous.id;\n }\n if (!id) return;\n if (previous?.id === id && previous.to === pos) {\n previous.to = pos + node.nodeSize;\n } else {\n spans.push({ id, from: pos, to: pos + node.nodeSize });\n }\n });\n return spans;\n}\n\n/** Refresh only linked data in the live document, leaving authored prose intact. */\nexport function refreshMdyFieldProjections(\n editor: CoreEditor,\n fields: readonly MdyFieldProjection[]\n): boolean {\n const byId = new Map(fields.map((field) => [field.id, field.display]));\n const state = editor.view.state;\n const spans = getMdyFieldSpans(state.doc, new Set(byId.keys()));\n const transaction = state.tr;\n for (const span of spans.reverse()) {\n const display = byId.get(span.id)!;\n const current = state.doc.textBetween(span.from, span.to, '', '\\n');\n const oldMarks = state.doc.nodeAt(span.from)?.marks ?? [];\n const link = oldMarks.find((mark) => mark.type.name === 'link');\n if (!link) continue;\n // Kerebron 0.8.12's link serializer gathers text tokens and drops inline\n // breaks. Its existing mdTemplate attribute emits this safe MDY label as\n // one link, preserving multiline projections without an upstream patch.\n const label = display\n .split(/\\r?\\n/)\n .map((line) =>\n line\n .replace(/&/g, '&')\n .replace(/\\$/g, '$')\n .replace(/[\\\\[\\]`*_~<>]/g, '\\\\$&')\n )\n .join('<br>');\n const template = `[${label}](${link.attrs.href})`;\n let looseBreak = false;\n state.doc.nodesBetween(span.from, span.to, (node) => {\n if (\n (node.type.name === 'br' || node.type.name === 'softbreak') &&\n !node.marks.some((mark) => mark.type.name === 'link')\n )\n looseBreak = true;\n });\n if (\n current === display &&\n !looseBreak &&\n link.attrs.mdTemplate === template\n )\n continue;\n const marks = oldMarks.map((mark) =>\n mark.type.name === 'link'\n ? mark.type.create({ ...mark.attrs, mdTemplate: template })\n : mark\n );\n const breakType = state.schema.nodes.br ?? state.schema.nodes.softbreak;\n const replacement: ProseMirrorNode[] = [];\n display.split(/\\r?\\n/).forEach((line, index) => {\n if (index && breakType)\n replacement.push(breakType.create(null, null, marks));\n if (line) replacement.push(state.schema.text(line, marks));\n });\n transaction.replaceWith(span.from, span.to, replacement);\n }\n if (!transaction.docChanged) return false;\n transaction.setMeta(MDY_PROJECTION_META, true);\n transaction.setMeta('addToHistory', false);\n editor.view.dispatch(transaction);\n return true;\n}\n\n/**\n * Protect each existing field projection from text edits or link removal.\n * A writer may delete a whole projection; its underlying data stays intact.\n * Inspect every step so paste, drag/drop, IME and toolbar commands obey the\n * same rule as typing. Programmatic document loads bypass this edit guard.\n */\nexport function canEditMdyTransaction(\n transaction: Transaction,\n fieldIds: ReadonlySet<string>\n): boolean {\n if (!transaction.docChanged) return true;\n for (let index = 0; index < transaction.steps.length; index += 1) {\n const before = transaction.docs[index];\n const after = transaction.docs[index + 1] ?? transaction.doc;\n const map = transaction.steps[index].getMap();\n const spans = getMdyFieldSpans(before, fieldIds);\n const step = transaction.steps[index].toJSON();\n if (\n (step.stepType === 'addMark' || step.stepType === 'removeMark') &&\n step.mark?.type === 'link' &&\n spans.some((span) => step.from < span.to && step.to > span.from)\n ) {\n return false;\n }\n const removed = new Set<MdyFieldSpan>();\n let allowed = true;\n\n map.forEach((oldStart, oldEnd, newStart, newEnd) => {\n for (const span of spans) {\n if (oldStart === oldEnd) {\n if (oldStart > span.from && oldStart < span.to) allowed = false;\n } else if (oldStart < span.to && oldEnd > span.from) {\n if (\n oldStart <= span.from &&\n oldEnd >= span.to &&\n (newStart === newEnd || after.textBetween(newStart, newEnd) === '')\n ) {\n removed.add(span);\n } else {\n allowed = false;\n }\n }\n }\n });\n if (!allowed) return false;\n\n // Mark-only steps have empty maps. Ensure they cannot detach a protected\n // projection from its id, while allowing harmless text formatting.\n const nextSpans = getMdyFieldSpans(after, fieldIds);\n for (const span of spans) {\n if (removed.has(span)) continue;\n const from = map.map(span.from, 1);\n const to = map.map(span.to, -1);\n if (\n before.textBetween(span.from, span.to) !==\n after.textBetween(from, to) ||\n !nextSpans.some(\n (next) => next.id === span.id && next.from === from && next.to === to\n )\n ) {\n return false;\n }\n }\n }\n return true;\n}\n\nconst mdyPluginKey = new PluginKey('mdy-field-links');\n\nexport function createMdyFieldPlugin(options: MdyEditorOptions): Plugin {\n const activate = (id: string, event: Event) => {\n event.preventDefault();\n if (!options.isDisabled?.()) options.onFieldActivate(id);\n return true;\n };\n const targetId = (event: Event) => {\n const element = event.target;\n const chip =\n element instanceof Element ? element.closest('[data-mdy-field]') : null;\n const id = chip?.getAttribute('data-mdy-field');\n return id && options.getFieldIds().has(id) ? id : null;\n };\n\n return new Plugin({\n key: mdyPluginKey,\n filterTransaction: (transaction) =>\n transaction.getMeta(MDY_PROJECTION_META) === true ||\n canEditMdyTransaction(transaction, options.getFieldIds()),\n props: {\n decorations: (state) =>\n DecorationSet.create(\n state.doc,\n getMdyFieldSpans(state.doc, options.getFieldIds()).map((span) =>\n Decoration.inline(span.from, span.to, {\n class: 'encounter-mdy-field',\n 'data-mdy-field': span.id,\n role: 'button',\n tabindex: '0',\n 'aria-label': `Linked field: ${options.getFieldLabel?.(span.id) ?? span.id}. Activate to edit in the form.`,\n 'aria-disabled': options.isDisabled?.() ? 'true' : 'false',\n style:\n 'background:rgba(59,130,246,.12);border-radius:.2em;padding:0 .15em;cursor:pointer;text-decoration:underline;text-underline-offset:.15em',\n })\n )\n ),\n handleDOMEvents: {\n click: (_view, event) => {\n const id = targetId(event);\n return id ? activate(id, event) : false;\n },\n },\n handleKeyDown: (view, event) => {\n const focusedId = targetId(event);\n if (focusedId && (event.key === 'Enter' || event.key === ' ')) {\n return activate(focusedId, event);\n }\n if (event.key !== 'Enter') return false;\n const { from, to } = view.state.selection;\n const span = getMdyFieldSpans(\n view.state.doc,\n options.getFieldIds()\n ).find((candidate) => from >= candidate.from && to <= candidate.to);\n return span ? activate(span.id, event) : false;\n },\n },\n });\n}\n\nclass MdyFieldExtension extends Extension {\n name = 'mdy-field-links';\n constructor(private readonly options: MdyEditorOptions) {\n super();\n }\n\n override getProseMirrorPlugins() {\n return [createMdyFieldPlugin(this.options)];\n }\n}\n\nclass MdyEditorKit implements EditorKit {\n name = 'mdy-field-links';\n constructor(private readonly options: MdyEditorOptions) {}\n\n getExtensions() {\n return [new MdyFieldExtension(this.options)];\n }\n}\n\nexport function createMdyEditorKit(options: MdyEditorOptions): EditorKit {\n return new MdyEditorKit(options);\n}\n","'use client';\n\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { CoreEditor } from '@kerebron/editor';\nimport { RichEditor, type RichEditorHandle } from '../RichEditor/RichEditor';\nimport { useEncounterMessages } from './messages';\nimport {\n createMdyEditorKit,\n refreshMdyFieldProjections,\n type MdyFieldProjection,\n} from '../RichEditor/mdyEditorKit';\n\nexport interface EncounterMdyEditorProps {\n /** MDY body only. The host retains and updates the YAML data separately. */\n body: string;\n fields?: MdyFieldProjection[];\n fieldIds?: string[];\n onChange: (body: string) => void;\n onFieldActivate: (id: string) => void;\n disabled?: boolean;\n}\n\nexport type EncounterMdyEditorHandle = RichEditorHandle;\n\n/** Free prose and headings, with form-backed MDY spans protected from typing. */\nexport const EncounterMdyEditor = forwardRef<\n EncounterMdyEditorHandle,\n EncounterMdyEditorProps\n>(function EncounterMdyEditor(\n { body, fields = [], fieldIds, onChange, onFieldActivate, disabled = false },\n ref\n) {\n const m = useEncounterMessages();\n const [editor, setEditor] = useState<CoreEditor | null>(null);\n const [loadFailed, setLoadFailed] = useState(false);\n const richEditor = useRef<RichEditorHandle>(null);\n const status = useRef({ editor, loadFailed, body });\n status.current = { editor, loadFailed, body };\n // The kit mounts once, while the canonical data index and activation target\n // may change as the user switches the form or updates its responses.\n const live = useRef({\n fieldIds: new Set(fieldIds),\n onFieldActivate,\n disabled: disabled || loadFailed || editor === null,\n });\n live.current = {\n fieldIds: new Set(fieldIds ?? fields.map((field) => field.id)),\n onFieldActivate,\n disabled: disabled || loadFailed || editor === null,\n };\n const fieldsRef = useRef(fields);\n fieldsRef.current = fields;\n useImperativeHandle(\n ref,\n () => ({\n getContent: async () => {\n // Until setup succeeds, editing is disabled and the host's exact body\n // is the only draft. An initial grammar/document-load failure can\n // therefore leave RichEdit without trying to serialize a failed load.\n // Once ready, retain read failures so unpublished prose is never lost.\n if (status.current.loadFailed && !status.current.editor)\n return status.current.body;\n return richEditor.current\n ? richEditor.current.getContent()\n : status.current.body;\n },\n focus: () => {\n if (!status.current.loadFailed) richEditor.current?.focus();\n },\n }),\n []\n );\n const editorKits = useMemo(\n () => [\n createMdyEditorKit({\n getFieldIds: () => live.current.fieldIds,\n getFieldLabel: (id) =>\n fieldsRef.current.find((field) => field.id === id)?.label,\n onFieldActivate: (id) => live.current.onFieldActivate(id),\n isDisabled: () => live.current.disabled,\n }),\n ],\n []\n );\n useEffect(() => {\n if (!editor) return;\n const refresh = () => refreshMdyFieldProjections(editor, fieldsRef.current);\n const loaded = () => refresh();\n editor.addEventListener('doc:loaded', loaded);\n refresh();\n return () => editor.removeEventListener('doc:loaded', loaded);\n }, [editor, fields]);\n\n return (\n <>\n {loadFailed && (\n <p role=\"alert\">\n {m(\n 'The narrative editor could not load. Your original document is preserved.'\n )}\n </p>\n )}\n <RichEditor\n ref={richEditor}\n value={body}\n onChange={onChange}\n onError={() => {\n status.current.loadFailed = true;\n setLoadFailed(true);\n }}\n onReady={(next) => {\n status.current.editor = next;\n setEditor(next);\n }}\n disabled={disabled || loadFailed || editor === null}\n aria-label={m('Encounter narrative')}\n editorKits={editorKits}\n className=\"encounter-mdy-editor\"\n />\n </>\n );\n});\n\nEncounterMdyEditor.displayName = 'EncounterMdyEditor';\n"]}
|