feat: upgrade to Emotion 10 (#2166)

This commit is contained in:
Shawn Erquhart 2019-03-15 10:19:57 -04:00 committed by GitHub
parent 7d6992e464
commit ccef446d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 4672 additions and 3875 deletions

View File

@ -17,6 +17,19 @@
},
"rules": {
"no-console": [0],
"react/prop-types": [1]
}
"react/prop-types": [1],
"no-duplicate-imports": "error",
"emotion/jsx-import": "error",
"emotion/no-vanilla": "error",
"emotion/import-from-emotion": "error",
"emotion/styled-import": "error"
},
"plugins": [
"emotion",
],
"settings": {
"react": {
"version": "detect",
},
},
}

View File

@ -1,14 +1,23 @@
{
"processors": ["stylelint-processor-styled-components"],
"processors": [
["stylelint-processor-styled-components", {
"parserPlugins": [
"jsx",
"objectRestSpread",
"exportDefaultFrom",
"classProperties",
],
}],
],
"extends": [
"stylelint-config-recommended",
"stylelint-config-styled-components"
"stylelint-config-styled-components",
],
"rules": {
"block-no-empty": null,
"no-duplicate-selectors": null,
"selector-type-no-unknown": [true, {
"ignoreTypes": ["$dummyValue"]
}]
}
"ignoreTypes": ["$dummyValue"],
}],
},
}

View File

@ -1,5 +1,5 @@
module.exports = {
setupTestFrameworkScriptFile: '<rootDir>/setupTestFramework.js',
setupFilesAfterEnv: ['<rootDir>/setupTestFramework.js'],
transform: {
'\\.js$': '<rootDir>/custom-preprocessor.js',
},

View File

@ -62,50 +62,54 @@
"last 2 ChromeAndroid versions"
],
"devDependencies": {
"@babel/cli": "^7.1.2",
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/cli": "^7.2.3",
"@babel/core": "^7.3.4",
"@babel/plugin-proposal-class-properties": "^7.3.4",
"@babel/plugin-proposal-export-default-from": "^7.2.0",
"@babel/plugin-proposal-object-rest-spread": "^7.3.4",
"@babel/preset-env": "^7.3.4",
"@babel/preset-react": "^7.0.0",
"all-contributors-cli": "^4.4.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.4",
"babel-plugin-emotion": "^9.2.11",
"babel-jest": "^24.5.0",
"babel-loader": "^8.0.5",
"babel-plugin-emotion": "^10.0.9",
"babel-plugin-inline-svg": "^1.0.0",
"babel-plugin-lodash": "^3.3.4",
"babel-plugin-module-resolver": "^3.1.1",
"babel-plugin-module-resolver": "^3.2.0",
"babel-plugin-transform-builtin-extend": "^1.1.2",
"babel-plugin-transform-export-extensions": "^6.22.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"cache-me-outside": "^0.0.4",
"cross-env": "^5.1.4",
"cypress": "^3.0.3",
"dom-testing-library": "^3.13.0",
"eslint": "^5.3.0",
"eslint-plugin-react": "^7.10.0",
"cypress": "^3.1.5",
"dom-testing-library": "^3.17.1",
"eslint": "^5.15.1",
"eslint-plugin-emotion": "^10.0.7",
"eslint-plugin-react": "^7.12.4",
"friendly-errors-webpack-plugin": "^1.7.0",
"http-server": "^0.11.1",
"jest": "^23.4.0",
"jest-cli": "^23.4.0",
"jest-emotion": "^9.2.7",
"lerna": "^3.4.0",
"jest": "^24.5.0",
"jest-cli": "^24.5.0",
"jest-emotion": "^10.0.9",
"lerna": "^3.13.1",
"npm-run-all": "^4.1.5",
"prettier": "1.14.0",
"react-test-renderer": "^16.0.0",
"rimraf": "^2.6.2",
"start-server-and-test": "^1.7.0",
"stylelint": "^9.4.0",
"prettier": "1.16.4",
"react-test-renderer": "^16.8.4",
"rimraf": "^2.6.3",
"start-server-and-test": "^1.7.11",
"stylelint": "^9.10.1",
"stylelint-config-recommended": "^2.1.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-processor-styled-components": "^1.3.1",
"stylelint-processor-styled-components": "^1.5.2",
"svg-inline-loader": "^0.8.0"
},
"workspaces": [
"packages/*"
],
"private": true
"private": true,
"dependencies": {
"emotion": "^10.0.9"
}
}

View File

@ -19,23 +19,23 @@
"build": "cross-env NODE_ENV=production webpack"
},
"dependencies": {
"js-base64": "^2.4.8",
"js-base64": "^2.5.1",
"semaphore": "^1.1.0"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-lib-auth": "^2.0.4",
"netlify-cms-lib-util": "^2.1.0",
"netlify-cms-ui-default": "^2.0.6",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
}
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { NetlifyAuthenticator } from 'netlify-cms-lib-auth';
import { AuthenticationPage, Icon } from 'netlify-cms-ui-default';

View File

@ -20,18 +20,19 @@
"build": "cross-env NODE_ENV=production webpack"
},
"dependencies": {
"gotrue-js": "^0.9.22",
"gotrue-js": "^0.9.24",
"ini": "^1.3.5",
"jwt-decode": "^2.2.0",
"minimatch": "^3.0.4"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-backend-bitbucket": "^2.0.0",
@ -41,7 +42,6 @@
"netlify-cms-lib-util": "^2.0.0",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
}
}

View File

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import React from 'react';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { partial } from 'lodash';
import {
AuthenticationPage,

View File

@ -20,22 +20,22 @@
},
"dependencies": {
"common-tags": "^1.8.0",
"js-base64": "^2.4.8",
"js-base64": "^2.5.1",
"semaphore": "^1.1.0"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"lodash": "^4.17.10",
"netlify-cms-lib-auth": "^2.0.0",
"netlify-cms-lib-util": "^2.0.0",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
}
}

View File

@ -1,8 +1,12 @@
import { localForage } from 'netlify-cms-lib-util';
import { Base64 } from 'js-base64';
import { uniq, initial, last, get, find, hasIn, partial, result } from 'lodash';
import { filterPromises, resolvePromiseProperties } from 'netlify-cms-lib-util';
import { APIError, EditorialWorkflowError } from 'netlify-cms-lib-util';
import {
localForage,
filterPromises,
resolvePromiseProperties,
APIError,
EditorialWorkflowError,
} from 'netlify-cms-lib-util';
const CMS_BRANCH_PREFIX = 'cms/';
@ -222,8 +226,8 @@ export default class API {
}
readUnpublishedBranchFile(contentKey) {
const metaDataPromise = this.retrieveMetadata(contentKey).then(
data => (data.objects.entry.path ? data : Promise.reject(null)),
const metaDataPromise = this.retrieveMetadata(contentKey).then(data =>
data.objects.entry.path ? data : Promise.reject(null),
);
return resolvePromiseProperties({
metaData: metaDataPromise,

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { NetlifyAuthenticator } from 'netlify-cms-lib-auth';
import { AuthenticationPage, Icon } from 'netlify-cms-ui-default';

View File

@ -19,23 +19,23 @@
"build": "cross-env NODE_ENV=production webpack"
},
"dependencies": {
"js-base64": "^2.4.8",
"js-base64": "^2.5.1",
"semaphore": "^1.1.0"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-lib-auth": "^2.0.0",
"netlify-cms-lib-util": "^2.0.0",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
}
}

View File

@ -129,8 +129,7 @@ export default class API {
.update(list => Map(list));
const actions = links
.keySeq()
.flatMap(
key =>
.flatMap(key =>
(key === 'prev' && index > 0) ||
(key === 'next' && index < pageCount) ||
(key === 'first' && index > 0) ||

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { NetlifyAuthenticator, ImplicitAuthenticator } from 'netlify-cms-lib-auth';
import { AuthenticationPage, Icon } from 'netlify-cms-ui-default';

View File

@ -22,18 +22,18 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.8.2",
"lodash": "^4.17.10",
"netlify-cms-lib-util": "^2.0.0",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-emotion": "^9.2.6",
"react-immutable-proptypes": "^2.1.0"
}
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Icon, buttons, shadows } from 'netlify-cms-ui-default';
const StyledAuthenticationPage = styled.section`

View File

@ -1,7 +1,6 @@
import { attempt, isError, take } from 'lodash';
import uuid from 'uuid/v4';
import { EditorialWorkflowError } from 'netlify-cms-lib-util';
import { Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
import { EditorialWorkflowError, Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
import AuthenticationPage from './AuthenticationPage';
window.repoFiles = window.repoFiles || {};

View File

@ -19,44 +19,44 @@
],
"license": "MIT",
"dependencies": {
"ajv": "^6.4.0",
"ajv-errors": "^1.0.0",
"copy-text-to-clipboard": "^1.0.4",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"ajv": "^6.10.0",
"ajv-errors": "^1.0.1",
"copy-text-to-clipboard": "^2.0.0",
"diacritics": "^1.3.0",
"emotion": "^9.2.6",
"fuzzy": "^0.1.1",
"gotrue-js": "^0.9.15",
"gray-matter": "^4.0.1",
"gotrue-js": "^0.9.24",
"gray-matter": "^4.0.2",
"history": "^4.7.2",
"immutable": "^3.7.6",
"js-base64": "^2.1.9",
"js-yaml": "^3.10.0",
"js-base64": "^2.5.1",
"js-yaml": "^3.12.2",
"jwt-decode": "^2.1.0",
"lodash": "^4.17.10",
"moment": "^2.11.2",
"lodash": "^4.17.11",
"moment": "^2.24.0",
"netlify-cms-editor-component-image": "^2.2.0",
"netlify-cms-lib-auth": "^2.0.5",
"netlify-cms-lib-util": "^2.1.2",
"netlify-cms-ui-default": "^2.4.1-alpha.0",
"node-polyglot": "^2.3.0",
"prop-types": "^15.5.10",
"react": "^16.8.1",
"react-dnd": "^7.0.0",
"react-dnd-html5-backend": "^7.0.0",
"react-dom": "^16.8.1",
"react-emotion": "^9.2.5",
"react-frame-component": "^4.0.2",
"react-hot-loader": "^4.0.0",
"prop-types": "^15.7.2",
"react": "^16.8.4",
"react-dnd": "^7.3.2",
"react-dnd-html5-backend": "^7.2.0",
"react-dom": "^16.8.4",
"react-frame-component": "^4.1.0",
"react-hot-loader": "^4.8.0",
"react-immutable-proptypes": "^2.1.0",
"react-is": "16.3.1",
"react-modal": "^3.1.5",
"react-is": "16.8.4",
"react-modal": "^3.8.1",
"react-polyglot": "^0.2.6",
"react-redux": "^5.1.1",
"react-router-dom": "^4.2.2",
"react-router-redux": "^5.0.0-alpha.8",
"react-scroll-sync": "^0.6.0",
"react-sortable-hoc": "^0.6.8",
"react-split-pane": "^0.1.82",
"react-split-pane": "^0.1.85",
"react-topbar-progress-indicator": "^2.0.0",
"react-waypoint": "^8.1.0",
"redux": "^4.0.1",
@ -68,13 +68,13 @@
"toml-j0.4": "^1.1.1",
"tomlify-j0.4": "^3.0.0-alpha.0",
"url": "^0.11.0",
"what-input": "^5.0.3"
"what-input": "^5.1.4"
},
"devDependencies": {
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"css-loader": "^2.1.1",
"to-string-loader": "^1.1.5",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
}
}

View File

@ -3,7 +3,6 @@ import { Map } from 'immutable';
import { stripIndent } from 'common-tags';
import moment from 'moment';
import fuzzy from 'fuzzy';
import { localForage } from 'netlify-cms-lib-util';
import { resolveFormat } from 'Formats/formats';
import { selectIntegration } from 'Reducers/integrations';
import {
@ -19,7 +18,7 @@ import {
import { createEntry } from 'ValueObjects/Entry';
import { sanitizeSlug } from 'Lib/urlHelper';
import { getBackend } from 'Lib/registry';
import { Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
import { localForage, Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
import { EDITORIAL_WORKFLOW, status } from 'Constants/publishModes';
class LocalStorageAuthStore {

View File

@ -8,6 +8,7 @@ import store from 'Redux';
import { mergeConfig } from 'Actions/config';
import { getPhrases } from 'Constants/defaultPhrases';
import { I18n } from 'react-polyglot';
import { GlobalStyles } from 'netlify-cms-ui-default';
import { ErrorBoundary } from 'UI';
import App from 'App/App';
import 'EditorWidgets';
@ -62,6 +63,8 @@ function bootstrap(opts = {}) {
* Create connected root component.
*/
const Root = () => (
<>
<GlobalStyles />
<I18n locale={'en'} messages={getPhrases()}>
<ErrorBoundary showBackup>
<Provider store={store}>
@ -71,6 +74,7 @@ function bootstrap(opts = {}) {
</Provider>
</ErrorBoundary>
</I18n>
</>
);
/**

View File

@ -3,7 +3,7 @@ import React from 'react';
import { hot } from 'react-hot-loader';
import { translate } from 'react-polyglot';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { connect } from 'react-redux';
import { Route, Switch, Redirect } from 'react-router-dom';
import { Notifs } from 'redux-notifications';

View File

@ -1,7 +1,9 @@
/** @jsx jsx */
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import { jsx, css } from '@emotion/core';
import { translate } from 'react-polyglot';
import { NavLink } from 'react-router-dom';
import {
@ -22,7 +24,9 @@ const styles = {
`,
};
const AppHeader = styled.header`
const AppHeader = props => (
<header
css={css`
${shadows.dropMain};
position: sticky;
width: 100%;
@ -30,7 +34,10 @@ const AppHeader = styled.header`
background-color: ${colors.foreground};
z-index: 300;
height: ${lengths.topBarHeight};
`;
`}
{...props}
/>
);
const AppHeaderContent = styled.div`
display: flex;

View File

@ -1,5 +1,5 @@
import React from 'react';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { translate } from 'react-polyglot';
import { lengths } from 'netlify-cms-ui-default';
import PropTypes from 'prop-types';

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { connect } from 'react-redux';
import { lengths } from 'netlify-cms-ui-default';
import { getNewEntryUrl } from 'Lib/urlHelper';

View File

@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { translate } from 'react-polyglot';
import { Link } from 'react-router-dom';
import { Icon, components, buttons, shadows, colors } from 'netlify-cms-ui-default';

View File

@ -1,5 +1,5 @@
import React from 'react';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Link } from 'react-router-dom';
import { resolvePath } from 'netlify-cms-lib-util';
import { colors, colorsRaw, components, lengths } from 'netlify-cms-ui-default';

View File

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import Waypoint from 'react-waypoint';
import { Map } from 'immutable';
import { Cursor } from 'netlify-cms-lib-util';

View File

@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import { translate } from 'react-polyglot';
import { NavLink } from 'react-router-dom';
import { Icon, components, colors, colorsRaw, lengths } from 'netlify-cms-ui-default';

View File

@ -31,8 +31,7 @@ import { loadDeployPreview } from 'Actions/deploys';
import { deserializeValues } from 'Lib/serializeEntryValues';
import { selectEntry, selectUnpublishedEntry, selectDeployPreview, getAsset } from 'Reducers';
import { selectFields } from 'Reducers/collections';
import { status } from 'Constants/publishModes';
import { EDITORIAL_WORKFLOW } from 'Constants/publishModes';
import { status, EDITORIAL_WORKFLOW } from 'Constants/publishModes';
import EditorInterface from './EditorInterface';
import withWorkflow from './withWorkflow';

View File

@ -1,16 +1,17 @@
/** @jsx jsx */
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { translate } from 'react-polyglot';
import styled, { css, cx } from 'react-emotion';
import { jsx, ClassNames, Global, css as coreCss } from '@emotion/core';
import styled from '@emotion/styled';
import { partial, uniqueId } from 'lodash';
import { connect } from 'react-redux';
import { colors, colorsRaw, transitions, lengths, borders } from 'netlify-cms-ui-default';
import { resolveWidget, getEditorComponents } from 'Lib/registry';
import { clearFieldErrors } from 'Actions/entries';
import { clearFieldErrors, loadEntry } from 'Actions/entries';
import { addAsset } from 'Actions/media';
import { query, clearSearch } from 'Actions/search';
import { loadEntry } from 'Actions/entries';
import {
openMediaLibrary,
removeInsertedMedia,
@ -20,8 +21,13 @@ import {
import { getAsset } from 'Reducers';
import Widget from './Widget';
const styles = {
label: css`
/**
* This is a necessary bridge as we are still passing classnames to widgets
* for styling. Once that changes we can stop storing raw style strings like
* this.
*/
const styleStrings = {
label: `
color: ${colors.controlLabel};
background-color: ${colors.textFieldBorder};
display: inline-block;
@ -55,15 +61,15 @@ const styles = {
background-color: #fff;
}
`,
labelActive: css`
labelActive: `
background-color: ${colors.active};
color: ${colors.textLight};
`,
labelError: css`
labelError: `
background-color: ${colors.errorText};
color: ${colorsRaw.white};
`,
widget: css`
widget: `
display: block;
width: 100%;
padding: ${lengths.inputPadding};
@ -85,10 +91,10 @@ const styles = {
height: 58px;
}
`,
widgetActive: css`
widgetActive: `
border-color: ${colors.active};
`,
widgetError: css`
widgetError: `
border-color: ${colors.errorText};
`,
};
@ -96,7 +102,7 @@ const styles = {
const ControlContainer = styled.div`
margin-top: 16px;
&:first-child {
&:first-of-type {
margin-top: 36px;
}
`;
@ -117,8 +123,8 @@ export const ControlHint = styled.p`
margin-bottom: 0;
padding: 3px 0;
font-size: 12px;
color: ${({ active, error }) =>
error ? colors.errorText : active ? colors.active : colors.controlLabel};
color: ${props =>
props.error ? colors.errorText : props.active ? colors.active : colors.controlLabel};
transition: color ${transitions.main};
`;
@ -191,22 +197,35 @@ class EditorControl extends React.Component {
const metadata = fieldsMetaData && fieldsMetaData.get(fieldName);
const errors = fieldsErrors && fieldsErrors.get(this.uniqueFieldId);
return (
<ClassNames>
{({ css, cx }) => (
<ControlContainer>
{widget.globalStyles && <Global styles={coreCss`${widget.globalStyles}`} />}
<ControlErrorsList>
{errors &&
errors.map(
error =>
error.message &&
typeof error.message === 'string' && (
<li key={error.message.trim().replace(/[^a-z0-9]+/gi, '-')}>{error.message}</li>
<li key={error.message.trim().replace(/[^a-z0-9]+/gi, '-')}>
{error.message}
</li>
),
)}
</ControlErrorsList>
<label
className={cx(
styles.label,
{ [styles.labelActive]: this.state.styleActive },
{ [styles.labelError]: !!errors },
css`
${styleStrings.label};
`,
this.state.styleActive &&
css`
${styleStrings.labelActive};
`,
!!errors &&
css`
${styleStrings.labelError};
`,
)}
htmlFor={this.uniqueFieldId}
>
@ -214,14 +233,32 @@ class EditorControl extends React.Component {
</label>
<Widget
classNameWrapper={cx(
styles.widget,
{ [styles.widgetActive]: this.state.styleActive },
{ [styles.widgetError]: !!errors },
css`
${styleStrings.widget};
`,
{
[css`
${styleStrings.widgetActive};
`]: this.state.styleActive,
},
{
[css`
${styleStrings.widgetError};
`]: !!errors,
},
)}
classNameWidget={styles.widget}
classNameWidgetActive={styles.widgetActive}
classNameLabel={styles.label}
classNameLabelActive={styles.labelActive}
classNameWidget={css`
${styleStrings.widget};
`}
classNameWidgetActive={css`
${styleStrings.widgetActive};
`}
classNameLabel={css`
${styleStrings.label};
`}
classNameLabelActive={css`
${styleStrings.labelActive};
`}
controlComponent={widget.control}
field={field}
uniqueFieldId={this.uniqueFieldId}
@ -260,6 +297,8 @@ class EditorControl extends React.Component {
</ControlHint>
)}
</ControlContainer>
)}
</ClassNames>
);
}
}

View File

@ -1,17 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import EditorControl, { ControlHint } from './EditorControl';
import styled from '@emotion/styled';
import EditorControl from './EditorControl';
const ControlPaneContainer = styled.div`
max-width: 800px;
margin: 0 auto;
padding-bottom: 16px;
p:not(${ControlHint}) {
font-size: 16px;
}
`;
export default class ControlPane extends React.Component {
@ -56,8 +53,7 @@ export default class ControlPane extends React.Component {
return (
<ControlPaneContainer>
{fields.map(
(field, i) =>
{fields.map((field, i) =>
field.get('widget') === 'hidden' ? null : (
<EditorControl
key={i}

View File

@ -1,7 +1,8 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css, injectGlobal } from 'react-emotion';
import { css, Global } from '@emotion/core';
import styled from '@emotion/styled';
import SplitPane from 'react-split-pane';
import { colors, colorsRaw, components, transitions } from 'netlify-cms-ui-default';
import { ScrollSync, ScrollSyncPane } from 'react-scroll-sync';
@ -25,10 +26,9 @@ const styles = {
`,
};
injectGlobal`
/**
* React Split Pane
*/
const ReactSplitPaneGlobalStyles = () => (
<Global
styles={css`
.Resizer.vertical {
width: 21px;
cursor: col-resize;
@ -50,8 +50,9 @@ injectGlobal`
background-color: ${colorsRaw.GrayLight};
}
}
`;
`}
/>
);
const StyledSplitPane = styled(SplitPane)`
${styles.splitPane};
@ -195,6 +196,7 @@ class EditorInterface extends Component {
const editorWithPreview = (
<ScrollSync enabled={this.state.scrollSyncEnabled}>
<div>
<ReactSplitPaneGlobalStyles />
<StyledSplitPane
maxSize={-100}
defaultSize="50%"

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
function isVisible(field) {
return field.get('widget') !== 'hidden';

View File

@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { List, Map } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Frame from 'react-frame-component';

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Icon, colors, colorsRaw, shadows, buttons } from 'netlify-cms-ui-default';
const EditorToggleButton = styled.button`

View File

@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css } from 'react-emotion';
import { css } from '@emotion/core';
import styled from '@emotion/styled';
import { translate } from 'react-polyglot';
import { Map } from 'immutable';
import { Link } from 'react-router-dom';

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { colors } from 'netlify-cms-ui-default';
const EmptyMessageContainer = styled.div`

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import { css } from '@emotion/core';
import styled from '@emotion/styled';
import { FileUploadButton } from 'UI';
import { buttons, shadows } from 'netlify-cms-ui-default';

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { colors, borders, lengths, shadows, effects } from 'netlify-cms-ui-default';
const IMAGE_HEIGHT = 160;

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import Waypoint from 'react-waypoint';
import MediaLibraryCard from './MediaLibraryCard';
import { Map } from 'immutable';

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Icon, shadows, colors, buttons } from 'netlify-cms-ui-default';
const CloseButton = styled.button`

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { isEmpty } from 'lodash';
import { translate } from 'react-polyglot';
import { Modal } from 'UI';

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Icon, lengths, colors } from 'netlify-cms-ui-default';
const SearchContainer = styled.div`

View File

@ -1,19 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-polyglot';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import copyToClipboard from 'copy-text-to-clipboard';
import { localForage } from 'netlify-cms-lib-util';
import { buttons, colors } from 'netlify-cms-ui-default';
const ISSUE_URL = 'https://github.com/netlify/netlify-cms/issues/new?template=bug_report.md';
const styles = {
errorBoundary: css`
const ErrorBoundaryContainer = styled.div`
padding: 40px;
h1 {
font-size: 28px;
color: ${colors.text};
}
h2 {
@ -32,11 +32,11 @@ const styles = {
height: 1px;
background-color: ${colors.text};
}
`,
errorText: css`
color: ${colors.errorText};
`,
};
a {
color: ${colors.text};
}
`;
const CopyButton = styled.button`
${buttons.button};
@ -104,16 +104,11 @@ class ErrorBoundary extends React.Component {
return this.props.children;
}
return (
<div className={styles.errorBoundary}>
<h1 className={styles.errorBoundaryText}>{t('ui.errorBoundary.title')}</h1>
<ErrorBoundaryContainer>
<h1>{t('ui.errorBoundary.title')}</h1>
<p>
<span>{t('ui.errorBoundary.details')}</span>
<a
href={ISSUE_URL}
target="_blank"
rel="noopener noreferrer"
className={styles.errorBoundaryText}
>
<a href={ISSUE_URL} target="_blank" rel="noopener noreferrer">
{t('ui.errorBoundary.reportIt')}
</a>
</p>
@ -121,7 +116,7 @@ class ErrorBoundary extends React.Component {
<h2>{t('ui.errorBoundary.detailsHeading')}</h2>
<p>{errorMessage}</p>
{backup && showBackup && <RecoveredEntry entry={backup} t={t} />}
</div>
</ErrorBoundaryContainer>
);
}
}

View File

@ -1,17 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import { css, cx, injectGlobal } from 'react-emotion';
import { css, Global, ClassNames } from '@emotion/core';
import ReactModal from 'react-modal';
import { transitions, shadows, lengths } from 'netlify-cms-ui-default';
injectGlobal`
const ReactModalGlobalStyles = () => (
<Global
styles={css`
.ReactModal__Body--open {
overflow: hidden;
}
`;
`}
/>
);
const styles = {
modalBody: css`
const styleStrings = {
modalBody: `
${shadows.dropDeep};
background-color: #fff;
border-radius: ${lengths.borderRadius};
@ -24,7 +28,7 @@ const styles = {
outline: none;
}
`,
overlay: css`
overlay: `
z-index: 99999;
position: fixed;
top: 0;
@ -38,11 +42,11 @@ const styles = {
background-color: rgba(0, 0, 0, 0);
transition: background-color ${transitions.main}, opacity ${transitions.main};
`,
overlayAfterOpen: css`
overlayAfterOpen: `
background-color: rgba(0, 0, 0, 0.6);
opacity: 1;
`,
overlayBeforeClose: css`
overlayBeforeClose: `
background-color: rgba(0, 0, 0, 0);
opacity: 0;
`,
@ -63,23 +67,41 @@ export class Modal extends React.Component {
render() {
const { isOpen, children, className, onClose } = this.props;
return (
<>
<ReactModalGlobalStyles />
<ClassNames>
{({ css, cx }) => (
<ReactModal
isOpen={isOpen}
onRequestClose={onClose}
closeTimeoutMS={300}
className={{
base: cx(styles.modalBody, className),
base: cx(
css`
${styleStrings.modalBody};
`,
className,
),
afterOpen: '',
beforeClose: '',
}}
overlayClassName={{
base: styles.overlay,
afterOpen: styles.overlayAfterOpen,
beforeClose: styles.overlayBeforeClose,
base: css`
${styleStrings.overlay};
`,
afterOpen: css`
${styleStrings.overlayAfterOpen};
`,
beforeClose: css`
${styleStrings.overlayBeforeClose};
`,
}}
>
{children}
</ReactModal>
)}
</ClassNames>
</>
);
}
}

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import { css } from '@emotion/core';
import styled from '@emotion/styled';
import { translate } from 'react-polyglot';
import { Icon, Dropdown, DropdownItem, DropdownButton, colors } from 'netlify-cms-ui-default';
import { stripProtocol } from 'Lib/urlHelper';

View File

@ -1,18 +1,24 @@
/** @jsx jsx */
// eslint-disable-next-line no-unused-vars
import React from 'react';
import PropTypes from 'prop-types';
import { css, injectGlobal, cx } from 'react-emotion';
import { jsx, css, Global } from '@emotion/core';
import { translate } from 'react-polyglot';
import reduxNotificationsStyles from 'redux-notifications/lib/styles.css';
import { shadows, colors, lengths } from 'netlify-cms-ui-default';
injectGlobal`
const ReduxNotificationsGlobalStyles = () => (
<Global
styles={css`
${reduxNotificationsStyles};
.notif__container {
z-index: 10000;
white-space: pre-wrap;
}
`;
`}
/>
);
const styles = {
toast: css`
@ -43,7 +49,8 @@ const styles = {
};
const Toast = ({ kind, message, t }) => (
<div className={cx(styles.toast, styles[kind])}>
<div css={[styles.toast, styles[kind]]}>
<ReduxNotificationsGlobalStyles />
{t(message.key, { details: message.details })}
</div>
);

View File

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { OrderedMap } from 'immutable';
import { translate } from 'react-polyglot';
import { connect } from 'react-redux';

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import { css } from '@emotion/core';
import styled from '@emotion/styled';
import { translate } from 'react-polyglot';
import { Link } from 'react-router-dom';
import { components, colors, colorsRaw, transitions, buttons } from 'netlify-cms-ui-default';

View File

@ -1,7 +1,9 @@
/** @jsx jsx */
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css, cx } from 'react-emotion';
import { jsx, css } from '@emotion/core';
import styled from '@emotion/styled';
import moment from 'moment';
import { translate } from 'react-polyglot';
import { colors, lengths } from 'netlify-cms-ui-default';
@ -16,22 +18,16 @@ const WorkflowListContainer = styled.div`
`;
const styles = {
column: css`
margin: 0 20px;
transition: background-color 0.5s ease;
border: 2px dashed transparent;
border-radius: 4px;
position: relative;
&:first-child {
columnPosition: idx =>
(idx === 0 &&
css`
margin-left: 0;
}
&:last-child {
`) ||
(idx === 2 &&
css`
margin-right: 0;
}
&:not(:first-child):not(:last-child) {
`) ||
css`
&:before,
&:after {
content: '';
@ -50,7 +46,14 @@ const styles = {
&:after {
right: -23px;
}
}
`,
column: css`
margin: 0 20px;
transition: background-color 0.5s ease;
border: 2px dashed transparent;
border-radius: 4px;
position: relative;
height: 100%;
`,
columnHovered: css`
border-color: ${colors.active};
@ -140,11 +143,12 @@ class WorkflowList extends React.Component {
this.props.handlePublish(collection, slug);
};
// eslint-disable-next-line react/display-name
renderColumns = (entries, column) => {
if (!entries) return null;
if (!column) {
return entries.entrySeq().map(([currColumn, currEntries]) => (
return entries.entrySeq().map(([currColumn, currEntries], idx) => (
<DropTarget
namespace={DNDNamespace}
key={currColumn}
@ -152,7 +156,14 @@ class WorkflowList extends React.Component {
>
{(connect, { isHovered }) =>
connect(
<div className={cx(styles.column, { [styles.columnHovered]: isHovered })}>
<div style={{ height: '100%' }}>
<div
css={[
styles.column,
styles.columnPosition(idx),
isHovered && styles.columnHovered,
]}
>
<ColumnHeader name={currColumn}>
{getColumnHeaderText(currColumn, this.props.t)}
</ColumnHeader>
@ -162,6 +173,7 @@ class WorkflowList extends React.Component {
})}
</ColumnCount>
{this.renderColumns(currEntries, currColumn)}
</div>
</div>,
)
}

View File

@ -84,7 +84,7 @@ describe('config', () => {
media_folder: 'baz',
collections: [],
});
}).toThrowError("'collections' should NOT have less than 1 items");
}).toThrowError("'collections' should NOT have fewer than 1 items");
});
it('should throw if collections is an array with a single null element in config', () => {

View File

@ -1,4 +1,5 @@
import { Map } from 'immutable';
import { oneLine } from 'common-tags';
import EditorComponent from 'ValueObjects/EditorComponent';
/**
@ -59,10 +60,39 @@ export function getPreviewTemplate(name) {
* Editor Widgets
*/
export function registerWidget(name, control, preview) {
if (Array.isArray(name)) {
name.forEach(widget => {
if (typeof widget !== 'object') {
console.error(`Cannot register widget: ${widget}`);
} else {
registerWidget(widget);
}
});
} else if (typeof name === 'string') {
// A registered widget control can be reused by a new widget, allowing
// multiple copies with different previews.
const newControl = typeof control === 'string' ? registry.widgets[control].control : control;
registry.widgets[name] = { control: newControl, preview };
} else if (typeof name === 'object') {
const {
name: widgetName,
controlComponent: control,
previewComponent: preview,
globalStyles,
} = name;
if (registry.widgets[widgetName]) {
console.error(oneLine`
Multiple widgets registered with name "${widgetName}". Only the last widget registered with
this name will be used.
`);
}
if (!control) {
throw Error(`Widget "${widgetName}" registered without \`controlComponent\`.`);
}
registry.widgets[widgetName] = { control, preview, globalStyles };
} else {
console.error('`registerWidget` failed, called with incorrect arguments.');
}
}
export function getWidget(name) {
return registry.widgets[name];

View File

@ -1,7 +1,7 @@
import { Map } from 'immutable';
/*
* Reducer for some global UI state that we want to share between components
* */
* Reducer for some global UI state that we want to share between components
* */
const globalUI = (state = Map({ isFetching: false }), action) => {
// Generic, global loading indicator
if (action.type.indexOf('REQUEST') > -1) {

View File

@ -20,8 +20,8 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"react": "^16.4.1"

View File

@ -24,8 +24,8 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"immutable": "^3.7.6",

View File

@ -1,5 +1,5 @@
import trim from 'lodash/trim';
import trimEnd from 'lodash/trim';
import trimEnd from 'lodash/trimEnd';
const NETLIFY_API = 'https://api.netlify.com';
const AUTH_ENDPOINT = 'auth';

View File

@ -17,12 +17,12 @@
},
"dependencies": {
"js-sha256": "^0.9.0",
"localforage": "^1.4.2"
"localforage": "^1.7.3"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"immutable": "^3.7.6",

View File

@ -25,8 +25,8 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"netlify-cms-lib-util": "^2.0.4"

View File

@ -23,11 +23,11 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"dependencies": {
"uploadcare-widget": "^3.6.2",
"uploadcare-widget-tab-effects": "^1.3.0"
"uploadcare-widget": "^3.7.0",
"uploadcare-widget-tab-effects": "^1.4.0"
}
}

View File

@ -18,18 +18,18 @@
"dependencies": {
"react-aria-menubutton": "^5.1.0",
"react-toggled": "^1.1.2",
"react-transition-group": "^2.2.1"
"react-transition-group": "^2.6.0"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"lodash": "^4.13.1",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
}
}

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import Icon from './Icon';
import { buttons, shadows } from './styles';

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import { css } from '@emotion/core';
import styled from '@emotion/styled';
import { Wrapper, Button as DropdownButton, Menu, MenuItem } from 'react-aria-menubutton';
import { buttons, components } from './styles';
import Icon from './Icon';

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import icons from './Icon/icons';
const IconWrapper = styled.span`

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import Icon from './Icon';
import { colors, lengths, buttons } from './styles';

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css, keyframes } from 'react-emotion';
import styled from '@emotion/styled';
import { css, keyframes } from '@emotion/core';
import CSSTransition from 'react-transition-group/CSSTransition';
import { colors } from './styles';

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import Icon from './Icon';
import { colors, buttons } from './styles';
import Dropdown, { StyledDropdownButton, DropdownItem } from './Dropdown';

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import ReactToggled from 'react-toggled';
import { colors, colorsRaw, shadows, transitions } from './styles';

View File

@ -1,4 +1,4 @@
import styled from 'react-emotion';
import styled from '@emotion/styled';
const WidgetPreviewContainer = styled.div`
margin: 15px 2px;

View File

@ -18,4 +18,5 @@ export {
transitions,
effects,
reactSelectStyles,
GlobalStyles,
} from './styles';

View File

@ -1,18 +1,5 @@
import { css, injectGlobal } from 'react-emotion';
export {
fonts,
colorsRaw,
colors,
lengths,
components,
buttons,
shadows,
borders,
transitions,
effects,
reactSelectStyles,
};
import React from 'react';
import { css, Global } from '@emotion/core';
/**
* Font Stacks
@ -102,6 +89,7 @@ const lengths = {
borderWidth: '2px',
topCardWidth: '682px',
pageMargin: '28px 18px',
objectWidgetTopBarContainerPadding: '0 14px 14px',
};
const borders = {
@ -130,19 +118,8 @@ const shadows = {
`,
};
const effects = {
checkerboard: css`
background-color: ${colors.checkerboardLight};
background-size: 16px 16px;
background-position: 0 0, 8px 8px;
background-image: linear-gradient(
45deg,
${colors.checkerboardDark} 25%,
transparent 25%,
transparent 75%,
${colors.checkerboardDark} 75%,
${colors.checkerboardDark}
),
const gradients = {
checkerboard: `
linear-gradient(
45deg,
${colors.checkerboardDark} 25%,
@ -150,7 +127,16 @@ const effects = {
transparent 75%,
${colors.checkerboardDark} 75%,
${colors.checkerboardDark}
);
)
`,
};
const effects = {
checkerboard: css`
background-color: ${colors.checkerboardLight};
background-size: 16px 16px;
background-position: 0 0, 8px 8px;
background-image: ${gradients.checkerboard}, ${gradients.checkerboard};
`,
};
@ -305,7 +291,7 @@ const components = {
margin-top: 8px;
`,
objectWidgetTopBarContainer: css`
padding: 0 14px 14px;
padding: ${lengths.objectWidgetTopBarContainerPadding};
`,
dropdownList: css`
${shadows.dropDeep};
@ -381,8 +367,12 @@ const reactSelectStyles = {
}),
};
injectGlobal`
*, *:before, *:after {
const GlobalStyles = () => (
<Global
styles={css`
*,
*:before,
*:after {
box-sizing: border-box;
}
@ -393,11 +383,10 @@ injectGlobal`
/**
* Don't show outlines if the user is utilizing mouse rather than keyboard.
*/
[data-whatintent="mouse"] *:focus {
[data-whatintent='mouse'] *:focus {
outline: none;
}
input {
border: 0;
}
@ -410,11 +399,18 @@ injectGlobal`
margin: 0;
}
ul, ol {
ul,
ol {
padding-left: 0;
}
h1, h2, h3, h4, h5, h6, p {
h1,
h2,
h3,
h4,
h5,
h6,
p {
font-family: ${fonts.primary};
color: ${colors.textLead};
font-size: 15px;
@ -422,7 +418,12 @@ injectGlobal`
margin-top: 0;
}
h1, h2, h3, h4, h5, h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
}
@ -450,4 +451,21 @@ injectGlobal`
textarea {
resize: none;
}
`;
`}
/>
);
export {
fonts,
colorsRaw,
colors,
lengths,
components,
buttons,
shadows,
borders,
transitions,
effects,
reactSelectStyles,
GlobalStyles,
};

View File

@ -21,11 +21,11 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",

View File

@ -1,12 +1,18 @@
/** @jsx jsx */
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import { jsx, css } from '@emotion/core';
import { Toggle, ToggleBackground, colors } from 'netlify-cms-ui-default';
const BooleanBackground = styled(ToggleBackground)`
background-color: ${props => (props.isActive ? colors.active : colors.textFieldBorder)};
`;
const BooleanBackground = ({ isActive, ...props }) => (
<ToggleBackground
css={css`
background-color: ${isActive ? colors.active : colors.textFieldBorder};
`}
{...props}
/>
);
export default class BooleanControl extends React.Component {
render() {

View File

@ -21,21 +21,21 @@
"build": "cross-env NODE_ENV=production webpack"
},
"dependencies": {
"react-datetime": "^2.11.0"
"react-datetime": "^2.16.3"
},
"devDependencies": {
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"css-loader": "^2.1.1",
"to-string-loader": "^1.1.5",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"moment": "^2.11.2",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
}
}

View File

@ -1,14 +1,11 @@
/** @jsx jsx */
import React from 'react';
import PropTypes from 'prop-types';
import { injectGlobal } from 'react-emotion';
import { jsx, css } from '@emotion/core';
import reactDateTimeStyles from 'react-datetime/css/react-datetime.css';
import DateTime from 'react-datetime';
import dateTimeStyles from 'react-datetime/css/react-datetime.css';
import moment from 'moment';
injectGlobal`
${dateTimeStyles}
`;
export default class DateControl extends React.Component {
static propTypes = {
field: PropTypes.object.isRequired,
@ -106,6 +103,11 @@ export default class DateControl extends React.Component {
const { forID, value, classNameWrapper, setActiveStyle } = this.props;
const { format, dateFormat, timeFormat } = this.formats;
return (
<div
css={css`
${reactDateTimeStyles};
`}
>
<DateTime
dateFormat={dateFormat}
timeFormat={timeFormat}
@ -115,6 +117,7 @@ export default class DateControl extends React.Component {
onBlur={this.onBlur}
inputProps={{ className: classNameWrapper, id: forID }}
/>
</div>
);
}
}

View File

@ -1,2 +1,11 @@
export DateControl from './DateControl';
export DatePreview from './DatePreview';
import controlComponent from './DateControl';
import previewComponent from './DatePreview';
const Widget = (opts = {}) => ({
name: 'date',
controlComponent,
previewComponent,
...opts,
});
export { Widget as default, controlComponent, previewComponent };

View File

@ -26,11 +26,11 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"react": "^16.4.1"
},
"localExternals": [

View File

@ -1,5 +1,5 @@
import React from 'react';
import { DateControl } from 'netlify-cms-widget-date';
import { controlComponent as DateControl } from 'netlify-cms-widget-date';
export default class DateTimeControl extends React.Component {
render() {

View File

@ -1,2 +1,11 @@
export DateTimeControl from './DateTimeControl';
export { DatePreview as DateTimePreview } from 'netlify-cms-widget-date';
import controlComponent from './DateTimeControl';
import { previewComponent } from 'netlify-cms-widget-date';
const Widget = (opts = {}) => ({
name: 'datetime',
controlComponent,
previewComponent,
...opts,
});
export { Widget as default, controlComponent, previewComponent };

View File

@ -27,16 +27,16 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6",
"react-immutable-proptypes": "^2.1.0"
}
}

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { List } from 'immutable';
import { WidgetPreviewContainer } from 'netlify-cms-ui-default';

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Map, List } from 'immutable';
import { once } from 'lodash';
import uuid from 'uuid/v4';
@ -33,12 +33,6 @@ const MultiImageWrapper = styled.div`
flex-wrap: wrap;
`;
const FileInfo = styled.div`
button:not(:first-child) {
margin-top: 12px;
}
`;
const FileLink = styled.a`
margin-bottom: 20px;
font-weight: normal;
@ -51,6 +45,10 @@ const FileLink = styled.a`
}
`;
const FileLinks = styled.div`
margin-bottom: 12px;
`;
const FileLinkList = styled.ul`
list-style-type: none;
`;
@ -63,6 +61,7 @@ const FileWidgetButton = styled.button`
const FileWidgetButtonRemove = styled.button`
${buttons.button};
${components.badgeDanger};
margin-top: 12px;
`;
function isMultiple(value) {
@ -192,14 +191,16 @@ export default function withFileControl({ forImage } = {}) {
if (isMultiple(value)) {
return (
<FileLinks>
<FileLinkList>
{value.map(val => (
<li key={val}>{this.renderFileLink(val)}</li>
))}
</FileLinkList>
</FileLinks>
);
}
return this.renderFileLink(value);
return <FileLinks>{this.renderFileLink(value)}</FileLinks>;
};
renderImages = () => {
@ -225,7 +226,7 @@ export default function withFileControl({ forImage } = {}) {
renderSelection = subject => (
<div>
{forImage ? this.renderImages() : null}
<FileInfo>
<div>
{forImage ? null : this.renderFileLinks()}
<FileWidgetButton onClick={this.handleChange}>
Choose different {subject}
@ -233,7 +234,7 @@ export default function withFileControl({ forImage } = {}) {
<FileWidgetButtonRemove onClick={this.handleRemove}>
Remove {subject}
</FileWidgetButtonRemove>
</FileInfo>
</div>
</div>
);

View File

@ -26,15 +26,16 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6"
"react": "^16.4.1"
},
"localExternals": [
"netlify-cms-widget-file"

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { List } from 'immutable';
import { WidgetPreviewContainer } from 'netlify-cms-ui-default';

View File

@ -26,17 +26,17 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6",
"react-immutable-proptypes": "^2.1.0"
},
"localExternals": [

View File

@ -1,7 +1,9 @@
/** @jsx jsx */
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { cx, css } from 'react-emotion';
import styled from '@emotion/styled';
import { jsx, css, ClassNames } from '@emotion/core';
import { List, Map } from 'immutable';
import { partial } from 'lodash';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
@ -12,13 +14,7 @@ import {
resolveFieldKeyType,
getErrorMessageForTypedFieldAndValue,
} from './typedListHelpers';
import {
ListItemTopBar,
ObjectWidgetTopBar,
colors,
lengths,
components,
} from 'netlify-cms-ui-default';
import { ListItemTopBar, ObjectWidgetTopBar, colors, lengths } from 'netlify-cms-ui-default';
function valueToString(value) {
return value ? value.join(',').replace(/,([^\s]|$)/g, ', $1') : '';
@ -41,10 +37,16 @@ const NestedObjectLabel = styled.div`
border-radius: 0 0 ${lengths.borderRadius} ${lengths.borderRadius};
`;
const styles = {
collapsedObjectControl: css`
const styleStrings = {
collapsedObjectControl: `
display: none;
`,
objectWidgetTopBarContainer: `
padding: ${lengths.objectWidgetTopBarContainerPadding};
`,
};
const styles = {
listControlItem: css`
margin-top: 18px;
@ -275,6 +277,7 @@ export default class ListControl extends React.Component {
this.setState({ itemsCollapsed: updatedItemsCollapsed });
};
// eslint-disable-next-line react/display-name
renderItem = (item, index) => {
const {
classNameWrapper,
@ -300,7 +303,7 @@ export default class ListControl extends React.Component {
return (
<SortableListItem
className={cx(styles.listControlItem, { [styles.listControlItemCollapsed]: collapsed })}
css={[styles.listControlItem, collapsed && styles.listControlItemCollapsed]}
index={index}
key={`item-${index}`}
>
@ -311,8 +314,14 @@ export default class ListControl extends React.Component {
dragHandleHOC={SortableHandle}
/>
<NestedObjectLabel collapsed={collapsed}>{this.objectLabel(item)}</NestedObjectLabel>
<ClassNames>
{({ css, cx }) => (
<ObjectControl
classNameWrapper={cx(classNameWrapper, { [styles.collapsedObjectControl]: collapsed })}
classNameWrapper={cx(classNameWrapper, {
[css`
${styleStrings.collapsedObjectControl};
`]: collapsed,
})}
value={item}
field={field}
onChangeObject={this.handleChangeFor(index)}
@ -326,6 +335,8 @@ export default class ListControl extends React.Component {
ref={this.processControlRef}
controlRef={controlRef}
/>
)}
</ClassNames>
</SortableListItem>
);
};
@ -335,7 +346,7 @@ export default class ListControl extends React.Component {
const errorMessage = getErrorMessageForTypedFieldAndValue(field, item);
return (
<SortableListItem
className={cx(styles.listControlItem, styles.listControlItemCollapsed)}
css={[styles.listControlItem, styles.listControlItemCollapsed]}
index={index}
key={`item-${index}`}
>
@ -360,7 +371,17 @@ export default class ListControl extends React.Component {
const listLabel = items.size === 1 ? labelSingular.toLowerCase() : label.toLowerCase();
return (
<div id={forID} className={cx(classNameWrapper, components.objectWidgetTopBarContainer)}>
<ClassNames>
{({ cx, css }) => (
<div
id={forID}
className={cx(
classNameWrapper,
css`
${styleStrings.objectWidgetTopBarContainer}
`,
)}
>
<ObjectWidgetTopBar
allowAdd={field.get('allow_add', true)}
onAdd={this.handleAdd}
@ -379,6 +400,8 @@ export default class ListControl extends React.Component {
lockAxis="y"
/>
</div>
)}
</ClassNames>
);
}

View File

@ -22,13 +22,13 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"css-loader": "^2.1.0",
"css-loader": "^2.1.1",
"to-string-loader": "^1.1.5",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
@ -36,6 +36,6 @@
"react-immutable-proptypes": "^2.1.0"
},
"dependencies": {
"ol": "^5.3.0"
"ol": "^5.3.1"
}
}

View File

@ -1,3 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { ClassNames } from '@emotion/core';
import olStyles from 'ol/ol.css';
import Map from 'ol/Map.js';
import View from 'ol/View.js';
@ -7,13 +10,6 @@ import TileLayer from 'ol/layer/Tile.js';
import VectorLayer from 'ol/layer/Vector.js';
import OSMSource from 'ol/source/OSM.js';
import VectorSource from 'ol/source/Vector.js';
import PropTypes from 'prop-types';
import React from 'react';
import { injectGlobal } from 'react-emotion';
injectGlobal`
${olStyles}
`;
const formatOptions = {
dataProjection: 'EPSG:4326',
@ -70,7 +66,23 @@ export default function withMapControl({ getFormat, getMap } = {}) {
}
render() {
return <div ref={this.mapContainer}> </div>;
return (
<ClassNames>
{({ cx, css }) => (
<div
className={cx(
this.props.classNameWrapper,
css`
${olStyles};
padding: 0;
overflow: hidden;
`,
)}
ref={this.mapContainer}
/>
)}
</ClassNames>
);
}
};
}

View File

@ -21,9 +21,9 @@
"build": "cross-env NODE_ENV=production webpack"
},
"dependencies": {
"is-hotkey": "^0.1.1",
"mdast-util-definitions": "^1.2.2",
"mdast-util-to-string": "^1.0.4",
"is-hotkey": "^0.1.4",
"mdast-util-definitions": "^1.2.3",
"mdast-util-to-string": "^1.0.5",
"rehype-parse": "^3.1.0",
"rehype-remark": "^2.0.0",
"rehype-stringify": "^3.0.0",
@ -42,18 +42,18 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-dom": "^16.0.0",
"react-emotion": "^9.2.5",
"react-immutable-proptypes": "^2.1.0"
}
}

View File

@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css, cx } from 'react-emotion';
import styled from '@emotion/styled';
import { ClassNames } from '@emotion/core';
import { Editor as Slate } from 'slate-react';
import Plain from 'slate-plain-serializer';
import { debounce } from 'lodash';
@ -9,8 +10,8 @@ import { lengths, fonts } from 'netlify-cms-ui-default';
import { editorStyleVars, EditorControlBar } from '../styles';
import Toolbar from './Toolbar';
const styles = {
slateRaw: css`
const styleStrings = {
slateRaw: `
position: relative;
overflow: hidden;
overflow-x: auto;
@ -83,12 +84,21 @@ export default class RawEditor extends React.Component {
rawMode
/>
</EditorControlBar>
<ClassNames>
{({ css, cx }) => (
<Slate
className={cx(className, styles.slateRaw)}
className={cx(
className,
css`
${styleStrings.slateRaw}
`,
)}
value={this.state.value}
onChange={this.handleChange}
onPaste={this.handlePaste}
/>
)}
</ClassNames>
</RawEditorContainer>
);
}

View File

@ -2,7 +2,8 @@
import React from 'react';
import { Map } from 'immutable';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import { partial, capitalize } from 'lodash';
import { ListItemTopBar, components, colors, lengths } from 'netlify-cms-ui-default';
import { getEditorControl, getEditorComponents } from './index';

View File

@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css } from 'react-emotion';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import { List } from 'immutable';
import {
Toggle,
@ -24,6 +25,7 @@ const ToolbarContainer = styled.div`
padding: 11px 14px;
min-height: 58px;
transition: background-color ${transitions.main}, color ${transitions.main};
color: ${colors.text};
`;
const ToolbarDropdownWrapper = styled.div`

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'react-emotion';
import styled from '@emotion/styled';
import { Icon, buttons } from 'netlify-cms-ui-default';
const StyledToolbarButton = styled.button`

View File

@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { cx } from 'react-emotion';
import styled from '@emotion/styled';
import { ClassNames } from '@emotion/core';
import { get, isEmpty, debounce, uniq } from 'lodash';
import { List } from 'immutable';
import { Value, Document, Block, Text } from 'slate';
@ -259,8 +260,15 @@ export default class Editor extends React.Component {
buttons={field.get('buttons')}
/>
</EditorControlBar>
<ClassNames>
{({ css, cx }) => (
<Slate
className={cx(className, visualEditorStyles)}
className={cx(
className,
css`
${visualEditorStyles}
`,
)}
value={this.state.value}
renderNode={renderNode}
renderMark={renderMark}
@ -272,6 +280,8 @@ export default class Editor extends React.Component {
ref={this.processRef}
spellCheck
/>
)}
</ClassNames>
</VisualEditorContainer>
);
}

View File

@ -1,8 +1,7 @@
import { css } from 'react-emotion';
import { colors, lengths, fonts } from 'netlify-cms-ui-default';
import { editorStyleVars } from '../styles';
export default css`
export default `
position: relative;
overflow: hidden;
overflow-x: auto;

View File

@ -1,4 +1,4 @@
import styled from 'react-emotion';
import styled from '@emotion/styled';
export const editorStyleVars = {
stickyDistanceBottom: '100px',

View File

@ -21,11 +21,10 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1"

View File

@ -23,17 +23,17 @@
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6",
"react-immutable-proptypes": "^2.1.0"
}
}

View File

@ -1,20 +1,23 @@
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { css, cx } from 'react-emotion';
import { ClassNames } from '@emotion/core';
import { Map, List } from 'immutable';
import { ObjectWidgetTopBar, components } from 'netlify-cms-ui-default';
import { ObjectWidgetTopBar, lengths } from 'netlify-cms-ui-default';
const styles = {
nestedObjectControl: css`
const styleStrings = {
nestedObjectControl: `
padding: 6px 14px 14px;
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
`,
objectWidgetTopBarContainer: `
padding: ${lengths.objectWidgetTopBarContainerPadding}
`,
};
export default class ObjectControl extends Component {
export default class ObjectControl extends React.Component {
componentValidate = {};
static propTypes = {
@ -116,11 +119,21 @@ export default class ObjectControl extends Component {
if (multiFields || singleField) {
return (
<ClassNames>
{({ css, cx }) => (
<div
id={forID}
className={cx(classNameWrapper, components.objectWidgetTopBarContainer, {
[styles.nestedObjectControl]: forList,
})}
className={cx(
classNameWrapper,
css`
${styleStrings.objectWidgetTopBarContainer}
`,
{
[css`
${styleStrings.nestedObjectControl}
`]: forList,
},
)}
>
{forList ? null : (
<ObjectWidgetTopBar
@ -130,6 +143,8 @@ export default class ObjectControl extends Component {
)}
{collapsed ? null : this.renderFields(multiFields, singleField)}
</div>
)}
</ClassNames>
);
}

View File

@ -21,21 +21,21 @@
"build": "cross-env NODE_ENV=production webpack"
},
"dependencies": {
"react-select": "^2.3.0"
"react-select": "^2.4.2"
},
"devDependencies": {
"cross-env": "^5.2.0",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
},
"peerDependencies": {
"emotion": "^9.2.6",
"@emotion/core": "^10.0.9",
"@emotion/styled": "^10.0.9",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.5",
"uuid": "^3.1.0"
}
}

View File

@ -104,22 +104,21 @@ function setup({ field, value }) {
describe('Relation widget', () => {
it('should list the first 20 option hits on initial load', async () => {
const field = fromJS(fieldConfig);
const { getAllByRole, input } = setup({ field });
const { getAllByText, input } = setup({ field });
fireEvent.keyDown(input, { key: 'ArrowDown' });
await wait(() => {
fireEvent.keyDown(input, { key: 'ArrowDown' });
expect(getAllByRole('option')).toHaveLength(20);
expect(getAllByText(/^Post # (\d{1,2}) post-number-\1$/)).toHaveLength(20);
});
});
it('should update option list based on search term', async () => {
const field = fromJS(fieldConfig);
const { getAllByRole, getByText, input } = setup({ field });
const { getAllByText, input } = setup({ field });
fireEvent.change(input, { target: { value: 'YAML' } });
await wait(() => {
fireEvent.change(input, { target: { value: 'YAML' } });
expect(getAllByRole('option')).toHaveLength(1);
expect(getByText('YAML post post-yaml')).toBeInTheDocument();
expect(getAllByText('YAML post post-yaml')).toHaveLength(1);
});
});

Some files were not shown because too many files have changed in this diff Show More