@vonaffenfels/contentful-slate-editor 1.2.15 → 1.2.19
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.
- package/.babelrc +37 -37
- package/.nvmrc +1 -1
- package/Readme.md +9 -9
- package/package.json +3 -3
- package/postcss.config.js +6 -6
- package/src/components/ConfigScreen.js +118 -118
- package/src/components/DialogCloudinary.js +51 -51
- package/src/components/DialogTranslation.js +316 -316
- package/src/components/EditorField.js +1 -1
- package/src/components/EntryEditor.js +50 -50
- package/src/components/Field.js +71 -71
- package/src/components/Sidebar.js +92 -92
- package/src/dev.js +4 -4
- package/src/hooks/useOnScreen.js +23 -23
- package/src/index.html +11 -11
- package/src/index.js +85 -85
- package/src/scss/dialog-cloudinary.scss +17 -17
- package/src/scss/index.scss +24 -24
- package/tailwind.config.js +4 -4
- package/webpack.config.dev.js +25 -25
- package/webpack.config.js +197 -197
package/.babelrc
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
{
|
|
2
|
-
"presets": [
|
|
3
|
-
"next/babel",
|
|
4
|
-
[
|
|
5
|
-
"@babel/preset-env",
|
|
6
|
-
{
|
|
7
|
-
"modules": false,
|
|
8
|
-
"targets": {
|
|
9
|
-
"browsers": [
|
|
10
|
-
"last 2 Chrome versions",
|
|
11
|
-
"last 2 Firefox versions",
|
|
12
|
-
"last 2 Safari versions",
|
|
13
|
-
"last 2 iOS versions",
|
|
14
|
-
"last 1 Android version",
|
|
15
|
-
"last 1 ChromeAndroid version",
|
|
16
|
-
"ie 11"
|
|
17
|
-
]
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
"@babel/preset-react"
|
|
22
|
-
],
|
|
23
|
-
"plugins": [
|
|
24
|
-
[
|
|
25
|
-
"@babel/plugin-proposal-private-property-in-object",
|
|
26
|
-
{
|
|
27
|
-
"loose": true
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
[
|
|
31
|
-
"@babel/plugin-proposal-class-properties",
|
|
32
|
-
{
|
|
33
|
-
"loose": true
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
"@babel/plugin-syntax-dynamic-import"
|
|
37
|
-
]
|
|
1
|
+
{
|
|
2
|
+
"presets": [
|
|
3
|
+
"next/babel",
|
|
4
|
+
[
|
|
5
|
+
"@babel/preset-env",
|
|
6
|
+
{
|
|
7
|
+
"modules": false,
|
|
8
|
+
"targets": {
|
|
9
|
+
"browsers": [
|
|
10
|
+
"last 2 Chrome versions",
|
|
11
|
+
"last 2 Firefox versions",
|
|
12
|
+
"last 2 Safari versions",
|
|
13
|
+
"last 2 iOS versions",
|
|
14
|
+
"last 1 Android version",
|
|
15
|
+
"last 1 ChromeAndroid version",
|
|
16
|
+
"ie 11"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"@babel/preset-react"
|
|
22
|
+
],
|
|
23
|
+
"plugins": [
|
|
24
|
+
[
|
|
25
|
+
"@babel/plugin-proposal-private-property-in-object",
|
|
26
|
+
{
|
|
27
|
+
"loose": true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
"@babel/plugin-proposal-class-properties",
|
|
32
|
+
{
|
|
33
|
+
"loose": true
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"@babel/plugin-syntax-dynamic-import"
|
|
37
|
+
]
|
|
38
38
|
}
|
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v14.16.1
|
|
1
|
+
v14.16.1
|
package/Readme.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# dev in other repo
|
|
2
|
-
contentful-apps and project in same folder
|
|
3
|
-
|
|
4
|
-
```shell
|
|
5
|
-
# in contentful-apps
|
|
6
|
-
yarn workspace @vonaffenfels/slate-editor buildWatch
|
|
7
|
-
|
|
8
|
-
# in project
|
|
9
|
-
yarn link ../contentful-apps --all
|
|
1
|
+
# dev in other repo
|
|
2
|
+
contentful-apps and project in same folder
|
|
3
|
+
|
|
4
|
+
```shell
|
|
5
|
+
# in contentful-apps
|
|
6
|
+
yarn workspace @vonaffenfels/slate-editor buildWatch
|
|
7
|
+
|
|
8
|
+
# in project
|
|
9
|
+
yarn link ../contentful-apps --all
|
|
10
10
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vonaffenfels/contentful-slate-editor",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.19",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepublish": "yarn run build",
|
|
6
6
|
"dev": "yarn run start",
|
|
@@ -95,10 +95,10 @@
|
|
|
95
95
|
"webpack-watch-files-plugin": "^1.2.1"
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@vonaffenfels/slate-editor": "^1.2.
|
|
98
|
+
"@vonaffenfels/slate-editor": "^1.2.19",
|
|
99
99
|
"webpack": "5.88.2"
|
|
100
100
|
},
|
|
101
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "aa2e077d950ae577347ebe01cd13860321b5141b",
|
|
102
102
|
"publishConfig": {
|
|
103
103
|
"access": "public"
|
|
104
104
|
}
|
package/postcss.config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
plugins: {
|
|
3
|
-
'postcss-import': {},
|
|
4
|
-
tailwindcss: {},
|
|
5
|
-
autoprefixer: {},
|
|
6
|
-
},
|
|
1
|
+
module.exports = {
|
|
2
|
+
plugins: {
|
|
3
|
+
'postcss-import': {},
|
|
4
|
+
tailwindcss: {},
|
|
5
|
+
autoprefixer: {},
|
|
6
|
+
},
|
|
7
7
|
};
|
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useEffect, useState,
|
|
3
|
-
} from 'react';
|
|
4
|
-
import {
|
|
5
|
-
Heading, Form, TextField, Workbench,
|
|
6
|
-
} from '@contentful/forma-36-react-components';
|
|
7
|
-
import {FormControl} from '@contentful/f36-components';
|
|
8
|
-
import {Multiselect} from '@contentful/f36-multiselect';
|
|
9
|
-
import {css} from 'emotion';
|
|
10
|
-
|
|
11
|
-
const Config = ({sdk}) => {
|
|
12
|
-
const [params, setParams] = useState({
|
|
13
|
-
translationService: "",
|
|
14
|
-
translationServiceKey: "",
|
|
15
|
-
usersWithTranslation: [],
|
|
16
|
-
});
|
|
17
|
-
const [spaceUsers, setSpaceUsers] = useState([]);
|
|
18
|
-
|
|
19
|
-
const onConfigure = async () => {
|
|
20
|
-
const currentState = await sdk.app.getCurrentState();
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
parameters: params,
|
|
24
|
-
targetState: currentState,
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const onFieldChanged = (value, field) => {
|
|
29
|
-
setParams({
|
|
30
|
-
...params,
|
|
31
|
-
[field]: value,
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
if (sdk) {
|
|
37
|
-
sdk.app.getParameters().then(params => {
|
|
38
|
-
setParams(params);
|
|
39
|
-
sdk.app.setReady();
|
|
40
|
-
});
|
|
41
|
-
sdk.space.getUsers().then(users => {
|
|
42
|
-
setSpaceUsers(users.items.map(v => v.email));
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}, [sdk]);
|
|
46
|
-
|
|
47
|
-
useEffect(() => {
|
|
48
|
-
if (sdk) {
|
|
49
|
-
sdk.app.onConfigure(() => onConfigure());
|
|
50
|
-
}
|
|
51
|
-
}, [sdk, params]);
|
|
52
|
-
|
|
53
|
-
const handleSelectItem = (event) => {
|
|
54
|
-
const {
|
|
55
|
-
checked,
|
|
56
|
-
value,
|
|
57
|
-
} = event.target;
|
|
58
|
-
|
|
59
|
-
let newValue = params?.usersWithTranslation || [];
|
|
60
|
-
if (checked) {
|
|
61
|
-
newValue = [...newValue, value];
|
|
62
|
-
} else {
|
|
63
|
-
newValue = newValue.filter((email) => email !== value);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
setParams({
|
|
67
|
-
...params,
|
|
68
|
-
usersWithTranslation: newValue,
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<Workbench className={css({
|
|
75
|
-
padding: '80px',
|
|
76
|
-
backgroundColor: "#FFF",
|
|
77
|
-
})}>
|
|
78
|
-
<Form>
|
|
79
|
-
<Heading>Configuration</Heading>
|
|
80
|
-
|
|
81
|
-
<FormControl>
|
|
82
|
-
<FormControl.Label>Benutzer mit Übersetzung im Editor</FormControl.Label>
|
|
83
|
-
<Multiselect
|
|
84
|
-
currentSelection={params.usersWithTranslation}
|
|
85
|
-
popoverProps={{isFullWidth: true}}
|
|
86
|
-
>
|
|
87
|
-
{spaceUsers.map((userEmail) => {
|
|
88
|
-
const val = userEmail.toLowerCase().replace(/\s/g, '-');
|
|
89
|
-
return (
|
|
90
|
-
<Multiselect.Option
|
|
91
|
-
key={`user-${val}}`}
|
|
92
|
-
itemId={val}
|
|
93
|
-
value={userEmail}
|
|
94
|
-
label={userEmail}
|
|
95
|
-
onSelectItem={handleSelectItem}
|
|
96
|
-
isChecked={params.usersWithTranslation?.includes(userEmail)}
|
|
97
|
-
/>
|
|
98
|
-
);
|
|
99
|
-
})}
|
|
100
|
-
</Multiselect>
|
|
101
|
-
</FormControl>
|
|
102
|
-
<TextField
|
|
103
|
-
value={params.translationService}
|
|
104
|
-
onChange={e => onFieldChanged(e.target.value, "translationService")}
|
|
105
|
-
labelText="Translation Service URL"
|
|
106
|
-
required
|
|
107
|
-
/>
|
|
108
|
-
<TextField
|
|
109
|
-
value={params.translationServiceKey}
|
|
110
|
-
onChange={e => onFieldChanged(e.target.value, "translationServiceKey")}
|
|
111
|
-
labelText="Translation Service API Key"
|
|
112
|
-
required
|
|
113
|
-
/>
|
|
114
|
-
</Form>
|
|
115
|
-
</Workbench>
|
|
116
|
-
);
|
|
117
|
-
};
|
|
118
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
useEffect, useState,
|
|
3
|
+
} from 'react';
|
|
4
|
+
import {
|
|
5
|
+
Heading, Form, TextField, Workbench,
|
|
6
|
+
} from '@contentful/forma-36-react-components';
|
|
7
|
+
import {FormControl} from '@contentful/f36-components';
|
|
8
|
+
import {Multiselect} from '@contentful/f36-multiselect';
|
|
9
|
+
import {css} from 'emotion';
|
|
10
|
+
|
|
11
|
+
const Config = ({sdk}) => {
|
|
12
|
+
const [params, setParams] = useState({
|
|
13
|
+
translationService: "",
|
|
14
|
+
translationServiceKey: "",
|
|
15
|
+
usersWithTranslation: [],
|
|
16
|
+
});
|
|
17
|
+
const [spaceUsers, setSpaceUsers] = useState([]);
|
|
18
|
+
|
|
19
|
+
const onConfigure = async () => {
|
|
20
|
+
const currentState = await sdk.app.getCurrentState();
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
parameters: params,
|
|
24
|
+
targetState: currentState,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const onFieldChanged = (value, field) => {
|
|
29
|
+
setParams({
|
|
30
|
+
...params,
|
|
31
|
+
[field]: value,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (sdk) {
|
|
37
|
+
sdk.app.getParameters().then(params => {
|
|
38
|
+
setParams(params);
|
|
39
|
+
sdk.app.setReady();
|
|
40
|
+
});
|
|
41
|
+
sdk.space.getUsers().then(users => {
|
|
42
|
+
setSpaceUsers(users.items.map(v => v.email));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}, [sdk]);
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (sdk) {
|
|
49
|
+
sdk.app.onConfigure(() => onConfigure());
|
|
50
|
+
}
|
|
51
|
+
}, [sdk, params]);
|
|
52
|
+
|
|
53
|
+
const handleSelectItem = (event) => {
|
|
54
|
+
const {
|
|
55
|
+
checked,
|
|
56
|
+
value,
|
|
57
|
+
} = event.target;
|
|
58
|
+
|
|
59
|
+
let newValue = params?.usersWithTranslation || [];
|
|
60
|
+
if (checked) {
|
|
61
|
+
newValue = [...newValue, value];
|
|
62
|
+
} else {
|
|
63
|
+
newValue = newValue.filter((email) => email !== value);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
setParams({
|
|
67
|
+
...params,
|
|
68
|
+
usersWithTranslation: newValue,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<Workbench className={css({
|
|
75
|
+
padding: '80px',
|
|
76
|
+
backgroundColor: "#FFF",
|
|
77
|
+
})}>
|
|
78
|
+
<Form>
|
|
79
|
+
<Heading>Configuration</Heading>
|
|
80
|
+
|
|
81
|
+
<FormControl>
|
|
82
|
+
<FormControl.Label>Benutzer mit Übersetzung im Editor</FormControl.Label>
|
|
83
|
+
<Multiselect
|
|
84
|
+
currentSelection={params.usersWithTranslation}
|
|
85
|
+
popoverProps={{isFullWidth: true}}
|
|
86
|
+
>
|
|
87
|
+
{spaceUsers.map((userEmail) => {
|
|
88
|
+
const val = userEmail.toLowerCase().replace(/\s/g, '-');
|
|
89
|
+
return (
|
|
90
|
+
<Multiselect.Option
|
|
91
|
+
key={`user-${val}}`}
|
|
92
|
+
itemId={val}
|
|
93
|
+
value={userEmail}
|
|
94
|
+
label={userEmail}
|
|
95
|
+
onSelectItem={handleSelectItem}
|
|
96
|
+
isChecked={params.usersWithTranslation?.includes(userEmail)}
|
|
97
|
+
/>
|
|
98
|
+
);
|
|
99
|
+
})}
|
|
100
|
+
</Multiselect>
|
|
101
|
+
</FormControl>
|
|
102
|
+
<TextField
|
|
103
|
+
value={params.translationService}
|
|
104
|
+
onChange={e => onFieldChanged(e.target.value, "translationService")}
|
|
105
|
+
labelText="Translation Service URL"
|
|
106
|
+
required
|
|
107
|
+
/>
|
|
108
|
+
<TextField
|
|
109
|
+
value={params.translationServiceKey}
|
|
110
|
+
onChange={e => onFieldChanged(e.target.value, "translationServiceKey")}
|
|
111
|
+
labelText="Translation Service API Key"
|
|
112
|
+
required
|
|
113
|
+
/>
|
|
114
|
+
</Form>
|
|
115
|
+
</Workbench>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
119
|
export default Config;
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useEffect, useRef,
|
|
3
|
-
} from 'react';
|
|
4
|
-
import "../scss/dialog-cloudinary.scss";
|
|
5
|
-
|
|
6
|
-
/* global cloudinary */
|
|
7
|
-
|
|
8
|
-
const DialogCloudinary = ({
|
|
9
|
-
sdk,
|
|
10
|
-
config,
|
|
11
|
-
activeConfig,
|
|
12
|
-
}) => {
|
|
13
|
-
const cloudinaryApiKey = activeConfig?.env?.CLOUDINARY_API_KEY;
|
|
14
|
-
const cloudinaryCloudName = activeConfig?.env?.CLOUDINARY_CLOUD_NAME;
|
|
15
|
-
|
|
16
|
-
const cloudinaryRef = useRef(null);
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
// sdk.window.startAutoResizer();
|
|
20
|
-
}, []);
|
|
21
|
-
|
|
22
|
-
const eventHandlers = {
|
|
23
|
-
insertHandler: (data) => {
|
|
24
|
-
sdk.close(data);
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const libraryOptions = {
|
|
29
|
-
cloud_name: cloudinaryCloudName,
|
|
30
|
-
api_key: cloudinaryApiKey,
|
|
31
|
-
remove_header: true,
|
|
32
|
-
max_files: config.max_files || undefined,
|
|
33
|
-
multiple: config.multiple || false,
|
|
34
|
-
insert_caption: 'Insert',
|
|
35
|
-
inline_container: '#cloudinary-root',
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (cloudinaryRef.current) {
|
|
40
|
-
const library = cloudinary.createMediaLibrary(libraryOptions, eventHandlers);
|
|
41
|
-
|
|
42
|
-
library.show(libraryOptions);
|
|
43
|
-
|
|
44
|
-
sdk.window.updateHeight(window.outerHeight);
|
|
45
|
-
}
|
|
46
|
-
}, [cloudinaryRef]);
|
|
47
|
-
|
|
48
|
-
return <div ref={cloudinaryRef} className="cloudinary-dialog" id="cloudinary-root"/>;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export default DialogCloudinary;
|
|
1
|
+
import React, {
|
|
2
|
+
useEffect, useRef,
|
|
3
|
+
} from 'react';
|
|
4
|
+
import "../scss/dialog-cloudinary.scss";
|
|
5
|
+
|
|
6
|
+
/* global cloudinary */
|
|
7
|
+
|
|
8
|
+
const DialogCloudinary = ({
|
|
9
|
+
sdk,
|
|
10
|
+
config,
|
|
11
|
+
activeConfig,
|
|
12
|
+
}) => {
|
|
13
|
+
const cloudinaryApiKey = activeConfig?.env?.CLOUDINARY_API_KEY;
|
|
14
|
+
const cloudinaryCloudName = activeConfig?.env?.CLOUDINARY_CLOUD_NAME;
|
|
15
|
+
|
|
16
|
+
const cloudinaryRef = useRef(null);
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
// sdk.window.startAutoResizer();
|
|
20
|
+
}, []);
|
|
21
|
+
|
|
22
|
+
const eventHandlers = {
|
|
23
|
+
insertHandler: (data) => {
|
|
24
|
+
sdk.close(data);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const libraryOptions = {
|
|
29
|
+
cloud_name: cloudinaryCloudName,
|
|
30
|
+
api_key: cloudinaryApiKey,
|
|
31
|
+
remove_header: true,
|
|
32
|
+
max_files: config.max_files || undefined,
|
|
33
|
+
multiple: config.multiple || false,
|
|
34
|
+
insert_caption: 'Insert',
|
|
35
|
+
inline_container: '#cloudinary-root',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (cloudinaryRef.current) {
|
|
40
|
+
const library = cloudinary.createMediaLibrary(libraryOptions, eventHandlers);
|
|
41
|
+
|
|
42
|
+
library.show(libraryOptions);
|
|
43
|
+
|
|
44
|
+
sdk.window.updateHeight(window.outerHeight);
|
|
45
|
+
}
|
|
46
|
+
}, [cloudinaryRef]);
|
|
47
|
+
|
|
48
|
+
return <div ref={cloudinaryRef} className="cloudinary-dialog" id="cloudinary-root"/>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default DialogCloudinary;
|