lkb-fields-document 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/component-blocks/dist/lkb-fields-document-component-blocks.cjs.d.ts +2 -0
- package/component-blocks/dist/lkb-fields-document-component-blocks.cjs.js +306 -0
- package/component-blocks/dist/lkb-fields-document-component-blocks.esm.js +300 -0
- package/component-blocks/dist/lkb-fields-document-component-blocks.node.cjs.js +306 -0
- package/component-blocks/dist/lkb-fields-document-component-blocks.node.esm.js +300 -0
- package/component-blocks/package.json +4 -0
- package/dist/Cell-0ac0ac66.node.cjs.js +21 -0
- package/dist/Cell-242f7404.esm.js +17 -0
- package/dist/Cell-3103f73d.node.esm.js +17 -0
- package/dist/Cell-bfb56d74.cjs.js +21 -0
- package/dist/Field-0e0f75ed.node.cjs.js +1628 -0
- package/dist/Field-28177061.cjs.js +1628 -0
- package/dist/Field-35b79e6b.node.esm.js +1619 -0
- package/dist/Field-92d13205.esm.js +1619 -0
- package/dist/api-2f524611.esm.js +502 -0
- package/dist/api-73636987.cjs.js +506 -0
- package/dist/api-8e2b20b8.node.cjs.js +506 -0
- package/dist/api-c32e360e.node.esm.js +502 -0
- package/dist/callout-ui-2aded278.cjs.js +131 -0
- package/dist/callout-ui-3e5ca544.node.esm.js +126 -0
- package/dist/callout-ui-8b5f2376.esm.js +126 -0
- package/dist/callout-ui-ad50f301.node.cjs.js +131 -0
- package/dist/declarations/src/component-blocks.d.ts +4 -0
- package/dist/declarations/src/component-blocks.d.ts.map +1 -0
- package/dist/declarations/src/document-editor/component-blocks/api.d.ts +120 -0
- package/dist/declarations/src/document-editor/component-blocks/api.d.ts.map +1 -0
- package/dist/declarations/src/document-editor/component-blocks/types.d.ts +241 -0
- package/dist/declarations/src/document-editor/component-blocks/types.d.ts.map +1 -0
- package/dist/declarations/src/document-editor/toolset/relationship/relationship-shared.d.ts +10 -0
- package/dist/declarations/src/document-editor/toolset/relationship/relationship-shared.d.ts.map +1 -0
- package/dist/declarations/src/index.d.ts +7 -0
- package/dist/declarations/src/index.d.ts.map +1 -0
- package/dist/declarations/src/my-component-blocks/index.d.ts +46 -0
- package/dist/declarations/src/my-component-blocks/index.d.ts.map +1 -0
- package/dist/declarations/src/structure/Cell.d.ts +5 -0
- package/dist/declarations/src/structure/Cell.d.ts.map +1 -0
- package/dist/declarations/src/structure/Field.d.ts +5 -0
- package/dist/declarations/src/structure/Field.d.ts.map +1 -0
- package/dist/declarations/src/structure/controller.d.ts +10 -0
- package/dist/declarations/src/structure/controller.d.ts.map +1 -0
- package/dist/declarations/src/structure/structure.d.ts +4 -0
- package/dist/declarations/src/structure/structure.d.ts.map +1 -0
- package/dist/declarations/src/structure-views.d.ts +5 -0
- package/dist/declarations/src/structure-views.d.ts.map +1 -0
- package/dist/declarations/src/types/DocumentFeatures.d.ts +33 -0
- package/dist/declarations/src/types/DocumentFeatures.d.ts.map +1 -0
- package/dist/declarations/src/types/DocumentFieldConfig.d.ts +18 -0
- package/dist/declarations/src/types/DocumentFieldConfig.d.ts.map +1 -0
- package/dist/declarations/src/types/FormattingConfig.d.ts +28 -0
- package/dist/declarations/src/types/FormattingConfig.d.ts.map +1 -0
- package/dist/declarations/src/types/RelationshipsConfig.d.ts +9 -0
- package/dist/declarations/src/types/RelationshipsConfig.d.ts.map +1 -0
- package/dist/declarations/src/types/StructureFieldConfig.d.ts +10 -0
- package/dist/declarations/src/types/StructureFieldConfig.d.ts.map +1 -0
- package/dist/declarations/src/validation/structure-validation.d.ts +218 -0
- package/dist/declarations/src/validation/structure-validation.d.ts.map +1 -0
- package/dist/declarations/src/views/Cell.d.ts +5 -0
- package/dist/declarations/src/views/Cell.d.ts.map +1 -0
- package/dist/declarations/src/views/Field.d.ts +5 -0
- package/dist/declarations/src/views/Field.d.ts.map +1 -0
- package/dist/declarations/src/views/controller.d.ts +15 -0
- package/dist/declarations/src/views/controller.d.ts.map +1 -0
- package/dist/declarations/src/views/document.d.ts +4 -0
- package/dist/declarations/src/views/document.d.ts.map +1 -0
- package/dist/declarations/src/views.d.ts +7 -0
- package/dist/declarations/src/views.d.ts.map +1 -0
- package/dist/editor-shared-a6e340e6.node.esm.js +1993 -0
- package/dist/editor-shared-a997ae98.node.cjs.js +2007 -0
- package/dist/editor-shared-cc1293ed.cjs.js +2007 -0
- package/dist/editor-shared-da518ba3.esm.js +1993 -0
- package/dist/form-from-preview-2042b9ef.cjs.js +512 -0
- package/dist/form-from-preview-5df6e492.node.esm.js +508 -0
- package/dist/form-from-preview-9e501058.node.cjs.js +512 -0
- package/dist/form-from-preview-b3a66f37.esm.js +508 -0
- package/dist/index-06c36775.cjs.js +14 -0
- package/dist/index-586adb8f.node.esm.js +11 -0
- package/dist/index-67d52357.esm.js +11 -0
- package/dist/index-c3223fdc.node.cjs.js +14 -0
- package/dist/layouts-6412fa2a.esm.js +189 -0
- package/dist/layouts-a4a3cf0b.node.cjs.js +196 -0
- package/dist/layouts-ba9a558b.cjs.js +196 -0
- package/dist/layouts-e653b908.node.esm.js +189 -0
- package/dist/lkb-fields-document.cjs.d.ts +2 -0
- package/dist/lkb-fields-document.cjs.js +1167 -0
- package/dist/lkb-fields-document.esm.js +1162 -0
- package/dist/lkb-fields-document.node.cjs.js +1167 -0
- package/dist/lkb-fields-document.node.esm.js +1162 -0
- package/dist/shared-0533009e.cjs.js +594 -0
- package/dist/shared-4684cc24.node.cjs.js +594 -0
- package/dist/shared-5e864055.node.esm.js +579 -0
- package/dist/shared-aaba5901.esm.js +579 -0
- package/dist/toolbar-state-3359e2f3.cjs.js +994 -0
- package/dist/toolbar-state-945823b8.node.esm.js +971 -0
- package/dist/toolbar-state-9611743f.node.cjs.js +994 -0
- package/dist/toolbar-state-bc8fe661.esm.js +971 -0
- package/dist/utils-06bcddc4.node.cjs.js +747 -0
- package/dist/utils-200ff260.node.esm.js +722 -0
- package/dist/utils-6409f730.cjs.js +747 -0
- package/dist/utils-bc6a0b82.esm.js +722 -0
- package/package.json +118 -0
- package/structure-views/dist/lkb-fields-document-structure-views.cjs.d.ts +2 -0
- package/structure-views/dist/lkb-fields-document-structure-views.cjs.js +138 -0
- package/structure-views/dist/lkb-fields-document-structure-views.esm.js +131 -0
- package/structure-views/dist/lkb-fields-document-structure-views.node.cjs.js +138 -0
- package/structure-views/dist/lkb-fields-document-structure-views.node.esm.js +131 -0
- package/structure-views/package.json +4 -0
- package/views/dist/lkb-fields-document-views.cjs.d.ts +2 -0
- package/views/dist/lkb-fields-document-views.cjs.js +114 -0
- package/views/dist/lkb-fields-document-views.esm.js +95 -0
- package/views/dist/lkb-fields-document-views.node.cjs.js +114 -0
- package/views/dist/lkb-fields-document-views.node.esm.js +95 -0
- package/views/package.json +4 -0
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var slateReact = require('slate-react');
|
|
5
|
+
var slate = require('slate');
|
|
6
|
+
var style = require('@keystar/ui/style');
|
|
7
|
+
var utils = require('./utils-6409f730.cjs.js');
|
|
8
|
+
var shared = require('./shared-0533009e.cjs.js');
|
|
9
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
+
var icon = require('@keystar/ui/icon');
|
|
11
|
+
var trash2Icon = require('@keystar/ui/icon/icons/trash2Icon');
|
|
12
|
+
var button = require('@keystar/ui/button');
|
|
13
|
+
var typography = require('@keystar/ui/typography');
|
|
14
|
+
var api = require('./api-73636987.cjs.js');
|
|
15
|
+
var formFromPreview = require('./form-from-preview-2042b9ef.cjs.js');
|
|
16
|
+
var dialog = require('@keystar/ui/dialog');
|
|
17
|
+
var field = require('@keystar/ui/field');
|
|
18
|
+
var layout = require('@keystar/ui/layout');
|
|
19
|
+
var slots = require('@keystar/ui/slots');
|
|
20
|
+
var tooltip = require('@keystar/ui/tooltip');
|
|
21
|
+
var trashIcon = require('@keystar/ui/icon/icons/trashIcon');
|
|
22
|
+
var overlays$2 = require('@react-aria/overlays');
|
|
23
|
+
var utils$1 = require('@react-aria/utils');
|
|
24
|
+
var overlays = require('@react-stately/overlays');
|
|
25
|
+
var overlays$1 = require('@keystar/ui/overlays');
|
|
26
|
+
require('@emotion/weak-memoize');
|
|
27
|
+
var layouts = require('./layouts-ba9a558b.cjs.js');
|
|
28
|
+
var context = require('lkb-core/admin-ui/context');
|
|
29
|
+
var views = require('lkb-core/fields/types/relationship/views');
|
|
30
|
+
|
|
31
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
32
|
+
|
|
33
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
34
|
+
|
|
35
|
+
// this ensures that when changes happen, they are immediately shown
|
|
36
|
+
// this stops the problem of a cursor resetting to the end when a change is made
|
|
37
|
+
// because the changes are applied asynchronously
|
|
38
|
+
function useElementWithSetNodes(editor, element) {
|
|
39
|
+
const [state, setState] = React.useState({
|
|
40
|
+
element,
|
|
41
|
+
elementWithChanges: element
|
|
42
|
+
});
|
|
43
|
+
if (state.element !== element) {
|
|
44
|
+
setState({
|
|
45
|
+
element,
|
|
46
|
+
elementWithChanges: element
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const elementRef = React.useRef(element);
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
elementRef.current = element;
|
|
52
|
+
});
|
|
53
|
+
const setNodes = React.useCallback(changesOrCallback => {
|
|
54
|
+
const currentElement = elementRef.current;
|
|
55
|
+
const changes = typeof changesOrCallback === 'function' ? changesOrCallback(currentElement) : changesOrCallback;
|
|
56
|
+
slate.Transforms.setNodes(editor, changes, {
|
|
57
|
+
at: slateReact.ReactEditor.findPath(editor, currentElement)
|
|
58
|
+
});
|
|
59
|
+
setState({
|
|
60
|
+
element: currentElement,
|
|
61
|
+
elementWithChanges: {
|
|
62
|
+
...currentElement,
|
|
63
|
+
...changes
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}, [editor]);
|
|
67
|
+
return [state.elementWithChanges, setNodes];
|
|
68
|
+
}
|
|
69
|
+
function useEventCallback(callback) {
|
|
70
|
+
const callbackRef = React.useRef(callback);
|
|
71
|
+
const cb = React.useCallback((...args) => {
|
|
72
|
+
return callbackRef.current(...args);
|
|
73
|
+
}, []);
|
|
74
|
+
React.useEffect(() => {
|
|
75
|
+
callbackRef.current = callback;
|
|
76
|
+
});
|
|
77
|
+
return cb;
|
|
78
|
+
}
|
|
79
|
+
const ForceValidationContext = /*#__PURE__*/React__default["default"].createContext(false);
|
|
80
|
+
const ForceValidationProvider = ForceValidationContext.Provider;
|
|
81
|
+
function focusWithPreviousSelection(editor) {
|
|
82
|
+
const selection = window.getSelection();
|
|
83
|
+
if (selection) {
|
|
84
|
+
selection.removeAllRanges();
|
|
85
|
+
selection.addRange(slateReact.ReactEditor.toDOMRange(editor, editor.selection));
|
|
86
|
+
}
|
|
87
|
+
slateReact.ReactEditor.focus(editor);
|
|
88
|
+
}
|
|
89
|
+
const blockElementSpacing = style.css({
|
|
90
|
+
marginBlock: '0.75em',
|
|
91
|
+
'&:first-child': {
|
|
92
|
+
marginBlockStart: 0
|
|
93
|
+
},
|
|
94
|
+
'&:last-child': {
|
|
95
|
+
marginBlockEnd: 0
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
function updateComponentBlockElementProps(editor, componentBlock, prevProps, newProps, basePath, setElement) {
|
|
100
|
+
slate.Editor.withoutNormalizing(editor, () => {
|
|
101
|
+
setElement({
|
|
102
|
+
props: newProps
|
|
103
|
+
});
|
|
104
|
+
const childPropPaths = findChildPropPathsWithPrevious(newProps, prevProps, {
|
|
105
|
+
kind: 'object',
|
|
106
|
+
fields: componentBlock.schema
|
|
107
|
+
}, [], [], []);
|
|
108
|
+
const getNode = () => slate.Node.get(editor, basePath);
|
|
109
|
+
const elementForChildren = getNode();
|
|
110
|
+
if (childPropPaths.length === 0) {
|
|
111
|
+
const indexes = elementForChildren.children.map((_, i) => i).reverse();
|
|
112
|
+
for (const idx of indexes) {
|
|
113
|
+
slate.Transforms.removeNodes(editor, {
|
|
114
|
+
at: [...basePath, idx]
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
slate.Transforms.insertNodes(editor, {
|
|
118
|
+
type: 'component-inline-prop',
|
|
119
|
+
propPath: undefined,
|
|
120
|
+
children: [{
|
|
121
|
+
text: ''
|
|
122
|
+
}]
|
|
123
|
+
}, {
|
|
124
|
+
at: [...basePath, 0]
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const initialPropPathsToEditorPath = new Map();
|
|
129
|
+
for (const [idx, node] of elementForChildren.children.entries()) {
|
|
130
|
+
utils.assert(node.type === 'component-block-prop' || node.type === 'component-inline-prop');
|
|
131
|
+
initialPropPathsToEditorPath.set(node.propPath === undefined ? undefined : JSON.stringify(node.propPath), idx);
|
|
132
|
+
}
|
|
133
|
+
const childrenLeftToAdd = new Set(childPropPaths);
|
|
134
|
+
for (const childProp of childPropPaths) {
|
|
135
|
+
if (childProp.prevPath === undefined) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const stringifiedPath = JSON.stringify(childProp.prevPath);
|
|
139
|
+
const idxInChildren = initialPropPathsToEditorPath.get(stringifiedPath);
|
|
140
|
+
if (idxInChildren !== undefined) {
|
|
141
|
+
const prevNode = elementForChildren.children[idxInChildren];
|
|
142
|
+
utils.assert(prevNode.propPath !== undefined);
|
|
143
|
+
if (!shared.areArraysEqual(childProp.path, prevNode.propPath)) {
|
|
144
|
+
slate.Transforms.setNodes(editor, {
|
|
145
|
+
propPath: childProp.path
|
|
146
|
+
}, {
|
|
147
|
+
at: [...basePath, idxInChildren]
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
childrenLeftToAdd.delete(childProp);
|
|
151
|
+
initialPropPathsToEditorPath.delete(stringifiedPath);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
let newIdx = getNode().children.length;
|
|
155
|
+
for (const childProp of childrenLeftToAdd) {
|
|
156
|
+
slate.Transforms.insertNodes(editor, {
|
|
157
|
+
type: `component-${childProp.options.kind}-prop`,
|
|
158
|
+
propPath: childProp.path,
|
|
159
|
+
children: [childProp.options.kind === 'block' ? {
|
|
160
|
+
type: 'paragraph',
|
|
161
|
+
children: [{
|
|
162
|
+
text: ''
|
|
163
|
+
}]
|
|
164
|
+
} : {
|
|
165
|
+
text: ''
|
|
166
|
+
}]
|
|
167
|
+
}, {
|
|
168
|
+
at: [...basePath, newIdx]
|
|
169
|
+
});
|
|
170
|
+
newIdx++;
|
|
171
|
+
}
|
|
172
|
+
const pathsToRemove = [];
|
|
173
|
+
for (const [, idxInChildren] of initialPropPathsToEditorPath) {
|
|
174
|
+
pathsToRemove.push(slate.Editor.pathRef(editor, [...basePath, idxInChildren]));
|
|
175
|
+
}
|
|
176
|
+
for (const pathRef of pathsToRemove) {
|
|
177
|
+
const path = pathRef.unref();
|
|
178
|
+
utils.assert(path !== null);
|
|
179
|
+
slate.Transforms.removeNodes(editor, {
|
|
180
|
+
at: path
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
const propPathsToExpectedIndexes = new Map();
|
|
184
|
+
for (const [idx, thing] of childPropPaths.entries()) {
|
|
185
|
+
propPathsToExpectedIndexes.set(JSON.stringify(thing.path), idx);
|
|
186
|
+
}
|
|
187
|
+
outer: while (true) {
|
|
188
|
+
for (const [idx, childNode] of getNode().children.entries()) {
|
|
189
|
+
utils.assert(childNode.type === 'component-block-prop' || childNode.type === 'component-inline-prop');
|
|
190
|
+
const expectedIndex = propPathsToExpectedIndexes.get(JSON.stringify(childNode.propPath));
|
|
191
|
+
utils.assert(expectedIndex !== undefined);
|
|
192
|
+
if (idx === expectedIndex) continue;
|
|
193
|
+
slate.Transforms.moveNodes(editor, {
|
|
194
|
+
at: [...basePath, idx],
|
|
195
|
+
to: [...basePath, expectedIndex]
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// start the for-loop again
|
|
199
|
+
continue outer;
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function findChildPropPathsWithPrevious(value, prevValue, schema, newPath, prevPath, pathWithKeys) {
|
|
206
|
+
switch (schema.kind) {
|
|
207
|
+
case 'form':
|
|
208
|
+
return [];
|
|
209
|
+
case 'relationship':
|
|
210
|
+
return [];
|
|
211
|
+
case 'child':
|
|
212
|
+
return [{
|
|
213
|
+
path: newPath,
|
|
214
|
+
prevPath,
|
|
215
|
+
options: schema.options
|
|
216
|
+
}];
|
|
217
|
+
case 'conditional':
|
|
218
|
+
{
|
|
219
|
+
const hasChangedDiscriminant = value.discriminant === prevValue.discriminant;
|
|
220
|
+
return findChildPropPathsWithPrevious(value.value, hasChangedDiscriminant ? prevValue.value : utils.getInitialPropsValue(schema.values[value.discriminant]), schema.values[value.discriminant], newPath.concat('value'), hasChangedDiscriminant ? undefined : prevPath === null || prevPath === void 0 ? void 0 : prevPath.concat('value'), hasChangedDiscriminant ? undefined : pathWithKeys === null || pathWithKeys === void 0 ? void 0 : pathWithKeys.concat('value'));
|
|
221
|
+
}
|
|
222
|
+
case 'object':
|
|
223
|
+
{
|
|
224
|
+
const paths = [];
|
|
225
|
+
for (const key of Object.keys(schema.fields)) {
|
|
226
|
+
paths.push(...findChildPropPathsWithPrevious(value[key], prevValue[key], schema.fields[key], newPath.concat(key), prevPath === null || prevPath === void 0 ? void 0 : prevPath.concat(key), pathWithKeys === null || pathWithKeys === void 0 ? void 0 : pathWithKeys.concat(key)));
|
|
227
|
+
}
|
|
228
|
+
return paths;
|
|
229
|
+
}
|
|
230
|
+
case 'array':
|
|
231
|
+
{
|
|
232
|
+
const paths = [];
|
|
233
|
+
const prevKeys = utils.getKeysForArrayValue(prevValue);
|
|
234
|
+
const keys = utils.getKeysForArrayValue(value);
|
|
235
|
+
for (const [i, val] of value.entries()) {
|
|
236
|
+
const key = keys[i];
|
|
237
|
+
const prevIdx = prevKeys.indexOf(key);
|
|
238
|
+
let prevVal;
|
|
239
|
+
if (prevIdx === -1) {
|
|
240
|
+
prevVal = utils.getInitialPropsValue(schema.element);
|
|
241
|
+
} else {
|
|
242
|
+
prevVal = prevValue[prevIdx];
|
|
243
|
+
}
|
|
244
|
+
paths.push(...findChildPropPathsWithPrevious(val, prevVal, schema.element, newPath.concat(i), prevIdx === -1 ? undefined : prevPath === null || prevPath === void 0 ? void 0 : prevPath.concat(prevIdx), prevIdx === -1 ? undefined : pathWithKeys === null || pathWithKeys === void 0 ? void 0 : pathWithKeys.concat(key)));
|
|
245
|
+
}
|
|
246
|
+
return paths;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const ChildrenByPathContext = /*#__PURE__*/React__default["default"].createContext({});
|
|
252
|
+
function ChildFieldEditable({
|
|
253
|
+
path
|
|
254
|
+
}) {
|
|
255
|
+
const childrenByPath = React.useContext(ChildrenByPathContext);
|
|
256
|
+
const child = childrenByPath[JSON.stringify(path)];
|
|
257
|
+
if (child === undefined) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
return child;
|
|
261
|
+
}
|
|
262
|
+
function ComponentBlockRender({
|
|
263
|
+
componentBlock,
|
|
264
|
+
element,
|
|
265
|
+
onChange,
|
|
266
|
+
children
|
|
267
|
+
}) {
|
|
268
|
+
const getPreviewProps = React.useMemo(() => {
|
|
269
|
+
return utils.createGetPreviewProps({
|
|
270
|
+
kind: 'object',
|
|
271
|
+
fields: componentBlock.schema
|
|
272
|
+
}, onChange, path => /*#__PURE__*/jsxRuntime.jsx(ChildFieldEditable, {
|
|
273
|
+
path: path
|
|
274
|
+
}));
|
|
275
|
+
}, [onChange, componentBlock]);
|
|
276
|
+
const previewProps = getPreviewProps(element.props);
|
|
277
|
+
const childrenByPath = {};
|
|
278
|
+
let maybeChild;
|
|
279
|
+
for (const child of children) {
|
|
280
|
+
const propPath = child.props.children.props.element.propPath;
|
|
281
|
+
if (propPath === undefined) {
|
|
282
|
+
maybeChild = child;
|
|
283
|
+
} else {
|
|
284
|
+
childrenByPath[JSON.stringify(propPathWithIndiciesToKeys(propPath, element.props))] = child;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const ComponentBlockPreview = componentBlock.preview;
|
|
288
|
+
return /*#__PURE__*/jsxRuntime.jsxs(ChildrenByPathContext.Provider, {
|
|
289
|
+
value: childrenByPath,
|
|
290
|
+
children: [React.useMemo(() => /*#__PURE__*/jsxRuntime.jsx(ComponentBlockPreview, {
|
|
291
|
+
...previewProps
|
|
292
|
+
}), [previewProps, ComponentBlockPreview]), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
293
|
+
className: style.css({
|
|
294
|
+
caretColor: 'transparent',
|
|
295
|
+
'& ::selection': {
|
|
296
|
+
backgroundColor: 'transparent'
|
|
297
|
+
}
|
|
298
|
+
}),
|
|
299
|
+
children: maybeChild
|
|
300
|
+
})]
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// note this is written to avoid crashing when the given prop path doesn't exist in the value
|
|
305
|
+
// this is because editor updates happen asynchronously but we have some logic to ensure
|
|
306
|
+
// that updating the props of a component block synchronously updates it
|
|
307
|
+
// (this is primarily to not mess up things like cursors in inputs)
|
|
308
|
+
// this means that sometimes the child elements will be inconsistent with the values
|
|
309
|
+
// so to deal with this, we return a prop path this is "wrong" but won't break anything
|
|
310
|
+
function propPathWithIndiciesToKeys(propPath, val) {
|
|
311
|
+
return propPath.map(key => {
|
|
312
|
+
var _val2;
|
|
313
|
+
if (typeof key === 'string') {
|
|
314
|
+
var _val;
|
|
315
|
+
val = (_val = val) === null || _val === void 0 ? void 0 : _val[key];
|
|
316
|
+
return key;
|
|
317
|
+
}
|
|
318
|
+
if (!Array.isArray(val)) {
|
|
319
|
+
val = undefined;
|
|
320
|
+
return '';
|
|
321
|
+
}
|
|
322
|
+
const keys = utils.getKeysForArrayValue(val);
|
|
323
|
+
val = (_val2 = val) === null || _val2 === void 0 ? void 0 : _val2[key];
|
|
324
|
+
return keys[key];
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function ChromefulComponentBlockElement(props) {
|
|
329
|
+
var _props$componentBlock;
|
|
330
|
+
const selected = slateReact.useSelected();
|
|
331
|
+
const isValid = React.useMemo(() => utils.clientSideValidateProp({
|
|
332
|
+
kind: 'object',
|
|
333
|
+
fields: props.componentBlock.schema
|
|
334
|
+
}, props.elementProps), [props.componentBlock, props.elementProps]);
|
|
335
|
+
const [editMode, setEditMode] = React.useState(false);
|
|
336
|
+
const onCloseEditMode = React.useCallback(() => {
|
|
337
|
+
setEditMode(false);
|
|
338
|
+
}, []);
|
|
339
|
+
const onShowEditMode = React.useCallback(() => {
|
|
340
|
+
setEditMode(true);
|
|
341
|
+
}, []);
|
|
342
|
+
const ChromefulToolbar = (_props$componentBlock = props.componentBlock.toolbar) !== null && _props$componentBlock !== void 0 ? _props$componentBlock : DefaultToolbarWithChrome;
|
|
343
|
+
return /*#__PURE__*/jsxRuntime.jsx(BlockPrimitive, {
|
|
344
|
+
selected: selected,
|
|
345
|
+
...props.attributes,
|
|
346
|
+
children: /*#__PURE__*/jsxRuntime.jsx(layout.Flex, {
|
|
347
|
+
gap: "medium",
|
|
348
|
+
direction: "column",
|
|
349
|
+
children: /*#__PURE__*/jsxRuntime.jsx(React.Fragment, {
|
|
350
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
351
|
+
children: [props.renderedBlock, /*#__PURE__*/jsxRuntime.jsx(ChromefulToolbar, {
|
|
352
|
+
isValid: isValid,
|
|
353
|
+
onRemove: props.onRemove,
|
|
354
|
+
props: props.previewProps,
|
|
355
|
+
onShowEditMode: onShowEditMode
|
|
356
|
+
}), /*#__PURE__*/jsxRuntime.jsx(dialog.DialogContainer, {
|
|
357
|
+
onDismiss: () => onCloseEditMode(),
|
|
358
|
+
children: (() => {
|
|
359
|
+
if (!editMode) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
return /*#__PURE__*/jsxRuntime.jsxs(dialog.Dialog, {
|
|
363
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs(typography.Heading, {
|
|
364
|
+
children: ["\u7F16\u8F91\u3010", props.componentBlock.label, "\u3011\u5C5E\u6027"]
|
|
365
|
+
}), /*#__PURE__*/jsxRuntime.jsx(FormValue, {
|
|
366
|
+
props: props.previewProps,
|
|
367
|
+
onClose: onCloseEditMode
|
|
368
|
+
})]
|
|
369
|
+
});
|
|
370
|
+
})()
|
|
371
|
+
})]
|
|
372
|
+
})
|
|
373
|
+
})
|
|
374
|
+
})
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Wrap block content, delimiting it from surrounding content, and provide a
|
|
380
|
+
* focus indicator because the cursor may not be present.
|
|
381
|
+
*/
|
|
382
|
+
const BlockPrimitive = /*#__PURE__*/React.forwardRef(function BlockPrimitive({
|
|
383
|
+
children,
|
|
384
|
+
selected,
|
|
385
|
+
...attributes
|
|
386
|
+
}, ref) {
|
|
387
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
388
|
+
...attributes,
|
|
389
|
+
ref: ref,
|
|
390
|
+
className: style.css(blockElementSpacing, {
|
|
391
|
+
position: 'relative',
|
|
392
|
+
paddingInlineStart: 0,
|
|
393
|
+
// tokenSchema.size.space.xlarge,
|
|
394
|
+
marginBottom: 0,
|
|
395
|
+
// tokenSchema.size.space.xlarge,
|
|
396
|
+
|
|
397
|
+
'::before': {
|
|
398
|
+
display: 'block',
|
|
399
|
+
content: '" "',
|
|
400
|
+
backgroundColor: selected ? style.tokenSchema.color.alias.borderSelected : style.tokenSchema.color.alias.borderIdle,
|
|
401
|
+
borderRadius: 4,
|
|
402
|
+
width: 0,
|
|
403
|
+
// 4,
|
|
404
|
+
position: 'absolute',
|
|
405
|
+
left: 0,
|
|
406
|
+
top: 0,
|
|
407
|
+
bottom: 0,
|
|
408
|
+
zIndex: 1
|
|
409
|
+
}
|
|
410
|
+
}),
|
|
411
|
+
children: children
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
function DefaultToolbarWithChrome({
|
|
415
|
+
onShowEditMode,
|
|
416
|
+
onRemove,
|
|
417
|
+
isValid
|
|
418
|
+
}) {
|
|
419
|
+
return /*#__PURE__*/jsxRuntime.jsx(api.NotEditable, {
|
|
420
|
+
children: /*#__PURE__*/jsxRuntime.jsxs(layout.Flex, {
|
|
421
|
+
direction: "column",
|
|
422
|
+
gap: "medium",
|
|
423
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs(layout.Flex, {
|
|
424
|
+
alignItems: "center",
|
|
425
|
+
gap: "regular",
|
|
426
|
+
UNSAFE_style: {
|
|
427
|
+
userSelect: 'none'
|
|
428
|
+
},
|
|
429
|
+
justifyContent: "flex-end",
|
|
430
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs(tooltip.TooltipTrigger, {
|
|
431
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(button.ActionButton, {
|
|
432
|
+
prominence: "low",
|
|
433
|
+
onPress: onRemove,
|
|
434
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icon.Icon, {
|
|
435
|
+
src: trash2Icon.trash2Icon
|
|
436
|
+
})
|
|
437
|
+
}), /*#__PURE__*/jsxRuntime.jsx(tooltip.Tooltip, {
|
|
438
|
+
tone: "critical",
|
|
439
|
+
children: "\u5220\u9664"
|
|
440
|
+
})]
|
|
441
|
+
}), /*#__PURE__*/jsxRuntime.jsx(button.ActionButton, {
|
|
442
|
+
onPress: () => onShowEditMode(),
|
|
443
|
+
children: "\u7F16\u8F91"
|
|
444
|
+
})]
|
|
445
|
+
}), !isValid && /*#__PURE__*/jsxRuntime.jsx(field.FieldMessage, {
|
|
446
|
+
children: "Contains invalid fields. Please edit."
|
|
447
|
+
})]
|
|
448
|
+
})
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
function FormValue({
|
|
452
|
+
onClose,
|
|
453
|
+
props
|
|
454
|
+
}) {
|
|
455
|
+
const formId = React.useId();
|
|
456
|
+
const [forceValidation, setForceValidation] = React.useState(false);
|
|
457
|
+
const [state, setState] = React.useState(() => formFromPreview.previewPropsToValue(props));
|
|
458
|
+
const previewProps = React.useMemo(() => utils.createGetPreviewProps(props.schema, setState, () => undefined), [props.schema])(state);
|
|
459
|
+
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
460
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(slots.Content, {
|
|
461
|
+
children: /*#__PURE__*/jsxRuntime.jsx(layout.Flex, {
|
|
462
|
+
id: formId,
|
|
463
|
+
elementType: "form",
|
|
464
|
+
onSubmit: event => {
|
|
465
|
+
if (event.target !== event.currentTarget) return;
|
|
466
|
+
event.preventDefault();
|
|
467
|
+
if (!utils.clientSideValidateProp(props.schema, state)) {
|
|
468
|
+
setForceValidation(true);
|
|
469
|
+
} else {
|
|
470
|
+
formFromPreview.previewPropsOnChange(state, props);
|
|
471
|
+
onClose();
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
direction: "column",
|
|
475
|
+
gap: "xxlarge",
|
|
476
|
+
children: /*#__PURE__*/jsxRuntime.jsx(formFromPreview.FormValueContentFromPreviewProps, {
|
|
477
|
+
...previewProps,
|
|
478
|
+
forceValidation: forceValidation
|
|
479
|
+
})
|
|
480
|
+
})
|
|
481
|
+
}), /*#__PURE__*/jsxRuntime.jsxs(button.ButtonGroup, {
|
|
482
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(button.Button, {
|
|
483
|
+
onPress: onClose,
|
|
484
|
+
children: "\u53D6\u6D88"
|
|
485
|
+
}), /*#__PURE__*/jsxRuntime.jsx(button.Button, {
|
|
486
|
+
form: formId,
|
|
487
|
+
prominence: "high",
|
|
488
|
+
type: "submit",
|
|
489
|
+
children: "\u786E\u5B9A"
|
|
490
|
+
})]
|
|
491
|
+
})]
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const BlockPopoverContext = /*#__PURE__*/React.createContext(null);
|
|
496
|
+
function useBlockPopoverContext() {
|
|
497
|
+
const context = React.useContext(BlockPopoverContext);
|
|
498
|
+
if (!context) {
|
|
499
|
+
throw new Error('useBlockPopoverContext must be used within a BlockPopoverTrigger');
|
|
500
|
+
}
|
|
501
|
+
return context;
|
|
502
|
+
}
|
|
503
|
+
const typeMatcher = utils.nodeTypeMatcher('code', 'component-block', 'layout', 'link', 'heading');
|
|
504
|
+
const ActiveBlockPopoverContext = /*#__PURE__*/React.createContext(undefined);
|
|
505
|
+
function useActiveBlockPopover() {
|
|
506
|
+
return React.useContext(ActiveBlockPopoverContext);
|
|
507
|
+
}
|
|
508
|
+
function ActiveBlockPopoverProvider(props) {
|
|
509
|
+
const nodeWithPopover = slate.Editor.above(props.editor, {
|
|
510
|
+
match: typeMatcher
|
|
511
|
+
});
|
|
512
|
+
return /*#__PURE__*/jsxRuntime.jsx(ActiveBlockPopoverContext.Provider, {
|
|
513
|
+
value: nodeWithPopover === null || nodeWithPopover === void 0 ? void 0 : nodeWithPopover[0],
|
|
514
|
+
children: props.children
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
const BlockPopoverTrigger = ({
|
|
518
|
+
children,
|
|
519
|
+
element
|
|
520
|
+
}) => {
|
|
521
|
+
const [trigger, popover] = children;
|
|
522
|
+
const activePopoverElement = useActiveBlockPopover();
|
|
523
|
+
const triggerRef = React.useRef(null);
|
|
524
|
+
const state = overlays.useOverlayTriggerState({
|
|
525
|
+
isOpen: activePopoverElement === element
|
|
526
|
+
});
|
|
527
|
+
const context = React.useMemo(() => ({
|
|
528
|
+
state,
|
|
529
|
+
triggerRef
|
|
530
|
+
}), [state, triggerRef]);
|
|
531
|
+
return /*#__PURE__*/jsxRuntime.jsxs(BlockPopoverContext.Provider, {
|
|
532
|
+
value: context,
|
|
533
|
+
children: [/*#__PURE__*/React.cloneElement(trigger, {
|
|
534
|
+
ref: triggerRef
|
|
535
|
+
}), popover]
|
|
536
|
+
});
|
|
537
|
+
};
|
|
538
|
+
function BlockPopover(props) {
|
|
539
|
+
const {
|
|
540
|
+
state
|
|
541
|
+
} = useBlockPopoverContext();
|
|
542
|
+
let wrapperRef = React.useRef(null);
|
|
543
|
+
return /*#__PURE__*/jsxRuntime.jsx(overlays$1.Overlay, {
|
|
544
|
+
isOpen: state.isOpen,
|
|
545
|
+
nodeRef: wrapperRef,
|
|
546
|
+
children: /*#__PURE__*/jsxRuntime.jsx(BlockPopoverWrapper, {
|
|
547
|
+
wrapperRef: wrapperRef,
|
|
548
|
+
...props
|
|
549
|
+
})
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
const BlockPopoverWrapper = ({
|
|
553
|
+
children,
|
|
554
|
+
placement: preferredPlacement = 'bottom'
|
|
555
|
+
}) => {
|
|
556
|
+
let popoverRef = React.useRef(null);
|
|
557
|
+
let {
|
|
558
|
+
state,
|
|
559
|
+
triggerRef
|
|
560
|
+
} = useBlockPopoverContext();
|
|
561
|
+
let {
|
|
562
|
+
placement,
|
|
563
|
+
popoverProps
|
|
564
|
+
} = useBlockPopover({
|
|
565
|
+
isNonModal: true,
|
|
566
|
+
isKeyboardDismissDisabled: false,
|
|
567
|
+
placement: preferredPlacement,
|
|
568
|
+
triggerRef,
|
|
569
|
+
popoverRef
|
|
570
|
+
}, state);
|
|
571
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
572
|
+
ref: popoverRef,
|
|
573
|
+
...popoverProps,
|
|
574
|
+
"data-open": state.isOpen,
|
|
575
|
+
"data-placement": placement,
|
|
576
|
+
contentEditable: false,
|
|
577
|
+
className: style.css({
|
|
578
|
+
backgroundColor: style.tokenSchema.color.background.surface,
|
|
579
|
+
// TODO: component token?
|
|
580
|
+
borderRadius: style.tokenSchema.size.radius.medium,
|
|
581
|
+
// TODO: component token?
|
|
582
|
+
border: `${style.tokenSchema.size.border.regular} solid ${style.tokenSchema.color.border.emphasis}`,
|
|
583
|
+
boxSizing: 'content-box',
|
|
584
|
+
// resolves measurement/scroll issues related to border
|
|
585
|
+
// boxShadow: `0 0 0 ${tokenSchema.size.border.regular} ${tokenSchema.color.border.emphasis}`,
|
|
586
|
+
minHeight: style.tokenSchema.size.element.regular,
|
|
587
|
+
minWidth: style.tokenSchema.size.element.regular,
|
|
588
|
+
opacity: 0,
|
|
589
|
+
outline: 0,
|
|
590
|
+
pointerEvents: 'auto',
|
|
591
|
+
position: 'absolute',
|
|
592
|
+
// use filter:drop-shadow instead of box-shadow so the arrow is included
|
|
593
|
+
filter: `drop-shadow(0 1px 4px ${style.tokenSchema.color.shadow.regular})`,
|
|
594
|
+
// filter bug in safari: https://stackoverflow.com/questions/56478925/safari-drop-shadow-filter-remains-visible-even-with-hidden-element
|
|
595
|
+
willChange: 'filter',
|
|
596
|
+
userSelect: 'none',
|
|
597
|
+
// placement
|
|
598
|
+
'&[data-placement="top"]': {
|
|
599
|
+
marginBottom: style.tokenSchema.size.space.regular,
|
|
600
|
+
transform: `translateY(${style.tokenSchema.size.space.regular})`
|
|
601
|
+
},
|
|
602
|
+
'&[data-placement="bottom"]': {
|
|
603
|
+
marginTop: style.tokenSchema.size.space.regular,
|
|
604
|
+
transform: `translateY(calc(${style.tokenSchema.size.space.regular} * -1))`
|
|
605
|
+
},
|
|
606
|
+
'&[data-open="true"]': {
|
|
607
|
+
opacity: 1,
|
|
608
|
+
transform: `translateX(0) translateY(0)`,
|
|
609
|
+
// enter animation
|
|
610
|
+
transition: style.transition(['opacity', 'transform'], {
|
|
611
|
+
easing: 'easeOut'
|
|
612
|
+
})
|
|
613
|
+
}
|
|
614
|
+
}),
|
|
615
|
+
children: typeof children === 'function' ? children(state.close) : children
|
|
616
|
+
});
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Provides the behavior and accessibility implementation for a popover component.
|
|
621
|
+
* A popover is an overlay element positioned relative to a trigger.
|
|
622
|
+
*/
|
|
623
|
+
function useBlockPopover(props, state) {
|
|
624
|
+
var _triggerRef$current2;
|
|
625
|
+
let {
|
|
626
|
+
triggerRef,
|
|
627
|
+
popoverRef,
|
|
628
|
+
isNonModal,
|
|
629
|
+
isKeyboardDismissDisabled,
|
|
630
|
+
...otherProps
|
|
631
|
+
} = props;
|
|
632
|
+
let [isSticky, setSticky] = React.useState(false);
|
|
633
|
+
let {
|
|
634
|
+
overlayProps,
|
|
635
|
+
underlayProps
|
|
636
|
+
} = overlays$2.useOverlay({
|
|
637
|
+
isOpen: state.isOpen,
|
|
638
|
+
onClose: state.close,
|
|
639
|
+
shouldCloseOnBlur: true,
|
|
640
|
+
isDismissable: !isNonModal,
|
|
641
|
+
isKeyboardDismissDisabled: false
|
|
642
|
+
}, popoverRef);
|
|
643
|
+
|
|
644
|
+
// stick the popover to the bottom of the viewport instead of flipping
|
|
645
|
+
const containerPadding = 8;
|
|
646
|
+
React.useEffect(() => {
|
|
647
|
+
if (state.isOpen) {
|
|
648
|
+
const checkForStickiness = () => {
|
|
649
|
+
var _popoverRef$current, _triggerRef$current;
|
|
650
|
+
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
|
|
651
|
+
let popoverRect = (_popoverRef$current = popoverRef.current) === null || _popoverRef$current === void 0 ? void 0 : _popoverRef$current.getBoundingClientRect();
|
|
652
|
+
let triggerRect = (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : _triggerRef$current.getBoundingClientRect();
|
|
653
|
+
if (popoverRect && triggerRect) {
|
|
654
|
+
setSticky(triggerRect.bottom + popoverRect.height + containerPadding * 2 > vh && triggerRect.top < vh);
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
checkForStickiness();
|
|
658
|
+
window.addEventListener('scroll', checkForStickiness);
|
|
659
|
+
return () => {
|
|
660
|
+
checkForStickiness();
|
|
661
|
+
window.removeEventListener('scroll', checkForStickiness);
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
}, [popoverRef, triggerRef, state.isOpen]);
|
|
665
|
+
let {
|
|
666
|
+
overlayProps: positionProps,
|
|
667
|
+
arrowProps,
|
|
668
|
+
placement,
|
|
669
|
+
updatePosition
|
|
670
|
+
} = overlays$2.useOverlayPosition({
|
|
671
|
+
...otherProps,
|
|
672
|
+
containerPadding,
|
|
673
|
+
shouldFlip: false,
|
|
674
|
+
targetRef: triggerRef,
|
|
675
|
+
overlayRef: popoverRef,
|
|
676
|
+
isOpen: state.isOpen,
|
|
677
|
+
onClose: undefined
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
// force update position when the trigger changes
|
|
681
|
+
let previousBoundingRect = usePrevious((_triggerRef$current2 = triggerRef.current) === null || _triggerRef$current2 === void 0 ? void 0 : _triggerRef$current2.getBoundingClientRect());
|
|
682
|
+
utils$1.useLayoutEffect(() => {
|
|
683
|
+
if (previousBoundingRect) {
|
|
684
|
+
var _triggerRef$current3;
|
|
685
|
+
const currentBoundingRect = (_triggerRef$current3 = triggerRef.current) === null || _triggerRef$current3 === void 0 ? void 0 : _triggerRef$current3.getBoundingClientRect();
|
|
686
|
+
if (currentBoundingRect) {
|
|
687
|
+
const hasChanged = previousBoundingRect.height !== currentBoundingRect.height || previousBoundingRect.width !== currentBoundingRect.width || previousBoundingRect.x !== currentBoundingRect.x || previousBoundingRect.y !== currentBoundingRect.y;
|
|
688
|
+
if (hasChanged) {
|
|
689
|
+
updatePosition();
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}, [previousBoundingRect, triggerRef, updatePosition]);
|
|
694
|
+
|
|
695
|
+
// make sure popovers are below modal dialogs and their blanket
|
|
696
|
+
if (positionProps.style) {
|
|
697
|
+
positionProps.style.zIndex = 1;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// switching to position: fixed will undoubtedly bite me later, but this hack works for now
|
|
701
|
+
if (isSticky) {
|
|
702
|
+
positionProps.style = {
|
|
703
|
+
...positionProps.style,
|
|
704
|
+
// @ts-expect-error
|
|
705
|
+
maxHeight: null,
|
|
706
|
+
position: 'fixed',
|
|
707
|
+
// @ts-expect-error
|
|
708
|
+
top: null,
|
|
709
|
+
bottom: containerPadding
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
return {
|
|
713
|
+
arrowProps,
|
|
714
|
+
placement,
|
|
715
|
+
popoverProps: utils$1.mergeProps(overlayProps, positionProps),
|
|
716
|
+
underlayProps,
|
|
717
|
+
updatePosition
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
function usePrevious(value) {
|
|
721
|
+
const ref = React.useRef(undefined);
|
|
722
|
+
React.useEffect(() => {
|
|
723
|
+
ref.current = value;
|
|
724
|
+
});
|
|
725
|
+
return ref.current;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
function ChromelessComponentBlockElement(props) {
|
|
729
|
+
var _props$componentBlock;
|
|
730
|
+
const hasToolbar = props.componentBlock.toolbar !== null;
|
|
731
|
+
const ChromelessToolbar = (_props$componentBlock = props.componentBlock.toolbar) !== null && _props$componentBlock !== void 0 ? _props$componentBlock : DefaultToolbarWithoutChrome;
|
|
732
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
733
|
+
...props.attributes,
|
|
734
|
+
className: blockElementSpacing,
|
|
735
|
+
children: hasToolbar ? /*#__PURE__*/jsxRuntime.jsxs(BlockPopoverTrigger, {
|
|
736
|
+
element: props.element,
|
|
737
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
738
|
+
children: props.renderedBlock
|
|
739
|
+
}), /*#__PURE__*/jsxRuntime.jsx(BlockPopover, {
|
|
740
|
+
children: /*#__PURE__*/jsxRuntime.jsx(ChromelessToolbar, {
|
|
741
|
+
onRemove: props.onRemove,
|
|
742
|
+
props: props.previewProps
|
|
743
|
+
})
|
|
744
|
+
})]
|
|
745
|
+
}) : /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
746
|
+
children: props.renderedBlock
|
|
747
|
+
})
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
function DefaultToolbarWithoutChrome({
|
|
751
|
+
onRemove
|
|
752
|
+
}) {
|
|
753
|
+
return /*#__PURE__*/jsxRuntime.jsxs(tooltip.TooltipTrigger, {
|
|
754
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(button.ActionButton, {
|
|
755
|
+
onPress: onRemove,
|
|
756
|
+
margin: "regular",
|
|
757
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icon.Icon, {
|
|
758
|
+
src: trashIcon.trashIcon
|
|
759
|
+
})
|
|
760
|
+
}), /*#__PURE__*/jsxRuntime.jsx(tooltip.Tooltip, {
|
|
761
|
+
tone: "critical",
|
|
762
|
+
children: "Remove"
|
|
763
|
+
})]
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
const ComponentBlockContext = /*#__PURE__*/React.createContext({});
|
|
768
|
+
function ComponentInlineProp(props) {
|
|
769
|
+
return /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
770
|
+
...props.attributes,
|
|
771
|
+
children: props.children
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
function insertComponentBlock(editor, componentBlocks, componentBlock) {
|
|
775
|
+
const node = utils.getInitialValue(componentBlock, componentBlocks[componentBlock]);
|
|
776
|
+
utils.insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, node);
|
|
777
|
+
const componentBlockEntry = slate.Editor.above(editor, {
|
|
778
|
+
match: node => node.type === 'component-block'
|
|
779
|
+
});
|
|
780
|
+
if (componentBlockEntry) {
|
|
781
|
+
const start = slate.Editor.start(editor, componentBlockEntry[1]);
|
|
782
|
+
slate.Transforms.setSelection(editor, {
|
|
783
|
+
anchor: start,
|
|
784
|
+
focus: start
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
function ComponentBlocksElement({
|
|
789
|
+
attributes,
|
|
790
|
+
children,
|
|
791
|
+
element: __elementToGetPath
|
|
792
|
+
}) {
|
|
793
|
+
const editor = slateReact.useSlateStatic();
|
|
794
|
+
const [currentElement, setElement] = useElementWithSetNodes(editor, __elementToGetPath);
|
|
795
|
+
const blockComponents = React.useContext(ComponentBlockContext);
|
|
796
|
+
const componentBlock = blockComponents[currentElement.component];
|
|
797
|
+
const elementToGetPathRef = React.useRef({
|
|
798
|
+
__elementToGetPath,
|
|
799
|
+
currentElement
|
|
800
|
+
});
|
|
801
|
+
React.useEffect(() => {
|
|
802
|
+
elementToGetPathRef.current = {
|
|
803
|
+
__elementToGetPath,
|
|
804
|
+
currentElement
|
|
805
|
+
};
|
|
806
|
+
});
|
|
807
|
+
const onRemove = useEventCallback(() => {
|
|
808
|
+
const path = slateReact.ReactEditor.findPath(editor, __elementToGetPath);
|
|
809
|
+
slate.Transforms.removeNodes(editor, {
|
|
810
|
+
at: path
|
|
811
|
+
});
|
|
812
|
+
});
|
|
813
|
+
const onPropsChange = React.useCallback(cb => {
|
|
814
|
+
const prevProps = elementToGetPathRef.current.currentElement.props;
|
|
815
|
+
updateComponentBlockElementProps(editor, componentBlock, prevProps, cb(prevProps), slateReact.ReactEditor.findPath(editor, elementToGetPathRef.current.__elementToGetPath), setElement);
|
|
816
|
+
}, [setElement, componentBlock, editor]);
|
|
817
|
+
const getToolbarPreviewProps = React.useMemo(() => {
|
|
818
|
+
if (!componentBlock) {
|
|
819
|
+
return () => {
|
|
820
|
+
throw new Error('expected component block to exist when called');
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
return utils.createGetPreviewProps({
|
|
824
|
+
kind: 'object',
|
|
825
|
+
fields: componentBlock.schema
|
|
826
|
+
}, onPropsChange, () => undefined);
|
|
827
|
+
}, [componentBlock, onPropsChange]);
|
|
828
|
+
if (!componentBlock) {
|
|
829
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
830
|
+
className: style.css({
|
|
831
|
+
border: 'red 4px solid',
|
|
832
|
+
padding: style.tokenSchema.size.space.medium
|
|
833
|
+
}),
|
|
834
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("pre", {
|
|
835
|
+
contentEditable: false,
|
|
836
|
+
className: style.css({
|
|
837
|
+
userSelect: 'none'
|
|
838
|
+
}),
|
|
839
|
+
children: `The block "${currentElement.component}" no longer exists.
|
|
840
|
+
|
|
841
|
+
Props:
|
|
842
|
+
|
|
843
|
+
${JSON.stringify(currentElement.props, null, 2)}
|
|
844
|
+
|
|
845
|
+
Content:`
|
|
846
|
+
}), children]
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
const toolbarPreviewProps = getToolbarPreviewProps(currentElement.props);
|
|
850
|
+
const renderedBlock = /*#__PURE__*/jsxRuntime.jsx(ComponentBlockRender, {
|
|
851
|
+
children: children,
|
|
852
|
+
componentBlock: componentBlock,
|
|
853
|
+
element: currentElement,
|
|
854
|
+
onChange: onPropsChange
|
|
855
|
+
});
|
|
856
|
+
return componentBlock.chromeless ? /*#__PURE__*/jsxRuntime.jsx(ChromelessComponentBlockElement, {
|
|
857
|
+
attributes: attributes,
|
|
858
|
+
renderedBlock: renderedBlock,
|
|
859
|
+
componentBlock: componentBlock,
|
|
860
|
+
onRemove: onRemove,
|
|
861
|
+
element: __elementToGetPath,
|
|
862
|
+
previewProps: toolbarPreviewProps
|
|
863
|
+
}) : /*#__PURE__*/jsxRuntime.jsx(ChromefulComponentBlockElement, {
|
|
864
|
+
attributes: attributes,
|
|
865
|
+
children: children,
|
|
866
|
+
componentBlock: componentBlock,
|
|
867
|
+
onRemove: onRemove,
|
|
868
|
+
previewProps: toolbarPreviewProps,
|
|
869
|
+
renderedBlock: renderedBlock,
|
|
870
|
+
elementProps: currentElement.props
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
const DocumentFieldRelationshipsContext = /*#__PURE__*/React.createContext({});
|
|
875
|
+
function useDocumentFieldRelationships() {
|
|
876
|
+
return React.useContext(DocumentFieldRelationshipsContext);
|
|
877
|
+
}
|
|
878
|
+
const DocumentFieldRelationshipsProvider = DocumentFieldRelationshipsContext.Provider;
|
|
879
|
+
function RelationshipElement({
|
|
880
|
+
attributes,
|
|
881
|
+
children,
|
|
882
|
+
element
|
|
883
|
+
}) {
|
|
884
|
+
var _element$data$label;
|
|
885
|
+
const editor = slateReact.useSlateStatic();
|
|
886
|
+
const relationships = React.useContext(DocumentFieldRelationshipsContext);
|
|
887
|
+
const relationship = relationships[element.relationship];
|
|
888
|
+
const list = context.useList(relationship.listKey);
|
|
889
|
+
return /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
890
|
+
...attributes,
|
|
891
|
+
className: style.css({
|
|
892
|
+
display: 'inline-flex',
|
|
893
|
+
alignItems: 'center'
|
|
894
|
+
}),
|
|
895
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
896
|
+
contentEditable: false,
|
|
897
|
+
className: style.css({
|
|
898
|
+
userSelect: 'none',
|
|
899
|
+
width: 200,
|
|
900
|
+
display: 'inline-block',
|
|
901
|
+
paddingLeft: 4,
|
|
902
|
+
paddingRight: 4,
|
|
903
|
+
flex: 1
|
|
904
|
+
}),
|
|
905
|
+
children: relationship ? /*#__PURE__*/jsxRuntime.jsx(views.ComboboxSingle, {
|
|
906
|
+
list: list,
|
|
907
|
+
labelField: list.labelField,
|
|
908
|
+
searchFields: list.initialSearchFields,
|
|
909
|
+
filter: list.initialFilter,
|
|
910
|
+
sort: list.initialSort,
|
|
911
|
+
state: {
|
|
912
|
+
kind: 'one',
|
|
913
|
+
value: element.data === null ? null : {
|
|
914
|
+
id: element.data.id,
|
|
915
|
+
label: (_element$data$label = element.data.label) !== null && _element$data$label !== void 0 ? _element$data$label : null,
|
|
916
|
+
built: undefined
|
|
917
|
+
},
|
|
918
|
+
onChange(newItem) {
|
|
919
|
+
const at = slateReact.ReactEditor.findPath(editor, element);
|
|
920
|
+
if (newItem === null) {
|
|
921
|
+
slate.Transforms.removeNodes(editor, {
|
|
922
|
+
at
|
|
923
|
+
});
|
|
924
|
+
} else {
|
|
925
|
+
slate.Transforms.setNodes(editor, {
|
|
926
|
+
data: {
|
|
927
|
+
id: newItem.id,
|
|
928
|
+
label: newItem.label,
|
|
929
|
+
data: newItem.data
|
|
930
|
+
}
|
|
931
|
+
}, {
|
|
932
|
+
at
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}) : 'Invalid relationship'
|
|
938
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
939
|
+
className: style.css({
|
|
940
|
+
flex: 0
|
|
941
|
+
}),
|
|
942
|
+
children: children
|
|
943
|
+
})]
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
const ToolbarStateContext = /*#__PURE__*/React__default["default"].createContext(null);
|
|
948
|
+
function useToolbarState() {
|
|
949
|
+
const toolbarState = React.useContext(ToolbarStateContext);
|
|
950
|
+
if (!toolbarState) {
|
|
951
|
+
throw new Error('ToolbarStateProvider must be used to use useToolbarState');
|
|
952
|
+
}
|
|
953
|
+
return toolbarState;
|
|
954
|
+
}
|
|
955
|
+
const ToolbarStateProvider = ({
|
|
956
|
+
children,
|
|
957
|
+
componentBlocks,
|
|
958
|
+
editorDocumentFeatures,
|
|
959
|
+
relationships
|
|
960
|
+
}) => {
|
|
961
|
+
const editor = slateReact.useSlate();
|
|
962
|
+
return /*#__PURE__*/jsxRuntime.jsx(DocumentFieldRelationshipsProvider, {
|
|
963
|
+
value: relationships,
|
|
964
|
+
children: /*#__PURE__*/jsxRuntime.jsx(layouts.LayoutOptionsProvider, {
|
|
965
|
+
value: editorDocumentFeatures.layouts,
|
|
966
|
+
children: /*#__PURE__*/jsxRuntime.jsx(ComponentBlockContext.Provider, {
|
|
967
|
+
value: componentBlocks,
|
|
968
|
+
children: /*#__PURE__*/jsxRuntime.jsx(ToolbarStateContext.Provider, {
|
|
969
|
+
value: shared.createToolbarState(editor, componentBlocks, editorDocumentFeatures),
|
|
970
|
+
children: children
|
|
971
|
+
})
|
|
972
|
+
})
|
|
973
|
+
})
|
|
974
|
+
});
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
exports.ActiveBlockPopoverProvider = ActiveBlockPopoverProvider;
|
|
978
|
+
exports.BlockPopover = BlockPopover;
|
|
979
|
+
exports.BlockPopoverTrigger = BlockPopoverTrigger;
|
|
980
|
+
exports.ComponentBlockContext = ComponentBlockContext;
|
|
981
|
+
exports.ComponentBlocksElement = ComponentBlocksElement;
|
|
982
|
+
exports.ComponentInlineProp = ComponentInlineProp;
|
|
983
|
+
exports.DocumentFieldRelationshipsContext = DocumentFieldRelationshipsContext;
|
|
984
|
+
exports.ForceValidationProvider = ForceValidationProvider;
|
|
985
|
+
exports.RelationshipElement = RelationshipElement;
|
|
986
|
+
exports.ToolbarStateProvider = ToolbarStateProvider;
|
|
987
|
+
exports.blockElementSpacing = blockElementSpacing;
|
|
988
|
+
exports.focusWithPreviousSelection = focusWithPreviousSelection;
|
|
989
|
+
exports.insertComponentBlock = insertComponentBlock;
|
|
990
|
+
exports.useActiveBlockPopover = useActiveBlockPopover;
|
|
991
|
+
exports.useDocumentFieldRelationships = useDocumentFieldRelationships;
|
|
992
|
+
exports.useElementWithSetNodes = useElementWithSetNodes;
|
|
993
|
+
exports.useEventCallback = useEventCallback;
|
|
994
|
+
exports.useToolbarState = useToolbarState;
|