migrate core to emotion
This commit is contained in:
@ -1,98 +0,0 @@
|
||||
(function () {
|
||||
var enterModule = require('react-hot-loader').enterModule;
|
||||
|
||||
enterModule && enterModule(module);
|
||||
})();
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import c from 'classnames';
|
||||
import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
var Dropdown = function Dropdown(_ref) {
|
||||
var label = _ref.label,
|
||||
button = _ref.button,
|
||||
className = _ref.className,
|
||||
_ref$classNameButton = _ref.classNameButton,
|
||||
classNameButton = _ref$classNameButton === undefined ? '' : _ref$classNameButton,
|
||||
_ref$dropdownWidth = _ref.dropdownWidth,
|
||||
dropdownWidth = _ref$dropdownWidth === undefined ? 'auto' : _ref$dropdownWidth,
|
||||
_ref$dropdownPosition = _ref.dropdownPosition,
|
||||
dropdownPosition = _ref$dropdownPosition === undefined ? 'left' : _ref$dropdownPosition,
|
||||
_ref$dropdownTopOverl = _ref.dropdownTopOverlap,
|
||||
dropdownTopOverlap = _ref$dropdownTopOverl === undefined ? '0' : _ref$dropdownTopOverl,
|
||||
children = _ref.children;
|
||||
|
||||
var style = {
|
||||
width: dropdownWidth,
|
||||
top: dropdownTopOverlap,
|
||||
left: dropdownPosition === 'left' ? 0 : 'auto',
|
||||
right: dropdownPosition === 'right' ? 0 : 'auto'
|
||||
};
|
||||
return React.createElement(
|
||||
Wrapper,
|
||||
{ className: c('nc-dropdown', className), onSelection: function onSelection(handler) {
|
||||
return handler();
|
||||
} },
|
||||
button ? React.createElement(
|
||||
Button,
|
||||
null,
|
||||
button
|
||||
) : React.createElement(
|
||||
Button,
|
||||
{ className: c('nc-dropdownButton', classNameButton) },
|
||||
label
|
||||
),
|
||||
React.createElement(
|
||||
Menu,
|
||||
null,
|
||||
React.createElement(
|
||||
'ul',
|
||||
{ className: 'nc-dropdownList', style: style },
|
||||
children
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
var DropdownItem = function DropdownItem(_ref2) {
|
||||
var label = _ref2.label,
|
||||
icon = _ref2.icon,
|
||||
iconDirection = _ref2.iconDirection,
|
||||
onClick = _ref2.onClick,
|
||||
className = _ref2.className;
|
||||
return React.createElement(
|
||||
MenuItem,
|
||||
{ className: c('nc-dropdownItem', className), value: onClick },
|
||||
React.createElement(
|
||||
'span',
|
||||
null,
|
||||
label
|
||||
),
|
||||
icon ? React.createElement(
|
||||
'span',
|
||||
{ className: 'nc-dropdownItemIcon' },
|
||||
React.createElement(Icon, { type: icon, direction: iconDirection, size: 'small' })
|
||||
) : null
|
||||
);
|
||||
};
|
||||
|
||||
export { Dropdown, DropdownItem };
|
||||
;
|
||||
|
||||
(function () {
|
||||
var reactHotLoader = require('react-hot-loader').default;
|
||||
|
||||
var leaveModule = require('react-hot-loader').leaveModule;
|
||||
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactHotLoader.register(Dropdown, 'Dropdown', 'src/Dropdown/Dropdown.js');
|
||||
reactHotLoader.register(DropdownItem, 'DropdownItem', 'src/Dropdown/Dropdown.js');
|
||||
leaveModule(module);
|
||||
})();
|
||||
|
||||
;
|
@ -1,77 +0,0 @@
|
||||
import _extends from 'babel-runtime/helpers/extends';
|
||||
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
|
||||
|
||||
(function () {
|
||||
var enterModule = require('react-hot-loader').enterModule;
|
||||
|
||||
enterModule && enterModule(module);
|
||||
})();
|
||||
|
||||
import React from 'react';
|
||||
import icons from './icons';
|
||||
|
||||
/**
|
||||
* Calculates rotation for icons that have a `direction` property configured
|
||||
* in the imported icon definition object. If no direction is configured, a
|
||||
* neutral rotation value is returned.
|
||||
*
|
||||
* Returned value is a string of shape `${degrees}deg`, for use in a CSS
|
||||
* transform.
|
||||
*/
|
||||
var getRotation = function getRotation(iconDirection, newDirection) {
|
||||
if (!iconDirection || !newDirection) {
|
||||
return '0deg';
|
||||
}
|
||||
var rotations = { right: 90, down: 180, left: 270, up: 360 };
|
||||
var degrees = rotations[newDirection] - rotations[iconDirection];
|
||||
return degrees + 'deg';
|
||||
};
|
||||
|
||||
var sizes = {
|
||||
xsmall: '12px',
|
||||
small: '18px',
|
||||
medium: '24px',
|
||||
large: '32px'
|
||||
};
|
||||
|
||||
var Icon = function Icon(props) {
|
||||
var type = props.type,
|
||||
direction = props.direction,
|
||||
_props$size = props.size,
|
||||
size = _props$size === undefined ? 'medium' : _props$size,
|
||||
_props$className = props.className,
|
||||
className = _props$className === undefined ? '' : _props$className,
|
||||
width = props.width,
|
||||
height = props.height,
|
||||
remainingProps = _objectWithoutProperties(props, ['type', 'direction', 'size', 'className', 'width', 'height']);
|
||||
|
||||
var icon = icons[type];
|
||||
var rotation = getRotation(icon.direction, direction);
|
||||
var transform = 'rotate(' + rotation + ')';
|
||||
var sizeResolved = sizes[size] || size;
|
||||
var style = { width: sizeResolved, height: sizeResolved, transform: transform };
|
||||
return React.createElement(
|
||||
'span',
|
||||
_extends({ className: 'nc-icon ' + className }, remainingProps),
|
||||
React.createElement('span', { dangerouslySetInnerHTML: { __html: icon.image }, style: style })
|
||||
);
|
||||
};
|
||||
export { Icon };
|
||||
;
|
||||
|
||||
(function () {
|
||||
var reactHotLoader = require('react-hot-loader').default;
|
||||
|
||||
var leaveModule = require('react-hot-loader').leaveModule;
|
||||
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactHotLoader.register(getRotation, 'getRotation', 'src/Icon/Icon.js');
|
||||
reactHotLoader.register(sizes, 'sizes', 'src/Icon/Icon.js');
|
||||
reactHotLoader.register(Icon, 'Icon', 'src/Icon/Icon.js');
|
||||
leaveModule(module);
|
||||
})();
|
||||
|
||||
;
|
@ -1,70 +0,0 @@
|
||||
import _extends from 'babel-runtime/helpers/extends';
|
||||
|
||||
(function () {
|
||||
var enterModule = require('react-hot-loader').enterModule;
|
||||
|
||||
enterModule && enterModule(module);
|
||||
})();
|
||||
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import images from './images/_index';
|
||||
|
||||
/**
|
||||
* This module outputs icon objects with the following shape:
|
||||
*
|
||||
* {
|
||||
* image: <svg>...</svg>,
|
||||
* ...props
|
||||
* }
|
||||
*
|
||||
* `props` here are config properties defined in this file for specific icons.
|
||||
* For example, an icon may face a specific direction, and the Icon component
|
||||
* accepts a `direction` prop to rotate directional icons, which relies on
|
||||
* defining the default direction here.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configuration for individual icons.
|
||||
*/
|
||||
var config = {
|
||||
'arrow': {
|
||||
direction: 'left'
|
||||
},
|
||||
'chevron': {
|
||||
direction: 'down'
|
||||
},
|
||||
'chevron-double': {
|
||||
direction: 'down'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Map icon definition objects - imported object of images simply maps the icon
|
||||
* name to the raw svg, so we move that to the `image` property of the
|
||||
* definition object and set any additional configured properties for each icon.
|
||||
*/
|
||||
var icons = mapValues(images, function (image, name) {
|
||||
var props = config[name] || {};
|
||||
return _extends({ image: image }, props);
|
||||
});
|
||||
|
||||
var _default = icons;
|
||||
export default _default;
|
||||
;
|
||||
|
||||
(function () {
|
||||
var reactHotLoader = require('react-hot-loader').default;
|
||||
|
||||
var leaveModule = require('react-hot-loader').leaveModule;
|
||||
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactHotLoader.register(config, 'config', 'src/Icon/icons.js');
|
||||
reactHotLoader.register(icons, 'icons', 'src/Icon/icons.js');
|
||||
reactHotLoader.register(_default, 'default', 'src/Icon/icons.js');
|
||||
leaveModule(module);
|
||||
})();
|
||||
|
||||
;
|
File diff suppressed because one or more lines are too long
@ -1,57 +0,0 @@
|
||||
(function () {
|
||||
var enterModule = require('react-hot-loader').enterModule;
|
||||
|
||||
enterModule && enterModule(module);
|
||||
})();
|
||||
|
||||
import React from 'react';
|
||||
import c from 'classnames';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
export var ListItemTopBar = function ListItemTopBar(_ref) {
|
||||
var collapsed = _ref.collapsed,
|
||||
onCollapseToggle = _ref.onCollapseToggle,
|
||||
onRemove = _ref.onRemove,
|
||||
dragHandleHOC = _ref.dragHandleHOC,
|
||||
className = _ref.className;
|
||||
|
||||
var DragHandle = dragHandleHOC && dragHandleHOC(function () {
|
||||
return React.createElement(
|
||||
'span',
|
||||
{ className: 'nc-listItemTopBar-dragIcon' },
|
||||
React.createElement(Icon, { type: 'drag-handle', size: 'small' })
|
||||
);
|
||||
});
|
||||
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: c('nc-listItemTopBar', className) },
|
||||
onCollapseToggle ? React.createElement(
|
||||
'button',
|
||||
{ className: 'nc-listItemTopBar-toggleButton', onClick: onCollapseToggle },
|
||||
React.createElement(Icon, { type: 'chevron', size: 'small', direction: collapsed ? 'right' : 'down' })
|
||||
) : null,
|
||||
dragHandleHOC ? React.createElement(DragHandle, null) : null,
|
||||
onRemove ? React.createElement(
|
||||
'button',
|
||||
{ className: 'nc-listItemTopBar-removeButton', onClick: onRemove },
|
||||
React.createElement(Icon, { type: 'close', size: 'small' })
|
||||
) : null
|
||||
);
|
||||
};
|
||||
;
|
||||
|
||||
(function () {
|
||||
var reactHotLoader = require('react-hot-loader').default;
|
||||
|
||||
var leaveModule = require('react-hot-loader').leaveModule;
|
||||
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactHotLoader.register(ListItemTopBar, 'ListItemTopBar', 'src/ListItemTopBar/ListItemTopBar.js');
|
||||
leaveModule(module);
|
||||
})();
|
||||
|
||||
;
|
@ -1,128 +0,0 @@
|
||||
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
|
||||
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
||||
import _createClass from 'babel-runtime/helpers/createClass';
|
||||
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
||||
import _inherits from 'babel-runtime/helpers/inherits';
|
||||
|
||||
(function () {
|
||||
var enterModule = require('react-hot-loader').enterModule;
|
||||
|
||||
enterModule && enterModule(module);
|
||||
})();
|
||||
|
||||
import React from 'react';
|
||||
import CSSTransition from 'react-transition-group/CSSTransition';
|
||||
import c from 'classnames';
|
||||
|
||||
export var Loader = function (_React$Component) {
|
||||
_inherits(Loader, _React$Component);
|
||||
|
||||
function Loader() {
|
||||
var _ref;
|
||||
|
||||
var _temp, _this, _ret;
|
||||
|
||||
_classCallCheck(this, Loader);
|
||||
|
||||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Loader.__proto__ || _Object$getPrototypeOf(Loader)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
|
||||
currentItem: 0
|
||||
}, _this.setAnimation = function () {
|
||||
if (_this.interval) return;
|
||||
var children = _this.props.children;
|
||||
|
||||
|
||||
_this.interval = setInterval(function () {
|
||||
var nextItem = _this.state.currentItem === children.length - 1 ? 0 : _this.state.currentItem + 1;
|
||||
_this.setState({ currentItem: nextItem });
|
||||
}, 5000);
|
||||
}, _this.renderChild = function () {
|
||||
var children = _this.props.children;
|
||||
var currentItem = _this.state.currentItem;
|
||||
|
||||
if (!children) {
|
||||
return null;
|
||||
} else if (typeof children == 'string') {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'nc-loader-text' },
|
||||
children
|
||||
);
|
||||
} else if (Array.isArray(children)) {
|
||||
_this.setAnimation();
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'nc-loader-text' },
|
||||
React.createElement(
|
||||
CSSTransition,
|
||||
{
|
||||
classNames: {
|
||||
enter: 'nc-loader-enter',
|
||||
enterActive: 'nc-loader-enterActive',
|
||||
exit: 'nc-loader-exit',
|
||||
exitActive: 'nc-loader-exitActive'
|
||||
},
|
||||
timeout: 500
|
||||
},
|
||||
React.createElement(
|
||||
'div',
|
||||
{ key: currentItem, className: 'nc-loader-animateItem' },
|
||||
children[currentItem]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}, _temp), _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
_createClass(Loader, [{
|
||||
key: 'componentWillUnmount',
|
||||
value: function componentWillUnmount() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _props = this.props,
|
||||
active = _props.active,
|
||||
className = _props.className;
|
||||
|
||||
var combinedClassName = c('nc-loader-root', { 'nc-loader-active': active }, className);
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: combinedClassName },
|
||||
this.renderChild()
|
||||
);
|
||||
}
|
||||
}, {
|
||||
key: '__reactstandin__regenerateByEval',
|
||||
// @ts-ignore
|
||||
value: function __reactstandin__regenerateByEval(key, code) {
|
||||
// @ts-ignore
|
||||
this[key] = eval(code);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Loader;
|
||||
}(React.Component);
|
||||
;
|
||||
|
||||
(function () {
|
||||
var reactHotLoader = require('react-hot-loader').default;
|
||||
|
||||
var leaveModule = require('react-hot-loader').leaveModule;
|
||||
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactHotLoader.register(Loader, 'Loader', 'src/Loader/Loader.js');
|
||||
leaveModule(module);
|
||||
})();
|
||||
|
||||
;
|
@ -1,57 +0,0 @@
|
||||
import _extends from 'babel-runtime/helpers/extends';
|
||||
|
||||
(function () {
|
||||
var enterModule = require('react-hot-loader').enterModule;
|
||||
|
||||
enterModule && enterModule(module);
|
||||
})();
|
||||
|
||||
import React from 'react';
|
||||
import ReactToggled from 'react-toggled';
|
||||
import c from 'classnames';
|
||||
|
||||
export var Toggle = function Toggle(_ref) {
|
||||
var active = _ref.active,
|
||||
onChange = _ref.onChange,
|
||||
className = _ref.className,
|
||||
classNameBackground = _ref.classNameBackground,
|
||||
classNameSwitch = _ref.classNameSwitch,
|
||||
onFocus = _ref.onFocus,
|
||||
onBlur = _ref.onBlur;
|
||||
return React.createElement(
|
||||
ReactToggled,
|
||||
{ on: active, onToggle: onChange },
|
||||
function (_ref2) {
|
||||
var on = _ref2.on,
|
||||
getElementTogglerProps = _ref2.getElementTogglerProps;
|
||||
return React.createElement(
|
||||
'span',
|
||||
_extends({
|
||||
className: c('nc-toggle', className, { 'nc-toggle-active': on }),
|
||||
role: 'switch',
|
||||
'aria-checked': on.toString(),
|
||||
onFocus: onFocus,
|
||||
onBlur: onBlur
|
||||
}, getElementTogglerProps()),
|
||||
React.createElement('span', { className: 'nc-toggle-background ' + classNameBackground }),
|
||||
React.createElement('span', { className: 'nc-toggle-switch ' + classNameSwitch })
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
;
|
||||
|
||||
(function () {
|
||||
var reactHotLoader = require('react-hot-loader').default;
|
||||
|
||||
var leaveModule = require('react-hot-loader').leaveModule;
|
||||
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactHotLoader.register(Toggle, 'Toggle', 'src/Toggle/Toggle.js');
|
||||
leaveModule(module);
|
||||
})();
|
||||
|
||||
;
|
7249
packages/netlify-cms-ui-default/package-lock.json
generated
7249
packages/netlify-cms-ui-default/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,14 +8,17 @@
|
||||
"netlify-cms"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "parcel build src --out-dir ."
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"emotion": "^9.1.3",
|
||||
"lodash": "^4.13.1",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.0.0",
|
||||
"react": "15.x || 16.x",
|
||||
"react-aria-menubutton": "^5.1.0",
|
||||
"react-emotion": "^9.2.6",
|
||||
"react-toggled": "^1.1.2",
|
||||
"react-transition-group": "^2.2.1"
|
||||
},
|
||||
|
115
packages/netlify-cms-ui-default/src/Dropdown.js
Normal file
115
packages/netlify-cms-ui-default/src/Dropdown.js
Normal file
@ -0,0 +1,115 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled, { css } from 'react-emotion';
|
||||
import { Wrapper, Button as DropdownButton, Menu, MenuItem } from 'react-aria-menubutton';
|
||||
import { shadows, colors, colorsRaw, lengths, buttons, components } from './styles';
|
||||
import Icon from './Icon';
|
||||
|
||||
const StyledWrapper = styled(Wrapper)`
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
`
|
||||
|
||||
const StyledDropdownButton = styled(DropdownButton)`
|
||||
${buttons.button};
|
||||
${buttons.default};
|
||||
display: block;
|
||||
padding-left: 20px;
|
||||
padding-right: 40px;
|
||||
|
||||
&:after {
|
||||
${components.caretDown};
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
color: currentColor;
|
||||
}
|
||||
`
|
||||
|
||||
const DropdownList = styled.ul`
|
||||
${shadows.dropDeep};
|
||||
background-color: ${colorsRaw.white};
|
||||
border-radius: ${lengths.borderRadius};
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
z-index: 1;
|
||||
|
||||
${props => css`
|
||||
width: ${props.width};
|
||||
top: ${props.top};
|
||||
left: ${props.position === 'left' ? 0 : 'auto'};
|
||||
right: ${props.position === 'right' ? 0 : 'auto'};
|
||||
`}
|
||||
`
|
||||
|
||||
const StyledMenuItem = styled(MenuItem)`
|
||||
${buttons.button};
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
color: ${colorsRaw.gray};
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid #eaebf1;
|
||||
padding: 10px 14px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
color: ${colors.active};
|
||||
background-color: ${colors.activeBackground};
|
||||
}
|
||||
`
|
||||
|
||||
const MenuItemIconContainer = styled.div`
|
||||
flex: 1 0 32px;
|
||||
text-align: right;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
`
|
||||
|
||||
const Dropdown = ({
|
||||
renderButton,
|
||||
dropdownWidth = 'auto',
|
||||
dropdownPosition = 'left',
|
||||
dropdownTopOverlap = '0',
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<StyledWrapper onSelection={handler => handler()}>
|
||||
{renderButton()}
|
||||
<Menu>
|
||||
<DropdownList width={dropdownWidth} top={dropdownTopOverlap} position={dropdownPosition}>
|
||||
{children}
|
||||
</DropdownList>
|
||||
</Menu>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownItem = ({ label, icon, iconDirection, onClick }) => (
|
||||
<StyledMenuItem value={onClick}>
|
||||
<span>{label}</span>
|
||||
{
|
||||
icon
|
||||
? <MenuItemIconContainer>
|
||||
<Icon type={icon} direction={iconDirection} size="small"/>
|
||||
</MenuItemIconContainer>
|
||||
: null
|
||||
}
|
||||
</StyledMenuItem>
|
||||
);
|
||||
|
||||
export { Dropdown as default, DropdownItem, DropdownButton, StyledDropdownButton };
|
@ -1,77 +0,0 @@
|
||||
:root {
|
||||
--dropdownList: {
|
||||
@apply(--dropShadowDeep);
|
||||
background-color: #fff;
|
||||
border-radius: var(--borderRadius);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
--dropdownItem: {
|
||||
@apply --button;
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
color: var(--colorText);
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid #eaebf1;
|
||||
padding: 10px 14px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
color: var(--colorBlue);
|
||||
background-color: var(--colorActiveBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nc-dropdown {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.nc-dropdownButton {
|
||||
@apply --button;
|
||||
@apply --buttonDefault;
|
||||
display: block;
|
||||
padding-left: 20px;
|
||||
padding-right: 40px;
|
||||
|
||||
&:after {
|
||||
@apply(--caretDown);
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
.nc-dropdownList {
|
||||
@apply(--dropdownList);
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.nc-dropdownItem {
|
||||
@apply(--dropdownItem);
|
||||
}
|
||||
|
||||
.nc-dropdownItemIcon {
|
||||
flex: 1 0 32px;
|
||||
text-align: right;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import c from 'classnames';
|
||||
import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
const Dropdown = ({
|
||||
label,
|
||||
button,
|
||||
className,
|
||||
classNameButton = '',
|
||||
dropdownWidth = 'auto',
|
||||
dropdownPosition = 'left',
|
||||
dropdownTopOverlap = '0',
|
||||
children
|
||||
}) => {
|
||||
const style = {
|
||||
width: dropdownWidth,
|
||||
top: dropdownTopOverlap,
|
||||
left: dropdownPosition === 'left' ? 0 : 'auto',
|
||||
right: dropdownPosition === 'right' ? 0 : 'auto',
|
||||
};
|
||||
return (
|
||||
<Wrapper className={c('nc-dropdown', className)} onSelection={handler => handler()}>
|
||||
{
|
||||
button
|
||||
? <Button>{button}</Button>
|
||||
: <Button className={c('nc-dropdownButton', classNameButton)}>{label}</Button>
|
||||
}
|
||||
<Menu>
|
||||
<ul className="nc-dropdownList" style={style}>
|
||||
{children}
|
||||
</ul>
|
||||
</Menu>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownItem = ({ label, icon, iconDirection, onClick, className }) => (
|
||||
<MenuItem className={c('nc-dropdownItem', className)} value={onClick}>
|
||||
<span>{label}</span>
|
||||
{
|
||||
icon
|
||||
? <span className="nc-dropdownItemIcon">
|
||||
<Icon type={icon} direction={iconDirection} size="small"/>
|
||||
</span>
|
||||
: null
|
||||
}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
|
||||
export { Dropdown, DropdownItem };
|
62
packages/netlify-cms-ui-default/src/Icon.js
Normal file
62
packages/netlify-cms-ui-default/src/Icon.js
Normal file
@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import styled from 'react-emotion';
|
||||
import icons from './Icon/icons';
|
||||
|
||||
const IconWrapper = styled.span`
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
width: ${props => props.size};
|
||||
height: ${props => props.size};
|
||||
transform: ${props => `rotation(${props.rotation})`};
|
||||
|
||||
& path:not(.no-fill),
|
||||
& circle:not(.no-fill),
|
||||
& polygon:not(.no-fill),
|
||||
& rect:not(.no-fill) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
& path.clipped {
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
`
|
||||
|
||||
/**
|
||||
* Calculates rotation for icons that have a `direction` property configured
|
||||
* in the imported icon definition object. If no direction is configured, a
|
||||
* neutral rotation value is returned.
|
||||
*
|
||||
* Returned value is a string of shape `${degrees}deg`, for use in a CSS
|
||||
* transform.
|
||||
*/
|
||||
const getRotation = (iconDirection, newDirection) => {
|
||||
if (!iconDirection || !newDirection) {
|
||||
return '0deg';
|
||||
}
|
||||
const rotations = { right: 90, down: 180, left: 270, up: 360 };
|
||||
const degrees = rotations[newDirection] - rotations[iconDirection];
|
||||
return `${degrees}deg`;
|
||||
}
|
||||
|
||||
const sizes = {
|
||||
xsmall: '12px',
|
||||
small: '18px',
|
||||
medium: '24px',
|
||||
large: '32px',
|
||||
};
|
||||
|
||||
const Icon = ({ type, direction, size = 'medium', width, height, className }) => (
|
||||
<IconWrapper
|
||||
className={className}
|
||||
dangerouslySetInnerHTML={{ __html: icons[type].image }}
|
||||
size={sizes[size] || size}
|
||||
rotation={getRotation(icons[type].direction, direction)}
|
||||
/>
|
||||
);
|
||||
|
||||
export default styled(Icon)``
|
@ -1,24 +0,0 @@
|
||||
.nc-icon {
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
|
||||
& > span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
& path:not(.no-fill),
|
||||
& circle:not(.no-fill),
|
||||
& polygon:not(.no-fill),
|
||||
& rect:not(.no-fill) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
& path.clipped {
|
||||
fill: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.nc-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import React from 'react';
|
||||
import icons from './icons';
|
||||
|
||||
/**
|
||||
* Calculates rotation for icons that have a `direction` property configured
|
||||
* in the imported icon definition object. If no direction is configured, a
|
||||
* neutral rotation value is returned.
|
||||
*
|
||||
* Returned value is a string of shape `${degrees}deg`, for use in a CSS
|
||||
* transform.
|
||||
*/
|
||||
const getRotation = (iconDirection, newDirection) => {
|
||||
if (!iconDirection || !newDirection) {
|
||||
return '0deg';
|
||||
}
|
||||
const rotations = { right: 90, down: 180, left: 270, up: 360 };
|
||||
const degrees = rotations[newDirection] - rotations[iconDirection];
|
||||
return `${degrees}deg`;
|
||||
}
|
||||
|
||||
const sizes = {
|
||||
xsmall: '12px',
|
||||
small: '18px',
|
||||
medium: '24px',
|
||||
large: '32px',
|
||||
};
|
||||
|
||||
export const Icon = props => {
|
||||
const {
|
||||
type,
|
||||
direction,
|
||||
size = 'medium',
|
||||
className = '',
|
||||
width,
|
||||
height,
|
||||
...remainingProps
|
||||
} = props;
|
||||
const icon = icons[type];
|
||||
const rotation = getRotation(icon.direction, direction)
|
||||
const transform = `rotate(${rotation})`;
|
||||
const sizeResolved = sizes[size] || size;
|
||||
const style = { width: sizeResolved, height: sizeResolved, transform };
|
||||
return (
|
||||
<span className={`nc-icon ${className}`} {...remainingProps}>
|
||||
<span dangerouslySetInnerHTML={{ __html: icon.image }} style={style}></span>
|
||||
</span>
|
||||
);
|
||||
}
|
61
packages/netlify-cms-ui-default/src/ListItemTopBar.js
Normal file
61
packages/netlify-cms-ui-default/src/ListItemTopBar.js
Normal file
@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import styled from 'react-emotion';
|
||||
import Icon from './Icon';
|
||||
import { colors, lengths } from './styles';
|
||||
|
||||
const TopBarButton = styled.button`
|
||||
color: ${colors.controlLabel};
|
||||
background: transparent;
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const TopBarButtonSpan = TopBarButton.withComponent('span');
|
||||
|
||||
const DragIcon = styled(TopBarButtonSpan)`
|
||||
width: 100%;
|
||||
cursor: move;
|
||||
`
|
||||
|
||||
const ListItemTopBar = ({ collapsed, onCollapseToggle, onRemove, dragHandleHOC }) => (
|
||||
<div>
|
||||
{
|
||||
onCollapseToggle
|
||||
? <TopBarButton onClick={onCollapseToggle}>
|
||||
<Icon type="chevron" size="small" direction={collapsed ? 'right' : 'down'}/>
|
||||
</TopBarButton>
|
||||
: null
|
||||
}
|
||||
{
|
||||
dragHandleHOC
|
||||
? <DragIcon>
|
||||
<Icon type="drag-handle" size="small"/>
|
||||
</DragIcon>
|
||||
: null
|
||||
}
|
||||
{
|
||||
onRemove
|
||||
? <TopBarButton onClick={onRemove}>
|
||||
<Icon type="close" size="small"/>
|
||||
</TopBarButton>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
const StyledListItemTopBar = styled(ListItemTopBar)`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 26px;
|
||||
border-radius: ${lengths.borderRadius} ${lengths.borderRadius} 0 0;
|
||||
position: relative;
|
||||
`
|
||||
|
||||
export default StyledListItemTopBar;
|
@ -1,29 +0,0 @@
|
||||
.nc-listItemTopBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 26px;
|
||||
border-radius: var(--borderRadius) var(--borderRadius) 0 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nc-listItemTopBar-toggleButton,
|
||||
.nc-listItemTopBar-dragIcon,
|
||||
.nc-listItemTopBar-removeButton {
|
||||
color: var(--controlLabelColor);
|
||||
background: transparent;
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nc-listControl-dragIcon {
|
||||
width: 100%;
|
||||
cursor: move;
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
import React from 'react';
|
||||
import c from 'classnames';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
|
||||
export const ListItemTopBar = ({ collapsed, onCollapseToggle, onRemove, dragHandleHOC, className }) => {
|
||||
const DragHandle = dragHandleHOC && dragHandleHOC(() =>
|
||||
<span className="nc-listItemTopBar-dragIcon">
|
||||
<Icon type="drag-handle" size="small"/>
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={c('nc-listItemTopBar', className)}>
|
||||
{
|
||||
onCollapseToggle
|
||||
? <button className="nc-listItemTopBar-toggleButton" onClick={onCollapseToggle}>
|
||||
<Icon type="chevron" size="small" direction={collapsed ? 'right' : 'down'}/>
|
||||
</button>
|
||||
: null
|
||||
}
|
||||
{ dragHandleHOC ? <DragHandle/> : null }
|
||||
{
|
||||
onRemove
|
||||
? <button className="nc-listItemTopBar-removeButton" onClick={onRemove}>
|
||||
<Icon type="close" size="small"/>
|
||||
</button>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
153
packages/netlify-cms-ui-default/src/Loader.js
Normal file
153
packages/netlify-cms-ui-default/src/Loader.js
Normal file
@ -0,0 +1,153 @@
|
||||
import React from 'react';
|
||||
import styled, { css, keyframes } from 'react-emotion';
|
||||
import CSSTransition from 'react-transition-group/CSSTransition';
|
||||
import { colors } from './styles';
|
||||
|
||||
const styles = {
|
||||
disabled: css`
|
||||
display: none;
|
||||
`,
|
||||
active: css`
|
||||
display: block;
|
||||
`,
|
||||
enter: css`
|
||||
opacity: 0.01;
|
||||
`,
|
||||
enterActive: css`
|
||||
opacity: 1;
|
||||
transition: opacity 500ms ease-in;
|
||||
`,
|
||||
exit: css`
|
||||
opacity: 1;
|
||||
`,
|
||||
exitActive: css`
|
||||
opacity: 0.01;
|
||||
transition: opacity 300ms ease-in;
|
||||
`,
|
||||
};
|
||||
|
||||
const animations = {
|
||||
loader: keyframes`
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
const LoaderText = styled.div`
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
text-align: center;
|
||||
color: #767676;
|
||||
margin-top: 55px;
|
||||
line-height: 35px;
|
||||
`
|
||||
|
||||
const LoaderItem = styled.div`
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
transform: translateX(-50%);
|
||||
`
|
||||
|
||||
export class Loader extends React.Component {
|
||||
state = {
|
||||
currentItem: 0,
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
setAnimation = () => {
|
||||
if (this.interval) return;
|
||||
const { children } = this.props;
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
const nextItem = (this.state.currentItem === children.length - 1) ? 0 : this.state.currentItem + 1;
|
||||
this.setState({ currentItem: nextItem });
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
renderChild = () => {
|
||||
const { children } = this.props;
|
||||
const { currentItem } = this.state;
|
||||
if (!children) {
|
||||
return null;
|
||||
} else if (typeof children == 'string') {
|
||||
return <LoaderText>{children}</LoaderText>;
|
||||
} else if (Array.isArray(children)) {
|
||||
this.setAnimation();
|
||||
return (
|
||||
<LoaderText>
|
||||
<CSSTransition
|
||||
classNames={{
|
||||
enter: styles.enter,
|
||||
enterActive: styles.enterActive,
|
||||
exit: styles.exit,
|
||||
exitActive: styles.exitActive,
|
||||
}}
|
||||
timeout={500}
|
||||
>
|
||||
<LoaderItem key={currentItem}>{children[currentItem]}</LoaderItem>
|
||||
</CSSTransition>
|
||||
</LoaderText>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { active, className } = this.props;
|
||||
return <div>{this.renderChild()}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
const StyledLoader = styled(Loader)`
|
||||
display: ${props => props.active ? 'block' : 'none'};
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: 0px;
|
||||
text-align: center;
|
||||
z-index: 1000;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
width: 2.28571429rem;
|
||||
height: 2.28571429rem;
|
||||
margin: 0em 0em 0em -1.14285714rem;
|
||||
}
|
||||
|
||||
/* Static Shape */
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0%;
|
||||
left: 50%;
|
||||
border-radius: 500rem;
|
||||
border: 0.2em solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Active Shape */
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0%;
|
||||
left: 50%;
|
||||
animation: ${animations.loader} 0.6s linear;
|
||||
animation-iteration-count: infinite;
|
||||
border-radius: 500rem;
|
||||
border-color: ${colors.active} transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 0.2em;
|
||||
box-shadow: 0px 0px 0px 1px transparent;
|
||||
}
|
||||
`
|
||||
|
||||
export default StyledLoader;
|
@ -1,108 +0,0 @@
|
||||
/* Active Animation */
|
||||
|
||||
@-webkit-keyframes loader {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loader {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.nc-loader-root {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: 0px;
|
||||
text-align: center;
|
||||
z-index: 1000;
|
||||
-webkit-transform: translateX(-50%) translateY(-50%);
|
||||
-ms-transform: translateX(-50%) translateY(-50%);
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
@apply(--loaderSize);
|
||||
margin: 0em 0em 0em -1.14285714rem;
|
||||
}
|
||||
|
||||
/* Static Shape */
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0%;
|
||||
left: 50%;
|
||||
border-radius: 500rem;
|
||||
border: 0.2em solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Active Shape */
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0%;
|
||||
left: 50%;
|
||||
animation: loader 0.6s linear;
|
||||
animation-iteration-count: infinite;
|
||||
border-radius: 500rem;
|
||||
border-color: #3A69C7 transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 0.2em;
|
||||
box-shadow: 0px 0px 0px 1px transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.nc-loader-text {
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
text-align: center;
|
||||
color: #767676;
|
||||
margin-top: 55px;
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
.nc-loader-active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nc-loader-disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*Animations*/
|
||||
.nc-loader-animateItem{
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.nc-loader-enter {
|
||||
opacity: 0.01;
|
||||
}
|
||||
.nc-loader-enter.nc-loader-enterActive {
|
||||
opacity: 1;
|
||||
transition: opacity 500ms ease-in;
|
||||
}
|
||||
.nc-loader-exit {
|
||||
opacity: 1;
|
||||
}
|
||||
.nc-loader-exit.nc-loader-exitActive {
|
||||
opacity: 0.01;
|
||||
transition: opacity 300ms ease-in;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
import React from 'react';
|
||||
import CSSTransition from 'react-transition-group/CSSTransition';
|
||||
import c from 'classnames';
|
||||
|
||||
export class Loader extends React.Component {
|
||||
|
||||
state = {
|
||||
currentItem: 0,
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
setAnimation = () => {
|
||||
if (this.interval) return;
|
||||
const { children } = this.props;
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
const nextItem = (this.state.currentItem === children.length - 1) ? 0 : this.state.currentItem + 1;
|
||||
this.setState({ currentItem: nextItem });
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
renderChild = () => {
|
||||
const { children } = this.props;
|
||||
const { currentItem } = this.state;
|
||||
if (!children) {
|
||||
return null;
|
||||
} else if (typeof children == 'string') {
|
||||
return <div className="nc-loader-text">{children}</div>;
|
||||
} else if (Array.isArray(children)) {
|
||||
this.setAnimation();
|
||||
return (<div className="nc-loader-text">
|
||||
<CSSTransition
|
||||
classNames={{
|
||||
enter: 'nc-loader-enter',
|
||||
enterActive: 'nc-loader-enterActive',
|
||||
exit: 'nc-loader-exit',
|
||||
exitActive: 'nc-loader-exitActive',
|
||||
}}
|
||||
timeout={500}
|
||||
>
|
||||
<div key={currentItem} className="nc-loader-animateItem">{children[currentItem]}</div>
|
||||
</CSSTransition>
|
||||
</div>);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { active, className } = this.props;
|
||||
const combinedClassName = c('nc-loader-root', { 'nc-loader-active': active }, className);
|
||||
return <div className={combinedClassName}>{this.renderChild()}</div>;
|
||||
}
|
||||
}
|
67
packages/netlify-cms-ui-default/src/Toggle.js
Normal file
67
packages/netlify-cms-ui-default/src/Toggle.js
Normal file
@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
import styled, { css, cx } from 'react-emotion';
|
||||
import ReactToggled from 'react-toggled';
|
||||
import { colors, colorsRaw, shadows, transitions } from './styles';
|
||||
|
||||
const styles = {
|
||||
switch: css`
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
`,
|
||||
switchHandle: css`
|
||||
${shadows.dropDeep};
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: ${colorsRaw.white};
|
||||
transition: transform ${transitions.main};
|
||||
`,
|
||||
switchHandleActive: css`
|
||||
transform: translateX(20px);
|
||||
`,
|
||||
switchBackground: css`
|
||||
width: 34px;
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
background-color: ${colors.active};
|
||||
`,
|
||||
};
|
||||
|
||||
const Toggle = ({
|
||||
active,
|
||||
onChange,
|
||||
className,
|
||||
classNameBackground,
|
||||
classNameSwitch,
|
||||
onFocus,
|
||||
onBlur
|
||||
}) =>
|
||||
<ReactToggled on={active} onToggle={onChange}>
|
||||
{({on, getElementTogglerProps}) => (
|
||||
<span
|
||||
className={cx(styles.switch, className)}
|
||||
role="switch"
|
||||
aria-checked={on.toString()}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
{...getElementTogglerProps()}
|
||||
>
|
||||
<span className={cx(styles.switchBackground, classNameBackground)}/>
|
||||
<span className={cx(
|
||||
styles.switchHandle,
|
||||
classNameSwitch,
|
||||
{ [styles.switchHandleActive]: on },
|
||||
)}/>
|
||||
</span>
|
||||
)}
|
||||
</ReactToggled>;
|
||||
|
||||
export default styled(Toggle)``
|
@ -1,32 +0,0 @@
|
||||
.nc-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nc-toggle-background {
|
||||
width: 34px;
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
background-color: #3a69c7;
|
||||
}
|
||||
|
||||
.nc-toggle-switch {
|
||||
@apply(--dropShadowDeep);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
transition: transform var(--transition);
|
||||
}
|
||||
|
||||
.nc-toggle-active .nc-toggle-switch {
|
||||
transform: translateX(20px);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import React from 'react'
|
||||
import ReactToggled from 'react-toggled';
|
||||
import c from 'classnames';
|
||||
|
||||
export const Toggle = ({
|
||||
active,
|
||||
onChange,
|
||||
className,
|
||||
classNameBackground,
|
||||
classNameSwitch,
|
||||
onFocus,
|
||||
onBlur
|
||||
}) =>
|
||||
<ReactToggled on={active} onToggle={onChange}>
|
||||
{({on, getElementTogglerProps}) => (
|
||||
<span
|
||||
className={c('nc-toggle', className, { 'nc-toggle-active': on })}
|
||||
role="switch"
|
||||
aria-checked={on.toString()}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
{...getElementTogglerProps()}
|
||||
>
|
||||
<span className={`nc-toggle-background ${classNameBackground}`}/>
|
||||
<span className={`nc-toggle-switch ${classNameSwitch}`}/>
|
||||
</span>
|
||||
)}
|
||||
</ReactToggled>;
|
@ -1,7 +0,0 @@
|
||||
import { Dropdown, DropdownItem } from './Dropdown/Dropdown';
|
||||
import { Icon } from './Icon/Icon';
|
||||
import { ListItemTopBar } from './ListItemTopBar/ListItemTopBar';
|
||||
import { Loader } from './Loader/Loader';
|
||||
import { Toggle } from './Toggle/Toggle';
|
||||
|
||||
export { Dropdown, DropdownItem, Icon, ListItemTopBar, Loader, Toggle };
|
310
packages/netlify-cms-ui-default/src/styles.js
Normal file
310
packages/netlify-cms-ui-default/src/styles.js
Normal file
@ -0,0 +1,310 @@
|
||||
import { css, injectGlobal } from 'react-emotion';
|
||||
|
||||
/**
|
||||
* Font Stacks
|
||||
*/
|
||||
export 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
|
||||
*/
|
||||
export 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',
|
||||
};
|
||||
|
||||
export 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',
|
||||
};
|
||||
|
||||
export const lengths = {
|
||||
topBarHeight: '56px',
|
||||
inputPadding: '16px 20px',
|
||||
borderRadius: '5px',
|
||||
richTextEditorMinHeight: '300px',
|
||||
borderWidth: '2px',
|
||||
topCardWidth: '682px',
|
||||
pageMargin: '84px 18px',
|
||||
};
|
||||
|
||||
export const borders = {
|
||||
textField: `solid ${lengths.borderWidth} ${colors.textFieldBorder}`,
|
||||
};
|
||||
|
||||
export const transitions = {
|
||||
main: '.2s ease',
|
||||
};
|
||||
|
||||
export const shadows = {
|
||||
drop: css`
|
||||
box-shadow: 0 2px 4px 0 rgba(19, 39, 48, .12);
|
||||
`,
|
||||
dropMain: css`
|
||||
box-shadow: 0 2px 6px 0 rgba(68, 74, 87, 0.05),
|
||||
0 1px 3px 0 rgba(68, 74, 87, 0.10);
|
||||
`,
|
||||
dropMiddle: css`
|
||||
box-shadow: 0 2px 6px 0 rgba(68, 74, 87, 0.15),
|
||||
0 1px 3px 0 rgba(68, 74, 87, 0.30);
|
||||
`,
|
||||
dropDeep: css`
|
||||
box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.15),
|
||||
0 1px 3px 0 rgba(68, 74, 87, 0.25);
|
||||
`,
|
||||
};
|
||||
|
||||
const textBadge = css`
|
||||
font-size: 13px;
|
||||
border-radius: ${lengths.borderRadius};
|
||||
padding: 4px 10px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
`;
|
||||
|
||||
const card = css`
|
||||
${shadows.dropMain};
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
`;
|
||||
|
||||
export 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`
|
||||
height: 23px;
|
||||
line-height: 23px;
|
||||
`,
|
||||
gray: css`
|
||||
background-color: ${colors.button};
|
||||
color: ${colors.buttonText};
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: ${colors.white};
|
||||
background-color: #555a65;
|
||||
}
|
||||
`,
|
||||
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};
|
||||
`,
|
||||
};
|
||||
|
||||
export const components = {
|
||||
card,
|
||||
caretDown: css`
|
||||
color: ${colorsRaw.white};
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 6px solid currentColor;
|
||||
border-radius: 2px;
|
||||
`,
|
||||
textBadgeSuccess: css`
|
||||
${textBadge};
|
||||
color: ${colorsRaw.green};
|
||||
background-color: ${colorsRaw.greenLight};
|
||||
`,
|
||||
textBadgeDanger: css`
|
||||
${textBadge};
|
||||
color: ${colorsRaw.red};
|
||||
background-color: #fbe0d7;
|
||||
`,
|
||||
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;
|
||||
`,
|
||||
}
|
||||
|
||||
injectGlobal`
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:focus {
|
||||
outline: -webkit-focus-ring-color auto ${lengths.borderRadius};
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't show outlines if the user is utilizing mouse rather than keyboard.
|
||||
*/
|
||||
[data-whatintent="mouse"] *:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: ${fonts.primary};
|
||||
font-weight: normal;
|
||||
background-color: ${colors.background};
|
||||
color: ${colors.text};
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p {
|
||||
font-family: ${fonts.primary};
|
||||
color: ${colors.textLead};
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
letter-spacing: 0.4px;
|
||||
color: ${colors.textLead};
|
||||
}
|
||||
|
||||
a,
|
||||
button {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
a {
|
||||
color: ${colors.text};
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
}
|
||||
`;
|
Reference in New Issue
Block a user