@arkyn/components 1.3.116 → 1.3.118

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.
@@ -6,9 +6,10 @@ type RichTextProps = {
6
6
  enforceCharacterLimit?: boolean;
7
7
  defaultValue?: string;
8
8
  isError?: boolean;
9
+ onChangeCharactersCount: (e: number) => void;
9
10
  onChange?: (value: Descendant[]) => void;
10
11
  onValueChange?: (value: string) => void;
11
12
  };
12
- declare function RichText({ name, defaultValue, enforceCharacterLimit, maxLimit, onValueChange, onChange, isError: baseIsError, }: RichTextProps): import("react/jsx-runtime").JSX.Element;
13
+ declare function RichText({ name, defaultValue, enforceCharacterLimit, onChangeCharactersCount, maxLimit, onValueChange, onChange, isError: baseIsError, }: RichTextProps): import("react/jsx-runtime").JSX.Element;
13
14
  export { RichText };
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RichText/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAgB,UAAU,EAAoB,MAAM,OAAO,CAAC;AAanE,OAAO,cAAc,CAAC;AAGtB,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAEF,iBAAS,QAAQ,CAAC,EAChB,IAAI,EACJ,YAAY,EACZ,qBAA6B,EAC7B,QAAe,EACf,aAAa,EACb,QAAQ,EACR,OAAO,EAAE,WAAW,GACrB,EAAE,aAAa,2CA8Gf;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RichText/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAgB,UAAU,EAAoB,MAAM,OAAO,CAAC;AAanE,OAAO,cAAc,CAAC;AAGtB,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uBAAuB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAEF,iBAAS,QAAQ,CAAC,EAChB,IAAI,EACJ,YAAY,EACZ,qBAA6B,EAC7B,uBAAuB,EACvB,QAAe,EACf,aAAa,EACb,QAAQ,EACR,OAAO,EAAE,WAAW,GACrB,EAAE,aAAa,2CAqHf;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import isHotkey from "is-hotkey";
2
3
  import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold, Code, Heading1, Heading2, Italic, Quote, Underline, } from "lucide-react";
3
4
  import { useCallback, useMemo, useRef, useState } from "react";
4
5
  import { createEditor, Transforms, Node } from "slate";
@@ -9,12 +10,18 @@ import { Element } from "./components/Element";
9
10
  import { Leaf } from "./components/Leaf";
10
11
  import { MarkButton } from "./components/MarkButton";
11
12
  import { Toolbar } from "./components/Toolbar";
13
+ import { toggleMark } from "./functions/toggleMark";
14
+ import { HOTKEYS } from "./template/HOTKEYS";
12
15
  import { INITIAL_VALUE } from "./template/INITIAL_VALUE";
13
16
  import "./styles.css";
14
17
  import { useFormController } from "../Form/FormController";
15
- function RichText({ name, defaultValue, enforceCharacterLimit = false, maxLimit = 2000, onValueChange, onChange, isError: baseIsError, }) {
16
- const [charactersCount, setCharactersCount] = useState(0);
17
- const [editorValue, setEditorValue] = useState(defaultValue ? JSON.parse(defaultValue) : INITIAL_VALUE);
18
+ function RichText({ name, defaultValue, enforceCharacterLimit = false, onChangeCharactersCount, maxLimit = 2000, onValueChange, onChange, isError: baseIsError, }) {
19
+ function extractText(nodes) {
20
+ return nodes.map((n) => Node.string(n)).join("");
21
+ }
22
+ const defaultNodes = defaultValue ? JSON.parse(defaultValue) : INITIAL_VALUE;
23
+ const [charactersCount, setCharactersCount] = useState(extractText(defaultNodes).length);
24
+ const [editorValue, setEditorValue] = useState(defaultNodes);
18
25
  const [onFocus, setOnFocus] = useState(false);
19
26
  const { id, inputRef, error } = useFormController();
20
27
  const baseRef = useRef(null);
@@ -23,12 +30,10 @@ function RichText({ name, defaultValue, enforceCharacterLimit = false, maxLimit
23
30
  const editor = useMemo(() => withHistory(withReact(createEditor())), []);
24
31
  const renderLeaf = useCallback(Leaf, []);
25
32
  const renderElement = useCallback(Element, []);
26
- function extractText(nodes) {
27
- return nodes.map((n) => Node.string(n)).join("");
28
- }
29
33
  function handleChange(value) {
30
34
  const text = extractText(value);
31
35
  setCharactersCount(text.length);
36
+ onChangeCharactersCount && onChangeCharactersCount(text.length);
32
37
  if (enforceCharacterLimit && text.length >= maxLimit) {
33
38
  return;
34
39
  }
@@ -43,11 +48,19 @@ function RichText({ name, defaultValue, enforceCharacterLimit = false, maxLimit
43
48
  const focusClass = onFocus ? "focusTrue" : "focusFalse";
44
49
  const errorClass = isError
45
50
  ? "errorTrue"
46
- : maxLimit === charactersCount
51
+ : maxLimit < charactersCount
47
52
  ? "errorTrue"
48
53
  : "errorFalse";
49
54
  const className = `arkynRichText ${errorClass} ${focusClass}`;
50
55
  const restatesCharacters = maxLimit - charactersCount;
51
- return (_jsxs(Slate, { editor: editor, initialValue: defaultValue ? JSON.parse(defaultValue) : INITIAL_VALUE, onChange: handleChange, onValueChange: handleChange, children: [_jsxs("div", { className: className, children: [_jsxs(Toolbar, { children: [_jsx(BlockButton, { format: "headingOne", icon: Heading1 }), _jsx(BlockButton, { format: "headingTwo", icon: Heading2 }), _jsx(BlockButton, { format: "blockQuote", icon: Quote }), _jsx(MarkButton, { format: "bold", icon: Bold }), _jsx(MarkButton, { format: "italic", icon: Italic }), _jsx(MarkButton, { format: "underline", icon: Underline }), _jsx(MarkButton, { format: "code", icon: Code }), _jsx(BlockButton, { format: "left", icon: AlignLeft }), _jsx(BlockButton, { format: "right", icon: AlignRight }), _jsx(BlockButton, { format: "center", icon: AlignCenter }), _jsx(BlockButton, { format: "justify", icon: AlignJustify })] }), _jsx(Editable, { className: "editorContainer", renderElement: renderElement, renderLeaf: renderLeaf, spellCheck: true, id: id, onFocus: () => setOnFocus(true), onBlur: () => setOnFocus(false) }), restatesCharacters < 0 && (_jsx("div", { className: "restatesCharacters", children: restatesCharacters }))] }), _jsx("input", { ref: ref, type: "hidden", name: name, value: JSON.stringify(editorValue) })] }));
56
+ return (_jsxs(Slate, { editor: editor, initialValue: defaultValue ? JSON.parse(defaultValue) : INITIAL_VALUE, onChange: handleChange, onValueChange: handleChange, children: [_jsxs("div", { className: className, children: [_jsxs(Toolbar, { children: [_jsx(BlockButton, { format: "headingOne", icon: Heading1 }), _jsx(BlockButton, { format: "headingTwo", icon: Heading2 }), _jsx(BlockButton, { format: "blockQuote", icon: Quote }), _jsx(MarkButton, { format: "bold", icon: Bold }), _jsx(MarkButton, { format: "italic", icon: Italic }), _jsx(MarkButton, { format: "underline", icon: Underline }), _jsx(MarkButton, { format: "code", icon: Code }), _jsx(BlockButton, { format: "left", icon: AlignLeft }), _jsx(BlockButton, { format: "right", icon: AlignRight }), _jsx(BlockButton, { format: "center", icon: AlignCenter }), _jsx(BlockButton, { format: "justify", icon: AlignJustify })] }), _jsx(Editable, { className: "editorContainer", renderElement: renderElement, renderLeaf: renderLeaf, spellCheck: true, id: id, onFocus: () => setOnFocus(true), onBlur: () => setOnFocus(false), onKeyDown: (event) => {
57
+ for (const hotkey in HOTKEYS) {
58
+ if (isHotkey(hotkey, event)) {
59
+ event.preventDefault();
60
+ const mark = HOTKEYS[hotkey];
61
+ toggleMark(editor, mark);
62
+ }
63
+ }
64
+ } }), restatesCharacters < 0 && (_jsx("div", { className: "restatesCharacters", children: restatesCharacters }))] }), _jsx("input", { ref: ref, type: "hidden", name: name, value: JSON.stringify(editorValue) }), _jsx("input", { type: "hidden", name: `${name}Count`, value: charactersCount })] }));
52
65
  }
53
66
  export { RichText };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkyn/components",
3
- "version": "1.3.116",
3
+ "version": "1.3.118",
4
4
  "main": "./dist/bundle.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Lucas Gonçalves",
@@ -35,6 +35,7 @@ type RichTextProps = {
35
35
  enforceCharacterLimit?: boolean;
36
36
  defaultValue?: string;
37
37
  isError?: boolean;
38
+ onChangeCharactersCount: (e: number) => void;
38
39
  onChange?: (value: Descendant[]) => void;
39
40
  onValueChange?: (value: string) => void;
40
41
  };
@@ -43,15 +44,23 @@ function RichText({
43
44
  name,
44
45
  defaultValue,
45
46
  enforceCharacterLimit = false,
47
+ onChangeCharactersCount,
46
48
  maxLimit = 2000,
47
49
  onValueChange,
48
50
  onChange,
49
51
  isError: baseIsError,
50
52
  }: RichTextProps) {
51
- const [charactersCount, setCharactersCount] = useState(0);
52
- const [editorValue, setEditorValue] = useState<Descendant[]>(
53
- defaultValue ? JSON.parse(defaultValue) : INITIAL_VALUE
53
+ function extractText(nodes: Descendant[]) {
54
+ return nodes.map((n) => Node.string(n)).join("");
55
+ }
56
+
57
+ const defaultNodes = defaultValue ? JSON.parse(defaultValue) : INITIAL_VALUE;
58
+
59
+ const [charactersCount, setCharactersCount] = useState(
60
+ extractText(defaultNodes).length
54
61
  );
62
+
63
+ const [editorValue, setEditorValue] = useState<Descendant[]>(defaultNodes);
55
64
  const [onFocus, setOnFocus] = useState(false);
56
65
 
57
66
  const { id, inputRef, error } = useFormController();
@@ -66,14 +75,12 @@ function RichText({
66
75
  const renderLeaf = useCallback(Leaf, []);
67
76
  const renderElement = useCallback(Element, []);
68
77
 
69
- function extractText(nodes: Descendant[]) {
70
- return nodes.map((n) => Node.string(n)).join("");
71
- }
72
-
73
78
  function handleChange(value: Descendant[]) {
74
79
  const text = extractText(value);
75
80
  setCharactersCount(text.length);
76
81
 
82
+ onChangeCharactersCount && onChangeCharactersCount(text.length);
83
+
77
84
  if (enforceCharacterLimit && text.length >= maxLimit) {
78
85
  return;
79
86
  } else {
@@ -90,7 +97,7 @@ function RichText({
90
97
  const focusClass = onFocus ? "focusTrue" : "focusFalse";
91
98
  const errorClass = isError
92
99
  ? "errorTrue"
93
- : maxLimit === charactersCount
100
+ : maxLimit < charactersCount
94
101
  ? "errorTrue"
95
102
  : "errorFalse";
96
103
 
@@ -133,15 +140,15 @@ function RichText({
133
140
  id={id}
134
141
  onFocus={() => setOnFocus(true)}
135
142
  onBlur={() => setOnFocus(false)}
136
- // onKeyDown={(event) => {
137
- // for (const hotkey in HOTKEYS) {
138
- // if (isHotkey(hotkey, event as any)) {
139
- // event.preventDefault();
140
- // const mark = HOTKEYS[hotkey as keyof typeof HOTKEYS];
141
- // toggleMark(editor, mark);
142
- // }
143
- // }
144
- // }}
143
+ onKeyDown={(event) => {
144
+ for (const hotkey in HOTKEYS) {
145
+ if (isHotkey(hotkey, event as any)) {
146
+ event.preventDefault();
147
+ const mark = HOTKEYS[hotkey as keyof typeof HOTKEYS];
148
+ toggleMark(editor, mark);
149
+ }
150
+ }
151
+ }}
145
152
  />
146
153
 
147
154
  {restatesCharacters < 0 && (
@@ -155,6 +162,8 @@ function RichText({
155
162
  name={name}
156
163
  value={JSON.stringify(editorValue)}
157
164
  />
165
+
166
+ <input type="hidden" name={`${name}Count`} value={charactersCount} />
158
167
  </Slate>
159
168
  );
160
169
  }