pds-dev-kit-web 2.2.225 → 2.2.226
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.
- package/dist/src/desktop/components/RichTextEditor/RichTextEditor.d.ts +5 -2
- package/dist/src/desktop/components/RichTextEditor/RichTextEditor.js +47 -21
- package/dist/src/mobile/components/RichTextEditor/RichTextEditor.d.ts +5 -2
- package/dist/src/mobile/components/RichTextEditor/RichTextEditor.js +46 -19
- package/package.json +1 -1
- package/release-note.md +2 -2
|
@@ -24,11 +24,14 @@ export type RichTextEditorProps = {
|
|
|
24
24
|
fileSizeValidationText?: string;
|
|
25
25
|
height?: string | number;
|
|
26
26
|
tinymceScriptSrc?: string;
|
|
27
|
-
onChange?: (value: string) => void;
|
|
27
|
+
onChange?: (value: string, isValid?: boolean) => void;
|
|
28
28
|
onBlur?: (value: string, count: number) => void;
|
|
29
|
-
onCountCharacter?: (count: number) => void;
|
|
30
29
|
onImageUpload?: ImageUploadHandler;
|
|
31
30
|
isLoadingUsed?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated onChange 이벤트를 사용해주세요.
|
|
33
|
+
*/
|
|
34
|
+
onCountCharacter?: (count: number) => void;
|
|
32
35
|
};
|
|
33
36
|
declare function RichTextEditor({ toolbar, defaultText, hintText, maxLength, minLength, maxFileSize, requirementMode, lengthValidationText, requiredValidationText, fileSizeValidationText, height, tinymceScriptSrc, onChange, onBlur, onCountCharacter, onImageUpload, isLoadingUsed }: RichTextEditorProps): JSX.Element;
|
|
34
37
|
export default RichTextEditor;
|
|
@@ -52,19 +52,20 @@ var uuid_1 = require("uuid");
|
|
|
52
52
|
var components_1 = require("../../../common/components");
|
|
53
53
|
var styled_components_1 = __importDefault(require("styled-components"));
|
|
54
54
|
var DesktopAlertDialog_1 = require("../DesktopAlertDialog");
|
|
55
|
+
var DEFAULT_ELEMENT_COUNT = 7;
|
|
55
56
|
function RichTextEditor(_a) {
|
|
56
57
|
var _this = this;
|
|
57
|
-
var _b;
|
|
58
|
-
var toolbar = _a.toolbar, defaultText = _a.defaultText, hintText = _a.hintText, maxLength = _a.maxLength, minLength = _a.minLength, maxFileSize = _a.maxFileSize,
|
|
58
|
+
var _b, _c, _d;
|
|
59
|
+
var toolbar = _a.toolbar, defaultText = _a.defaultText, hintText = _a.hintText, maxLength = _a.maxLength, minLength = _a.minLength, maxFileSize = _a.maxFileSize, _e = _a.requirementMode, requirementMode = _e === void 0 ? 'none' : _e, lengthValidationText = _a.lengthValidationText, requiredValidationText = _a.requiredValidationText, fileSizeValidationText = _a.fileSizeValidationText, _f = _a.height, height = _f === void 0 ? 600 : _f, _g = _a.tinymceScriptSrc, tinymceScriptSrc = _g === void 0 ? '/tinymce/tinymce.min.js' : _g, onChange = _a.onChange, onBlur = _a.onBlur, onCountCharacter = _a.onCountCharacter, onImageUpload = _a.onImageUpload, _h = _a.isLoadingUsed, isLoadingUsed = _h === void 0 ? true : _h;
|
|
59
60
|
var t = (0, react_i18next_1.useTranslation)('translation').t;
|
|
60
|
-
var
|
|
61
|
-
var
|
|
62
|
-
var
|
|
61
|
+
var _j = (0, react_1.useState)(0), count = _j[0], setCount = _j[1];
|
|
62
|
+
var _k = (0, react_1.useState)(true), isEditorLoading = _k[0], setIsEditorLoading = _k[1];
|
|
63
|
+
var _l = (0, react_1.useState)(false), isEditorDirty = _l[0], setIsEditorDirty = _l[1];
|
|
64
|
+
var _m = (0, react_1.useState)(false), isFileValidationAlertDialogOpen = _m[0], setIsFilValidationAlertDialogOpen = _m[1];
|
|
63
65
|
var editorRef = (0, react_1.useRef)(null);
|
|
64
|
-
var isEditorDirty = (0, react_1.useRef)(false);
|
|
65
66
|
var editorContent = (_b = editorRef.current) === null || _b === void 0 ? void 0 : _b.getContent();
|
|
67
|
+
var elementsCount = Array.from((_d = (_c = editorRef.current) === null || _c === void 0 ? void 0 : _c.contentDocument.all) !== null && _d !== void 0 ? _d : []).filter(function (element) { return !['BR', 'P'].includes(element.tagName); }).length - DEFAULT_ELEMENT_COUNT;
|
|
66
68
|
var useDarkMode = window.PdsUtils.tone === 'DARK';
|
|
67
|
-
var validationText = (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
|
|
68
69
|
(0, react_1.useEffect)(function () {
|
|
69
70
|
if (defaultText && defaultText.length === 0) {
|
|
70
71
|
setCount(defaultText.length);
|
|
@@ -94,14 +95,34 @@ function RichTextEditor(_a) {
|
|
|
94
95
|
}
|
|
95
96
|
};
|
|
96
97
|
var handleEditorValueChange = function (value, editor) {
|
|
98
|
+
// NOTE: 기본 요소를 제외한 추가된 HTML 요소의 개수
|
|
99
|
+
var addedElementsCount = Array.from(editor.contentDocument.all).filter(function (element) { return !['BR', 'P'].includes(element.tagName); }).length - DEFAULT_ELEMENT_COUNT;
|
|
97
100
|
var wordCount = editor.plugins.wordcount;
|
|
101
|
+
var charCount = 0;
|
|
98
102
|
if (wordCount) {
|
|
99
|
-
|
|
103
|
+
charCount = wordCount.body.getCharacterCount();
|
|
100
104
|
onCountCharacter === null || onCountCharacter === void 0 ? void 0 : onCountCharacter(charCount);
|
|
101
105
|
setCount(charCount);
|
|
102
106
|
}
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
var isValid = function () {
|
|
108
|
+
// NOTE: 추가된 HTML 요소가 존재해도, maxLength를 초과할 경우.
|
|
109
|
+
if (maxLength && charCount > maxLength) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
// NOTE: 기본 요소를 제외한 추가된 HTML 요소가 존재하는 경우 유효성 검사를 통과합니다.
|
|
113
|
+
if (addedElementsCount > 0) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (requirementMode === 'use' && charCount === 0) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (minLength && charCount < minLength) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
};
|
|
124
|
+
setIsEditorDirty(value ? true : false);
|
|
125
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(value, isValid());
|
|
105
126
|
};
|
|
106
127
|
var handleEditorBlur = function () {
|
|
107
128
|
var _a, _b;
|
|
@@ -179,17 +200,22 @@ function RichTextEditor(_a) {
|
|
|
179
200
|
}
|
|
180
201
|
});
|
|
181
202
|
}); };
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
203
|
+
var validationText = (0, react_1.useMemo)(function () {
|
|
204
|
+
if (requirementMode === 'use' &&
|
|
205
|
+
!isEditorDirty &&
|
|
206
|
+
(!editorContent || editorContent.length === 0) &&
|
|
207
|
+
elementsCount <= 0) {
|
|
208
|
+
return (0, jsx_runtime_1.jsx)(S_Error, { children: requiredValidationText });
|
|
209
|
+
}
|
|
210
|
+
if (elementsCount <= 0 && minLength && count > 0 && count < minLength) {
|
|
211
|
+
return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
|
|
212
|
+
}
|
|
213
|
+
// 추가된 HTML 요소가 있어도, maxLength에 의한 validation은 수행합니다.
|
|
214
|
+
if (maxLength && count > 0 && count > maxLength) {
|
|
215
|
+
return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
|
|
216
|
+
}
|
|
217
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
|
|
218
|
+
}, [requirementMode, isEditorDirty, editorContent, elementsCount, count, minLength, maxLength]);
|
|
193
219
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(S_Editor, { children: [isEditorLoading && isLoadingUsed && ((0, jsx_runtime_1.jsx)(S_LoadingWrapper, { children: (0, jsx_runtime_1.jsx)(components_1.CircularProgress, {}) })), (0, jsx_runtime_1.jsx)(tinymce_react_1.Editor, { tinymceScriptSrc: tinymceScriptSrc, onInit: handleInit, onEditorChange: handleEditorValueChange, initialValue: defaultText, init: {
|
|
194
220
|
menubar: false,
|
|
195
221
|
promotion: false,
|
|
@@ -24,11 +24,14 @@ export type RichTextEditorProps = {
|
|
|
24
24
|
fileSizeValidationText?: string;
|
|
25
25
|
height?: string | number;
|
|
26
26
|
tinymceScriptSrc?: string;
|
|
27
|
-
onChange?: (value: string) => void;
|
|
27
|
+
onChange?: (value: string, isValid?: boolean) => void;
|
|
28
28
|
onBlur?: (value: string, count: number) => void;
|
|
29
|
-
onCountCharacter?: (count: number) => void;
|
|
30
29
|
onImageUpload?: ImageUploadHandler;
|
|
31
30
|
isLoadingUsed?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated onChange 이벤트를 사용해주세요.
|
|
33
|
+
*/
|
|
34
|
+
onCountCharacter?: (count: number) => void;
|
|
32
35
|
};
|
|
33
36
|
declare function RichTextEditor({ toolbar, defaultText, hintText, maxLength, minLength, maxFileSize, required, lengthValidationText, requiredValidationText, fileSizeValidationText, height, tinymceScriptSrc, onChange, onBlur, onCountCharacter, onImageUpload, isLoadingUsed }: RichTextEditorProps): JSX.Element;
|
|
34
37
|
export default RichTextEditor;
|
|
@@ -52,19 +52,20 @@ var uuid_1 = require("uuid");
|
|
|
52
52
|
var components_1 = require("../../../common/components");
|
|
53
53
|
var styled_components_1 = __importDefault(require("styled-components"));
|
|
54
54
|
var MobileAlertDialog_1 = require("../MobileAlertDialog");
|
|
55
|
+
var DEFAULT_ELEMENT_COUNT = 7;
|
|
55
56
|
function RichTextEditor(_a) {
|
|
56
57
|
var _this = this;
|
|
57
|
-
var _b;
|
|
58
|
-
var toolbar = _a.toolbar, defaultText = _a.defaultText, hintText = _a.hintText, maxLength = _a.maxLength, minLength = _a.minLength, maxFileSize = _a.maxFileSize, required = _a.required, lengthValidationText = _a.lengthValidationText, requiredValidationText = _a.requiredValidationText, fileSizeValidationText = _a.fileSizeValidationText,
|
|
58
|
+
var _b, _c, _d;
|
|
59
|
+
var toolbar = _a.toolbar, defaultText = _a.defaultText, hintText = _a.hintText, maxLength = _a.maxLength, minLength = _a.minLength, maxFileSize = _a.maxFileSize, required = _a.required, lengthValidationText = _a.lengthValidationText, requiredValidationText = _a.requiredValidationText, fileSizeValidationText = _a.fileSizeValidationText, _e = _a.height, height = _e === void 0 ? 600 : _e, _f = _a.tinymceScriptSrc, tinymceScriptSrc = _f === void 0 ? '/tinymce/tinymce.min.js' : _f, onChange = _a.onChange, onBlur = _a.onBlur, onCountCharacter = _a.onCountCharacter, onImageUpload = _a.onImageUpload, _g = _a.isLoadingUsed, isLoadingUsed = _g === void 0 ? true : _g;
|
|
59
60
|
var t = (0, react_i18next_1.useTranslation)('translation').t;
|
|
60
|
-
var
|
|
61
|
-
var
|
|
62
|
-
var
|
|
61
|
+
var _h = (0, react_1.useState)(0), count = _h[0], setCount = _h[1];
|
|
62
|
+
var _j = (0, react_1.useState)(true), isEditorLoading = _j[0], setIsEditorLoading = _j[1];
|
|
63
|
+
var _k = (0, react_1.useState)(false), isEditorDirty = _k[0], setIsEditorDirty = _k[1];
|
|
64
|
+
var _l = (0, react_1.useState)(false), isFileValidationAlertDialogOpen = _l[0], setIsFilValidationAlertDialogOpen = _l[1];
|
|
63
65
|
var editorRef = (0, react_1.useRef)(null);
|
|
64
|
-
var isEditorDirty = (0, react_1.useRef)(false);
|
|
65
66
|
var editorContent = (_b = editorRef.current) === null || _b === void 0 ? void 0 : _b.getContent();
|
|
67
|
+
var elementsCount = Array.from((_d = (_c = editorRef.current) === null || _c === void 0 ? void 0 : _c.contentDocument.all) !== null && _d !== void 0 ? _d : []).filter(function (element) { return !['BR', 'P'].includes(element.tagName); }).length - DEFAULT_ELEMENT_COUNT;
|
|
66
68
|
var useDarkMode = window.PdsUtils.tone === 'DARK';
|
|
67
|
-
var validationText = (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
|
|
68
69
|
(0, react_1.useEffect)(function () {
|
|
69
70
|
if (defaultText && defaultText.length === 0) {
|
|
70
71
|
setCount(defaultText.length);
|
|
@@ -94,14 +95,34 @@ function RichTextEditor(_a) {
|
|
|
94
95
|
}
|
|
95
96
|
};
|
|
96
97
|
var handleEditorValueChange = function (value, editor) {
|
|
98
|
+
// NOTE: 기본 요소를 제외한 추가된 HTML 요소의 개수
|
|
99
|
+
var addedElementsCount = Array.from(editor.contentDocument.all).filter(function (element) { return !['BR', 'P'].includes(element.tagName); }).length - DEFAULT_ELEMENT_COUNT;
|
|
97
100
|
var wordCount = editor.plugins.wordcount;
|
|
101
|
+
var charCount = 0;
|
|
98
102
|
if (wordCount) {
|
|
99
|
-
|
|
103
|
+
charCount = wordCount.body.getCharacterCount();
|
|
100
104
|
onCountCharacter === null || onCountCharacter === void 0 ? void 0 : onCountCharacter(charCount);
|
|
101
105
|
setCount(charCount);
|
|
102
106
|
}
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
var isValid = function () {
|
|
108
|
+
// NOTE: 추가된 HTML 요소가 존재해도, maxLength를 초과할 경우.
|
|
109
|
+
if (maxLength && charCount > maxLength) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
// NOTE: 기본 요소를 제외한 추가된 HTML 요소가 존재하는 경우 유효성 검사를 통과합니다.
|
|
113
|
+
if (addedElementsCount > 0) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (required && charCount === 0) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (minLength && charCount < minLength) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
};
|
|
124
|
+
setIsEditorDirty(value ? true : false);
|
|
125
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(value, isValid());
|
|
105
126
|
};
|
|
106
127
|
var handleEditorBlur = function () {
|
|
107
128
|
var _a, _b;
|
|
@@ -179,15 +200,21 @@ function RichTextEditor(_a) {
|
|
|
179
200
|
}
|
|
180
201
|
});
|
|
181
202
|
}); };
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
var validationText = (0, react_1.useMemo)(function () {
|
|
204
|
+
if (required &&
|
|
205
|
+
!isEditorDirty &&
|
|
206
|
+
(!editorContent || editorContent.length === 0) &&
|
|
207
|
+
elementsCount <= 0) {
|
|
208
|
+
return (0, jsx_runtime_1.jsx)(S_Error, { children: requiredValidationText });
|
|
209
|
+
}
|
|
210
|
+
if (elementsCount <= 0 && minLength && count > 0 && count < minLength) {
|
|
211
|
+
return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
|
|
212
|
+
}
|
|
213
|
+
if (maxLength && count > 0 && count > maxLength) {
|
|
214
|
+
return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
|
|
215
|
+
}
|
|
216
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
|
|
217
|
+
}, [required, isEditorDirty, editorContent, elementsCount, count, minLength, maxLength]);
|
|
191
218
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(S_Editor, { children: [isEditorLoading && isLoadingUsed && ((0, jsx_runtime_1.jsx)(S_LoadingWrapper, { children: (0, jsx_runtime_1.jsx)(components_1.CircularProgress, {}) })), (0, jsx_runtime_1.jsx)(tinymce_react_1.Editor, { tinymceScriptSrc: tinymceScriptSrc, onInit: handleInit, onEditorChange: handleEditorValueChange, initialValue: defaultText, init: {
|
|
192
219
|
images_max_width: '100%',
|
|
193
220
|
menubar: false,
|
package/package.json
CHANGED
package/release-note.md
CHANGED