pds-dev-kit-web 2.2.313 → 2.2.315

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 (30) hide show
  1. package/.claude/settings.local.json +18 -0
  2. package/.idea/codeStyles/Project.xml +59 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/pds-dev-kit.iml +12 -0
  7. package/.idea/prettier.xml +7 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/.reference/OldEmailRichTextEditor/CustomTinyMCEEditor.tsx +209 -0
  10. package/.reference/OldEmailRichTextEditor/personalization_tag_plugin.ts +43 -0
  11. package/.reference/OldEmailRichTextEditor/tinymce-toolbar.css +13 -0
  12. package/.reference/email_editor_refactoring_prd.md +57 -0
  13. package/dist/index.d.ts +4 -4
  14. package/dist/index.js +6 -3
  15. package/dist/src/common/decorators/withFormProvider.js +8 -5
  16. package/dist/src/desktop/components/RichTextEditor/EmailRichTextEditor.d.ts +13 -0
  17. package/dist/src/desktop/components/RichTextEditor/EmailRichTextEditor.js +127 -0
  18. package/dist/src/desktop/components/RichTextEditor/index.d.ts +3 -0
  19. package/dist/src/desktop/components/RichTextEditor/index.js +3 -1
  20. package/dist/src/desktop/components/RichTextEditor/plugins/personalization_tag_plugin.d.ts +9 -0
  21. package/dist/src/desktop/components/RichTextEditor/plugins/personalization_tag_plugin.js +26 -0
  22. package/dist/src/desktop/components/index.d.ts +2 -2
  23. package/dist/src/desktop/components/index.js +3 -2
  24. package/dist/src/desktop/index.d.ts +1 -1
  25. package/dist/src/desktop/index.js +3 -2
  26. package/package.json +1 -1
  27. package/pds-dev-kit-web-2.2.314.tgz +0 -0
  28. package/release-note.md +2 -2
  29. package/_wildcard.machine.publr.co+2-key.pem +0 -28
  30. package/_wildcard.machine.publr.co+2.pem +0 -26
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git mv:*)",
5
+ "Bash(mkdir -p reference/OldEmailRichTextEditor)",
6
+ "Bash(mv src/desktop/components/RichTextEditor/OldEmailRichTextEditor/* reference/OldEmailRichTextEditor/)",
7
+ "Bash(mv src/desktop/components/RichTextEditor/email_editor_refactoring_prd.md reference/)",
8
+ "Bash(rmdir src/desktop/components/RichTextEditor/OldEmailRichTextEditor)",
9
+ "Bash(git restore:*)",
10
+ "Bash(git add:*)",
11
+ "Bash(npm run:*)",
12
+ "Bash(source ~/.zshrc)",
13
+ "Bash(npx tsc:*)",
14
+ "Bash(./node_modules/.bin/tsc --noEmit --pretty)",
15
+ "Bash(git commit:*)"
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,59 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <code_scheme name="Project" version="173">
3
+ <HTMLCodeStyleSettings>
4
+ <option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
5
+ </HTMLCodeStyleSettings>
6
+ <JSCodeStyleSettings version="0">
7
+ <option name="FORCE_SEMICOLON_STYLE" value="true" />
8
+ <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
9
+ <option name="USE_DOUBLE_QUOTES" value="false" />
10
+ <option name="FORCE_QUOTE_STYlE" value="true" />
11
+ <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
12
+ <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
13
+ <option name="SPACES_WITHIN_IMPORTS" value="true" />
14
+ </JSCodeStyleSettings>
15
+ <TypeScriptCodeStyleSettings version="0">
16
+ <option name="FORCE_SEMICOLON_STYLE" value="true" />
17
+ <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
18
+ <option name="USE_DOUBLE_QUOTES" value="false" />
19
+ <option name="FORCE_QUOTE_STYlE" value="true" />
20
+ <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
21
+ <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
22
+ <option name="SPACES_WITHIN_IMPORTS" value="true" />
23
+ </TypeScriptCodeStyleSettings>
24
+ <VueCodeStyleSettings>
25
+ <option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
26
+ <option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
27
+ </VueCodeStyleSettings>
28
+ <codeStyleSettings language="HTML">
29
+ <option name="SOFT_MARGINS" value="100" />
30
+ <indentOptions>
31
+ <option name="INDENT_SIZE" value="2" />
32
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
33
+ <option name="TAB_SIZE" value="2" />
34
+ </indentOptions>
35
+ </codeStyleSettings>
36
+ <codeStyleSettings language="JavaScript">
37
+ <option name="SOFT_MARGINS" value="100" />
38
+ <indentOptions>
39
+ <option name="INDENT_SIZE" value="2" />
40
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
41
+ <option name="TAB_SIZE" value="2" />
42
+ </indentOptions>
43
+ </codeStyleSettings>
44
+ <codeStyleSettings language="TypeScript">
45
+ <option name="SOFT_MARGINS" value="100" />
46
+ <indentOptions>
47
+ <option name="INDENT_SIZE" value="2" />
48
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
49
+ <option name="TAB_SIZE" value="2" />
50
+ </indentOptions>
51
+ </codeStyleSettings>
52
+ <codeStyleSettings language="Vue">
53
+ <option name="SOFT_MARGINS" value="100" />
54
+ <indentOptions>
55
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
56
+ </indentOptions>
57
+ </codeStyleSettings>
58
+ </code_scheme>
59
+ </component>
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="USE_PER_PROJECT_SETTINGS" value="true" />
4
+ </state>
5
+ </component>
@@ -0,0 +1,7 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
+ <inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" />
6
+ </profile>
7
+ </component>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/pds-dev-kit.iml" filepath="$PROJECT_DIR$/.idea/pds-dev-kit.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
+ <excludeFolder url="file://$MODULE_DIR$/temp" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+ </content>
9
+ <orderEntry type="inheritedJdk" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ </component>
12
+ </module>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="PrettierConfiguration">
4
+ <option name="myConfigurationMode" value="AUTOMATIC" />
5
+ <option name="myRunOnSave" value="true" />
6
+ </component>
7
+ </project>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,209 @@
1
+ import { Editor } from '@tinymce/tinymce-react';
2
+ import { useRef, useEffect, useMemo } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import tinymce from 'tinymce';
5
+ import 'tinymce/icons/default';
6
+ import 'tinymce/models/dom';
7
+ import 'tinymce/plugins/advlist';
8
+ import 'tinymce/plugins/anchor';
9
+ import 'tinymce/plugins/autolink';
10
+ import 'tinymce/plugins/charmap';
11
+ import 'tinymce/plugins/code';
12
+ import 'tinymce/plugins/fullscreen';
13
+ import 'tinymce/plugins/image';
14
+ import 'tinymce/plugins/insertdatetime';
15
+ import 'tinymce/plugins/link';
16
+ import 'tinymce/plugins/lists';
17
+ import 'tinymce/plugins/media';
18
+ import 'tinymce/plugins/preview';
19
+ import 'tinymce/plugins/searchreplace';
20
+ import 'tinymce/plugins/table';
21
+ import 'tinymce/plugins/visualblocks';
22
+ import 'tinymce/skins/content/default/content.min.css';
23
+ import 'tinymce/skins/ui/oxide/content.min.css';
24
+ import 'tinymce/skins/ui/oxide/skin.min.css';
25
+ import 'tinymce/themes/silver';
26
+
27
+ import { showDesktopAlertDialog } from '@core/overlay';
28
+
29
+ import {
30
+ PersonalizationTagCallback,
31
+ setPersonalizationModalCallback,
32
+ registerCustomTokensPlugin
33
+ } from './personalization_tag_plugin';
34
+ import './tinymce-toolbar.css';
35
+
36
+ import type { Editor as TinyMCEEditor } from 'tinymce';
37
+
38
+ type ImageUploadHandler = (file: File) => Promise<string>;
39
+
40
+ type EditorProps = {
41
+ initialContent?: string;
42
+ onChange?: (content: string) => void;
43
+ onOpenPersonalizationModal?: PersonalizationTagCallback;
44
+ onImageUpload?: ImageUploadHandler;
45
+ };
46
+
47
+ // Register the custom plugin before any Editor component mounts
48
+ registerCustomTokensPlugin(tinymce);
49
+
50
+ export default function CustomTinyMCEEditor({
51
+ initialContent,
52
+ onChange,
53
+ onOpenPersonalizationModal,
54
+ onImageUpload
55
+ }: EditorProps) {
56
+ const { t } = useTranslation('translation');
57
+ const editorRef = useRef<TinyMCEEditor | null>(null);
58
+ const uploadedBlobsRef = useRef<Map<string, string>>(new Map());
59
+ const isEditorReady = useRef(false);
60
+
61
+ // Store initial content in ref so it doesn't change on re-renders
62
+ const initialContentRef = useRef(initialContent);
63
+
64
+ // Use refs to keep callbacks stable
65
+ const onChangeRef = useRef(onChange);
66
+ const onImageUploadRef = useRef(onImageUpload);
67
+ const tRef = useRef(t);
68
+
69
+ // Update refs when props change
70
+ useEffect(() => {
71
+ onChangeRef.current = onChange;
72
+ }, [onChange]);
73
+
74
+ useEffect(() => {
75
+ onImageUploadRef.current = onImageUpload;
76
+ }, [onImageUpload]);
77
+
78
+ useEffect(() => {
79
+ tRef.current = t;
80
+ }, [t]);
81
+
82
+ useEffect(() => {
83
+ setPersonalizationModalCallback(onOpenPersonalizationModal || null);
84
+ return () => {
85
+ setPersonalizationModalCallback(null);
86
+ };
87
+ }, [onOpenPersonalizationModal]);
88
+
89
+ const handleInit = (_evt: unknown, editor: TinyMCEEditor) => {
90
+ editorRef.current = editor;
91
+ isEditorReady.current = true;
92
+ };
93
+
94
+ // Use the official onEditorChange callback from @tinymce/tinymce-react
95
+ const handleEditorChange = (content: string) => {
96
+ onChangeRef.current?.(content);
97
+ };
98
+
99
+ // Memoize init object to prevent re-initialization
100
+ const editorInit = useMemo(
101
+ () => ({
102
+ height: 500,
103
+ menubar: false,
104
+ statusbar: true,
105
+ elementpath: false,
106
+ branding: false,
107
+ toolbar_mode: 'wrap' as const,
108
+ plugins:
109
+ 'advlist anchor autolink charmap code fullscreen image insertdatetime link lists media preview searchreplace table visualblocks customtokens',
110
+ toolbar:
111
+ 'blocks bold italic underline strikethrough | forecolor backcolor alignleft aligncenter alignright alignjustify outdent indent | numlist bullist blockquote insertTag link image media undo redo',
112
+ skin: false,
113
+ content_css: false,
114
+ content_style: `
115
+ body { font-family:Helvetica,Arial,sans-serif; font-size:16px; line-height: 1.5; overflow-wrap: break-word; word-break: break-word; word-wrap: break-word; }
116
+ p { margin: 0; }
117
+ a { color: #0066cc; text-decoration: underline; }
118
+ img { max-width: 100%; height: auto; display: block; margin: 16px 0; border: none; object-fit: contain; }
119
+ video, iframe { width: 100%; margin: 16px 0; padding: 0; border: none; display: block; max-width: 100%; }
120
+ span[data-mce-object="video"], span[data-mce-object="iframe"] { display: block; width: 100%; margin: 16px 0; border: none; }
121
+ span[data-mce-object]::before { content: ''; display: block; }
122
+ span[data-mce-object]::after { content: ''; display: block; }
123
+ .mce-object-video, .mce-object-iframe, .mce-preview-object { margin: 0; padding: 0; border: none; }
124
+ .mce-preview-object > iframe { border: none; }
125
+ table { width: 100%; margin: 16px 0; border: none; border-collapse: collapse; }
126
+ .alert-warning { border-left: 5px solid #ffdd00; padding: 10px; background: #fff8e1; margin: 10px 0; border-radius: 4px; }
127
+ `,
128
+ automatic_uploads: true,
129
+ images_reuse_filename: true,
130
+ paste_data_images: true,
131
+ media_live_embeds: true,
132
+ images_upload_handler: (blobInfo: {
133
+ blobUri: () => string;
134
+ blob: () => Blob;
135
+ filename: () => string;
136
+ }): Promise<string> => {
137
+ return new Promise((resolve, reject) => {
138
+ const blobUri = blobInfo.blobUri();
139
+
140
+ const existingUrl = uploadedBlobsRef.current.get(blobUri);
141
+ if (existingUrl) {
142
+ resolve(existingUrl);
143
+ return;
144
+ }
145
+
146
+ if (!onImageUploadRef.current) {
147
+ reject(new Error('No upload handler'));
148
+ return;
149
+ }
150
+
151
+ const file = new File([blobInfo.blob()], blobInfo.filename(), {
152
+ type: blobInfo.blob().type
153
+ });
154
+
155
+ onImageUploadRef
156
+ .current(file)
157
+ .then((url) => {
158
+ uploadedBlobsRef.current.set(blobUri, url);
159
+ resolve(url);
160
+ })
161
+ .catch((error) => {
162
+ showDesktopAlertDialog({
163
+ contentText: tRef.current('str_papp_image_upload_failed'),
164
+ btnMode: 'tbtn_amount1',
165
+ tBtn1Text: tRef.current('str_confirm')
166
+ });
167
+ reject(error);
168
+ });
169
+ });
170
+ },
171
+ // Additional event handlers for formatting changes that onEditorChange might miss
172
+ setup: (editor: TinyMCEEditor) => {
173
+ // Handle formatting commands - use setTimeout to ensure DOM is updated
174
+ editor.on('ExecCommand', (e) => {
175
+ // Only trigger for formatting-related commands
176
+ const formattingCommands = [
177
+ 'mceToggleFormat',
178
+ 'Bold',
179
+ 'Italic',
180
+ 'Underline',
181
+ 'Strikethrough',
182
+ 'ForeColor',
183
+ 'BackColor',
184
+ 'FontSize',
185
+ 'FormatBlock'
186
+ ];
187
+ if (formattingCommands.some((cmd) => e.command.includes(cmd))) {
188
+ setTimeout(() => {
189
+ const content = editor.getContent();
190
+ onChangeRef.current?.(content);
191
+ }, 10);
192
+ }
193
+ });
194
+ }
195
+ }),
196
+ []
197
+ );
198
+
199
+ return (
200
+ <div>
201
+ <Editor
202
+ onInit={handleInit}
203
+ initialValue={initialContentRef.current}
204
+ onEditorChange={handleEditorChange}
205
+ init={editorInit}
206
+ />
207
+ </div>
208
+ );
209
+ }
@@ -0,0 +1,43 @@
1
+ import { TinyMCE, Editor } from 'tinymce';
2
+
3
+ export type PersonalizationTagCallback = (insertTag: (tag: string) => void) => void;
4
+
5
+ let onOpenPersonalizationModalCallback: PersonalizationTagCallback | null = null;
6
+
7
+ export function setPersonalizationModalCallback(callback: PersonalizationTagCallback | null) {
8
+ onOpenPersonalizationModalCallback = callback;
9
+ }
10
+
11
+ /**
12
+ * Registers the custom tokens plugin with the provided TinyMCE instance.
13
+ * Must be called before the Editor component initializes.
14
+ */
15
+ export function registerCustomTokensPlugin(tinymceInstance: TinyMCE): void {
16
+ // Prevent duplicate registration
17
+ if (tinymceInstance.PluginManager.get('customtokens')) {
18
+ return;
19
+ }
20
+
21
+ tinymceInstance.PluginManager.add('customtokens', (editor: Editor) => {
22
+ editor.ui.registry.addIcon(
23
+ 'merge-field',
24
+ '<svg width="24" height="24" viewBox="0 0 24 24"><text x="4" y="17" font-size="14" font-weight="900" stroke="currentColor" stroke-width="0.5">{ }</text></svg>'
25
+ );
26
+
27
+ editor.ui.registry.addButton('insertTag', {
28
+ tooltip: 'Insert Personalization Tag',
29
+ icon: 'merge-field',
30
+ onAction: () => {
31
+ const insertTag = (tag: string) => {
32
+ // Insert as plain text so it can be formatted like regular text
33
+ editor.insertContent(tag);
34
+ };
35
+
36
+ if (onOpenPersonalizationModalCallback) {
37
+ onOpenPersonalizationModalCallback(insertTag);
38
+ }
39
+ }
40
+ });
41
+ return { getMetadata: () => ({ name: 'Personalization Tag Plugin', url: '' }) };
42
+ });
43
+ }
@@ -0,0 +1,13 @@
1
+ /* TinyMCE toolbar button size reduction */
2
+ .tox .tox-tbtn {
3
+ width: 25px;
4
+ min-width: 25px;
5
+ }
6
+
7
+ .tox .tox-tbtn--select {
8
+ width: auto !important;
9
+ }
10
+
11
+ .tox.tox-tinymce {
12
+ z-index: 0 !important;
13
+ }
@@ -0,0 +1,57 @@
1
+ # [Refactoring] PDS RichTextEditor 기반 범용 이메일 에디터 구축 및 피처 종속 로직 분리
2
+
3
+ ## 1. 진행 배경 및 목적 (Background & Objective)
4
+ * **배경**: 현재 제품(Product) 프로젝트에는 특정 이메일 발송 피처를 위해 자체적으로 구현한 `CustomTinyMCEEditor`(`.reference/OldEmailRichTextEditor/CustomTinyMCEEditor.tsx`)가 존재합니다. 이번 통합 리팩토링을 위해 해당 컴포넌트를 임시로 PDS(`pds-dev-kit`) 프로젝트로 가져온 상태입니다.
5
+ * **문제점**: `CustomTinyMCEEditor`는 범용적인 이메일 에디터가 아니라 **특정 피처의 비즈니스 로직(예: 특정 모달 호출, 고유 이미지 처리 등)에 강하게 결합**되어 만들어졌습니다. 이를 그대로 PDS 라이브러리의 공통 컴포넌트로 편입시킬 경우 도메인 의존성이 생기는 문제가 발생합니다.
6
+ * **목적**:
7
+ 1. `CustomTinyMCEEditor`에 혼재된 **'범용 이메일 에디터로서의 내부 로직'**과 **'특정 피처를 위한 외부 로직'**을 완벽하게 분리(Decoupling)합니다.
8
+ 2. PDS의 표준인 `RichTextEditor`를 유연하게 확장하여, 범용으로 사용할 수 있는 래퍼 컴포넌트 `EmailRichTextEditor`를 PDS 내부에 구축합니다.
9
+ 3. 제품(Consumer) 측에서는 이 `EmailRichTextEditor`를 가져다 쓰되, 도메인 특화 파트(모달, 업로드 등)는 Props와 콜백을 통해 주입(Injection)하도록 제어의 역전(IoC) 구조를 만듭니다.
10
+
11
+ ## 2. 핵심 구현 전략 (Core Strategy)
12
+ * **관심사의 분리 (Separation of Concerns)**
13
+ * **PDS (EmailRichTextEditor)의 책임**: 이메일용 컴팩트 툴바 UI, 이메일에 적합한 Content Style(인라인 CSS 호환), 이메일 작성에 필요한 공통 플러그인 렌더링.
14
+ * **제품 프로젝트(Consumer)의 책임**: 이미지 업로드 API 통신, 특정 피처용 개인화 태그(치환 태그) 삽입 모달의 렌더링 및 제어 로직 구현 후 주입.
15
+ * **확장성 확보 (initOptions 도입)**: `RichTextEditor`가 모든 에디터 옵션을 Prop으로 들고 있지 않게 하고, TinyMCE의 `init` 설정을 소비자가 통째로 병합할 수 있도록 `initOptions` Prop을 신설합니다.
16
+
17
+ ---
18
+
19
+ ## 3. 상세 요구사항 (Detailed Requirements)
20
+
21
+ ### Task 1. `RichTextEditor` 확장 및 하위 호환성 보장 (`src/desktop/components/RichTextEditor/RichTextEditor.tsx`)
22
+ PDS 전체에서 사용되는 표준 에디터이므로 레거시 화면이 깨지지 않는 것이 가장 중요합니다.
23
+ * **Prop 확장**
24
+ * `initOptions?: Parameters<TinyMCE['init']>[0];`: TinyMCE 고유 설정을 주입받습니다. 컴포넌트 내부의 기본 `init` 설정과 병합하되, `initOptions`의 값이 우선순위를 가지도록 구현하세요 (`...initOptions`).
25
+ * `onSetup?: (editor: TinyMCEEditor) => void;`: 에디터 초기화(Setup) 시점에 외부에서 이벤트를 바인딩할 수 있도록 콜백을 엽니다.
26
+ * `isCompactToolbar?: boolean;`: `true` 시 이메일 에디터 특유의 좁은 간격/작은 버튼 스타일이 적용되도록 CSS를 조건부 처리하세요.
27
+ * **기본 설정 정비**
28
+ * `automatic_uploads`, `images_reuse_filename`, `paste_data_images`, `media_live_embeds` 등을 기본 `init` 속성으로 명시하세요.
29
+
30
+ ### Task 2. `EmailRichTextEditor` 범용 래퍼 구축 (`src/desktop/components/RichTextEditor/EmailRichTextEditor.tsx`)
31
+ PDS 라이브러리로서 제공될 순수 **'이메일 전용 텍스트 에디터'**입니다. 특정 비즈니스 로직은 철저히 배제하세요.
32
+ * `RichTextEditor`를 반환하는 Wrapper 형태로 구현합니다.
33
+ * **기본 이메일 설정 주입 (`initOptions`)**
34
+ * 범용 이메일 에디터에 필요한 상수들 (`EMAIL_PLUGINS`, `EMAIL_TOOLBAR`, `EMAIL_CONTENT_STYLE`)을 선언하고 `initOptions`를 통해 `RichTextEditor`에 주입합니다.
35
+ * 이미지 업로드 캐싱 로직(드래그 앤 드롭 시 기존 업로드 Blob 재사용)은 에디터의 범용 UI/UX 편의 기능이므로, 래퍼 컴포넌트 내 `images_upload_handler`에 공통으로 구현합니다. (실제 업로드 통신 함수인 `onImageUpload`는 Props로 받아 실행)
36
+ * **커스텀 이벤트 브릿지 (`onSetup`)**
37
+ * 포맷팅 변경 시점(`Bold`, `Italic` 등 `ExecCommand` 발생)에 강제로 `onChange`를 지연 트리거 시키는 동기화 로직을 주입합니다.
38
+ * 에디터 기본 높이(`height`)는 기존 UI와 동일하게 `500`으로 고정합니다.
39
+
40
+ ### Task 3. 외부 도메인 로직 분리 설계 (`personalization_tag_plugin.ts` 리팩토링)
41
+ 제품의 특정 피처에서만 쓰이던 '개인화 태그(치환 태그)' 플러그인을 범용 에디터에 올바르게 결합하기 위한 작업입니다.
42
+ * **글로벌 등록 폐기**: `tinymce.PluginManager`에 의존하던 전역 등록 방식을 버리고, 특정 에디터 인스턴스에만 적용되도록 변경합니다.
43
+ * **Setup 콜백 생성 함수로 변경**
44
+ * `getPersonalizationSetup(onOpenPersonalizationModal?: Callback)` 형태의 팩토리 함수로 리팩토링하세요.
45
+ * 이 함수는 `EmailRichTextEditor`가 렌더링 될 때, 외부(제품 프로젝트)로부터 `onOpenPersonalizationModal` 콜백을 주입받아 모달 트리거 로직을 완성한 뒤, TinyMCE의 `setup` 시점에 실행할 함수를 반환해야 합니다.
46
+
47
+ ---
48
+
49
+ ## 4. 완료 조건 및 검증 (Acceptance Criteria)
50
+
51
+ 1. **관심사 분리 확인**: PDS 내의 `EmailRichTextEditor` 코드를 리뷰했을 때, 특정 제품의 모달 이름, API 엔드포인트 등의 비즈니스 종속 코드가 단 한 줄도 없어야 합니다. 오직 PDS의 컴포넌트로서 Props Interface만 제공해야 합니다.
52
+ 2. **하위 호환성 (Regression Free)**: 기존 `RichTextEditor`를 사용하는 일반 화면에서 런타임 에러, TypeScript 인터페이스 에러, 스타일 깨짐이 없어야 합니다.
53
+ 3. **기능 검증**: 제품 프로젝트에서 `EmailRichTextEditor`를 마운트했을 때,
54
+ * 기존과 동일한 컴팩트 툴바 UI가 노출될 것
55
+ * `{ }` (개인화 태그) 아이콘 클릭 시, 앱에서 주입한 전용 모달이 정상적으로 호출될 것
56
+ * 이미지 업로드, 텍스트 포맷팅 등이 기존 `CustomTinyMCEEditor` 환경과 100% 동일하게 동작할 것
57
+ 4. **마무리**: 통합 검증 통과 시 `.reference/OldEmailRichTextEditor` 참고용 폴더를 안전하게 삭제합니다.
package/dist/index.d.ts CHANGED
@@ -8,20 +8,20 @@ export { AdminListItemTransition, InputTransition, ButtonTransition } from './sr
8
8
  export { Form };
9
9
  import { Divider, Icon, ImageView, LinearProgress, LottieIcon, Spacing, Switch } from './src/hybrid';
10
10
  export { Divider, Icon, ImageView, LinearProgress, LottieIcon, Spacing, Switch };
11
- import { LayoutWF, WFContainersBox, LayoutWH, WHContainersBox, LayoutWS, WSGlobalMenuContainer, WSContainersBox, LayoutWT, WTGlobalMenuContainer, WTContainersBox, D_AdminList, D_AdminListHeader, D_AdminListItem, D_BasicButtonGroup, D_BasicChatListItem, D_BasicFormGroup, D_BasicList, D_BasicListItem, D_BlogTextField, D_BodyTextGroup, D_BoxItem, D_Card, D_CardList, D_ChatBubbleListItem, D_ChatList, D_Checkbox, D_Chip, D_ContextMenu, D_ContextMenuItem, D_DesktopAlertDialog, D_DesktopHeaderBar, D_DesktopTabBar, D_Dropdown, D_DynamicDesktopNavBar, D_DynamicDesktopNavBarTemplates, D_EditApplyTextField, D_FilterBar, D_FloatingActionButton, D_Hero, D_HorizontalFormGroup, D_IconButton, D_ImageSlide, D_LottieReactionButton, D_MainButton, D_PageTitleTextGroup, D_Radio, D_ReactionButton, D_SegmentedButtonGroup, D_Select, D_Slider, D_Snackbar, D_StatusBlock, D_TextButton, D_PriceTextField, D_TextField, D_TextLabel, D_PriceTextLabel, D_UploadIconButton, D_UploadMainButton, D_UploadTextButton, D_UserDesktopNavBar, D_UserDesktopTabBar, D_UserDesktopSideTab, D_AnnotationSheet, D_ContentSheet, D_DesktopBasicModal, D_DesktopBasicModalWithTab, DesktopBasicModalWithTabInfoType, D_DesktopHeadlessModal, D_DesktopTutorialModal, DesktopTutorialModalInfoType, D_SectionSheet, D_Calendar, D_RichTextEditor, D_LocalizedContentModal, LocalizedButton } from './src/desktop';
11
+ import { LayoutWF, WFContainersBox, LayoutWH, WHContainersBox, LayoutWS, WSGlobalMenuContainer, WSContainersBox, LayoutWT, WTGlobalMenuContainer, WTContainersBox, D_AdminList, D_AdminListHeader, D_AdminListItem, D_BasicButtonGroup, D_BasicChatListItem, D_BasicFormGroup, D_BasicList, D_BasicListItem, D_BlogTextField, D_BodyTextGroup, D_BoxItem, D_Card, D_CardList, D_ChatBubbleListItem, D_ChatList, D_Checkbox, D_Chip, D_ComboBox, D_ContextMenu, D_ContextMenuItem, D_DesktopAlertDialog, D_DesktopHeaderBar, D_DesktopTabBar, D_Dropdown, D_DynamicDesktopNavBar, D_DynamicDesktopNavBarTemplates, D_EditApplyTextField, D_FilterBar, D_FloatingActionButton, D_Hero, D_HorizontalFormGroup, D_IconButton, D_ImageSlide, D_LottieReactionButton, D_MainButton, D_PageTitleTextGroup, D_Radio, D_ReactionButton, D_SegmentedButtonGroup, D_Select, D_Slider, D_Snackbar, D_StatusBlock, D_TextButton, D_PriceTextField, D_TextField, D_TextLabel, D_PriceTextLabel, D_UploadIconButton, D_UploadMainButton, D_UploadTextButton, D_UserDesktopNavBar, D_UserDesktopTabBar, D_UserDesktopSideTab, D_AnnotationSheet, D_ContentSheet, D_DesktopBasicModal, D_DesktopBasicModalWithTab, DesktopBasicModalWithTabInfoType, D_DesktopHeadlessModal, D_DesktopTutorialModal, DesktopTutorialModalInfoType, D_SectionSheet, D_Calendar, D_RichTextEditor, D_EmailRichTextEditor, D_LocalizedContentModal, LocalizedButton } from './src/desktop';
12
12
  export { LayoutWF, WFContainersBox };
13
13
  export { LayoutWH, WHContainersBox };
14
14
  export { LayoutWS, WSGlobalMenuContainer, WSContainersBox };
15
15
  export { LayoutWT, WTGlobalMenuContainer, WTContainersBox };
16
- export { D_AdminList, D_AdminListHeader, D_AdminListItem, D_BasicButtonGroup, D_BasicChatListItem, D_BasicFormGroup, D_BasicList, D_BasicListItem, D_BlogTextField, D_BodyTextGroup, D_BoxItem, D_Card, D_CardList, D_ChatBubbleListItem, D_ChatList, D_Checkbox, D_Chip, D_ContextMenu, D_ContextMenuItem, D_DesktopAlertDialog, D_DesktopHeaderBar, D_DesktopTabBar, D_Dropdown, D_DynamicDesktopNavBar, D_DynamicDesktopNavBarTemplates, D_EditApplyTextField, D_FilterBar, D_FloatingActionButton, D_Hero, D_HorizontalFormGroup, D_IconButton, D_ImageSlide, D_LottieReactionButton, D_MainButton, D_PageTitleTextGroup, D_Radio, D_ReactionButton, D_SegmentedButtonGroup, D_Select, D_Slider, D_Snackbar, D_StatusBlock, D_TextButton, D_PriceTextField, D_TextField, D_TextLabel, D_PriceTextLabel, D_UploadIconButton, D_UploadMainButton, D_UploadTextButton, D_UserDesktopNavBar, D_UserDesktopTabBar, D_UserDesktopSideTab, D_Calendar, D_RichTextEditor, LocalizedButton };
16
+ export { D_AdminList, D_AdminListHeader, D_AdminListItem, D_BasicButtonGroup, D_BasicChatListItem, D_BasicFormGroup, D_BasicList, D_BasicListItem, D_BlogTextField, D_BodyTextGroup, D_BoxItem, D_Card, D_CardList, D_ChatBubbleListItem, D_ChatList, D_Checkbox, D_Chip, D_ComboBox, D_ContextMenu, D_ContextMenuItem, D_DesktopAlertDialog, D_DesktopHeaderBar, D_DesktopTabBar, D_Dropdown, D_DynamicDesktopNavBar, D_DynamicDesktopNavBarTemplates, D_EditApplyTextField, D_FilterBar, D_FloatingActionButton, D_Hero, D_HorizontalFormGroup, D_IconButton, D_ImageSlide, D_LottieReactionButton, D_MainButton, D_PageTitleTextGroup, D_Radio, D_ReactionButton, D_SegmentedButtonGroup, D_Select, D_Slider, D_Snackbar, D_StatusBlock, D_TextButton, D_PriceTextField, D_TextField, D_TextLabel, D_PriceTextLabel, D_UploadIconButton, D_UploadMainButton, D_UploadTextButton, D_UserDesktopNavBar, D_UserDesktopTabBar, D_UserDesktopSideTab, D_Calendar, D_RichTextEditor, D_EmailRichTextEditor, LocalizedButton };
17
17
  export { D_AnnotationSheet, D_ContentSheet, D_DesktopBasicModal, D_DesktopBasicModalWithTab, D_DesktopHeadlessModal, D_DesktopTutorialModal, D_LocalizedContentModal, D_SectionSheet };
18
18
  export type { DesktopBasicModalWithTabInfoType, DesktopTutorialModalInfoType };
19
- import { LayoutMF, MFContainersBox, LayoutMM, MMNavigationContainer, MMContainersBox, LayoutMP, MPNavigationContainer, MPTabContainer, MPContainersBox, LayoutMS, MSNavigationContainer, MSContainersBox, M_BasicButtonGroup, M_BasicChatListItem, M_BasicFormGroup, M_BasicList, M_BasicListItem, M_BlogTextField, M_BodyTextGroup, M_BoxItem, M_Card, M_CardList, M_ChatBubbleListItem, M_ChatList, M_Checkbox, M_Chip, M_ContextMenu, M_ContextMenuItem, M_DatePicker, M_Dropdown, M_FloatingActionButton, M_HorizontalFormGroup, M_IconButton, M_ImageSlide, M_LottieReactionButton, M_MainButton, M_MobileAlertDialog, M_MobileHeaderBar, M_MobileTabBar, M_Radio, M_ReactionButton, M_SegmentedButtonGroup, M_Select, M_Slider, M_Snackbar, M_StatusBlock, M_TextButton, M_PriceTextField, M_TextField, M_TextLabel, M_PriceTextLabel, M_UploadIconButton, M_UploadMainButton, M_UploadTextButton, M_AnnotationSheet, M_ContentSheet, M_MobileBasicModal, M_SectionSheet, M_RichTextEditor } from './src/mobile';
19
+ import { LayoutMF, MFContainersBox, LayoutMM, MMNavigationContainer, MMContainersBox, LayoutMP, MPNavigationContainer, MPTabContainer, MPContainersBox, LayoutMS, MSNavigationContainer, MSContainersBox, M_BasicButtonGroup, M_BasicChatListItem, M_BasicFormGroup, M_BasicList, M_BasicListItem, M_BlogTextField, M_BodyTextGroup, M_BoxItem, M_Card, M_CardList, M_ChatBubbleListItem, M_ChatList, M_Checkbox, M_Chip, M_ComboBox, M_ContextMenu, M_ContextMenuItem, M_DatePicker, M_Dropdown, M_FloatingActionButton, M_HorizontalFormGroup, M_IconButton, M_ImageSlide, M_LottieReactionButton, M_MainButton, M_MobileAlertDialog, M_MobileHeaderBar, M_MobileTabBar, M_Radio, M_ReactionButton, M_SegmentedButtonGroup, M_Select, M_Slider, M_Snackbar, M_StatusBlock, M_TextButton, M_PriceTextField, M_TextField, M_TextLabel, M_PriceTextLabel, M_UploadIconButton, M_UploadMainButton, M_UploadTextButton, M_AnnotationSheet, M_ContentSheet, M_MobileBasicModal, M_SectionSheet, M_RichTextEditor } from './src/mobile';
20
20
  export { LayoutMF, MFContainersBox };
21
21
  export { LayoutMM, MMNavigationContainer, MMContainersBox };
22
22
  export { LayoutMP, MPNavigationContainer, MPTabContainer, MPContainersBox };
23
23
  export { LayoutMS, MSNavigationContainer, MSContainersBox };
24
- export { M_BasicButtonGroup, M_BasicChatListItem, M_BasicFormGroup, M_BasicList, M_BasicListItem, M_BlogTextField, M_BodyTextGroup, M_BoxItem, M_Card, M_CardList, M_ChatBubbleListItem, M_ChatList, M_Checkbox, M_Chip, M_ContextMenu, M_ContextMenuItem, M_DatePicker, M_Dropdown, M_FloatingActionButton, M_HorizontalFormGroup, M_IconButton, M_ImageSlide, M_LottieReactionButton, M_MainButton, M_MobileAlertDialog, M_MobileHeaderBar, M_MobileTabBar, M_Radio, M_ReactionButton, M_SegmentedButtonGroup, M_Select, M_Slider, M_Snackbar, M_StatusBlock, M_TextButton, M_PriceTextField, M_TextField, M_TextLabel, M_PriceTextLabel, M_UploadIconButton, M_UploadMainButton, M_UploadTextButton, M_RichTextEditor };
24
+ export { M_BasicButtonGroup, M_BasicChatListItem, M_BasicFormGroup, M_BasicList, M_BasicListItem, M_BlogTextField, M_BodyTextGroup, M_BoxItem, M_Card, M_CardList, M_ChatBubbleListItem, M_ChatList, M_Checkbox, M_Chip, M_ComboBox, M_ContextMenu, M_ContextMenuItem, M_DatePicker, M_Dropdown, M_FloatingActionButton, M_HorizontalFormGroup, M_IconButton, M_ImageSlide, M_LottieReactionButton, M_MainButton, M_MobileAlertDialog, M_MobileHeaderBar, M_MobileTabBar, M_Radio, M_ReactionButton, M_SegmentedButtonGroup, M_Select, M_Slider, M_Snackbar, M_StatusBlock, M_TextButton, M_PriceTextField, M_TextField, M_TextLabel, M_PriceTextLabel, M_UploadIconButton, M_UploadMainButton, M_UploadTextButton, M_RichTextEditor };
25
25
  export { M_AnnotationSheet, M_ContentSheet, M_MobileBasicModal, M_SectionSheet };
26
26
  import { DynamicLayout } from './src/sub';
27
27
  export { DynamicLayout };
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LayoutWF = exports.Switch = exports.Spacing = exports.LottieIcon = exports.LinearProgress = exports.ImageView = exports.Icon = exports.Divider = exports.Form = exports.ButtonTransition = exports.InputTransition = exports.AdminListItemTransition = exports.scaleBounceOutIncludeTranslate02 = exports.scaleBounceInIncludeTranslate02 = exports.scaleBounceOutIncludeTranslate = exports.scaleBounceInIncludeTranslate = exports.scaleBounceOut02 = exports.scaleBounceOut = exports.scaleBounceIn02 = exports.scaleBounceIn = exports.gelatine = exports.scaleDownIncludeTranslate = exports.scaleUpIncludeTranslate = exports.scaleDown = exports.scaleUp = exports.glow = exports.fadeOut = exports.fadeIn = exports.modalOverlayOffAni = exports.modalOverlayOnAni = exports.modalOffAni = exports.modalOnAni = exports.dialogOverlayOffAni = exports.dialogOverlayOnAni = exports.dialogOffAni = exports.dialogOnAni = exports.theme = exports.customTheme = exports.uiColors = exports.spacing = exports.boxShadow = exports.mobileEditorLineHeight = exports.mobileEditorFontSize = exports.mobileLineHeight = exports.mobileFontSize = exports.desktopEditorLineHeight = exports.desktopEditorFontSize = exports.desktopLineHeight = exports.desktopFontSize = exports.fontWeight = void 0;
4
- exports.D_Snackbar = exports.D_Slider = exports.D_Select = exports.D_SegmentedButtonGroup = exports.D_ReactionButton = exports.D_Radio = exports.D_PageTitleTextGroup = exports.D_MainButton = exports.D_LottieReactionButton = exports.D_ImageSlide = exports.D_IconButton = exports.D_HorizontalFormGroup = exports.D_Hero = exports.D_FloatingActionButton = exports.D_FilterBar = exports.D_EditApplyTextField = exports.D_DynamicDesktopNavBarTemplates = exports.D_DynamicDesktopNavBar = exports.D_Dropdown = exports.D_DesktopTabBar = exports.D_DesktopHeaderBar = exports.D_DesktopAlertDialog = exports.D_ContextMenuItem = exports.D_ContextMenu = exports.D_Chip = exports.D_Checkbox = exports.D_ChatList = exports.D_ChatBubbleListItem = exports.D_CardList = exports.D_Card = exports.D_BoxItem = exports.D_BodyTextGroup = exports.D_BlogTextField = exports.D_BasicListItem = exports.D_BasicList = exports.D_BasicFormGroup = exports.D_BasicChatListItem = exports.D_BasicButtonGroup = exports.D_AdminListItem = exports.D_AdminListHeader = exports.D_AdminList = exports.WTContainersBox = exports.WTGlobalMenuContainer = exports.LayoutWT = exports.WSContainersBox = exports.WSGlobalMenuContainer = exports.LayoutWS = exports.WHContainersBox = exports.LayoutWH = exports.WFContainersBox = void 0;
5
- exports.M_ContextMenu = exports.M_Chip = exports.M_Checkbox = exports.M_ChatList = exports.M_ChatBubbleListItem = exports.M_CardList = exports.M_Card = exports.M_BoxItem = exports.M_BodyTextGroup = exports.M_BlogTextField = exports.M_BasicListItem = exports.M_BasicList = exports.M_BasicFormGroup = exports.M_BasicChatListItem = exports.M_BasicButtonGroup = exports.MSContainersBox = exports.MSNavigationContainer = exports.LayoutMS = exports.MPContainersBox = exports.MPTabContainer = exports.MPNavigationContainer = exports.LayoutMP = exports.MMContainersBox = exports.MMNavigationContainer = exports.LayoutMM = exports.MFContainersBox = exports.LayoutMF = exports.D_SectionSheet = exports.D_LocalizedContentModal = exports.D_DesktopTutorialModal = exports.D_DesktopHeadlessModal = exports.D_DesktopBasicModalWithTab = exports.D_DesktopBasicModal = exports.D_ContentSheet = exports.D_AnnotationSheet = exports.LocalizedButton = exports.D_RichTextEditor = exports.D_Calendar = exports.D_UserDesktopSideTab = exports.D_UserDesktopTabBar = exports.D_UserDesktopNavBar = exports.D_UploadTextButton = exports.D_UploadMainButton = exports.D_UploadIconButton = exports.D_PriceTextLabel = exports.D_TextLabel = exports.D_TextField = exports.D_PriceTextField = exports.D_TextButton = exports.D_StatusBlock = void 0;
6
- exports.ToolBar = exports.BulkActionBar = exports.AdminListItem = exports.AdminListHeader = exports.AdminList = exports.DynamicLayout = exports.M_SectionSheet = exports.M_MobileBasicModal = exports.M_ContentSheet = exports.M_AnnotationSheet = exports.M_RichTextEditor = exports.M_UploadTextButton = exports.M_UploadMainButton = exports.M_UploadIconButton = exports.M_PriceTextLabel = exports.M_TextLabel = exports.M_TextField = exports.M_PriceTextField = exports.M_TextButton = exports.M_StatusBlock = exports.M_Snackbar = exports.M_Slider = exports.M_Select = exports.M_SegmentedButtonGroup = exports.M_ReactionButton = exports.M_Radio = exports.M_MobileTabBar = exports.M_MobileHeaderBar = exports.M_MobileAlertDialog = exports.M_MainButton = exports.M_LottieReactionButton = exports.M_ImageSlide = exports.M_IconButton = exports.M_HorizontalFormGroup = exports.M_FloatingActionButton = exports.M_Dropdown = exports.M_DatePicker = exports.M_ContextMenuItem = void 0;
4
+ exports.D_Slider = exports.D_Select = exports.D_SegmentedButtonGroup = exports.D_ReactionButton = exports.D_Radio = exports.D_PageTitleTextGroup = exports.D_MainButton = exports.D_LottieReactionButton = exports.D_ImageSlide = exports.D_IconButton = exports.D_HorizontalFormGroup = exports.D_Hero = exports.D_FloatingActionButton = exports.D_FilterBar = exports.D_EditApplyTextField = exports.D_DynamicDesktopNavBarTemplates = exports.D_DynamicDesktopNavBar = exports.D_Dropdown = exports.D_DesktopTabBar = exports.D_DesktopHeaderBar = exports.D_DesktopAlertDialog = exports.D_ContextMenuItem = exports.D_ContextMenu = exports.D_ComboBox = exports.D_Chip = exports.D_Checkbox = exports.D_ChatList = exports.D_ChatBubbleListItem = exports.D_CardList = exports.D_Card = exports.D_BoxItem = exports.D_BodyTextGroup = exports.D_BlogTextField = exports.D_BasicListItem = exports.D_BasicList = exports.D_BasicFormGroup = exports.D_BasicChatListItem = exports.D_BasicButtonGroup = exports.D_AdminListItem = exports.D_AdminListHeader = exports.D_AdminList = exports.WTContainersBox = exports.WTGlobalMenuContainer = exports.LayoutWT = exports.WSContainersBox = exports.WSGlobalMenuContainer = exports.LayoutWS = exports.WHContainersBox = exports.LayoutWH = exports.WFContainersBox = void 0;
5
+ exports.M_Checkbox = exports.M_ChatList = exports.M_ChatBubbleListItem = exports.M_CardList = exports.M_Card = exports.M_BoxItem = exports.M_BodyTextGroup = exports.M_BlogTextField = exports.M_BasicListItem = exports.M_BasicList = exports.M_BasicFormGroup = exports.M_BasicChatListItem = exports.M_BasicButtonGroup = exports.MSContainersBox = exports.MSNavigationContainer = exports.LayoutMS = exports.MPContainersBox = exports.MPTabContainer = exports.MPNavigationContainer = exports.LayoutMP = exports.MMContainersBox = exports.MMNavigationContainer = exports.LayoutMM = exports.MFContainersBox = exports.LayoutMF = exports.D_SectionSheet = exports.D_LocalizedContentModal = exports.D_DesktopTutorialModal = exports.D_DesktopHeadlessModal = exports.D_DesktopBasicModalWithTab = exports.D_DesktopBasicModal = exports.D_ContentSheet = exports.D_AnnotationSheet = exports.LocalizedButton = exports.D_EmailRichTextEditor = exports.D_RichTextEditor = exports.D_Calendar = exports.D_UserDesktopSideTab = exports.D_UserDesktopTabBar = exports.D_UserDesktopNavBar = exports.D_UploadTextButton = exports.D_UploadMainButton = exports.D_UploadIconButton = exports.D_PriceTextLabel = exports.D_TextLabel = exports.D_TextField = exports.D_PriceTextField = exports.D_TextButton = exports.D_StatusBlock = exports.D_Snackbar = void 0;
6
+ exports.ToolBar = exports.BulkActionBar = exports.AdminListItem = exports.AdminListHeader = exports.AdminList = exports.DynamicLayout = exports.M_SectionSheet = exports.M_MobileBasicModal = exports.M_ContentSheet = exports.M_AnnotationSheet = exports.M_RichTextEditor = exports.M_UploadTextButton = exports.M_UploadMainButton = exports.M_UploadIconButton = exports.M_PriceTextLabel = exports.M_TextLabel = exports.M_TextField = exports.M_PriceTextField = exports.M_TextButton = exports.M_StatusBlock = exports.M_Snackbar = exports.M_Slider = exports.M_Select = exports.M_SegmentedButtonGroup = exports.M_ReactionButton = exports.M_Radio = exports.M_MobileTabBar = exports.M_MobileHeaderBar = exports.M_MobileAlertDialog = exports.M_MainButton = exports.M_LottieReactionButton = exports.M_ImageSlide = exports.M_IconButton = exports.M_HorizontalFormGroup = exports.M_FloatingActionButton = exports.M_Dropdown = exports.M_DatePicker = exports.M_ContextMenuItem = exports.M_ContextMenu = exports.M_ComboBox = exports.M_Chip = void 0;
7
7
  /* eslint-disable import/order */
8
8
  /* eslint-disable import/first */
9
9
  // common
@@ -94,6 +94,7 @@ Object.defineProperty(exports, "D_ChatBubbleListItem", { enumerable: true, get:
94
94
  Object.defineProperty(exports, "D_ChatList", { enumerable: true, get: function () { return desktop_1.D_ChatList; } });
95
95
  Object.defineProperty(exports, "D_Checkbox", { enumerable: true, get: function () { return desktop_1.D_Checkbox; } });
96
96
  Object.defineProperty(exports, "D_Chip", { enumerable: true, get: function () { return desktop_1.D_Chip; } });
97
+ Object.defineProperty(exports, "D_ComboBox", { enumerable: true, get: function () { return desktop_1.D_ComboBox; } });
97
98
  Object.defineProperty(exports, "D_ContextMenu", { enumerable: true, get: function () { return desktop_1.D_ContextMenu; } });
98
99
  Object.defineProperty(exports, "D_ContextMenuItem", { enumerable: true, get: function () { return desktop_1.D_ContextMenuItem; } });
99
100
  Object.defineProperty(exports, "D_DesktopAlertDialog", { enumerable: true, get: function () { return desktop_1.D_DesktopAlertDialog; } });
@@ -139,6 +140,7 @@ Object.defineProperty(exports, "D_DesktopTutorialModal", { enumerable: true, get
139
140
  Object.defineProperty(exports, "D_SectionSheet", { enumerable: true, get: function () { return desktop_1.D_SectionSheet; } });
140
141
  Object.defineProperty(exports, "D_Calendar", { enumerable: true, get: function () { return desktop_1.D_Calendar; } });
141
142
  Object.defineProperty(exports, "D_RichTextEditor", { enumerable: true, get: function () { return desktop_1.D_RichTextEditor; } });
143
+ Object.defineProperty(exports, "D_EmailRichTextEditor", { enumerable: true, get: function () { return desktop_1.D_EmailRichTextEditor; } });
142
144
  Object.defineProperty(exports, "D_LocalizedContentModal", { enumerable: true, get: function () { return desktop_1.D_LocalizedContentModal; } });
143
145
  Object.defineProperty(exports, "LocalizedButton", { enumerable: true, get: function () { return desktop_1.LocalizedButton; } });
144
146
  // mobile
@@ -169,6 +171,7 @@ Object.defineProperty(exports, "M_ChatBubbleListItem", { enumerable: true, get:
169
171
  Object.defineProperty(exports, "M_ChatList", { enumerable: true, get: function () { return mobile_1.M_ChatList; } });
170
172
  Object.defineProperty(exports, "M_Checkbox", { enumerable: true, get: function () { return mobile_1.M_Checkbox; } });
171
173
  Object.defineProperty(exports, "M_Chip", { enumerable: true, get: function () { return mobile_1.M_Chip; } });
174
+ Object.defineProperty(exports, "M_ComboBox", { enumerable: true, get: function () { return mobile_1.M_ComboBox; } });
172
175
  Object.defineProperty(exports, "M_ContextMenu", { enumerable: true, get: function () { return mobile_1.M_ContextMenu; } });
173
176
  Object.defineProperty(exports, "M_ContextMenuItem", { enumerable: true, get: function () { return mobile_1.M_ContextMenuItem; } });
174
177
  Object.defineProperty(exports, "M_DatePicker", { enumerable: true, get: function () { return mobile_1.M_DatePicker; } });
@@ -13,16 +13,19 @@ var __assign = (this && this.__assign) || function () {
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.withFormProvider = void 0;
15
15
  var jsx_runtime_1 = require("react/jsx-runtime");
16
- /* eslint-disable @typescript-eslint/no-empty-function */
17
- /* eslint-disable react-hooks/rules-of-hooks */
16
+ /* eslint-disable no-console */
18
17
  var react_hook_form_1 = require("react-hook-form");
19
18
  var components_1 = require("../components");
20
- var withFormProvider = function (storyFn) {
19
+ // 컴포넌트로 분리
20
+ var FormProviderWrapper = function (_a) {
21
+ var children = _a.children;
21
22
  var methods = (0, react_hook_form_1.useForm)({ mode: 'onChange' });
22
23
  var handleSubmit = function (data) {
23
- // eslint-disable-next-line no-console
24
24
  console.log('submit success', data);
25
25
  };
26
- return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, __assign({}, methods, { children: (0, jsx_runtime_1.jsx)(components_1.Form, __assign({ onSubmit: methods.handleSubmit(handleSubmit) }, { children: storyFn() })) })));
26
+ return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, __assign({}, methods, { children: (0, jsx_runtime_1.jsx)(components_1.Form, __assign({ onSubmit: methods.handleSubmit(handleSubmit) }, { children: children })) })));
27
+ };
28
+ var withFormProvider = function (storyFn) {
29
+ return (0, jsx_runtime_1.jsx)(FormProviderWrapper, { children: storyFn() });
27
30
  };
28
31
  exports.withFormProvider = withFormProvider;
@@ -0,0 +1,13 @@
1
+ /// <reference types="react" />
2
+ import { OpenPersonalizationModalCallback } from './plugins/personalization_tag_plugin';
3
+ import type { ImageUploadResult } from './RichTextEditor';
4
+ export interface EmailRichTextEditorProps {
5
+ defaultText?: string;
6
+ tinymceScriptSrc?: string;
7
+ height?: number;
8
+ onChange?: (content: string) => void;
9
+ onImageUpload?: (file: File) => Promise<ImageUploadResult>;
10
+ onOpenPersonalizationModal?: OpenPersonalizationModalCallback;
11
+ onImageUploadError?: (error: unknown) => void;
12
+ }
13
+ export default function EmailRichTextEditor({ defaultText, tinymceScriptSrc, height, onChange, onImageUpload, onOpenPersonalizationModal, onImageUploadError }: EmailRichTextEditorProps): JSX.Element;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ var jsx_runtime_1 = require("react/jsx-runtime");
11
+ var tinymce_react_1 = require("@tinymce/tinymce-react");
12
+ var react_1 = require("react");
13
+ var uuid_1 = require("uuid");
14
+ var styled_components_1 = __importDefault(require("styled-components"));
15
+ var personalization_tag_plugin_1 = require("./plugins/personalization_tag_plugin");
16
+ var EMAIL_PLUGINS = 'advlist anchor autolink charmap code fullscreen image insertdatetime link lists media preview searchreplace table visualblocks';
17
+ var EMAIL_TOOLBAR = 'blocks bold italic underline strikethrough | forecolor backcolor alignleft aligncenter alignright alignjustify outdent indent | numlist bullist blockquote insertTag link image media undo redo';
18
+ var EMAIL_EDITOR_CUSTOM_CSS = "\n .tox .tox-tbtn {\n width: 25px;\n min-width: 25px;\n }\n\n .tox .tox-tbtn--select {\n width: auto !important;\n }\n\n .tox.tox-tinymce {\n z-index: 0 !important;\n }\n";
19
+ var EMAIL_CONTENT_STYLE = "\n body { font-family:Helvetica,Arial,sans-serif; font-size:16px; line-height: 1.5; overflow-wrap: break-word; word-break: break-word; word-wrap: break-word; }\n p { margin: 0; }\n a { color: #0066cc; text-decoration: underline; }\n img { max-width: 100%; height: auto; display: block; margin: 16px 0; border: none; object-fit: contain; }\n video, iframe { width: 100%; margin: 16px 0; padding: 0; border: none; display: block; max-width: 100%; }\n span[data-mce-object=\"video\"], span[data-mce-object=\"iframe\"] { display: block; width: 100%; margin: 16px 0; border: none; }\n span[data-mce-object]::before { content: ''; display: block; }\n span[data-mce-object]::after { content: ''; display: block; }\n .mce-object-video, .mce-object-iframe, .mce-preview-object { margin: 0; padding: 0; border: none; }\n .mce-preview-object > iframe { border: none; }\n table { width: 100%; margin: 16px 0; border: none; border-collapse: collapse; }\n .alert-warning { border-left: 5px solid #ffdd00; padding: 10px; background: #fff8e1; margin: 10px 0; border-radius: 4px; }\n";
20
+ function EmailRichTextEditor(_a) {
21
+ var defaultText = _a.defaultText, tinymceScriptSrc = _a.tinymceScriptSrc, _b = _a.height, height = _b === void 0 ? 500 : _b, onChange = _a.onChange, onImageUpload = _a.onImageUpload, onOpenPersonalizationModal = _a.onOpenPersonalizationModal, onImageUploadError = _a.onImageUploadError;
22
+ var editorRef = (0, react_1.useRef)(null);
23
+ var uploadedBlobsRef = (0, react_1.useRef)(new Map());
24
+ var initialContentRef = (0, react_1.useRef)(defaultText);
25
+ var onChangeRef = (0, react_1.useRef)(onChange);
26
+ var onImageUploadRef = (0, react_1.useRef)(onImageUpload);
27
+ var onImageUploadErrorRef = (0, react_1.useRef)(onImageUploadError);
28
+ var onOpenPersonalizationModalRef = (0, react_1.useRef)(onOpenPersonalizationModal);
29
+ (0, react_1.useEffect)(function () {
30
+ onChangeRef.current = onChange;
31
+ }, [onChange]);
32
+ (0, react_1.useEffect)(function () {
33
+ onImageUploadRef.current = onImageUpload;
34
+ }, [onImageUpload]);
35
+ (0, react_1.useEffect)(function () {
36
+ onImageUploadErrorRef.current = onImageUploadError;
37
+ }, [onImageUploadError]);
38
+ (0, react_1.useEffect)(function () {
39
+ onOpenPersonalizationModalRef.current = onOpenPersonalizationModal;
40
+ }, [onOpenPersonalizationModal]);
41
+ var handleInit = function (_evt, editor) {
42
+ editorRef.current = editor;
43
+ };
44
+ var handleEditorChange = function (content) {
45
+ var _a;
46
+ (_a = onChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onChangeRef, content);
47
+ };
48
+ var useDarkMode = window.PdsUtils.tone === 'DARK';
49
+ var editorInit = (0, react_1.useMemo)(function () { return ({
50
+ height: height,
51
+ menubar: false,
52
+ statusbar: true,
53
+ elementpath: false,
54
+ branding: false,
55
+ toolbar_mode: 'wrap',
56
+ plugins: EMAIL_PLUGINS,
57
+ toolbar: EMAIL_TOOLBAR,
58
+ skin: useDarkMode ? 'oxide-dark' : 'oxide',
59
+ content_css: useDarkMode ? 'dark' : 'default',
60
+ content_style: EMAIL_CONTENT_STYLE,
61
+ automatic_uploads: true,
62
+ images_reuse_filename: true,
63
+ paste_data_images: true,
64
+ media_live_embeds: true,
65
+ images_upload_handler: function (blobInfo) {
66
+ return new Promise(function (resolve, reject) {
67
+ var blobUri = blobInfo.blobUri();
68
+ var existingUrl = uploadedBlobsRef.current.get(blobUri);
69
+ if (existingUrl) {
70
+ resolve(existingUrl);
71
+ return;
72
+ }
73
+ if (!onImageUploadRef.current) {
74
+ reject(new Error('No upload handler'));
75
+ return;
76
+ }
77
+ var file = new File([blobInfo.blob()], blobInfo.filename() || (0, uuid_1.v4)(), {
78
+ type: blobInfo.blob().type
79
+ });
80
+ onImageUploadRef
81
+ .current(file)
82
+ .then(function (result) {
83
+ if (result.location) {
84
+ uploadedBlobsRef.current.set(blobUri, result.location);
85
+ resolve(result.location);
86
+ }
87
+ else {
88
+ reject(new Error('Upload failed'));
89
+ }
90
+ })
91
+ .catch(function (error) {
92
+ var _a;
93
+ (_a = onImageUploadErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onImageUploadErrorRef, error);
94
+ reject(error);
95
+ });
96
+ });
97
+ },
98
+ setup: function (editor) {
99
+ var personalizationSetup = (0, personalization_tag_plugin_1.getPersonalizationSetup)(onOpenPersonalizationModalRef.current);
100
+ personalizationSetup(editor);
101
+ editor.on('ExecCommand', function (e) {
102
+ var formattingCommands = [
103
+ 'mceToggleFormat',
104
+ 'Bold',
105
+ 'Italic',
106
+ 'Underline',
107
+ 'Strikethrough',
108
+ 'ForeColor',
109
+ 'BackColor',
110
+ 'FontSize',
111
+ 'FormatBlock'
112
+ ];
113
+ if (formattingCommands.some(function (cmd) { return e.command.includes(cmd); })) {
114
+ setTimeout(function () {
115
+ var _a;
116
+ var content = editor.getContent();
117
+ (_a = onChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onChangeRef, content);
118
+ }, 10);
119
+ }
120
+ });
121
+ }
122
+ }); }, []);
123
+ return ((0, jsx_runtime_1.jsx)(S_EmailEditor, { children: (0, jsx_runtime_1.jsx)(tinymce_react_1.Editor, { tinymceScriptSrc: tinymceScriptSrc || '/tinymce/tinymce.min.js', onInit: handleInit, initialValue: initialContentRef.current, onEditorChange: handleEditorChange, init: editorInit }) }));
124
+ }
125
+ exports.default = EmailRichTextEditor;
126
+ var S_EmailEditor = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n height: fit-content;\n position: relative;\n ", "\n"], ["\n height: fit-content;\n position: relative;\n ", "\n"])), EMAIL_EDITOR_CUSTOM_CSS);
127
+ var templateObject_1;
@@ -1,2 +1,5 @@
1
1
  export { default as RichTextEditor } from './RichTextEditor';
2
2
  export type { RichTextEditorProps, ImageUploadHandler, ImageUploadResult } from './RichTextEditor';
3
+ export { default as EmailRichTextEditor } from './EmailRichTextEditor';
4
+ export type { EmailRichTextEditorProps } from './EmailRichTextEditor';
5
+ export type { OpenPersonalizationModalCallback, InsertTagCallback } from './plugins/personalization_tag_plugin';
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.RichTextEditor = void 0;
6
+ exports.EmailRichTextEditor = exports.RichTextEditor = void 0;
7
7
  var RichTextEditor_1 = require("./RichTextEditor");
8
8
  Object.defineProperty(exports, "RichTextEditor", { enumerable: true, get: function () { return __importDefault(RichTextEditor_1).default; } });
9
+ var EmailRichTextEditor_1 = require("./EmailRichTextEditor");
10
+ Object.defineProperty(exports, "EmailRichTextEditor", { enumerable: true, get: function () { return __importDefault(EmailRichTextEditor_1).default; } });
@@ -0,0 +1,9 @@
1
+ import type { Editor } from 'tinymce';
2
+ export type InsertTagCallback = (tag: string) => void;
3
+ export type OpenPersonalizationModalCallback = (insertTag: InsertTagCallback) => void;
4
+ /**
5
+ * Returns a setup function that registers the generic personalization tag button
6
+ * isolated to a specific TinyMCE Editor instance.
7
+ * @param onOpenPersonalizationModal - A callback provided by the consumer to render their own modal content and logic when `{ }` is clicked.
8
+ */
9
+ export declare function getPersonalizationSetup(onOpenPersonalizationModal?: OpenPersonalizationModalCallback): (editor: Editor) => void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPersonalizationSetup = void 0;
4
+ /**
5
+ * Returns a setup function that registers the generic personalization tag button
6
+ * isolated to a specific TinyMCE Editor instance.
7
+ * @param onOpenPersonalizationModal - A callback provided by the consumer to render their own modal content and logic when `{ }` is clicked.
8
+ */
9
+ function getPersonalizationSetup(onOpenPersonalizationModal) {
10
+ return function (editor) {
11
+ editor.ui.registry.addIcon('merge-field', '<svg width="24" height="24" viewBox="0 0 24 24"><text x="4" y="17" font-size="14" font-weight="900" stroke="currentColor" stroke-width="0.5">{ }</text></svg>');
12
+ editor.ui.registry.addButton('insertTag', {
13
+ tooltip: 'Insert Personalization Tag',
14
+ icon: 'merge-field',
15
+ onAction: function () {
16
+ var insertTag = function (tag) {
17
+ editor.insertContent(tag);
18
+ };
19
+ if (onOpenPersonalizationModal) {
20
+ onOpenPersonalizationModal(insertTag);
21
+ }
22
+ }
23
+ });
24
+ };
25
+ }
26
+ exports.getPersonalizationSetup = getPersonalizationSetup;
@@ -39,7 +39,7 @@ import { PriceTextField } from './PriceTextField';
39
39
  import { PriceTextLabel } from './PriceTextLabel';
40
40
  import { Radio } from './Radio';
41
41
  import { ReactionButton } from './ReactionButton';
42
- import { RichTextEditor } from './RichTextEditor';
42
+ import { RichTextEditor, EmailRichTextEditor } from './RichTextEditor';
43
43
  import { SegmentedButtonGroup } from './SegmentedButtonGroup';
44
44
  import { Select } from './Select';
45
45
  import { Slider } from './Slider';
@@ -55,4 +55,4 @@ import { UploadTextButton } from './UploadTextButton';
55
55
  import { UserDesktopNavBar } from './UserDesktopNavBar';
56
56
  import { UserDesktopSideTab } from './UserDesktopSideTab';
57
57
  import { UserDesktopTabBar } from './UserDesktopTabBar';
58
- export { AdminList, AdminListHeader, AdminListItem, BasicButtonGroup, BasicChatListItem, BasicFormGroup, BasicList, BasicListItem, BlogTextField, BodyTextGroup, BoxItem, Card, CardList, ChatBubbleListItem, ChatList, Checkbox, Chip, ComboBox, ContextMenu, ContextMenuItem, DesktopAlertDialog, DesktopHeaderBar, DesktopTabBar, Dropdown, DynamicDesktopNavBar, DynamicDesktopNavBarTemplates, EditApplyTextField, FilterBar, FloatingActionButton, Hero, HorizontalFormGroup, IconButton, ImageSlide, LottieReactionButton, MainButton, PageTitleTextGroup, PriceTextField, Radio, ReactionButton, RichTextEditor, SegmentedButtonGroup, Select, Slider, Snackbar, SpeechBubble, StatusBlock, TextButton, TextField, TextLabel, PriceTextLabel, UploadIconButton, UploadMainButton, UploadTextButton, UserDesktopNavBar, UserDesktopTabBar, UserDesktopSideTab, Calendar, LocalizedButton };
58
+ export { AdminList, AdminListHeader, AdminListItem, BasicButtonGroup, BasicChatListItem, BasicFormGroup, BasicList, BasicListItem, BlogTextField, BodyTextGroup, BoxItem, Card, CardList, ChatBubbleListItem, ChatList, Checkbox, Chip, ComboBox, ContextMenu, ContextMenuItem, DesktopAlertDialog, DesktopHeaderBar, DesktopTabBar, Dropdown, DynamicDesktopNavBar, DynamicDesktopNavBarTemplates, EditApplyTextField, FilterBar, FloatingActionButton, Hero, HorizontalFormGroup, IconButton, ImageSlide, LottieReactionButton, MainButton, PageTitleTextGroup, PriceTextField, Radio, ReactionButton, RichTextEditor, EmailRichTextEditor, SegmentedButtonGroup, Select, Slider, Snackbar, SpeechBubble, StatusBlock, TextButton, TextField, TextLabel, PriceTextLabel, UploadIconButton, UploadMainButton, UploadTextButton, UserDesktopNavBar, UserDesktopTabBar, UserDesktopSideTab, Calendar, LocalizedButton };
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PriceTextLabel = exports.TextLabel = exports.TextField = exports.TextButton = exports.StatusBlock = exports.SpeechBubble = exports.Snackbar = exports.Slider = exports.Select = exports.SegmentedButtonGroup = exports.RichTextEditor = exports.ReactionButton = exports.Radio = exports.PriceTextField = exports.PageTitleTextGroup = exports.MainButton = exports.LottieReactionButton = exports.ImageSlide = exports.IconButton = exports.HorizontalFormGroup = exports.Hero = exports.FloatingActionButton = exports.FilterBar = exports.EditApplyTextField = exports.DynamicDesktopNavBarTemplates = exports.DynamicDesktopNavBar = exports.Dropdown = exports.DesktopTabBar = exports.DesktopHeaderBar = exports.DesktopAlertDialog = exports.ContextMenuItem = exports.ContextMenu = exports.ComboBox = exports.Chip = exports.Checkbox = exports.ChatList = exports.ChatBubbleListItem = exports.CardList = exports.Card = exports.BoxItem = exports.BodyTextGroup = exports.BlogTextField = exports.BasicListItem = exports.BasicList = exports.BasicFormGroup = exports.BasicChatListItem = exports.BasicButtonGroup = exports.AdminListItem = exports.AdminListHeader = exports.AdminList = void 0;
4
- exports.LocalizedButton = exports.Calendar = exports.UserDesktopSideTab = exports.UserDesktopTabBar = exports.UserDesktopNavBar = exports.UploadTextButton = exports.UploadMainButton = exports.UploadIconButton = void 0;
3
+ exports.TextLabel = exports.TextField = exports.TextButton = exports.StatusBlock = exports.SpeechBubble = exports.Snackbar = exports.Slider = exports.Select = exports.SegmentedButtonGroup = exports.EmailRichTextEditor = exports.RichTextEditor = exports.ReactionButton = exports.Radio = exports.PriceTextField = exports.PageTitleTextGroup = exports.MainButton = exports.LottieReactionButton = exports.ImageSlide = exports.IconButton = exports.HorizontalFormGroup = exports.Hero = exports.FloatingActionButton = exports.FilterBar = exports.EditApplyTextField = exports.DynamicDesktopNavBarTemplates = exports.DynamicDesktopNavBar = exports.Dropdown = exports.DesktopTabBar = exports.DesktopHeaderBar = exports.DesktopAlertDialog = exports.ContextMenuItem = exports.ContextMenu = exports.ComboBox = exports.Chip = exports.Checkbox = exports.ChatList = exports.ChatBubbleListItem = exports.CardList = exports.Card = exports.BoxItem = exports.BodyTextGroup = exports.BlogTextField = exports.BasicListItem = exports.BasicList = exports.BasicFormGroup = exports.BasicChatListItem = exports.BasicButtonGroup = exports.AdminListItem = exports.AdminListHeader = exports.AdminList = void 0;
4
+ exports.LocalizedButton = exports.Calendar = exports.UserDesktopSideTab = exports.UserDesktopTabBar = exports.UserDesktopNavBar = exports.UploadTextButton = exports.UploadMainButton = exports.UploadIconButton = exports.PriceTextLabel = void 0;
5
5
  var AdminList_1 = require("./AdminList");
6
6
  Object.defineProperty(exports, "AdminList", { enumerable: true, get: function () { return AdminList_1.AdminList; } });
7
7
  var AdminListHeader_1 = require("./AdminListHeader");
@@ -87,6 +87,7 @@ var ReactionButton_1 = require("./ReactionButton");
87
87
  Object.defineProperty(exports, "ReactionButton", { enumerable: true, get: function () { return ReactionButton_1.ReactionButton; } });
88
88
  var RichTextEditor_1 = require("./RichTextEditor");
89
89
  Object.defineProperty(exports, "RichTextEditor", { enumerable: true, get: function () { return RichTextEditor_1.RichTextEditor; } });
90
+ Object.defineProperty(exports, "EmailRichTextEditor", { enumerable: true, get: function () { return RichTextEditor_1.EmailRichTextEditor; } });
90
91
  var SegmentedButtonGroup_1 = require("./SegmentedButtonGroup");
91
92
  Object.defineProperty(exports, "SegmentedButtonGroup", { enumerable: true, get: function () { return SegmentedButtonGroup_1.SegmentedButtonGroup; } });
92
93
  var Select_1 = require("./Select");
@@ -8,5 +8,5 @@ export { ContainersBox as WSContainersBox } from './layout/LayoutWS/ContainersBo
8
8
  export { LayoutWT } from './layout/LayoutWT';
9
9
  export { GlobalMenuContainer as WTGlobalMenuContainer } from './layout/LayoutWT/Containers';
10
10
  export { ContainersBox as WTContainersBox } from './layout/LayoutWT/ContainersBox';
11
- export { AdminList as D_AdminList, AdminListHeader as D_AdminListHeader, AdminListItem as D_AdminListItem, BasicButtonGroup as D_BasicButtonGroup, BasicChatListItem as D_BasicChatListItem, BasicFormGroup as D_BasicFormGroup, BasicList as D_BasicList, BasicListItem as D_BasicListItem, BlogTextField as D_BlogTextField, BodyTextGroup as D_BodyTextGroup, BoxItem as D_BoxItem, Card as D_Card, CardList as D_CardList, ChatBubbleListItem as D_ChatBubbleListItem, ChatList as D_ChatList, Checkbox as D_Checkbox, Chip as D_Chip, ComboBox as D_ComboBox, ContextMenu as D_ContextMenu, ContextMenuItem as D_ContextMenuItem, DesktopAlertDialog as D_DesktopAlertDialog, DesktopHeaderBar as D_DesktopHeaderBar, DesktopTabBar as D_DesktopTabBar, Dropdown as D_Dropdown, DynamicDesktopNavBar as D_DynamicDesktopNavBar, DynamicDesktopNavBarTemplates as D_DynamicDesktopNavBarTemplates, EditApplyTextField as D_EditApplyTextField, FilterBar as D_FilterBar, FloatingActionButton as D_FloatingActionButton, Hero as D_Hero, HorizontalFormGroup as D_HorizontalFormGroup, IconButton as D_IconButton, ImageSlide as D_ImageSlide, LottieReactionButton as D_LottieReactionButton, MainButton as D_MainButton, PageTitleTextGroup as D_PageTitleTextGroup, Radio as D_Radio, ReactionButton as D_ReactionButton, RichTextEditor as D_RichTextEditor, SegmentedButtonGroup as D_SegmentedButtonGroup, Select as D_Select, Slider as D_Slider, Snackbar as D_Snackbar, SpeechBubble as D_SpeechBubble, StatusBlock as D_StatusBlock, TextButton as D_TextButton, PriceTextField as D_PriceTextField, TextField as D_TextField, TextLabel as D_TextLabel, PriceTextLabel as D_PriceTextLabel, UploadIconButton as D_UploadIconButton, UploadMainButton as D_UploadMainButton, UploadTextButton as D_UploadTextButton, UserDesktopNavBar as D_UserDesktopNavBar, UserDesktopTabBar as D_UserDesktopTabBar, UserDesktopSideTab as D_UserDesktopSideTab, Calendar as D_Calendar, LocalizedButton } from './components';
11
+ export { AdminList as D_AdminList, AdminListHeader as D_AdminListHeader, AdminListItem as D_AdminListItem, BasicButtonGroup as D_BasicButtonGroup, BasicChatListItem as D_BasicChatListItem, BasicFormGroup as D_BasicFormGroup, BasicList as D_BasicList, BasicListItem as D_BasicListItem, BlogTextField as D_BlogTextField, BodyTextGroup as D_BodyTextGroup, BoxItem as D_BoxItem, Card as D_Card, CardList as D_CardList, ChatBubbleListItem as D_ChatBubbleListItem, ChatList as D_ChatList, Checkbox as D_Checkbox, Chip as D_Chip, ComboBox as D_ComboBox, ContextMenu as D_ContextMenu, ContextMenuItem as D_ContextMenuItem, DesktopAlertDialog as D_DesktopAlertDialog, DesktopHeaderBar as D_DesktopHeaderBar, DesktopTabBar as D_DesktopTabBar, Dropdown as D_Dropdown, DynamicDesktopNavBar as D_DynamicDesktopNavBar, DynamicDesktopNavBarTemplates as D_DynamicDesktopNavBarTemplates, EditApplyTextField as D_EditApplyTextField, FilterBar as D_FilterBar, FloatingActionButton as D_FloatingActionButton, Hero as D_Hero, HorizontalFormGroup as D_HorizontalFormGroup, IconButton as D_IconButton, ImageSlide as D_ImageSlide, LottieReactionButton as D_LottieReactionButton, MainButton as D_MainButton, PageTitleTextGroup as D_PageTitleTextGroup, Radio as D_Radio, ReactionButton as D_ReactionButton, RichTextEditor as D_RichTextEditor, EmailRichTextEditor as D_EmailRichTextEditor, SegmentedButtonGroup as D_SegmentedButtonGroup, Select as D_Select, Slider as D_Slider, Snackbar as D_Snackbar, SpeechBubble as D_SpeechBubble, StatusBlock as D_StatusBlock, TextButton as D_TextButton, PriceTextField as D_PriceTextField, TextField as D_TextField, TextLabel as D_TextLabel, PriceTextLabel as D_PriceTextLabel, UploadIconButton as D_UploadIconButton, UploadMainButton as D_UploadMainButton, UploadTextButton as D_UploadTextButton, UserDesktopNavBar as D_UserDesktopNavBar, UserDesktopTabBar as D_UserDesktopTabBar, UserDesktopSideTab as D_UserDesktopSideTab, Calendar as D_Calendar, LocalizedButton } from './components';
12
12
  export { AnnotationSheet as D_AnnotationSheet, ContentSheet as D_ContentSheet, DesktopBasicModal as D_DesktopBasicModal, DesktopBasicModalWithTab as D_DesktopBasicModalWithTab, DesktopBasicModalWithTabInfoType, DesktopHeadlessModal as D_DesktopHeadlessModal, DesktopTutorialModal as D_DesktopTutorialModal, DesktopTutorialModalInfoType, SectionSheet as D_SectionSheet, LocalizedContentModal as D_LocalizedContentModal } from './panels';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.D_SegmentedButtonGroup = exports.D_RichTextEditor = exports.D_ReactionButton = exports.D_Radio = exports.D_PageTitleTextGroup = exports.D_MainButton = exports.D_LottieReactionButton = exports.D_ImageSlide = exports.D_IconButton = exports.D_HorizontalFormGroup = exports.D_Hero = exports.D_FloatingActionButton = exports.D_FilterBar = exports.D_EditApplyTextField = exports.D_DynamicDesktopNavBarTemplates = exports.D_DynamicDesktopNavBar = exports.D_Dropdown = exports.D_DesktopTabBar = exports.D_DesktopHeaderBar = exports.D_DesktopAlertDialog = exports.D_ContextMenuItem = exports.D_ContextMenu = exports.D_ComboBox = exports.D_Chip = exports.D_Checkbox = exports.D_ChatList = exports.D_ChatBubbleListItem = exports.D_CardList = exports.D_Card = exports.D_BoxItem = exports.D_BodyTextGroup = exports.D_BlogTextField = exports.D_BasicListItem = exports.D_BasicList = exports.D_BasicFormGroup = exports.D_BasicChatListItem = exports.D_BasicButtonGroup = exports.D_AdminListItem = exports.D_AdminListHeader = exports.D_AdminList = exports.WTContainersBox = exports.WTGlobalMenuContainer = exports.LayoutWT = exports.WSContainersBox = exports.WSGlobalMenuContainer = exports.LayoutWS = exports.WHContainersBox = exports.LayoutWH = exports.WFContainersBox = exports.LayoutWF = void 0;
4
- exports.D_LocalizedContentModal = exports.D_SectionSheet = exports.D_DesktopTutorialModal = exports.D_DesktopHeadlessModal = exports.D_DesktopBasicModalWithTab = exports.D_DesktopBasicModal = exports.D_ContentSheet = exports.D_AnnotationSheet = exports.LocalizedButton = exports.D_Calendar = exports.D_UserDesktopSideTab = exports.D_UserDesktopTabBar = exports.D_UserDesktopNavBar = exports.D_UploadTextButton = exports.D_UploadMainButton = exports.D_UploadIconButton = exports.D_PriceTextLabel = exports.D_TextLabel = exports.D_TextField = exports.D_PriceTextField = exports.D_TextButton = exports.D_StatusBlock = exports.D_SpeechBubble = exports.D_Snackbar = exports.D_Slider = exports.D_Select = void 0;
3
+ exports.D_EmailRichTextEditor = exports.D_RichTextEditor = exports.D_ReactionButton = exports.D_Radio = exports.D_PageTitleTextGroup = exports.D_MainButton = exports.D_LottieReactionButton = exports.D_ImageSlide = exports.D_IconButton = exports.D_HorizontalFormGroup = exports.D_Hero = exports.D_FloatingActionButton = exports.D_FilterBar = exports.D_EditApplyTextField = exports.D_DynamicDesktopNavBarTemplates = exports.D_DynamicDesktopNavBar = exports.D_Dropdown = exports.D_DesktopTabBar = exports.D_DesktopHeaderBar = exports.D_DesktopAlertDialog = exports.D_ContextMenuItem = exports.D_ContextMenu = exports.D_ComboBox = exports.D_Chip = exports.D_Checkbox = exports.D_ChatList = exports.D_ChatBubbleListItem = exports.D_CardList = exports.D_Card = exports.D_BoxItem = exports.D_BodyTextGroup = exports.D_BlogTextField = exports.D_BasicListItem = exports.D_BasicList = exports.D_BasicFormGroup = exports.D_BasicChatListItem = exports.D_BasicButtonGroup = exports.D_AdminListItem = exports.D_AdminListHeader = exports.D_AdminList = exports.WTContainersBox = exports.WTGlobalMenuContainer = exports.LayoutWT = exports.WSContainersBox = exports.WSGlobalMenuContainer = exports.LayoutWS = exports.WHContainersBox = exports.LayoutWH = exports.WFContainersBox = exports.LayoutWF = void 0;
4
+ exports.D_LocalizedContentModal = exports.D_SectionSheet = exports.D_DesktopTutorialModal = exports.D_DesktopHeadlessModal = exports.D_DesktopBasicModalWithTab = exports.D_DesktopBasicModal = exports.D_ContentSheet = exports.D_AnnotationSheet = exports.LocalizedButton = exports.D_Calendar = exports.D_UserDesktopSideTab = exports.D_UserDesktopTabBar = exports.D_UserDesktopNavBar = exports.D_UploadTextButton = exports.D_UploadMainButton = exports.D_UploadIconButton = exports.D_PriceTextLabel = exports.D_TextLabel = exports.D_TextField = exports.D_PriceTextField = exports.D_TextButton = exports.D_StatusBlock = exports.D_SpeechBubble = exports.D_Snackbar = exports.D_Slider = exports.D_Select = exports.D_SegmentedButtonGroup = void 0;
5
5
  // layoutWF
6
6
  var LayoutWF_1 = require("./layout/LayoutWF");
7
7
  Object.defineProperty(exports, "LayoutWF", { enumerable: true, get: function () { return LayoutWF_1.LayoutWF; } });
@@ -67,6 +67,7 @@ Object.defineProperty(exports, "D_PageTitleTextGroup", { enumerable: true, get:
67
67
  Object.defineProperty(exports, "D_Radio", { enumerable: true, get: function () { return components_1.Radio; } });
68
68
  Object.defineProperty(exports, "D_ReactionButton", { enumerable: true, get: function () { return components_1.ReactionButton; } });
69
69
  Object.defineProperty(exports, "D_RichTextEditor", { enumerable: true, get: function () { return components_1.RichTextEditor; } });
70
+ Object.defineProperty(exports, "D_EmailRichTextEditor", { enumerable: true, get: function () { return components_1.EmailRichTextEditor; } });
70
71
  Object.defineProperty(exports, "D_SegmentedButtonGroup", { enumerable: true, get: function () { return components_1.SegmentedButtonGroup; } });
71
72
  Object.defineProperty(exports, "D_Select", { enumerable: true, get: function () { return components_1.Select; } });
72
73
  Object.defineProperty(exports, "D_Slider", { enumerable: true, get: function () { return components_1.Slider; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pds-dev-kit-web",
3
- "version": "2.2.313",
3
+ "version": "2.2.315",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
Binary file
package/release-note.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # PDS-DEV-KIT-WEB Release Notes
2
- ## [v2.2.313]
2
+ ## [v2.2.315]
3
3
  ## daily|https://design.storybook.publ.biz/
4
4
 
5
5
  ### 업데이트 사항
6
- * [PDS-1423] ComboBox 추가
6
+ * EmailRichTextEditor 컴포넌트 추가
@@ -1,28 +0,0 @@
1
- -----BEGIN PRIVATE KEY-----
2
- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDs4IzefteDpp40
3
- hBgk+1bVmLIe5+aU4KVUV39w+6zl9kBjooHgoE+QWre7HK7oDssQJacGcDdqLil+
4
- 2VBUob5pVht/UrcfV0/8NGZgFPj3/eyyIqraJeXZtI0+18y5uN9yuwyt6ZJvF6vp
5
- fgJlftRLDBkADr28IK1kZ8LBYd2nMqp8hgIa5GhpbwfftZkLO26sbbN8Xonr8SyE
6
- abe7c4KywTPfMxxmLhY6muKVQ3xDvE/YXawamfCHcGCstx4a3GxojmRXczve+o0Z
7
- VvSJquvg0A4gZo7NoRPNfrIhN9YH4LTs7px4TAOyi+DQC2FqapIEXgvBeMV+GcLJ
8
- o7T3hEuVAgMBAAECggEAYdlgV4iN/hQVxhvK3Xv1osYwzhN9bIJfyTdbrZBJG7Vd
9
- Y8r9W4zdUQQoYWK33aQ+vazQEhjIy1PGUF/0jwFBZsHrGe1RN+EZaVU79PS047xA
10
- ylUHvpVpHUU4E32RVCbKJtqdojmaA8oDebBTzRlXGKkmqp9sQQo+lftGuBt1NFsu
11
- D34JjVJrg6R637eGolEdtlEt6mZun1wLpMA0a/XWn0GKfFekZz8zL9Vf/djipy+7
12
- D2tbLOStlMg7nTLInMC0yAwd+M+MHpGsqGQ1CAZ5gAtDeOWLjiZ7XOwadxtMdvCj
13
- uST6INab//ovwML6LypXs371LKV/YJ/cAa3bKbBdAQKBgQDwRTwm8dfGzacBQOgJ
14
- Lz37yTVThCNkkzV4FcEWXwQg+Vg1lEBbDvKbzc/R4lcN+eI8Ytkl4IJibx8r4lnm
15
- 9f14uV8BWt9M86jsaSDqcyujAFyVp+Mk3KKxtZkHKBdVYAdpRXLbYpbXBmIW4jEW
16
- vqgq+G8YBdKaD60yHJa7yId2GwKBgQD8YnIq8IBK2y0bwz5fMuoVAto54kBbJ5xu
17
- 051/qEpwp6F8zL5l90YfMzfaDI+HGd39Exyh1jw40tC/oftrpku45aUKlKh2p0Eu
18
- XIisd/ogREOgX+rccNK3/+vNIvuNMUG+P058CXIG77xmuVNhMcTCJlkVNkCvTqiD
19
- C15nG4MgDwKBgH8rNeYq9JjteioIr4dE8NqWKVpVwuHVpGQ1p2fuzGGjd5OMLu/D
20
- HpdmPEuLL6ZfDuYFL4eDp57vz6DLgefjZNAD1QwDi9LP2CWgkuJkKMFyTI6NOITn
21
- HllOk3sdNhRi6ilGr778FHgkkcAo4fB24s0zhqFBW7FdAL9YMFOdlEznAoGBAMmd
22
- 01peGf6yrIxbIn5ma/0w9Cf9iC/JqvwV7OHIDP+FykmqPgeyy7+s6Nc15YqlrWK4
23
- W80lGaLDNqN/wRu0ExW3zmpva0yuPDHPFhfBGH2iSuvY9AP51TvMJBER+yZFzSEv
24
- 7YDFAuRrq3PcZLFmUqpOfCen2XCyQ4e8E0QHBG8dAoGATLPdAJKh8QtrAHetvKba
25
- U6DvB9bZK1c9+JpMYTgm0sv0VAxEug6g7K5dzFze674+cT9aBjztmm9f9vMFrjLP
26
- jDEjf9078+yJMPHvJRfArm5wkEwtKB/+8l5EdegO3ddHEadeyKYkXhqr7xDi+Y7C
27
- NpXDacZzaSPE3eM94owa1Lw=
28
- -----END PRIVATE KEY-----
@@ -1,26 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIEVDCCArygAwIBAgIQIQ3K3sDryHneKbPt2m/uYjANBgkqhkiG9w0BAQsFADB5
3
- MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExJzAlBgNVBAsMHmNjbHNz
4
- QGNjbHNzdWktTWFjQm9va1Byby5sb2NhbDEuMCwGA1UEAwwlbWtjZXJ0IGNjbHNz
5
- QGNjbHNzdWktTWFjQm9va1Byby5sb2NhbDAeFw0yNTAzMzExMTMwMjlaFw0yNzA3
6
- MDExMTMwMjlaMFIxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZp
7
- Y2F0ZTEnMCUGA1UECwweY2Nsc3NAY2Nsc3N1aS1NYWNCb29rUHJvLmxvY2FsMIIB
8
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7OCM3n7Xg6aeNIQYJPtW1Ziy
9
- HufmlOClVFd/cPus5fZAY6KB4KBPkFq3uxyu6A7LECWnBnA3ai4pftlQVKG+aVYb
10
- f1K3H1dP/DRmYBT49/3ssiKq2iXl2bSNPtfMubjfcrsMremSbxer6X4CZX7USwwZ
11
- AA69vCCtZGfCwWHdpzKqfIYCGuRoaW8H37WZCzturG2zfF6J6/EshGm3u3OCssEz
12
- 3zMcZi4WOprilUN8Q7xP2F2sGpnwh3BgrLceGtxsaI5kV3M73vqNGVb0iarr4NAO
13
- IGaOzaETzX6yITfWB+C07O6ceEwDsovg0AthamqSBF4LwXjFfhnCyaO094RLlQID
14
- AQABo38wfTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYD
15
- VR0jBBgwFoAUivgDIbPxV5kEtkRARvALcvb3RgwwNQYDVR0RBC4wLIISKi5tYWNo
16
- aW5lLnB1YmxyLmNvhwTAqAEOhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEB
17
- CwUAA4IBgQCnQOeM9UfVUHc5+0GGQvFsou88CsaTj8GGOK2Jsc5Qgc4puG9uX/Wl
18
- ex8VLerV1+/E27E9idhD6kN3lFpV0MG8b4YxlctCUXhpK0dT/fAau8kQIlwyU0cH
19
- AsZA1KmFTEtTiktMieRySHg2B4f5+FA3egRg5GEh1Um9al8+aFS2kR6uytN3yJOP
20
- FS0iX4j/nh35SuE0m5qwGDJuUd5/6V+oCrAlqDCdJt2WI/KK7rXP/l+h22hcUnm1
21
- 6BXg95qTuASgHo559vXKlIGcG0rn+Gjt0hSJxdXTPLT9ixgE6fL93h1ouu67bJfK
22
- mgfUd0tzl43DgUnQKNZhbVx8U0S1d1mixrDPwjXYR3REZEW2EtCoaoTiUN4NbTkV
23
- UpHxXac/iSq03Vtw/eutQturAMFhRTcmLUdb9sCFONx8D+lOjzAmn2c4aoVPCZv5
24
- TDUSFopOvekxS2ngBJqb4YFtE0rebpoIuwuXvDaAdh9YCCDOghan0FLFRdMsD/kz
25
- kOlXSJWNgZ0=
26
- -----END CERTIFICATE-----