UNPKG

@gssfed/vital-ui-kit-react

Version:
158 lines (140 loc) 3.16 kB
/** * @flow * Copyright © 2018 Galaxy Software Services https://github.com/GSS-FED/vital-ui-kit-react * MIT license */ import * as React from 'react'; import styled from 'styled-components'; import ResizeObserver from 'resize-observer-polyfill'; import Track from '../Track'; import { stateColor } from '../utils'; const Root = styled.div` display: block; margin-bottom: 14px; `; const StatusWrapper = styled.div` display: flex; justify-content: space-between; position: absolute; top: ${props => (props.size === 'large' ? '8px' : '4px')}; border: 1px solid transparent; line-height: 2em; width: 100%; height: 100%; left: -1px; right: auto; text-align: right; `; const Status = styled.div` min-width: 10px; white-space: nowrap; color: ${props => stateColor(props, props.theme.progressBar.defaultColor)}; `; const Label = styled(Status)` font-size: 12px; `; type State = { width: number, }; type Props = { size?: 'small' | 'medium' | 'large', /** 1 - 100 precentage */ value: number, /** whether to show current value label */ showStatus?: boolean, /** text label */ textLabel?: Node, // TODO: add label align options /** state alarm */ alarm?: boolean, /** state warning */ warning?: boolean, /** state success */ success?: boolean, }; /** * @render react * @name ProgressBar * @description show the progress with percentage of current status * @example * <ProgressBar * value={60} * showStatus * textLabel="File uploading" * /> */ class ProgressBar extends React.Component<Props, State> { static defaultProps = { size: 'medium', showStatus: false, textLabel: null, alarm: false, warning: false, success: false, }; state = { width: 0, }; componentDidMount() { this.handleUpdate(); const resizeObserver = new ResizeObserver(this.handleUpdate); resizeObserver.observe(this.node); } componentWillReceiveProps(prevProps: Props, newProps: Props) { if (prevProps.value !== newProps.value) { this.getPositionFromValue(); } } getPositionFromValue = () => { this.setState({ width: Math.round( (this.props.value / 100) * this.node.offsetWidth, ), }); }; handleUpdate = () => { if (!this.node) { return; } this.getPositionFromValue(); }; node: ?HTMLElement; render() { const { alarm, warning, success, textLabel, size, value, showStatus, } = this.props; return ( <Root> {showStatus && ( <StatusWrapper size={size}> <Label alarm={alarm} warning={warning} success={success}> {textLabel && textLabel} </Label> <Status> {value} % </Status> </StatusWrapper> )} <Track alarm={alarm} warning={warning} success={success} trackRef={s => { this.node = s; }} size={size} selectionWidth={this.state.width} /> </Root> ); } } export default ProgressBar;