vcc-ui
Version:
VCC UI is a collection of React UI Components that can be used for developing front-end applications at Volvo Car Corporation.
111 lines (95 loc) • 2.79 kB
JavaScript
import React, { createContext, useContext } from 'react';
import { useFela } from 'react-fela';
import { Flex } from '../flex';
import PropTypes from 'prop-types';
const ColContext = createContext();
const styles = {
column: ({ theme, sizes: { default: defaultSize, ...otherSizes } }) => ({
boxSizing: 'border-box',
flexBasis: `${(defaultSize / 4) * 100}%`,
maxWidth: `${(defaultSize / 4) * 100}%`,
paddingLeft: theme.baselineGrid,
paddingRight: theme.baselineGrid,
[theme.breakpoints.fromL]: {
flexBasis: `${(defaultSize / 12) * 100}%`,
maxWidth: `${(defaultSize / 12) * 100}%`,
paddingLeft: theme.baselineGrid * 1.5,
paddingRight: theme.baselineGrid * 1.5,
},
extend: [
{
condition: otherSizes[theme.breakpoints.fromM],
style: {
// We use onlyM here so that breakpoint orders don't need to be defined by the user
[theme.breakpoints.onlyM]: {
flexBasis: `${(otherSizes[theme.breakpoints.fromM] / 4) * 100}%`,
maxWidth: `${(otherSizes[theme.breakpoints.fromM] / 4) * 100}%`,
},
},
},
{
condition: otherSizes[theme.breakpoints.fromL],
style: {
[theme.breakpoints.fromL]: {
flexBasis: `${(otherSizes[theme.breakpoints.fromL] / 12) * 100}%`,
maxWidth: `${(otherSizes[theme.breakpoints.fromL] / 12) * 100}%`,
},
},
},
],
}),
};
function getSizes(size, theme) {
if (typeof size === 'number') {
return {
default: 4,
[theme.breakpoints.fromL]: size,
};
}
return {
default: 4,
...size,
};
}
function getRealSizes(size, contextSize, theme) {
const sizes = getSizes(size, theme);
if (!contextSize) {
return sizes;
}
const availableSizes = getSizes(contextSize, theme);
const realSizes = {};
for (let key in sizes) {
if (availableSizes[key]) {
if (key === theme.breakpoints.fromL) {
realSizes[key] = (12 / availableSizes[key]) * sizes[key];
} else {
realSizes[key] = (4 / availableSizes[key]) * sizes[key];
}
} else {
realSizes[key] = sizes[key];
}
}
return realSizes;
}
export function Col({
size = { default: 4, '@media (min-width: 1024px)': 12 },
children,
}) {
const { theme } = useFela();
const contextSize = useContext(ColContext);
const styleProps = {
sizes: getRealSizes(size, contextSize, theme),
theme,
};
return (
<ColContext.Provider value={size}>
<Flex extend={styles.column(styleProps)}>{children}</Flex>
</ColContext.Provider>
);
}
Col.propTypes = {
/** Size of column */
size: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
/** A JSX node */
children: PropTypes.node,
};