1 | import React from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 | import classNames from 'classnames';
|
4 | import { mapToCssModules, tagPropType, isObject } from './utils';
|
5 |
|
6 | const colWidths = ['xs', 'sm', 'md', 'lg', 'xl'];
|
7 | const stringOrNumberProp = PropTypes.oneOfType([PropTypes.number, PropTypes.string]);
|
8 |
|
9 | const columnProps = PropTypes.oneOfType([
|
10 | PropTypes.bool,
|
11 | PropTypes.number,
|
12 | PropTypes.string,
|
13 | PropTypes.shape({
|
14 | size: PropTypes.oneOfType([PropTypes.bool, PropTypes.number, PropTypes.string]),
|
15 | order: stringOrNumberProp,
|
16 | offset: stringOrNumberProp
|
17 | })
|
18 | ]);
|
19 |
|
20 | const propTypes = {
|
21 | tag: tagPropType,
|
22 | xs: columnProps,
|
23 | sm: columnProps,
|
24 | md: columnProps,
|
25 | lg: columnProps,
|
26 | xl: columnProps,
|
27 | className: PropTypes.string,
|
28 | cssModule: PropTypes.object,
|
29 | widths: PropTypes.array,
|
30 | };
|
31 |
|
32 | const defaultProps = {
|
33 | tag: 'div',
|
34 | widths: colWidths,
|
35 | };
|
36 |
|
37 | const getColumnSizeClass = (isXs, colWidth, colSize) => {
|
38 | if (colSize === true || colSize === '') {
|
39 | return isXs ? 'col' : `col-${colWidth}`;
|
40 | } else if (colSize === 'auto') {
|
41 | return isXs ? 'col-auto' : `col-${colWidth}-auto`;
|
42 | }
|
43 |
|
44 | return isXs ? `col-${colSize}` : `col-${colWidth}-${colSize}`;
|
45 | };
|
46 |
|
47 | const Col = (props) => {
|
48 | const {
|
49 | className,
|
50 | cssModule,
|
51 | widths,
|
52 | tag: Tag,
|
53 | ...attributes
|
54 | } = props;
|
55 | const colClasses = [];
|
56 |
|
57 | widths.forEach((colWidth, i) => {
|
58 | let columnProp = props[colWidth];
|
59 |
|
60 | delete attributes[colWidth];
|
61 |
|
62 | if (!columnProp && columnProp !== '') {
|
63 | return;
|
64 | }
|
65 |
|
66 | const isXs = !i;
|
67 |
|
68 | if (isObject(columnProp)) {
|
69 | const colSizeInterfix = isXs ? '-' : `-${colWidth}-`;
|
70 | const colClass = getColumnSizeClass(isXs, colWidth, columnProp.size);
|
71 |
|
72 | colClasses.push(mapToCssModules(classNames({
|
73 | [colClass]: columnProp.size || columnProp.size === '',
|
74 | [`order${colSizeInterfix}${columnProp.order}`]: columnProp.order || columnProp.order === 0,
|
75 | [`offset${colSizeInterfix}${columnProp.offset}`]: columnProp.offset || columnProp.offset === 0
|
76 | }), cssModule));
|
77 | } else {
|
78 | const colClass = getColumnSizeClass(isXs, colWidth, columnProp);
|
79 | colClasses.push(colClass);
|
80 | }
|
81 | });
|
82 |
|
83 | if (!colClasses.length) {
|
84 | colClasses.push('col');
|
85 | }
|
86 |
|
87 | const classes = mapToCssModules(classNames(
|
88 | className,
|
89 | colClasses
|
90 | ), cssModule);
|
91 |
|
92 | return (
|
93 | <Tag {...attributes} className={classes} />
|
94 | );
|
95 | };
|
96 |
|
97 | Col.propTypes = propTypes;
|
98 | Col.defaultProps = defaultProps;
|
99 |
|
100 | export default Col;
|