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', 'xxl'];
|
7 | const stringOrNumberProp = PropTypes.oneOfType([
|
8 | PropTypes.number,
|
9 | PropTypes.string,
|
10 | ]);
|
11 |
|
12 | const columnProps = PropTypes.oneOfType([
|
13 | PropTypes.bool,
|
14 | PropTypes.number,
|
15 | PropTypes.string,
|
16 | PropTypes.shape({
|
17 | size: PropTypes.oneOfType([
|
18 | PropTypes.bool,
|
19 | PropTypes.number,
|
20 | PropTypes.string,
|
21 | ]),
|
22 | order: stringOrNumberProp,
|
23 | offset: stringOrNumberProp,
|
24 | }),
|
25 | ]);
|
26 |
|
27 | const propTypes = {
|
28 | tag: tagPropType,
|
29 | xs: columnProps,
|
30 | sm: columnProps,
|
31 | md: columnProps,
|
32 | lg: columnProps,
|
33 | xl: columnProps,
|
34 | xxl: columnProps,
|
35 | className: PropTypes.string,
|
36 | cssModule: PropTypes.object,
|
37 | widths: PropTypes.array,
|
38 | };
|
39 |
|
40 | const getColumnSizeClass = (isXs, colWidth, colSize) => {
|
41 | if (colSize === true || colSize === '') {
|
42 | return isXs ? 'col' : `col-${colWidth}`;
|
43 | }
|
44 | if (colSize === 'auto') {
|
45 | return isXs ? 'col-auto' : `col-${colWidth}-auto`;
|
46 | }
|
47 |
|
48 | return isXs ? `col-${colSize}` : `col-${colWidth}-${colSize}`;
|
49 | };
|
50 |
|
51 | export const getColumnClasses = (attributes, cssModule, widths = colWidths) => {
|
52 | const modifiedAttributes = attributes;
|
53 | const colClasses = [];
|
54 |
|
55 | widths.forEach((colWidth, i) => {
|
56 | let columnProp = modifiedAttributes[colWidth];
|
57 |
|
58 | delete modifiedAttributes[colWidth];
|
59 |
|
60 | if (!columnProp && columnProp !== '') {
|
61 | return;
|
62 | }
|
63 |
|
64 | const isXs = !i;
|
65 |
|
66 | if (isObject(columnProp)) {
|
67 | const colSizeInterfix = isXs ? '-' : `-${colWidth}-`;
|
68 | const colClass = getColumnSizeClass(isXs, colWidth, columnProp.size);
|
69 |
|
70 | colClasses.push(
|
71 | mapToCssModules(
|
72 | classNames({
|
73 | [colClass]: columnProp.size || columnProp.size === '',
|
74 | [`order${colSizeInterfix}${columnProp.order}`]:
|
75 | columnProp.order || columnProp.order === 0,
|
76 | [`offset${colSizeInterfix}${columnProp.offset}`]:
|
77 | columnProp.offset || columnProp.offset === 0,
|
78 | }),
|
79 | cssModule,
|
80 | ),
|
81 | );
|
82 | } else {
|
83 | const colClass = getColumnSizeClass(isXs, colWidth, columnProp);
|
84 | colClasses.push(colClass);
|
85 | }
|
86 | });
|
87 |
|
88 | return {
|
89 | colClasses,
|
90 | modifiedAttributes,
|
91 | };
|
92 | };
|
93 |
|
94 | function Col(props) {
|
95 | const {
|
96 | className,
|
97 | cssModule,
|
98 | widths = colWidths,
|
99 | tag: Tag = 'div',
|
100 | ...attributes
|
101 | } = props;
|
102 |
|
103 | let { modifiedAttributes, colClasses } = getColumnClasses(
|
104 | attributes,
|
105 | cssModule,
|
106 | widths,
|
107 | );
|
108 |
|
109 | if (!colClasses.length) {
|
110 | colClasses.push('col');
|
111 | }
|
112 |
|
113 | const classes = mapToCssModules(classNames(className, colClasses), cssModule);
|
114 |
|
115 | return <Tag {...modifiedAttributes} className={classes} />;
|
116 | }
|
117 |
|
118 | Col.propTypes = propTypes;
|
119 |
|
120 | export default Col;
|
121 |
|
\ | No newline at end of file |