@qoretechnologies/reqraft 0.10.62-pr.141.g7591ef9 → 0.10.62-pr.141.gd67d7d6
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/dist/components/form/fields/rich-text/RichText.d.ts +17 -6
- package/dist/components/form/fields/rich-text/RichText.d.ts.map +1 -1
- package/dist/components/form/fields/rich-text/RichText.js +90 -15
- package/dist/components/form/fields/rich-text/RichText.js.map +1 -1
- package/dist/helpers/choiceChip.d.ts +54 -3
- package/dist/helpers/choiceChip.d.ts.map +1 -1
- package/dist/helpers/choiceChip.js +100 -13
- package/dist/helpers/choiceChip.js.map +1 -1
- package/package.json +1 -1
- package/src/components/form/engine/FormEngine.stories.tsx +97 -0
- package/src/components/form/fields/rich-text/RichText.stories.tsx +139 -1
- package/src/components/form/fields/rich-text/RichText.tsx +130 -13
- package/src/helpers/choiceChip.ts +137 -8
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { IReqoreRichTextEditorProps } from '@qoretechnologies/reqore/dist/components/RichTextEditor';
|
|
3
3
|
import { IReqoreFormTemplates } from '@qoretechnologies/reqore/dist/components/Textarea';
|
|
4
4
|
import { IQorusAllowedValue } from '@qoretechnologies/ts-toolkit';
|
|
5
|
+
import { IChoiceChipBehavior } from '../../../../helpers/choiceChip';
|
|
5
6
|
export interface IRichTextFormFieldProps extends Omit<IReqoreRichTextEditorProps, 'onChange' | 'value' | 'tags' | 'actions'> {
|
|
6
7
|
/**
|
|
7
8
|
* A form field's OWN chips — not the editor's template catalogue, which this
|
|
@@ -31,13 +32,23 @@ export interface IRichTextFormFieldProps extends Omit<IReqoreRichTextEditorProps
|
|
|
31
32
|
singleLine?: boolean;
|
|
32
33
|
/**
|
|
33
34
|
* The choices the field offers, when it offers any. A value that IS one of
|
|
34
|
-
* them — the whole string, as picked from the field's suggestions
|
|
35
|
-
* as
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
35
|
+
* them — the whole string, as picked from the field's suggestions, or a
|
|
36
|
+
* document of nothing but that string, as an edit of it stores — is drawn as
|
|
37
|
+
* one chip named from the choice (`general` rather than `C07ERBFS0P6`), and
|
|
38
|
+
* is still emitted as that value: the chip's own value is the choice's, and a
|
|
39
|
+
* document that is nothing but the chip reads back as it. A field spreads
|
|
40
|
+
* its schema here, so this is the schema's own key.
|
|
39
41
|
*/
|
|
40
42
|
allowed_values?: IQorusAllowedValue[];
|
|
43
|
+
/**
|
|
44
|
+
* What a choice chip does when the author acts on it — Backspace right after
|
|
45
|
+
* it, a click on it. By default each opens the chip into its value as plain
|
|
46
|
+
* text, the cursor at the end, so one letter of what was chosen can be
|
|
47
|
+
* changed; see `IChoiceChipBehavior` for the alternatives. Text that is again
|
|
48
|
+
* exactly one of the choices becomes its chip when the author leaves the
|
|
49
|
+
* field — not while typing, where a choice can be the start of a longer value.
|
|
50
|
+
*/
|
|
51
|
+
choiceChip?: IChoiceChipBehavior;
|
|
41
52
|
/**
|
|
42
53
|
* With `valueFormat: 'text'`: the token grammar the value's references are
|
|
43
54
|
* WRITTEN in, when the host speaks one of its own.
|
|
@@ -62,5 +73,5 @@ export interface IRichTextFormFieldProps extends Omit<IReqoreRichTextEditorProps
|
|
|
62
73
|
* Exported so the mapping is assertable without rendering a Slate editor.
|
|
63
74
|
*/
|
|
64
75
|
export declare const getChipTooltipDescriptions: (templates?: IReqoreFormTemplates) => Record<string, string>;
|
|
65
|
-
export declare const RichTextFormField: import("react").MemoExoticComponent<({ value, onChange, allowTemplates, templates, valueFormat, singleLine, templateToken, allowed_values, ...rest }: IRichTextFormFieldProps) => import("react/jsx-runtime").JSX.Element>;
|
|
76
|
+
export declare const RichTextFormField: import("react").MemoExoticComponent<({ value, onChange, allowTemplates, templates, valueFormat, singleLine, templateToken, allowed_values, choiceChip, ...rest }: IRichTextFormFieldProps) => import("react/jsx-runtime").JSX.Element>;
|
|
66
77
|
//# sourceMappingURL=RichText.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichText.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/fields/rich-text/RichText.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,0BAA0B,
|
|
1
|
+
{"version":3,"file":"RichText.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/fields/rich-text/RichText.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,0BAA0B,EAG3B,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AAGzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAOlE,OAAO,EAOL,mBAAmB,EAGpB,MAAM,gCAAgC,CAAC;AAmBxC,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CACnD,0BAA0B,EAC1B,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAC1C;IACC;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,0BAA0B,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAClC,gFAAgF;IAChF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACtC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,eACzB,oBAAoB,KAC/B,OAAO,MAAM,EAAE,MAAM,CA0BvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,oKAW3B,uBAAuB,6CA0XxB,CAAC"}
|
|
@@ -28,6 +28,7 @@ var RichTextEditor_1 = require("@qoretechnologies/reqore/dist/components/RichTex
|
|
|
28
28
|
var lodash_1 = require("lodash");
|
|
29
29
|
var react_1 = require("react");
|
|
30
30
|
var react_use_1 = require("react-use");
|
|
31
|
+
var slate_react_1 = require("slate-react");
|
|
31
32
|
var emittedValues_1 = require("../emittedValues");
|
|
32
33
|
var choiceChip_1 = require("../../../../helpers/choiceChip");
|
|
33
34
|
var singleLineString_1 = require("../../../../helpers/singleLineString");
|
|
@@ -73,8 +74,12 @@ var getChipTooltipDescriptions = function (templates) {
|
|
|
73
74
|
exports.getChipTooltipDescriptions = getChipTooltipDescriptions;
|
|
74
75
|
exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
75
76
|
var _b, _c;
|
|
76
|
-
var value = _a.value, onChange = _a.onChange, allowTemplates = _a.allowTemplates, templates = _a.templates, _d = _a.valueFormat, valueFormat = _d === void 0 ? 'richtext' : _d, singleLine = _a.singleLine, templateToken = _a.templateToken, allowed_values = _a.allowed_values, rest = __rest(_a, ["value", "onChange", "allowTemplates", "templates", "valueFormat", "singleLine", "templateToken", "allowed_values"]);
|
|
77
|
+
var value = _a.value, onChange = _a.onChange, allowTemplates = _a.allowTemplates, templates = _a.templates, _d = _a.valueFormat, valueFormat = _d === void 0 ? 'richtext' : _d, singleLine = _a.singleLine, templateToken = _a.templateToken, allowed_values = _a.allowed_values, choiceChip = _a.choiceChip, rest = __rest(_a, ["value", "onChange", "allowTemplates", "templates", "valueFormat", "singleLine", "templateToken", "allowed_values", "choiceChip"]);
|
|
77
78
|
var isText = valueFormat === 'text';
|
|
79
|
+
/* The Slate editor behind Reqore's, for the two chip actions below: both
|
|
80
|
+
rewrite the document in place, which the editor's props cannot. */
|
|
81
|
+
var editorRef = (0, react_1.useRef)(null);
|
|
82
|
+
var chipBehavior = __assign(__assign({}, choiceChip_1.DEFAULT_CHOICE_CHIP_BEHAVIOR), choiceChip);
|
|
78
83
|
/* The document the editor shows for a value: a choice by its chip, a text
|
|
79
84
|
with its references as chips, a document as it is. */
|
|
80
85
|
var toLocal = function (next) {
|
|
@@ -87,6 +92,18 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
87
92
|
return choice ? (0, choiceChip_1.choiceToNodes)(choice) : next;
|
|
88
93
|
};
|
|
89
94
|
var _e = (0, react_1.useState)(function () { return toLocal(value); }), localValue = _e[0], setLocalValue = _e[1];
|
|
95
|
+
/* What a value stands for: the choice's value when the value is that choice
|
|
96
|
+
by any spelling — the plain string, the chip, a document of just the text —
|
|
97
|
+
else the value itself. Values are compared by this, so opening a chip, or
|
|
98
|
+
typing its id back, is not a change to the value. */
|
|
99
|
+
var standsFor = function (next) {
|
|
100
|
+
var chip = (0, choiceChip_1.choiceValueOfNodes)(next);
|
|
101
|
+
if (chip !== undefined) {
|
|
102
|
+
return chip;
|
|
103
|
+
}
|
|
104
|
+
var choice = (0, choiceChip_1.choiceForValue)(next, allowed_values);
|
|
105
|
+
return choice ? (0, choiceChip_1.choiceValue)(choice) : next;
|
|
106
|
+
};
|
|
90
107
|
/* In text mode, the string the editor's document stands for. The value that
|
|
91
108
|
comes back from the parent is usually that same string, and rebuilding the
|
|
92
109
|
document from it would hand the editor a new tree on every keystroke —
|
|
@@ -97,7 +114,6 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
97
114
|
them away. See `EmittedValues`. */
|
|
98
115
|
var emitted = (0, emittedValues_1.useEmittedValues)(lodash_1.isEqual);
|
|
99
116
|
(0, react_1.useEffect)(function () {
|
|
100
|
-
var _a;
|
|
101
117
|
if (emitted.isEcho(isText ? String(value !== null && value !== void 0 ? value : '') : value)) {
|
|
102
118
|
return;
|
|
103
119
|
}
|
|
@@ -109,9 +125,9 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
109
125
|
}
|
|
110
126
|
return;
|
|
111
127
|
}
|
|
112
|
-
// Compared as what
|
|
113
|
-
//
|
|
114
|
-
if (
|
|
128
|
+
// Compared as what each stands for: a lone choice chip IS the value it
|
|
129
|
+
// draws, so the value coming back is not a change to it.
|
|
130
|
+
if (!(0, lodash_1.isEqual)(standsFor(value), standsFor(localValue))) {
|
|
115
131
|
setLocalValue(toLocal(value));
|
|
116
132
|
}
|
|
117
133
|
}, [JSON.stringify(value)]);
|
|
@@ -143,7 +159,7 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
143
159
|
// A document that is nothing but one choice chip is emitted as the
|
|
144
160
|
// choice's value — what was stored and what the server resolves.
|
|
145
161
|
var next = (_a = (0, choiceChip_1.choiceValueOfNodes)(localValue)) !== null && _a !== void 0 ? _a : localValue;
|
|
146
|
-
if (!(0, lodash_1.isEqual)(next, value)) {
|
|
162
|
+
if (!(0, lodash_1.isEqual)(standsFor(next), standsFor(value))) {
|
|
147
163
|
emitted.record(next);
|
|
148
164
|
onChange === null || onChange === void 0 ? void 0 : onChange(next);
|
|
149
165
|
}
|
|
@@ -180,6 +196,39 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
180
196
|
var descriptionByValue = (0, react_1.useMemo)(function () { return (0, exports.getChipTooltipDescriptions)(templates); }, [
|
|
181
197
|
JSON.stringify(templates),
|
|
182
198
|
]);
|
|
199
|
+
/* Opens a choice chip into its value as text and puts the cursor there.
|
|
200
|
+
A click on the chip — a non-editable node — need not have given the
|
|
201
|
+
editor focus, so focus is asked of Slate, which places the DOM caret where
|
|
202
|
+
the selection is and focuses after; but only once the text the chip became
|
|
203
|
+
is rendered (the effect below), since Slate resolves the caret through the
|
|
204
|
+
rendered DOM. Asked any earlier it lost: a DOM `focus()` before the
|
|
205
|
+
transform let the browser put the caret at the editor's start and the
|
|
206
|
+
`selectionchange` it raised beat the render, so the next key typed landed
|
|
207
|
+
there; asked on the next frame, the frame came before React's commit
|
|
208
|
+
often enough. An editor that already has focus (Backspace came from it)
|
|
209
|
+
is returned at once, and its own render puts the caret where the
|
|
210
|
+
selection is. */
|
|
211
|
+
var focusOnceRendered = (0, react_1.useRef)(false);
|
|
212
|
+
var openChoiceChip = (0, react_1.useCallback)(function (path) {
|
|
213
|
+
var editor = editorRef.current;
|
|
214
|
+
if (editor && path && (0, choiceChip_1.unwrapChoiceChip)(editor, path)) {
|
|
215
|
+
focusOnceRendered.current = true;
|
|
216
|
+
}
|
|
217
|
+
}, []);
|
|
218
|
+
(0, react_1.useEffect)(function () {
|
|
219
|
+
var editor = editorRef.current;
|
|
220
|
+
if (!focusOnceRendered.current || !editor) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
focusOnceRendered.current = false;
|
|
224
|
+
try {
|
|
225
|
+
slate_react_1.ReactEditor.toDOMNode(editor, editor);
|
|
226
|
+
slate_react_1.ReactEditor.focus(editor);
|
|
227
|
+
}
|
|
228
|
+
catch (_a) {
|
|
229
|
+
// Not mounted in a document — nothing to focus.
|
|
230
|
+
}
|
|
231
|
+
}, [localValue]);
|
|
183
232
|
var handleGetTagProps = (0, react_1.useCallback)(function (tag) {
|
|
184
233
|
var _a, _b, _c, _d, _e, _f;
|
|
185
234
|
var tagValue = (_a = tag.value) === null || _a === void 0 ? void 0 : _a.toString();
|
|
@@ -189,11 +238,9 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
189
238
|
/* One of the field's own choices, drawn by the name it was picked by;
|
|
190
239
|
what it stands for on hover. */
|
|
191
240
|
if ((_b = tag.metadata) === null || _b === void 0 ? void 0 : _b.allowedValue) {
|
|
192
|
-
return {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
tooltip: (_d = tag.metadata) === null || _d === void 0 ? void 0 : _d.description,
|
|
196
|
-
};
|
|
241
|
+
return __assign({ icon: 'ListCheck', label: (_c = tag.label) !== null && _c !== void 0 ? _c : tagValue, tooltip: (_d = tag.metadata) === null || _d === void 0 ? void 0 : _d.description }, (chipBehavior.click === 'unwrap' ?
|
|
242
|
+
{ onClick: function () { return openChoiceChip(editorRef.current ? (0, choiceChip_1.pathOfNode)(editorRef.current, tag) : undefined); } }
|
|
243
|
+
: {}));
|
|
197
244
|
}
|
|
198
245
|
/* A reference in a string is drawn exactly as the collapsed row draws the
|
|
199
246
|
same value (`ReadOnlyTemplateTag`): named from the catalogue, its
|
|
@@ -237,14 +284,42 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
237
284
|
: undefined }, (0, templates_1.getTemplateTagStyle)(tag.metadata));
|
|
238
285
|
}
|
|
239
286
|
return {};
|
|
240
|
-
}, [descriptionByValue, renderMarkdown, isText, templates]);
|
|
287
|
+
}, [descriptionByValue, renderMarkdown, isText, templates, chipBehavior.click, openChoiceChip]);
|
|
288
|
+
/* Leaving the field: text that is exactly one of the choices becomes its
|
|
289
|
+
chip again, as the picker would have drawn it. Only here, never while
|
|
290
|
+
typing — a choice can be the start of a longer value, and a chip drawn
|
|
291
|
+
under the cursor would swallow it. */
|
|
292
|
+
var handleBlur = (0, react_1.useCallback)(function (event) {
|
|
293
|
+
var _a, _b;
|
|
294
|
+
var shown = isText ? lastTextRef.current : localValue;
|
|
295
|
+
if ((0, choiceChip_1.choiceForValue)(shown, allowed_values)) {
|
|
296
|
+
setLocalValue(toLocal(shown));
|
|
297
|
+
}
|
|
298
|
+
(_b = (_a = rest).onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
299
|
+
}, [isText, localValue, choiceKey, rest.onBlur]);
|
|
241
300
|
var handleKeyDown = (0, react_1.useCallback)(function (event) {
|
|
242
301
|
var _a, _b;
|
|
243
302
|
if (isText && singleLine && event.key === 'Enter') {
|
|
244
303
|
event.preventDefault();
|
|
245
304
|
}
|
|
305
|
+
/* Backspace right after a choice chip opens it rather than deleting it,
|
|
306
|
+
when so configured. Stopped here, at keydown, so the browser raises no
|
|
307
|
+
`beforeinput` for the editor to delete the chip by. */
|
|
308
|
+
if (event.key === 'Backspace' && chipBehavior.backspace === 'unwrap' && editorRef.current) {
|
|
309
|
+
var path = (0, choiceChip_1.choiceChipAtCursor)(editorRef.current);
|
|
310
|
+
if (path) {
|
|
311
|
+
event.preventDefault();
|
|
312
|
+
openChoiceChip(path);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
246
315
|
(_b = (_a = rest).onKeyDown) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
247
|
-
}, [
|
|
316
|
+
}, [
|
|
317
|
+
isText,
|
|
318
|
+
singleLine,
|
|
319
|
+
chipBehavior.backspace,
|
|
320
|
+
openChoiceChip,
|
|
321
|
+
rest.onKeyDown,
|
|
322
|
+
]);
|
|
248
323
|
var tags = (0, react_1.useMemo)(function () {
|
|
249
324
|
var _tags = {};
|
|
250
325
|
if ((0, lodash_1.size)(templates === null || templates === void 0 ? void 0 : templates.items) && allowTemplates) {
|
|
@@ -282,9 +357,9 @@ exports.RichTextFormField = (0, react_1.memo)(function (_a) {
|
|
|
282
357
|
editor's `tags` is the template catalogue this component computes. */
|
|
283
358
|
var editorProps = __assign({}, rest);
|
|
284
359
|
delete editorProps.tags;
|
|
285
|
-
return ((0, jsx_runtime_1.jsx)(RichTextEditor_1.ReqoreRichTextEditor, __assign({ value: formattedValue, onChange: handleChange }, editorProps, { tagsListProps: __assign({ useTargetWidth: true, minWidth: '300px', maxWidth: '600px', listCustomTheme: {
|
|
360
|
+
return ((0, jsx_runtime_1.jsx)(RichTextEditor_1.ReqoreRichTextEditor, __assign({ ref: editorRef, value: formattedValue, onChange: handleChange }, editorProps, { tagsListProps: __assign({ useTargetWidth: true, minWidth: '300px', maxWidth: '600px', listCustomTheme: {
|
|
286
361
|
main: '#1b151f',
|
|
287
|
-
} }, (rest.tagsListProps || {})), getTagProps: handleGetTagProps, tags: tags, panelProps: { fluid: true, style: __assign({ minWidth: '150px' }, (_c = rest.panelProps) === null || _c === void 0 ? void 0 : _c.style) }, readOnly: readOnly, onKeyDown: handleKeyDown,
|
|
362
|
+
} }, (rest.tagsListProps || {})), getTagProps: handleGetTagProps, tags: tags, panelProps: { fluid: true, style: __assign({ minWidth: '150px' }, (_c = rest.panelProps) === null || _c === void 0 ? void 0 : _c.style) }, readOnly: readOnly, onKeyDown: handleKeyDown, onBlur: handleBlur,
|
|
288
363
|
/* A form field carries no document toolbar. Styling was already off, so
|
|
289
364
|
the bar held only undo and redo — drawn by Reqore as a panel as wide as
|
|
290
365
|
the tag list, which under a field reads as an empty 600px menu with two
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichText.js","sourceRoot":"","sources":["../../../../../src/components/form/fields/rich-text/RichText.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RichText.js","sourceRoot":"","sources":["../../../../../src/components/form/fields/rich-text/RichText.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IQorusAllowedValue } from '@qoretechnologies/ts-toolkit';
|
|
2
|
+
import { Editor, Path } from 'slate';
|
|
2
3
|
/**
|
|
3
4
|
* A value that IS one of the field's own choices, drawn as that choice.
|
|
4
5
|
*
|
|
@@ -25,10 +26,18 @@ export interface IChoiceChipNode {
|
|
|
25
26
|
text: '';
|
|
26
27
|
}];
|
|
27
28
|
}
|
|
29
|
+
/** The choice's value as the plain string it is; it arrives in the form engine's `{type, value}` envelope. */
|
|
30
|
+
export declare const choiceValue: (choice: IQorusAllowedValue) => string;
|
|
28
31
|
/**
|
|
29
|
-
* The
|
|
30
|
-
*
|
|
31
|
-
|
|
32
|
+
* The text a document is, when it is one paragraph of plain text and nothing
|
|
33
|
+
* else; `undefined` for anything more — a chip, a mark, a second paragraph.
|
|
34
|
+
*/
|
|
35
|
+
export declare const plainTextOfNodes: (nodes: unknown) => string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The choice a value is: a whole plain string the field offers, or a document
|
|
38
|
+
* that is one paragraph of exactly that text — which is what an edit of the
|
|
39
|
+
* chip stores, so an id typed back is the choice it was. A string or document
|
|
40
|
+
* holding anything more is the author's own text and is never a choice.
|
|
32
41
|
*/
|
|
33
42
|
export declare const choiceForValue: (value: unknown, choices?: IQorusAllowedValue[]) => IQorusAllowedValue | undefined;
|
|
34
43
|
/** The one-chip document that draws a choice by its name. */
|
|
@@ -38,10 +47,52 @@ export declare const choiceToNodes: (choice: IQorusAllowedValue) => {
|
|
|
38
47
|
text: string;
|
|
39
48
|
} | IChoiceChipNode)[];
|
|
40
49
|
}[];
|
|
50
|
+
export declare const isChoiceChip: (node: unknown) => node is IChoiceChipNode;
|
|
41
51
|
/**
|
|
42
52
|
* The value a document is, when the document is one choice chip and nothing
|
|
43
53
|
* else; `undefined` when the author has written anything around it, in which
|
|
44
54
|
* case the document itself is the value.
|
|
45
55
|
*/
|
|
46
56
|
export declare const choiceValueOfNodes: (nodes: unknown) => string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* What a choice chip does when the author acts on it, by action.
|
|
59
|
+
*
|
|
60
|
+
* The chip is a void: it holds no text of its own, so a key or a click on it
|
|
61
|
+
* has nothing to land in, and an author who wants to change one letter of the
|
|
62
|
+
* value it draws (`C07ERBFS0P6` to `C07ERBFS0P7`) has no way in unless the
|
|
63
|
+
* chip opens. Each action is configurable, and the default is the one that
|
|
64
|
+
* opens it: a creatable choice is the author's to edit.
|
|
65
|
+
*/
|
|
66
|
+
export interface IChoiceChipBehavior {
|
|
67
|
+
/**
|
|
68
|
+
* Backspace with the cursor right after the chip. `unwrap` (the default)
|
|
69
|
+
* turns the chip into its value as plain text, the cursor at the end of it,
|
|
70
|
+
* for the author to edit; `remove` deletes it whole, as the editor deletes
|
|
71
|
+
* any other chip.
|
|
72
|
+
*/
|
|
73
|
+
backspace?: 'unwrap' | 'remove';
|
|
74
|
+
/**
|
|
75
|
+
* A click on the chip's body. `unwrap` (the default) turns the chip into its
|
|
76
|
+
* value as plain text, the cursor at the end of it; `cursor` only places the
|
|
77
|
+
* cursor after it, as a click on a template chip does.
|
|
78
|
+
*/
|
|
79
|
+
click?: 'unwrap' | 'cursor';
|
|
80
|
+
}
|
|
81
|
+
export declare const DEFAULT_CHOICE_CHIP_BEHAVIOR: Required<IChoiceChipBehavior>;
|
|
82
|
+
/** Where the node is in the document, by identity; the editor renders the document's own nodes, so a chip handed to a click handler is one of them. */
|
|
83
|
+
export declare const pathOfNode: (editor: Editor, node: unknown) => Path | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* The chip the cursor is on: right after it with nothing between, where
|
|
86
|
+
* Backspace would take it, or inside it, where the arrow keys can leave the
|
|
87
|
+
* cursor. Nothing when the selection spans text or sits anywhere else.
|
|
88
|
+
*/
|
|
89
|
+
export declare const choiceChipAtCursor: (editor: Editor) => Path | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Opens the chip at `path` into its value as plain text, the cursor at the
|
|
92
|
+
* end of the text: what the author read is what they chose, now editable
|
|
93
|
+
* letter by letter. The document is text from here on, and is stored as the
|
|
94
|
+
* field stores anything typed; it is drawn as a chip again only when it is
|
|
95
|
+
* read back as exactly one of the choices.
|
|
96
|
+
*/
|
|
97
|
+
export declare const unwrapChoiceChip: (editor: Editor, path: Path) => boolean;
|
|
47
98
|
//# sourceMappingURL=choiceChip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choiceChip.d.ts","sourceRoot":"","sources":["../../src/helpers/choiceChip.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAyB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"choiceChip.d.ts","sourceRoot":"","sources":["../../src/helpers/choiceChip.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAyB,MAAM,8BAA8B,CAAC;AACzF,OAAO,EAAE,MAAM,EAAQ,IAAI,EAAqB,MAAM,OAAO,CAAC;AAI9D;;;;;;;;;;;GAWG;AAEH,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,QAAQ,EAAE,CAAC;QAAE,IAAI,EAAE,EAAE,CAAA;KAAE,CAAC,CAAC;CAC1B;AAED,8GAA8G;AAC9G,eAAO,MAAM,WAAW,WAAY,kBAAkB,KAAG,MACR,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,UAAW,OAAO,KAAG,MAAM,GAAG,SAqB1D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,UAClB,OAAO,YACJ,kBAAkB,EAAE,KAC7B,kBAAkB,GAAG,SAUvB,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,aAAa,WAChB,kBAAkB,KACzB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,CAAC,EAAE,CAAA;CAAE,EAoBzE,CAAC;AAEF,eAAO,MAAM,YAAY,SAAU,OAAO,4BAIuC,CAAC;AAElF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,UAAW,OAAO,KAAG,MAAM,GAAG,SAa5D,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAChC;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC7B;AAED,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,mBAAmB,CAGtE,CAAC;AAEF,uJAAuJ;AACvJ,eAAO,MAAM,UAAU,WAAY,MAAM,QAAQ,OAAO,KAAG,IAAI,GAAG,SAWjE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,WAAY,MAAM,KAAG,IAAI,GAAG,SAqB1D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,WAAY,MAAM,iBAAe,OAc7D,CAAC"}
|
|
@@ -11,7 +11,8 @@ var __assign = (this && this.__assign) || function () {
|
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.choiceValueOfNodes = exports.choiceToNodes = exports.choiceForValue = exports.CHOICE_CHIP_META = void 0;
|
|
14
|
+
exports.unwrapChoiceChip = exports.choiceChipAtCursor = exports.pathOfNode = exports.DEFAULT_CHOICE_CHIP_BEHAVIOR = exports.choiceValueOfNodes = exports.isChoiceChip = exports.choiceToNodes = exports.choiceForValue = exports.plainTextOfNodes = exports.choiceValue = exports.CHOICE_CHIP_META = void 0;
|
|
15
|
+
var slate_1 = require("slate");
|
|
15
16
|
var allowedValues_1 = require("./allowedValues");
|
|
16
17
|
var options_1 = require("./options");
|
|
17
18
|
/**
|
|
@@ -28,25 +29,52 @@ var options_1 = require("./options");
|
|
|
28
29
|
*/
|
|
29
30
|
/** The marker a choice chip carries, so it is told apart from a template reference. */
|
|
30
31
|
exports.CHOICE_CHIP_META = 'allowedValue';
|
|
32
|
+
/** The choice's value as the plain string it is; it arrives in the form engine's `{type, value}` envelope. */
|
|
33
|
+
var choiceValue = function (choice) { var _a; return String((_a = (0, options_1.getListElementValue)(choice.value)) !== null && _a !== void 0 ? _a : ''); };
|
|
34
|
+
exports.choiceValue = choiceValue;
|
|
31
35
|
/**
|
|
32
|
-
* The
|
|
33
|
-
*
|
|
34
|
-
|
|
36
|
+
* The text a document is, when it is one paragraph of plain text and nothing
|
|
37
|
+
* else; `undefined` for anything more — a chip, a mark, a second paragraph.
|
|
38
|
+
*/
|
|
39
|
+
var plainTextOfNodes = function (nodes) {
|
|
40
|
+
if (!Array.isArray(nodes) || nodes.length !== 1) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
var paragraph = nodes[0];
|
|
44
|
+
if ((paragraph === null || paragraph === void 0 ? void 0 : paragraph.type) !== 'paragraph' || !Array.isArray(paragraph.children)) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
var text = '';
|
|
48
|
+
for (var _i = 0, _a = paragraph.children; _i < _a.length; _i++) {
|
|
49
|
+
var child = _a[_i];
|
|
50
|
+
if (typeof (child === null || child === void 0 ? void 0 : child.text) !== 'string' || Object.keys(child).some(function (key) { return key !== 'text'; })) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
text += child.text;
|
|
54
|
+
}
|
|
55
|
+
return text;
|
|
56
|
+
};
|
|
57
|
+
exports.plainTextOfNodes = plainTextOfNodes;
|
|
58
|
+
/**
|
|
59
|
+
* The choice a value is: a whole plain string the field offers, or a document
|
|
60
|
+
* that is one paragraph of exactly that text — which is what an edit of the
|
|
61
|
+
* chip stores, so an id typed back is the choice it was. A string or document
|
|
62
|
+
* holding anything more is the author's own text and is never a choice.
|
|
35
63
|
*/
|
|
36
64
|
var choiceForValue = function (value, choices) {
|
|
37
|
-
|
|
65
|
+
var text = typeof value === 'string' ? value : (0, exports.plainTextOfNodes)(value);
|
|
66
|
+
if (!text || !(choices === null || choices === void 0 ? void 0 : choices.length)) {
|
|
38
67
|
return undefined;
|
|
39
68
|
}
|
|
40
|
-
return (0, allowedValues_1.findAllowedValueOption)(
|
|
69
|
+
return (0, allowedValues_1.findAllowedValueOption)(text, { allowed_values: choices });
|
|
41
70
|
};
|
|
42
71
|
exports.choiceForValue = choiceForValue;
|
|
43
72
|
/** The one-chip document that draws a choice by its name. */
|
|
44
73
|
var choiceToNodes = function (choice) {
|
|
45
74
|
var _a;
|
|
46
|
-
var _b, _c
|
|
47
|
-
|
|
48
|
-
var
|
|
49
|
-
var description = (_c = choice.short_desc) !== null && _c !== void 0 ? _c : choice.desc;
|
|
75
|
+
var _b, _c;
|
|
76
|
+
var value = (0, exports.choiceValue)(choice);
|
|
77
|
+
var description = (_b = choice.short_desc) !== null && _b !== void 0 ? _b : choice.desc;
|
|
50
78
|
return [
|
|
51
79
|
{
|
|
52
80
|
type: 'paragraph',
|
|
@@ -55,7 +83,7 @@ var choiceToNodes = function (choice) {
|
|
|
55
83
|
{
|
|
56
84
|
type: 'tag',
|
|
57
85
|
value: value,
|
|
58
|
-
label: (
|
|
86
|
+
label: (_c = choice.display_name) !== null && _c !== void 0 ? _c : value,
|
|
59
87
|
metadata: __assign((_a = {}, _a[exports.CHOICE_CHIP_META] = true, _a), (description ? { description: description } : {})),
|
|
60
88
|
children: [{ text: '' }],
|
|
61
89
|
},
|
|
@@ -72,6 +100,7 @@ var isChoiceChip = function (node) {
|
|
|
72
100
|
node.type === 'tag' &&
|
|
73
101
|
!!((_a = node.metadata) === null || _a === void 0 ? void 0 : _a[exports.CHOICE_CHIP_META]);
|
|
74
102
|
};
|
|
103
|
+
exports.isChoiceChip = isChoiceChip;
|
|
75
104
|
/**
|
|
76
105
|
* The value a document is, when the document is one choice chip and nothing
|
|
77
106
|
* else; `undefined` when the author has written anything around it, in which
|
|
@@ -83,12 +112,70 @@ var choiceValueOfNodes = function (nodes) {
|
|
|
83
112
|
return undefined;
|
|
84
113
|
}
|
|
85
114
|
var children = (_b = (_a = nodes[0]) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : [];
|
|
86
|
-
var chips = children.filter(isChoiceChip);
|
|
115
|
+
var chips = children.filter(exports.isChoiceChip);
|
|
87
116
|
var text = children
|
|
88
|
-
.filter(function (node) { return !isChoiceChip(node); })
|
|
117
|
+
.filter(function (node) { return !(0, exports.isChoiceChip)(node); })
|
|
89
118
|
.map(function (node) { return (typeof (node === null || node === void 0 ? void 0 : node.text) === 'string' ? node.text : '\u0000'); })
|
|
90
119
|
.join('');
|
|
91
120
|
return chips.length === 1 && text === '' ? chips[0].value : undefined;
|
|
92
121
|
};
|
|
93
122
|
exports.choiceValueOfNodes = choiceValueOfNodes;
|
|
123
|
+
exports.DEFAULT_CHOICE_CHIP_BEHAVIOR = {
|
|
124
|
+
backspace: 'unwrap',
|
|
125
|
+
click: 'unwrap',
|
|
126
|
+
};
|
|
127
|
+
/** Where the node is in the document, by identity; the editor renders the document's own nodes, so a chip handed to a click handler is one of them. */
|
|
128
|
+
var pathOfNode = function (editor, node) {
|
|
129
|
+
// Stepped by hand: the build target cannot iterate a generator (TS2802).
|
|
130
|
+
var nodes = slate_1.Node.nodes(editor);
|
|
131
|
+
for (var entry = nodes.next(); !entry.done; entry = nodes.next()) {
|
|
132
|
+
if (entry.value[0] === node) {
|
|
133
|
+
return entry.value[1];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
};
|
|
138
|
+
exports.pathOfNode = pathOfNode;
|
|
139
|
+
/**
|
|
140
|
+
* The chip the cursor is on: right after it with nothing between, where
|
|
141
|
+
* Backspace would take it, or inside it, where the arrow keys can leave the
|
|
142
|
+
* cursor. Nothing when the selection spans text or sits anywhere else.
|
|
143
|
+
*/
|
|
144
|
+
var choiceChipAtCursor = function (editor) {
|
|
145
|
+
var selection = editor.selection;
|
|
146
|
+
if (!selection || !slate_1.Range.isCollapsed(selection)) {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
var _a = selection.anchor, path = _a.path, offset = _a.offset;
|
|
150
|
+
var inside = slate_1.Editor.above(editor, { at: path, match: exports.isChoiceChip, voids: true });
|
|
151
|
+
if (inside) {
|
|
152
|
+
return inside[1];
|
|
153
|
+
}
|
|
154
|
+
if (offset !== 0 || !slate_1.Path.hasPrevious(path)) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
var previous = slate_1.Path.previous(path);
|
|
158
|
+
return (0, exports.isChoiceChip)(slate_1.Node.get(editor, previous)) ? previous : undefined;
|
|
159
|
+
};
|
|
160
|
+
exports.choiceChipAtCursor = choiceChipAtCursor;
|
|
161
|
+
/**
|
|
162
|
+
* Opens the chip at `path` into its value as plain text, the cursor at the
|
|
163
|
+
* end of the text: what the author read is what they chose, now editable
|
|
164
|
+
* letter by letter. The document is text from here on, and is stored as the
|
|
165
|
+
* field stores anything typed; it is drawn as a chip again only when it is
|
|
166
|
+
* read back as exactly one of the choices.
|
|
167
|
+
*/
|
|
168
|
+
var unwrapChoiceChip = function (editor, path) {
|
|
169
|
+
var chip = slate_1.Node.get(editor, path);
|
|
170
|
+
if (!(0, exports.isChoiceChip)(chip)) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
slate_1.Editor.withoutNormalizing(editor, function () {
|
|
174
|
+
slate_1.Transforms.removeNodes(editor, { at: path });
|
|
175
|
+
slate_1.Transforms.insertNodes(editor, [{ text: chip.value }], { at: path });
|
|
176
|
+
slate_1.Transforms.select(editor, slate_1.Editor.end(editor, path));
|
|
177
|
+
});
|
|
178
|
+
return true;
|
|
179
|
+
};
|
|
180
|
+
exports.unwrapChoiceChip = unwrapChoiceChip;
|
|
94
181
|
//# sourceMappingURL=choiceChip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choiceChip.js","sourceRoot":"","sources":["../../src/helpers/choiceChip.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA,iDAAyD;AACzD,qCAAgD;AAEhD;;;;;;;;;;;GAWG;AAEH,uFAAuF;AAC1E,QAAA,gBAAgB,GAAG,cAAc,CAAC;AAU/C
|
|
1
|
+
{"version":3,"file":"choiceChip.js","sourceRoot":"","sources":["../../src/helpers/choiceChip.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qoretechnologies/reqraft",
|
|
3
|
-
"version": "0.10.62-pr.141.
|
|
3
|
+
"version": "0.10.62-pr.141.gd67d7d6",
|
|
4
4
|
"description": "ReQraft is a collection of React components and hooks that are used across Qore Technologies' products made using the ReQore component library from Qore.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9815,3 +9815,100 @@ export const PickingARichTextChoiceShowsItsName: Story = {
|
|
|
9815
9815
|
await expectChannelChip(canvasElement);
|
|
9816
9816
|
},
|
|
9817
9817
|
};
|
|
9818
|
+
|
|
9819
|
+
export const ARichTextChoiceRetypedReturnsToItsChip: Story = {
|
|
9820
|
+
parameters: {
|
|
9821
|
+
docs: {
|
|
9822
|
+
description: {
|
|
9823
|
+
story:
|
|
9824
|
+
'Renders a compact form whose rich-text Channel option shows its stored choice as the chip "general". A click opens the chip into C07ERBFS0P6 as text; Backspace makes the form emit C07ERBFS0P and a typed 6 makes it emit C07ERBFS0P6 again, each as a document and still shown as text while the author types; Tab out of the editor draws the chip "general" again and emits nothing further, since that document already stands for the choice.',
|
|
9825
|
+
},
|
|
9826
|
+
},
|
|
9827
|
+
},
|
|
9828
|
+
args: {
|
|
9829
|
+
compact: true,
|
|
9830
|
+
minColumnWidth: '360px',
|
|
9831
|
+
initialExpandedOptions: ['channel'],
|
|
9832
|
+
value: { channel: { type: 'richtext', value: 'C07ERBFS0P6' } },
|
|
9833
|
+
options: RICH_TEXT_CHOICE_OPTIONS,
|
|
9834
|
+
},
|
|
9835
|
+
play: async ({ args, canvasElement }) => {
|
|
9836
|
+
await expectChannelChip(canvasElement);
|
|
9837
|
+
const row = canvasElement.querySelector('[data-field="channel"]') as HTMLElement;
|
|
9838
|
+
const editor = row.querySelector('[contenteditable="true"]') as HTMLElement;
|
|
9839
|
+
|
|
9840
|
+
await userEvent.click(within(row).getByText('general'));
|
|
9841
|
+
await waitFor(() => {
|
|
9842
|
+
expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
9843
|
+
expect(editor.contains(document.activeElement)).toBe(true);
|
|
9844
|
+
});
|
|
9845
|
+
|
|
9846
|
+
const channelValue = (text: string) =>
|
|
9847
|
+
expect.objectContaining({
|
|
9848
|
+
channel: expect.objectContaining({ value: [{ type: 'paragraph', children: [{ text }] }] }),
|
|
9849
|
+
});
|
|
9850
|
+
|
|
9851
|
+
// One key at a time, each emitted before the next: typed within the
|
|
9852
|
+
// field's debounce, the two would settle as the value the field started
|
|
9853
|
+
// with, and nothing would be emitted at all.
|
|
9854
|
+
await userEvent.keyboard('{Backspace}');
|
|
9855
|
+
await waitFor(() =>
|
|
9856
|
+
expect(args.onChange).toHaveBeenLastCalledWith('test', channelValue('C07ERBFS0P'), undefined)
|
|
9857
|
+
);
|
|
9858
|
+
await userEvent.keyboard('6');
|
|
9859
|
+
await waitFor(() =>
|
|
9860
|
+
expect(args.onChange).toHaveBeenLastCalledWith('test', channelValue('C07ERBFS0P6'), undefined)
|
|
9861
|
+
);
|
|
9862
|
+
await expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
9863
|
+
|
|
9864
|
+
await userEvent.tab();
|
|
9865
|
+
await expectChannelChip(canvasElement);
|
|
9866
|
+
// Leaving the row changed nothing: the chip stands for what was emitted.
|
|
9867
|
+
await expect(args.onChange).toHaveBeenLastCalledWith('test', channelValue('C07ERBFS0P6'), undefined);
|
|
9868
|
+
},
|
|
9869
|
+
};
|
|
9870
|
+
|
|
9871
|
+
export const ClickingARichTextChoiceEditsItsValue: Story = {
|
|
9872
|
+
parameters: {
|
|
9873
|
+
docs: {
|
|
9874
|
+
description: {
|
|
9875
|
+
story:
|
|
9876
|
+
'Renders a compact form whose rich-text Channel option shows its stored choice as the chip "general". A click on the chip opens it into its value as editable text: the row shows C07ERBFS0P6 and no chip, with the cursor at the end, so Backspace and a typed 7 make it C07ERBFS0P7 — the value the form then emits for the option.',
|
|
9877
|
+
},
|
|
9878
|
+
},
|
|
9879
|
+
},
|
|
9880
|
+
args: {
|
|
9881
|
+
compact: true,
|
|
9882
|
+
minColumnWidth: '360px',
|
|
9883
|
+
initialExpandedOptions: ['channel'],
|
|
9884
|
+
value: { channel: { type: 'richtext', value: 'C07ERBFS0P6' } },
|
|
9885
|
+
options: RICH_TEXT_CHOICE_OPTIONS,
|
|
9886
|
+
},
|
|
9887
|
+
play: async ({ args, canvasElement }) => {
|
|
9888
|
+
await expectChannelChip(canvasElement);
|
|
9889
|
+
const row = canvasElement.querySelector('[data-field="channel"]') as HTMLElement;
|
|
9890
|
+
const editor = row.querySelector('[contenteditable="true"]') as HTMLElement;
|
|
9891
|
+
|
|
9892
|
+
// The chip's label: a tag binds its click to its content, not its frame.
|
|
9893
|
+
await userEvent.click(within(row).getByText('general'));
|
|
9894
|
+
await waitFor(() => {
|
|
9895
|
+
expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
9896
|
+
expect(editor.textContent).toBe('C07ERBFS0P6');
|
|
9897
|
+
expect(editor.contains(document.activeElement)).toBe(true);
|
|
9898
|
+
});
|
|
9899
|
+
|
|
9900
|
+
await userEvent.keyboard('{Backspace}7');
|
|
9901
|
+
await waitFor(() => expect(editor.textContent).toBe('C07ERBFS0P7'));
|
|
9902
|
+
await waitFor(() =>
|
|
9903
|
+
expect(args.onChange).toHaveBeenLastCalledWith(
|
|
9904
|
+
'test',
|
|
9905
|
+
expect.objectContaining({
|
|
9906
|
+
channel: expect.objectContaining({
|
|
9907
|
+
value: [{ type: 'paragraph', children: [{ text: 'C07ERBFS0P7' }] }],
|
|
9908
|
+
}),
|
|
9909
|
+
}),
|
|
9910
|
+
undefined
|
|
9911
|
+
)
|
|
9912
|
+
);
|
|
9913
|
+
},
|
|
9914
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { expect, fn, within } from 'storybook/test';
|
|
2
|
+
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
|
|
5
5
|
import { StoryMeta } from '../../../../types';
|
|
@@ -76,6 +76,144 @@ export const WithChoiceValue: Story = {
|
|
|
76
76
|
},
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
+
export const WithChoiceValueAsDocument: Story = {
|
|
80
|
+
args: {
|
|
81
|
+
...WithChoiceValue.args,
|
|
82
|
+
value: [{ type: 'paragraph', children: [{ text: 'C07ERBFS0P6' }] }] as never,
|
|
83
|
+
},
|
|
84
|
+
parameters: {
|
|
85
|
+
docs: {
|
|
86
|
+
description: {
|
|
87
|
+
story:
|
|
88
|
+
'Renders the RichText field holding a document that is nothing but the id of one of its choices — what an edit of the chip stores — drawn as the chip "general"; the id is not shown, and nothing is emitted for it, since the document already stands for the choice.',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
async play({ args, canvasElement }) {
|
|
93
|
+
const canvas = within(canvasElement);
|
|
94
|
+
await expect(canvas.getByText('general')).toBeInTheDocument();
|
|
95
|
+
await expect(canvas.queryByText('C07ERBFS0P6')).not.toBeInTheDocument();
|
|
96
|
+
await new Promise((resolve) => setTimeout(resolve, 400));
|
|
97
|
+
await expect(args.onChange).not.toHaveBeenCalled();
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const RetypingTheChoiceReturnsItsChip: Story = {
|
|
102
|
+
args: WithChoiceValue.args,
|
|
103
|
+
parameters: {
|
|
104
|
+
docs: {
|
|
105
|
+
description: {
|
|
106
|
+
story:
|
|
107
|
+
'Renders the RichText field holding a choice drawn as the chip "general". A click opens it into C07ERBFS0P6 as text; Backspace emits C07ERBFS0P, and a typed 6 emits C07ERBFS0P6 again, each as a document and still shown as text while the author types; leaving the field with Tab draws it as the chip "general" once more and emits nothing further, since that document already stands for the choice.',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
async play({ args, canvasElement }) {
|
|
112
|
+
const canvas = within(canvasElement);
|
|
113
|
+
const editor = canvas.getByRole('textbox');
|
|
114
|
+
|
|
115
|
+
await userEvent.click(canvas.getByText('general'));
|
|
116
|
+
await waitFor(() => {
|
|
117
|
+
expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
118
|
+
expect(editor.contains(document.activeElement)).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// One key at a time, each emitted before the next: typed within the
|
|
122
|
+
// field's debounce, the two would settle as the value the field started
|
|
123
|
+
// with, and nothing would be emitted at all.
|
|
124
|
+
await userEvent.keyboard('{Backspace}');
|
|
125
|
+
await waitFor(() =>
|
|
126
|
+
expect(args.onChange).toHaveBeenLastCalledWith([
|
|
127
|
+
{ type: 'paragraph', children: [{ text: 'C07ERBFS0P' }] },
|
|
128
|
+
])
|
|
129
|
+
);
|
|
130
|
+
await userEvent.keyboard('6');
|
|
131
|
+
await waitFor(() =>
|
|
132
|
+
expect(args.onChange).toHaveBeenLastCalledWith([
|
|
133
|
+
{ type: 'paragraph', children: [{ text: 'C07ERBFS0P6' }] },
|
|
134
|
+
])
|
|
135
|
+
);
|
|
136
|
+
await expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
137
|
+
|
|
138
|
+
await userEvent.tab();
|
|
139
|
+
await waitFor(() => {
|
|
140
|
+
expect(editor.querySelector('.reqore-tag')?.textContent).toContain('general');
|
|
141
|
+
expect(editor.textContent).not.toContain('C07ERBFS0P6');
|
|
142
|
+
});
|
|
143
|
+
// Leaving the field changed nothing: the chip stands for what was emitted.
|
|
144
|
+
await expect(args.onChange).toHaveBeenLastCalledWith([
|
|
145
|
+
{ type: 'paragraph', children: [{ text: 'C07ERBFS0P6' }] },
|
|
146
|
+
]);
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const ClickOpensTheChoiceChip: Story = {
|
|
151
|
+
args: WithChoiceValue.args,
|
|
152
|
+
parameters: {
|
|
153
|
+
docs: {
|
|
154
|
+
description: {
|
|
155
|
+
story:
|
|
156
|
+
'Renders the RichText field holding a choice drawn as the chip "general", with the default chip behaviour. A click on the chip opens it into its value as editable text: the editor shows C07ERBFS0P6 and no chip, the cursor at its end, so Backspace and a typed 7 make it C07ERBFS0P7, which is what the field emits.',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
async play({ args, canvasElement }) {
|
|
161
|
+
const canvas = within(canvasElement);
|
|
162
|
+
const editor = canvas.getByRole('textbox');
|
|
163
|
+
|
|
164
|
+
await userEvent.click(canvas.getByText('general'));
|
|
165
|
+
await waitFor(() => {
|
|
166
|
+
expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
167
|
+
expect(editor.textContent).toBe('C07ERBFS0P6');
|
|
168
|
+
expect(editor.contains(document.activeElement)).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
await userEvent.keyboard('{Backspace}7');
|
|
172
|
+
await waitFor(() => expect(editor.textContent).toBe('C07ERBFS0P7'));
|
|
173
|
+
await waitFor(() =>
|
|
174
|
+
expect(args.onChange).toHaveBeenLastCalledWith([
|
|
175
|
+
{ type: 'paragraph', children: [{ text: 'C07ERBFS0P7' }] },
|
|
176
|
+
])
|
|
177
|
+
);
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const BackspaceOpensTheChoiceChip: Story = {
|
|
182
|
+
args: {
|
|
183
|
+
...WithChoiceValue.args,
|
|
184
|
+
choiceChip: { click: 'cursor' },
|
|
185
|
+
},
|
|
186
|
+
parameters: {
|
|
187
|
+
docs: {
|
|
188
|
+
description: {
|
|
189
|
+
story:
|
|
190
|
+
'Renders the RichText field holding a choice drawn as the chip "general", configured so that a click on the chip only places the cursor after it. Backspace then opens the chip into its value as editable text: the editor shows C07ERBFS0P6 and no chip, the cursor at its end, so one more Backspace and a typed 7 make it C07ERBFS0P7, which is what the field emits.',
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
async play({ args, canvasElement }) {
|
|
195
|
+
const canvas = within(canvasElement);
|
|
196
|
+
const editor = canvas.getByRole('textbox');
|
|
197
|
+
|
|
198
|
+
await userEvent.click(canvas.getByText('general'));
|
|
199
|
+
await waitFor(() => expect(editor.contains(document.activeElement)).toBe(true));
|
|
200
|
+
|
|
201
|
+
await userEvent.keyboard('{Backspace}');
|
|
202
|
+
await waitFor(() => {
|
|
203
|
+
expect(editor.querySelector('.reqore-tag')).toBeNull();
|
|
204
|
+
expect(editor.textContent).toBe('C07ERBFS0P6');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
await userEvent.keyboard('{Backspace}7');
|
|
208
|
+
await waitFor(() => expect(editor.textContent).toBe('C07ERBFS0P7'));
|
|
209
|
+
await waitFor(() =>
|
|
210
|
+
expect(args.onChange).toHaveBeenLastCalledWith([
|
|
211
|
+
{ type: 'paragraph', children: [{ text: 'C07ERBFS0P7' }] },
|
|
212
|
+
])
|
|
213
|
+
);
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
|
|
79
217
|
export const Empty: Story = {
|
|
80
218
|
parameters: {
|
|
81
219
|
docs: {
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IReqoreRichTextEditorProps,
|
|
3
3
|
ReqoreRichTextEditor,
|
|
4
|
+
TReqoreRichTextEditorRef,
|
|
4
5
|
} from '@qoretechnologies/reqore/dist/components/RichTextEditor';
|
|
5
6
|
import { IReqoreFormTemplates } from '@qoretechnologies/reqore/dist/components/Textarea';
|
|
6
7
|
import { IReqoreTagProps } from '@qoretechnologies/reqore/dist/components/Tag';
|
|
7
8
|
import { IReqoreTooltip } from '@qoretechnologies/reqore/dist/types/global';
|
|
8
9
|
import { IQorusAllowedValue } from '@qoretechnologies/ts-toolkit';
|
|
9
10
|
import { isEqual, size } from 'lodash';
|
|
10
|
-
import { KeyboardEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
11
|
+
import { FocusEvent, KeyboardEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
11
12
|
import { useDebounce } from 'react-use';
|
|
13
|
+
import { Path } from 'slate';
|
|
14
|
+
import { ReactEditor } from 'slate-react';
|
|
12
15
|
import { useEmittedValues } from '../emittedValues';
|
|
13
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
choiceChipAtCursor,
|
|
18
|
+
choiceForValue,
|
|
19
|
+
choiceToNodes,
|
|
20
|
+
choiceValue,
|
|
21
|
+
choiceValueOfNodes,
|
|
22
|
+
DEFAULT_CHOICE_CHIP_BEHAVIOR,
|
|
23
|
+
IChoiceChipBehavior,
|
|
24
|
+
pathOfNode,
|
|
25
|
+
unwrapChoiceChip,
|
|
26
|
+
} from '../../../../helpers/choiceChip';
|
|
14
27
|
import { flattenToSingleLine, hasLineBreak } from '../../../../helpers/singleLineString';
|
|
15
28
|
import {
|
|
16
29
|
renderTemplateItemDescriptions,
|
|
@@ -61,13 +74,23 @@ export interface IRichTextFormFieldProps extends Omit<
|
|
|
61
74
|
singleLine?: boolean;
|
|
62
75
|
/**
|
|
63
76
|
* The choices the field offers, when it offers any. A value that IS one of
|
|
64
|
-
* them — the whole string, as picked from the field's suggestions
|
|
65
|
-
* as
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
77
|
+
* them — the whole string, as picked from the field's suggestions, or a
|
|
78
|
+
* document of nothing but that string, as an edit of it stores — is drawn as
|
|
79
|
+
* one chip named from the choice (`general` rather than `C07ERBFS0P6`), and
|
|
80
|
+
* is still emitted as that value: the chip's own value is the choice's, and a
|
|
81
|
+
* document that is nothing but the chip reads back as it. A field spreads
|
|
82
|
+
* its schema here, so this is the schema's own key.
|
|
69
83
|
*/
|
|
70
84
|
allowed_values?: IQorusAllowedValue[];
|
|
85
|
+
/**
|
|
86
|
+
* What a choice chip does when the author acts on it — Backspace right after
|
|
87
|
+
* it, a click on it. By default each opens the chip into its value as plain
|
|
88
|
+
* text, the cursor at the end, so one letter of what was chosen can be
|
|
89
|
+
* changed; see `IChoiceChipBehavior` for the alternatives. Text that is again
|
|
90
|
+
* exactly one of the choices becomes its chip when the author leaves the
|
|
91
|
+
* field — not while typing, where a choice can be the start of a longer value.
|
|
92
|
+
*/
|
|
93
|
+
choiceChip?: IChoiceChipBehavior;
|
|
71
94
|
/**
|
|
72
95
|
* With `valueFormat: 'text'`: the token grammar the value's references are
|
|
73
96
|
* WRITTEN in, when the host speaks one of its own.
|
|
@@ -131,9 +154,14 @@ export const RichTextFormField = memo(({
|
|
|
131
154
|
singleLine,
|
|
132
155
|
templateToken,
|
|
133
156
|
allowed_values,
|
|
157
|
+
choiceChip,
|
|
134
158
|
...rest
|
|
135
159
|
}: IRichTextFormFieldProps) => {
|
|
136
160
|
const isText = valueFormat === 'text';
|
|
161
|
+
/* The Slate editor behind Reqore's, for the two chip actions below: both
|
|
162
|
+
rewrite the document in place, which the editor's props cannot. */
|
|
163
|
+
const editorRef = useRef<TReqoreRichTextEditorRef>(null);
|
|
164
|
+
const chipBehavior = { ...DEFAULT_CHOICE_CHIP_BEHAVIOR, ...choiceChip };
|
|
137
165
|
/* The document the editor shows for a value: a choice by its chip, a text
|
|
138
166
|
with its references as chips, a document as it is. */
|
|
139
167
|
const toLocal = (next: unknown): any => {
|
|
@@ -146,6 +174,18 @@ export const RichTextFormField = memo(({
|
|
|
146
174
|
return choice ? choiceToNodes(choice) : next;
|
|
147
175
|
};
|
|
148
176
|
const [localValue, setLocalValue] = useState<any>(() => toLocal(value));
|
|
177
|
+
/* What a value stands for: the choice's value when the value is that choice
|
|
178
|
+
by any spelling — the plain string, the chip, a document of just the text —
|
|
179
|
+
else the value itself. Values are compared by this, so opening a chip, or
|
|
180
|
+
typing its id back, is not a change to the value. */
|
|
181
|
+
const standsFor = (next: unknown): unknown => {
|
|
182
|
+
const chip = choiceValueOfNodes(next);
|
|
183
|
+
if (chip !== undefined) {
|
|
184
|
+
return chip;
|
|
185
|
+
}
|
|
186
|
+
const choice = choiceForValue(next, allowed_values);
|
|
187
|
+
return choice ? choiceValue(choice) : next;
|
|
188
|
+
};
|
|
149
189
|
/* In text mode, the string the editor's document stands for. The value that
|
|
150
190
|
comes back from the parent is usually that same string, and rebuilding the
|
|
151
191
|
document from it would hand the editor a new tree on every keystroke —
|
|
@@ -168,9 +208,9 @@ export const RichTextFormField = memo(({
|
|
|
168
208
|
}
|
|
169
209
|
return;
|
|
170
210
|
}
|
|
171
|
-
// Compared as what
|
|
172
|
-
//
|
|
173
|
-
if (
|
|
211
|
+
// Compared as what each stands for: a lone choice chip IS the value it
|
|
212
|
+
// draws, so the value coming back is not a change to it.
|
|
213
|
+
if (!isEqual(standsFor(value), standsFor(localValue))) {
|
|
174
214
|
setLocalValue(toLocal(value));
|
|
175
215
|
}
|
|
176
216
|
}, [JSON.stringify(value)]);
|
|
@@ -205,7 +245,7 @@ export const RichTextFormField = memo(({
|
|
|
205
245
|
// A document that is nothing but one choice chip is emitted as the
|
|
206
246
|
// choice's value — what was stored and what the server resolves.
|
|
207
247
|
const next = choiceValueOfNodes(localValue) ?? localValue;
|
|
208
|
-
if (!isEqual(next, value)) {
|
|
248
|
+
if (!isEqual(standsFor(next), standsFor(value))) {
|
|
209
249
|
emitted.record(next);
|
|
210
250
|
onChange?.(next);
|
|
211
251
|
}
|
|
@@ -248,6 +288,43 @@ export const RichTextFormField = memo(({
|
|
|
248
288
|
JSON.stringify(templates),
|
|
249
289
|
]);
|
|
250
290
|
|
|
291
|
+
/* Opens a choice chip into its value as text and puts the cursor there.
|
|
292
|
+
A click on the chip — a non-editable node — need not have given the
|
|
293
|
+
editor focus, so focus is asked of Slate, which places the DOM caret where
|
|
294
|
+
the selection is and focuses after; but only once the text the chip became
|
|
295
|
+
is rendered (the effect below), since Slate resolves the caret through the
|
|
296
|
+
rendered DOM. Asked any earlier it lost: a DOM `focus()` before the
|
|
297
|
+
transform let the browser put the caret at the editor's start and the
|
|
298
|
+
`selectionchange` it raised beat the render, so the next key typed landed
|
|
299
|
+
there; asked on the next frame, the frame came before React's commit
|
|
300
|
+
often enough. An editor that already has focus (Backspace came from it)
|
|
301
|
+
is returned at once, and its own render puts the caret where the
|
|
302
|
+
selection is. */
|
|
303
|
+
const focusOnceRendered = useRef(false);
|
|
304
|
+
const openChoiceChip = useCallback((path: Path | undefined): void => {
|
|
305
|
+
const editor = editorRef.current;
|
|
306
|
+
|
|
307
|
+
if (editor && path && unwrapChoiceChip(editor, path)) {
|
|
308
|
+
focusOnceRendered.current = true;
|
|
309
|
+
}
|
|
310
|
+
}, []);
|
|
311
|
+
|
|
312
|
+
useEffect(() => {
|
|
313
|
+
const editor = editorRef.current;
|
|
314
|
+
|
|
315
|
+
if (!focusOnceRendered.current || !editor) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
focusOnceRendered.current = false;
|
|
319
|
+
|
|
320
|
+
try {
|
|
321
|
+
ReactEditor.toDOMNode(editor, editor);
|
|
322
|
+
ReactEditor.focus(editor);
|
|
323
|
+
} catch {
|
|
324
|
+
// Not mounted in a document — nothing to focus.
|
|
325
|
+
}
|
|
326
|
+
}, [localValue]);
|
|
327
|
+
|
|
251
328
|
const handleGetTagProps = useCallback(
|
|
252
329
|
(tag: any): IReqoreTagProps => {
|
|
253
330
|
const tagValue = tag.value?.toString();
|
|
@@ -263,6 +340,11 @@ export const RichTextFormField = memo(({
|
|
|
263
340
|
icon: 'ListCheck',
|
|
264
341
|
label: tag.label ?? tagValue,
|
|
265
342
|
tooltip: tag.metadata?.description,
|
|
343
|
+
/* The editor hands the document's own node here, so the chip is
|
|
344
|
+
found by identity; a chip already gone is a click on nothing. */
|
|
345
|
+
...(chipBehavior.click === 'unwrap' ?
|
|
346
|
+
{ onClick: () => openChoiceChip(editorRef.current ? pathOfNode(editorRef.current, tag) : undefined) }
|
|
347
|
+
: {}),
|
|
266
348
|
};
|
|
267
349
|
}
|
|
268
350
|
|
|
@@ -323,7 +405,23 @@ export const RichTextFormField = memo(({
|
|
|
323
405
|
|
|
324
406
|
return {};
|
|
325
407
|
},
|
|
326
|
-
[descriptionByValue, renderMarkdown, isText, templates]
|
|
408
|
+
[descriptionByValue, renderMarkdown, isText, templates, chipBehavior.click, openChoiceChip]
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
/* Leaving the field: text that is exactly one of the choices becomes its
|
|
412
|
+
chip again, as the picker would have drawn it. Only here, never while
|
|
413
|
+
typing — a choice can be the start of a longer value, and a chip drawn
|
|
414
|
+
under the cursor would swallow it. */
|
|
415
|
+
const handleBlur = useCallback(
|
|
416
|
+
(event: FocusEvent<HTMLTextAreaElement>): void => {
|
|
417
|
+
const shown = isText ? lastTextRef.current : localValue;
|
|
418
|
+
|
|
419
|
+
if (choiceForValue(shown, allowed_values)) {
|
|
420
|
+
setLocalValue(toLocal(shown));
|
|
421
|
+
}
|
|
422
|
+
(rest as { onBlur?: (event: FocusEvent<HTMLTextAreaElement>) => void }).onBlur?.(event);
|
|
423
|
+
},
|
|
424
|
+
[isText, localValue, choiceKey, (rest as { onBlur?: unknown }).onBlur]
|
|
327
425
|
);
|
|
328
426
|
|
|
329
427
|
const handleKeyDown = useCallback(
|
|
@@ -331,9 +429,26 @@ export const RichTextFormField = memo(({
|
|
|
331
429
|
if (isText && singleLine && event.key === 'Enter') {
|
|
332
430
|
event.preventDefault();
|
|
333
431
|
}
|
|
432
|
+
/* Backspace right after a choice chip opens it rather than deleting it,
|
|
433
|
+
when so configured. Stopped here, at keydown, so the browser raises no
|
|
434
|
+
`beforeinput` for the editor to delete the chip by. */
|
|
435
|
+
if (event.key === 'Backspace' && chipBehavior.backspace === 'unwrap' && editorRef.current) {
|
|
436
|
+
const path = choiceChipAtCursor(editorRef.current);
|
|
437
|
+
|
|
438
|
+
if (path) {
|
|
439
|
+
event.preventDefault();
|
|
440
|
+
openChoiceChip(path);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
334
443
|
(rest as { onKeyDown?: (event: KeyboardEvent<HTMLTextAreaElement>) => void }).onKeyDown?.(event);
|
|
335
444
|
},
|
|
336
|
-
[
|
|
445
|
+
[
|
|
446
|
+
isText,
|
|
447
|
+
singleLine,
|
|
448
|
+
chipBehavior.backspace,
|
|
449
|
+
openChoiceChip,
|
|
450
|
+
(rest as { onKeyDown?: unknown }).onKeyDown,
|
|
451
|
+
]
|
|
337
452
|
);
|
|
338
453
|
|
|
339
454
|
const tags = useMemo<IReqoreRichTextEditorProps['tags']>((): IReqoreRichTextEditorProps['tags'] => {
|
|
@@ -384,6 +499,7 @@ export const RichTextFormField = memo(({
|
|
|
384
499
|
|
|
385
500
|
return (
|
|
386
501
|
<ReqoreRichTextEditor
|
|
502
|
+
ref={editorRef}
|
|
387
503
|
value={formattedValue}
|
|
388
504
|
onChange={handleChange}
|
|
389
505
|
/* `rest` is spread BEFORE everything this component computes. It used to
|
|
@@ -409,6 +525,7 @@ export const RichTextFormField = memo(({
|
|
|
409
525
|
panelProps={{ fluid: true, style: { minWidth: '150px', ...rest.panelProps?.style } }}
|
|
410
526
|
readOnly={readOnly}
|
|
411
527
|
onKeyDown={handleKeyDown}
|
|
528
|
+
onBlur={handleBlur}
|
|
412
529
|
/* A form field carries no document toolbar. Styling was already off, so
|
|
413
530
|
the bar held only undo and redo — drawn by Reqore as a panel as wide as
|
|
414
531
|
the tag list, which under a field reads as an empty 600px menu with two
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Copyright 2026 Qore Technologies, s.r.o.
|
|
2
2
|
import { IQorusAllowedValue, TQorusFormFieldSchema } from '@qoretechnologies/ts-toolkit';
|
|
3
|
+
import { Editor, Node, Path, Range, Transforms } from 'slate';
|
|
3
4
|
import { findAllowedValueOption } from './allowedValues';
|
|
4
5
|
import { getListElementValue } from './options';
|
|
5
6
|
|
|
@@ -27,20 +28,54 @@ export interface IChoiceChipNode {
|
|
|
27
28
|
children: [{ text: '' }];
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
/** The choice's value as the plain string it is; it arrives in the form engine's `{type, value}` envelope. */
|
|
32
|
+
export const choiceValue = (choice: IQorusAllowedValue): string =>
|
|
33
|
+
String(getListElementValue(choice.value) ?? '');
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The text a document is, when it is one paragraph of plain text and nothing
|
|
37
|
+
* else; `undefined` for anything more — a chip, a mark, a second paragraph.
|
|
38
|
+
*/
|
|
39
|
+
export const plainTextOfNodes = (nodes: unknown): string | undefined => {
|
|
40
|
+
if (!Array.isArray(nodes) || nodes.length !== 1) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const paragraph = nodes[0] as { type?: unknown; children?: unknown[] } | undefined;
|
|
45
|
+
|
|
46
|
+
if (paragraph?.type !== 'paragraph' || !Array.isArray(paragraph.children)) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let text = '';
|
|
51
|
+
|
|
52
|
+
for (const child of paragraph.children as { text?: unknown }[]) {
|
|
53
|
+
if (typeof child?.text !== 'string' || Object.keys(child).some((key) => key !== 'text')) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
text += child.text;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return text;
|
|
60
|
+
};
|
|
61
|
+
|
|
30
62
|
/**
|
|
31
|
-
* The choice a value is
|
|
32
|
-
*
|
|
33
|
-
*
|
|
63
|
+
* The choice a value is: a whole plain string the field offers, or a document
|
|
64
|
+
* that is one paragraph of exactly that text — which is what an edit of the
|
|
65
|
+
* chip stores, so an id typed back is the choice it was. A string or document
|
|
66
|
+
* holding anything more is the author's own text and is never a choice.
|
|
34
67
|
*/
|
|
35
68
|
export const choiceForValue = (
|
|
36
69
|
value: unknown,
|
|
37
70
|
choices?: IQorusAllowedValue[]
|
|
38
71
|
): IQorusAllowedValue | undefined => {
|
|
39
|
-
|
|
72
|
+
const text = typeof value === 'string' ? value : plainTextOfNodes(value);
|
|
73
|
+
|
|
74
|
+
if (!text || !choices?.length) {
|
|
40
75
|
return undefined;
|
|
41
76
|
}
|
|
42
77
|
|
|
43
|
-
return findAllowedValueOption(
|
|
78
|
+
return findAllowedValueOption(text, { allowed_values: choices } as TQorusFormFieldSchema) as
|
|
44
79
|
| IQorusAllowedValue
|
|
45
80
|
| undefined;
|
|
46
81
|
};
|
|
@@ -49,8 +84,7 @@ export const choiceForValue = (
|
|
|
49
84
|
export const choiceToNodes = (
|
|
50
85
|
choice: IQorusAllowedValue
|
|
51
86
|
): { type: 'paragraph'; children: ({ text: string } | IChoiceChipNode)[] }[] => {
|
|
52
|
-
|
|
53
|
-
const value = String(getListElementValue(choice.value) ?? '');
|
|
87
|
+
const value = choiceValue(choice);
|
|
54
88
|
const description = (choice as { desc?: string; short_desc?: string }).short_desc ?? choice.desc;
|
|
55
89
|
|
|
56
90
|
return [
|
|
@@ -71,7 +105,7 @@ export const choiceToNodes = (
|
|
|
71
105
|
];
|
|
72
106
|
};
|
|
73
107
|
|
|
74
|
-
const isChoiceChip = (node: unknown): node is IChoiceChipNode =>
|
|
108
|
+
export const isChoiceChip = (node: unknown): node is IChoiceChipNode =>
|
|
75
109
|
!!node &&
|
|
76
110
|
typeof node === 'object' &&
|
|
77
111
|
(node as { type?: unknown }).type === 'tag' &&
|
|
@@ -96,3 +130,98 @@ export const choiceValueOfNodes = (nodes: unknown): string | undefined => {
|
|
|
96
130
|
|
|
97
131
|
return chips.length === 1 && text === '' ? chips[0].value : undefined;
|
|
98
132
|
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* What a choice chip does when the author acts on it, by action.
|
|
136
|
+
*
|
|
137
|
+
* The chip is a void: it holds no text of its own, so a key or a click on it
|
|
138
|
+
* has nothing to land in, and an author who wants to change one letter of the
|
|
139
|
+
* value it draws (`C07ERBFS0P6` to `C07ERBFS0P7`) has no way in unless the
|
|
140
|
+
* chip opens. Each action is configurable, and the default is the one that
|
|
141
|
+
* opens it: a creatable choice is the author's to edit.
|
|
142
|
+
*/
|
|
143
|
+
export interface IChoiceChipBehavior {
|
|
144
|
+
/**
|
|
145
|
+
* Backspace with the cursor right after the chip. `unwrap` (the default)
|
|
146
|
+
* turns the chip into its value as plain text, the cursor at the end of it,
|
|
147
|
+
* for the author to edit; `remove` deletes it whole, as the editor deletes
|
|
148
|
+
* any other chip.
|
|
149
|
+
*/
|
|
150
|
+
backspace?: 'unwrap' | 'remove';
|
|
151
|
+
/**
|
|
152
|
+
* A click on the chip's body. `unwrap` (the default) turns the chip into its
|
|
153
|
+
* value as plain text, the cursor at the end of it; `cursor` only places the
|
|
154
|
+
* cursor after it, as a click on a template chip does.
|
|
155
|
+
*/
|
|
156
|
+
click?: 'unwrap' | 'cursor';
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export const DEFAULT_CHOICE_CHIP_BEHAVIOR: Required<IChoiceChipBehavior> = {
|
|
160
|
+
backspace: 'unwrap',
|
|
161
|
+
click: 'unwrap',
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/** Where the node is in the document, by identity; the editor renders the document's own nodes, so a chip handed to a click handler is one of them. */
|
|
165
|
+
export const pathOfNode = (editor: Editor, node: unknown): Path | undefined => {
|
|
166
|
+
// Stepped by hand: the build target cannot iterate a generator (TS2802).
|
|
167
|
+
const nodes = Node.nodes(editor);
|
|
168
|
+
|
|
169
|
+
for (let entry = nodes.next(); !entry.done; entry = nodes.next()) {
|
|
170
|
+
if (entry.value[0] === node) {
|
|
171
|
+
return entry.value[1];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return undefined;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The chip the cursor is on: right after it with nothing between, where
|
|
180
|
+
* Backspace would take it, or inside it, where the arrow keys can leave the
|
|
181
|
+
* cursor. Nothing when the selection spans text or sits anywhere else.
|
|
182
|
+
*/
|
|
183
|
+
export const choiceChipAtCursor = (editor: Editor): Path | undefined => {
|
|
184
|
+
const { selection } = editor;
|
|
185
|
+
|
|
186
|
+
if (!selection || !Range.isCollapsed(selection)) {
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const { path, offset } = selection.anchor;
|
|
191
|
+
const inside = Editor.above(editor, { at: path, match: isChoiceChip, voids: true });
|
|
192
|
+
|
|
193
|
+
if (inside) {
|
|
194
|
+
return inside[1];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (offset !== 0 || !Path.hasPrevious(path)) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const previous = Path.previous(path);
|
|
202
|
+
|
|
203
|
+
return isChoiceChip(Node.get(editor, previous)) ? previous : undefined;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Opens the chip at `path` into its value as plain text, the cursor at the
|
|
208
|
+
* end of the text: what the author read is what they chose, now editable
|
|
209
|
+
* letter by letter. The document is text from here on, and is stored as the
|
|
210
|
+
* field stores anything typed; it is drawn as a chip again only when it is
|
|
211
|
+
* read back as exactly one of the choices.
|
|
212
|
+
*/
|
|
213
|
+
export const unwrapChoiceChip = (editor: Editor, path: Path): boolean => {
|
|
214
|
+
const chip = Node.get(editor, path);
|
|
215
|
+
|
|
216
|
+
if (!isChoiceChip(chip)) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
Editor.withoutNormalizing(editor, () => {
|
|
221
|
+
Transforms.removeNodes(editor, { at: path });
|
|
222
|
+
Transforms.insertNodes(editor, [{ text: chip.value }], { at: path });
|
|
223
|
+
Transforms.select(editor, Editor.end(editor, path));
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
return true;
|
|
227
|
+
};
|