x-star-editor 0.1.2 → 0.2.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.
@@ -0,0 +1,3 @@
1
+ declare module '*.worker.js' {
2
+ export default string;
3
+ }
@@ -1,5 +1,5 @@
1
1
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
- import { useEffect, useRef } from 'react';
2
+ import { useRef } from 'react';
3
3
  import { editorRender } from "./markdown";
4
4
 
5
5
  /**
@@ -343,38 +343,24 @@ export var useContainer = function useContainer() {
343
343
  return;
344
344
  }
345
345
  selection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
346
- };
346
+ if (!ref.current) {
347
+ return;
348
+ }
349
+ var range = document.createRange();
350
+ range.setStart(focus.node, focus.offset);
351
+ range.setEnd(focus.node, focus.offset);
352
+ var rangeRect = range.getBoundingClientRect();
353
+ var containerRect = ref.current.getBoundingClientRect();
354
+ var topOffset = rangeRect.top - containerRect.top;
355
+ var bottomOffset = rangeRect.bottom - containerRect.bottom;
347
356
 
348
- // 容器选区改变后将光标滚动到视口内
349
- useEffect(function () {
350
- var listener = function listener() {
351
- var selection = window.getSelection();
352
- if (!selection || !selection.focusNode || !ref.current || !ref.current.contains(selection.focusNode)) {
353
- return;
354
- }
355
- var range = document.createRange();
356
- range.setStart(selection.focusNode, selection.focusOffset);
357
- range.setEnd(selection.focusNode, selection.focusOffset);
358
- var rangeRect = range.getBoundingClientRect();
359
- var containerRect = ref.current.getBoundingClientRect();
360
- var topOffset = rangeRect.top - containerRect.top;
361
- var bottomOffset = rangeRect.bottom - containerRect.bottom;
362
- if (topOffset < 10) {
363
- ref.current.scrollTop += topOffset - 10;
364
- } else if (bottomOffset > -10) {
365
- ref.current.scrollTop += bottomOffset + 10;
366
- }
367
- };
368
- document.addEventListener('selectionchange', listener, {
369
- capture: true,
370
- passive: true
371
- });
372
- return function () {
373
- return document.removeEventListener('selectionchange', listener, {
374
- capture: true
375
- });
376
- };
377
- }, []);
357
+ // 将光标滚动到视口内
358
+ if (topOffset < 0) {
359
+ ref.current.scrollTop += topOffset;
360
+ } else if (bottomOffset > 0) {
361
+ ref.current.scrollTop += bottomOffset;
362
+ }
363
+ };
378
364
  return useRef({
379
365
  ref: ref,
380
366
  normalize: normalize,
@@ -1,4 +1,5 @@
1
1
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
+ import { createKeybindingsHandler } from 'tinykeys';
2
3
  import { createSelection, getRange } from "./container";
3
4
 
4
5
  /**
@@ -90,111 +91,255 @@ export var selectHandler = function selectHandler(selection) {
90
91
  */
91
92
 
92
93
  export var getDefaultKeyboardEventHandlers = function getDefaultKeyboardEventHandlers() {
93
- return [
94
- // 处理 Enter 和 Tab
95
- function (_ref8) {
96
- var selection = _ref8.selection,
94
+ return [function (_ref8) {
95
+ var sourceCode = _ref8.sourceCode,
96
+ selection = _ref8.selection,
97
97
  dispatch = _ref8.dispatch,
98
98
  e = _ref8.e;
99
- if (!e.altKey && !e.ctrlKey && !e.metaKey && (e.key === 'Enter' || e.key === 'Tab')) {
100
- e.preventDefault();
101
- dispatch({
102
- type: 'insert',
103
- payload: {
104
- text: e.key === 'Enter' ? '\n' : '\t'
105
- },
106
- selection: selection
107
- });
108
- }
109
- },
110
- // 处理 Backspace 和 Delete
111
- function (_ref9) {
112
- var selection = _ref9.selection,
113
- dispatch = _ref9.dispatch,
114
- e = _ref9.e;
115
- if (!e.altKey && !e.metaKey && (e.key === 'Backspace' || e.key === 'Delete')) {
116
- e.preventDefault();
117
- dispatch({
118
- type: 'delete',
119
- payload: {
120
- direction: e.key === 'Backspace' ? 'backward' : 'forward',
121
- boundary: !e.ctrlKey ? 'char' : 'line'
122
- },
123
- selection: selection
124
- });
125
- }
126
- },
127
- // 处理斜体和粗体
128
- function (_ref10) {
129
- var selection = _ref10.selection,
130
- dispatch = _ref10.dispatch,
131
- e = _ref10.e;
132
- if (!e.altKey && e.ctrlKey && !e.metaKey && (e.key === 'i' || e.key === 'b')) {
133
- e.preventDefault();
134
- dispatch({
135
- type: 'toggle',
136
- payload: {
137
- type: e.key === 'i' ? 'emphasis' : 'strong'
138
- },
139
- selection: selection
140
- });
141
- }
142
- },
143
- // 处理撤销和恢复
144
- function (_ref11) {
145
- var dispatch = _ref11.dispatch,
146
- e = _ref11.e;
147
- if (!e.altKey && e.ctrlKey && !e.metaKey && (e.key === 'z' || e.key === 'y')) {
148
- e.preventDefault();
149
- dispatch({
150
- type: e.key === 'z' ? 'undo' : 'redo'
151
- });
152
- }
153
- },
154
- // 处理左键和右键
155
- function (_ref12) {
156
- var sourceCode = _ref12.sourceCode,
157
- selection = _ref12.selection,
158
- dispatch = _ref12.dispatch,
159
- e = _ref12.e;
160
- if (!e.altKey && !e.ctrlKey && !e.metaKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight')) {
161
- e.preventDefault();
162
- var anchorOffset = selection.anchorOffset,
163
- focusOffset = selection.focusOffset;
164
- var _getRange = getRange(selection),
165
- startOffset = _getRange.startOffset,
166
- endOffset = _getRange.endOffset;
167
- if (e.shiftKey) {
168
- if (e.key === 'ArrowLeft' && focusOffset) {
99
+ return createKeybindingsHandler({
100
+ Tab: function Tab(e) {
101
+ e.preventDefault();
102
+ dispatch({
103
+ type: 'insert',
104
+ payload: {
105
+ text: '\t'
106
+ },
107
+ selection: selection
108
+ });
109
+ },
110
+ Backspace: function Backspace(e) {
111
+ e.preventDefault();
112
+ dispatch({
113
+ type: 'delete',
114
+ payload: {
115
+ direction: 'backward',
116
+ boundary: 'char'
117
+ },
118
+ selection: selection
119
+ });
120
+ },
121
+ '$mod+Backspace': function $modBackspace(e) {
122
+ e.preventDefault();
123
+ dispatch({
124
+ type: 'delete',
125
+ payload: {
126
+ direction: 'backward',
127
+ boundary: 'line'
128
+ },
129
+ selection: selection
130
+ });
131
+ },
132
+ 'Shift+Backspace': function ShiftBackspace(e) {
133
+ e.preventDefault();
134
+ dispatch({
135
+ type: 'delete',
136
+ payload: {
137
+ direction: 'backward',
138
+ boundary: 'char'
139
+ },
140
+ selection: selection
141
+ });
142
+ },
143
+ 'Meta+Backspace': function MetaBackspace(e) {
144
+ return e.preventDefault();
145
+ },
146
+ 'Alt+Backspace': function AltBackspace(e) {
147
+ return e.preventDefault();
148
+ },
149
+ 'Control+Backspace': function ControlBackspace(e) {
150
+ return e.preventDefault();
151
+ },
152
+ 'Shift+Meta+Backspace': function ShiftMetaBackspace(e) {
153
+ return e.preventDefault();
154
+ },
155
+ 'Shift+Alt+Backspace': function ShiftAltBackspace(e) {
156
+ return e.preventDefault();
157
+ },
158
+ 'Shift+Control+Backspace': function ShiftControlBackspace(e) {
159
+ return e.preventDefault();
160
+ },
161
+ 'Meta+Alt+Backspace': function MetaAltBackspace(e) {
162
+ return e.preventDefault();
163
+ },
164
+ 'Meta+Control+Backspace': function MetaControlBackspace(e) {
165
+ return e.preventDefault();
166
+ },
167
+ 'Alt+Control+Backspace': function AltControlBackspace(e) {
168
+ return e.preventDefault();
169
+ },
170
+ 'Shift+Meta+Alt+Backspace': function ShiftMetaAltBackspace(e) {
171
+ return e.preventDefault();
172
+ },
173
+ 'Shift+Meta+Control+Backspace': function ShiftMetaControlBackspace(e) {
174
+ return e.preventDefault();
175
+ },
176
+ 'Shift+Alt+Control+Backspace': function ShiftAltControlBackspace(e) {
177
+ return e.preventDefault();
178
+ },
179
+ 'Meta+Alt+Control+Backspace': function MetaAltControlBackspace(e) {
180
+ return e.preventDefault();
181
+ },
182
+ Delete: function Delete(e) {
183
+ e.preventDefault();
184
+ dispatch({
185
+ type: 'delete',
186
+ payload: {
187
+ direction: 'forward',
188
+ boundary: 'char'
189
+ },
190
+ selection: selection
191
+ });
192
+ },
193
+ '$mod+Delete': function $modDelete(e) {
194
+ e.preventDefault();
195
+ dispatch({
196
+ type: 'delete',
197
+ payload: {
198
+ direction: 'forward',
199
+ boundary: 'line'
200
+ },
201
+ selection: selection
202
+ });
203
+ },
204
+ 'Shift+Delete': function ShiftDelete(e) {
205
+ e.preventDefault();
206
+ dispatch({
207
+ type: 'delete',
208
+ payload: {
209
+ direction: 'forward',
210
+ boundary: 'char'
211
+ },
212
+ selection: selection
213
+ });
214
+ },
215
+ 'Meta+Delete': function MetaDelete(e) {
216
+ return e.preventDefault();
217
+ },
218
+ 'Alt+Delete': function AltDelete(e) {
219
+ return e.preventDefault();
220
+ },
221
+ 'Control+Delete': function ControlDelete(e) {
222
+ return e.preventDefault();
223
+ },
224
+ 'Shift+Meta+Delete': function ShiftMetaDelete(e) {
225
+ return e.preventDefault();
226
+ },
227
+ 'Shift+Alt+Delete': function ShiftAltDelete(e) {
228
+ return e.preventDefault();
229
+ },
230
+ 'Shift+Control+Delete': function ShiftControlDelete(e) {
231
+ return e.preventDefault();
232
+ },
233
+ 'Meta+Alt+Delete': function MetaAltDelete(e) {
234
+ return e.preventDefault();
235
+ },
236
+ 'Meta+Control+Delete': function MetaControlDelete(e) {
237
+ return e.preventDefault();
238
+ },
239
+ 'Alt+Control+Delete': function AltControlDelete(e) {
240
+ return e.preventDefault();
241
+ },
242
+ 'Shift+Meta+Alt+Delete': function ShiftMetaAltDelete(e) {
243
+ return e.preventDefault();
244
+ },
245
+ 'Shift+Meta+Control+Delete': function ShiftMetaControlDelete(e) {
246
+ return e.preventDefault();
247
+ },
248
+ 'Shift+Alt+Control+Delete': function ShiftAltControlDelete(e) {
249
+ return e.preventDefault();
250
+ },
251
+ 'Meta+Alt+Control+Delete': function MetaAltControlDelete(e) {
252
+ return e.preventDefault();
253
+ },
254
+ '$mod+KeyI': function $modKeyI(e) {
255
+ e.preventDefault();
256
+ dispatch({
257
+ type: 'toggle',
258
+ payload: {
259
+ type: 'emphasis'
260
+ },
261
+ selection: selection
262
+ });
263
+ },
264
+ '$mod+KeyB': function $modKeyB(e) {
265
+ e.preventDefault();
266
+ dispatch({
267
+ type: 'toggle',
268
+ payload: {
269
+ type: 'strong'
270
+ },
271
+ selection: selection
272
+ });
273
+ },
274
+ '$mod+KeyZ': function $modKeyZ(e) {
275
+ e.preventDefault();
276
+ dispatch({
277
+ type: 'undo'
278
+ });
279
+ },
280
+ '$mod+KeyY': function $modKeyY(e) {
281
+ e.preventDefault();
282
+ dispatch({
283
+ type: 'redo'
284
+ });
285
+ },
286
+ ArrowLeft: function ArrowLeft(e) {
287
+ e.preventDefault();
288
+ var _getRange = getRange(selection),
289
+ startOffset = _getRange.startOffset,
290
+ endOffset = _getRange.endOffset;
291
+ if (startOffset < endOffset) {
169
292
  dispatch({
170
293
  type: 'select',
171
- selection: createSelection(anchorOffset, focusOffset - 1)
294
+ selection: createSelection(startOffset)
172
295
  });
173
- } else if (e.key === 'ArrowRight' && focusOffset < sourceCode.length) {
296
+ } else if (startOffset) {
174
297
  dispatch({
175
298
  type: 'select',
176
- selection: createSelection(anchorOffset, focusOffset + 1)
299
+ selection: createSelection(startOffset - 1)
177
300
  });
178
301
  }
179
- } else {
180
- if (startOffset < endOffset) {
302
+ },
303
+ 'Shift+ArrowLeft': function ShiftArrowLeft(e) {
304
+ e.preventDefault();
305
+ var anchorOffset = selection.anchorOffset,
306
+ focusOffset = selection.focusOffset;
307
+ if (focusOffset) {
181
308
  dispatch({
182
309
  type: 'select',
183
- selection: createSelection(e.key === 'ArrowLeft' ? startOffset : endOffset)
310
+ selection: createSelection(anchorOffset, focusOffset - 1)
184
311
  });
185
- } else if (e.key === 'ArrowLeft' && startOffset) {
312
+ }
313
+ },
314
+ ArrowRight: function ArrowRight(e) {
315
+ e.preventDefault();
316
+ var _getRange2 = getRange(selection),
317
+ startOffset = _getRange2.startOffset,
318
+ endOffset = _getRange2.endOffset;
319
+ if (startOffset < endOffset) {
186
320
  dispatch({
187
321
  type: 'select',
188
- selection: createSelection(startOffset - 1)
322
+ selection: createSelection(endOffset)
189
323
  });
190
- } else if (e.key === 'ArrowRight' && startOffset < sourceCode.length) {
324
+ } else if (startOffset < sourceCode.length) {
191
325
  dispatch({
192
326
  type: 'select',
193
327
  selection: createSelection(startOffset + 1)
194
328
  });
195
329
  }
330
+ },
331
+ 'Shift+ArrowRight': function ShiftArrowRight(e) {
332
+ e.preventDefault();
333
+ var anchorOffset = selection.anchorOffset,
334
+ focusOffset = selection.focusOffset;
335
+ if (focusOffset < sourceCode.length) {
336
+ dispatch({
337
+ type: 'select',
338
+ selection: createSelection(anchorOffset, focusOffset + 1)
339
+ });
340
+ }
196
341
  }
197
- }
342
+ })(e.nativeEvent);
198
343
  }];
199
344
  };
200
345
 
@@ -1,11 +1,17 @@
1
1
  import React from 'react';
2
2
  import type { XStarMdEditorHandle, XStarMdEditorProps } from '../x-star-md-editor';
3
3
  import type { XStarMdViewerHandle, XStarMdViewerProps } from '../x-star-md-viewer';
4
- export interface XStarEditorHandle {
5
- getEditor: () => XStarMdEditorHandle | null;
6
- getViewer: () => XStarMdViewerHandle | null;
4
+ export interface XStarEditorHandle extends XStarMdEditorHandle, XStarMdViewerHandle {
7
5
  }
8
6
  export interface XStarEditorProps {
7
+ /**
8
+ * CSS 类名
9
+ */
10
+ className?: string;
11
+ /**
12
+ * CSS 样式
13
+ */
14
+ style?: React.CSSProperties;
9
15
  /**
10
16
  * 编辑器和浏览器的高度(不包括工具栏)
11
17
  */
@@ -25,11 +31,11 @@ export interface XStarEditorProps {
25
31
  /**
26
32
  * 编辑器属性
27
33
  */
28
- editorProps?: Omit<XStarMdEditorProps, 'locale' | 'initialValue' | 'onChange' | 'onInsertFile'>;
34
+ editorProps?: Omit<XStarMdEditorProps, 'height' | 'locale' | 'initialValue' | 'onChange' | 'onInsertFile'>;
29
35
  /**
30
36
  * 浏览器属性
31
37
  */
32
- viewerProps?: Omit<XStarMdViewerProps, 'value' | 'enableWebWorker'>;
38
+ viewerProps?: Omit<XStarMdViewerProps, 'height' | 'value' | 'enableWebWorker'>;
33
39
  /**
34
40
  * 文本变化回调函数
35
41
  */
@@ -7,7 +7,9 @@ import { prefix } from "../utils/global";
7
7
  import XStarMdEditor, { useMdEditorRef } from "../x-star-md-editor";
8
8
  import XStarMdViewer, { useMdViewerRef } from "../x-star-md-viewer";
9
9
  var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
10
- var height = _ref.height,
10
+ var className = _ref.className,
11
+ style = _ref.style,
12
+ height = _ref.height,
11
13
  locale = _ref.locale,
12
14
  initialValue = _ref.initialValue,
13
15
  enableWebWorker = _ref.enableWebWorker,
@@ -22,21 +24,14 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
22
24
  var editorRef = useMdEditorRef();
23
25
  var viewerRef = useMdViewerRef();
24
26
  useImperativeHandle(ref, function () {
25
- return {
26
- getEditor: function getEditor() {
27
- return editorRef.current;
28
- },
29
- getViewer: function getViewer() {
30
- return viewerRef.current;
31
- }
32
- };
27
+ return _objectSpread(_objectSpread({}, editorRef.current), viewerRef.current);
33
28
  }, []);
34
29
 
35
30
  // 同步滚动
36
31
  useEffect(function () {
37
32
  var _editorRef$current, _viewerRef$current;
38
- var editor = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getContainer();
39
- var viewer = (_viewerRef$current = viewerRef.current) === null || _viewerRef$current === void 0 ? void 0 : _viewerRef$current.getContainer();
33
+ var editor = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getEditorContainer();
34
+ var viewer = (_viewerRef$current = viewerRef.current) === null || _viewerRef$current === void 0 ? void 0 : _viewerRef$current.getViewerContainer();
40
35
 
41
36
  /**
42
37
  * 获取两个父元素的子元素到各自父元素顶部的距离
@@ -135,13 +130,12 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
135
130
  };
136
131
  }, []);
137
132
  return /*#__PURE__*/React.createElement("div", {
138
- className: classNames("".concat(prefix, "editor"))
133
+ className: classNames("".concat(prefix, "editor"), className),
134
+ style: style
139
135
  }, /*#__PURE__*/React.createElement(XStarMdEditor, _extends({
140
136
  ref: editorRef
141
137
  }, editorProps, {
142
- style: _objectSpread(_objectSpread({}, editorProps === null || editorProps === void 0 ? void 0 : editorProps.style), {}, {
143
- height: height
144
- }),
138
+ height: height,
145
139
  locale: locale,
146
140
  initialValue: initialValue,
147
141
  onChange: function onChange(value) {
@@ -152,9 +146,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
152
146
  })), /*#__PURE__*/React.createElement(XStarMdViewer, _extends({
153
147
  ref: viewerRef
154
148
  }, viewerProps, {
155
- style: _objectSpread(_objectSpread({}, viewerProps === null || viewerProps === void 0 ? void 0 : viewerProps.style), {}, {
156
- height: height
157
- }),
149
+ height: height,
158
150
  value: value,
159
151
  enableWebWorker: enableWebWorker
160
152
  })));
@@ -7,7 +7,7 @@ interface EditorOptions {
7
7
  */
8
8
  toolbarItemMap: ToolbarItemMap;
9
9
  /**
10
- * 工具栏项
10
+ * 工具栏项数组
11
11
  */
12
12
  toolbarItems: ToolbarItems;
13
13
  /**
@@ -20,7 +20,7 @@ export interface XStarMdEditorPlugin {
20
20
  }
21
21
  export interface XStarMdEditorHandle {
22
22
  exec: Executor;
23
- getContainer: () => HTMLDivElement | null;
23
+ getEditorContainer: () => HTMLDivElement;
24
24
  }
25
25
  export interface XStarMdEditorProps {
26
26
  /**
@@ -31,6 +31,10 @@ export interface XStarMdEditorProps {
31
31
  * CSS 样式
32
32
  */
33
33
  style?: React.CSSProperties;
34
+ /**
35
+ * 编辑器的高度(不包括工具栏)
36
+ */
37
+ height?: React.CSSProperties['height'];
34
38
  /**
35
39
  * 工具栏 CSS 类名
36
40
  */