@retailmenot/anchor
Version:
A React UI Library by RetailMeNot
100 lines (95 loc) • 3.95 kB
JavaScript
import * as React from 'react';
import styled, { css } from '@xstyled/styled-components';
import { breakpoints, space as spaceStyles } from '@xstyled/system';
import classNames from 'classnames';
import { debugColor, generateBreakpointCSS, GridContext, } from '../utils';
import { ResponsiveContext } from '../ResponsiveProvider';
const StyledCell = styled.div `
height: 100%;
min-width: 0;
// The order in which the media queries are generated is very important, hence breakpoints() is
// called multiple times as opposed to just once with a single object.
${({ responsiveCSS }) => {
return (responsiveCSS &&
responsiveCSS.map((k) => {
return breakpoints(k);
}));
}}
${({ left }) => left && `grid-column-start: ${left}`};
${({ width }) => width && `grid-column-end: span ${width}`};
${({ top }) => top && `grid-row-start: ${top}`};
${({ height }) => height && `grid-row-end: span ${height}`};
${({ area }) => area && `grid-area: ${area}`};
${({ debug }) => debug &&
css({
backgroundColor: debugColor,
})};
`;
/* Used these flex styles rather than xstyled 'flexboxes' system prop to limit the props the user
would have to use for the same effect. May rethink this if users ask for even more flex control. */
const Box = styled('div') `
box-sizing: border-box;
${spaceStyles}
${({ align, center, middle, valign }) => {
const styles = {};
// This is to keep the API from breaking from v1.3.3 and below.
// The middle and center props should be deprecated.
const tmpValign = middle ? 'middle' : valign;
const tmpAlign = center ? 'center' : align;
if (tmpAlign || tmpValign) {
styles.display = 'flex';
if (tmpValign) {
styles.height = '100%';
}
}
switch (tmpAlign) {
case 'left':
styles.justifyContent = 'flex-start';
break;
case 'center':
styles.justifyContent = 'center';
break;
case 'right':
styles.justifyContent = 'flex-end';
break;
}
switch (tmpValign) {
case 'top':
styles.alignItems = 'flex-start';
break;
case 'middle':
styles.alignItems = 'center';
break;
case 'bottom':
styles.alignItems = 'flex-end';
break;
}
return css(styles);
}}
`;
Box.displayName = 'Box';
export class Cell extends React.PureComponent {
constructor(props, context) {
super(props, context);
// Generates css data for xstyle'd media queries in the constructor so as to only
// fire a single time and before render. Width and height have a default of 1.
const { sortedResponsiveCSS, generalSettings } = generateBreakpointCSS({
left: props.left,
height: props.height || 1,
top: props.top,
width: props.width || 1,
}, context.breakpoints);
this.state = {
generalSettings,
sortedResponsiveCSS,
};
}
render() {
const { align, center, children, className, debug, middle, valign, } = this.props;
const { generalSettings, sortedResponsiveCSS } = this.state;
return (React.createElement(GridContext.Consumer, null, ({ debug: contextDebug }) => (React.createElement(StyledCell, { className: classNames('anchor-cell', className), debug: contextDebug || debug, responsiveCSS: sortedResponsiveCSS, left: generalSettings.left || undefined, height: generalSettings.height || undefined, top: generalSettings.top || undefined, width: generalSettings.width || undefined },
React.createElement(Box, Object.assign({}, this.props, { align: align, center: center, className: "anchor-cell-box", valign: valign, middle: middle }), children)))));
}
}
Cell.contextType = ResponsiveContext;
//# sourceMappingURL=Cell.component.js.map