pds-dev-kit-web 2.2.225 → 2.2.227

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.
@@ -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,23 +52,27 @@ 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, _c = _a.requirementMode, requirementMode = _c === void 0 ? 'none' : _c, lengthValidationText = _a.lengthValidationText, requiredValidationText = _a.requiredValidationText, fileSizeValidationText = _a.fileSizeValidationText, _d = _a.height, height = _d === void 0 ? 600 : _d, _e = _a.tinymceScriptSrc, tinymceScriptSrc = _e === void 0 ? '/tinymce/tinymce.min.js' : _e, onChange = _a.onChange, onBlur = _a.onBlur, onCountCharacter = _a.onCountCharacter, onImageUpload = _a.onImageUpload, _f = _a.isLoadingUsed, isLoadingUsed = _f === void 0 ? true : _f;
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 _g = (0, react_1.useState)(0), count = _g[0], setCount = _g[1];
61
- var _h = (0, react_1.useState)(true), isEditorLoading = _h[0], setIsEditorLoading = _h[1];
62
- var _j = (0, react_1.useState)(false), isFileValidationAlertDialogOpen = _j[0], setIsFilValidationAlertDialogOpen = _j[1];
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);
71
72
  }
73
+ if (defaultText && defaultText.length !== 0 && editorRef.current) {
74
+ handleEditorValueChange(defaultText, editorRef.current);
75
+ }
72
76
  }, [defaultText]);
73
77
  var handleInit = function (evt, editor) {
74
78
  if (isLoadingUsed) {
@@ -94,14 +98,34 @@ function RichTextEditor(_a) {
94
98
  }
95
99
  };
96
100
  var handleEditorValueChange = function (value, editor) {
101
+ // NOTE: 기본 요소를 제외한 추가된 HTML 요소의 개수
102
+ var addedElementsCount = Array.from(editor.contentDocument.all).filter(function (element) { return !['BR', 'P'].includes(element.tagName); }).length - DEFAULT_ELEMENT_COUNT;
97
103
  var wordCount = editor.plugins.wordcount;
104
+ var charCount = 0;
98
105
  if (wordCount) {
99
- var charCount = wordCount.body.getCharacterCount();
106
+ charCount = wordCount.body.getCharacterCount();
100
107
  onCountCharacter === null || onCountCharacter === void 0 ? void 0 : onCountCharacter(charCount);
101
108
  setCount(charCount);
102
109
  }
103
- isEditorDirty.current = true;
104
- onChange === null || onChange === void 0 ? void 0 : onChange(value);
110
+ var isValid = function () {
111
+ // NOTE: 추가된 HTML 요소가 존재해도, maxLength를 초과할 경우.
112
+ if (maxLength && charCount > maxLength) {
113
+ return false;
114
+ }
115
+ // NOTE: 기본 요소를 제외한 추가된 HTML 요소가 존재하는 경우 유효성 검사를 통과합니다.
116
+ if (addedElementsCount > 0) {
117
+ return true;
118
+ }
119
+ if (requirementMode === 'use' && charCount === 0) {
120
+ return false;
121
+ }
122
+ if (minLength && charCount < minLength) {
123
+ return false;
124
+ }
125
+ return true;
126
+ };
127
+ setIsEditorDirty(value ? true : false);
128
+ onChange === null || onChange === void 0 ? void 0 : onChange(value, isValid());
105
129
  };
106
130
  var handleEditorBlur = function () {
107
131
  var _a, _b;
@@ -179,17 +203,22 @@ function RichTextEditor(_a) {
179
203
  }
180
204
  });
181
205
  }); };
182
- if (requirementMode === 'use' &&
183
- isEditorDirty.current &&
184
- (!editorContent || editorContent.length === 0)) {
185
- validationText = (0, jsx_runtime_1.jsx)(S_Error, { children: requiredValidationText });
186
- }
187
- if (minLength && count > 0 && count < minLength) {
188
- validationText = (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
189
- }
190
- if (maxLength && count > 0 && count > maxLength) {
191
- validationText = (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
192
- }
206
+ var validationText = (0, react_1.useMemo)(function () {
207
+ if (requirementMode === 'use' &&
208
+ !isEditorDirty &&
209
+ (!editorContent || editorContent.length === 0) &&
210
+ elementsCount <= 0) {
211
+ return (0, jsx_runtime_1.jsx)(S_Error, { children: requiredValidationText });
212
+ }
213
+ if (elementsCount <= 0 && minLength && count > 0 && count < minLength) {
214
+ return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
215
+ }
216
+ // 추가된 HTML 요소가 있어도, maxLength에 의한 validation은 수행합니다.
217
+ if (maxLength && count > 0 && count > maxLength) {
218
+ return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
219
+ }
220
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
221
+ }, [requirementMode, isEditorDirty, editorContent, elementsCount, count, minLength, maxLength]);
193
222
  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
223
  menubar: false,
195
224
  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,23 +52,27 @@ 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, _c = _a.height, height = _c === void 0 ? 600 : _c, _d = _a.tinymceScriptSrc, tinymceScriptSrc = _d === void 0 ? '/tinymce/tinymce.min.js' : _d, onChange = _a.onChange, onBlur = _a.onBlur, onCountCharacter = _a.onCountCharacter, onImageUpload = _a.onImageUpload, _e = _a.isLoadingUsed, isLoadingUsed = _e === void 0 ? true : _e;
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 _f = (0, react_1.useState)(0), count = _f[0], setCount = _f[1];
61
- var _g = (0, react_1.useState)(true), isEditorLoading = _g[0], setIsEditorLoading = _g[1];
62
- var _h = (0, react_1.useState)(false), isFileValidationAlertDialogOpen = _h[0], setIsFilValidationAlertDialogOpen = _h[1];
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);
71
72
  }
73
+ if (defaultText && defaultText.length !== 0 && editorRef.current) {
74
+ handleEditorValueChange(defaultText, editorRef.current);
75
+ }
72
76
  }, [defaultText]);
73
77
  var handleInit = function (evt, editor) {
74
78
  if (isLoadingUsed) {
@@ -94,14 +98,34 @@ function RichTextEditor(_a) {
94
98
  }
95
99
  };
96
100
  var handleEditorValueChange = function (value, editor) {
101
+ // NOTE: 기본 요소를 제외한 추가된 HTML 요소의 개수
102
+ var addedElementsCount = Array.from(editor.contentDocument.all).filter(function (element) { return !['BR', 'P'].includes(element.tagName); }).length - DEFAULT_ELEMENT_COUNT;
97
103
  var wordCount = editor.plugins.wordcount;
104
+ var charCount = 0;
98
105
  if (wordCount) {
99
- var charCount = wordCount.body.getCharacterCount();
106
+ charCount = wordCount.body.getCharacterCount();
100
107
  onCountCharacter === null || onCountCharacter === void 0 ? void 0 : onCountCharacter(charCount);
101
108
  setCount(charCount);
102
109
  }
103
- isEditorDirty.current = true;
104
- onChange === null || onChange === void 0 ? void 0 : onChange(value);
110
+ var isValid = function () {
111
+ // NOTE: 추가된 HTML 요소가 존재해도, maxLength를 초과할 경우.
112
+ if (maxLength && charCount > maxLength) {
113
+ return false;
114
+ }
115
+ // NOTE: 기본 요소를 제외한 추가된 HTML 요소가 존재하는 경우 유효성 검사를 통과합니다.
116
+ if (addedElementsCount > 0) {
117
+ return true;
118
+ }
119
+ if (required && charCount === 0) {
120
+ return false;
121
+ }
122
+ if (minLength && charCount < minLength) {
123
+ return false;
124
+ }
125
+ return true;
126
+ };
127
+ setIsEditorDirty(value ? true : false);
128
+ onChange === null || onChange === void 0 ? void 0 : onChange(value, isValid());
105
129
  };
106
130
  var handleEditorBlur = function () {
107
131
  var _a, _b;
@@ -179,15 +203,21 @@ function RichTextEditor(_a) {
179
203
  }
180
204
  });
181
205
  }); };
182
- if (required && isEditorDirty.current && (!editorContent || editorContent.length === 0)) {
183
- validationText = (0, jsx_runtime_1.jsx)(S_Error, { children: requiredValidationText });
184
- }
185
- if (minLength && count > 0 && count < minLength) {
186
- validationText = (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
187
- }
188
- if (maxLength && count > 0 && count > maxLength) {
189
- validationText = (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
190
- }
206
+ var validationText = (0, react_1.useMemo)(function () {
207
+ if (required &&
208
+ !isEditorDirty &&
209
+ (!editorContent || editorContent.length === 0) &&
210
+ elementsCount <= 0) {
211
+ return (0, jsx_runtime_1.jsx)(S_Error, { children: requiredValidationText });
212
+ }
213
+ if (elementsCount <= 0 && minLength && count > 0 && count < minLength) {
214
+ return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
215
+ }
216
+ if (maxLength && count > 0 && count > maxLength) {
217
+ return (0, jsx_runtime_1.jsx)(S_Error, { children: lengthValidationText });
218
+ }
219
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
220
+ }, [required, isEditorDirty, editorContent, elementsCount, count, minLength, maxLength]);
191
221
  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
222
  images_max_width: '100%',
193
223
  menubar: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pds-dev-kit-web",
3
- "version": "2.2.225",
3
+ "version": "2.2.227",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
package/release-note.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # PDS-DEV-KIT-WEB Release Notes
2
- ## [v2.2.225]
2
+ ## [v2.2.227]
3
3
  ## daily|https://design.storybook.publ.biz/
4
4
 
5
5
  ### 업데이트 사항
6
- * [PDS-1355] AdminListItem데이터 누락시 기본 폴백 텍스트 처리
6
+ * [PDS-1356] RichTextEditordefaultText가 있을 때, 초기 진입 시 validation을 통과하지 못하는 현상 수정