mirror of
https://github.com/strapi/strapi.git
synced 2025-11-23 13:40:58 +00:00
Add media lib in the example
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
90f437bc48
commit
373f77ac8a
@ -40,21 +40,99 @@ Once this step is over all we need to do is to create our new WYSIWYG which will
|
|||||||
|
|
||||||
### Creating the WYSIWYG
|
### Creating the WYSIWYG
|
||||||
|
|
||||||
In this part we will create two components:
|
In this part we will create three components:
|
||||||
|
|
||||||
|
- MediaLib which will be used to insert media in the editor
|
||||||
- Wysiwyg which will wrap the CKEditor with a label and the errors
|
- Wysiwyg which will wrap the CKEditor with a label and the errors
|
||||||
- CKEditor which will be the implementation of the new WYSIWYG
|
- CKEditor which will be the implementation of the new WYSIWYG
|
||||||
|
|
||||||
|
### Creating the MediaLib
|
||||||
|
|
||||||
|
**Path —** `./plugins/wysiwyg/admin/src/components/MediaLib/index.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useStrapi, prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const MediaLib = ({ isOpen, onChange, onToggle }) => {
|
||||||
|
const {
|
||||||
|
strapi: {
|
||||||
|
componentApi: { getComponent },
|
||||||
|
},
|
||||||
|
} = useStrapi();
|
||||||
|
const [data, setData] = useState(null);
|
||||||
|
const [isDisplayed, setIsDisplayed] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen) {
|
||||||
|
setIsDisplayed(true);
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const Component = getComponent('media-library').Component;
|
||||||
|
|
||||||
|
const handleInputChange = data => {
|
||||||
|
if (data) {
|
||||||
|
const { url } = data;
|
||||||
|
|
||||||
|
setData({ ...data, url: prefixFileUrlWithBackendUrl(url) });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClosed = () => {
|
||||||
|
if (data) {
|
||||||
|
onChange(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
setData(null);
|
||||||
|
setIsDisplayed(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Component && isDisplayed) {
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
allowedTypes={['images', 'videos', 'files']}
|
||||||
|
isOpen={isOpen}
|
||||||
|
multiple={false}
|
||||||
|
noNavigation
|
||||||
|
onClosed={handleClosed}
|
||||||
|
onInputMediaChange={handleInputChange}
|
||||||
|
onToggle={onToggle}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaLib.defaultProps = {
|
||||||
|
isOpen: false,
|
||||||
|
onChange: () => {},
|
||||||
|
onToggle: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaLib.propTypes = {
|
||||||
|
isOpen: PropTypes.bool,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
onToggle: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MediaLib;
|
||||||
|
```
|
||||||
|
|
||||||
#### Creating the WYSIWYG Wrapper
|
#### Creating the WYSIWYG Wrapper
|
||||||
|
|
||||||
**Path —** `./plugins/wysiwyg/admin/src/components/Wysiwyg/index.js`
|
**Path —** `./plugins/wysiwyg/admin/src/components/Wysiwyg/index.js`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import React from 'react';
|
iimport React, { useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
import { Button } from '@buffetjs/core';
|
||||||
import { Label, InputDescription, InputErrors } from 'strapi-helper-plugin';
|
import { Label, InputDescription, InputErrors } from 'strapi-helper-plugin';
|
||||||
import Editor from '../CKEditor';
|
import Editor from '../CKEditor';
|
||||||
|
import MediaLib from '../MediaLib';
|
||||||
|
|
||||||
const Wysiwyg = ({
|
const Wysiwyg = ({
|
||||||
inputDescription,
|
inputDescription,
|
||||||
@ -65,12 +143,28 @@ const Wysiwyg = ({
|
|||||||
onChange,
|
onChange,
|
||||||
value,
|
value,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
let spacer = !isEmpty(inputDescription) ? <div style={{ height: '.4rem' }} /> : <div />;
|
let spacer = !isEmpty(inputDescription) ? <div style={{ height: '.4rem' }} /> : <div />;
|
||||||
|
|
||||||
if (!noErrorsDescription && !isEmpty(errors)) {
|
if (!noErrorsDescription && !isEmpty(errors)) {
|
||||||
spacer = <div />;
|
spacer = <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleChange = data => {
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
if (data.mime.includes('image')) {
|
||||||
|
const imgTag = `<p><img src="${data.url}" caption="${data.caption}" alt="${data.alternativeText}"></img></p>`;
|
||||||
|
const newValue = value ? `${value}${imgTag}` : imgTag;
|
||||||
|
|
||||||
|
onChange({ target: { name, value: newValue } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle videos and other type of files
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleToggle = () => setIsOpen(prev => !prev);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -80,6 +174,11 @@ const Wysiwyg = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Label htmlFor={name} message={label} style={{ marginBottom: 10 }} />
|
<Label htmlFor={name} message={label} style={{ marginBottom: 10 }} />
|
||||||
|
<div>
|
||||||
|
<Button color="primary" onClick={handleToggle}>
|
||||||
|
MediaLib
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<Editor name={name} onChange={onChange} value={value} />
|
<Editor name={name} onChange={onChange} value={value} />
|
||||||
<InputDescription
|
<InputDescription
|
||||||
message={inputDescription}
|
message={inputDescription}
|
||||||
@ -87,6 +186,7 @@ const Wysiwyg = ({
|
|||||||
/>
|
/>
|
||||||
<InputErrors errors={(!noErrorsDescription && errors) || []} name={name} />
|
<InputErrors errors={(!noErrorsDescription && errors) || []} name={name} />
|
||||||
{spacer}
|
{spacer}
|
||||||
|
<MediaLib onToggle={handleToggle} isOpen={isOpen} onChange={handleChange} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -124,6 +224,7 @@ Wysiwyg.propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default Wysiwyg;
|
export default Wysiwyg;
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Implementing CKEditor
|
#### Implementing CKEditor
|
||||||
@ -146,11 +247,33 @@ const Wrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const configuration = {
|
||||||
|
toolbar: [
|
||||||
|
'heading',
|
||||||
|
'|',
|
||||||
|
'bold',
|
||||||
|
'italic',
|
||||||
|
'link',
|
||||||
|
'bulletedList',
|
||||||
|
'numberedList',
|
||||||
|
'|',
|
||||||
|
'indent',
|
||||||
|
'outdent',
|
||||||
|
'|',
|
||||||
|
'blockQuote',
|
||||||
|
'insertTable',
|
||||||
|
'mediaEmbed',
|
||||||
|
'undo',
|
||||||
|
'redo',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const Editor = ({ onChange, name, value }) => {
|
const Editor = ({ onChange, name, value }) => {
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<CKEditor
|
<CKEditor
|
||||||
editor={ClassicEditor}
|
editor={ClassicEditor}
|
||||||
|
config={configuration}
|
||||||
data={value}
|
data={value}
|
||||||
onChange={(event, editor) => {
|
onChange={(event, editor) => {
|
||||||
const data = editor.getData();
|
const data = editor.getData();
|
||||||
@ -164,7 +287,7 @@ const Editor = ({ onChange, name, value }) => {
|
|||||||
Editor.propTypes = {
|
Editor.propTypes = {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Editor;
|
export default Editor;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user