UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

76 lines (75 loc) 2.77 kB
import "../../CommonImports"; import "../../Core/core.css"; import * as React from "react"; import { EventManagement } from '../../Core/EventManagement'; import { TimerManagement } from '../../Core/TimerManagement'; import { css } from '../../Util'; const ResizeDelayMs = 100; export class ResponsiveViewport extends React.Component { constructor(props) { super(props); this._onAsyncResize = () => { this._resize(); }; this._resolveElement = (element) => { this._element = element; }; const { initialWidth } = props; this.events = new EventManagement(); this.timers = new TimerManagement(); this.state = { activeBreakpoints: initialWidth == null ? [] : this._getActiveBreakpoints(initialWidth) }; this._onAsyncResize = this.timers.throttle(this._onAsyncResize, ResizeDelayMs, { leading: false }); } componentDidMount() { this.events.addEventListener(window, "resize", this._onAsyncResize); // React to initial width this._onAsyncResize(); } componentWillUnmount() { this.events.removeAllListeners(); this.timers.dispose(); } shouldComponentUpdate(newProps, newState) { if (this.props !== newProps) { return true; } const newBreakPoints = newState.activeBreakpoints; const oldBreakPoints = this.state.activeBreakpoints; return newBreakPoints.length !== oldBreakPoints.length || newBreakPoints.some((b, idx) => b !== oldBreakPoints[idx]); } render() { const { tag = "div", className, children, onRenderContent } = this.props; const { activeBreakpoints } = this.state; const content = (onRenderContent && onRenderContent(activeBreakpoints)) || children; return React.createElement(tag, { className: css(className, ...(activeBreakpoints && activeBreakpoints.map(x => x.className))), ref: this._resolveElement }, content); } measure() { this._resize(); } _resize() { const rect = this._element.getBoundingClientRect(); const { width } = rect; this.setState({ activeBreakpoints: this._getActiveBreakpoints(width) }); } _getActiveBreakpoints(width) { const { breakPoints } = this.props; return breakPoints.filter(bp => { if (bp.minWidth >= 0 && width < bp.minWidth) { return false; } if (bp.maxWidth >= 0 && width >= bp.maxWidth) { return false; } return true; }); } }