Unverified Commit 3f981a42 authored by Tor Raswill's avatar Tor Raswill Committed by GitHub
Browse files

#4887 Add support for setting columns in <Row> (#4900)



* Update Row.js

Extend Row with colSize prop and let it accept sizing inputs similar to <Col>

* Update RowSpec.js

Extend RowSpec test to include changes to Row

* Extend docs to include Row Columns

Extend docs to include Row Columns

* Update Row.js

Update const names, props and descriptions to better explain what they do

* Update Row.js

Re-added type object, renamed cols array to rowCols, renamed col const to cols to match cols in object

* Update Row.js

clean up per comments from @taion

* Update Row.js

Place comment for as correctly, remove rowCols and replace with classes to tidier code.

* Update Row.js

remove unneeded code

* Updated docs

Updated docs, re-wrote text

* Update src/Row.js

Co-Authored-By: default avatarJimmy Jia <tesrin@gmail.com>

* Add types to Row.d.ts

Add types for rowColumns

* Update types/components/Row.d.ts

Co-Authored-By: default avatarJimmy Jia <tesrin@gmail.com>

* Update docs

Update docs for <Row> column widths and simplify it a bit by rewording some and removing unneeded example that showed the same thing again.

Updated imports to better follow previously imported examples.

Co-authored-by: default avatarTor Raswill <tor.raswill@dqc.se>
Co-authored-by: default avatarJimmy Jia <tesrin@gmail.com>
parent d0002741
......@@ -5,6 +5,16 @@ import React from 'react';
import { useBootstrapPrefix } from './ThemeProvider';
const DEVICE_SIZES = ['xl', 'lg', 'md', 'sm', 'xs'];
const rowColWidth = PropTypes.oneOfType([PropTypes.number, PropTypes.string]);
const rowColumns = PropTypes.oneOfType([
rowColWidth,
PropTypes.shape({
cols: rowColWidth,
}),
]);
const propTypes = {
/**
* @default 'row'
......@@ -14,36 +24,93 @@ const propTypes = {
/** Removes the gutter spacing between `Col`s as well as any added negative margins. */
noGutters: PropTypes.bool.isRequired,
as: PropTypes.elementType,
/**
* The number of columns that will fit next to each other on extra small devices (<576px)
*
* @type {(number|{ cols: number })}
*/
xs: rowColumns,
/**
* The number of columns that will fit next to each other on small devices (≥576px)
*
* @type {(number|{ cols: number })}
*/
sm: rowColumns,
/**
* The number of columns that will fit next to each other on medium devices (≥768px)
*
* @type {(number|{ cols: number })}
*/
md: rowColumns,
/**
* The number of columns that will fit next to each other on large devices (≥992px)
*
* @type {(number|{ cols: number })}
*/
lg: rowColumns,
/**
* The number of columns that will fit next to each other on extra large devices (≥1200px)
*
* @type {(number|{ cols: number })}
*/
xl: rowColumns,
};
const defaultProps = {
noGutters: false,
};
const Row = React.forwardRef((props, ref) => {
const {
bsPrefix,
noGutters,
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
as: Component = 'div',
className,
...otherProps
} = props;
const decoratedBsPrefix = useBootstrapPrefix(bsPrefix, 'row');
return (
<Component
ref={ref}
{...otherProps}
className={classNames(
className,
decoratedBsPrefix,
noGutters && 'no-gutters',
)}
/>
);
});
const Row = React.forwardRef(
(
{
bsPrefix,
className,
noGutters,
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
as: Component = 'div',
...props
},
ref,
) => {
const decoratedBsPrefix = useBootstrapPrefix(bsPrefix, 'row');
const sizePrefix = `${decoratedBsPrefix}-cols`;
const classes = [];
DEVICE_SIZES.forEach(brkPoint => {
const propValue = props[brkPoint];
delete props[brkPoint];
let cols;
if (propValue != null && typeof propValue === 'object') {
({ cols } = propValue);
} else {
cols = propValue;
}
let infix = brkPoint !== 'xs' ? `-${brkPoint}` : '';
if (cols != null) classes.push(`${sizePrefix}${infix}-${cols}`);
});
return (
<Component
ref={ref}
{...props}
className={classNames(
className,
decoratedBsPrefix,
noGutters && 'no-gutters',
...classes,
)}
/>
);
},
);
Row.displayName = 'Row';
Row.propTypes = propTypes;
......
......@@ -4,6 +4,14 @@ import { mount } from 'enzyme';
import Row from '../src/Row';
describe('Row', () => {
it('Should include "row" when there are no sizes', () => {
mount(<Row />).assertSingle('.row');
});
it('Should include sizes', () => {
mount(<Row xs={4} md={8} />).assertSingle('.row-cols-md-8.row-cols-4');
});
it('uses "div" by default', () => {
mount(
<Row className="custom-class">
......
......@@ -2,8 +2,29 @@ import * as React from 'react';
import { BsPrefixComponent } from './helpers';
type RowColWidth =
| number
| '1'
| '2'
| '3'
| '4'
| '5'
| '6'
| '7'
| '8'
| '9'
| '10'
| '11'
| '12';
type RowColumns = RowColWidth | { cols?: RowColWidth };
export interface RowProps {
noGutters?: boolean;
xs?: RowColumns;
sm?: RowColumns;
md?: RowColumns;
lg?: RowColumns;
xl?: RowColumns;
}
declare class Row<
......
<Container>
<Row xs={2} md={4} lg={6}>
<Col>1 of 2</Col>
<Col>2 of 2</Col>
</Row>
<Row xs={1} md={2}>
<Col>1 of 3</Col>
<Col>2 of 3</Col>
<Col>3 of 3</Col>
</Row>
</Container>;
<Container>
<Row md={4}>
<Col>1 of 3</Col>
<Col xs={6}>2 of 3</Col>
<Col>3 of 3</Col>
</Row>
</Container>;
......@@ -9,6 +9,8 @@ import GridContainer from '../../examples/Grid/Container';
import GridContainerFluid from '../../examples/Grid/ContainerFluid';
import GridContainerFluidBreakpoint from '../../examples/Grid/ContainerFluidBreakpoint';
import GridAutoLayout from '../../examples/Grid/AutoLayout';
import GridRowColLayout from '../../examples/Grid/RowColLayout';
import GridRowColLayoutColWidthBreakpoint from '../../examples/Grid/RowColLayoutColWidthBreakpoint';
import GridAutoLayoutSizing from '../../examples/Grid/AutoLayoutSizing';
import GridAutoLayoutVariable from '../../examples/Grid/AutoLayoutVariable';
import GridOffsetting from '../../examples/Grid/Offsetting';
......@@ -174,6 +176,31 @@ export default withLayout(function GridSection({ data }) {
codeText={GridOffsetting}
exampleClassName={styles.example}
/>
<LinkedHeading h="3" id="row-layout-col-sizing">
Setting column widths in Row
</LinkedHeading>
<p>
The <code>Row</code> lets you specify column widths across 5 breakpoint
sizes (xs, sm, md, large, and xl). For every breakpoint, you can specify
the amount of columns that will fit next to each other.
</p>
<ReactPlayground
codeText={GridRowColLayout}
exampleClassName={styles.example}
/>
<p>
Note that <code>Row</code> column widths will override <code>Col</code>{' '}
widths set on lower breakpoints when viewed on larger screens. The{' '}
<code>{'<Col xs={6} />'}</code> size will be overriden by{' '}
<code>{'<Row md={4} />'}</code> on medium and larger screens.
</p>
<ReactPlayground
codeText={GridRowColLayoutColWidthBreakpoint}
exampleClassName={styles.example}
/>
<LinkedHeading h="2" id="grid-props">
API
</LinkedHeading>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment