lkb-fields-document 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/component-blocks/dist/lkb-fields-document-component-blocks.cjs.d.ts +2 -2
  2. package/component-blocks/dist/lkb-fields-document-component-blocks.cjs.js +16 -306
  3. package/component-blocks/dist/lkb-fields-document-component-blocks.node.cjs.js +16 -306
  4. package/dist/lkb-fields-document.cjs.d.ts +2 -2
  5. package/dist/lkb-fields-document.cjs.js +16 -1167
  6. package/dist/lkb-fields-document.node.cjs.js +16 -1167
  7. package/package.json +6 -6
  8. package/structure-views/dist/lkb-fields-document-structure-views.cjs.d.ts +2 -2
  9. package/structure-views/dist/lkb-fields-document-structure-views.cjs.js +16 -138
  10. package/structure-views/dist/lkb-fields-document-structure-views.node.cjs.js +16 -138
  11. package/views/dist/lkb-fields-document-views.cjs.d.ts +2 -2
  12. package/views/dist/lkb-fields-document-views.cjs.js +13 -111
  13. package/views/dist/lkb-fields-document-views.node.cjs.js +13 -111
  14. package/component-blocks/dist/lkb-fields-document-component-blocks.esm.js +0 -300
  15. package/component-blocks/dist/lkb-fields-document-component-blocks.node.esm.js +0 -300
  16. package/dist/Cell-0ac0ac66.node.cjs.js +0 -21
  17. package/dist/Cell-242f7404.esm.js +0 -17
  18. package/dist/Cell-3103f73d.node.esm.js +0 -17
  19. package/dist/Cell-bfb56d74.cjs.js +0 -21
  20. package/dist/Field-0e0f75ed.node.cjs.js +0 -1628
  21. package/dist/Field-28177061.cjs.js +0 -1628
  22. package/dist/Field-35b79e6b.node.esm.js +0 -1619
  23. package/dist/Field-92d13205.esm.js +0 -1619
  24. package/dist/api-2f524611.esm.js +0 -502
  25. package/dist/api-73636987.cjs.js +0 -506
  26. package/dist/api-8e2b20b8.node.cjs.js +0 -506
  27. package/dist/api-c32e360e.node.esm.js +0 -502
  28. package/dist/callout-ui-2aded278.cjs.js +0 -131
  29. package/dist/callout-ui-3e5ca544.node.esm.js +0 -126
  30. package/dist/callout-ui-8b5f2376.esm.js +0 -126
  31. package/dist/callout-ui-ad50f301.node.cjs.js +0 -131
  32. package/dist/declarations/src/component-blocks.d.ts +0 -4
  33. package/dist/declarations/src/component-blocks.d.ts.map +0 -1
  34. package/dist/declarations/src/document-editor/component-blocks/api.d.ts +0 -120
  35. package/dist/declarations/src/document-editor/component-blocks/api.d.ts.map +0 -1
  36. package/dist/declarations/src/document-editor/component-blocks/types.d.ts +0 -241
  37. package/dist/declarations/src/document-editor/component-blocks/types.d.ts.map +0 -1
  38. package/dist/declarations/src/document-editor/toolset/relationship/relationship-shared.d.ts +0 -10
  39. package/dist/declarations/src/document-editor/toolset/relationship/relationship-shared.d.ts.map +0 -1
  40. package/dist/declarations/src/index.d.ts +0 -7
  41. package/dist/declarations/src/index.d.ts.map +0 -1
  42. package/dist/declarations/src/my-component-blocks/index.d.ts +0 -46
  43. package/dist/declarations/src/my-component-blocks/index.d.ts.map +0 -1
  44. package/dist/declarations/src/structure/Cell.d.ts +0 -5
  45. package/dist/declarations/src/structure/Cell.d.ts.map +0 -1
  46. package/dist/declarations/src/structure/Field.d.ts +0 -5
  47. package/dist/declarations/src/structure/Field.d.ts.map +0 -1
  48. package/dist/declarations/src/structure/controller.d.ts +0 -10
  49. package/dist/declarations/src/structure/controller.d.ts.map +0 -1
  50. package/dist/declarations/src/structure/structure.d.ts +0 -4
  51. package/dist/declarations/src/structure/structure.d.ts.map +0 -1
  52. package/dist/declarations/src/structure-views.d.ts +0 -5
  53. package/dist/declarations/src/structure-views.d.ts.map +0 -1
  54. package/dist/declarations/src/types/DocumentFeatures.d.ts +0 -33
  55. package/dist/declarations/src/types/DocumentFeatures.d.ts.map +0 -1
  56. package/dist/declarations/src/types/DocumentFieldConfig.d.ts +0 -18
  57. package/dist/declarations/src/types/DocumentFieldConfig.d.ts.map +0 -1
  58. package/dist/declarations/src/types/FormattingConfig.d.ts +0 -28
  59. package/dist/declarations/src/types/FormattingConfig.d.ts.map +0 -1
  60. package/dist/declarations/src/types/RelationshipsConfig.d.ts +0 -9
  61. package/dist/declarations/src/types/RelationshipsConfig.d.ts.map +0 -1
  62. package/dist/declarations/src/types/StructureFieldConfig.d.ts +0 -10
  63. package/dist/declarations/src/types/StructureFieldConfig.d.ts.map +0 -1
  64. package/dist/declarations/src/validation/structure-validation.d.ts +0 -218
  65. package/dist/declarations/src/validation/structure-validation.d.ts.map +0 -1
  66. package/dist/declarations/src/views/Cell.d.ts +0 -5
  67. package/dist/declarations/src/views/Cell.d.ts.map +0 -1
  68. package/dist/declarations/src/views/Field.d.ts +0 -5
  69. package/dist/declarations/src/views/Field.d.ts.map +0 -1
  70. package/dist/declarations/src/views/controller.d.ts +0 -15
  71. package/dist/declarations/src/views/controller.d.ts.map +0 -1
  72. package/dist/declarations/src/views/document.d.ts +0 -4
  73. package/dist/declarations/src/views/document.d.ts.map +0 -1
  74. package/dist/declarations/src/views.d.ts +0 -7
  75. package/dist/declarations/src/views.d.ts.map +0 -1
  76. package/dist/editor-shared-a6e340e6.node.esm.js +0 -1993
  77. package/dist/editor-shared-a997ae98.node.cjs.js +0 -2007
  78. package/dist/editor-shared-cc1293ed.cjs.js +0 -2007
  79. package/dist/editor-shared-da518ba3.esm.js +0 -1993
  80. package/dist/form-from-preview-2042b9ef.cjs.js +0 -512
  81. package/dist/form-from-preview-5df6e492.node.esm.js +0 -508
  82. package/dist/form-from-preview-9e501058.node.cjs.js +0 -512
  83. package/dist/form-from-preview-b3a66f37.esm.js +0 -508
  84. package/dist/index-06c36775.cjs.js +0 -14
  85. package/dist/index-586adb8f.node.esm.js +0 -11
  86. package/dist/index-67d52357.esm.js +0 -11
  87. package/dist/index-c3223fdc.node.cjs.js +0 -14
  88. package/dist/layouts-6412fa2a.esm.js +0 -189
  89. package/dist/layouts-a4a3cf0b.node.cjs.js +0 -196
  90. package/dist/layouts-ba9a558b.cjs.js +0 -196
  91. package/dist/layouts-e653b908.node.esm.js +0 -189
  92. package/dist/lkb-fields-document.esm.js +0 -1162
  93. package/dist/lkb-fields-document.node.esm.js +0 -1162
  94. package/dist/shared-0533009e.cjs.js +0 -594
  95. package/dist/shared-4684cc24.node.cjs.js +0 -594
  96. package/dist/shared-5e864055.node.esm.js +0 -579
  97. package/dist/shared-aaba5901.esm.js +0 -579
  98. package/dist/toolbar-state-3359e2f3.cjs.js +0 -994
  99. package/dist/toolbar-state-945823b8.node.esm.js +0 -971
  100. package/dist/toolbar-state-9611743f.node.cjs.js +0 -994
  101. package/dist/toolbar-state-bc8fe661.esm.js +0 -971
  102. package/dist/utils-06bcddc4.node.cjs.js +0 -747
  103. package/dist/utils-200ff260.node.esm.js +0 -722
  104. package/dist/utils-6409f730.cjs.js +0 -747
  105. package/dist/utils-bc6a0b82.esm.js +0 -722
  106. package/structure-views/dist/lkb-fields-document-structure-views.esm.js +0 -131
  107. package/structure-views/dist/lkb-fields-document-structure-views.node.esm.js +0 -131
  108. package/views/dist/lkb-fields-document-views.esm.js +0 -95
  109. package/views/dist/lkb-fields-document-views.node.esm.js +0 -95
@@ -1,1619 +0,0 @@
1
- 'use client';
2
- import { Field as Field$1 } from '@keystar/ui/field';
3
- import { css, tokenSchema } from '@keystar/ui/style';
4
- import { Text, Heading, Kbd, Prose } from '@keystar/ui/typography';
5
- import { useState, useEffect, useMemo, useContext, useRef, Fragment as Fragment$1, useCallback } from 'react';
6
- import isHotkey from 'is-hotkey';
7
- import { Node, Transforms, Editor, Element, Text as Text$1 } from 'slate';
8
- import { useSlateStatic, ReactEditor, useSelected, withReact, Slate, useSlate, Editable } from 'slate-react';
9
- import { w as wrapLink, i as insertBlockquote, a as insertDivider, c as createDocumentEditor } from './editor-shared-a6e340e6.node.esm.js';
10
- import { u as clearFormatting, k as insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading, v as getPlaceholderTextForPropPath } from './utils-200ff260.node.esm.js';
11
- import { Icon } from '@keystar/ui/icon';
12
- import { boldIcon } from '@keystar/ui/icon/icons/boldIcon';
13
- import { italicIcon } from '@keystar/ui/icon/icons/italicIcon';
14
- import { plusIcon } from '@keystar/ui/icon/icons/plusIcon';
15
- import { chevronDownIcon } from '@keystar/ui/icon/icons/chevronDownIcon';
16
- import { codeIcon } from '@keystar/ui/icon/icons/codeIcon';
17
- import { removeFormattingIcon } from '@keystar/ui/icon/icons/removeFormattingIcon';
18
- import { strikethroughIcon } from '@keystar/ui/icon/icons/strikethroughIcon';
19
- import { subscriptIcon } from '@keystar/ui/icon/icons/subscriptIcon';
20
- import { superscriptIcon } from '@keystar/ui/icon/icons/superscriptIcon';
21
- import { typeIcon } from '@keystar/ui/icon/icons/typeIcon';
22
- import { underlineIcon } from '@keystar/ui/icon/icons/underlineIcon';
23
- import { maximizeIcon } from '@keystar/ui/icon/icons/maximizeIcon';
24
- import { minimizeIcon } from '@keystar/ui/icon/icons/minimizeIcon';
25
- import { EditorToolbarGroup, EditorToolbarItem, EditorToolbarButton, EditorToolbar, EditorToolbarSeparator } from '@keystar/ui/editor';
26
- import { linkIcon } from '@keystar/ui/icon/icons/linkIcon';
27
- import { externalLinkIcon } from '@keystar/ui/icon/icons/externalLinkIcon';
28
- import { editIcon } from '@keystar/ui/icon/icons/editIcon';
29
- import { u as useElementWithSetNodes, a as useActiveBlockPopover, b as useEventCallback, B as BlockPopoverTrigger, c as BlockPopover, f as focusWithPreviousSelection, d as useToolbarState, D as DocumentFieldRelationshipsContext, C as ComponentBlockContext, i as insertComponentBlock, R as RelationshipElement, e as ComponentInlineProp, g as ComponentBlocksElement, h as useDocumentFieldRelationships, T as ToolbarStateProvider, A as ActiveBlockPopoverProvider, F as ForceValidationProvider } from './toolbar-state-945823b8.node.esm.js';
30
- import { i as isValidURL } from './index-586adb8f.node.esm.js';
31
- import { ActionButton, ButtonGroup, Button } from '@keystar/ui/button';
32
- import { DialogContainer, useDialogContainer, Dialog } from '@keystar/ui/dialog';
33
- import { Flex } from '@keystar/ui/layout';
34
- import { TooltipTrigger, Tooltip } from '@keystar/ui/tooltip';
35
- import '@react-aria/i18n';
36
- import '@keystar/ui/number-field';
37
- import { Picker, Item as Item$1 } from '@keystar/ui/picker';
38
- import '@keystar/ui/combobox';
39
- import { TextField } from '@keystar/ui/text-field';
40
- import { Item } from '@keystar/ui/tag';
41
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
42
- import '@keystar/ui/checkbox';
43
- import { Content } from '@keystar/ui/slots';
44
- import { unlinkIcon } from '@keystar/ui/icon/icons/unlinkIcon';
45
- import { LayoutsButton, LayoutArea, LayoutContainer } from './layouts-e653b908.node.esm.js';
46
- import { t as toggleList, i as insertLayout, u as unnestList, h as nestList } from './shared-5e864055.node.esm.js';
47
- import { listIcon } from '@keystar/ui/icon/icons/listIcon';
48
- import { listOrderedIcon } from '@keystar/ui/icon/icons/listOrderedIcon';
49
- import { quoteIcon } from '@keystar/ui/icon/icons/quoteIcon';
50
- import { alignLeftIcon } from '@keystar/ui/icon/icons/alignLeftIcon';
51
- import { alignRightIcon } from '@keystar/ui/icon/icons/alignRightIcon';
52
- import { alignCenterIcon } from '@keystar/ui/icon/icons/alignCenterIcon';
53
- import { MenuTrigger, Menu } from '@keystar/ui/menu';
54
- import { minusIcon } from '@keystar/ui/icon/icons/minusIcon';
55
- import { ActionGroup } from '@keystar/ui/action-group';
56
- import { matchSorter } from 'match-sorter';
57
- import scrollIntoView from 'scroll-into-view-if-needed';
58
- import { useOverlayTrigger } from '@react-aria/overlays';
59
- import { useListState } from '@react-stately/list';
60
- import { useOverlayTriggerState } from '@react-stately/overlays';
61
- import { Popover } from '@keystar/ui/overlays';
62
- import { Item as Item$2, useListBoxLayout, ListBoxBase } from '@keystar/ui/listbox';
63
- import { KeystarProvider } from '@keystar/ui/core';
64
- import 'slate-history';
65
- import '@emotion/weak-memoize';
66
- import 'mdast-util-from-markdown';
67
- import 'mdast-util-gfm-autolink-literal/from-markdown';
68
- import 'micromark-extension-gfm-autolink-literal';
69
- import 'mdast-util-gfm-strikethrough/from-markdown';
70
- import 'micromark-extension-gfm-strikethrough';
71
- import '@keystar/ui/icon/icons/trash2Icon';
72
- import './api-c32e360e.node.esm.js';
73
- import 'lkb-core';
74
- import '@keystar/ui/drag-and-drop';
75
- import './form-from-preview-5df6e492.node.esm.js';
76
- import 'lkb-core/admin-ui/context';
77
- import 'lkb-core/fields/types/relationship/views';
78
- import 'lkb-core/admin-ui/utils';
79
- import '@keystar/ui/list-view';
80
- import '@keystar/ui/icon/icons/trashIcon';
81
- import '@react-aria/utils';
82
- import '@braintree/sanitize-url';
83
-
84
- function LinkElement({
85
- attributes,
86
- children,
87
- element: __elementForGettingPath
88
- }) {
89
- const editor = useSlateStatic();
90
- const [currentElement, setNode] = useElementWithSetNodes(editor, __elementForGettingPath);
91
- const href = currentElement.href;
92
-
93
- // const [localForceValidation, setLocalForceValidation] = useState(false)
94
- const [dialogOpen, setDialogOpen] = useState(false);
95
- const activePopoverElement = useActiveBlockPopover();
96
- const selected = activePopoverElement === __elementForGettingPath;
97
- useEffect(() => {
98
- if (selected && !href) {
99
- setDialogOpen(true);
100
- }
101
- }, [href, selected]);
102
- const unlink = useEventCallback(() => {
103
- Transforms.unwrapNodes(editor, {
104
- at: ReactEditor.findPath(editor, __elementForGettingPath)
105
- });
106
- });
107
- // const forceValidation = useForceValidation()
108
- // TODO: show the invalid state
109
- // const showInvalidState = isValidURL(href) ? false : forceValidation || localForceValidation
110
- return /*#__PURE__*/jsxs(Fragment, {
111
- children: [/*#__PURE__*/jsxs(BlockPopoverTrigger, {
112
- element: __elementForGettingPath,
113
- children: [/*#__PURE__*/jsx("a", {
114
- href: href,
115
- ...attributes,
116
- children: children
117
- }), /*#__PURE__*/jsx(BlockPopover, {
118
- placement: "bottom start",
119
- children: /*#__PURE__*/jsxs(Flex, {
120
- gap: "small",
121
- padding: "regular",
122
- children: [/*#__PURE__*/jsxs(TooltipTrigger, {
123
- children: [/*#__PURE__*/jsx(ActionButton, {
124
- prominence: "low",
125
- onPress: () => setDialogOpen(true),
126
- children: /*#__PURE__*/jsx(Icon, {
127
- src: editIcon
128
- })
129
- }), /*#__PURE__*/jsx(Tooltip, {
130
- children: "Edit"
131
- })]
132
- }), /*#__PURE__*/jsxs(TooltipTrigger, {
133
- children: [/*#__PURE__*/jsx(ActionButton, {
134
- prominence: "low",
135
- onPress: () => {
136
- window.open(href, '_blank', 'noopener,noreferrer');
137
- },
138
- children: /*#__PURE__*/jsx(Icon, {
139
- src: externalLinkIcon
140
- })
141
- }), /*#__PURE__*/jsx(Tooltip, {
142
- children: /*#__PURE__*/jsx(Text, {
143
- truncate: 3,
144
- children: href
145
- })
146
- })]
147
- }), /*#__PURE__*/jsxs(TooltipTrigger, {
148
- children: [/*#__PURE__*/jsx(ActionButton, {
149
- prominence: "low",
150
- onPress: unlink,
151
- children: /*#__PURE__*/jsx(Icon, {
152
- src: unlinkIcon
153
- })
154
- }), /*#__PURE__*/jsx(Tooltip, {
155
- children: "Unlink"
156
- })]
157
- })]
158
- })
159
- })]
160
- }), /*#__PURE__*/jsx(DialogContainer, {
161
- onDismiss: () => {
162
- setDialogOpen(false);
163
- focusWithPreviousSelection(editor);
164
- },
165
- children: dialogOpen && /*#__PURE__*/jsx(LinkDialog, {
166
- text: Node.string(currentElement),
167
- href: href,
168
- onSubmit: ({
169
- href
170
- }) => {
171
- setNode({
172
- href
173
- });
174
- }
175
- })
176
- })]
177
- });
178
- }
179
- function LinkDialog({
180
- onSubmit,
181
- ...props
182
- }) {
183
- let [href, setHref] = useState(props.href || '');
184
- let [touched, setTouched] = useState(false);
185
- let {
186
- dismiss
187
- } = useDialogContainer();
188
- const showInvalidState = touched && !isValidURL(href);
189
- return /*#__PURE__*/jsx(Dialog, {
190
- size: "small",
191
- children: /*#__PURE__*/jsxs("form", {
192
- style: {
193
- display: 'contents'
194
- },
195
- onSubmit: event => {
196
- if (event.target !== event.currentTarget) return;
197
- event.preventDefault();
198
- if (!showInvalidState) {
199
- dismiss();
200
- onSubmit({
201
- href
202
- });
203
- }
204
- },
205
- children: [/*#__PURE__*/jsxs(Heading, {
206
- children: [props.href ? '编辑' : '添加', "\u94FE\u63A5"]
207
- }), /*#__PURE__*/jsx(Content, {
208
- children: /*#__PURE__*/jsxs(Flex, {
209
- gap: "large",
210
- direction: "column",
211
- children: [/*#__PURE__*/jsx(TextField, {
212
- label: "\u6587\u672C",
213
- value: props.text,
214
- isReadOnly: true
215
- }), /*#__PURE__*/jsx(TextField, {
216
- autoFocus: true,
217
- isRequired: true,
218
- onBlur: () => setTouched(true),
219
- label: "\u94FE\u63A5",
220
- onChange: setHref,
221
- value: href,
222
- errorMessage: showInvalidState && '请输入有效的链接地址.'
223
- })]
224
- })
225
- }), /*#__PURE__*/jsxs(ButtonGroup, {
226
- children: [/*#__PURE__*/jsx(Button, {
227
- onPress: dismiss,
228
- children: "\u53D6\u6D88"
229
- }), /*#__PURE__*/jsx(Button, {
230
- prominence: "high",
231
- type: "submit",
232
- children: "\u4FDD\u5B58"
233
- })]
234
- })]
235
- })
236
- });
237
- }
238
- let _linkIcon = /*#__PURE__*/jsx(Icon, {
239
- src: linkIcon
240
- });
241
- function LinkButton() {
242
- const {
243
- editor,
244
- links: {
245
- isDisabled,
246
- isSelected
247
- }
248
- } = useToolbarState();
249
- return useMemo(() => /*#__PURE__*/jsx(ActionButton, {
250
- prominence: "low",
251
- isDisabled: isDisabled,
252
- isSelected: isSelected,
253
- onPress: () => {
254
- wrapLink(editor, '');
255
- ReactEditor.focus(editor);
256
- },
257
- children: _linkIcon
258
- }), [isSelected, isDisabled, editor]);
259
- }
260
- const linkButton = /*#__PURE__*/jsxs(TooltipTrigger, {
261
- children: [/*#__PURE__*/jsx(LinkButton, {}), /*#__PURE__*/jsx(Tooltip, {
262
- children: /*#__PURE__*/jsx(Text, {
263
- children: "Link"
264
- })
265
- })]
266
- });
267
-
268
- function ListButtons(props) {
269
- const {
270
- editor,
271
- lists
272
- } = useToolbarState();
273
- const items = useMemo(() => {
274
- return [!!props.lists.unordered && {
275
- label: '无序列表',
276
- key: 'unordered',
277
- shortcut: '-⎵',
278
- icon: listIcon
279
- }, !!props.lists.unordered && {
280
- label: '有序列表',
281
- key: 'ordered',
282
- shortcut: '1.⎵',
283
- icon: listOrderedIcon
284
- }].filter(removeFalse);
285
- }, [props.lists]);
286
- return useMemo(() => {
287
- const disabledKeys = [];
288
- if (lists.ordered.isDisabled) disabledKeys.push('ordered');
289
- if (lists.unordered.isDisabled) disabledKeys.push('unordered');
290
- const activeListType = lists.ordered.isSelected ? 'ordered' : lists.unordered.isSelected ? 'unordered' : null;
291
- return /*#__PURE__*/jsx(EditorToolbarGroup, {
292
- value: activeListType,
293
- disabledKeys: disabledKeys,
294
- onChange: key => {
295
- const format = `${key}-list`;
296
- toggleList(editor, format);
297
- ReactEditor.focus(editor);
298
- },
299
- selectionMode: "single",
300
- children: items.map(item => /*#__PURE__*/jsxs(TooltipTrigger, {
301
- children: [/*#__PURE__*/jsx(EditorToolbarItem, {
302
- value: item.key,
303
- children: /*#__PURE__*/jsx(Icon, {
304
- src: item.icon
305
- })
306
- }), /*#__PURE__*/jsxs(Tooltip, {
307
- children: [/*#__PURE__*/jsx(Text, {
308
- children: item.label
309
- }), /*#__PURE__*/jsx(Kbd, {
310
- children: item.shortcut
311
- })]
312
- })]
313
- }, item.key))
314
- });
315
- }, [editor, lists.ordered.isDisabled, lists.ordered.isSelected, lists.unordered.isDisabled, lists.unordered.isSelected, props.lists.ordered, props.lists.unordered]);
316
- }
317
- function removeFalse(val) {
318
- return val !== false;
319
- }
320
-
321
- const BlockquoteElement = ({
322
- attributes,
323
- children
324
- }) => {
325
- return /*#__PURE__*/jsx("blockquote", {
326
- ...attributes,
327
- children: children
328
- });
329
- };
330
- const BlockquoteButton = () => {
331
- const {
332
- editor,
333
- blockquote: {
334
- isDisabled,
335
- isSelected
336
- }
337
- } = useToolbarState();
338
- return useMemo(() => /*#__PURE__*/jsx(EditorToolbarButton, {
339
- isSelected: isSelected,
340
- isDisabled: isDisabled,
341
- onPress: () => {
342
- insertBlockquote(editor);
343
- ReactEditor.focus(editor);
344
- },
345
- children: /*#__PURE__*/jsx(Icon, {
346
- src: quoteIcon
347
- })
348
- }), [editor, isDisabled, isSelected]);
349
- };
350
- const blockquoteButton = /*#__PURE__*/jsxs(TooltipTrigger, {
351
- children: [/*#__PURE__*/jsx(BlockquoteButton, {}), /*#__PURE__*/jsxs(Tooltip, {
352
- children: [/*#__PURE__*/jsx(Text, {
353
- children: "\u5F15\u7528"
354
- }), /*#__PURE__*/jsx(Kbd, {
355
- children: '>⎵'
356
- })]
357
- })]
358
- });
359
-
360
- function CodeButton() {
361
- const {
362
- editor,
363
- code: {
364
- isDisabled,
365
- isSelected
366
- }
367
- } = useToolbarState();
368
- return useMemo(() => /*#__PURE__*/jsx(EditorToolbarButton, {
369
- isSelected: isSelected,
370
- isDisabled: isDisabled,
371
- onPress: () => {
372
- if (isSelected) {
373
- Transforms.unwrapNodes(editor, {
374
- match: node => node.type === 'code'
375
- });
376
- } else {
377
- Transforms.wrapNodes(editor, {
378
- type: 'code',
379
- children: [{
380
- text: ''
381
- }]
382
- });
383
- }
384
- ReactEditor.focus(editor);
385
- },
386
- children: /*#__PURE__*/jsx(Icon, {
387
- src: codeIcon
388
- })
389
- }), [isDisabled, isSelected, editor]);
390
- }
391
- const codeButton = /*#__PURE__*/jsxs(TooltipTrigger, {
392
- children: [/*#__PURE__*/jsx(CodeButton, {}), /*#__PURE__*/jsxs(Tooltip, {
393
- children: [/*#__PURE__*/jsx(Text, {
394
- children: "\u4EE3\u7801\u5757"
395
- }), /*#__PURE__*/jsx(Kbd, {
396
- children: "```"
397
- })]
398
- })]
399
- });
400
-
401
- const values = {
402
- start: {
403
- key: 'start',
404
- label: '左对齐',
405
- icon: /*#__PURE__*/jsx(Icon, {
406
- src: alignLeftIcon
407
- })
408
- },
409
- center: {
410
- key: 'center',
411
- label: '居中对齐',
412
- icon: /*#__PURE__*/jsx(Icon, {
413
- src: alignCenterIcon
414
- })
415
- },
416
- end: {
417
- key: 'end',
418
- label: '右对齐',
419
- icon: /*#__PURE__*/jsx(Icon, {
420
- src: alignRightIcon
421
- })
422
- }
423
- };
424
- const TextAlignMenu = ({
425
- alignment
426
- }) => {
427
- const toolbarState = useToolbarState();
428
- const items = useMemo(() => [values.start, ...Object.keys(alignment).map(x => values[x])], [alignment]);
429
- return useMemo(() => /*#__PURE__*/jsxs(MenuTrigger, {
430
- children: [/*#__PURE__*/jsxs(TooltipTrigger, {
431
- children: [/*#__PURE__*/jsxs(EditorToolbarButton, {
432
- children: [values[toolbarState.alignment.selected].icon, /*#__PURE__*/jsx(Icon, {
433
- src: chevronDownIcon
434
- })]
435
- }), /*#__PURE__*/jsx(Tooltip, {
436
- children: /*#__PURE__*/jsx(Text, {
437
- children: "\u6587\u672C\u5BF9\u9F50"
438
- })
439
- })]
440
- }), /*#__PURE__*/jsx(Menu, {
441
- selectionMode: "single",
442
- selectedKeys: [toolbarState.alignment.selected],
443
- items: items,
444
- onAction: key => {
445
- if (key === 'start') {
446
- Transforms.unsetNodes(toolbarState.editor, 'textAlign', {
447
- match: node => node.type === 'paragraph' || node.type === 'heading'
448
- });
449
- } else {
450
- Transforms.setNodes(toolbarState.editor, {
451
- textAlign: key
452
- }, {
453
- match: node => node.type === 'paragraph' || node.type === 'heading'
454
- });
455
- }
456
- ReactEditor.focus(toolbarState.editor);
457
- },
458
- children: item => {
459
- return /*#__PURE__*/jsxs(Item, {
460
- textValue: item.label,
461
- children: [/*#__PURE__*/jsx(Text, {
462
- children: item.label
463
- }), item.icon]
464
- }, item.key);
465
- }
466
- })]
467
- }), [items, toolbarState.alignment.selected, toolbarState.editor]);
468
- };
469
-
470
- const DividerButtonInner = () => {
471
- const {
472
- editor,
473
- dividers: {
474
- isDisabled
475
- }
476
- } = useToolbarState();
477
- return useMemo(() => /*#__PURE__*/jsx(EditorToolbarButton, {
478
- isDisabled: isDisabled,
479
- isSelected: false,
480
- onPress: () => {
481
- insertDivider(editor);
482
- },
483
- children: /*#__PURE__*/jsx(Icon, {
484
- src: minusIcon
485
- })
486
- }), [editor, isDisabled]);
487
- };
488
- const DividerButton = /*#__PURE__*/jsxs(TooltipTrigger, {
489
- delay: 200,
490
- children: [/*#__PURE__*/jsx(DividerButtonInner, {}), /*#__PURE__*/jsxs(Tooltip, {
491
- children: [/*#__PURE__*/jsx(Text, {
492
- children: "\u6DFB\u52A0\u5206\u9694\u7EBF"
493
- }), /*#__PURE__*/jsx(Kbd, {
494
- children: "---"
495
- })]
496
- })]
497
- });
498
-
499
- function Toolbar({
500
- documentFeatures,
501
- viewState
502
- }) {
503
- const relationship = useContext(DocumentFieldRelationshipsContext);
504
- const blockComponent = useContext(ComponentBlockContext);
505
- const hasBlockItems = Object.entries(relationship).length || Object.keys(blockComponent).length;
506
- const hasMarks = Object.values(documentFeatures.formatting.inlineMarks).some(x => x);
507
- const hasAlignment = documentFeatures.formatting.alignment.center || documentFeatures.formatting.alignment.end;
508
- const hasLists = documentFeatures.formatting.listTypes.unordered || documentFeatures.formatting.listTypes.ordered;
509
- return /*#__PURE__*/jsxs(ToolbarWrapper, {
510
- children: [/*#__PURE__*/jsxs(ToolbarScrollArea, {
511
- children: [!!documentFeatures.formatting.headingLevels.length && /*#__PURE__*/jsx(HeadingMenu, {
512
- headingLevels: documentFeatures.formatting.headingLevels
513
- }), /*#__PURE__*/jsxs(EditorToolbar, {
514
- children: [hasMarks && /*#__PURE__*/jsxs(Fragment, {
515
- children: [/*#__PURE__*/jsx(EditorToolbarSeparator, {}), /*#__PURE__*/jsx(InlineMarks, {
516
- marks: documentFeatures.formatting.inlineMarks
517
- })]
518
- }), /*#__PURE__*/jsx(EditorToolbarSeparator, {}), (hasAlignment || hasLists) && /*#__PURE__*/jsxs(EditorToolbarGroup, {
519
- children: [hasAlignment && /*#__PURE__*/jsx(TextAlignMenu, {
520
- alignment: documentFeatures.formatting.alignment
521
- }), hasLists && /*#__PURE__*/jsx(ListButtons, {
522
- lists: documentFeatures.formatting.listTypes
523
- })]
524
- }), /*#__PURE__*/jsxs(EditorToolbarGroup, {
525
- children: [documentFeatures.dividers && DividerButton, documentFeatures.links && linkButton, documentFeatures.formatting.blockTypes.blockquote && blockquoteButton, !!documentFeatures.layouts.length && /*#__PURE__*/jsx(LayoutsButton, {
526
- layouts: documentFeatures.layouts
527
- }), documentFeatures.formatting.blockTypes.code && codeButton]
528
- }), useMemo(() => {
529
- return viewState && /*#__PURE__*/jsx(EditorToolbarGroup, {
530
- children: /*#__PURE__*/jsxs(TooltipTrigger, {
531
- children: [/*#__PURE__*/jsx(EditorToolbarButton, {
532
- isSelected: viewState.expanded,
533
- onPress: () => {
534
- viewState.toggle();
535
- },
536
- children: /*#__PURE__*/jsx(Icon, {
537
- src: viewState.expanded ? minimizeIcon : maximizeIcon
538
- })
539
- }), /*#__PURE__*/jsx(Tooltip, {
540
- children: viewState.expanded ? '折叠' : '展开'
541
- })]
542
- })
543
- });
544
- }, [viewState])]
545
- })]
546
- }), !!hasBlockItems && /*#__PURE__*/jsx(InsertBlockMenu, {})]
547
- });
548
- }
549
- const headingMenuVals = new Map([['normal', 'normal'], ['1', 1], ['2', 2], ['3', 3], ['4', 4], ['5', 5], ['6', 6]]);
550
- const HeadingMenu = ({
551
- headingLevels
552
- }) => {
553
- const {
554
- editor,
555
- textStyles
556
- } = useToolbarState();
557
- const isDisabled = textStyles.allowedHeadingLevels.length === 0;
558
- const items = useMemo(() => {
559
- let resolvedItems = [{
560
- name: '段落',
561
- id: 'normal'
562
- }];
563
- headingLevels.forEach(level => {
564
- resolvedItems.push({
565
- name: `标题 ${level}`,
566
- id: level.toString()
567
- });
568
- });
569
- return resolvedItems;
570
- }, [headingLevels]);
571
- const selected = textStyles.selected.toString();
572
- return useMemo(() => /*#__PURE__*/jsx(Picker, {
573
- flexShrink: 0,
574
- width: "scale.1700",
575
- prominence: "low",
576
- items: items,
577
- isDisabled: isDisabled,
578
- selectedKey: selected,
579
- onSelectionChange: selected => {
580
- let key = headingMenuVals.get(selected);
581
- if (key === 'normal') {
582
- Editor.withoutNormalizing(editor, () => {
583
- Transforms.unsetNodes(editor, 'level', {
584
- match: n => n.type === 'heading'
585
- });
586
- Transforms.setNodes(editor, {
587
- type: 'paragraph'
588
- }, {
589
- match: n => n.type === 'heading'
590
- });
591
- });
592
- } else if (key) {
593
- Transforms.setNodes(editor, {
594
- type: 'heading',
595
- level: key
596
- }, {
597
- match: node => node.type === 'paragraph' || node.type === 'heading'
598
- });
599
- }
600
- ReactEditor.focus(editor);
601
- },
602
- children: item => /*#__PURE__*/jsx(Item$1, {
603
- children: item.name
604
- }, item.id)
605
- }), [editor, isDisabled, items, selected]);
606
- };
607
- function InsertBlockMenu() {
608
- const editor = useSlateStatic();
609
- const componentBlocks = useContext(ComponentBlockContext);
610
- return /*#__PURE__*/jsxs(MenuTrigger, {
611
- align: "end",
612
- children: [/*#__PURE__*/jsxs(TooltipTrigger, {
613
- children: [/*#__PURE__*/jsxs(ActionButton, {
614
- marginY: "regular",
615
- marginEnd: "medium",
616
- children: [/*#__PURE__*/jsx(Icon, {
617
- src: plusIcon
618
- }), /*#__PURE__*/jsx(Icon, {
619
- src: chevronDownIcon
620
- })]
621
- }), /*#__PURE__*/jsxs(Tooltip, {
622
- children: [/*#__PURE__*/jsx(Text, {
623
- children: "Insert"
624
- }), /*#__PURE__*/jsx(Kbd, {
625
- children: "/"
626
- })]
627
- })]
628
- }), /*#__PURE__*/jsx(Menu, {
629
- onAction: key => {
630
- insertComponentBlock(editor, componentBlocks, key);
631
- },
632
- items: Object.entries(componentBlocks),
633
- children: ([key, item]) => /*#__PURE__*/jsx(Item$1, {
634
- children: item.label
635
- }, key)
636
- })]
637
- });
638
- }
639
- const inlineMarks = [{
640
- key: 'bold',
641
- label: 'Bold',
642
- icon: boldIcon,
643
- shortcut: `B`
644
- }, {
645
- key: 'italic',
646
- label: 'Italic',
647
- icon: italicIcon,
648
- shortcut: `I`
649
- }, {
650
- key: 'underline',
651
- label: 'Underline',
652
- icon: underlineIcon,
653
- shortcut: `U`
654
- }, {
655
- key: 'strikethrough',
656
- label: 'Strikethrough',
657
- icon: strikethroughIcon
658
- }, {
659
- key: 'code',
660
- label: 'Code',
661
- icon: codeIcon
662
- }, {
663
- key: 'superscript',
664
- label: 'Superscript',
665
- icon: superscriptIcon
666
- }, {
667
- key: 'subscript',
668
- label: 'Subscript',
669
- icon: subscriptIcon
670
- }, {
671
- key: 'clearFormatting',
672
- label: 'Clear formatting',
673
- icon: removeFormattingIcon
674
- }];
675
- function InlineMarks({
676
- marks: _marksShown
677
- }) {
678
- const {
679
- editor,
680
- clearFormatting: {
681
- isDisabled
682
- },
683
- marks
684
- } = useToolbarState();
685
- const marksShown = useMemoStringified(_marksShown);
686
- const selectedKeys = useMemoStringified(Object.keys(marks).filter(key => marks[key].isSelected));
687
- const disabledKeys = useMemoStringified(Object.keys(marks).filter(key => marks[key].isDisabled).concat(isDisabled ? 'clearFormatting' : []));
688
- return useMemo(() => {
689
- const items = inlineMarks.filter(item => item.key === 'clearFormatting' || marksShown[item.key]);
690
- return /*#__PURE__*/jsx(ActionGroup, {
691
- UNSAFE_className: css({
692
- minWidth: `calc(${tokenSchema.size.element.medium} * 4)`
693
- }),
694
- prominence: "low",
695
- density: "compact",
696
- buttonLabelBehavior: "hide",
697
- overflowMode: "collapse",
698
- summaryIcon: /*#__PURE__*/jsx(Icon, {
699
- src: typeIcon
700
- }),
701
- items: items,
702
- selectionMode: "multiple",
703
- selectedKeys: selectedKeys,
704
- disabledKeys: disabledKeys,
705
- onAction: key => {
706
- if (key === 'clearFormatting') {
707
- clearFormatting(editor);
708
- } else {
709
- var _Editor$marks;
710
- const mark = key;
711
- if ((_Editor$marks = Editor.marks(editor)) !== null && _Editor$marks !== void 0 && _Editor$marks[mark]) {
712
- Editor.removeMark(editor, mark);
713
- } else {
714
- Editor.addMark(editor, mark, true);
715
- }
716
- }
717
- ReactEditor.focus(editor);
718
- },
719
- children: item => {
720
- return /*#__PURE__*/jsxs(Item$1, {
721
- textValue: item.label,
722
- children: [/*#__PURE__*/jsx(Text, {
723
- children: item.label
724
- }), 'shortcut' in item && /*#__PURE__*/jsx(Kbd, {
725
- meta: true,
726
- children: item.shortcut
727
- }), /*#__PURE__*/jsx(Icon, {
728
- src: item.icon
729
- })]
730
- }, item.key);
731
- }
732
- });
733
- }, [disabledKeys, editor, marksShown, selectedKeys]);
734
- }
735
- function useMemoStringified(value) {
736
- return useMemo(() => value, [JSON.stringify(value)]);
737
- }
738
- function useEntryLayoutSplitPaneContext() {
739
- return null;
740
- }
741
- const ToolbarContainer = ({
742
- children
743
- }) => {
744
- return /*#__PURE__*/jsx("div", {
745
- className: css({
746
- display: 'flex'
747
- }),
748
- children: children
749
- });
750
- };
751
- const ToolbarWrapper = ({
752
- children
753
- }) => {
754
- let entryLayoutPane = useEntryLayoutSplitPaneContext();
755
- return /*#__PURE__*/jsx(Fragment, {
756
- children: /*#__PURE__*/jsx("div", {
757
- "data-layout": entryLayoutPane,
758
- className: css({
759
- backdropFilter: 'blur(8px)',
760
- backgroundClip: 'padding-box',
761
- backgroundColor: `color-mix(in srgb, transparent, ${tokenSchema.color.background.canvas} 90%)`,
762
- borderBottom: `${tokenSchema.size.border.regular} solid color-mix(in srgb, transparent, ${tokenSchema.color.foreground.neutral} 10%)`,
763
- borderStartEndRadius: tokenSchema.size.radius.medium,
764
- borderStartStartRadius: tokenSchema.size.radius.medium,
765
- minWidth: 0,
766
- position: 'sticky',
767
- top: 0,
768
- zIndex: 2,
769
- '&[data-layout="main"]': {
770
- borderRadius: 0
771
- }
772
- }),
773
- children: /*#__PURE__*/jsx(ToolbarContainer, {
774
- children: children
775
- })
776
- })
777
- });
778
- };
779
- const ToolbarScrollArea = props => {
780
- let entryLayoutPane = useEntryLayoutSplitPaneContext();
781
- return /*#__PURE__*/jsx(Flex, {
782
- "data-layout": entryLayoutPane,
783
- paddingY: "regular",
784
- paddingX: "medium",
785
- gap: "large",
786
- flex: true,
787
- minWidth: 0,
788
- UNSAFE_className: css({
789
- msOverflowStyle: 'none' /* for Internet Explorer, Edge */,
790
- scrollbarWidth: 'none' /* for Firefox */,
791
- overflowX: 'auto',
792
- /* for Chrome, Safari, and Opera */
793
- '&::-webkit-scrollbar': {
794
- display: 'none'
795
- },
796
- '&[data-layout="main"]': {
797
- paddingInline: 0
798
- }
799
- }),
800
- ...props
801
- });
802
- };
803
-
804
- function HeadingElement({
805
- attributes,
806
- children,
807
- element
808
- }) {
809
- const Tag = `h${element.level}`;
810
- return /*#__PURE__*/jsx(Tag, {
811
- ...attributes,
812
- style: {
813
- textAlign: element.textAlign
814
- },
815
- children: children
816
- });
817
- }
818
-
819
- const renderElement = props => {
820
- switch (props.element.type) {
821
- case 'layout':
822
- return /*#__PURE__*/jsx(LayoutContainer, {
823
- attributes: props.attributes,
824
- children: props.children,
825
- element: props.element
826
- });
827
- case 'layout-area':
828
- return /*#__PURE__*/jsx(LayoutArea, {
829
- ...props
830
- });
831
- case 'code':
832
- return /*#__PURE__*/jsx(CodeElement, {
833
- ...props
834
- });
835
- case 'component-block':
836
- {
837
- return /*#__PURE__*/jsx(ComponentBlocksElement, {
838
- attributes: props.attributes,
839
- children: props.children,
840
- element: props.element
841
- });
842
- }
843
- case 'component-inline-prop':
844
- case 'component-block-prop':
845
- return /*#__PURE__*/jsx(ComponentInlineProp, {
846
- ...props
847
- });
848
- case 'heading':
849
- return /*#__PURE__*/jsx(HeadingElement, {
850
- attributes: props.attributes,
851
- children: props.children,
852
- element: props.element
853
- });
854
- case 'link':
855
- return /*#__PURE__*/jsx(LinkElement, {
856
- attributes: props.attributes,
857
- children: props.children,
858
- element: props.element
859
- });
860
- case 'ordered-list':
861
- return /*#__PURE__*/jsx("ol", {
862
- ...props.attributes,
863
- children: props.children
864
- });
865
- case 'unordered-list':
866
- return /*#__PURE__*/jsx("ul", {
867
- ...props.attributes,
868
- children: props.children
869
- });
870
- case 'list-item':
871
- return /*#__PURE__*/jsx("li", {
872
- ...props.attributes,
873
- children: props.children
874
- });
875
- case 'list-item-content':
876
- return /*#__PURE__*/jsx("span", {
877
- ...props.attributes,
878
- children: props.children
879
- });
880
- case 'blockquote':
881
- return /*#__PURE__*/jsx(BlockquoteElement, {
882
- ...props
883
- });
884
- case 'relationship':
885
- return /*#__PURE__*/jsx(RelationshipElement, {
886
- attributes: props.attributes,
887
- children: props.children,
888
- element: props.element
889
- });
890
- case 'divider':
891
- return /*#__PURE__*/jsx(DividerElement, {
892
- ...props
893
- });
894
- default:
895
- return /*#__PURE__*/jsx("p", {
896
- style: {
897
- textAlign: props.element.textAlign
898
- },
899
- ...props.attributes,
900
- children: props.children
901
- });
902
- }
903
- };
904
-
905
- /* Block Elements */
906
-
907
- const CodeElement = ({
908
- attributes,
909
- children
910
- }) => {
911
- return /*#__PURE__*/jsx("pre", {
912
- spellCheck: "false",
913
- ...attributes,
914
- children: /*#__PURE__*/jsx("code", {
915
- children: children
916
- })
917
- });
918
- };
919
- function DividerElement({
920
- attributes,
921
- children
922
- }) {
923
- const selected = useSelected();
924
- return /*#__PURE__*/jsxs("div", {
925
- ...attributes,
926
- style: {
927
- caretColor: 'transparent'
928
- },
929
- children: [/*#__PURE__*/jsx("hr", {
930
- style: {
931
- backgroundColor: selected ? tokenSchema.color.alias.borderSelected : tokenSchema.color.alias.borderIdle
932
- }
933
- }), children]
934
- });
935
- }
936
-
937
- function getOptions(toolbarState, componentBlocks, relationships) {
938
- const options = [...Object.entries(relationships).map(([relationship, {
939
- label
940
- }]) => ({
941
- label,
942
- insert: editor => {
943
- Transforms.insertNodes(editor, {
944
- type: 'relationship',
945
- relationship,
946
- data: null,
947
- children: [{
948
- text: ''
949
- }]
950
- });
951
- }
952
- })), ...Object.keys(componentBlocks).map(key => ({
953
- label: componentBlocks[key].label,
954
- insert: editor => {
955
- insertComponentBlock(editor, componentBlocks, key);
956
- }
957
- })), ...toolbarState.textStyles.allowedHeadingLevels.filter(a => toolbarState.editorDocumentFeatures.formatting.headingLevels.includes(a)).map(level => ({
958
- label: `Heading ${level}`,
959
- insert(editor) {
960
- insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, {
961
- type: 'heading',
962
- level,
963
- children: [{
964
- text: ''
965
- }]
966
- });
967
- }
968
- })), !toolbarState.blockquote.isDisabled && toolbarState.editorDocumentFeatures.formatting.blockTypes.blockquote && {
969
- label: 'Blockquote',
970
- insert(editor) {
971
- insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, {
972
- type: 'blockquote',
973
- children: [{
974
- text: ''
975
- }]
976
- });
977
- }
978
- }, !toolbarState.code.isDisabled && toolbarState.editorDocumentFeatures.formatting.blockTypes.code && {
979
- label: 'Code block',
980
- insert(editor) {
981
- insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, {
982
- type: 'code',
983
- children: [{
984
- text: ''
985
- }]
986
- });
987
- }
988
- }, !toolbarState.dividers.isDisabled && toolbarState.editorDocumentFeatures.dividers && {
989
- label: 'Divider',
990
- insert(editor) {
991
- insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, {
992
- type: 'divider',
993
- children: [{
994
- text: ''
995
- }]
996
- });
997
- }
998
- }, !!toolbarState.editorDocumentFeatures.layouts.length && {
999
- label: 'Layout',
1000
- insert(editor) {
1001
- insertLayout(editor, toolbarState.editorDocumentFeatures.layouts[0]);
1002
- }
1003
- }, !toolbarState.lists.ordered.isDisabled && toolbarState.editorDocumentFeatures.formatting.listTypes.ordered && {
1004
- label: 'Numbered List',
1005
- keywords: ['ordered list'],
1006
- insert(editor) {
1007
- insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, {
1008
- type: 'ordered-list',
1009
- children: [{
1010
- text: ''
1011
- }]
1012
- });
1013
- }
1014
- }, !toolbarState.lists.unordered.isDisabled && toolbarState.editorDocumentFeatures.formatting.listTypes.unordered && {
1015
- label: 'Bullet List',
1016
- keywords: ['unordered list'],
1017
- insert(editor) {
1018
- insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading(editor, {
1019
- type: 'unordered-list',
1020
- children: [{
1021
- text: ''
1022
- }]
1023
- });
1024
- }
1025
- }];
1026
- return options.filter(x => typeof x !== 'boolean');
1027
- }
1028
- function insertOption(editor, text, option) {
1029
- const path = ReactEditor.findPath(editor, text);
1030
- Transforms.delete(editor, {
1031
- at: {
1032
- focus: Editor.start(editor, path),
1033
- anchor: Editor.end(editor, path)
1034
- }
1035
- });
1036
- option.insert(editor);
1037
- }
1038
- function InsertMenu({
1039
- children,
1040
- text
1041
- }) {
1042
- const toolbarState = useToolbarState();
1043
- const {
1044
- editor
1045
- } = toolbarState;
1046
- const componentBlocks = useContext(ComponentBlockContext);
1047
- const relationships = useDocumentFieldRelationships();
1048
- const options = matchSorter(getOptions(toolbarState, componentBlocks, relationships), text.text.slice(1), {
1049
- keys: ['label', 'keywords']
1050
- }).map((option, index) => ({
1051
- ...option,
1052
- index
1053
- }));
1054
- const stateRef = useRef({
1055
- options,
1056
- text
1057
- });
1058
- useEffect(() => {
1059
- stateRef.current = {
1060
- options,
1061
- text
1062
- };
1063
- });
1064
- const listenerRef = useRef(_event => {});
1065
- useEffect(() => {
1066
- listenerRef.current = event => {
1067
- if (event.defaultPrevented) return;
1068
- switch (event.key) {
1069
- case 'ArrowDown':
1070
- {
1071
- if (stateRef.current.options.length) {
1072
- event.preventDefault();
1073
- state.selectionManager.setFocused(true);
1074
- state.selectionManager.setFocusedKey((Number(state.selectionManager.focusedKey) === stateRef.current.options.length - 1 ? 0 : Number(state.selectionManager.focusedKey) + 1).toString());
1075
- }
1076
- return;
1077
- }
1078
- case 'ArrowUp':
1079
- {
1080
- if (stateRef.current.options.length) {
1081
- event.preventDefault();
1082
- state.selectionManager.setFocused(true);
1083
- state.selectionManager.setFocusedKey((state.selectionManager.focusedKey === '0' ? stateRef.current.options.length - 1 : Number(state.selectionManager.focusedKey) - 1).toString());
1084
- }
1085
- return;
1086
- }
1087
- case 'Enter':
1088
- {
1089
- const option = stateRef.current.options[Number(state.selectionManager.focusedKey)];
1090
- if (option) {
1091
- insertOption(editor, stateRef.current.text, option);
1092
- event.preventDefault();
1093
- }
1094
- return;
1095
- }
1096
- case 'Escape':
1097
- {
1098
- const path = ReactEditor.findPath(editor, stateRef.current.text);
1099
- Transforms.unsetNodes(editor, 'insertMenu', {
1100
- at: path
1101
- });
1102
- event.preventDefault();
1103
- return;
1104
- }
1105
- }
1106
- };
1107
- });
1108
- useEffect(() => {
1109
- const domNode = ReactEditor.toDOMNode(editor, editor);
1110
- let listener = event => listenerRef.current(event);
1111
- domNode.addEventListener('keydown', listener);
1112
- return () => {
1113
- domNode.removeEventListener('keydown', listener);
1114
- };
1115
- }, [editor]);
1116
- const triggerRef = useRef(null);
1117
- const overlayState = useOverlayTriggerState({
1118
- isOpen: true
1119
- });
1120
- const {
1121
- triggerProps: {
1122
- onPress,
1123
- ...triggerProps
1124
- },
1125
- overlayProps
1126
- } = useOverlayTrigger({
1127
- type: 'listbox'
1128
- }, overlayState, triggerRef);
1129
- let state = useListState({
1130
- items: options,
1131
- children: item => /*#__PURE__*/jsx(Item$2, {
1132
- children: item.label
1133
- }, item.index)
1134
- });
1135
- useEffect(() => {
1136
- if (!state.selectionManager.isFocused && state.collection.size) {
1137
- state.selectionManager.setFocused(true);
1138
- state.selectionManager.setFocusedKey('0');
1139
- }
1140
- }, [state]);
1141
- const scrollableRef = useRef(null);
1142
- useEffect(() => {
1143
- var _scrollableRef$curren;
1144
- const element = (_scrollableRef$curren = scrollableRef.current) === null || _scrollableRef$curren === void 0 || (_scrollableRef$curren = _scrollableRef$curren.querySelector('[role="listbox"] [role="presentation"]')) === null || _scrollableRef$curren === void 0 ? void 0 : _scrollableRef$curren.children[state.selectionManager.focusedKey];
1145
- if (element) {
1146
- scrollIntoView(element, {
1147
- scrollMode: 'if-needed',
1148
- boundary: scrollableRef.current,
1149
- block: 'nearest'
1150
- });
1151
- }
1152
- }, [state.selectionManager.focusedKey]);
1153
- const listboxRef = useRef(null);
1154
- let layout = useListBoxLayout();
1155
- return /*#__PURE__*/jsxs(Fragment$1, {
1156
- children: [/*#__PURE__*/jsx("span", {
1157
- ...triggerProps,
1158
- role: "button",
1159
- className: css({
1160
- color: tokenSchema.color.foreground.accent,
1161
- fontWeight: tokenSchema.typography.fontWeight.medium
1162
- }),
1163
- ref: triggerRef,
1164
- children: children
1165
- }), /*#__PURE__*/jsx(Popover, {
1166
- width: "alias.singleLineWidth",
1167
- placement: "bottom start",
1168
- isNonModal: true,
1169
- hideArrow: true,
1170
- ...overlayProps,
1171
- state: overlayState,
1172
- triggerRef: triggerRef,
1173
- children: /*#__PURE__*/jsx("div", {
1174
- className: css({
1175
- overflow: 'scroll',
1176
- maxHeight: 300
1177
- }),
1178
- ref: scrollableRef,
1179
- children: /*#__PURE__*/jsx(ListBoxBase, {
1180
- state: state,
1181
- shouldUseVirtualFocus: true,
1182
- layout: layout,
1183
- ref: listboxRef,
1184
- onAction: key => {
1185
- insertOption(editor, text, options[key]);
1186
- }
1187
- })
1188
- })
1189
- })]
1190
- });
1191
- }
1192
-
1193
- function Placeholder({
1194
- placeholder,
1195
- children
1196
- }) {
1197
- const [width, setWidth] = useState(0);
1198
- return /*#__PURE__*/jsxs("span", {
1199
- className: css({
1200
- position: 'relative',
1201
- display: 'inline-block',
1202
- width
1203
- }),
1204
- children: [/*#__PURE__*/jsx("span", {
1205
- contentEditable: false,
1206
- className: css({
1207
- position: 'absolute',
1208
- pointerEvents: 'none',
1209
- display: 'inline-block',
1210
- left: 0,
1211
- top: 0,
1212
- maxWidth: '100%',
1213
- whiteSpace: 'nowrap',
1214
- opacity: '0.5',
1215
- userSelect: 'none',
1216
- fontStyle: 'normal',
1217
- fontWeight: 'normal',
1218
- textDecoration: 'none',
1219
- textAlign: 'left'
1220
- }),
1221
- children: /*#__PURE__*/jsx("span", {
1222
- ref: node => {
1223
- if (node) {
1224
- const offsetWidth = node.offsetWidth;
1225
- if (offsetWidth !== width) {
1226
- setWidth(offsetWidth);
1227
- }
1228
- }
1229
- },
1230
- children: placeholder
1231
- })
1232
- }), children]
1233
- });
1234
- }
1235
- const Leaf = ({
1236
- leaf,
1237
- text,
1238
- children,
1239
- attributes
1240
- }) => {
1241
- const {
1242
- underline,
1243
- strikethrough,
1244
- bold,
1245
- italic,
1246
- code,
1247
- keyboard,
1248
- superscript,
1249
- subscript,
1250
- placeholder,
1251
- insertMenu
1252
- } = leaf;
1253
- if (placeholder !== undefined) {
1254
- children = /*#__PURE__*/jsx(Placeholder, {
1255
- placeholder: placeholder,
1256
- children: children
1257
- });
1258
- }
1259
- if (insertMenu) {
1260
- children = /*#__PURE__*/jsx(InsertMenu, {
1261
- text: text,
1262
- children: children
1263
- });
1264
- }
1265
- if (code) {
1266
- children = /*#__PURE__*/jsx("code", {
1267
- children: children
1268
- });
1269
- }
1270
- if (bold) {
1271
- children = /*#__PURE__*/jsx("strong", {
1272
- children: children
1273
- });
1274
- }
1275
- if (strikethrough) {
1276
- children = /*#__PURE__*/jsx("s", {
1277
- children: children
1278
- });
1279
- }
1280
- if (italic) {
1281
- children = /*#__PURE__*/jsx("em", {
1282
- children: children
1283
- });
1284
- }
1285
- if (keyboard) {
1286
- children = /*#__PURE__*/jsx("kbd", {
1287
- children: children
1288
- });
1289
- }
1290
- if (superscript) {
1291
- children = /*#__PURE__*/jsx("sup", {
1292
- children: children
1293
- });
1294
- }
1295
- if (subscript) {
1296
- children = /*#__PURE__*/jsx("sub", {
1297
- children: children
1298
- });
1299
- }
1300
- if (underline) {
1301
- children = /*#__PURE__*/jsx("u", {
1302
- children: children
1303
- });
1304
- }
1305
- return /*#__PURE__*/jsx("span", {
1306
- ...attributes,
1307
- children: children
1308
- });
1309
- };
1310
- const renderLeaf = props => {
1311
- return /*#__PURE__*/jsx(Leaf, {
1312
- ...props
1313
- });
1314
- };
1315
-
1316
- const styles = css({
1317
- flex: 1,
1318
- background: tokenSchema.color.background.canvas,
1319
- borderColor: tokenSchema.color.alias.borderIdle,
1320
- outline: 0,
1321
- padding: tokenSchema.size.space.medium,
1322
- minHeight: 120,
1323
- scrollbarGutter: 'stable',
1324
- overflowY: 'auto',
1325
- height: 224,
1326
- resize: 'vertical',
1327
- borderBottomLeftRadius: tokenSchema.size.radius.medium,
1328
- borderBottomRightRadius: tokenSchema.size.radius.medium,
1329
- '&[data-expanded=true]': {
1330
- // the !important is necessary to override the height set by resizing as an inline style
1331
- height: 'auto !important',
1332
- resize: 'none'
1333
- },
1334
- 'ol ol ol ol ol ol ol ol ol': {
1335
- listStyle: 'lower-roman'
1336
- },
1337
- 'ol ol ol ol ol ol ol ol': {
1338
- listStyle: 'lower-alpha'
1339
- },
1340
- 'ol ol ol ol ol ol ol': {
1341
- listStyle: 'decimal'
1342
- },
1343
- 'ol ol ol ol ol ol': {
1344
- listStyle: 'lower-roman'
1345
- },
1346
- 'ol ol ol ol ol': {
1347
- listStyle: 'lower-alpha'
1348
- },
1349
- 'ol ol ol ol': {
1350
- listStyle: 'decimal'
1351
- },
1352
- 'ol ol ol': {
1353
- listStyle: 'lower-roman'
1354
- },
1355
- 'ol ol': {
1356
- listStyle: 'lower-alpha'
1357
- },
1358
- ol: {
1359
- listStyle: 'decimal'
1360
- },
1361
- 'ul ul ul ul ul ul ul ul ul': {
1362
- listStyle: 'square'
1363
- },
1364
- 'ul ul ul ul ul ul ul ul': {
1365
- listStyle: 'circle'
1366
- },
1367
- 'ul ul ul ul ul ul ul': {
1368
- listStyle: 'disc'
1369
- },
1370
- 'ul ul ul ul ul ul': {
1371
- listStyle: 'square'
1372
- },
1373
- 'ul ul ul ul ul': {
1374
- listStyle: 'circle'
1375
- },
1376
- 'ul ul ul ul': {
1377
- listStyle: 'disc'
1378
- },
1379
- 'ul ul ul': {
1380
- listStyle: 'square'
1381
- },
1382
- 'ul ul': {
1383
- listStyle: 'circle'
1384
- },
1385
- ul: {
1386
- listStyle: 'disc'
1387
- }
1388
- });
1389
- const HOTKEYS = {
1390
- 'mod+b': 'bold',
1391
- 'mod+i': 'italic',
1392
- 'mod+u': 'underline'
1393
- };
1394
- function isMarkActive(editor, mark) {
1395
- const marks = Editor.marks(editor);
1396
- if (marks !== null && marks !== void 0 && marks[mark]) {
1397
- return true;
1398
- }
1399
- // see the stuff about marks in toolbar-state for why this is here
1400
- for (const entry of Editor.nodes(editor, {
1401
- match: Text$1.isText
1402
- })) {
1403
- if (entry[0][mark]) {
1404
- return true;
1405
- }
1406
- }
1407
- return false;
1408
- }
1409
- const getKeyDownHandler = editor => event => {
1410
- if (event.defaultPrevented) return;
1411
- for (const hotkey in HOTKEYS) {
1412
- if (isHotkey(hotkey, event.nativeEvent)) {
1413
- event.preventDefault();
1414
- const mark = HOTKEYS[hotkey];
1415
- const isActive = isMarkActive(editor, mark);
1416
- if (isActive) {
1417
- Editor.removeMark(editor, mark);
1418
- } else {
1419
- Editor.addMark(editor, mark, true);
1420
- }
1421
- return;
1422
- }
1423
- }
1424
- if (isHotkey('mod+\\', event.nativeEvent)) {
1425
- clearFormatting(editor);
1426
- return;
1427
- }
1428
- if (isHotkey('mod+k', event.nativeEvent)) {
1429
- event.preventDefault();
1430
- wrapLink(editor, '');
1431
- return;
1432
- }
1433
- if (event.key === 'Tab') {
1434
- const didAction = event.shiftKey ? unnestList(editor) : nestList(editor);
1435
- if (didAction) {
1436
- event.preventDefault();
1437
- return;
1438
- }
1439
- }
1440
- if (event.key === 'Tab' && editor.selection) {
1441
- const layoutArea = Editor.above(editor, {
1442
- match: node => node.type === 'layout-area'
1443
- });
1444
- if (layoutArea) {
1445
- const layoutAreaToEnter = event.shiftKey ? Editor.before(editor, layoutArea[1], {
1446
- unit: 'block'
1447
- }) : Editor.after(editor, layoutArea[1], {
1448
- unit: 'block'
1449
- });
1450
- Transforms.setSelection(editor, {
1451
- anchor: layoutAreaToEnter,
1452
- focus: layoutAreaToEnter
1453
- });
1454
- event.preventDefault();
1455
- }
1456
- }
1457
- };
1458
- function DocumentEditor({
1459
- onChange,
1460
- value,
1461
- componentBlocks,
1462
- relationships,
1463
- documentFeatures,
1464
- initialExpanded = true,
1465
- ...props
1466
- }) {
1467
- const [expanded, setExpanded] = useState(initialExpanded);
1468
- const editor = useMemo(() => createDocumentEditor(documentFeatures, componentBlocks, relationships, {
1469
- ReactEditor,
1470
- withReact
1471
- }), [documentFeatures, componentBlocks, relationships]);
1472
- return /*#__PURE__*/jsx(KeystarProvider, {
1473
- children: /*#__PURE__*/jsx("div", {
1474
- className: css({
1475
- border: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.border.neutral}`,
1476
- borderRadius: tokenSchema.size.radius.medium
1477
- }),
1478
- children: /*#__PURE__*/jsxs(DocumentEditorProvider, {
1479
- componentBlocks: componentBlocks,
1480
- documentFeatures: documentFeatures,
1481
- relationships: relationships,
1482
- editor: editor,
1483
- value: value,
1484
- onChange: value => {
1485
- onChange === null || onChange === void 0 || onChange(value);
1486
- // this fixes a strange issue in Safari where the selection stays inside of the editor
1487
- // after a blur event happens but the selection is still in the editor
1488
- // so the cursor is visually in the wrong place and it inserts text backwards
1489
- const selection = window.getSelection();
1490
- if (selection && !ReactEditor.isFocused(editor)) {
1491
- const editorNode = ReactEditor.toDOMNode(editor, editor);
1492
- if (selection.anchorNode === editorNode) {
1493
- ReactEditor.focus(editor);
1494
- }
1495
- }
1496
- },
1497
- children: [useMemo(() => onChange !== undefined && /*#__PURE__*/jsx(Toolbar, {
1498
- documentFeatures: documentFeatures,
1499
- viewState: {
1500
- expanded,
1501
- toggle: () => {
1502
- setExpanded(v => !v);
1503
- }
1504
- }
1505
- }), [expanded, documentFeatures, onChange]), /*#__PURE__*/jsx(Prose, {
1506
- size: "regular",
1507
- children: /*#__PURE__*/jsx(DocumentEditorEditable, {
1508
- "data-expanded": expanded,
1509
- ...props,
1510
- readOnly: onChange === undefined
1511
- })
1512
- })]
1513
- })
1514
- })
1515
- });
1516
- }
1517
- function DocumentEditorProvider({
1518
- children,
1519
- editor,
1520
- onChange,
1521
- value,
1522
- componentBlocks,
1523
- documentFeatures,
1524
- relationships
1525
- }) {
1526
- const identity = useMemo(() => Math.random().toString(36), [editor]);
1527
- return /*#__PURE__*/jsx(Slate
1528
- // this fixes issues with Slate crashing when a fast refresh occcurs
1529
- , {
1530
- editor: editor,
1531
- initialValue: value,
1532
- onChange: value => {
1533
- onChange(value);
1534
- // this fixes a strange issue in Safari where the selection stays inside of the editor
1535
- // after a blur event happens but the selection is still in the editor
1536
- // so the cursor is visually in the wrong place and it inserts text backwards
1537
- const selection = window.getSelection();
1538
- if (selection && !ReactEditor.isFocused(editor)) {
1539
- const editorNode = ReactEditor.toDOMNode(editor, editor);
1540
- if (selection.anchorNode === editorNode) {
1541
- ReactEditor.focus(editor);
1542
- }
1543
- }
1544
- },
1545
- children: /*#__PURE__*/jsx(ToolbarStateProvider, {
1546
- componentBlocks: componentBlocks,
1547
- editorDocumentFeatures: documentFeatures,
1548
- relationships: relationships,
1549
- children: children
1550
- })
1551
- }, identity);
1552
- }
1553
- function DocumentEditorEditable(props) {
1554
- var _props$className;
1555
- const editor = useSlate();
1556
- const componentBlocks = useContext(ComponentBlockContext);
1557
- const onKeyDown = useMemo(() => getKeyDownHandler(editor), [editor]);
1558
- return /*#__PURE__*/jsx(ActiveBlockPopoverProvider, {
1559
- editor: editor,
1560
- children: /*#__PURE__*/jsx(Editable, {
1561
- decorate: useCallback(([node, path]) => {
1562
- const decorations = [];
1563
- if (node.type === 'component-block') {
1564
- if (node.children.length === 1 && Element.isElement(node.children[0]) && node.children[0].type === 'component-inline-prop' && node.children[0].propPath === undefined) {
1565
- return decorations;
1566
- }
1567
- node.children.forEach((child, index) => {
1568
- if (Node.string(child) === '' && Element.isElement(child) && (child.type === 'component-block-prop' || child.type === 'component-inline-prop') && child.propPath !== undefined) {
1569
- const start = Editor.start(editor, [...path, index]);
1570
- const placeholder = getPlaceholderTextForPropPath(child.propPath, componentBlocks[node.component].schema, node.props);
1571
- if (placeholder) {
1572
- decorations.push({
1573
- placeholder,
1574
- anchor: start,
1575
- focus: start
1576
- });
1577
- }
1578
- }
1579
- });
1580
- }
1581
- return decorations;
1582
- }, [editor, componentBlocks]),
1583
- className: `${styles} ${(_props$className = props.className) !== null && _props$className !== void 0 ? _props$className : ''}`,
1584
- onKeyDown: onKeyDown,
1585
- renderElement: renderElement,
1586
- renderLeaf: renderLeaf,
1587
- ...props
1588
- })
1589
- });
1590
- }
1591
-
1592
- // Field 组件用于在编辑视图中显示字段值
1593
- function Field(props) {
1594
- const {
1595
- autoFocus,
1596
- field,
1597
- forceValidation,
1598
- onChange,
1599
- value
1600
- } = props;
1601
- return /*#__PURE__*/jsx(Field$1, {
1602
- label: field.label,
1603
- description: field.description,
1604
- children: inputProps => /*#__PURE__*/jsx(ForceValidationProvider, {
1605
- value: !!forceValidation,
1606
- children: /*#__PURE__*/jsx(DocumentEditor, {
1607
- ...inputProps,
1608
- autoFocus: autoFocus,
1609
- componentBlocks: field.componentBlocks,
1610
- documentFeatures: field.documentFeatures,
1611
- onChange: onChange,
1612
- relationships: field.relationships,
1613
- value: value
1614
- })
1615
- })
1616
- });
1617
- }
1618
-
1619
- export { Field as default };