diff --git a/packages/netlify-cms-core/package.json b/packages/netlify-cms-core/package.json index be945262..1ff941c4 100644 --- a/packages/netlify-cms-core/package.json +++ b/packages/netlify-cms-core/package.json @@ -49,7 +49,7 @@ "react-frame-component": "^5.2.1", "react-hot-loader": "^4.8.0", "react-immutable-proptypes": "^2.1.0", - "react-is": "16.13.1", + "react-is": "18.2.0", "react-markdown": "^6.0.2", "react-modal": "^3.8.1", "react-polyglot": "^0.7.0", @@ -92,6 +92,7 @@ "react-immutable-proptypes": "^2.1.0" }, "devDependencies": { + "@types/react": "18.0.20", "@types/history": "^4.7.8", "@types/redux-mock-store": "^1.0.2", "@types/url-join": "^4.0.0", diff --git a/packages/netlify-cms-core/src/bootstrap.js b/packages/netlify-cms-core/src/bootstrap.js index 841cc546..fca6eb2d 100644 --- a/packages/netlify-cms-core/src/bootstrap.js +++ b/packages/netlify-cms-core/src/bootstrap.js @@ -3,6 +3,7 @@ import { render } from 'react-dom'; import { Provider, connect } from 'react-redux'; import { Route, Router } from 'react-router-dom'; import { I18n } from 'react-polyglot'; +import { GlobalStyles } from 'netlify-cms-ui-default'; import { store } from './redux'; import { history } from './routing/history'; @@ -84,6 +85,7 @@ function bootstrap(opts = {}) { function Root() { return ( <> + diff --git a/packages/netlify-cms-core/src/components/App/App.js b/packages/netlify-cms-core/src/components/App/App.js index b5928f28..28ce42ff 100644 --- a/packages/netlify-cms-core/src/components/App/App.js +++ b/packages/netlify-cms-core/src/components/App/App.js @@ -33,6 +33,11 @@ TopBarProgress.config({ barThickness: 2, }); +const AppWrapper = styled.div` + width: 100%; + min-height: 100%; +` + const AppMainContainer = styled.div` min-width: 1200px; max-width: 1440px; @@ -175,7 +180,7 @@ class App extends React.Component { const hasWorkflow = publishMode === EDITORIAL_WORKFLOW; return ( - <> +
{useMediaLibrary ? : null} - + ); } } diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js index 6fc40985..11e6fbd6 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js @@ -7,7 +7,13 @@ import { ClassNames, Global, css as coreCss } from '@emotion/core'; import styled from '@emotion/styled'; import { partial, uniqueId } from 'lodash'; import { connect } from 'react-redux'; -import { FieldLabel, colors, transitions, lengths, borders } from 'netlify-cms-ui-default'; +import { + FieldLabel, + colors, + transitions, + lengths, + borders, +} from 'netlify-cms-ui-default'; import ReactMarkdown from 'react-markdown'; import gfm from 'remark-gfm'; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js deleted file mode 100644 index 6986a78b..00000000 --- a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { isElement } from 'react-is'; - -/** - * We need to create a lightweight component here so that we can access the - * context within the Frame. This allows us to attach the ScrollSyncPane to the - * body. - */ -class PreviewContent extends React.Component { - render() { - const { previewComponent, previewProps } = this.props; - return isElement(previewComponent) - ? React.cloneElement(previewComponent, previewProps) - : React.createElement(previewComponent, previewProps); - } -} - -PreviewContent.propTypes = { - previewComponent: PropTypes.func.isRequired, - previewProps: PropTypes.object, -}; - -export default PreviewContent; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewContent.tsx b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewContent.tsx new file mode 100644 index 00000000..8ee46df4 --- /dev/null +++ b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewContent.tsx @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +/* eslint-disable func-style */ +import { CmsWidgetPreviewProps } from 'netlify-cms-core'; +import React, { ComponentType, ReactNode, useMemo } from 'react'; +import ReactDOM from 'react-dom'; + +interface PreviewContentProps { + previewComponent?: + | React.ReactElement> + | ComponentType; + previewProps: CmsWidgetPreviewProps; +} + +const PreviewContent = ({ previewComponent, previewProps }: PreviewContentProps) => { + const element = useMemo(() => document.getElementById('nc-root'), []); + + return useMemo(() => { + if (!element) { + return null; + } + + let children: ReactNode; + if (!previewComponent) { + children = null; + } else if (React.isValidElement(previewComponent)) { + children = React.cloneElement(previewComponent, previewProps); + } else { + children = React.createElement(previewComponent, previewProps); + } + + return ReactDOM.createPortal(
{children}
, element); + }, [previewComponent, previewProps, element]); +}; + +export default PreviewContent; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js b/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js index f7f28498..9b3f3fb9 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js @@ -300,7 +300,9 @@ export class EditorToolbar extends React.Component { : this.renderNewEntrySimplePublishControls({ canCreate })}
{showDelete ? ( - {t('editor.editorToolbar.deleteEntry')} + + {t('editor.editorToolbar.deleteEntry')} + ) : null}
@@ -319,12 +321,17 @@ export class EditorToolbar extends React.Component { return ( {deployPreviewReady ? ( - + {label} ) : ( - + {t('editor.editorToolbar.deployPreviewPendingButtonLabel')} @@ -348,7 +355,9 @@ export class EditorToolbar extends React.Component { {statusKey && ( - {t(`editor.editorToolbar.${statusToLocaleKey[statusKey]}`)} + + {t(`editor.editorToolbar.${statusToLocaleKey[statusKey]}`)} + )} ); @@ -388,6 +397,7 @@ export class EditorToolbar extends React.Component { '' ) : ( onChangeStatus('PENDING_PUBLISH')} icon={currentStatus === status.get('PENDING_PUBLISH') ? 'check' : null} @@ -404,6 +414,7 @@ export class EditorToolbar extends React.Component { return canPublish ? ( ( @@ -445,6 +456,7 @@ export class EditorToolbar extends React.Component { return canPublish || canCreate ? ( ( @@ -480,6 +492,7 @@ export class EditorToolbar extends React.Component { const { onDuplicate, t } = this.props; return canCreate ? ( ( @@ -503,7 +516,7 @@ export class EditorToolbar extends React.Component { const { onPersist, onPersistAndNew, onPersistAndDuplicate, isPersisting, t } = this.props; return ( -
+
{hasChanged ? ( - {t('editor.editorToolbar.unsavedChanges')} + {t('editor.editorToolbar.unsavedChanges')} ) : ( - {t('editor.editorToolbar.changesSaved')} + {t('editor.editorToolbar.changesSaved')} )}
diff --git a/packages/netlify-cms-ui-default/src/index.js b/packages/netlify-cms-ui-default/src/index.js index 5a7bb815..b9bb4339 100644 --- a/packages/netlify-cms-ui-default/src/index.js +++ b/packages/netlify-cms-ui-default/src/index.js @@ -28,6 +28,7 @@ import { effects, zIndex, reactSelectStyles, + GlobalStyles, } from './styles'; export const NetlifyCmsUiDefault = { @@ -61,6 +62,7 @@ export const NetlifyCmsUiDefault = { effects, zIndex, reactSelectStyles, + GlobalStyles, }; export { Dropdown, @@ -93,5 +95,6 @@ export { effects, zIndex, reactSelectStyles, + GlobalStyles, GoBackButton, }; diff --git a/packages/netlify-cms-ui-default/src/styles.js b/packages/netlify-cms-ui-default/src/styles.js deleted file mode 100644 index 534ad8b9..00000000 --- a/packages/netlify-cms-ui-default/src/styles.js +++ /dev/null @@ -1,440 +0,0 @@ -import { css } from '@emotion/core'; - -/** - * Font Stacks - */ -const fonts = { - primary: ` - -apple-system, - BlinkMacSystemFont, - "Segoe UI", - Roboto, - Helvetica, - Arial, - sans-serif, - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol" - `, - mono: ` - 'SFMono-Regular', - Consolas, - "Liberation Mono", - Menlo, - Courier, - monospace; - `, -}; - -/** - * Theme Colors - */ -const colorsRaw = { - white: '#fff', - grayLight: '#eff0f4', - gray: '#798291', - grayDark: '#313d3e', - blue: '#3a69c7', - blueLight: '#e8f5fe', - green: '#005614', - greenLight: '#caef6f', - brown: '#754e00', - yellow: '#ffee9c', - red: '#ff003b', - redLight: '#fcefea', - purple: '#70399f', - purpleLight: '#f6d8ff', - teal: '#17a2b8', - tealLight: '#ddf5f9', -}; - -const colors = { - statusDraftText: colorsRaw.purple, - statusDraftBackground: colorsRaw.purpleLight, - statusReviewText: colorsRaw.brown, - statusReviewBackground: colorsRaw.yellow, - statusReadyText: colorsRaw.green, - statusReadyBackground: colorsRaw.greenLight, - text: colorsRaw.gray, - textLight: colorsRaw.white, - textLead: colorsRaw.grayDark, - background: colorsRaw.grayLight, - foreground: colorsRaw.white, - active: colorsRaw.blue, - activeBackground: colorsRaw.blueLight, - inactive: colorsRaw.gray, - button: colorsRaw.grayDark, - buttonText: colorsRaw.white, - inputBackground: colorsRaw.white, - infoText: colorsRaw.blue, - infoBackground: colorsRaw.blueLight, - successText: colorsRaw.green, - successBackground: colorsRaw.greenLight, - warnText: colorsRaw.brown, - warnBackground: colorsRaw.yellow, - errorText: colorsRaw.red, - errorBackground: colorsRaw.redLight, - textFieldBorder: '#dfdfe3', - controlLabel: '#7a8291', - checkerboardLight: '#f2f2f2', - checkerboardDark: '#e6e6e6', - mediaDraftText: colorsRaw.purple, - mediaDraftBackground: colorsRaw.purpleLight, -}; - -const lengths = { - topBarHeight: '56px', - inputPadding: '16px 20px', - borderRadius: '5px', - richTextEditorMinHeight: '300px', - borderWidth: '2px', - topCardWidth: '722px', - pageMargin: '28px 18px', - objectWidgetTopBarContainerPadding: '0 14px 14px', -}; - -const borders = { - textField: `solid ${lengths.borderWidth} ${colors.textFieldBorder}`, -}; - -const transitions = { - main: '.2s ease', -}; - -const shadows = { - drop: ` - box-shadow: 0 2px 4px 0 rgba(19, 39, 48, 0.12); - `, - dropMain: ` - box-shadow: 0 2px 6px 0 rgba(68, 74, 87, 0.05), 0 1px 3px 0 rgba(68, 74, 87, 0.1); - `, - dropMiddle: ` - box-shadow: 0 2px 6px 0 rgba(68, 74, 87, 0.15), 0 1px 3px 0 rgba(68, 74, 87, 0.3); - `, - dropDeep: ` - box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.15), 0 1px 3px 0 rgba(68, 74, 87, 0.25); - `, - inset: ` - box-shadow: inset 0 0 4px rgba(68, 74, 87, 0.3); - `, -}; - -const text = { - fieldLabel: css` - font-size: 12px; - text-transform: uppercase; - font-weight: 600; - color: ${colors.controlLabel}; - `, -}; - -const gradients = { - checkerboard: ` - linear-gradient( - 45deg, - ${colors.checkerboardDark} 25%, - transparent 25%, - 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}; - `, -}; - -const badge = css` - font-size: 13px; - line-height: 1; -`; - -const backgroundBadge = css` - ${badge}; - display: block; - border-radius: ${lengths.borderRadius}; - padding: 4px 10px; - text-align: center; -`; - -const textBadge = css` - ${badge}; - display: inline-block; - font-weight: 700; - text-transform: uppercase; -`; - -const card = css` - ${shadows.dropMain}; - border-radius: 5px; - background-color: #fff; -`; - -const buttons = { - button: css` - border: 0; - border-radius: ${lengths.borderRadius}; - cursor: pointer; - `, - default: css` - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: ${colorsRaw.gray}; - color: ${colorsRaw.white}; - `, - widget: css` - display: flex; - justify-content: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; - `, - medium: css` - height: 27px; - line-height: 27px; - font-size: 12px; - font-weight: 600; - border-radius: 3px; - padding: 0 24px 0 14px; - `, - small: css` - font-size: 13px; - height: 23px; - line-height: 23px; - `, - gray: css` - background-color: ${colors.button}; - color: ${colors.buttonText}; - - &:focus, - &:hover { - color: ${colorsRaw.white}; - background-color: #555a65; - } - `, - grayText: css` - background-color: transparent; - color: ${colorsRaw.gray}; - `, - green: css` - background-color: #aae31f; - color: ${colorsRaw.green}; - `, - lightRed: css` - background-color: ${colorsRaw.redLight}; - color: ${colorsRaw.red}; - `, - lightBlue: css` - background-color: ${colorsRaw.blueLight}; - color: ${colorsRaw.blue}; - `, - lightTeal: css` - background-color: ${colorsRaw.tealLight}; - color: #1195aa; - `, - teal: css` - background-color: ${colorsRaw.teal}; - color: ${colorsRaw.white}; - `, - disabled: css` - background-color: ${colorsRaw.grayLight}; - color: ${colorsRaw.gray}; - cursor: default; - `, -}; - -const caret = css` - color: ${colorsRaw.white}; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; -`; - -const components = { - card, - caretDown: css` - ${caret}; - border-top: 6px solid currentColor; - border-bottom: 0; - `, - caretRight: css` - ${caret}; - border-left: 6px solid currentColor; - border-right: 0; - `, - badge: css` - ${backgroundBadge}; - color: ${colors.infoText}; - background-color: ${colors.infoBackground}; - `, - badgeSuccess: css` - ${backgroundBadge}; - color: ${colors.successText}; - background-color: ${colors.successBackground}; - `, - badgeDanger: css` - ${backgroundBadge}; - color: ${colorsRaw.red}; - background-color: #fbe0d7; - `, - textBadge: css` - ${textBadge}; - color: ${colors.infoText}; - `, - textBadgeSuccess: css` - ${textBadge}; - color: ${colors.successText}; - `, - textBadgeDanger: css` - ${textBadge}; - color: ${colorsRaw.red}; - `, - loaderSize: css` - width: 2.2857rem; - height: 2.2857rem; - `, - cardTop: css` - ${card}; - width: ${lengths.topCardWidth}; - max-width: 100%; - padding: 18px 20px; - margin-bottom: 28px; - `, - cardTopHeading: css` - font-size: 22px; - font-weight: 600; - line-height: 37px; - margin: 0; - padding: 0; - `, - cardTopDescription: css` - max-width: 480px; - color: ${colors.text}; - font-size: 14px; - margin-top: 8px; - `, - objectWidgetTopBarContainer: css` - padding: ${lengths.objectWidgetTopBarContainerPadding}; - `, - dropdownList: css` - ${shadows.dropDeep}; - background-color: ${colorsRaw.white}; - border-radius: ${lengths.borderRadius}; - overflow: hidden; - `, - dropdownItem: css` - ${buttons.button}; - background-color: transparent; - border-radius: 0; - color: ${colorsRaw.gray}; - font-weight: 500; - border-bottom: 1px solid #eaebf1; - padding: 8px 14px; - display: flex; - justify-content: space-between; - align-items: center; - min-width: max-content; - - &:last-of-type { - border-bottom: 0; - } - - &.active, - &:hover, - &:active, - &:focus { - color: ${colors.active}; - background-color: ${colors.activeBackground}; - } - `, - viewControlsText: css` - font-size: 14px; - color: ${colors.text}; - margin-right: 12px; - white-space: nowrap; - `, -}; - -const reactSelectStyles = { - control: styles => ({ - ...styles, - border: 0, - boxShadow: 'none', - padding: '9px 0 9px 12px', - }), - option: (styles, state) => ({ - ...styles, - backgroundColor: state.isSelected - ? `${colors.active}` - : state.isFocused - ? `${colors.activeBackground}` - : 'transparent', - paddingLeft: '22px', - }), - menu: styles => ({ ...styles, right: 0, zIndex: zIndex.zIndex300 }), - container: styles => ({ ...styles, padding: '0 !important' }), - indicatorSeparator: (styles, state) => - state.hasValue && state.selectProps.isClearable - ? { ...styles, backgroundColor: `${colors.textFieldBorder}` } - : { display: 'none' }, - dropdownIndicator: styles => ({ ...styles, color: `${colors.controlLabel}` }), - clearIndicator: styles => ({ ...styles, color: `${colors.controlLabel}` }), - multiValue: styles => ({ - ...styles, - backgroundColor: colors.background, - }), - multiValueLabel: styles => ({ - ...styles, - color: colors.textLead, - fontWeight: 500, - }), - multiValueRemove: styles => ({ - ...styles, - color: colors.controlLabel, - ':hover': { - color: colors.errorText, - backgroundColor: colors.errorBackground, - }, - }), -}; - -const zIndex = { - zIndex0: 0, - zIndex1: 1, - zIndex2: 2, - zIndex10: 10, - zIndex100: 100, - zIndex200: 200, - zIndex299: 299, - zIndex300: 300, - zIndex1000: 1000, - zIndex10000: 10000, - zIndex99999: 99999, -}; - -export { - fonts, - colorsRaw, - colors, - lengths, - components, - buttons, - text, - shadows, - borders, - transitions, - effects, - zIndex, - reactSelectStyles, -}; diff --git a/packages/netlify-cms-ui-default/src/styles.jsx b/packages/netlify-cms-ui-default/src/styles.jsx new file mode 100644 index 00000000..7f5e5479 --- /dev/null +++ b/packages/netlify-cms-ui-default/src/styles.jsx @@ -0,0 +1,586 @@ +import React from 'react'; +import { css, Global } from '@emotion/core'; + +export const quantifier = '.cms-wrapper'; + +/** + * Font Stacks + */ +const fonts = { + primary: ` + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Helvetica, + Arial, + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol" + `, + mono: ` + 'SFMono-Regular', + Consolas, + "Liberation Mono", + Menlo, + Courier, + monospace; + `, +}; + +/** + * Theme Colors + */ +const colorsRaw = { + white: '#fff', + grayLight: '#eff0f4', + gray: '#798291', + grayDark: '#313d3e', + blue: '#3a69c7', + blueLight: '#e8f5fe', + green: '#005614', + greenLight: '#caef6f', + brown: '#754e00', + yellow: '#ffee9c', + red: '#ff003b', + redLight: '#fcefea', + purple: '#70399f', + purpleLight: '#f6d8ff', + teal: '#17a2b8', + tealLight: '#ddf5f9', +}; + +const colors = { + statusDraftText: colorsRaw.purple, + statusDraftBackground: colorsRaw.purpleLight, + statusReviewText: colorsRaw.brown, + statusReviewBackground: colorsRaw.yellow, + statusReadyText: colorsRaw.green, + statusReadyBackground: colorsRaw.greenLight, + text: colorsRaw.gray, + textLight: colorsRaw.white, + textLead: colorsRaw.grayDark, + background: colorsRaw.grayLight, + foreground: colorsRaw.white, + active: colorsRaw.blue, + activeBackground: colorsRaw.blueLight, + inactive: colorsRaw.gray, + button: colorsRaw.gray, + buttonText: colorsRaw.white, + inputBackground: colorsRaw.white, + infoText: colorsRaw.blue, + infoBackground: colorsRaw.blueLight, + successText: colorsRaw.green, + successBackground: colorsRaw.greenLight, + warnText: colorsRaw.brown, + warnBackground: colorsRaw.yellow, + errorText: colorsRaw.red, + errorBackground: colorsRaw.redLight, + textFieldBorder: '#dfdfe3', + controlLabel: '#7a8291', + checkerboardLight: '#f2f2f2', + checkerboardDark: '#e6e6e6', + mediaDraftText: colorsRaw.purple, + mediaDraftBackground: colorsRaw.purpleLight, +}; + +const lengths = { + topBarHeight: '56px', + inputPadding: '16px 20px', + borderRadius: '5px', + richTextEditorMinHeight: '300px', + borderWidth: '2px', + topCardWidth: '682px', + pageMargin: '28px 18px', + objectWidgetTopBarContainerPadding: '0 14px 14px', +}; + +const borders = { + textField: `solid ${lengths.borderWidth} ${colors.textFieldBorder}`, +}; + +const transitions = { + main: '.2s ease', +}; + +const shadows = { + drop: ` + && { + box-shadow: 0 2px 4px 0 rgba(19, 39, 48, 0.12); + } + `, + dropMain: ` + && { + box-shadow: 0 2px 6px 0 rgba(68, 74, 87, 0.05), 0 1px 3px 0 rgba(68, 74, 87, 0.1); + } + `, + dropMiddle: ` + && { + box-shadow: 0 2px 6px 0 rgba(68, 74, 87, 0.15), 0 1px 3px 0 rgba(68, 74, 87, 0.3); + } + `, + dropDeep: ` + && { + box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.15), 0 1px 3px 0 rgba(68, 74, 87, 0.25); + } + `, + inset: ` + && { + box-shadow: inset 0 0 4px rgba(68, 74, 87, 0.3); + } + `, +}; + +const text = { + fieldLabel: css` + && { + font-size: 12px; + text-transform: uppercase; + font-weight: 600; + } + `, +}; + +const gradients = { + checkerboard: ` + linear-gradient( + 45deg, + ${colors.checkerboardDark} 25%, + transparent 25%, + 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}; + } + `, +}; + +const badge = css` + && { + font-size: 13px; + line-height: 1; + } +`; + +const backgroundBadge = css` + && { + ${badge}; + display: block; + border-radius: ${lengths.borderRadius}; + padding: 4px 10px; + text-align: center; + } +`; + +const textBadge = css` + && { + ${badge}; + display: inline-block; + font-weight: 700; + text-transform: uppercase; + } +`; + +const card = css` + && { + ${shadows.dropMain}; + border-radius: 5px; + background-color: #fff; + } +`; + +const buttons = { + button: css` + && { + border: 0; + border-radius: ${lengths.borderRadius}; + cursor: pointer; + } + `, + default: css` + && { + height: 36px; + line-height: 36px; + font-weight: 500; + padding: 0 15px; + background-color: ${colorsRaw.gray}; + color: ${colorsRaw.white}; + } + `, + medium: css` + && { + height: 27px; + line-height: 27px; + font-size: 12px; + font-weight: 600; + border-radius: 3px; + padding: 0 24px 0 14px; + } + `, + small: css` + && { + font-size: 13px; + height: 23px; + line-height: 23px; + } + `, + gray: css` + && { + background-color: ${colors.button}; + color: ${colors.buttonText}; + + &:focus, + &:hover { + color: ${colorsRaw.white}; + background-color: #555a65; + } + } + `, + grayText: css` + && { + background-color: transparent; + color: ${colorsRaw.gray}; + } + `, + green: css` + && { + background-color: #aae31f; + color: ${colorsRaw.green}; + } + `, + lightRed: css` + && { + background-color: ${colorsRaw.redLight}; + color: ${colorsRaw.red}; + } + `, + lightBlue: css` + && { + background-color: ${colorsRaw.blueLight}; + color: ${colorsRaw.blue}; + } + `, + lightTeal: css` + && { + background-color: ${colorsRaw.tealLight}; + color: #1195aa; + } + `, + teal: css` + && { + background-color: ${colorsRaw.teal}; + color: ${colorsRaw.white}; + } + `, + disabled: css` + && { + background-color: ${colorsRaw.grayLight}; + color: ${colorsRaw.gray}; + } + `, +}; + +const caret = css` + color: ${colorsRaw.white}; + width: 0; + height: 0; + border: 5px solid transparent; + border-radius: 2px; +`; + +const components = { + card, + caretDown: css` + ${caret}; + border-top: 6px solid currentColor; + border-bottom: 0; + `, + caretRight: css` + ${caret}; + border-left: 6px solid currentColor; + border-right: 0; + `, + badge: css` + && { + ${backgroundBadge}; + color: ${colors.infoText}; + background-color: ${colors.infoBackground}; + } + `, + badgeSuccess: css` + && { + ${backgroundBadge}; + color: ${colors.successText}; + background-color: ${colors.successBackground}; + } + `, + badgeDanger: css` + && { + ${backgroundBadge}; + color: ${colorsRaw.red}; + background-color: #fbe0d7; + } + `, + textBadge: css` + && { + ${textBadge}; + color: ${colors.infoText}; + } + `, + textBadgeSuccess: css` + && { + ${textBadge}; + color: ${colors.successText}; + } + `, + textBadgeDanger: css` + && { + ${textBadge}; + color: ${colorsRaw.red}; + } + `, + loaderSize: css` + && { + width: 2.28571429rem; + height: 2.28571429rem; + } + `, + cardTop: css` + && { + ${card}; + width: ${lengths.topCardWidth}; + max-width: 100%; + padding: 18px 20px; + margin-bottom: 28px; + } + `, + cardTopHeading: css` + && { + font-size: 22px; + font-weight: 600; + line-height: 37px; + margin: 0; + padding: 0; + } + `, + cardTopDescription: css` + && { + max-width: 480px; + color: ${colors.text}; + font-size: 14px; + margin-top: 8px; + } + `, + objectWidgetTopBarContainer: css` + && { + padding: ${lengths.objectWidgetTopBarContainerPadding}; + } + `, + dropdownList: css` + && { + ${shadows.dropDeep}; + background-color: ${colorsRaw.white}; + border-radius: ${lengths.borderRadius}; + overflow: hidden; + } + `, + dropdownItem: css` + && { + ${buttons.button}; + background-color: transparent; + border-radius: 0; + color: ${colorsRaw.gray}; + font-weight: 500; + border-bottom: 1px solid #eaebf1; + padding: 8px 14px; + display: flex; + justify-content: space-between; + align-items: center; + min-width: max-content; + + &:last-of-type { + border-bottom: 0; + } + + &.active, + &:hover, + &:active, + &:focus { + color: ${colors.active}; + background-color: ${colors.activeBackground}; + } + } + `, + viewControlsText: css` + && { + font-size: 14px; + color: ${colors.text}; + margin-right: 12px; + white-space: nowrap; + } + `, +}; + +const reactSelectStyles = { + control: styles => ({ + ...styles, + border: 0, + boxShadow: 'none', + padding: '9px 0 9px 12px', + }), + option: (styles, state) => ({ + ...styles, + backgroundColor: state.isSelected + ? `${colors.active}` + : state.isFocused + ? `${colors.activeBackground}` + : 'transparent', + paddingLeft: '22px', + }), + menu: styles => ({ ...styles, right: 0, zIndex: zIndex.zIndex300 }), + container: styles => ({ ...styles, padding: '0 !important' }), + indicatorSeparator: (styles, state) => + state.hasValue && state.selectProps.isClearable + ? { ...styles, backgroundColor: `${colors.textFieldBorder}` } + : { display: 'none' }, + dropdownIndicator: styles => ({ ...styles, color: `${colors.controlLabel}` }), + clearIndicator: styles => ({ ...styles, color: `${colors.controlLabel}` }), + multiValue: styles => ({ + ...styles, + backgroundColor: colors.background, + }), + multiValueLabel: styles => ({ + ...styles, + color: colors.textLead, + fontWeight: 500, + }), + multiValueRemove: styles => ({ + ...styles, + color: colors.controlLabel, + ':hover': { + color: colors.errorText, + backgroundColor: colors.errorBackground, + }, + }), +}; + +const zIndex = { + zIndex0: 0, + zIndex1: 1, + zIndex2: 2, + zIndex10: 10, + zIndex100: 100, + zIndex200: 200, + zIndex299: 299, + zIndex300: 300, + zIndex1000: 1000, + zIndex10000: 10000, + zIndex99999: 99999, +}; + +function GlobalStyles() { + return ( + + ); +} + +export { + fonts, + colorsRaw, + colors, + lengths, + components, + buttons, + text, + shadows, + borders, + transitions, + effects, + zIndex, + reactSelectStyles, + GlobalStyles, +}; diff --git a/packages/netlify-cms/package.json b/packages/netlify-cms/package.json index 20f7f889..1d90c2e3 100644 --- a/packages/netlify-cms/package.json +++ b/packages/netlify-cms/package.json @@ -29,5 +29,8 @@ "react": "^16.8.4", "react-dom": "^16.8.4" }, + "devDependencies": { + "react-hot-loader": "4.13.0" + }, "incrementToForceBump": 2 } diff --git a/tsconfig.json b/tsconfig.json index 747a5c7c..dfd00ad2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "module": "esnext", "moduleResolution": "node", "esModuleInterop": true, + "preserveSymlinks": true, "noEmit": true, "strict": true, "isolatedModules": true, diff --git a/yarn.lock b/yarn.lock index 78da231b..438b71bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3720,6 +3720,15 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@18.0.20": + version "18.0.20" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.20.tgz#e4c36be3a55eb5b456ecf501bd4a00fd4fd0c9ab" + integrity sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/react@^17": version "17.0.44" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7" @@ -15360,7 +15369,7 @@ react-helmet-async@^1.0.2: react-fast-compare "^3.2.0" shallowequal "^1.1.0" -react-hot-loader@^4.8.0: +react-hot-loader@4.13.0, react-hot-loader@^4.8.0: version "4.13.0" resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.13.0.tgz#c27e9408581c2a678f5316e69c061b226dc6a202" integrity sha512-JrLlvUPqh6wIkrK2hZDfOyq/Uh/WeVEr8nc7hkn2/3Ul0sx1Kr5y4kOGNacNRoj7RhwLNcQ3Udf1KJXrqc0ZtA== @@ -15404,7 +15413,12 @@ react-inspector@^4.0.0: is-dom "^1.0.9" prop-types "^15.6.1" -react-is@16.13.1, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.4, react-is@^16.8.6: +react-is@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.4, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==