UNPKG

dbl-components

Version:

Framework based on bootstrap 5

148 lines (130 loc) 4 kB
import React from "react"; import PropTypes from "prop-types"; import ResizeSensor from "css-element-queries/src/ResizeSensor"; import { eventHandler } from "dbl-utils"; import Component from "../component"; import Icons from "../media/icons"; const typeClasses = PropTypes.oneOfType([ PropTypes.string, PropTypes.arrayOf(PropTypes.string), ]); export default class Container extends Component { static jsClass = "Container"; static propTypes = { ...Component.propTypes, fluid: PropTypes.bool, fullWidth: PropTypes.bool, breakpoints: PropTypes.objectOf(PropTypes.number), xsClasses: typeClasses, smClasses: typeClasses, mdClasses: typeClasses, lgClasses: typeClasses, xlClasses: typeClasses, xxlClasses: typeClasses, }; static defaultProps = { ...Component.defaultProps, fluid: true, fullWidth: false, breakpoints: { xs: 0, sm: 576, md: 768, lg: 992, xl: 1200, xxl: 1400, }, }; breakpoint = false; orientation = false; waitBreakpoint = React.createElement(Icons, { icon: "spinner", classes: "spinner", }); constructor(props) { super(props); this.onResize = this.onResize.bind(this); } get componentProps() { return { id: this.props.name, ...this.props._props, }; } updateSize() { const { fluid, fullWidth } = this.props; const containerType = !fullWidth ? fluid ? "container-fluid" : "container" : ""; const localClasses = new Set(this.state.localClasses.split(" ")); Object.keys(this.props.breakpoints).forEach((br) => localClasses.delete(br) ); [containerType, this.breakpoint, "animate"].forEach((c) => localClasses.add(c) ); this.state.localClasses = Array.from(localClasses).flat().join(" "); if (!this.addClasses(this.props[this.breakpoint + "Classes"])) { this.setState({ localClasses: this.state.localClasses, }); } } onResize(firstTime) { const resizingFunc = () => { if (!this.ref.current) return; let width, height; if (firstTime === true) ({ offsetWidth: width, offsetHeight: height } = this.ref.current); else ({ width, height } = firstTime); // TODO: no se toma en cuenta el ordenamiento de los breakpoints, ordenarlos // y buscar la manera de empatar automagicamente con sass $container-max-widths this.breakpoint = Object.keys(this.props.breakpoints) .filter((br) => width >= this.props.breakpoints[br]) .pop(); this.orientation = width >= height ? "landscape" : "portrait"; this.width = width; this.height = height; const resp = { width, height, breakpoint: this.breakpoint, orientation: this.orientation, }; if (typeof this.props.onResize === "function") { this.props.onResize(resp); } eventHandler.dispatch("resize." + this.props.name, resp); this.updateSize(); }; if (firstTime === true) { resizingFunc(); eventHandler.dispatch("ready." + this.props.name); } else { clearTimeout(this.onResizeTimeout); this.onResizeTimeout = setTimeout(resizingFunc, 200); } } componentDidMount() { if (this.ref.current) this.resizeSensor = new ResizeSensor(this.ref.current, this.onResize); this.onResize(true); } componentDidUpdate(prevProps) { if ( prevProps.fluid != this.props.fluid || prevProps.fullWidth != this.props.fullWidth ) { this.updateSize(); } } componentWillUnmount() { clearTimeout(this.onResizeTimeout); if (this.resizeSensor) this.resizeSensor.detach(); } content(children = this.props.children) { return !!this.breakpoint ? children : this.waitBreakpoint; } }