@contentful/field-editor-markdown 1.4.0 → 1.5.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.
@@ -160,6 +160,7 @@ function MarkdownEditor(props) {
160
160
  value: currentValue,
161
161
  previewComponents: props.previewComponents
162
162
  })), _react.createElement(_MarkdownBottomBar.MarkdownBottomBar, null, _react.createElement(_MarkdownBottomBar.MarkdownHelp, {
163
+ mode: selectedTab,
163
164
  onClick: openMarkdownHelp
164
165
  })), _react.createElement(_MarkdownConstraints.MarkdownConstraints, {
165
166
  sdk: props.sdk,
@@ -168,7 +169,7 @@ function MarkdownEditor(props) {
168
169
  }
169
170
  function MarkdownEditorConnected(props) {
170
171
  return _react.createElement(_fieldeditorshared.FieldConnector, {
171
- throttle: 300,
172
+ debounce: 300,
172
173
  field: props.sdk.field,
173
174
  isInitiallyDisabled: props.isInitiallyDisabled
174
175
  }, ({ value , disabled , setValue , externalReset })=>{
@@ -67,6 +67,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
67
67
  }
68
68
  return newObj;
69
69
  }
70
+ const SANITIZE_LINK = 'https://en.wikipedia.org/wiki/HTML_sanitization';
70
71
  const styles = {
71
72
  root: (0, _emotion.css)({
72
73
  display: 'flex',
@@ -80,7 +81,7 @@ const styles = {
80
81
  help: (0, _emotion.css)({
81
82
  color: _f36tokens.default.gray700,
82
83
  fontSize: _f36tokens.default.fontSizeS,
83
- button: {
84
+ '& button, & a': {
84
85
  fontSize: _f36tokens.default.fontSizeS,
85
86
  lineHeight: 'inherit'
86
87
  }
@@ -92,17 +93,49 @@ function MarkdownCounter(props) {
92
93
  className: styles.help
93
94
  }, props.words, " ", props.words !== 1 ? 'words' : 'word', ", ", props.characters, ' ', props.characters !== 1 ? 'characters' : 'character');
94
95
  }
96
+ function SanitizeMessage() {
97
+ return _react.createElement("span", null, "The preview of the content in this field will be sanitized.", ' ', _react.createElement(_f36components.TextLink, {
98
+ as: "a",
99
+ target: "_blank",
100
+ rel: "noopener noreferrer",
101
+ href: SANITIZE_LINK
102
+ }, "Learn more."));
103
+ }
104
+ function CheatSheetMessage({ onClick }) {
105
+ return _react.createElement("span", null, "Format your text like a pro with the", ' ', _react.createElement(_f36components.TextLink, {
106
+ as: "button",
107
+ testId: "open-markdown-cheatsheet-button",
108
+ onClick: onClick
109
+ }, "markdown cheatsheet"), ".");
110
+ }
95
111
  function MarkdownHelp(props) {
112
+ let content;
113
+ switch(props.mode){
114
+ case 'preview':
115
+ content = _react.createElement(SanitizeMessage, null);
116
+ break;
117
+ case 'editor':
118
+ content = _react.createElement(CheatSheetMessage, {
119
+ onClick: props.onClick
120
+ });
121
+ break;
122
+ case 'zen':
123
+ content = _react.createElement(_f36components.Stack, {
124
+ flexDirection: "column",
125
+ spacing: "spacing2Xs",
126
+ alignItems: "flex-start"
127
+ }, _react.createElement(CheatSheetMessage, {
128
+ onClick: props.onClick
129
+ }), _react.createElement(SanitizeMessage, null));
130
+ break;
131
+ default:
132
+ content = null;
133
+ throw new Error(`Invalid HelpMode provided in MarkdownHelp: ${props.mode}`);
134
+ }
96
135
  return _react.createElement(_f36components.Paragraph, {
97
136
  marginBottom: "none",
98
137
  className: styles.help
99
- }, "Format your text like a pro with the", ' ', _react.createElement(_f36components.TextLink, {
100
- as: "button",
101
- testId: "open-markdown-cheatsheet-button",
102
- onClick: ()=>{
103
- props.onClick();
104
- }
105
- }, "markdown cheatsheet"), ".");
138
+ }, content);
106
139
  }
107
140
  function MarkdownBottomBar(props) {
108
141
  return _react.createElement("div", {
@@ -11,9 +11,9 @@ Object.defineProperty(exports, "default", {
11
11
  const _react = _interop_require_wildcard(require("react"));
12
12
  const _reactmarkdown = _interop_require_default(require("react-markdown"));
13
13
  const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
14
- const _dompurify = _interop_require_default(require("dompurify"));
15
14
  const _emotion = require("emotion");
16
15
  const _rehyperaw = _interop_require_default(require("rehype-raw"));
16
+ const _rehypesanitize = _interop_require_default(require("rehype-sanitize"));
17
17
  const _remarkgfm = _interop_require_default(require("remark-gfm"));
18
18
  const _replaceMailtoAmp = require("../utils/replaceMailtoAmp");
19
19
  function _interop_require_default(obj) {
@@ -227,18 +227,14 @@ const MarkdownPreview = _react.memo((props)=>{
227
227
  const className = (0, _emotion.cx)(props.minHeight !== undefined ? (0, _emotion.css)({
228
228
  minHeight: props.minHeight
229
229
  }) : undefined, props.mode === 'default' ? styles.framed : styles.zen, props.direction === 'rtl' ? styles.rtl : undefined);
230
- const cleanHTML = _react.useMemo(()=>{
231
- return (0, _replaceMailtoAmp.replaceMailtoAmp)(_dompurify.default.sanitize(props.value));
232
- }, [
233
- props.value
234
- ]);
235
230
  return _react.createElement("div", {
236
231
  className: className,
237
232
  "data-test-id": "markdown-preview"
238
233
  }, _react.createElement(_reactmarkdown.default, {
239
234
  className: styles.root,
240
235
  rehypePlugins: [
241
- _rehyperaw.default
236
+ _rehyperaw.default,
237
+ _rehypesanitize.default
242
238
  ],
243
239
  remarkPlugins: [
244
240
  _remarkgfm.default
@@ -252,7 +248,7 @@ const MarkdownPreview = _react.memo((props)=>{
252
248
  Embedly: props.previewComponents?.embedly
253
249
  })
254
250
  }
255
- }, cleanHTML));
251
+ }, (0, _replaceMailtoAmp.replaceMailtoAmp)(props.value)));
256
252
  });
257
253
  MarkdownPreview.displayName = 'MarkdownPreview';
258
254
  const _default = MarkdownPreview;
@@ -105,6 +105,7 @@ const ToolbarButton = _react.forwardRef((props, ref)=>{
105
105
  const { tooltip , onClick , children , className , variant ='transparent' , tooltipPlace ='top' , isDisabled =false , ...otherProps } = props;
106
106
  return _react.createElement(_f36components.Tooltip, {
107
107
  className: styles.tooltip,
108
+ usePortal: true,
108
109
  placement: tooltipPlace,
109
110
  content: tooltip
110
111
  }, _react.createElement(_f36components.IconButton, {
@@ -337,8 +338,11 @@ function ZenMarkdownToolbar(props) {
337
338
  return _react.createElement("div", {
338
339
  className: styles.root
339
340
  }, _react.createElement(_f36components.Flex, {
340
- justifyContent: "space-between"
341
- }, _react.createElement(_f36components.Flex, null, _react.createElement(MainButtons, props), _react.createElement(AdditionalButtons, props)), _react.createElement(_f36components.Flex, null, _react.createElement(_InsertLinkSelector.InsertLinkSelector, {
341
+ justifyContent: "space-between",
342
+ alignItems: "flex-start"
343
+ }, _react.createElement(_f36components.Flex, {
344
+ flexWrap: "wrap"
345
+ }, _react.createElement(MainButtons, props), _react.createElement(AdditionalButtons, props)), _react.createElement(_f36components.Flex, null, _react.createElement(_InsertLinkSelector.InsertLinkSelector, {
342
346
  disabled: props.disabled,
343
347
  onSelectExisting: props.actions.linkExistingMedia,
344
348
  onAddNew: props.actions.addNewMedia,
@@ -17,6 +17,7 @@ _export(exports, {
17
17
  }
18
18
  });
19
19
  const _react = _interop_require_wildcard(require("react"));
20
+ const _f36components = require("@contentful/f36-components");
20
21
  const _f36icons = require("@contentful/f36-icons");
21
22
  const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
22
23
  const _emotion = require("emotion");
@@ -74,73 +75,59 @@ function _interop_require_wildcard(obj, nodeInterop) {
74
75
  const MarkdownPreview = _react.lazy(()=>Promise.resolve().then(()=>_interop_require_wildcard(require("../components/MarkdownPreview"))));
75
76
  const styles = {
76
77
  root: (0, _emotion.css)({
77
- position: 'fixed',
78
- left: 0,
79
- right: 0,
80
- top: 0,
81
- bottom: 0
78
+ display: 'grid',
79
+ gridTemplateRows: 'min-content 1fr min-content',
80
+ gridTemplateColumns: '1fr 1px 1fr',
81
+ height: '85vh'
82
82
  }),
83
83
  topSplit: (0, _emotion.css)({
84
- position: 'fixed',
85
- top: 0,
86
- height: '48px',
87
- left: 0,
88
- right: 0
84
+ gridRow: '1 / 2',
85
+ gridColumn: '1 / 4'
89
86
  }),
90
87
  bottomSplit: (0, _emotion.css)({
91
- position: 'fixed',
92
- bottom: 0,
93
- left: 0,
94
- right: 0,
95
- height: '36px'
88
+ gridRow: '3 / 4',
89
+ gridColumn: '1 / 4'
96
90
  }),
97
91
  editorSplit: (0, _emotion.css)({
98
- width: '50%',
99
- position: 'fixed',
100
- top: '48px',
101
- left: 0,
102
- bottom: '36px',
103
- overflowX: 'hidden',
92
+ gridRow: '2 / 3',
93
+ gridColumn: '1 / 2',
104
94
  overflowY: 'scroll'
105
95
  }),
106
96
  editorSplitFullscreen: (0, _emotion.css)({
107
- left: 0,
108
- right: 0,
109
- width: '100%'
97
+ gridRow: '2 / 3',
98
+ gridColumn: '1 / 4',
99
+ overflowY: 'scroll'
110
100
  }),
111
101
  previewSplit: (0, _emotion.css)({
112
- width: '50%',
113
- position: 'fixed',
114
- top: '48px',
115
- right: 0,
116
- bottom: '36px',
117
- overflowX: 'hidden',
102
+ gridRow: '2 / 3',
103
+ gridColumn: '3 / 4',
118
104
  overflowY: 'scroll'
119
105
  }),
120
106
  separator: (0, _emotion.css)({
121
- position: 'fixed',
122
- top: '48px',
123
- bottom: '36px',
124
- width: '1px',
125
- background: _f36tokens.default.gray400,
126
- left: '50%'
107
+ gridRow: '2 / 3',
108
+ gridColumn: '2 / 3',
109
+ backgroundColor: _f36tokens.default.gray400,
110
+ width: '1px'
127
111
  }),
128
112
  button: (0, _emotion.css)({
129
- position: 'fixed',
130
113
  cursor: 'pointer',
131
114
  zIndex: 105,
132
- top: '49%',
133
115
  height: '30px',
134
116
  backgroundColor: _f36tokens.default.gray100,
135
117
  border: `1px solid ${_f36tokens.default.gray400}`,
136
118
  padding: 0
137
119
  }),
138
120
  hideButton: (0, _emotion.css)({
139
- left: '50%'
121
+ gridRow: '2 / 3',
122
+ gridColumn: '2 / 3',
123
+ justifySelf: 'end',
124
+ alignSelf: 'center'
140
125
  }),
141
126
  showButton: (0, _emotion.css)({
142
- right: 0,
143
- borderRightWidth: 0
127
+ gridRow: '2 / 3',
128
+ gridColumn: '3 / 4',
129
+ justifySelf: 'end',
130
+ alignSelf: 'center'
144
131
  }),
145
132
  icon: (0, _emotion.css)({
146
133
  verticalAlign: 'middle'
@@ -177,17 +164,17 @@ const ZenModeModalDialog = (props)=>{
177
164
  });
178
165
  };
179
166
  const direction = props.sdk.locales.direction[props.locale] ?? 'ltr';
180
- return _react.createElement("div", {
167
+ return _react.createElement(_f36components.Grid, {
181
168
  className: styles.root,
182
169
  "data-test-id": "zen-mode-markdown-editor"
183
- }, _react.createElement("div", {
170
+ }, _react.createElement(_f36components.Grid.Item, {
184
171
  className: styles.topSplit
185
172
  }, _react.createElement(_MarkdownToolbar.MarkdownToolbar, {
186
173
  mode: "zen",
187
174
  disabled: false,
188
175
  canUploadAssets: false,
189
176
  actions: actions
190
- })), _react.createElement("div", {
177
+ })), _react.createElement(_f36components.Grid.Item, {
191
178
  className: (0, _emotion.cx)(styles.editorSplit, {
192
179
  [styles.editorSplitFullscreen]: showPreview === false
193
180
  })
@@ -206,7 +193,7 @@ const ZenModeModalDialog = (props)=>{
206
193
  props.saveValueToSDK(value);
207
194
  });
208
195
  }
209
- })), showPreview && _react.createElement("div", {
196
+ })), showPreview && _react.createElement(_f36components.Grid.Item, {
210
197
  className: styles.previewSplit
211
198
  }, _react.createElement(_react.Suspense, {
212
199
  fallback: _react.createElement(_MarkdownPreviewSkeleton.default, null)
@@ -215,7 +202,7 @@ const ZenModeModalDialog = (props)=>{
215
202
  mode: "zen",
216
203
  value: currentValue,
217
204
  previewComponents: props.previewComponents
218
- }))), showPreview && _react.createElement("div", {
205
+ }))), showPreview && _react.createElement(_f36components.Grid.Item, {
219
206
  className: styles.separator
220
207
  }), showPreview && _react.createElement("button", {
221
208
  className: (0, _emotion.cx)(styles.button, styles.hideButton),
@@ -237,9 +224,10 @@ const ZenModeModalDialog = (props)=>{
237
224
  variant: "muted",
238
225
  size: "tiny",
239
226
  className: styles.icon
240
- })), _react.createElement("div", {
227
+ })), _react.createElement(_f36components.Grid.Item, {
241
228
  className: styles.bottomSplit
242
229
  }, _react.createElement(_MarkdownBottomBar.MarkdownBottomBar, null, _react.createElement(_MarkdownBottomBar.MarkdownHelp, {
230
+ mode: "zen",
243
231
  onClick: ()=>{
244
232
  (0, _CheatsheetModalDialog.openCheatsheetModal)(props.sdk.dialogs);
245
233
  }
@@ -247,10 +235,9 @@ const ZenModeModalDialog = (props)=>{
247
235
  };
248
236
  const openZenMode = (dialogs, options)=>{
249
237
  return dialogs.openCurrent({
250
- width: 'zen',
238
+ width: 'fullWidth',
251
239
  shouldCloseOnEscapePress: false,
252
- minHeight: '100vh',
253
- shouldCloseOnOverlayClick: false,
240
+ shouldCloseOnOverlayClick: true,
254
241
  parameters: {
255
242
  type: _types.MarkdownDialogType.zenMode,
256
243
  initialValue: options.initialValue,
@@ -98,6 +98,7 @@ export function MarkdownEditor(props) {
98
98
  value: currentValue,
99
99
  previewComponents: props.previewComponents
100
100
  })), React.createElement(MarkdownBottomBar, null, React.createElement(MarkdownHelp, {
101
+ mode: selectedTab,
101
102
  onClick: openMarkdownHelp
102
103
  })), React.createElement(MarkdownConstraints, {
103
104
  sdk: props.sdk,
@@ -106,7 +107,7 @@ export function MarkdownEditor(props) {
106
107
  }
107
108
  export function MarkdownEditorConnected(props) {
108
109
  return React.createElement(FieldConnector, {
109
- throttle: 300,
110
+ debounce: 300,
110
111
  field: props.sdk.field,
111
112
  isInitiallyDisabled: props.isInitiallyDisabled
112
113
  }, ({ value , disabled , setValue , externalReset })=>{
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
- import { Paragraph, TextLink } from '@contentful/f36-components';
2
+ import { Paragraph, Stack, TextLink } from '@contentful/f36-components';
3
3
  import tokens from '@contentful/f36-tokens';
4
4
  import { css } from 'emotion';
5
+ const SANITIZE_LINK = 'https://en.wikipedia.org/wiki/HTML_sanitization';
5
6
  const styles = {
6
7
  root: css({
7
8
  display: 'flex',
@@ -15,7 +16,7 @@ const styles = {
15
16
  help: css({
16
17
  color: tokens.gray700,
17
18
  fontSize: tokens.fontSizeS,
18
- button: {
19
+ '& button, & a': {
19
20
  fontSize: tokens.fontSizeS,
20
21
  lineHeight: 'inherit'
21
22
  }
@@ -27,17 +28,49 @@ export function MarkdownCounter(props) {
27
28
  className: styles.help
28
29
  }, props.words, " ", props.words !== 1 ? 'words' : 'word', ", ", props.characters, ' ', props.characters !== 1 ? 'characters' : 'character');
29
30
  }
31
+ function SanitizeMessage() {
32
+ return React.createElement("span", null, "The preview of the content in this field will be sanitized.", ' ', React.createElement(TextLink, {
33
+ as: "a",
34
+ target: "_blank",
35
+ rel: "noopener noreferrer",
36
+ href: SANITIZE_LINK
37
+ }, "Learn more."));
38
+ }
39
+ function CheatSheetMessage({ onClick }) {
40
+ return React.createElement("span", null, "Format your text like a pro with the", ' ', React.createElement(TextLink, {
41
+ as: "button",
42
+ testId: "open-markdown-cheatsheet-button",
43
+ onClick: onClick
44
+ }, "markdown cheatsheet"), ".");
45
+ }
30
46
  export function MarkdownHelp(props) {
47
+ let content;
48
+ switch(props.mode){
49
+ case 'preview':
50
+ content = React.createElement(SanitizeMessage, null);
51
+ break;
52
+ case 'editor':
53
+ content = React.createElement(CheatSheetMessage, {
54
+ onClick: props.onClick
55
+ });
56
+ break;
57
+ case 'zen':
58
+ content = React.createElement(Stack, {
59
+ flexDirection: "column",
60
+ spacing: "spacing2Xs",
61
+ alignItems: "flex-start"
62
+ }, React.createElement(CheatSheetMessage, {
63
+ onClick: props.onClick
64
+ }), React.createElement(SanitizeMessage, null));
65
+ break;
66
+ default:
67
+ content = null;
68
+ throw new Error(`Invalid HelpMode provided in MarkdownHelp: ${props.mode}`);
69
+ }
31
70
  return React.createElement(Paragraph, {
32
71
  marginBottom: "none",
33
72
  className: styles.help
34
- }, "Format your text like a pro with the", ' ', React.createElement(TextLink, {
35
- as: "button",
36
- testId: "open-markdown-cheatsheet-button",
37
- onClick: ()=>{
38
- props.onClick();
39
- }
40
- }, "markdown cheatsheet"), ".");
73
+ }, content);
41
74
  }
42
75
  export function MarkdownBottomBar(props) {
43
76
  return React.createElement("div", {
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import ReactMarkdown from 'react-markdown';
3
3
  import tokens from '@contentful/f36-tokens';
4
- import DOMPurify from 'dompurify';
5
4
  import { css, cx } from 'emotion';
6
5
  import rehypeRaw from 'rehype-raw';
6
+ import rehypeSanitize from 'rehype-sanitize';
7
7
  import remarkGfm from 'remark-gfm';
8
8
  import { replaceMailtoAmp } from '../utils/replaceMailtoAmp';
9
9
  const styles = {
@@ -173,18 +173,14 @@ const MarkdownPreview = React.memo((props)=>{
173
173
  const className = cx(props.minHeight !== undefined ? css({
174
174
  minHeight: props.minHeight
175
175
  }) : undefined, props.mode === 'default' ? styles.framed : styles.zen, props.direction === 'rtl' ? styles.rtl : undefined);
176
- const cleanHTML = React.useMemo(()=>{
177
- return replaceMailtoAmp(DOMPurify.sanitize(props.value));
178
- }, [
179
- props.value
180
- ]);
181
176
  return React.createElement("div", {
182
177
  className: className,
183
178
  "data-test-id": "markdown-preview"
184
179
  }, React.createElement(ReactMarkdown, {
185
180
  className: styles.root,
186
181
  rehypePlugins: [
187
- rehypeRaw
182
+ rehypeRaw,
183
+ rehypeSanitize
188
184
  ],
189
185
  remarkPlugins: [
190
186
  remarkGfm
@@ -198,7 +194,7 @@ const MarkdownPreview = React.memo((props)=>{
198
194
  Embedly: props.previewComponents?.embedly
199
195
  })
200
196
  }
201
- }, cleanHTML));
197
+ }, replaceMailtoAmp(props.value)));
202
198
  });
203
199
  MarkdownPreview.displayName = 'MarkdownPreview';
204
200
  export default MarkdownPreview;
@@ -40,6 +40,7 @@ const ToolbarButton = React.forwardRef((props, ref)=>{
40
40
  const { tooltip , onClick , children , className , variant ='transparent' , tooltipPlace ='top' , isDisabled =false , ...otherProps } = props;
41
41
  return React.createElement(Tooltip, {
42
42
  className: styles.tooltip,
43
+ usePortal: true,
43
44
  placement: tooltipPlace,
44
45
  content: tooltip
45
46
  }, React.createElement(IconButton, {
@@ -272,8 +273,11 @@ export function ZenMarkdownToolbar(props) {
272
273
  return React.createElement("div", {
273
274
  className: styles.root
274
275
  }, React.createElement(Flex, {
275
- justifyContent: "space-between"
276
- }, React.createElement(Flex, null, React.createElement(MainButtons, props), React.createElement(AdditionalButtons, props)), React.createElement(Flex, null, React.createElement(InsertLinkSelector, {
276
+ justifyContent: "space-between",
277
+ alignItems: "flex-start"
278
+ }, React.createElement(Flex, {
279
+ flexWrap: "wrap"
280
+ }, React.createElement(MainButtons, props), React.createElement(AdditionalButtons, props)), React.createElement(Flex, null, React.createElement(InsertLinkSelector, {
277
281
  disabled: props.disabled,
278
282
  onSelectExisting: props.actions.linkExistingMedia,
279
283
  onAddNew: props.actions.addNewMedia,
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { Grid } from '@contentful/f36-components';
2
3
  import { ChevronLeftIcon, ChevronRightIcon } from '@contentful/f36-icons';
3
4
  import tokens from '@contentful/f36-tokens';
4
5
  import { css, cx } from 'emotion';
@@ -12,73 +13,59 @@ import { MarkdownDialogType } from '../types';
12
13
  const MarkdownPreview = React.lazy(()=>import('../components/MarkdownPreview'));
13
14
  const styles = {
14
15
  root: css({
15
- position: 'fixed',
16
- left: 0,
17
- right: 0,
18
- top: 0,
19
- bottom: 0
16
+ display: 'grid',
17
+ gridTemplateRows: 'min-content 1fr min-content',
18
+ gridTemplateColumns: '1fr 1px 1fr',
19
+ height: '85vh'
20
20
  }),
21
21
  topSplit: css({
22
- position: 'fixed',
23
- top: 0,
24
- height: '48px',
25
- left: 0,
26
- right: 0
22
+ gridRow: '1 / 2',
23
+ gridColumn: '1 / 4'
27
24
  }),
28
25
  bottomSplit: css({
29
- position: 'fixed',
30
- bottom: 0,
31
- left: 0,
32
- right: 0,
33
- height: '36px'
26
+ gridRow: '3 / 4',
27
+ gridColumn: '1 / 4'
34
28
  }),
35
29
  editorSplit: css({
36
- width: '50%',
37
- position: 'fixed',
38
- top: '48px',
39
- left: 0,
40
- bottom: '36px',
41
- overflowX: 'hidden',
30
+ gridRow: '2 / 3',
31
+ gridColumn: '1 / 2',
42
32
  overflowY: 'scroll'
43
33
  }),
44
34
  editorSplitFullscreen: css({
45
- left: 0,
46
- right: 0,
47
- width: '100%'
35
+ gridRow: '2 / 3',
36
+ gridColumn: '1 / 4',
37
+ overflowY: 'scroll'
48
38
  }),
49
39
  previewSplit: css({
50
- width: '50%',
51
- position: 'fixed',
52
- top: '48px',
53
- right: 0,
54
- bottom: '36px',
55
- overflowX: 'hidden',
40
+ gridRow: '2 / 3',
41
+ gridColumn: '3 / 4',
56
42
  overflowY: 'scroll'
57
43
  }),
58
44
  separator: css({
59
- position: 'fixed',
60
- top: '48px',
61
- bottom: '36px',
62
- width: '1px',
63
- background: tokens.gray400,
64
- left: '50%'
45
+ gridRow: '2 / 3',
46
+ gridColumn: '2 / 3',
47
+ backgroundColor: tokens.gray400,
48
+ width: '1px'
65
49
  }),
66
50
  button: css({
67
- position: 'fixed',
68
51
  cursor: 'pointer',
69
52
  zIndex: 105,
70
- top: '49%',
71
53
  height: '30px',
72
54
  backgroundColor: tokens.gray100,
73
55
  border: `1px solid ${tokens.gray400}`,
74
56
  padding: 0
75
57
  }),
76
58
  hideButton: css({
77
- left: '50%'
59
+ gridRow: '2 / 3',
60
+ gridColumn: '2 / 3',
61
+ justifySelf: 'end',
62
+ alignSelf: 'center'
78
63
  }),
79
64
  showButton: css({
80
- right: 0,
81
- borderRightWidth: 0
65
+ gridRow: '2 / 3',
66
+ gridColumn: '3 / 4',
67
+ justifySelf: 'end',
68
+ alignSelf: 'center'
82
69
  }),
83
70
  icon: css({
84
71
  verticalAlign: 'middle'
@@ -115,17 +102,17 @@ export const ZenModeModalDialog = (props)=>{
115
102
  });
116
103
  };
117
104
  const direction = props.sdk.locales.direction[props.locale] ?? 'ltr';
118
- return React.createElement("div", {
105
+ return React.createElement(Grid, {
119
106
  className: styles.root,
120
107
  "data-test-id": "zen-mode-markdown-editor"
121
- }, React.createElement("div", {
108
+ }, React.createElement(Grid.Item, {
122
109
  className: styles.topSplit
123
110
  }, React.createElement(MarkdownToolbar, {
124
111
  mode: "zen",
125
112
  disabled: false,
126
113
  canUploadAssets: false,
127
114
  actions: actions
128
- })), React.createElement("div", {
115
+ })), React.createElement(Grid.Item, {
129
116
  className: cx(styles.editorSplit, {
130
117
  [styles.editorSplitFullscreen]: showPreview === false
131
118
  })
@@ -144,7 +131,7 @@ export const ZenModeModalDialog = (props)=>{
144
131
  props.saveValueToSDK(value);
145
132
  });
146
133
  }
147
- })), showPreview && React.createElement("div", {
134
+ })), showPreview && React.createElement(Grid.Item, {
148
135
  className: styles.previewSplit
149
136
  }, React.createElement(React.Suspense, {
150
137
  fallback: React.createElement(MarkdownPreviewSkeleton, null)
@@ -153,7 +140,7 @@ export const ZenModeModalDialog = (props)=>{
153
140
  mode: "zen",
154
141
  value: currentValue,
155
142
  previewComponents: props.previewComponents
156
- }))), showPreview && React.createElement("div", {
143
+ }))), showPreview && React.createElement(Grid.Item, {
157
144
  className: styles.separator
158
145
  }), showPreview && React.createElement("button", {
159
146
  className: cx(styles.button, styles.hideButton),
@@ -175,9 +162,10 @@ export const ZenModeModalDialog = (props)=>{
175
162
  variant: "muted",
176
163
  size: "tiny",
177
164
  className: styles.icon
178
- })), React.createElement("div", {
165
+ })), React.createElement(Grid.Item, {
179
166
  className: styles.bottomSplit
180
167
  }, React.createElement(MarkdownBottomBar, null, React.createElement(MarkdownHelp, {
168
+ mode: "zen",
181
169
  onClick: ()=>{
182
170
  openCheatsheetModal(props.sdk.dialogs);
183
171
  }
@@ -185,10 +173,9 @@ export const ZenModeModalDialog = (props)=>{
185
173
  };
186
174
  export const openZenMode = (dialogs, options)=>{
187
175
  return dialogs.openCurrent({
188
- width: 'zen',
176
+ width: 'fullWidth',
189
177
  shouldCloseOnEscapePress: false,
190
- minHeight: '100vh',
191
- shouldCloseOnOverlayClick: false,
178
+ shouldCloseOnOverlayClick: true,
192
179
  parameters: {
193
180
  type: MarkdownDialogType.zenMode,
194
181
  initialValue: options.initialValue,
@@ -1,11 +1,15 @@
1
1
  import * as React from 'react';
2
+ import { MarkdownTab } from 'types';
2
3
  export declare function MarkdownCounter(props: {
3
4
  words: number;
4
5
  characters: number;
5
6
  }): React.JSX.Element;
7
+ type HelpMode = MarkdownTab | 'zen';
6
8
  export declare function MarkdownHelp(props: {
7
9
  onClick: () => void;
10
+ mode: HelpMode;
8
11
  }): React.JSX.Element;
9
12
  export declare function MarkdownBottomBar(props: {
10
13
  children: React.ReactNode;
11
14
  }): React.JSX.Element;
15
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-markdown",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -38,26 +38,25 @@
38
38
  "@contentful/f36-components": "^4.0.27",
39
39
  "@contentful/f36-icons": "^4.1.0",
40
40
  "@contentful/f36-tokens": "^4.0.0",
41
- "@contentful/field-editor-shared": "^1.3.1",
41
+ "@contentful/field-editor-shared": "^1.4.0",
42
42
  "@types/codemirror": "0.0.109",
43
43
  "codemirror": "^5.65.11",
44
44
  "constate": "^3.2.0",
45
- "dompurify": "^2.2.9",
46
45
  "emotion": "^10.0.17",
47
46
  "lodash": "^4.17.15",
48
47
  "react-markdown": "^8.0.7",
49
48
  "rehype-raw": "^6.1.1",
49
+ "rehype-sanitize": "^6.0.0",
50
50
  "remark-gfm": "^3.0.1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@babel/core": "^7.5.5",
54
54
  "@contentful/app-sdk": "^4.2.0",
55
- "@contentful/field-editor-test-utils": "^1.4.1",
56
- "@types/dompurify": "^2.2.2"
55
+ "@contentful/field-editor-test-utils": "^1.4.1"
57
56
  },
58
57
  "peerDependencies": {
59
58
  "@contentful/app-sdk": "^4.2.0",
60
59
  "react": ">=16.8.0"
61
60
  },
62
- "gitHead": "a605be7ef5e386a16142f15f170825125cfaee57"
61
+ "gitHead": "2db95226af0417c42aae8d1be85796fc8774e283"
63
62
  }