migrate file and image widgets
This commit is contained in:
parent
e80a407cee
commit
2efd09ba94
@ -4,13 +4,13 @@ import { GitLabBackend } from 'netlify-cms-backend-gitlab';
|
||||
import { GitGatewayBackend } from 'netlify-cms-backend-git-gateway';
|
||||
import { TestBackend } from 'netlify-cms-backend-test';
|
||||
import { BooleanControl } from 'netlify-cms-widget-boolean';
|
||||
import { StringControl, StringPreview } from 'netlify-cms-widget-string';
|
||||
import { DateControl, DatePreview } from 'netlify-cms-widget-date';
|
||||
import { DateTimeControl, DateTimePreview } from 'netlify-cms-widget-datetime';
|
||||
import { FileControl, FilePreview } from 'netlify-cms-widget-file';
|
||||
import { ImageControl, ImagePreview } from 'netlify-cms-widget-image';
|
||||
import { StringControl, StringPreview } from 'netlify-cms-widget-string';
|
||||
// import { NumberControl, NumberPreview } from 'netlify-cms-widget-number';
|
||||
// import { TextControl, TextPreview } from 'netlify-cms-widget-text';
|
||||
// import { ImageControl, ImagePreview } from 'netlify-cms-widget-image';
|
||||
// import { FileControl, FilePreview } from 'netlify-cms-widget-file';
|
||||
// import { SelectControl, SelectPreview } from 'netlify-cms-widget-select';
|
||||
// import { MarkdownControl, MarkdownPreview } from 'netlify-cms-widget-markdown';
|
||||
// import { ListControl, ListPreview } from 'netlify-cms-widget-list';
|
||||
@ -25,13 +25,13 @@ registerBackend('test-repo', TestBackend);
|
||||
registerWidget('boolean', BooleanControl);
|
||||
registerWidget('date', DateControl, DatePreview);
|
||||
registerWidget('datetime', DateTimeControl, DateTimePreview);
|
||||
registerWidget('file', FileControl, FilePreview);
|
||||
registerWidget('image', ImageControl, ImagePreview);
|
||||
registerWidget('string', StringControl, StringPreview);
|
||||
// registerWidget('text', TextControl, TextPreview);
|
||||
// registerWidget('number', NumberControl, NumberPreview);
|
||||
// registerWidget('list', ListControl, ListPreview);
|
||||
// registerWidget('markdown', MarkdownControl, MarkdownPreview);
|
||||
// registerWidget('image', ImageControl, ImagePreview);
|
||||
// registerWidget('file', FileControl, FilePreview);
|
||||
// registerWidget('select', SelectControl, SelectPreview);
|
||||
// registerWidget('object', ObjectControl, ObjectPreview);
|
||||
// registerWidget('relation', RelationControl, RelationPreview);
|
||||
|
@ -5,10 +5,6 @@ import NumberControl from './Number/NumberControl';
|
||||
import NumberPreview from './Number/NumberPreview';
|
||||
import TextControl from './Text/TextControl';
|
||||
import TextPreview from './Text/TextPreview';
|
||||
import ImageControl from './Image/ImageControl';
|
||||
import ImagePreview from './Image/ImagePreview';
|
||||
import FileControl from './File/FileControl';
|
||||
import FilePreview from './File/FilePreview';
|
||||
import SelectControl from './Select/SelectControl';
|
||||
import SelectPreview from './Select/SelectPreview';
|
||||
import MarkdownControl from './Markdown/MarkdownControl';
|
||||
@ -24,8 +20,6 @@ registerWidget('text', TextControl, TextPreview);
|
||||
registerWidget('number', NumberControl, NumberPreview);
|
||||
registerWidget('list', ListControl, ListPreview);
|
||||
registerWidget('markdown', MarkdownControl, MarkdownPreview);
|
||||
registerWidget('image', ImageControl, ImagePreview);
|
||||
registerWidget('file', FileControl, FilePreview);
|
||||
registerWidget('select', SelectControl, SelectPreview);
|
||||
registerWidget('object', ObjectControl, ObjectPreview);
|
||||
registerWidget('relation', RelationControl, RelationPreview);
|
||||
|
@ -1,10 +1,3 @@
|
||||
export function truncateMiddle(string = "", size) {
|
||||
if (string.length <= size) {
|
||||
return string;
|
||||
}
|
||||
return `${ string.substring(0, size / 2) }\u2026${ string.substring(string.length - size / 2 + 1, string.length) }`;
|
||||
}
|
||||
|
||||
export function stringToRGB(str) {
|
||||
if (!str) return "000000";
|
||||
let hash = 0;
|
||||
|
@ -214,10 +214,15 @@ const components = {
|
||||
border-top: 6px solid currentColor;
|
||||
border-radius: 2px;
|
||||
`,
|
||||
textBadge: css`
|
||||
${textBadge};
|
||||
color: ${colors.infoText};
|
||||
background-color: ${colors.infoBackground};
|
||||
`,
|
||||
textBadgeSuccess: css`
|
||||
${textBadge};
|
||||
color: ${colorsRaw.green};
|
||||
background-color: ${colorsRaw.greenLight};
|
||||
color: ${colors.successText};
|
||||
background-color: ${colors.successBackground};
|
||||
`,
|
||||
textBadgeDanger: css`
|
||||
${textBadge};
|
||||
|
@ -1,2 +1,2 @@
|
||||
export DateTimeControl from './DateTimeControl';
|
||||
export DateTimePreview from 'netlify-cms-widget-date';
|
||||
export { DatePreview as DateTimePreview } from 'netlify-cms-widget-date';
|
||||
|
34
packages/netlify-cms-widget-file/package.json
Normal file
34
packages/netlify-cms-widget-file/package.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "netlify-cms-widget-file",
|
||||
"description": "Widget for uploading files in Netlify CMS.",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"main": "dist/netlify-cms-widget-file.js",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"netlify",
|
||||
"netlify-cms",
|
||||
"widget",
|
||||
"file",
|
||||
"upload",
|
||||
"file-upload"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "webpack -w",
|
||||
"build": "webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"netlify-cms-ui-default": "^2.0.0-alpha.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6",
|
||||
"react-immutable-proptypes": "^2.1.0"
|
||||
}
|
||||
}
|
16
packages/netlify-cms-widget-file/src/FilePreview.js
Normal file
16
packages/netlify-cms-widget-file/src/FilePreview.js
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { WidgetPreviewContainer } from 'netlify-cms-ui-default';
|
||||
|
||||
const FilePreview = ({ value, getAsset }) => (
|
||||
<WidgetPreviewContainer>
|
||||
{ value ? <a href={getAsset(value)}>{ value }</a> : null}
|
||||
</WidgetPreviewContainer>
|
||||
);
|
||||
|
||||
FilePreview.propTypes = {
|
||||
getAsset: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
};
|
||||
|
||||
export default FilePreview;
|
5
packages/netlify-cms-widget-file/src/index.js
Normal file
5
packages/netlify-cms-widget-file/src/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
import withFileControl from './withFileControl';
|
||||
|
||||
export { withFileControl };
|
||||
export const FileControl = withFileControl();
|
||||
export FilePreview from './FilePreview';
|
167
packages/netlify-cms-widget-file/src/withFileControl.js
Normal file
167
packages/netlify-cms-widget-file/src/withFileControl.js
Normal file
@ -0,0 +1,167 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled from 'react-emotion';
|
||||
import uuid from 'uuid/v4';
|
||||
import { lengths, components, buttons } from 'netlify-cms-ui-default';
|
||||
|
||||
const MAX_DISPLAY_LENGTH = 50;
|
||||
|
||||
const FileContent = styled.div`
|
||||
display: flex;
|
||||
`
|
||||
|
||||
const ImageWrapper = styled.div`
|
||||
width: 155px;
|
||||
height: 100px;
|
||||
margin-right: 20px;
|
||||
`
|
||||
|
||||
const Image = styled.img`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: ${lengths.borderRadius};
|
||||
`
|
||||
|
||||
const FileInfo = styled.div`
|
||||
button:not(:first-child) {
|
||||
margin-top: 12px;
|
||||
}
|
||||
`
|
||||
|
||||
const FileName = styled.span`
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
`
|
||||
|
||||
const FileWidgetButton = styled.button`
|
||||
${buttons.button};
|
||||
${components.textBadge};
|
||||
display: block;
|
||||
`
|
||||
|
||||
const FileWidgetButtonRemove = styled.button`
|
||||
${buttons.button};
|
||||
${components.textBadgeDanger};
|
||||
display: block;
|
||||
`
|
||||
|
||||
export default function withFileControl({ forImage } = {}) {
|
||||
return class extends React.Component {
|
||||
static propTypes = {
|
||||
field: PropTypes.object.isRequired,
|
||||
getAsset: PropTypes.func.isRequired,
|
||||
mediaPaths: ImmutablePropTypes.map.isRequired,
|
||||
onAddAsset: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onRemoveInsertedMedia: PropTypes.func.isRequired,
|
||||
onOpenMediaLibrary: PropTypes.func.isRequired,
|
||||
classNameWrapper: PropTypes.string.isRequired,
|
||||
value: PropTypes.node,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
value: '',
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.controlID = uuid();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
/**
|
||||
* Always update if the value changes.
|
||||
*/
|
||||
if (this.props.value !== nextProps.value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a media path for this control in the state object, and that
|
||||
* path is different than the value in `nextProps`, update.
|
||||
*/
|
||||
const mediaPath = nextProps.mediaPaths.get(this.controlID);
|
||||
if (mediaPath && (nextProps.value !== mediaPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { mediaPaths, value, onRemoveInsertedMedia, onChange } = nextProps;
|
||||
const mediaPath = mediaPaths.get(this.controlID);
|
||||
if (mediaPath && mediaPath !== value) {
|
||||
onChange(mediaPath);
|
||||
} else if (mediaPath && mediaPath === value) {
|
||||
onRemoveInsertedMedia(this.controlID);
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = e => {
|
||||
const { field, onOpenMediaLibrary } = this.props;
|
||||
e.preventDefault();
|
||||
return onOpenMediaLibrary({
|
||||
controlID: this.controlID,
|
||||
forImage,
|
||||
privateUpload: field.get('private'),
|
||||
});
|
||||
};
|
||||
|
||||
handleRemove = e => {
|
||||
e.preventDefault();
|
||||
return this.props.onChange('');
|
||||
};
|
||||
|
||||
renderFileName = () => {
|
||||
const { value, classNameWrapper } = this.props;
|
||||
const size = MAX_DISPLAY_LENGTH;
|
||||
if (!value || value.length <= size) {
|
||||
return value;
|
||||
}
|
||||
return `${ value.substring(0, size / 2) }\u2026${ value.substring(value.length - size / 2 + 1, value.length) }`;
|
||||
};
|
||||
|
||||
renderSelection = (subject) => {
|
||||
const fileName = this.renderFileName();
|
||||
const { getAsset, value } = this.props;
|
||||
return (
|
||||
<FileContent>
|
||||
{ forImage ? <ImageWrapper><Image src={getAsset(value)}/></ImageWrapper> : null }
|
||||
<FileInfo>
|
||||
<FileName>{fileName}</FileName>
|
||||
<FileWidgetButton onClick={this.handleChange}>
|
||||
Choose different {subject}
|
||||
</FileWidgetButton>
|
||||
<FileWidgetButtonRemove onClick={this.handleRemove}>
|
||||
Remove {subject}
|
||||
</FileWidgetButtonRemove>
|
||||
</FileInfo>
|
||||
</FileContent>
|
||||
);
|
||||
};
|
||||
|
||||
renderNoSelection = (subject, article) => (
|
||||
<FileWidgetButton onClick={this.handleChange}>
|
||||
Choose {article} {subject}
|
||||
</FileWidgetButton>
|
||||
);
|
||||
|
||||
render() {
|
||||
const { value, classNameWrapper } = this.props;
|
||||
const subject = forImage ? 'image' : 'file';
|
||||
const article = forImage ? 'an' : 'a';
|
||||
|
||||
return (
|
||||
<div className={classNameWrapper}>
|
||||
<span>
|
||||
{ value ? this.renderSelection(subject) : this.renderNoSelection(subject, article) }
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
3
packages/netlify-cms-widget-file/webpack.config.js
Normal file
3
packages/netlify-cms-widget-file/webpack.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const { getConfig } = require('../../scripts/webpack.js');
|
||||
|
||||
module.exports = getConfig();
|
36
packages/netlify-cms-widget-image/package.json
Normal file
36
packages/netlify-cms-widget-image/package.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "netlify-cms-widget-image",
|
||||
"description": "Widget for uploading images in Netlify CMS.",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"main": "dist/netlify-cms-widget-image.js",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"netlify",
|
||||
"netlify-cms",
|
||||
"widget",
|
||||
"image",
|
||||
"upload",
|
||||
"image-upload"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "webpack -w",
|
||||
"build": "webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"netlify-cms-widget-file": "^2.0.0-alpha.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"netlify-cms-ui-default": "^2.0.0-alpha.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6"
|
||||
},
|
||||
"localExternals": [
|
||||
"netlify-cms-widget-file"
|
||||
]
|
||||
}
|
22
packages/netlify-cms-widget-image/src/ImagePreview.js
Normal file
22
packages/netlify-cms-widget-image/src/ImagePreview.js
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import { WidgetPreviewContainer } from 'netlify-cms-ui-default';
|
||||
|
||||
const Image = styled.img`
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
`
|
||||
|
||||
const ImagePreview = ({ value, getAsset }) => (
|
||||
<WidgetPreviewContainer>
|
||||
{ value ? <Image src={getAsset(value)} role="presentation"/> : null}
|
||||
</WidgetPreviewContainer>
|
||||
);
|
||||
|
||||
ImagePreview.propTypes = {
|
||||
getAsset: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
};
|
||||
|
||||
export default ImagePreview;
|
4
packages/netlify-cms-widget-image/src/index.js
Normal file
4
packages/netlify-cms-widget-image/src/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
import { withFileControl } from 'netlify-cms-widget-file';
|
||||
|
||||
export const ImageControl = withFileControl({ forImage: true });
|
||||
export ImagePreview from './ImagePreview';
|
3
packages/netlify-cms-widget-image/webpack.config.js
Normal file
3
packages/netlify-cms-widget-image/webpack.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const { getConfig } = require('../../scripts/webpack.js');
|
||||
|
||||
module.exports = getConfig();
|
Loading…
x
Reference in New Issue
Block a user