Commit 2cdb86fd by Vladislav Lagunov

Добавлены компоненты из @bitmaster/components

parent c7b12244
import * as React from 'react';
import * as classNames from 'classnames';
import { lighten } from '@material-ui/core/styles/colorManipulator';
// @ts-ignore
import withStyles, { WithStyles, StyleRules, StyledComponentProps } from '@material-ui/core/styles/withStyles';
import { Theme } from '@material-ui/core/styles/createMuiTheme';
/** aliass */
export type Duration = number;
// props
export interface Props {
className?: string;
duration: Duration;
startAnimation?: boolean;
onPassRewinder: Function;
}
// Component
class CircleTimer extends React.Component<Props & WithStyles<ClassKey>> {
spinner: HTMLDivElement | null = null;
filler: HTMLDivElement | null = null;
mask: HTMLDivElement | null = null;
public static getStyles(duration: Duration) {
const spinnerAnimation = `rota ${duration}ms linear 1`;
const fillerAnimation = `opa ${duration}ms steps(1,end) 1 reverse`;
const maskAnimation = `opa ${duration}ms steps(1,end) 1`;
return {
spinner: {
MozAnimation: spinnerAnimation,
WebkitAnimation: spinnerAnimation,
OebkitAnimation: spinnerAnimation,
animation: spinnerAnimation,
},
filler: {
MozAnimation: fillerAnimation,
WebkitAnimation: fillerAnimation,
OAnimation: fillerAnimation,
animation: fillerAnimation,
},
mask: {
MozAnimation: maskAnimation,
WebkitAnimation: maskAnimation,
OAnimation: maskAnimation,
animation: maskAnimation,
},
};
}
componentDidMount() {
this.props.onPassRewinder && this.props.onPassRewinder(this.rewind);
}
componentWillUnmount() {
this.props.onPassRewinder && this.props.onPassRewinder(null);
}
rewind = () => { // TODO: нужно править!!!
const { spinner, filler, mask } = this;
if (spinner === null || filler === null || mask === null) return;
const elements = [ spinner, filler, mask ];
const currentAnimations = elements.map(e => e.style.animation);
elements.forEach(e => { e.style['MozAnimation'] = e.style['WebkitAnimation'] = e.style.animation = 'none'});
elements.forEach(e => e.offsetWidth); // хак https://css-tricks.com/restart-css-animation/
elements.forEach((e, i) => { e.style['MozAnimation'] = e.style['WebkitAnimation'] = e.style.animation = currentAnimations[i]});
};
render() {
const { duration, classes, className, ...other } = this.props;
const rootClass = classNames(classes.root, className);
const styles = CircleTimer.getStyles(this.props.duration || 1000);
return <div {...other} className={rootClass}>
<div className={classes.spinner} style={styles.spinner} ref={e => this.spinner = e}></div>
<div className={classes.filler} style={styles.filler} ref={e => this.filler = e}></div>
<div className={classes.mask} style={styles.mask} ref={e => this.mask = e}></div>
</div>;
}
}
export default withStyles(styles)(CircleTimer);
// CSS классы
export type ClassKey = 'root'|'spinner'|'filler'|'mask'|'rotaClass'|'opaClass'|'@keyframes rota'|'@keyframes opa';
// Styles
export function styles(theme: Theme): StyleRules<ClassKey> {
// const duration = '1s';
const size = '1.5em';
const pie = {
width: '50%',
height: '100%',
transformOrigin: '100% 50%',
position: 'absolute' as 'absolute',
background: lighten('#000', 0.7),
};
return {
root: {
position: 'relative',
display: 'inline-block',
background: 'white',
width: size,
height: size,
boxSizing: 'border-box',
'& *': {
boxSizing: 'border-box',
},
},
spinner: {
...pie,
borderRadius: '100% 0 0 100% / 50% 0 0 50%',
zIndex: 200,
borderRight: 'none',
},
filler: {
...pie,
borderRadius: '0 100% 100% 0 / 0 50% 50% 0',
left: '50%',
opacity: 0,
zIndex: 100,
borderLeft: 'none',
},
mask: {
width: '50%',
height: '100%',
position: 'absolute',
background: 'inherit',
opacity: 1,
zIndex: 300,
},
rotaClass: {
animation: 'rota 100ms linear infinite',
},
opaClass: {
animation: 'opa 100ms linear infinite',
},
'@keyframes rota': {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
'@keyframes opa': {
'0%': { opacity: 1 },
'50%': { opacity: 0 },
'100%': { opacity: 0 },
},
};
}
export * from './CircleTimer';
export { default } from './CircleTimer';
import * as React from 'react';
import * as classNames from 'classnames';
import { fade } from '@material-ui/core/styles/colorManipulator';
import CircularProgress from '@material-ui/core/CircularProgress';
import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles';
import { StandardProps } from '@material-ui/core';
import { Theme } from '@material-ui/core/styles/createMuiTheme';
// Props
export type Props = StandardProps<React.HTMLProps<HTMLDivElement>, ClassKey> & {
pending: boolean;
}
// Component
function PendingOverlay(props: Props & WithStyles<ClassKey>) {
const { classes, className, ...rest } = props;
const rootClass = classNames(classes.root, className, { [classes.pending]: props.pending });
// @ts-ignore
return <div {...rest} className={rootClass}>{props.pending && <CircularProgress/>}</div>;
}
export default withStyles(styles)(PendingOverlay);
// CSS классы
export type ClassKey = 'root'|'pending';
// Styles
export function styles(theme: Theme): StyleRules<ClassKey> {
return {
root: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background: fade(theme.palette.background.paper, 0.57),
zIndex: 1000,
visibility: 'hidden',
'&$pending': {
visibility: 'visible',
},
},
pending: {},
};
}
export * from './PendingOverlay';
export { default } from './PendingOverlay';
import * as React from 'react';
import * as classNames from 'classnames';
import { CircularProgress } from '@material-ui/core';
import withStyles, { WithStyles, StyleRules } from '@material-ui/core/styles/withStyles';
import { Theme } from '@material-ui/core/styles/createMuiTheme';
// Props
export interface Props {
className?: string;
}
// Component
export function Spinner(props: Props & WithStyles<ClassKey>) {
const { classes, className } = props;
const rootClass = classNames(classes.root, className);
return <div className={rootClass}>
<div className={classes.wrapper}>
<CircularProgress size={32} color="secondary"/>
<h2 className={classes.title}>Please, wait…</h2>
</div>
</div>;
}
export default withStyles(styles)(Spinner);
// CSS классы
export type ClassKey = 'root'|'title'|'wrapper';
// Styles
export function styles(theme: Theme): StyleRules {
return {
root: {
display: 'block',
position: 'absolute',
width: '100%',
height: '100%',
},
title: {
...theme.typography.title,
},
wrapper: {
width: '100%',
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
textAlign: 'center',
},
};
}
export * from './Spinner';
export { default } from './Spinner';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment