Completely updated React, fixed #11, (hopefully)

This commit is contained in:
2018-03-04 19:11:49 -05:00
parent 6e0afd6e2a
commit 34e5f5139a
13674 changed files with 333464 additions and 473223 deletions

View File

@@ -3,7 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { css } from 'glamor';
const rule = isDefault =>
const styles = isDefault =>
css({
color: isDefault ? '#000' : '#fff',
fontWeight: 'bold',
@@ -21,16 +21,26 @@ const rule = isDefault =>
}
});
function DefaultCloseButton({ closeToast, type }) {
function DefaultCloseButton({ closeToast, type, ariaLabel }) {
return (
<button {...rule(type === 'default')} type="button" onClick={closeToast}>
<button
{...styles(type === 'default')}
type="button"
onClick={closeToast}
aria-label={ariaLabel}
>
</button>
);
}
DefaultCloseButton.propTypes = {
closeToast: PropTypes.func
closeToast: PropTypes.func,
arialLabel: PropTypes.string
};
DefaultCloseButton.defaultProps = {
ariaLabel: 'close'
};
export default DefaultCloseButton;

View File

@@ -9,15 +9,15 @@ const animate = {
animationFillMode: 'both'
};
const animation = pos => {
const styles = pos => {
const { enter, exit } = getAnimation(pos);
const enterAnimation = css.keyframes('enter', {
const enterAnimation = css.keyframes({
'from, 60%, 75%, 90%, to': {
animationTimingFunction: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)'
},
...enter
});
const exitAnimation = css.keyframes('exit', exit);
const exitAnimation = css.keyframes(exit);
return {
enter: css({ ...animate, animationName: enterAnimation }),
@@ -26,15 +26,30 @@ const animation = pos => {
};
function DefaultTransition({ children, position, ...props }) {
const { enter, exit } = animation(position);
const { enter, exit } = styles(position);
const onEnter = node => node.classList.add(enter);
const onEntered = node => node.classList.remove(enter);
const onExit = node => {
const height = node.getBoundingClientRect().height;
node.style.transition = 'padding 0.75s, height 0.75s, maringBottom 0.75s';
node.style.minHeight = 0;
node.style.height = height >= 48 ? height + 'px' : '48px';
requestAnimationFrame(() => {
node.style.padding = 0;
node.style.height = 0;
node.style.marginBottom = 0;
requestAnimationFrame(() => node.classList.add(exit));
});
};
return (
<Transition
{...props}
timeout={750}
onEnter={node => node.classList.add(enter)}
onEntered={node => node.classList.remove(enter)}
onExit={node => node.classList.add(exit)}
onEnter={onEnter}
onEntered={onEntered}
onExit={onExit}
>
{children}
</Transition>

View File

@@ -3,35 +3,37 @@ import PropTypes from 'prop-types';
import { css } from 'glamor';
import { TYPE } from './constant';
import style from './style';
import defaultStyle from './defaultStyle';
const trackProgress = css.keyframes('track-progress', {
const trackProgress = css.keyframes({
'0%': { width: '100%' },
'100%': { width: 0 }
});
const progress = (type, isRunning, hide, delay) =>
const styles = (type, isRunning, hide, delay) =>
css({
position: 'absolute',
bottom: 0,
left: 0,
width: 0,
height: '5px',
zIndex: style.zIndex,
zIndex: defaultStyle.zIndex,
opacity: hide ? 0 : 0.7,
animation: `${trackProgress} linear 1`,
animationPlayState: isRunning ? 'running' : 'paused',
animationDuration: `${delay}ms`,
backgroundColor: 'rgba(255,255,255,.7)',
...(type === 'default' ? { background: style.colorProgressDefault } : {})
...(type === 'default'
? { background: defaultStyle.colorProgressDefault }
: {})
});
function ProgressBar({ delay, isRunning, closeToast, type, hide, className }) {
return (
<div
{...(typeof className !== 'string'
? css(progress(type, isRunning, hide, delay), className)
: progress(type, isRunning, hide, delay))}
? css(styles(type, isRunning, hide, delay), className)
: styles(type, isRunning, hide, delay))}
{...typeof className === 'string' && { className }}
onAnimationEnd={closeToast}
/>

View File

@@ -4,39 +4,41 @@ import { css } from 'glamor';
import ProgressBar from './ProgressBar';
import { POSITION, TYPE } from './constant';
import style from './style';
import defaultStyle from './defaultStyle';
import {
falseOrElement,
falseOrDelay,
objectValues
} from './util/propValidator';
const toast = type =>
css({
position: 'relative',
minHeight: '48px',
marginBottom: '1rem',
padding: '8px',
borderRadius: '1px',
boxShadow:
'0 1px 10px 0 rgba(0, 0, 0, .1), 0 2px 15px 0 rgba(0, 0, 0, .05)',
display: 'flex',
justifyContent: 'space-between',
maxHeight: '800px',
overflow: 'hidden',
fontFamily: style.fontFamily,
cursor: 'pointer',
background: style[`color${type.charAt(0).toUpperCase()}${type.slice(1)}`],
...(type === 'default' ? { color: '#aaa' } : {}),
[`@media ${style.mobile}`]: {
marginBottom: 0
}
});
const body = css({
margin: 'auto 0',
flex: 1
});
const styles = {
container: type =>
css({
position: 'relative',
minHeight: '48px',
marginBottom: '1rem',
padding: '8px',
borderRadius: '1px',
boxShadow:
'0 1px 10px 0 rgba(0, 0, 0, .1), 0 2px 15px 0 rgba(0, 0, 0, .05)',
display: 'flex',
justifyContent: 'space-between',
maxHeight: '800px',
overflow: 'hidden',
fontFamily: defaultStyle.fontFamily,
cursor: 'pointer',
background:
defaultStyle[`color${type.charAt(0).toUpperCase()}${type.slice(1)}`],
...(type === 'default' ? { color: '#aaa' } : {}),
[`@media ${defaultStyle.mobile}`]: {
marginBottom: 0
}
}),
body: css({
margin: 'auto 0',
flex: 1
})
};
class Toast extends Component {
static propTypes = {
@@ -61,7 +63,8 @@ class Toast extends Component {
PropTypes.string,
PropTypes.object
]),
updateId: PropTypes.number
updateId: PropTypes.number,
ariaLabel: PropTypes.string
};
static defaultProps = {
@@ -73,7 +76,8 @@ class Toast extends Component {
className: '',
bodyClassName: '',
progressClassName: '',
updateId: null
updateId: null,
role: 'alert'
};
state = {
@@ -136,7 +140,8 @@ class Toast extends Component {
className,
bodyClassName,
progressClassName,
updateId
updateId,
role
} = this.props;
return (
@@ -149,14 +154,15 @@ class Toast extends Component {
>
<div
{...(typeof className !== 'string'
? css(toast(type), className)
: toast(type))}
? css(styles.container(type), className)
: styles.container(type))}
{...this.getToastProps()}
>
<div
{...this.props.in && { role: role }}
{...(typeof bodyClassName !== 'string'
? css(body, bodyClassName)
: body)}
? css(styles.body, bodyClassName)
: styles.body)}
{...typeof bodyClassName === 'string' && {
className: bodyClassName
}}

View File

@@ -7,7 +7,7 @@ import Toast from './Toast';
import DefaultCloseButton from './DefaultCloseButton';
import DefaultTransition from './DefaultTransition';
import { POSITION, ACTION } from './constant';
import style from './style';
import defaultStyle from './defaultStyle';
import EventManager from './util/EventManager';
import {
falseOrDelay,
@@ -16,50 +16,44 @@ import {
objectValues
} from './util/propValidator';
const toastPosition = pos => {
const getToastPositionStyle = pos => {
const positionKey = pos.toUpperCase().replace('-', '_');
const positionRule =
typeof POSITION[positionKey] !== 'undefined'
? style[positionKey]
: style.TOP_RIGHT;
? defaultStyle[positionKey]
: defaultStyle.TOP_RIGHT;
/** define margin for center toast based on toast witdh */
if (
positionKey.indexOf('CENTER') !== -1 &&
typeof positionRule.marginLeft === 'undefined'
) {
positionRule.marginLeft = `-${parseInt(style.width, 10) / 2}px`;
positionRule.marginLeft = `-${parseInt(defaultStyle.width, 10) / 2}px`;
}
return css(
positionRule,
css({
[`@media ${style.mobile}`]: {
left: 0,
margin: 0,
position: 'fixed',
...(pos.substring(0, 3) === 'top' ? { top: 0 } : { bottom: 0 })
}
})
);
return positionRule;
};
const container = (disablePointer, position) =>
const styles = (disablePointer, position) =>
css(
{
zIndex: style.zIndex,
zIndex: defaultStyle.zIndex,
position: 'fixed',
padding: '4px',
width: style.width,
width: defaultStyle.width,
boxSizing: 'border-box',
color: '#fff',
...(disablePointer ? { pointerEvents: 'none' } : {}),
[`@media ${style.mobile}`]: {
[`@media ${defaultStyle.mobile}`]: {
width: '100vw',
padding: 0
padding: 0,
left: 0,
margin: 0,
position: 'fixed',
...(position.substring(0, 3) === 'top' ? { top: 0 } : { bottom: 0 })
}
},
toastPosition(position)
getToastPositionStyle(position)
);
class ToastContainer extends Component {
@@ -348,8 +342,8 @@ class ToastContainer extends Component {
return (
<TransitionGroup
{...(typeof className !== 'string'
? css(container(disablePointer, position), className)
: container(disablePointer, position))}
? css(styles(disablePointer, position), className)
: styles(disablePointer, position))}
{...typeof className === 'string' && { className }}
{...style !== null && { style }}
key={`container-${position}`}

View File

@@ -1,4 +1,4 @@
const style = {
const defaultStyle = {
width: '320px',
colorDefault: '#fff',
colorInfo: '#3498db',
@@ -38,8 +38,8 @@ const style = {
export function defineStyle(props) {
for (let prop in props) {
style[prop] = props[prop];
defaultStyle[prop] = props[prop];
}
}
export default style;
export default defaultStyle;

View File

@@ -1,5 +1,5 @@
import ToastContainer from './ToastContainer';
import toaster from './toaster';
import { defineStyle } from './style';
import { defineStyle } from './defaultStyle';
export { ToastContainer, toaster as toast, defineStyle as style };

View File

@@ -66,28 +66,27 @@ const toaster = Object.assign(
dismiss: (id = null) => container && EventManager.emit(ACTION.CLEAR, id),
isActive: () => false,
update(id, options) {
if (container && typeof container.collection[id] !== 'undefined') {
const {
options: oldOptions,
content: oldContent
} = container.collection[id];
const updateId =
oldOptions.updateId !== null ? oldOptions.updateId + 1 : 1;
setTimeout(() => {
if (container && typeof container.collection[id] !== 'undefined') {
const {
options: oldOptions,
content: oldContent
} = container.collection[id];
const updateId =
oldOptions.updateId !== null ? oldOptions.updateId + 1 : 1;
const nextOptions = Object.assign({}, oldOptions, options, {
toastId: id,
updateId: updateId
});
const content =
typeof nextOptions.render !== 'undefined'
? nextOptions.render
: oldContent;
delete nextOptions.render;
return emitEvent(content, nextOptions);
}
return false;
const nextOptions = Object.assign({}, oldOptions, options, {
toastId: id,
updateId: updateId
});
const content =
typeof nextOptions.render !== 'undefined'
? nextOptions.render
: oldContent;
delete nextOptions.render;
emitEvent(content, nextOptions);
}
}, 0);
}
},
{