@contentful/field-editor-markdown 1.3.1 → 1.4.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.
@@ -22,7 +22,7 @@ const _fieldeditorshared = require("@contentful/field-editor-shared");
22
22
  const _emotion = require("emotion");
23
23
  const _MarkdownBottomBar = require("./components/MarkdownBottomBar");
24
24
  const _MarkdownConstraints = require("./components/MarkdownConstraints");
25
- const _MarkdownPreview = require("./components/MarkdownPreview");
25
+ const _MarkdownPreviewSkeleton = _interop_require_default(require("./components/MarkdownPreviewSkeleton"));
26
26
  const _MarkdownTabs = require("./components/MarkdownTabs");
27
27
  const _MarkdownTextarea = require("./components/MarkdownTextarea/MarkdownTextarea");
28
28
  const _MarkdownToolbar = require("./components/MarkdownToolbar");
@@ -72,6 +72,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
72
72
  }
73
73
  return newObj;
74
74
  }
75
+ const MarkdownPreview = _react.lazy(()=>Promise.resolve().then(()=>_interop_require_wildcard(require("./components/MarkdownPreview"))));
75
76
  const styles = {
76
77
  container: (0, _emotion.css)({
77
78
  display: 'flex',
@@ -150,13 +151,15 @@ function MarkdownEditor(props) {
150
151
  setCurrentValue(value);
151
152
  });
152
153
  }
153
- }), selectedTab === 'preview' && _react.createElement(_MarkdownPreview.MarkdownPreview, {
154
+ }), selectedTab === 'preview' && _react.createElement(_react.Suspense, {
155
+ fallback: _react.createElement(_MarkdownPreviewSkeleton.default, null)
156
+ }, _react.createElement(MarkdownPreview, {
154
157
  direction: direction,
155
158
  minHeight: props.minHeight,
156
159
  mode: "default",
157
160
  value: currentValue,
158
161
  previewComponents: props.previewComponents
159
- }), _react.createElement(_MarkdownBottomBar.MarkdownBottomBar, null, _react.createElement(_MarkdownBottomBar.MarkdownHelp, {
162
+ })), _react.createElement(_MarkdownBottomBar.MarkdownBottomBar, null, _react.createElement(_MarkdownBottomBar.MarkdownHelp, {
160
163
  onClick: openMarkdownHelp
161
164
  })), _react.createElement(_MarkdownConstraints.MarkdownConstraints, {
162
165
  sdk: props.sdk,
@@ -2,17 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "MarkdownPreview", {
5
+ Object.defineProperty(exports, "default", {
6
6
  enumerable: true,
7
7
  get: function() {
8
- return MarkdownPreview;
8
+ return _default;
9
9
  }
10
10
  });
11
11
  const _react = _interop_require_wildcard(require("react"));
12
+ const _reactmarkdown = _interop_require_default(require("react-markdown"));
12
13
  const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
13
14
  const _dompurify = _interop_require_default(require("dompurify"));
14
15
  const _emotion = require("emotion");
15
- const _markdowntojsx = _interop_require_default(require("markdown-to-jsx"));
16
+ const _rehyperaw = _interop_require_default(require("rehype-raw"));
17
+ const _remarkgfm = _interop_require_default(require("remark-gfm"));
16
18
  const _replaceMailtoAmp = require("../utils/replaceMailtoAmp");
17
19
  function _interop_require_default(obj) {
18
20
  return obj && obj.__esModule ? obj : {
@@ -70,7 +72,7 @@ const styles = {
70
72
  font-family: ${_f36tokens.default.fontStackPrimary};
71
73
  line-height: ${_f36tokens.default.lineHeightDefault};
72
74
  color: ${_f36tokens.default.gray700};
73
- white-space: pre-line;
75
+ white-space: normal;
74
76
 
75
77
  h1,
76
78
  h2,
@@ -212,7 +214,7 @@ function MarkdownLink(props) {
212
214
  const { Embedly , children , ...rest } = props;
213
215
  if (props.className === 'embedly-card' && Embedly) {
214
216
  return _react.createElement(Embedly, {
215
- url: props.href
217
+ url: props.href ?? ''
216
218
  });
217
219
  }
218
220
  return _react.createElement("a", {
@@ -222,7 +224,7 @@ function MarkdownLink(props) {
222
224
  }, children);
223
225
  }
224
226
  const MarkdownPreview = _react.memo((props)=>{
225
- const className = (0, _emotion.cx)(styles.root, props.minHeight !== undefined ? (0, _emotion.css)({
227
+ const className = (0, _emotion.cx)(props.minHeight !== undefined ? (0, _emotion.css)({
226
228
  minHeight: props.minHeight
227
229
  }) : undefined, props.mode === 'default' ? styles.framed : styles.zen, props.direction === 'rtl' ? styles.rtl : undefined);
228
230
  const cleanHTML = _react.useMemo(()=>{
@@ -233,17 +235,24 @@ const MarkdownPreview = _react.memo((props)=>{
233
235
  return _react.createElement("div", {
234
236
  className: className,
235
237
  "data-test-id": "markdown-preview"
236
- }, _react.createElement(_markdowntojsx.default, {
237
- options: {
238
- overrides: {
239
- a: {
240
- component: MarkdownLink,
241
- props: {
242
- Embedly: props.previewComponents?.embedly
243
- }
244
- }
245
- }
238
+ }, _react.createElement(_reactmarkdown.default, {
239
+ className: styles.root,
240
+ rehypePlugins: [
241
+ _rehyperaw.default
242
+ ],
243
+ remarkPlugins: [
244
+ _remarkgfm.default
245
+ ],
246
+ remarkRehypeOptions: {
247
+ allowDangerousHtml: true
248
+ },
249
+ components: {
250
+ a: (markdownProps)=>_react.createElement(MarkdownLink, {
251
+ ...markdownProps,
252
+ Embedly: props.previewComponents?.embedly
253
+ })
246
254
  }
247
255
  }, cleanHTML));
248
256
  });
249
257
  MarkdownPreview.displayName = 'MarkdownPreview';
258
+ const _default = MarkdownPreview;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return MarkdownPreviewSkeleton;
9
+ }
10
+ });
11
+ const _react = _interop_require_default(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
14
+ const _emotion = require("emotion");
15
+ function _interop_require_default(obj) {
16
+ return obj && obj.__esModule ? obj : {
17
+ default: obj
18
+ };
19
+ }
20
+ const styles = {
21
+ root: (0, _emotion.css)({
22
+ border: `1px solid ${_f36tokens.default.gray400}`,
23
+ borderWidth: '0 1px',
24
+ minHeight: '300px',
25
+ padding: `${_f36tokens.default.spacingL}`
26
+ })
27
+ };
28
+ function MarkdownPreviewSkeleton() {
29
+ return _react.default.createElement(_f36components.Skeleton.Container, {
30
+ className: styles.root
31
+ }, _react.default.createElement(_f36components.Skeleton.DisplayText, null), _react.default.createElement(_f36components.Skeleton.BodyText, {
32
+ offsetTop: 37,
33
+ numberOfLines: 5
34
+ }));
35
+ }
@@ -21,7 +21,7 @@ const _f36icons = require("@contentful/f36-icons");
21
21
  const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
22
22
  const _emotion = require("emotion");
23
23
  const _MarkdownBottomBar = require("../components/MarkdownBottomBar");
24
- const _MarkdownPreview = require("../components/MarkdownPreview");
24
+ const _MarkdownPreviewSkeleton = _interop_require_default(require("../components/MarkdownPreviewSkeleton"));
25
25
  const _MarkdownTextarea = require("../components/MarkdownTextarea/MarkdownTextarea");
26
26
  const _MarkdownToolbar = require("../components/MarkdownToolbar");
27
27
  const _CheatsheetModalDialog = require("../dialogs/CheatsheetModalDialog");
@@ -71,6 +71,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
71
71
  }
72
72
  return newObj;
73
73
  }
74
+ const MarkdownPreview = _react.lazy(()=>Promise.resolve().then(()=>_interop_require_wildcard(require("../components/MarkdownPreview"))));
74
75
  const styles = {
75
76
  root: (0, _emotion.css)({
76
77
  position: 'fixed',
@@ -207,12 +208,14 @@ const ZenModeModalDialog = (props)=>{
207
208
  }
208
209
  })), showPreview && _react.createElement("div", {
209
210
  className: styles.previewSplit
210
- }, _react.createElement(_MarkdownPreview.MarkdownPreview, {
211
+ }, _react.createElement(_react.Suspense, {
212
+ fallback: _react.createElement(_MarkdownPreviewSkeleton.default, null)
213
+ }, _react.createElement(MarkdownPreview, {
211
214
  direction: direction,
212
215
  mode: "zen",
213
216
  value: currentValue,
214
217
  previewComponents: props.previewComponents
215
- })), showPreview && _react.createElement("div", {
218
+ }))), showPreview && _react.createElement("div", {
216
219
  className: styles.separator
217
220
  }), showPreview && _react.createElement("button", {
218
221
  className: (0, _emotion.cx)(styles.button, styles.hideButton),
package/dist/cjs/index.js CHANGED
@@ -13,7 +13,7 @@ _export(exports, {
13
13
  return _MarkdownEditor.MarkdownEditorConnected;
14
14
  },
15
15
  MarkdownPreview: function() {
16
- return _MarkdownPreview.MarkdownPreview;
16
+ return _MarkdownPreview.default;
17
17
  },
18
18
  openMarkdownDialog: function() {
19
19
  return _openMarkdownDialog.openMarkdownDialog;
@@ -24,6 +24,11 @@ _export(exports, {
24
24
  });
25
25
  require("./codemirrorImports");
26
26
  const _MarkdownEditor = require("./MarkdownEditor");
27
- const _MarkdownPreview = require("./components/MarkdownPreview");
27
+ const _MarkdownPreview = _interop_require_default(require("./components/MarkdownPreview"));
28
28
  const _openMarkdownDialog = require("./dialogs/openMarkdownDialog");
29
29
  const _renderMarkdownDialog = require("./dialogs/renderMarkdownDialog");
30
+ function _interop_require_default(obj) {
31
+ return obj && obj.__esModule ? obj : {
32
+ default: obj
33
+ };
34
+ }
@@ -4,12 +4,13 @@ import { FieldConnector } from '@contentful/field-editor-shared';
4
4
  import { css } from 'emotion';
5
5
  import { MarkdownBottomBar, MarkdownHelp } from './components/MarkdownBottomBar';
6
6
  import { MarkdownConstraints } from './components/MarkdownConstraints';
7
- import { MarkdownPreview } from './components/MarkdownPreview';
7
+ import MarkdownPreviewSkeleton from './components/MarkdownPreviewSkeleton';
8
8
  import { MarkdownTabs } from './components/MarkdownTabs';
9
9
  import { MarkdownTextarea } from './components/MarkdownTextarea/MarkdownTextarea';
10
10
  import { MarkdownToolbar } from './components/MarkdownToolbar';
11
11
  import { openCheatsheetModal } from './dialogs/CheatsheetModalDialog';
12
12
  import { createMarkdownActions } from './MarkdownActions';
13
+ const MarkdownPreview = React.lazy(()=>import('./components/MarkdownPreview'));
13
14
  const styles = {
14
15
  container: css({
15
16
  display: 'flex',
@@ -88,13 +89,15 @@ export function MarkdownEditor(props) {
88
89
  setCurrentValue(value);
89
90
  });
90
91
  }
91
- }), selectedTab === 'preview' && React.createElement(MarkdownPreview, {
92
+ }), selectedTab === 'preview' && React.createElement(React.Suspense, {
93
+ fallback: React.createElement(MarkdownPreviewSkeleton, null)
94
+ }, React.createElement(MarkdownPreview, {
92
95
  direction: direction,
93
96
  minHeight: props.minHeight,
94
97
  mode: "default",
95
98
  value: currentValue,
96
99
  previewComponents: props.previewComponents
97
- }), React.createElement(MarkdownBottomBar, null, React.createElement(MarkdownHelp, {
100
+ })), React.createElement(MarkdownBottomBar, null, React.createElement(MarkdownHelp, {
98
101
  onClick: openMarkdownHelp
99
102
  })), React.createElement(MarkdownConstraints, {
100
103
  sdk: props.sdk,
@@ -1,8 +1,10 @@
1
1
  import * as React from 'react';
2
+ import ReactMarkdown from 'react-markdown';
2
3
  import tokens from '@contentful/f36-tokens';
3
4
  import DOMPurify from 'dompurify';
4
5
  import { css, cx } from 'emotion';
5
- import Markdown from 'markdown-to-jsx';
6
+ import rehypeRaw from 'rehype-raw';
7
+ import remarkGfm from 'remark-gfm';
6
8
  import { replaceMailtoAmp } from '../utils/replaceMailtoAmp';
7
9
  const styles = {
8
10
  root: css`
@@ -16,7 +18,7 @@ const styles = {
16
18
  font-family: ${tokens.fontStackPrimary};
17
19
  line-height: ${tokens.lineHeightDefault};
18
20
  color: ${tokens.gray700};
19
- white-space: pre-line;
21
+ white-space: normal;
20
22
 
21
23
  h1,
22
24
  h2,
@@ -158,7 +160,7 @@ function MarkdownLink(props) {
158
160
  const { Embedly , children , ...rest } = props;
159
161
  if (props.className === 'embedly-card' && Embedly) {
160
162
  return React.createElement(Embedly, {
161
- url: props.href
163
+ url: props.href ?? ''
162
164
  });
163
165
  }
164
166
  return React.createElement("a", {
@@ -167,8 +169,8 @@ function MarkdownLink(props) {
167
169
  rel: "noopener noreferrer"
168
170
  }, children);
169
171
  }
170
- export const MarkdownPreview = React.memo((props)=>{
171
- const className = cx(styles.root, props.minHeight !== undefined ? css({
172
+ const MarkdownPreview = React.memo((props)=>{
173
+ const className = cx(props.minHeight !== undefined ? css({
172
174
  minHeight: props.minHeight
173
175
  }) : undefined, props.mode === 'default' ? styles.framed : styles.zen, props.direction === 'rtl' ? styles.rtl : undefined);
174
176
  const cleanHTML = React.useMemo(()=>{
@@ -179,17 +181,24 @@ export const MarkdownPreview = React.memo((props)=>{
179
181
  return React.createElement("div", {
180
182
  className: className,
181
183
  "data-test-id": "markdown-preview"
182
- }, React.createElement(Markdown, {
183
- options: {
184
- overrides: {
185
- a: {
186
- component: MarkdownLink,
187
- props: {
188
- Embedly: props.previewComponents?.embedly
189
- }
190
- }
191
- }
184
+ }, React.createElement(ReactMarkdown, {
185
+ className: styles.root,
186
+ rehypePlugins: [
187
+ rehypeRaw
188
+ ],
189
+ remarkPlugins: [
190
+ remarkGfm
191
+ ],
192
+ remarkRehypeOptions: {
193
+ allowDangerousHtml: true
194
+ },
195
+ components: {
196
+ a: (markdownProps)=>React.createElement(MarkdownLink, {
197
+ ...markdownProps,
198
+ Embedly: props.previewComponents?.embedly
199
+ })
192
200
  }
193
201
  }, cleanHTML));
194
202
  });
195
203
  MarkdownPreview.displayName = 'MarkdownPreview';
204
+ export default MarkdownPreview;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { Skeleton } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { css } from 'emotion';
5
+ const styles = {
6
+ root: css({
7
+ border: `1px solid ${tokens.gray400}`,
8
+ borderWidth: '0 1px',
9
+ minHeight: '300px',
10
+ padding: `${tokens.spacingL}`
11
+ })
12
+ };
13
+ export default function MarkdownPreviewSkeleton() {
14
+ return React.createElement(Skeleton.Container, {
15
+ className: styles.root
16
+ }, React.createElement(Skeleton.DisplayText, null), React.createElement(Skeleton.BodyText, {
17
+ offsetTop: 37,
18
+ numberOfLines: 5
19
+ }));
20
+ }
@@ -3,12 +3,13 @@ import { ChevronLeftIcon, ChevronRightIcon } from '@contentful/f36-icons';
3
3
  import tokens from '@contentful/f36-tokens';
4
4
  import { css, cx } from 'emotion';
5
5
  import { MarkdownBottomBar, MarkdownHelp } from '../components/MarkdownBottomBar';
6
- import { MarkdownPreview } from '../components/MarkdownPreview';
6
+ import MarkdownPreviewSkeleton from '../components/MarkdownPreviewSkeleton';
7
7
  import { MarkdownTextarea } from '../components/MarkdownTextarea/MarkdownTextarea';
8
8
  import { MarkdownToolbar } from '../components/MarkdownToolbar';
9
9
  import { openCheatsheetModal } from '../dialogs/CheatsheetModalDialog';
10
10
  import { createMarkdownActions } from '../MarkdownActions';
11
11
  import { MarkdownDialogType } from '../types';
12
+ const MarkdownPreview = React.lazy(()=>import('../components/MarkdownPreview'));
12
13
  const styles = {
13
14
  root: css({
14
15
  position: 'fixed',
@@ -145,12 +146,14 @@ export const ZenModeModalDialog = (props)=>{
145
146
  }
146
147
  })), showPreview && React.createElement("div", {
147
148
  className: styles.previewSplit
149
+ }, React.createElement(React.Suspense, {
150
+ fallback: React.createElement(MarkdownPreviewSkeleton, null)
148
151
  }, React.createElement(MarkdownPreview, {
149
152
  direction: direction,
150
153
  mode: "zen",
151
154
  value: currentValue,
152
155
  previewComponents: props.previewComponents
153
- })), showPreview && React.createElement("div", {
156
+ }))), showPreview && React.createElement("div", {
154
157
  className: styles.separator
155
158
  }), showPreview && React.createElement("button", {
156
159
  className: cx(styles.button, styles.hideButton),
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import './codemirrorImports';
2
2
  export { MarkdownEditorConnected as MarkdownEditor } from './MarkdownEditor';
3
- export { MarkdownPreview } from './components/MarkdownPreview';
3
+ export { default as MarkdownPreview } from './components/MarkdownPreview';
4
4
  export { openMarkdownDialog } from './dialogs/openMarkdownDialog';
5
5
  export { renderMarkdownDialog } from './dialogs/renderMarkdownDialog';
@@ -10,5 +10,5 @@ type MarkdownPreviewProps = {
10
10
  value: string;
11
11
  previewComponents?: PreviewComponents;
12
12
  };
13
- export declare const MarkdownPreview: React.MemoExoticComponent<(props: MarkdownPreviewProps) => React.JSX.Element>;
14
- export {};
13
+ declare const MarkdownPreview: React.MemoExoticComponent<(props: MarkdownPreviewProps) => React.JSX.Element>;
14
+ export default MarkdownPreview;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export default function MarkdownPreviewSkeleton(): React.JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import './codemirrorImports';
2
2
  export { MarkdownEditorConnected as MarkdownEditor } from './MarkdownEditor';
3
- export { MarkdownPreview } from './components/MarkdownPreview';
3
+ export { default as MarkdownPreview } from './components/MarkdownPreview';
4
4
  export { openMarkdownDialog } from './dialogs/openMarkdownDialog';
5
5
  export { renderMarkdownDialog } from './dialogs/renderMarkdownDialog';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-markdown",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -40,13 +40,14 @@
40
40
  "@contentful/f36-tokens": "^4.0.0",
41
41
  "@contentful/field-editor-shared": "^1.3.1",
42
42
  "@types/codemirror": "0.0.109",
43
- "@types/markdown-to-jsx": "6.11.3",
44
43
  "codemirror": "^5.65.11",
45
44
  "constate": "^3.2.0",
46
45
  "dompurify": "^2.2.9",
47
46
  "emotion": "^10.0.17",
48
47
  "lodash": "^4.17.15",
49
- "markdown-to-jsx": "^7.1.1"
48
+ "react-markdown": "^8.0.7",
49
+ "rehype-raw": "^6.1.1",
50
+ "remark-gfm": "^3.0.1"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@babel/core": "^7.5.5",
@@ -58,5 +59,5 @@
58
59
  "@contentful/app-sdk": "^4.2.0",
59
60
  "react": ">=16.8.0"
60
61
  },
61
- "gitHead": "ca904b19ca794a2c40d82e1f7ede9e0be3560f22"
62
+ "gitHead": "a605be7ef5e386a16142f15f170825125cfaee57"
62
63
  }