@pega/cosmos-react-rte 3.0.0-dev.3.0 → 3.0.0-dev.30.0

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 (86) hide show
  1. package/lib/components/Editor/Editor.d.ts +7 -0
  2. package/lib/components/Editor/Editor.d.ts.map +1 -1
  3. package/lib/components/Editor/Editor.js +195 -49
  4. package/lib/components/Editor/Editor.js.map +1 -1
  5. package/lib/components/Editor/Editor.styles.d.ts +4 -0
  6. package/lib/components/Editor/Editor.styles.d.ts.map +1 -0
  7. package/lib/components/Editor/Editor.styles.js +41 -0
  8. package/lib/components/Editor/Editor.styles.js.map +1 -0
  9. package/lib/components/Editor/Editor.types.d.ts +18 -7
  10. package/lib/components/Editor/Editor.types.d.ts.map +1 -1
  11. package/lib/components/Editor/Editor.types.js.map +1 -1
  12. package/lib/components/Editor/ImageEditor.d.ts +10 -0
  13. package/lib/components/Editor/ImageEditor.d.ts.map +1 -0
  14. package/lib/components/Editor/ImageEditor.js +271 -0
  15. package/lib/components/Editor/ImageEditor.js.map +1 -0
  16. package/lib/components/Editor/Toolbar/AnchorButton.d.ts.map +1 -1
  17. package/lib/components/Editor/Toolbar/AnchorButton.js +36 -17
  18. package/lib/components/Editor/Toolbar/AnchorButton.js.map +1 -1
  19. package/lib/components/Editor/Toolbar/ImageButton.js +2 -2
  20. package/lib/components/Editor/Toolbar/ImageButton.js.map +1 -1
  21. package/lib/components/Editor/Toolbar/TextSelect.js +2 -2
  22. package/lib/components/Editor/Toolbar/TextSelect.js.map +1 -1
  23. package/lib/components/Editor/Toolbar/Toolbar.d.ts.map +1 -1
  24. package/lib/components/Editor/Toolbar/Toolbar.js +23 -17
  25. package/lib/components/Editor/Toolbar/Toolbar.js.map +1 -1
  26. package/lib/components/RichTextEditor/DecoratorComponents/CodeBlock.js +1 -1
  27. package/lib/components/RichTextEditor/DecoratorComponents/CodeBlock.js.map +1 -1
  28. package/lib/components/RichTextEditor/DecoratorComponents/Image.js +2 -2
  29. package/lib/components/RichTextEditor/DecoratorComponents/Image.js.map +1 -1
  30. package/lib/components/RichTextEditor/DecoratorComponents/Link.js +3 -3
  31. package/lib/components/RichTextEditor/DecoratorComponents/Link.js.map +1 -1
  32. package/lib/components/RichTextEditor/DecoratorComponents/Table.d.ts +0 -2
  33. package/lib/components/RichTextEditor/DecoratorComponents/Table.d.ts.map +1 -1
  34. package/lib/components/RichTextEditor/DecoratorComponents/Table.js +6 -33
  35. package/lib/components/RichTextEditor/DecoratorComponents/Table.js.map +1 -1
  36. package/lib/components/RichTextEditor/RichTextEditor.d.ts.map +1 -1
  37. package/lib/components/RichTextEditor/RichTextEditor.js +45 -11
  38. package/lib/components/RichTextEditor/RichTextEditor.js.map +1 -1
  39. package/lib/components/RichTextEditor/RichTextEditor.styles.d.ts +0 -2
  40. package/lib/components/RichTextEditor/RichTextEditor.styles.d.ts.map +1 -1
  41. package/lib/components/RichTextEditor/RichTextEditor.styles.js +17 -126
  42. package/lib/components/RichTextEditor/RichTextEditor.styles.js.map +1 -1
  43. package/lib/components/RichTextEditor/RichTextTreeRenderer.d.ts +9 -0
  44. package/lib/components/RichTextEditor/RichTextTreeRenderer.d.ts.map +1 -0
  45. package/lib/components/RichTextEditor/RichTextTreeRenderer.js +15 -0
  46. package/lib/components/RichTextEditor/RichTextTreeRenderer.js.map +1 -0
  47. package/lib/components/RichTextEditor/RichTextViewer.d.ts +1 -0
  48. package/lib/components/RichTextEditor/RichTextViewer.d.ts.map +1 -1
  49. package/lib/components/RichTextEditor/RichTextViewer.js +13 -27
  50. package/lib/components/RichTextEditor/RichTextViewer.js.map +1 -1
  51. package/lib/components/RichTextEditor/Toolbar/AnchorButton.js +5 -5
  52. package/lib/components/RichTextEditor/Toolbar/AnchorButton.js.map +1 -1
  53. package/lib/components/RichTextEditor/Toolbar/ImageButton.js +2 -2
  54. package/lib/components/RichTextEditor/Toolbar/ImageButton.js.map +1 -1
  55. package/lib/components/RichTextEditor/Toolbar/IndentButton.d.ts.map +1 -1
  56. package/lib/components/RichTextEditor/Toolbar/IndentButton.js +6 -3
  57. package/lib/components/RichTextEditor/Toolbar/IndentButton.js.map +1 -1
  58. package/lib/components/RichTextEditor/Toolbar/TableButton.js +1 -1
  59. package/lib/components/RichTextEditor/Toolbar/TableButton.js.map +1 -1
  60. package/lib/components/RichTextEditor/Toolbar/TextSelect.js +2 -2
  61. package/lib/components/RichTextEditor/Toolbar/TextSelect.js.map +1 -1
  62. package/lib/components/RichTextEditor/Toolbar/Toolbar.d.ts.map +1 -1
  63. package/lib/components/RichTextEditor/Toolbar/Toolbar.js +17 -8
  64. package/lib/components/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  65. package/lib/components/RichTextEditor/Toolbar/ToolbarButton.js +1 -1
  66. package/lib/components/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
  67. package/lib/components/RichTextEditor/utils/EditorCommands.d.ts.map +1 -1
  68. package/lib/components/RichTextEditor/utils/EditorCommands.js +23 -3
  69. package/lib/components/RichTextEditor/utils/EditorCommands.js.map +1 -1
  70. package/lib/components/RichTextEditor/utils/htmlConverter.d.ts.map +1 -1
  71. package/lib/components/RichTextEditor/utils/htmlConverter.js +5 -2
  72. package/lib/components/RichTextEditor/utils/htmlConverter.js.map +1 -1
  73. package/lib/components/RichTextEditor/utils/interactionRenderer.d.ts +1 -1
  74. package/lib/components/RichTextEditor/utils/interactionRenderer.d.ts.map +1 -1
  75. package/lib/components/RichTextEditor/utils/interactionRenderer.js +2 -5
  76. package/lib/components/RichTextEditor/utils/interactionRenderer.js.map +1 -1
  77. package/lib/components/RichTextEditor/utils/markdownConverter.js +1 -1
  78. package/lib/components/RichTextEditor/utils/markdownConverter.js.map +1 -1
  79. package/lib/components/RichTextEditor/utils/renderers.d.ts +20 -3
  80. package/lib/components/RichTextEditor/utils/renderers.d.ts.map +1 -1
  81. package/lib/components/RichTextEditor/utils/renderers.js +120 -25
  82. package/lib/components/RichTextEditor/utils/renderers.js.map +1 -1
  83. package/lib/components/RichTextEditor/utils/search.d.ts.map +1 -1
  84. package/lib/components/RichTextEditor/utils/search.js +9 -1
  85. package/lib/components/RichTextEditor/utils/search.js.map +1 -1
  86. package/package.json +22 -19
@@ -2,9 +2,16 @@ import 'tinymce/icons/default';
2
2
  import 'tinymce/themes/silver';
3
3
  import 'tinymce/plugins/advlist';
4
4
  import 'tinymce/plugins/lists';
5
+ import 'tinymce/plugins/autolink';
6
+ import 'tinymce/models/dom';
5
7
  import { FC } from 'react';
8
+ import { DefaultTheme } from 'styled-components';
6
9
  import { ForwardProps } from '@pega/cosmos-react-core';
7
10
  import { EditorProps } from './Editor.types';
11
+ export declare const getImageStyles: (theme: DefaultTheme) => string;
12
+ export declare const StyledInnerEditor: import("styled-components").StyledComponent<"div", DefaultTheme, {
13
+ showPlaceholder: boolean;
14
+ }, never>;
8
15
  declare const Editor: FC<EditorProps & ForwardProps>;
9
16
  export default Editor;
10
17
  //# sourceMappingURL=Editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../../../src/components/Editor/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EACL,EAAE,EASH,MAAM,OAAO,CAAC;AAGf,OAAO,EAIL,YAAY,EAOb,MAAM,yBAAyB,CAAC;AAWjC,OAAO,EAAE,WAAW,EAAe,MAAM,gBAAgB,CAAC;AAiB1D,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,GAAG,YAAY,CAmR1C,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../../../src/components/Editor/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,0BAA0B,CAAC;AAClC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EACL,EAAE,EASH,MAAM,OAAO,CAAC;AACf,OAAe,EAAO,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI9D,OAAO,EAIL,YAAY,EASb,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAAE,WAAW,EAAe,MAAM,gBAAgB,CAAC;AAkB1D,eAAO,MAAM,cAAc,UAAW,YAAY,WAQjD,CAAC;AAEF,eAAO,MAAM,iBAAiB;qBAAiC,OAAO;SAarE,CAAC;AAIF,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,GAAG,YAAY,CA+a1C,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -4,61 +4,133 @@ import 'tinymce/icons/default';
4
4
  import 'tinymce/themes/silver';
5
5
  import 'tinymce/plugins/advlist';
6
6
  import 'tinymce/plugins/lists';
7
+ import 'tinymce/plugins/autolink';
8
+ import 'tinymce/models/dom';
7
9
  import { forwardRef, useEffect, useRef, useState, useLayoutEffect, useImperativeHandle } from 'react';
8
10
  import styled, { css } from 'styled-components';
9
- import { createUID, FormControl, FormField, useAfterInitialEffect, useTheme, useUID, useI18n, useConsolidatedRef, defaultThemeProp } from '@pega/cosmos-react-core';
10
- import StyledRichTextEditor, { StyledEditorContainer, StyledRichTextFormField, StyledHtml } from '../RichTextEditor/RichTextEditor.styles';
11
+ import { compile, serialize, stringify } from 'stylis';
12
+ import { stripUnit } from 'polished';
13
+ import { createUID, FormControl, FormField, useAfterInitialEffect, useTheme, useUID, useI18n, useConsolidatedRef, defaultThemeProp, useAutoResize, useConfiguration } from '@pega/cosmos-react-core';
14
+ import { getHtmlStyles } from '@pega/cosmos-react-core/lib/components/HTML/HTML';
15
+ import { createGlobalBodyStyles, createGlobalRootStyles, globalSpacingStyles } from '@pega/cosmos-react-core/lib/styles/GlobalStyle';
16
+ import StyledRichTextEditor, { StyledRichTextFormField } from '../RichTextEditor/RichTextEditor.styles';
11
17
  import Toolbar from './Toolbar/Toolbar';
12
18
  import EditorContext from './Editor.context';
13
19
  import { getTextFormats } from './Toolbar/TextSelect';
14
- const StyledInnerEditor = styled.div(({ theme, showPlaceholder }) => {
20
+ import ImageEditor, { imgHoverClass } from './ImageEditor';
21
+ import { offscreenSelectionStyles, placeholderStyles, StyledEditorContainer } from './Editor.styles';
22
+ const getFileFromUrl = async (url, name) => {
23
+ const response = await fetch(url);
24
+ const data = await response.blob();
25
+ return new File([data], name, {
26
+ type: data.type
27
+ });
28
+ };
29
+ export const getImageStyles = (theme) => {
30
+ return `
31
+ img:hover,
32
+ img.${imgHoverClass} {
33
+ box-shadow: 0 0 0 0.06125rem ${theme.base.palette['primary-background']},
34
+ 0 0 0 0.125rem ${theme.base.palette.interactive}, 0 0 0 0.25rem rgba(0, 118, 209, 0.3);
35
+ }
36
+ `;
37
+ };
38
+ export const StyledInnerEditor = styled.div(({ theme, showPlaceholder }) => {
15
39
  return css `
16
- ${showPlaceholder &&
40
+ ${showPlaceholder &&
17
41
  css `
18
- ::before {
19
- color: ${theme.base.colors.slate.medium};
20
- position: absolute;
21
- content: attr(data-mce-placeholder);
22
- }
23
- `}
24
- `;
42
+ ::before {
43
+ color: ${theme.base.colors.slate.medium};
44
+ position: absolute;
45
+ content: attr(data-mce-placeholder);
46
+ }
47
+ `}
48
+ `;
25
49
  });
26
50
  StyledInnerEditor.defaultProps = defaultThemeProp;
27
51
  const Editor = forwardRef((props, ref) => {
28
- const { components: { 'text-area': { 'min-height': minHeight } } } = useTheme();
52
+ const { components: { 'text-area': { 'min-height': textAreaMinHeight } } } = useTheme();
53
+ const theme = useTheme();
54
+ const { styleSheetTarget } = useConfiguration();
29
55
  const [editor, setEditor] = useState();
56
+ const [focused, setFocused] = useState(false);
30
57
  const t = useI18n();
31
58
  const uid = useUID();
32
59
  const labelId = useUID();
33
60
  const editorRef = useConsolidatedRef(ref);
61
+ const tinyMceRef = useRef(null);
62
+ const tinyMceContainerRef = useRef(null);
34
63
  const initialized = useRef(false);
35
- const { id = uid, toolbar = [], label, labelHidden, info, status, required, disabled, readOnly, onChange, onFocus, onBlur, onImageAdded, onInit, defaultValue, customComponents = [], height = { min: minHeight }, customActions, placeholder, ...restProps } = props;
36
- const [showPlaceholder, setShowPlaceholder] = useState(() => !defaultValue);
64
+ const { id = uid, toolbar = [], label, labelHidden, info, status, required, disabled, readOnly, onChange, onKeyDown, onFocus, onBlur, onImageAdded, onInit, defaultValue, customComponents = [], height, customActions, placeholder, children, spellcheck = true, ...restProps } = props;
65
+ const baseHeight = {
66
+ min: height?.min ?? stripUnit(textAreaMinHeight) * 16,
67
+ max: height?.max ?? undefined
68
+ };
69
+ const getHeight = (type) => {
70
+ if (typeof baseHeight === 'number') {
71
+ return stripUnit(baseHeight);
72
+ }
73
+ if (baseHeight[type]) {
74
+ return stripUnit(baseHeight[type]);
75
+ }
76
+ return undefined;
77
+ };
78
+ const imagesEnabled = toolbar.includes('images');
79
+ const maxHeight = getHeight('max');
80
+ const minHeight = getHeight('min');
81
+ const [autoResizeRef, resizeEditor] = useAutoResize(maxHeight, minHeight);
37
82
  const formFieldRef = useRef(null);
38
83
  const value = useRef(defaultValue);
84
+ const renderToolbar = editor && toolbar.length > 0 && !readOnly && !disabled;
85
+ const processPastedImgUrls = async (infoArr) => {
86
+ const files = await Promise.all(infoArr.map(({ id: imgId, url }) => getFileFromUrl(url, imgId)));
87
+ files.forEach((file, i) => {
88
+ onImageAdded?.(file, infoArr[i].id);
89
+ });
90
+ };
91
+ const pastePreprocess = (plugin, args) => {
92
+ const isImg = args.content.includes('<img');
93
+ if (!imagesEnabled && isImg) {
94
+ args.content = args.content.replace(/<img(.*)\/>/g, '');
95
+ }
96
+ if (imagesEnabled && isImg) {
97
+ const pastedHtml = new DOMParser().parseFromString(args.content, 'text/html').body;
98
+ const imgInfo = [];
99
+ pastedHtml.querySelectorAll('img').forEach(imgEl => {
100
+ const imgId = createUID();
101
+ const url = imgEl.src;
102
+ imgInfo.push({ id: imgId, url });
103
+ imgEl.setAttribute('id', imgId);
104
+ imgEl.setAttribute('src', '');
105
+ });
106
+ args.content = pastedHtml.innerHTML;
107
+ processPastedImgUrls(imgInfo);
108
+ }
109
+ };
39
110
  useImperativeHandle(editorRef, () => ({
40
111
  focus: () => {
41
112
  editor?.focus();
42
113
  },
43
114
  getPlainText: () => {
44
- return editor ? editor?.getContent({ format: 'text' }) : '';
115
+ return editor ? editor.getContent({ format: 'text' }) : '';
45
116
  },
46
117
  getRichText: () => {
47
- return editor ? JSON.stringify(editor?.getContent({ format: 'raw' })) : '';
118
+ return editor ? JSON.stringify(editor.getContent({ format: 'raw' })) : '';
48
119
  },
49
120
  getHtml: () => {
50
- return editor ? editor?.getContent({ format: 'html' }) : '';
121
+ return editor ? editor.getContent({ format: 'html' }) : '';
51
122
  },
52
123
  clear: () => {
53
124
  editor?.setContent('');
54
125
  },
55
126
  appendImage: ({ src, alt }, imageId) => {
56
127
  if (editor) {
57
- const editorEl = editor.getElement();
128
+ const editorEl = editor.getDoc();
58
129
  const imageEl = editorEl.querySelector(`#${imageId}`);
59
130
  if (imageEl) {
60
131
  imageEl.setAttribute('src', src);
61
132
  imageEl.setAttribute('alt', alt);
133
+ resizeEditor();
62
134
  }
63
135
  }
64
136
  },
@@ -77,34 +149,66 @@ const Editor = forwardRef((props, ref) => {
77
149
  element: formFieldRef.current || undefined
78
150
  }), [editor]);
79
151
  useLayoutEffect(() => {
152
+ if (!tinyMceRef.current || !tinyMceContainerRef.current)
153
+ return;
154
+ const styles = serialize(compile(getHtmlStyles(theme)), stringify);
155
+ const imageStyles = serialize(compile(getImageStyles(theme)), stringify);
80
156
  tinymce
81
157
  .init({
82
158
  readonly: readOnly || disabled,
83
159
  skin: false,
84
- selector: `#${id}`,
160
+ target: tinyMceRef.current,
85
161
  toolbar: false,
86
162
  menubar: false,
87
- inline: true,
88
- plugins: 'lists advlist',
163
+ plugins: 'lists advlist autolink',
164
+ paste_data_images: true,
89
165
  lists_indent_on_tab: true,
90
166
  icons: '',
167
+ branding: false,
168
+ elementpath: false,
91
169
  placeholder,
92
- init_instance_callback: () => {
93
- customComponents.forEach(comp => {
94
- if (!customElements.get(comp.name)) {
95
- customElements.define(comp.name, comp.customElement);
96
- }
97
- });
170
+ content_css: false,
171
+ browser_spellcheck: spellcheck,
172
+ paste_preprocess: pastePreprocess,
173
+ content_style: `${createGlobalRootStyles(theme)} ${globalSpacingStyles} ${createGlobalBodyStyles(theme)} body { min-height: 3rem; padding: ${toolbar.length > 0 && !readOnly ? theme.base.spacing : 0}; } html { overflow: hidden; } ${offscreenSelectionStyles} ${placeholderStyles} ${imageStyles} ${styles}`,
174
+ init_instance_callback: initializedEditor => {
175
+ const iframeWindow = tinyMceContainerRef.current?.querySelector('iframe').contentWindow;
176
+ const editorCustomElements = iframeWindow?.customElements;
177
+ if (editorCustomElements) {
178
+ customComponents.forEach(({ name, createCustomElement: customElementCreator, style }) => {
179
+ if (!editorCustomElements.get(name)) {
180
+ editorCustomElements.define(name, customElementCreator(iframeWindow));
181
+ }
182
+ if (style) {
183
+ const styleEl = document.createElement('style');
184
+ styleEl.innerText = style;
185
+ initializedEditor.getDoc().head.appendChild(styleEl);
186
+ }
187
+ });
188
+ }
98
189
  },
99
- custom_elements: `~${customComponents.reduce((prev, { name }, i) => {
100
- return i === 0 ? name : `${prev},${name}`;
101
- }, '')}`,
190
+ extended_valid_elements: `${customComponents
191
+ .map(comp => `${comp.name}${comp.extensionAttributes ? `[${comp.extensionAttributes.join('|')}]` : ''}`)
192
+ .join(',')}`,
193
+ custom_elements: `~${customComponents.map(comp => comp.name).join('~,')}`,
102
194
  setup: editorSettings => {
195
+ editorSettings.on('keydown', e => {
196
+ onKeyDown?.(e);
197
+ });
103
198
  getTextFormats().forEach((format, i) => {
104
199
  editorSettings.addShortcut(`meta+alt+${i}`, `${t('rte_change_text_format')} ${format.text}`, () => {
105
200
  editorSettings.execCommand('FormatBlock', false, format.type);
106
201
  });
107
202
  });
203
+ editorSettings.addShortcut('meta+shift+b', t('rte_bold'), () => {
204
+ editorSettings.execCommand('Bold');
205
+ });
206
+ editorSettings.addShortcut('meta+shift+i', t('rte_italic'), () => {
207
+ editorSettings.execCommand('Italic');
208
+ });
209
+ editorSettings.addShortcut('meta+shift+x', t('rte_strike_through'), () => {
210
+ editorSettings.execCommand('Strikethrough');
211
+ });
108
212
  editorSettings.addShortcut('meta+shift+l', t('rte_toggle_unordered_list'), () => {
109
213
  editorSettings.execCommand('InsertUnorderedList');
110
214
  });
@@ -125,8 +229,26 @@ const Editor = forwardRef((props, ref) => {
125
229
  })
126
230
  .then(tinymceEditors => {
127
231
  setEditor(tinymceEditors[0]);
232
+ tinymceEditors[0].editorContainer?.setAttribute('style', '');
233
+ const iframe = tinyMceContainerRef.current?.querySelector('iframe');
234
+ if (iframe) {
235
+ const globalStyles = styleSheetTarget?.querySelectorAll('[data-cosmos-global-style]') ??
236
+ [];
237
+ const extraStyles = document.querySelectorAll('[data-cosmos-global-style]') ?? [];
238
+ const iframeContentHead = iframe?.contentDocument?.querySelector('head');
239
+ [...globalStyles, ...extraStyles].forEach(sheet => {
240
+ iframeContentHead?.appendChild(sheet.cloneNode(true));
241
+ });
242
+ autoResizeRef.current = iframe;
243
+ resizeEditor();
244
+ }
128
245
  });
129
246
  }, []);
247
+ useEffect(() => {
248
+ if (editor) {
249
+ editor.options.set('paste_preprocess', pastePreprocess);
250
+ }
251
+ }, [imagesEnabled]);
130
252
  useEffect(() => {
131
253
  if (!editor || initialized.current)
132
254
  return;
@@ -136,20 +258,37 @@ const Editor = forwardRef((props, ref) => {
136
258
  useEffect(() => {
137
259
  if (!editor)
138
260
  return;
261
+ const onChangeEvents = ['keyup', 'FormatApply', 'FormatRemove', 'ExecCommand'];
262
+ const onEditorKeyDown = (event) => {
263
+ resizeEditor();
264
+ if (event.key === 'Enter') {
265
+ editor.selection.getNode().scrollIntoView(false);
266
+ }
267
+ };
139
268
  const onEditorChange = () => {
140
- setShowPlaceholder(!editor?.getContent({ format: 'text' }));
269
+ onChange?.(editor);
141
270
  };
142
271
  const onEditorFocus = () => {
272
+ setFocused(true);
143
273
  onFocus?.();
144
274
  };
145
275
  const onEditorBlur = () => {
276
+ setFocused(false);
146
277
  onBlur?.();
147
278
  };
148
- editor.on('input', onEditorChange);
279
+ onChangeEvents.forEach(event => {
280
+ editor.on(event, onEditorChange);
281
+ });
282
+ editor.on('keydown', onEditorKeyDown);
283
+ editor.on('paste', resizeEditor);
149
284
  editor.on('focus', onEditorFocus);
150
285
  editor.on('blur', onEditorBlur);
151
286
  return () => {
152
- editor.off('input', onEditorChange);
287
+ onChangeEvents.forEach(event => {
288
+ editor.off(event, onEditorChange);
289
+ });
290
+ editor.off('keydown', onEditorKeyDown);
291
+ editor.off('paste', resizeEditor);
153
292
  editor.off('focus', onEditorFocus);
154
293
  editor.off('blur', onEditorBlur);
155
294
  };
@@ -169,31 +308,38 @@ const Editor = forwardRef((props, ref) => {
169
308
  e.preventDefault();
170
309
  if (e.dataTransfer) {
171
310
  Array.from(e.dataTransfer.files).forEach(file => {
172
- if (file.type.includes('image')) {
311
+ if (file.type.includes('image') && imagesEnabled) {
173
312
  addImage(file);
174
313
  }
175
314
  });
176
315
  }
177
316
  };
178
317
  editor?.on('drop', onEditorDrop);
318
+ const body = editor?.getDoc().body;
319
+ const resizeObserver = new ResizeObserver(() => {
320
+ resizeEditor();
321
+ });
322
+ if (body) {
323
+ resizeObserver.observe(body);
324
+ }
179
325
  return () => {
180
326
  editor?.off('drop', onEditorDrop);
327
+ resizeObserver.disconnect();
181
328
  };
182
- }, [editor]);
183
- const renderToolbar = editor && toolbar.length > 0 && !readOnly && !disabled;
184
- return (_jsx(EditorContext.Provider, { value: { addImage, editor: editor || {} }, children: _jsx(FormField, { as: StyledRichTextFormField, toolbar: renderToolbar, label:
185
- // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
186
- _jsx("span", { onClick: () => {
187
- editor?.focus();
188
- }, children: label }, void 0), labelFor: '', labelId: labelId, labelHidden: labelHidden, id: id, info: info, status: status, required: required, disabled: disabled, readOnly: readOnly, onFocus: (e) => {
189
- if (e.target === formFieldRef.current && !disabled) {
190
- editor?.focus();
191
- }
192
- }, ref: formFieldRef, tabIndex: disabled ? -1 : undefined, children: _jsxs(FormControl, { ...restProps, ref: editorRef, required: required, disabled: disabled, readOnly: readOnly, status: status, as: StyledRichTextEditor, toolbar: renderToolbar, children: [_jsx(StyledEditorContainer, { readOnly: readOnly, onClick: () => {
193
- if (!disabled) {
194
- editor?.focus();
195
- }
196
- }, toolbar: renderToolbar, containerHeight: height, children: _jsx(StyledHtml, { id: id, style: { outline: 'none', border: 'none' }, dangerouslySetInnerHTML: { __html: value.current || '' }, "aria-label": `${label}${renderToolbar ? `. ${t('rte_toolbar_instructions')}.` : ''}`, as: StyledInnerEditor, showPlaceholder: showPlaceholder, "aria-labelledby": labelId, role: 'textbox' }, void 0) }, void 0), renderToolbar && (_jsx(Toolbar, { features: toolbar, editor: editor, customActions: customActions }, void 0))] }, void 0) }, void 0) }, void 0));
329
+ }, [editor, resizeEditor]);
330
+ return (_jsxs(EditorContext.Provider, { value: { addImage, editor: editor || {} }, children: [_jsx(FormField, { as: StyledRichTextFormField, toolbar: renderToolbar, label:
331
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
332
+ _jsx("span", { onClick: () => {
333
+ editor?.focus();
334
+ }, children: label }), labelFor: '', labelId: labelId, labelHidden: labelHidden, id: id, info: info, status: status, required: required, disabled: disabled, readOnly: readOnly, onFocus: (e) => {
335
+ if (e.target === formFieldRef.current && !disabled) {
336
+ editor?.focus();
337
+ }
338
+ }, ref: formFieldRef, tabIndex: disabled ? -1 : undefined, children: _jsxs(FormControl, { ...restProps, ref: editorRef, required: required, disabled: disabled, readOnly: readOnly, status: status, as: StyledRichTextEditor, toolbar: renderToolbar, focused: focused, children: [_jsxs(StyledEditorContainer, { onClick: () => {
339
+ if (!disabled) {
340
+ editor?.focus();
341
+ }
342
+ }, ref: tinyMceContainerRef, children: [_jsx("textarea", { id: id, value: value.current || '', onChange: () => { }, "aria-label": `${label}${renderToolbar ? `. ${t('rte_toolbar_instructions')}.` : ''}`, "aria-labelledby": labelId, ref: tinyMceRef }), tinyMceContainerRef.current && editor && !readOnly && (_jsx(ImageEditor, { editor: editor, editorEl: tinyMceContainerRef.current, onChange: () => onChange?.(editor) }))] }), renderToolbar && (_jsx(Toolbar, { features: toolbar, editor: editor, customActions: customActions }))] }) }), children] }));
197
343
  });
198
344
  export default Editor;
199
345
  //# sourceMappingURL=Editor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../../src/components/Editor/Editor.tsx"],"names":[],"mappings":"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","sourcesContent":["import tinymce, { Editor as TinymceEditor } from 'tinymce/tinymce';\nimport 'tinymce/icons/default';\nimport 'tinymce/themes/silver';\nimport 'tinymce/plugins/advlist';\nimport 'tinymce/plugins/lists';\nimport {\n FC,\n forwardRef,\n PropsWithoutRef,\n useEffect,\n useRef,\n useState,\n useLayoutEffect,\n useImperativeHandle,\n FocusEvent\n} from 'react';\nimport styled, { css } from 'styled-components';\n\nimport {\n createUID,\n FormControl,\n FormField,\n ForwardProps,\n useAfterInitialEffect,\n useTheme,\n useUID,\n useI18n,\n useConsolidatedRef,\n defaultThemeProp\n} from '@pega/cosmos-react-core';\n\nimport StyledRichTextEditor, {\n StyledEditorContainer,\n StyledRichTextFormField,\n StyledHtml\n} from '../RichTextEditor/RichTextEditor.styles';\n\nimport Toolbar from './Toolbar/Toolbar';\nimport EditorContext from './Editor.context';\nimport { getTextFormats } from './Toolbar/TextSelect';\nimport { EditorProps, EditorState } from './Editor.types';\n\nconst StyledInnerEditor = styled.div<{ showPlaceholder: boolean }>(({ theme, showPlaceholder }) => {\n return css`\n ${showPlaceholder &&\n css`\n ::before {\n color: ${theme.base.colors.slate.medium};\n position: absolute;\n content: attr(data-mce-placeholder);\n }\n `}\n `;\n});\n\nStyledInnerEditor.defaultProps = defaultThemeProp;\n\nconst Editor: FC<EditorProps & ForwardProps> = forwardRef(\n (props: PropsWithoutRef<EditorProps>, ref: EditorProps['ref']) => {\n const {\n components: {\n 'text-area': { 'min-height': minHeight }\n }\n } = useTheme();\n const [editor, setEditor] = useState<TinymceEditor>();\n const t = useI18n();\n const uid = useUID();\n const labelId = useUID();\n const editorRef = useConsolidatedRef(ref);\n const initialized = useRef(false);\n\n const {\n id = uid,\n toolbar = [],\n label,\n labelHidden,\n info,\n status,\n required,\n disabled,\n readOnly,\n onChange,\n onFocus,\n onBlur,\n onImageAdded,\n onInit,\n defaultValue,\n customComponents = [],\n height = { min: minHeight },\n customActions,\n placeholder,\n ...restProps\n } = props;\n\n const [showPlaceholder, setShowPlaceholder] = useState(() => !defaultValue);\n const formFieldRef = useRef<HTMLElement>(null);\n const value = useRef(defaultValue);\n\n useImperativeHandle<any, EditorState>(\n editorRef,\n () => ({\n focus: () => {\n editor?.focus();\n },\n getPlainText: () => {\n return editor ? editor?.getContent({ format: 'text' }) : '';\n },\n getRichText: () => {\n return editor ? JSON.stringify(editor?.getContent({ format: 'raw' })) : '';\n },\n getHtml: () => {\n return editor ? editor?.getContent({ format: 'html' }) : '';\n },\n clear: () => {\n editor?.setContent('');\n },\n appendImage: ({ src, alt }, imageId) => {\n if (editor) {\n const editorEl = editor.getElement();\n const imageEl = editorEl.querySelector(`#${imageId}`);\n if (imageEl) {\n imageEl.setAttribute('src', src);\n imageEl.setAttribute('alt', alt);\n }\n }\n },\n insertText: (text: string) => {\n editor?.insertContent(text);\n },\n insertHtml: (html: string, overwrite: boolean = false) => {\n if (overwrite) {\n editor?.setContent('');\n }\n editor?.insertContent(html);\n },\n getEditor: () => {\n return editor;\n },\n element: formFieldRef.current || undefined\n }),\n [editor]\n );\n\n useLayoutEffect(() => {\n tinymce\n .init({\n readonly: readOnly || disabled,\n skin: false,\n selector: `#${id}`,\n toolbar: false,\n menubar: false,\n inline: true,\n plugins: 'lists advlist',\n lists_indent_on_tab: true,\n icons: '',\n placeholder,\n init_instance_callback: () => {\n customComponents.forEach(comp => {\n if (!customElements.get(comp.name)) {\n customElements.define(comp.name, comp.customElement);\n }\n });\n },\n custom_elements: `~${customComponents.reduce((prev, { name }, i) => {\n return i === 0 ? name : `${prev},${name}`;\n }, '')}`,\n setup: editorSettings => {\n getTextFormats().forEach((format, i) => {\n editorSettings.addShortcut(\n `meta+alt+${i}`,\n `${t('rte_change_text_format')} ${format.text}`,\n () => {\n editorSettings.execCommand('FormatBlock', false, format.type);\n }\n );\n });\n editorSettings.addShortcut('meta+shift+l', t('rte_toggle_unordered_list'), () => {\n editorSettings.execCommand('InsertUnorderedList');\n });\n editorSettings.addShortcut('alt+m', t('rte_indent_selection'), () => {\n editorSettings.execCommand('Indent');\n });\n editorSettings.addShortcut('alt+shift+m', t('rte_unindent_selection'), () => {\n editorSettings.execCommand('Outdent');\n });\n customActions?.forEach(action => {\n if (action.shortcut) {\n editorSettings.addShortcut(\n action.shortcut.pattern,\n action.shortcut.description,\n () => {\n action.shortcut?.command(editorSettings);\n }\n );\n }\n });\n }\n })\n .then(tinymceEditors => {\n setEditor(tinymceEditors[0]);\n });\n }, []);\n\n useEffect(() => {\n if (!editor || initialized.current) return;\n initialized.current = true;\n onInit?.(editor);\n }, [editor, onInit]);\n\n useEffect(() => {\n if (!editor) return;\n const onEditorChange = () => {\n setShowPlaceholder(!editor?.getContent({ format: 'text' }));\n };\n const onEditorFocus = () => {\n onFocus?.();\n };\n const onEditorBlur = () => {\n onBlur?.();\n };\n editor.on('input', onEditorChange);\n editor.on('focus', onEditorFocus);\n editor.on('blur', onEditorBlur);\n return () => {\n editor.off('input', onEditorChange);\n editor.off('focus', onEditorFocus);\n editor.off('blur', onEditorBlur);\n };\n }, [editor, onFocus, onBlur]);\n\n useAfterInitialEffect(() => {\n editor?.mode.set(readOnly || disabled ? 'readonly' : 'design');\n }, [readOnly, disabled]);\n\n const addImage = (image: File) => {\n if (editor) {\n const imageId = createUID();\n editor.insertContent(`<img src='' id='${imageId}' style=\"max-width: 100%;\"/>`);\n onImageAdded?.(image, imageId);\n }\n };\n\n useEffect(() => {\n const onEditorDrop = (e: DragEvent) => {\n e.preventDefault();\n if (e.dataTransfer) {\n Array.from(e.dataTransfer.files).forEach(file => {\n if (file.type.includes('image')) {\n addImage(file);\n }\n });\n }\n };\n editor?.on('drop', onEditorDrop);\n return () => {\n editor?.off('drop', onEditorDrop);\n };\n }, [editor]);\n\n const renderToolbar = editor && toolbar.length > 0 && !readOnly && !disabled;\n\n return (\n <EditorContext.Provider value={{ addImage, editor: editor || ({} as TinymceEditor) }}>\n <FormField\n as={StyledRichTextFormField}\n toolbar={renderToolbar}\n label={\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events\n <span\n onClick={() => {\n editor?.focus();\n }}\n >\n {label}\n </span>\n }\n labelFor=''\n labelId={labelId}\n labelHidden={labelHidden}\n id={id}\n info={info}\n status={status}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n onFocus={(e: FocusEvent) => {\n if (e.target === formFieldRef.current && !disabled) {\n editor?.focus();\n }\n }}\n ref={formFieldRef}\n tabIndex={disabled ? -1 : undefined}\n >\n <FormControl\n {...restProps}\n ref={editorRef}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n status={status}\n as={StyledRichTextEditor}\n toolbar={renderToolbar}\n >\n <StyledEditorContainer\n readOnly={readOnly}\n onClick={() => {\n if (!disabled) {\n editor?.focus();\n }\n }}\n toolbar={renderToolbar}\n containerHeight={height}\n >\n <StyledHtml\n id={id}\n style={{ outline: 'none', border: 'none' }}\n dangerouslySetInnerHTML={{ __html: value.current || '' }}\n aria-label={`${label}${renderToolbar ? `. ${t('rte_toolbar_instructions')}.` : ''}`}\n as={StyledInnerEditor}\n showPlaceholder={showPlaceholder}\n aria-labelledby={labelId}\n role='textbox'\n />\n </StyledEditorContainer>\n {renderToolbar && (\n <Toolbar features={toolbar} editor={editor} customActions={customActions} />\n )}\n </FormControl>\n </FormField>\n </EditorContext.Provider>\n );\n }\n);\n\nexport default Editor;\n"]}
1
+ {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../../src/components/Editor/Editor.tsx"],"names":[],"mappings":"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","sourcesContent":["import tinymce, { Editor as TinymceEditor, EditorEvent } from 'tinymce/tinymce';\nimport 'tinymce/icons/default';\nimport 'tinymce/themes/silver';\nimport 'tinymce/plugins/advlist';\nimport 'tinymce/plugins/lists';\nimport 'tinymce/plugins/autolink';\nimport 'tinymce/models/dom';\nimport {\n FC,\n forwardRef,\n PropsWithoutRef,\n useEffect,\n useRef,\n useState,\n useLayoutEffect,\n useImperativeHandle,\n FocusEvent\n} from 'react';\nimport styled, { css, DefaultTheme } from 'styled-components';\nimport { compile, serialize, stringify } from 'stylis';\nimport { stripUnit } from 'polished';\n\nimport {\n createUID,\n FormControl,\n FormField,\n ForwardProps,\n useAfterInitialEffect,\n useTheme,\n useUID,\n useI18n,\n useConsolidatedRef,\n defaultThemeProp,\n useAutoResize,\n useConfiguration\n} from '@pega/cosmos-react-core';\nimport { getHtmlStyles } from '@pega/cosmos-react-core/lib/components/HTML/HTML';\nimport {\n createGlobalBodyStyles,\n createGlobalRootStyles,\n globalSpacingStyles\n} from '@pega/cosmos-react-core/lib/styles/GlobalStyle';\n\nimport StyledRichTextEditor, {\n StyledRichTextFormField\n} from '../RichTextEditor/RichTextEditor.styles';\n\nimport Toolbar from './Toolbar/Toolbar';\nimport EditorContext from './Editor.context';\nimport { getTextFormats } from './Toolbar/TextSelect';\nimport { EditorProps, EditorState } from './Editor.types';\nimport ImageEditor, { imgHoverClass } from './ImageEditor';\nimport {\n offscreenSelectionStyles,\n placeholderStyles,\n StyledEditorContainer\n} from './Editor.styles';\n\ntype ImageInfoArray = { id: string; url: string }[];\n\nconst getFileFromUrl = async (url: string, name: string) => {\n const response = await fetch(url);\n const data = await response.blob();\n return new File([data], name, {\n type: data.type\n });\n};\n\nexport const getImageStyles = (theme: DefaultTheme) => {\n return `\n img:hover,\n img.${imgHoverClass} {\n box-shadow: 0 0 0 0.06125rem ${theme.base.palette['primary-background']},\n 0 0 0 0.125rem ${theme.base.palette.interactive}, 0 0 0 0.25rem rgba(0, 118, 209, 0.3);\n }\n `;\n};\n\nexport const StyledInnerEditor = styled.div<{ showPlaceholder: boolean }>(\n ({ theme, showPlaceholder }) => {\n return css`\n ${showPlaceholder &&\n css`\n ::before {\n color: ${theme.base.colors.slate.medium};\n position: absolute;\n content: attr(data-mce-placeholder);\n }\n `}\n `;\n }\n);\n\nStyledInnerEditor.defaultProps = defaultThemeProp;\n\nconst Editor: FC<EditorProps & ForwardProps> = forwardRef(\n (props: PropsWithoutRef<EditorProps>, ref: EditorProps['ref']) => {\n const {\n components: {\n 'text-area': { 'min-height': textAreaMinHeight }\n }\n } = useTheme();\n const theme = useTheme();\n const { styleSheetTarget } = useConfiguration();\n const [editor, setEditor] = useState<TinymceEditor>();\n const [focused, setFocused] = useState(false);\n const t = useI18n();\n const uid = useUID();\n const labelId = useUID();\n const editorRef = useConsolidatedRef(ref);\n const tinyMceRef = useRef<HTMLTextAreaElement>(null);\n const tinyMceContainerRef = useRef<HTMLDivElement>(null);\n const initialized = useRef(false);\n\n const {\n id = uid,\n toolbar = [],\n label,\n labelHidden,\n info,\n status,\n required,\n disabled,\n readOnly,\n onChange,\n onKeyDown,\n onFocus,\n onBlur,\n onImageAdded,\n onInit,\n defaultValue,\n customComponents = [],\n height,\n customActions,\n placeholder,\n children,\n spellcheck = true,\n ...restProps\n } = props;\n const baseHeight: EditorProps['height'] = {\n min: height?.min ?? (stripUnit(textAreaMinHeight) as number) * 16,\n max: height?.max ?? undefined\n };\n const getHeight = (type: 'max' | 'min') => {\n if (typeof baseHeight === 'number') {\n return stripUnit(baseHeight) as number;\n }\n if (baseHeight[type]) {\n return stripUnit(baseHeight[type] as number) as number;\n }\n return undefined;\n };\n\n const imagesEnabled = toolbar.includes('images');\n const maxHeight = getHeight('max');\n const minHeight = getHeight('min');\n const [autoResizeRef, resizeEditor] = useAutoResize<HTMLIFrameElement>(maxHeight, minHeight);\n const formFieldRef = useRef<HTMLElement>(null);\n const value = useRef(defaultValue);\n const renderToolbar = editor && toolbar.length > 0 && !readOnly && !disabled;\n\n const processPastedImgUrls = async (infoArr: ImageInfoArray) => {\n const files = await Promise.all(\n infoArr.map(({ id: imgId, url }) => getFileFromUrl(url, imgId))\n );\n files.forEach((file, i) => {\n onImageAdded?.(file, infoArr[i].id);\n });\n };\n\n const pastePreprocess = (plugin: unknown, args: { content: string }) => {\n const isImg = args.content.includes('<img');\n if (!imagesEnabled && isImg) {\n args.content = args.content.replace(/<img(.*)\\/>/g, '');\n }\n if (imagesEnabled && isImg) {\n const pastedHtml: HTMLElement = new DOMParser().parseFromString(\n args.content,\n 'text/html'\n ).body;\n const imgInfo: ImageInfoArray = [];\n pastedHtml.querySelectorAll('img').forEach(imgEl => {\n const imgId = createUID();\n const url = imgEl.src;\n imgInfo.push({ id: imgId, url });\n imgEl.setAttribute('id', imgId);\n imgEl.setAttribute('src', '');\n });\n args.content = pastedHtml.innerHTML;\n processPastedImgUrls(imgInfo);\n }\n };\n\n useImperativeHandle<any, EditorState>(\n editorRef,\n () => ({\n focus: () => {\n editor?.focus();\n },\n getPlainText: () => {\n return editor ? editor.getContent({ format: 'text' }) : '';\n },\n getRichText: () => {\n return editor ? JSON.stringify(editor.getContent({ format: 'raw' })) : '';\n },\n getHtml: () => {\n return editor ? editor.getContent({ format: 'html' }) : '';\n },\n clear: () => {\n editor?.setContent('');\n },\n appendImage: ({ src, alt }, imageId) => {\n if (editor) {\n const editorEl = editor.getDoc();\n const imageEl = editorEl.querySelector(`#${imageId}`);\n if (imageEl) {\n imageEl.setAttribute('src', src);\n imageEl.setAttribute('alt', alt);\n resizeEditor();\n }\n }\n },\n insertText: (text: string) => {\n editor?.insertContent(text);\n },\n insertHtml: (html: string, overwrite: boolean = false) => {\n if (overwrite) {\n editor?.setContent('');\n }\n editor?.insertContent(html);\n },\n getEditor: () => {\n return editor;\n },\n element: formFieldRef.current || undefined\n }),\n [editor]\n );\n\n useLayoutEffect(() => {\n if (!tinyMceRef.current || !tinyMceContainerRef.current) return;\n const styles = serialize(compile(getHtmlStyles(theme)), stringify);\n const imageStyles = serialize(compile(getImageStyles(theme)), stringify);\n tinymce\n .init({\n readonly: readOnly || disabled,\n skin: false,\n target: tinyMceRef.current,\n toolbar: false,\n menubar: false,\n plugins: 'lists advlist autolink',\n paste_data_images: true,\n lists_indent_on_tab: true,\n icons: '',\n branding: false,\n elementpath: false,\n placeholder,\n content_css: false,\n browser_spellcheck: spellcheck,\n paste_preprocess: pastePreprocess,\n content_style: `${createGlobalRootStyles(\n theme\n )} ${globalSpacingStyles} ${createGlobalBodyStyles(\n theme\n )} body { min-height: 3rem; padding: ${\n toolbar.length > 0 && !readOnly ? theme.base.spacing : 0\n }; } html { overflow: hidden; } ${offscreenSelectionStyles} ${placeholderStyles} ${imageStyles} ${styles}`,\n init_instance_callback: initializedEditor => {\n const iframeWindow = (\n tinyMceContainerRef.current?.querySelector('iframe') as HTMLIFrameElement\n ).contentWindow;\n const editorCustomElements = iframeWindow?.customElements;\n if (editorCustomElements) {\n customComponents.forEach(\n ({ name, createCustomElement: customElementCreator, style }) => {\n if (!editorCustomElements.get(name)) {\n editorCustomElements.define(\n name,\n customElementCreator(iframeWindow as unknown as typeof globalThis)\n );\n }\n if (style) {\n const styleEl = document.createElement('style');\n styleEl.innerText = style;\n initializedEditor.getDoc().head.appendChild(styleEl);\n }\n }\n );\n }\n },\n extended_valid_elements: `${customComponents\n .map(\n comp =>\n `${comp.name}${\n comp.extensionAttributes ? `[${comp.extensionAttributes.join('|')}]` : ''\n }`\n )\n .join(',')}`,\n custom_elements: `~${customComponents.map(comp => comp.name).join('~,')}`,\n setup: editorSettings => {\n editorSettings.on('keydown', e => {\n onKeyDown?.(e);\n });\n getTextFormats().forEach((format, i) => {\n editorSettings.addShortcut(\n `meta+alt+${i}`,\n `${t('rte_change_text_format')} ${format.text}`,\n () => {\n editorSettings.execCommand('FormatBlock', false, format.type);\n }\n );\n });\n editorSettings.addShortcut('meta+shift+b', t('rte_bold'), () => {\n editorSettings.execCommand('Bold');\n });\n editorSettings.addShortcut('meta+shift+i', t('rte_italic'), () => {\n editorSettings.execCommand('Italic');\n });\n editorSettings.addShortcut('meta+shift+x', t('rte_strike_through'), () => {\n editorSettings.execCommand('Strikethrough');\n });\n editorSettings.addShortcut('meta+shift+l', t('rte_toggle_unordered_list'), () => {\n editorSettings.execCommand('InsertUnorderedList');\n });\n editorSettings.addShortcut('alt+m', t('rte_indent_selection'), () => {\n editorSettings.execCommand('Indent');\n });\n editorSettings.addShortcut('alt+shift+m', t('rte_unindent_selection'), () => {\n editorSettings.execCommand('Outdent');\n });\n customActions?.forEach(action => {\n if (action.shortcut) {\n editorSettings.addShortcut(\n action.shortcut.pattern,\n action.shortcut.description,\n () => {\n action.shortcut?.command(editorSettings);\n }\n );\n }\n });\n }\n })\n .then(tinymceEditors => {\n setEditor(tinymceEditors[0]);\n tinymceEditors[0].editorContainer?.setAttribute('style', '');\n const iframe = tinyMceContainerRef.current?.querySelector('iframe');\n if (iframe) {\n const globalStyles =\n styleSheetTarget?.querySelectorAll('[data-cosmos-global-style]') ??\n ([] as HTMLElement[]);\n const extraStyles =\n document.querySelectorAll('[data-cosmos-global-style]') ?? ([] as HTMLElement[]);\n const iframeContentHead = iframe?.contentDocument?.querySelector('head');\n [...globalStyles, ...extraStyles].forEach(sheet => {\n iframeContentHead?.appendChild(sheet.cloneNode(true));\n });\n autoResizeRef.current = iframe;\n resizeEditor();\n }\n });\n }, []);\n\n useEffect(() => {\n if (editor) {\n editor.options.set('paste_preprocess', pastePreprocess);\n }\n }, [imagesEnabled]);\n\n useEffect(() => {\n if (!editor || initialized.current) return;\n initialized.current = true;\n onInit?.(editor);\n }, [editor, onInit]);\n\n useEffect(() => {\n if (!editor) return;\n const onChangeEvents = ['keyup', 'FormatApply', 'FormatRemove', 'ExecCommand'];\n const onEditorKeyDown = (event: EditorEvent<KeyboardEvent>) => {\n resizeEditor();\n if (event.key === 'Enter') {\n editor.selection.getNode().scrollIntoView(false);\n }\n };\n const onEditorChange = () => {\n onChange?.(editor);\n };\n const onEditorFocus = () => {\n setFocused(true);\n onFocus?.();\n };\n const onEditorBlur = () => {\n setFocused(false);\n onBlur?.();\n };\n onChangeEvents.forEach(event => {\n editor.on(event, onEditorChange);\n });\n editor.on('keydown', onEditorKeyDown);\n editor.on('paste', resizeEditor);\n editor.on('focus', onEditorFocus);\n editor.on('blur', onEditorBlur);\n return () => {\n onChangeEvents.forEach(event => {\n editor.off(event, onEditorChange);\n });\n editor.off('keydown', onEditorKeyDown);\n editor.off('paste', resizeEditor);\n editor.off('focus', onEditorFocus);\n editor.off('blur', onEditorBlur);\n };\n }, [editor, onFocus, onBlur]);\n\n useAfterInitialEffect(() => {\n editor?.mode.set(readOnly || disabled ? 'readonly' : 'design');\n }, [readOnly, disabled]);\n\n const addImage = (image: File) => {\n if (editor) {\n const imageId = createUID();\n editor.insertContent(`<img src='' id='${imageId}' style=\"max-width: 100%;\"/>`);\n onImageAdded?.(image, imageId);\n }\n };\n\n useEffect(() => {\n const onEditorDrop = (e: DragEvent) => {\n e.preventDefault();\n if (e.dataTransfer) {\n Array.from(e.dataTransfer.files).forEach(file => {\n if (file.type.includes('image') && imagesEnabled) {\n addImage(file);\n }\n });\n }\n };\n editor?.on('drop', onEditorDrop);\n const body = editor?.getDoc().body;\n const resizeObserver = new ResizeObserver(() => {\n resizeEditor();\n });\n if (body) {\n resizeObserver.observe(body);\n }\n return () => {\n editor?.off('drop', onEditorDrop);\n resizeObserver.disconnect();\n };\n }, [editor, resizeEditor]);\n\n return (\n <EditorContext.Provider value={{ addImage, editor: editor || ({} as TinymceEditor) }}>\n <FormField\n as={StyledRichTextFormField}\n toolbar={renderToolbar}\n label={\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events\n <span\n onClick={() => {\n editor?.focus();\n }}\n >\n {label}\n </span>\n }\n labelFor=''\n labelId={labelId}\n labelHidden={labelHidden}\n id={id}\n info={info}\n status={status}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n onFocus={(e: FocusEvent) => {\n if (e.target === formFieldRef.current && !disabled) {\n editor?.focus();\n }\n }}\n ref={formFieldRef}\n tabIndex={disabled ? -1 : undefined}\n >\n <FormControl\n {...restProps}\n ref={editorRef}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n status={status}\n as={StyledRichTextEditor}\n toolbar={renderToolbar}\n focused={focused}\n >\n <StyledEditorContainer\n onClick={() => {\n if (!disabled) {\n editor?.focus();\n }\n }}\n ref={tinyMceContainerRef}\n >\n <textarea\n id={id}\n value={value.current || ''}\n onChange={() => {}}\n aria-label={`${label}${renderToolbar ? `. ${t('rte_toolbar_instructions')}.` : ''}`}\n aria-labelledby={labelId}\n ref={tinyMceRef}\n />\n {tinyMceContainerRef.current && editor && !readOnly && (\n <ImageEditor\n editor={editor}\n editorEl={tinyMceContainerRef.current}\n onChange={() => onChange?.(editor)}\n />\n )}\n </StyledEditorContainer>\n {renderToolbar && (\n <Toolbar features={toolbar} editor={editor} customActions={customActions} />\n )}\n </FormControl>\n </FormField>\n {children}\n </EditorContext.Provider>\n );\n }\n);\n\nexport default Editor;\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const offscreenSelectionStyles = "\n .mce-offscreen-selection {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n whiteSpace: nowrap;\n width: 1px;\n }\n";
2
+ export declare const placeholderStyles = "\n .mce-content-body[data-mce-placeholder] {\n position: relative;\n }\n .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before {\n cursor: text;\n color: rgb(117, 117, 117);\n content: attr(data-mce-placeholder);\n position: absolute;\n }\n";
3
+ export declare const StyledEditorContainer: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, {}, never>;
4
+ //# sourceMappingURL=Editor.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Editor.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Editor/Editor.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,oOAYpC,CAAC;AAEF,eAAO,MAAM,iBAAiB,yRAU7B,CAAC;AAEF,eAAO,MAAM,qBAAqB,yGAchC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import styled, { css } from 'styled-components';
2
+ export const offscreenSelectionStyles = `
3
+ .mce-offscreen-selection {
4
+ border: 0;
5
+ clip: rect(0 0 0 0);
6
+ height: 1px;
7
+ margin: -1px;
8
+ overflow: hidden;
9
+ padding: 0;
10
+ position: absolute;
11
+ whiteSpace: nowrap;
12
+ width: 1px;
13
+ }
14
+ `;
15
+ export const placeholderStyles = `
16
+ .mce-content-body[data-mce-placeholder] {
17
+ position: relative;
18
+ }
19
+ .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before {
20
+ cursor: text;
21
+ color: rgb(117, 117, 117);
22
+ content: attr(data-mce-placeholder);
23
+ position: absolute;
24
+ }
25
+ `;
26
+ export const StyledEditorContainer = styled.div(() => {
27
+ return css `
28
+ &:hover {
29
+ cursor: text;
30
+ }
31
+
32
+ iframe {
33
+ width: 100%;
34
+ }
35
+
36
+ .tox-statusbar {
37
+ display: none !important;
38
+ }
39
+ `;
40
+ });
41
+ //# sourceMappingURL=Editor.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Editor.styles.js","sourceRoot":"","sources":["../../../src/components/Editor/Editor.styles.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;CAYvC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;CAUhC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;IACnD,OAAO,GAAG,CAAA;;;;;;;;;;;;GAYT,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import styled, { css } from 'styled-components';\n\nexport const offscreenSelectionStyles = `\n .mce-offscreen-selection {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n whiteSpace: nowrap;\n width: 1px;\n }\n`;\n\nexport const placeholderStyles = `\n .mce-content-body[data-mce-placeholder] {\n position: relative;\n }\n .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before {\n cursor: text;\n color: rgb(117, 117, 117);\n content: attr(data-mce-placeholder);\n position: absolute;\n }\n`;\n\nexport const StyledEditorContainer = styled.div(() => {\n return css`\n &:hover {\n cursor: text;\n }\n\n iframe {\n width: 100%;\n }\n\n .tox-statusbar {\n display: none !important;\n }\n `;\n});\n"]}
@@ -1,4 +1,4 @@
1
- import { Ref } from 'react';
1
+ import { ReactNode, Ref, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent } from 'react';
2
2
  import { Editor as TinymceEditor } from 'tinymce/tinymce';
3
3
  import { Action, BaseProps, FormControlProps } from '@pega/cosmos-react-core';
4
4
  import { Features } from '../RichTextEditor/Toolbar/Toolbar.types';
@@ -10,7 +10,7 @@ export declare type EditorState = RichTextEditorState & {
10
10
  export declare type CustomAction = {
11
11
  text: Action['text'];
12
12
  icon: NonNullable<Action['icon']>;
13
- onMouseDown: () => void;
13
+ onMouseDown: (e: ReactMouseEvent | ReactKeyboardEvent) => void;
14
14
  active?: (editor: TinymceEditor) => void;
15
15
  shortcut?: {
16
16
  pattern: string;
@@ -19,14 +19,20 @@ export declare type CustomAction = {
19
19
  };
20
20
  };
21
21
  export declare type CustomComponent = {
22
- customElement: CustomElementConstructor;
22
+ createCustomElement: (window: typeof globalThis) => CustomElementConstructor;
23
23
  name: string;
24
+ extensionAttributes?: string[];
25
+ style?: string;
24
26
  };
25
27
  export interface EditorProps extends FormControlProps, BaseProps {
26
28
  /** An array of strings that activate features on the toolbar */
27
29
  toolbar?: Features[];
30
+ /** Children content */
31
+ children?: ReactNode;
28
32
  /** A callback that supplies an object with functions that can manipulate the editor and retrieve it's content/state */
29
- onChange?: () => void;
33
+ onChange?: (editor?: TinymceEditor) => void;
34
+ /** KeyDown event custom handlers for the editor */
35
+ onKeyDown?: (event?: KeyboardEvent) => void;
30
36
  /** A callback that runs if the editor is focused */
31
37
  onFocus?: () => void;
32
38
  /** A callback that runs if the editor loses focus */
@@ -42,14 +48,19 @@ export interface EditorProps extends FormControlProps, BaseProps {
42
48
  /** Will automatically focus the RTE on render if true */
43
49
  autoFocus?: boolean;
44
50
  /** Sets the height for the RTE. If no max height is set the RTE will continue to expand, otherwise an overflow will be applied */
45
- height?: string | {
46
- min?: string;
47
- max?: string;
51
+ height?: {
52
+ min?: number;
53
+ max?: number;
48
54
  };
49
55
  /** An array of custom components, custom components must use web component API */
50
56
  customComponents?: CustomComponent[];
51
57
  /** An array of custom buttons to be inserted into the toolbar */
52
58
  customActions?: CustomAction[];
59
+ /**
60
+ * Enables browser spellcheck.
61
+ * @default true
62
+ */
63
+ spellcheck?: boolean;
53
64
  /** Handle to the state. */
54
65
  ref?: Ref<EditorState>;
55
66
  }