@nethru/ui 1.0.56 → 1.0.58

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 (2) hide show
  1. package/dist/Editor.js +70 -5
  2. package/package.json +1 -1
package/dist/Editor.js CHANGED
@@ -1,9 +1,12 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { Box, Typography } from "@mui/material";
1
3
  import CodeMirror from '@uiw/react-codemirror';
2
4
  import { javascript } from '@codemirror/lang-javascript';
3
5
  import { json } from '@codemirror/lang-json';
4
6
  import { EditorView } from "@codemirror/view";
5
- import { Box, Typography } from "@mui/material";
6
- import { useEffect, useMemo, useRef, useState } from "react";
7
+ import { RegExpCursor, SearchCursor } from '@codemirror/search';
8
+ import { StateEffect, StateField } from "@codemirror/state";
9
+ import { Decoration } from "@codemirror/view";
7
10
  import { jsx as _jsx } from "react/jsx-runtime";
8
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
9
12
  export default function Editor({
@@ -14,11 +17,15 @@ export default function Editor({
14
17
  basicSetup,
15
18
  extensions = [],
16
19
  jsonFormat = false,
20
+ keyword,
21
+ isRegExp = false,
22
+ autoScrollToBottom = false,
17
23
  onUpdate,
18
24
  style,
19
25
  ...props
20
26
  }) {
21
27
  const ref = useRef();
28
+ const [view, setView] = useState();
22
29
  const [content, setContent] = useState('');
23
30
  const [focused, setFocused] = useState(false);
24
31
  const styles = useMemo(() => {
@@ -28,13 +35,70 @@ export default function Editor({
28
35
  };
29
36
  // eslint-disable-next-line
30
37
  }, [readOnly, error, focused, ref.current]);
38
+ const highlight = useMemo(() => {
39
+ const highlightEffect = StateEffect.define();
40
+ const decoration = Decoration.mark({
41
+ attributes: {
42
+ style: "background-color:#e9db5d" //#90caf9
43
+ }
44
+ });
45
+
46
+ const extension = StateField.define({
47
+ create() {
48
+ return Decoration.none;
49
+ },
50
+ update(value, transaction) {
51
+ value = value.map(transaction.changes);
52
+ for (let effect of transaction.effects) {
53
+ if (effect.is(highlightEffect)) {
54
+ value = value.update({
55
+ add: effect.value,
56
+ sort: true
57
+ });
58
+ }
59
+ }
60
+ return value;
61
+ },
62
+ provide: field => EditorView.decorations.from(field)
63
+ });
64
+ return {
65
+ effect: highlightEffect,
66
+ decoration: decoration,
67
+ extension: extension
68
+ };
69
+ }, []);
31
70
  const handleUpdate = viewUpdate => {
32
71
  setFocused(viewUpdate.view.hasFocus);
33
72
  if (onUpdate) onUpdate(viewUpdate);
34
73
  };
74
+ const highlightKeyword = useCallback(() => {
75
+ if (!view || !keyword) return;
76
+ const {
77
+ effect,
78
+ decoration
79
+ } = highlight;
80
+ const cursor = isRegExp ? new RegExpCursor(view.state.doc, keyword) : new SearchCursor(view.state.doc, keyword, undefined, undefined, s => s.toLowerCase());
81
+ while (true) {
82
+ cursor.next();
83
+ if (cursor.done) break;
84
+ view.dispatch({
85
+ effects: effect.of([decoration.range(cursor.value.from, cursor.value.to)])
86
+ });
87
+ }
88
+ }, [view, highlight, keyword, isRegExp]);
89
+ const scrollToBottom = useCallback(() => {
90
+ if (!view || !autoScrollToBottom) return;
91
+ view.dispatch({
92
+ effects: EditorView.scrollIntoView(view.state.doc.length)
93
+ });
94
+ }, [view, autoScrollToBottom]);
35
95
  useEffect(() => {
36
- setTimeout(() => setContent(value), 100);
37
- }, [value]);
96
+ setTimeout(() => {
97
+ setContent(value);
98
+ highlightKeyword();
99
+ scrollToBottom();
100
+ }, 100);
101
+ }, [value, view, highlightKeyword, scrollToBottom]);
38
102
  return /*#__PURE__*/_jsxs(Box, {
39
103
  ref: ref,
40
104
  children: [/*#__PURE__*/_jsx(CodeMirror, {
@@ -42,12 +106,13 @@ export default function Editor({
42
106
  editable: !readOnly,
43
107
  extensions: [jsonFormat ? json() : javascript({
44
108
  jsx: true
45
- }), EditorView.lineWrapping, ...extensions],
109
+ }), EditorView.lineWrapping, highlight.extension, ...extensions],
46
110
  basicSetup: {
47
111
  ...basicSetup,
48
112
  highlightActiveLineGutter: false,
49
113
  highlightActiveLine: !readOnly
50
114
  },
115
+ onCreateEditor: (view, state) => setView(view),
51
116
  onUpdate: handleUpdate,
52
117
  style: {
53
118
  ...style,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nethru/ui",
3
- "version": "1.0.56",
3
+ "version": "1.0.58",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "/dist"