@arkyn/components 1.3.116 → 1.3.118
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/bundle.js +2446 -2431
- package/dist/bundle.umd.cjs +28 -28
- package/dist/components/RichText/index.d.ts +2 -1
- package/dist/components/RichText/index.d.ts.map +1 -1
- package/dist/components/RichText/index.js +21 -8
- package/package.json +1 -1
- package/src/components/RichText/index.tsx +26 -17
@@ -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,
|
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
|
-
|
17
|
-
|
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
|
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)
|
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
@@ -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
|
-
|
52
|
-
|
53
|
-
|
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
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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
|
}
|