@contentful/field-editor-markdown 1.2.1 → 1.3.1

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 (136) hide show
  1. package/dist/cjs/MarkdownActions.js +235 -0
  2. package/dist/cjs/MarkdownEditor.js +180 -0
  3. package/dist/cjs/__fixtures__/FakeSdk.js +183 -0
  4. package/dist/cjs/__fixtures__/asset/index.js +37 -0
  5. package/dist/cjs/__fixtures__/content-type/index.js +16 -0
  6. package/dist/cjs/__fixtures__/entry/index.js +33 -0
  7. package/dist/cjs/__fixtures__/fixtures.js +71 -0
  8. package/dist/cjs/__fixtures__/locale/index.js +40 -0
  9. package/dist/cjs/__fixtures__/space/index.js +16 -0
  10. package/dist/cjs/codemirrorImports.js +9 -0
  11. package/dist/cjs/components/HeadingSelector.js +66 -0
  12. package/dist/cjs/components/InsertLinkSelector.js +86 -0
  13. package/dist/cjs/components/MarkdownBottomBar.js +111 -0
  14. package/dist/cjs/components/MarkdownConstraints.js +79 -0
  15. package/dist/cjs/components/MarkdownPreview.js +249 -0
  16. package/dist/cjs/components/MarkdownTabs.js +128 -0
  17. package/dist/cjs/components/MarkdownTextarea/CodeMirrorWrapper.js +383 -0
  18. package/dist/cjs/components/MarkdownTextarea/MarkdownCommands.js +233 -0
  19. package/dist/cjs/components/MarkdownTextarea/MarkdownTextarea.js +190 -0
  20. package/dist/cjs/components/MarkdownTextarea/createMarkdownEditor.js +101 -0
  21. package/dist/cjs/components/MarkdownToolbar.js +367 -0
  22. package/dist/cjs/components/icons.js +193 -0
  23. package/dist/cjs/dialogs/CheatsheetModalDialog.js +239 -0
  24. package/dist/cjs/dialogs/ConfirmInsertAssetModalDialog.js +94 -0
  25. package/dist/cjs/dialogs/EmdebExternalContentDialog.js +202 -0
  26. package/dist/cjs/dialogs/InsertLinkModalDialog.js +149 -0
  27. package/dist/cjs/dialogs/InsertTableModalDialog.js +140 -0
  28. package/dist/cjs/dialogs/SpecialCharacterModalDialog.js +146 -0
  29. package/dist/cjs/dialogs/ZenModeModalDialog.js +257 -0
  30. package/dist/cjs/dialogs/openMarkdownDialog.js +121 -0
  31. package/dist/cjs/dialogs/renderMarkdownDialog.js +108 -0
  32. package/dist/cjs/index.js +29 -0
  33. package/dist/cjs/types.js +20 -0
  34. package/dist/cjs/utils/insertAssetLinks.js +122 -0
  35. package/dist/cjs/utils/insertAssetLinks.spec.js +22 -0
  36. package/dist/cjs/utils/isValidUrl.js +22 -0
  37. package/dist/cjs/utils/linkOrganizer.js +187 -0
  38. package/dist/cjs/utils/linkOrganizer.spec.js +96 -0
  39. package/dist/cjs/utils/replaceMailtoAmp.js +15 -0
  40. package/dist/cjs/utils/replaceMailtoAmp.spec.js +22 -0
  41. package/dist/cjs/utils/specialCharacters.js +228 -0
  42. package/dist/cjs/utils/userAgent.js +28 -0
  43. package/dist/esm/MarkdownActions.js +186 -0
  44. package/dist/esm/MarkdownEditor.js +118 -0
  45. package/dist/esm/__fixtures__/FakeSdk.js +173 -0
  46. package/dist/esm/__fixtures__/asset/index.js +6 -0
  47. package/dist/esm/__fixtures__/content-type/index.js +2 -0
  48. package/dist/esm/__fixtures__/entry/index.js +5 -0
  49. package/dist/esm/__fixtures__/fixtures.js +6 -0
  50. package/dist/esm/__fixtures__/locale/index.js +15 -0
  51. package/dist/esm/__fixtures__/space/index.js +2 -0
  52. package/dist/esm/codemirrorImports.js +5 -0
  53. package/dist/esm/components/HeadingSelector.js +17 -0
  54. package/dist/esm/components/InsertLinkSelector.js +37 -0
  55. package/dist/esm/components/MarkdownBottomBar.js +46 -0
  56. package/dist/esm/components/MarkdownConstraints.js +25 -0
  57. package/dist/esm/components/MarkdownPreview.js +195 -0
  58. package/dist/esm/components/MarkdownTabs.js +74 -0
  59. package/dist/esm/components/MarkdownTextarea/CodeMirrorWrapper.js +329 -0
  60. package/dist/esm/components/MarkdownTextarea/MarkdownCommands.js +218 -0
  61. package/dist/esm/components/MarkdownTextarea/MarkdownTextarea.js +136 -0
  62. package/dist/esm/components/MarkdownTextarea/createMarkdownEditor.js +52 -0
  63. package/dist/esm/components/MarkdownToolbar.js +302 -0
  64. package/dist/esm/components/icons.js +112 -0
  65. package/dist/esm/dialogs/CheatsheetModalDialog.js +177 -0
  66. package/dist/esm/dialogs/ConfirmInsertAssetModalDialog.js +37 -0
  67. package/dist/esm/dialogs/EmdebExternalContentDialog.js +140 -0
  68. package/dist/esm/dialogs/InsertLinkModalDialog.js +92 -0
  69. package/dist/esm/dialogs/InsertTableModalDialog.js +78 -0
  70. package/dist/esm/dialogs/SpecialCharacterModalDialog.js +84 -0
  71. package/dist/esm/dialogs/ZenModeModalDialog.js +195 -0
  72. package/dist/esm/dialogs/openMarkdownDialog.js +72 -0
  73. package/dist/esm/dialogs/renderMarkdownDialog.js +59 -0
  74. package/dist/esm/index.js +5 -0
  75. package/dist/esm/types.js +10 -0
  76. package/dist/esm/utils/insertAssetLinks.js +99 -0
  77. package/dist/esm/utils/insertAssetLinks.spec.js +18 -0
  78. package/dist/esm/utils/isValidUrl.js +4 -0
  79. package/dist/esm/utils/linkOrganizer.js +152 -0
  80. package/dist/esm/utils/linkOrganizer.spec.js +53 -0
  81. package/dist/esm/utils/replaceMailtoAmp.js +5 -0
  82. package/dist/esm/utils/replaceMailtoAmp.spec.js +18 -0
  83. package/dist/esm/utils/specialCharacters.js +218 -0
  84. package/dist/esm/utils/userAgent.js +13 -0
  85. package/dist/{MarkdownActions.d.ts → types/MarkdownActions.d.ts} +38 -38
  86. package/dist/{MarkdownEditor.d.ts → types/MarkdownEditor.d.ts} +22 -22
  87. package/dist/types/__fixtures__/FakeSdk.d.ts +8 -0
  88. package/dist/types/__fixtures__/asset/index.d.ts +6 -0
  89. package/dist/types/__fixtures__/content-type/index.d.ts +2 -0
  90. package/dist/types/__fixtures__/entry/index.d.ts +5 -0
  91. package/dist/types/__fixtures__/fixtures.d.ts +6 -0
  92. package/dist/types/__fixtures__/locale/index.d.ts +42 -0
  93. package/dist/types/__fixtures__/space/index.d.ts +2 -0
  94. package/dist/{codemirrorImports.d.ts → types/codemirrorImports.d.ts} +5 -5
  95. package/dist/{components → types/components}/HeadingSelector.d.ts +7 -7
  96. package/dist/{components → types/components}/InsertLinkSelector.d.ts +9 -9
  97. package/dist/{components → types/components}/MarkdownBottomBar.d.ts +11 -11
  98. package/dist/{components → types/components}/MarkdownConstraints.d.ts +6 -6
  99. package/dist/{components → types/components}/MarkdownPreview.d.ts +14 -14
  100. package/dist/{components → types/components}/MarkdownTabs.d.ts +8 -8
  101. package/dist/{components → types/components}/MarkdownTextarea/CodeMirrorWrapper.d.ts +58 -58
  102. package/dist/{components → types/components}/MarkdownTextarea/MarkdownCommands.d.ts +33 -33
  103. package/dist/{components → types/components}/MarkdownTextarea/MarkdownTextarea.d.ts +17 -17
  104. package/dist/{components → types/components}/MarkdownTextarea/createMarkdownEditor.d.ts +55 -55
  105. package/dist/{components → types/components}/MarkdownToolbar.d.ts +12 -12
  106. package/dist/types/components/icons.d.ts +18 -0
  107. package/dist/{dialogs → types/dialogs}/CheatsheetModalDialog.d.ts +4 -4
  108. package/dist/{dialogs → types/dialogs}/ConfirmInsertAssetModalDialog.d.ts +23 -23
  109. package/dist/{dialogs → types/dialogs}/EmdebExternalContentDialog.d.ts +9 -9
  110. package/dist/{dialogs → types/dialogs}/InsertLinkModalDialog.d.ts +17 -17
  111. package/dist/{dialogs → types/dialogs}/InsertTableModalDialog.d.ts +13 -13
  112. package/dist/{dialogs → types/dialogs}/SpecialCharacterModalDialog.d.ts +9 -9
  113. package/dist/{dialogs → types/dialogs}/ZenModeModalDialog.d.ts +24 -24
  114. package/dist/{dialogs → types/dialogs}/openMarkdownDialog.d.ts +5 -5
  115. package/dist/{dialogs → types/dialogs}/renderMarkdownDialog.d.ts +8 -8
  116. package/dist/{index.d.ts → types/index.d.ts} +5 -5
  117. package/dist/{types.d.ts → types/types.d.ts} +75 -75
  118. package/dist/{utils → types/utils}/insertAssetLinks.d.ts +29 -29
  119. package/dist/types/utils/insertAssetLinks.spec.d.ts +1 -0
  120. package/dist/{utils → types/utils}/isValidUrl.d.ts +2 -2
  121. package/dist/{utils → types/utils}/linkOrganizer.d.ts +6 -6
  122. package/dist/types/utils/linkOrganizer.spec.d.ts +1 -0
  123. package/dist/{utils → types/utils}/replaceMailtoAmp.d.ts +1 -1
  124. package/dist/types/utils/replaceMailtoAmp.spec.d.ts +1 -0
  125. package/dist/{utils → types/utils}/specialCharacters.d.ts +4 -4
  126. package/dist/{utils → types/utils}/userAgent.d.ts +1 -1
  127. package/package.json +25 -12
  128. package/CHANGELOG.md +0 -314
  129. package/dist/components/icons.d.ts +0 -18
  130. package/dist/field-editor-markdown.cjs.development.js +0 -3609
  131. package/dist/field-editor-markdown.cjs.development.js.map +0 -1
  132. package/dist/field-editor-markdown.cjs.production.min.js +0 -216
  133. package/dist/field-editor-markdown.cjs.production.min.js.map +0 -1
  134. package/dist/field-editor-markdown.esm.js +0 -3599
  135. package/dist/field-editor-markdown.esm.js.map +0 -1
  136. package/dist/index.js +0 -8
@@ -0,0 +1,186 @@
1
+ import { openConfirmInsertAsset } from './dialogs/ConfirmInsertAssetModalDialog';
2
+ import { openEmbedExternalContentDialog } from './dialogs/EmdebExternalContentDialog';
3
+ import { openInsertLinkDialog } from './dialogs/InsertLinkModalDialog';
4
+ import { openInsertTableDialog } from './dialogs/InsertTableModalDialog';
5
+ import { openInsertSpecialCharacter } from './dialogs/SpecialCharacterModalDialog';
6
+ import { openZenMode } from './dialogs/ZenModeModalDialog';
7
+ import { insertAssetLinks } from './utils/insertAssetLinks';
8
+ import * as LinkOrganizer from './utils/linkOrganizer';
9
+ export function createMarkdownActions(props) {
10
+ const { sdk , editor , locale } = props;
11
+ const insertAssetsWithConfirmation = async (assets)=>{
12
+ if (assets) {
13
+ const { links , fallbacks } = await insertAssetLinks(assets, {
14
+ localeCode: locale,
15
+ defaultLocaleCode: sdk.locales.default,
16
+ fallbackCode: sdk.locales.fallbacks[locale]
17
+ });
18
+ if (links && links.length > 0) {
19
+ if (fallbacks) {
20
+ const insertAnyway = await openConfirmInsertAsset(sdk.dialogs, {
21
+ locale: locale,
22
+ assets: fallbacks
23
+ });
24
+ if (!insertAnyway) {
25
+ throw Error('User decided to not use fallbacks');
26
+ }
27
+ }
28
+ return links.map((link)=>link.asMarkdown).join('\n\n');
29
+ }
30
+ }
31
+ return '';
32
+ };
33
+ return {
34
+ headings: {
35
+ h1: ()=>{
36
+ editor?.actions.h1();
37
+ },
38
+ h2: ()=>{
39
+ editor?.actions.h2();
40
+ },
41
+ h3: ()=>{
42
+ editor?.actions.h3();
43
+ }
44
+ },
45
+ simple: {
46
+ italic: ()=>{
47
+ editor?.actions.italic();
48
+ },
49
+ bold: ()=>{
50
+ editor?.actions.bold();
51
+ },
52
+ quote: ()=>{
53
+ editor?.actions.quote();
54
+ },
55
+ ol: ()=>{
56
+ editor?.actions.ol();
57
+ },
58
+ ul: ()=>{
59
+ editor?.actions.ul();
60
+ },
61
+ strike: ()=>{
62
+ editor?.actions.strike();
63
+ },
64
+ code: ()=>{
65
+ editor?.actions.code();
66
+ },
67
+ hr: ()=>{
68
+ editor?.actions.hr();
69
+ },
70
+ indent: ()=>{
71
+ editor?.actions.indent();
72
+ },
73
+ dedent: ()=>{
74
+ editor?.actions.dedent();
75
+ }
76
+ },
77
+ history: {
78
+ undo: ()=>{
79
+ editor?.actions.undo();
80
+ },
81
+ redo: ()=>{
82
+ editor?.actions.redo();
83
+ }
84
+ },
85
+ insertLink: async ()=>{
86
+ if (!editor) {
87
+ return;
88
+ }
89
+ editor.usePrimarySelection();
90
+ const selectedText = editor.getSelectedText();
91
+ const result = await openInsertLinkDialog(sdk.dialogs, {
92
+ selectedText
93
+ });
94
+ if (result) {
95
+ editor.actions.link(result.url, selectedText || result.text, result.title);
96
+ }
97
+ },
98
+ insertSpecialCharacter: async ()=>{
99
+ if (!editor) {
100
+ return;
101
+ }
102
+ const result = await openInsertSpecialCharacter(sdk.dialogs);
103
+ if (result) {
104
+ editor.insert(result);
105
+ }
106
+ },
107
+ insertTable: async ()=>{
108
+ if (!editor) {
109
+ return;
110
+ }
111
+ const result = await openInsertTableDialog(sdk.dialogs);
112
+ if (result) {
113
+ editor.actions.table(result);
114
+ }
115
+ },
116
+ organizeLinks: ()=>{
117
+ if (!editor) {
118
+ return;
119
+ }
120
+ let text = editor.getContent();
121
+ if (!text) {
122
+ return;
123
+ }
124
+ text = LinkOrganizer.convertInlineToRef(text);
125
+ text = LinkOrganizer.rewriteRefs(text);
126
+ editor.setContent(text);
127
+ sdk.notifier.success('All your links are now references at the bottom of your document.');
128
+ },
129
+ embedExternalContent: async ()=>{
130
+ if (!editor) {
131
+ return;
132
+ }
133
+ const result = await openEmbedExternalContentDialog(sdk.dialogs);
134
+ if (result) {
135
+ editor.insert(result);
136
+ }
137
+ },
138
+ addNewMedia: async ()=>{
139
+ if (!editor) {
140
+ return;
141
+ }
142
+ try {
143
+ const { entity: asset } = await sdk.navigator.openNewAsset({
144
+ slideIn: {
145
+ waitForClose: true
146
+ }
147
+ });
148
+ const markdownLinks = await insertAssetsWithConfirmation([
149
+ asset
150
+ ]);
151
+ editor.insert(markdownLinks);
152
+ } finally{
153
+ editor.focus();
154
+ }
155
+ },
156
+ linkExistingMedia: async ()=>{
157
+ if (!editor) {
158
+ return;
159
+ }
160
+ try {
161
+ const assets = await sdk.dialogs.selectMultipleAssets({
162
+ locale: locale
163
+ });
164
+ const markdownLinks = await insertAssetsWithConfirmation(assets);
165
+ editor.insert(markdownLinks);
166
+ } finally{
167
+ editor.focus();
168
+ }
169
+ },
170
+ openZenMode: async ()=>{
171
+ if (!editor) {
172
+ return;
173
+ }
174
+ const result = await openZenMode(sdk.dialogs, {
175
+ initialValue: editor.getContent(),
176
+ locale: props.locale
177
+ });
178
+ editor.setContent(result.value);
179
+ if (result.cursor) {
180
+ editor.setCursor(result.cursor);
181
+ }
182
+ editor.focus();
183
+ },
184
+ closeZenMode: ()=>{}
185
+ };
186
+ }
@@ -0,0 +1,118 @@
1
+ import * as React from 'react';
2
+ import tokens from '@contentful/f36-tokens';
3
+ import { FieldConnector } from '@contentful/field-editor-shared';
4
+ import { css } from 'emotion';
5
+ import { MarkdownBottomBar, MarkdownHelp } from './components/MarkdownBottomBar';
6
+ import { MarkdownConstraints } from './components/MarkdownConstraints';
7
+ import { MarkdownPreview } from './components/MarkdownPreview';
8
+ import { MarkdownTabs } from './components/MarkdownTabs';
9
+ import { MarkdownTextarea } from './components/MarkdownTextarea/MarkdownTextarea';
10
+ import { MarkdownToolbar } from './components/MarkdownToolbar';
11
+ import { openCheatsheetModal } from './dialogs/CheatsheetModalDialog';
12
+ import { createMarkdownActions } from './MarkdownActions';
13
+ const styles = {
14
+ container: css({
15
+ display: 'flex',
16
+ flexDirection: 'column',
17
+ fontFamily: tokens.fontStackPrimary
18
+ })
19
+ };
20
+ export function MarkdownEditor(props) {
21
+ const [currentValue, setCurrentValue] = React.useState(props.initialValue ?? '');
22
+ const [selectedTab, setSelectedTab] = React.useState('editor');
23
+ const [editor, setEditor] = React.useState(null);
24
+ const [canUploadAssets, setCanUploadAssets] = React.useState(false);
25
+ React.useEffect(()=>{
26
+ if (editor && props.onReady) {
27
+ props.onReady(editor);
28
+ setTimeout(()=>{
29
+ editor.refresh();
30
+ }, 1);
31
+ }
32
+ }, [
33
+ editor
34
+ ]);
35
+ React.useEffect(()=>{
36
+ props.sdk.access.can('create', 'Asset').then((value)=>{
37
+ setCanUploadAssets(value);
38
+ });
39
+ }, []);
40
+ React.useEffect(()=>{
41
+ if (editor) {
42
+ editor.setReadOnly(props.disabled);
43
+ }
44
+ }, [
45
+ editor,
46
+ props.disabled
47
+ ]);
48
+ const isActionDisabled = editor === null || props.disabled || selectedTab !== 'editor';
49
+ const direction = props.sdk.locales.direction[props.sdk.field.locale] ?? 'ltr';
50
+ const actions = React.useMemo(()=>{
51
+ return createMarkdownActions({
52
+ sdk: props.sdk,
53
+ editor,
54
+ locale: props.sdk.field.locale
55
+ });
56
+ }, [
57
+ editor
58
+ ]);
59
+ const openMarkdownHelp = React.useCallback(()=>{
60
+ openCheatsheetModal(props.sdk.dialogs);
61
+ }, []);
62
+ return React.createElement("div", {
63
+ className: styles.container,
64
+ "data-test-id": "markdown-editor"
65
+ }, React.createElement(MarkdownTabs, {
66
+ active: selectedTab,
67
+ onSelect: (tab)=>{
68
+ setSelectedTab(tab);
69
+ }
70
+ }), React.createElement(MarkdownToolbar, {
71
+ mode: "default",
72
+ disabled: isActionDisabled,
73
+ canUploadAssets: canUploadAssets,
74
+ actions: actions
75
+ }), React.createElement(MarkdownTextarea, {
76
+ minHeight: props.minHeight,
77
+ mode: "default",
78
+ visible: selectedTab === 'editor',
79
+ disabled: isActionDisabled,
80
+ direction: direction,
81
+ onReady: (editor)=>{
82
+ editor.setContent(props.initialValue ?? '');
83
+ editor.setReadOnly(props.disabled);
84
+ setEditor(editor);
85
+ editor.events.onChange((value)=>{
86
+ const trimmedValue = value.replace(/^\s+$/gm, '');
87
+ props.saveValueToSDK(trimmedValue);
88
+ setCurrentValue(value);
89
+ });
90
+ }
91
+ }), selectedTab === 'preview' && React.createElement(MarkdownPreview, {
92
+ direction: direction,
93
+ minHeight: props.minHeight,
94
+ mode: "default",
95
+ value: currentValue,
96
+ previewComponents: props.previewComponents
97
+ }), React.createElement(MarkdownBottomBar, null, React.createElement(MarkdownHelp, {
98
+ onClick: openMarkdownHelp
99
+ })), React.createElement(MarkdownConstraints, {
100
+ sdk: props.sdk,
101
+ value: currentValue
102
+ }));
103
+ }
104
+ export function MarkdownEditorConnected(props) {
105
+ return React.createElement(FieldConnector, {
106
+ throttle: 300,
107
+ field: props.sdk.field,
108
+ isInitiallyDisabled: props.isInitiallyDisabled
109
+ }, ({ value , disabled , setValue , externalReset })=>{
110
+ return React.createElement(MarkdownEditor, {
111
+ ...props,
112
+ key: `markdown-editor-${externalReset}`,
113
+ initialValue: value,
114
+ disabled: disabled,
115
+ saveValueToSDK: setValue
116
+ });
117
+ });
118
+ }
@@ -0,0 +1,173 @@
1
+ import { createFakeCMAAdapter, createFakeFieldAPI, createFakeLocalesAPI, createFakeSpaceAPI } from '@contentful/field-editor-test-utils';
2
+ import { assets, contentTypes, entries, locales as localesFixtures, spaces } from './fixtures';
3
+ const newLink = (linkType, id)=>({
4
+ sys: {
5
+ id,
6
+ linkType,
7
+ type: 'Link'
8
+ }
9
+ });
10
+ export function newReferenceEditorFakeSdk(props) {
11
+ const rawInitialValue = window.localStorage.getItem('initialValue');
12
+ const initialValue = rawInitialValue ? JSON.parse(rawInitialValue) : props?.initialValue;
13
+ const rawValidations = window.localStorage.getItem('fieldValidations');
14
+ const validations = rawValidations ? JSON.parse(rawValidations) : props?.validations;
15
+ const customizeMock = (field)=>{
16
+ return validations ? {
17
+ ...field,
18
+ validations
19
+ } : field;
20
+ };
21
+ const [field, mitt] = createFakeFieldAPI(customizeMock, initialValue);
22
+ const space = createFakeSpaceAPI();
23
+ const locales = createFakeLocalesAPI();
24
+ const entryLinks = [
25
+ newLink('Entry', entries.published.sys.id),
26
+ newLink('Entry', entries.changed.sys.id),
27
+ newLink('Entry', entries.empty.sys.id)
28
+ ];
29
+ const assetLinks = [
30
+ newLink('Asset', assets.published.sys.id),
31
+ newLink('Asset', assets.changed.sys.id),
32
+ newLink('Asset', assets.empty.sys.id)
33
+ ];
34
+ let selectorCounter = 0;
35
+ const delay = (ms)=>{
36
+ return new Promise((resolve)=>setTimeout(resolve, ms));
37
+ };
38
+ const localizeContentTypes = (contentTypes)=>{
39
+ return contentTypes.map((contentType)=>({
40
+ ...contentType,
41
+ fields: contentType.fields.map((field)=>({
42
+ ...field,
43
+ localized: true
44
+ }))
45
+ }));
46
+ };
47
+ const sdk = {
48
+ field,
49
+ locales,
50
+ cmaAdapter: createFakeCMAAdapter({
51
+ Entry: {
52
+ get: async ({ entryId })=>{
53
+ if (props?.fetchDelay) {
54
+ await delay(props.fetchDelay);
55
+ }
56
+ if (entryId === entries.empty.sys.id) {
57
+ return entries.empty;
58
+ }
59
+ if (entryId === entries.published.sys.id) {
60
+ return entries.published;
61
+ }
62
+ if (entryId === entries.changed.sys.id) {
63
+ return entries.changed;
64
+ }
65
+ return Promise.reject({});
66
+ }
67
+ },
68
+ Asset: {
69
+ get: async ({ assetId })=>{
70
+ if (props?.fetchDelay) {
71
+ await delay(props.fetchDelay);
72
+ }
73
+ if (assetId === assets.empty.sys.id) {
74
+ return assets.empty;
75
+ }
76
+ if (assetId === assets.published.sys.id) {
77
+ return assets.published;
78
+ }
79
+ if (assetId === assets.changed.sys.id) {
80
+ return assets.changed;
81
+ }
82
+ return Promise.reject({});
83
+ }
84
+ },
85
+ Space: {
86
+ get: async (params)=>{
87
+ if (params.spaceId === spaces.indifferent.sys.id) {
88
+ return spaces.indifferent;
89
+ }
90
+ return Promise.reject({});
91
+ }
92
+ },
93
+ ContentType: {
94
+ get: async ({ contentTypeId })=>{
95
+ if (contentTypeId === contentTypes.published.sys.id) {
96
+ return contentTypes.published;
97
+ }
98
+ return Promise.reject({});
99
+ }
100
+ },
101
+ Locale: {
102
+ getMany: async ()=>localesFixtures.list
103
+ }
104
+ }),
105
+ space: {
106
+ ...space,
107
+ getCachedContentTypes () {
108
+ return localizeContentTypes(space.getCachedContentTypes());
109
+ },
110
+ getContentTypes () {
111
+ return Promise.resolve(space.getContentTypes().then((response)=>{
112
+ return {
113
+ ...response,
114
+ items: localizeContentTypes(response.items)
115
+ };
116
+ }));
117
+ },
118
+ async getEntityScheduledActions () {
119
+ return [];
120
+ }
121
+ },
122
+ dialogs: {
123
+ selectSingleAsset: async ()=>{
124
+ selectorCounter++;
125
+ return assetLinks[selectorCounter % assetLinks.length];
126
+ },
127
+ selectMultipleAssets: async ()=>{
128
+ selectorCounter++;
129
+ return selectorCounter % 2 ? assetLinks.slice(0, 2) : [
130
+ assetLinks[2]
131
+ ];
132
+ },
133
+ selectSingleEntry: async ()=>{
134
+ selectorCounter++;
135
+ return entryLinks[selectorCounter % entryLinks.length];
136
+ },
137
+ selectMultipleEntries: async ()=>{
138
+ selectorCounter++;
139
+ return selectorCounter % 2 ? entryLinks.slice(0, 2) : [
140
+ entryLinks[2]
141
+ ];
142
+ }
143
+ },
144
+ navigator: {
145
+ openNewAsset: async ()=>({
146
+ entity: newLink('Asset', assets.empty.sys.id)
147
+ }),
148
+ openAsset: async ()=>{
149
+ alert('open Asset in slide in');
150
+ return {};
151
+ },
152
+ openNewEntry: async ()=>({
153
+ entity: newLink('Entry', entries.empty.sys.id)
154
+ }),
155
+ openEntry: async ()=>{
156
+ alert('open entry in slide in');
157
+ return {};
158
+ },
159
+ onSlideInNavigation: ()=>()=>({})
160
+ },
161
+ access: {
162
+ can: async ()=>true
163
+ },
164
+ ids: {
165
+ space: 'space-id',
166
+ environment: 'environment-id'
167
+ }
168
+ };
169
+ return [
170
+ sdk,
171
+ mitt
172
+ ];
173
+ }
@@ -0,0 +1,6 @@
1
+ import changed from './changed_asset.json';
2
+ import created from './created_asset.json';
3
+ import empty from './empty_asset.json';
4
+ import invalid from './invalid_asset.json';
5
+ import published from './published_asset.json';
6
+ export { changed, empty, published, invalid, created };
@@ -0,0 +1,2 @@
1
+ import published from './published_content_type.json';
2
+ export { published };
@@ -0,0 +1,5 @@
1
+ import changed from './changed_entry.json';
2
+ import empty from './empty_entry.json';
3
+ import invalid from './invalid_entry.json';
4
+ import published from './published_entry.json';
5
+ export { changed, empty, published, invalid };
@@ -0,0 +1,6 @@
1
+ import * as assets from './asset';
2
+ import * as contentTypes from './content-type';
3
+ import * as entries from './entry';
4
+ import * as locales from './locale';
5
+ import * as spaces from './space';
6
+ export { assets, contentTypes, entries, locales, spaces };
@@ -0,0 +1,15 @@
1
+ import englishDefault from './english_default_locale.json';
2
+ import german from './german_locale.json';
3
+ const list = {
4
+ sys: {
5
+ type: 'Array'
6
+ },
7
+ total: 2,
8
+ skip: 0,
9
+ limit: 100,
10
+ items: [
11
+ englishDefault,
12
+ german
13
+ ]
14
+ };
15
+ export { englishDefault, german, list };
@@ -0,0 +1,2 @@
1
+ import indifferent from './indifferent_space.json';
2
+ export { indifferent };
@@ -0,0 +1,5 @@
1
+ import 'codemirror/mode/markdown/markdown';
2
+ import 'codemirror/mode/xml/xml';
3
+ import 'codemirror/addon/edit/continuelist';
4
+ import 'codemirror/addon/mode/overlay';
5
+ import 'codemirror/addon/display/autorefresh';
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import { Menu } from '@contentful/f36-components';
3
+ export const HeadingSelector = (props)=>{
4
+ const handleMenuClick = (heading)=>{
5
+ props.onSelect(heading);
6
+ };
7
+ return React.createElement(Menu, null, React.createElement(Menu.Trigger, null, props.children), React.createElement(Menu.List, null, React.createElement(Menu.Item, {
8
+ testId: "markdown-action-button-heading-h1",
9
+ onClick: ()=>handleMenuClick('h1')
10
+ }, "Heading 1"), React.createElement(Menu.Item, {
11
+ testId: "markdown-action-button-heading-h2",
12
+ onClick: ()=>handleMenuClick('h2')
13
+ }, "Heading 2"), React.createElement(Menu.Item, {
14
+ testId: "markdown-action-button-heading-h3",
15
+ onClick: ()=>handleMenuClick('h3')
16
+ }, "Heading 3")));
17
+ };
@@ -0,0 +1,37 @@
1
+ import * as React from 'react';
2
+ import { Button, Menu } from '@contentful/f36-components';
3
+ import { AssetIcon, ChevronDownIcon } from '@contentful/f36-icons';
4
+ export const InsertLinkSelector = (props)=>{
5
+ if (props.canAddNew) {
6
+ return React.createElement(MultipleMediaContextMenu, props);
7
+ } else {
8
+ return React.createElement(Button, {
9
+ isDisabled: props.disabled,
10
+ startIcon: React.createElement(AssetIcon, null),
11
+ testId: "markdownEditor.linkExistingAssets",
12
+ size: "small",
13
+ variant: "secondary",
14
+ onClick: ()=>{
15
+ props.onSelectExisting();
16
+ }
17
+ }, "Insert media");
18
+ }
19
+ };
20
+ const MultipleMediaContextMenu = (props)=>{
21
+ return React.createElement(Menu, {
22
+ placement: "bottom-end"
23
+ }, React.createElement(Menu.Trigger, null, React.createElement(Button, {
24
+ endIcon: React.createElement(ChevronDownIcon, null),
25
+ isDisabled: props.disabled,
26
+ startIcon: React.createElement(AssetIcon, null),
27
+ testId: "markdownEditor.insertMediaDropdownTrigger",
28
+ size: "small",
29
+ variant: "secondary"
30
+ }, "Insert media")), React.createElement(Menu.List, null, React.createElement(Menu.Item, {
31
+ testId: "markdownEditor.uploadAssetsAndLink",
32
+ onClick: ()=>props.onAddNew()
33
+ }, "Add new media and link"), React.createElement(Menu.Item, {
34
+ testId: "markdownEditor.linkExistingAssets",
35
+ onClick: ()=>props.onSelectExisting()
36
+ }, "Link existing media")));
37
+ };
@@ -0,0 +1,46 @@
1
+ import * as React from 'react';
2
+ import { Paragraph, TextLink } from '@contentful/f36-components';
3
+ import tokens from '@contentful/f36-tokens';
4
+ import { css } from 'emotion';
5
+ const styles = {
6
+ root: css({
7
+ display: 'flex',
8
+ justifyContent: 'space-between',
9
+ background: tokens.gray100,
10
+ border: `1px solid ${tokens.gray400}`,
11
+ borderBottomLeftRadius: tokens.borderRadiusSmall,
12
+ borderBottomRightRadius: tokens.borderRadiusSmall,
13
+ padding: `${tokens.spacingXs} ${tokens.spacingS}`
14
+ }),
15
+ help: css({
16
+ color: tokens.gray700,
17
+ fontSize: tokens.fontSizeS,
18
+ button: {
19
+ fontSize: tokens.fontSizeS,
20
+ lineHeight: 'inherit'
21
+ }
22
+ })
23
+ };
24
+ export function MarkdownCounter(props) {
25
+ return React.createElement(Paragraph, {
26
+ marginBottom: "none",
27
+ className: styles.help
28
+ }, props.words, " ", props.words !== 1 ? 'words' : 'word', ", ", props.characters, ' ', props.characters !== 1 ? 'characters' : 'character');
29
+ }
30
+ export function MarkdownHelp(props) {
31
+ return React.createElement(Paragraph, {
32
+ marginBottom: "none",
33
+ 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"), ".");
41
+ }
42
+ export function MarkdownBottomBar(props) {
43
+ return React.createElement("div", {
44
+ className: styles.root
45
+ }, props.children);
46
+ }
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import tokens from '@contentful/f36-tokens';
3
+ import { CharCounter, CharValidation, ConstraintsUtils } from '@contentful/field-editor-shared';
4
+ import { css } from 'emotion';
5
+ const styles = {
6
+ root: css({
7
+ display: 'flex',
8
+ justifyContent: 'space-between',
9
+ fontSize: tokens.fontSizeM,
10
+ marginTop: tokens.spacingXs,
11
+ color: tokens.gray700
12
+ })
13
+ };
14
+ export function MarkdownConstraints(props) {
15
+ const constraints = ConstraintsUtils.fromFieldValidations(props.sdk.field.validations, props.sdk.field.type);
16
+ const checkConstraint = ConstraintsUtils.makeChecker(constraints);
17
+ return React.createElement("div", {
18
+ className: styles.root
19
+ }, React.createElement(CharCounter, {
20
+ value: props.value,
21
+ checkConstraint: checkConstraint
22
+ }), React.createElement(CharValidation, {
23
+ constraints: constraints
24
+ }));
25
+ }