migrate core to emotion

This commit is contained in:
Shawn Erquhart
2018-07-06 18:56:28 -04:00
parent 768fcbaa1d
commit 4931711892
114 changed files with 3414 additions and 78296 deletions

View File

@ -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);
})();
;

View File

@ -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);
})();
;

View File

@ -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

View File

@ -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);
})();
;

View File

@ -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);
})();
;

View File

@ -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);
})();
;

File diff suppressed because it is too large Load Diff

View File

@ -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"
},

View 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 };

View File

@ -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;
}

View File

@ -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 };

View 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)``

View File

@ -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%;
}

View File

@ -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>
);
}

View 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;

View File

@ -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;
}

View File

@ -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>
);
};

View 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;

View File

@ -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;
}

View File

@ -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>;
}
}

View 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)``

View File

@ -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);
}

View File

@ -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>;

View File

@ -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 };

View 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;
}
`;