Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Creating a Grid system based of Bootstrap

So I am just trying to learn reactjs and one of the things I was playing around with was creating a grid based layout component that is similar to bootstrap. Yes, I know it already exists, but you can't learn without trying. So I was hoping to share with you what I have and get feedback for things I should improve. Can't know what I am doing wrong unless someone tells me. lol

So the JSX looks like this.

<Grid>
    <Row md-direction="row-reverse">
        <Col sm md={4} classNames="text-center" direction="column-reverse">
            <p>Column 1.1</p>
            <p>Column 1.2</p>
            <p>Column 1.3</p>
        </Col>
        <Col sm md={4}>
            <p>Column 2</p>
        </Col>
        <Col sm md={4}>
            <p>Column 3</p>
        </Col>
    </Row>
</Grid>

Then my component look like this

import React, { Component } from 'react';

const getClassNames = (props, classnames = '') => {
    const colWidths = ['xs', 'sm', 'md', 'lg', 'xl'];
    const alignmentOptions = ['direction', 'justify', 'align'];

    // Loop through column widths
    colWidths.forEach((colWidth, index) => {
        // Verify width was set
        if (typeof props[colWidth] !== typeof undefined) {
            // If width has a numeric value display size and number
            if (typeof props[colWidth] === 'number') {
                classnames += ` col-${colWidth}-${props[colWidth]}`;

            // If width has bool value display as col-{width}
            }else{
                classnames += ` col-${colWidth}`;
            }
        }

        // Loop through Flex Alignment Options
        alignmentOptions.forEach((alignmentOption, index) => {
            // Remove {xs-} from alignment setting so it looks like {direction="row"} instead of {xs-direction}
            let alignmentSetting = `${colWidth}-${alignmentOption}`.replace(/xs-/g, '');

            // If alignment optin was set, add it to class names
            if (typeof props[alignmentSetting] !== typeof undefined) {
                classnames += ` flex-${alignmentSetting}-${props[alignmentSetting]}`
            }
        });
    });

    // Return full list of classNames || remove any {xs-} from classNames
    return `${classnames} ${props.classNames || ''}`.replace(/xs-/g, '').trim();;
}

export class Grid extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        // Allow custom tag names
        const TagName = this.props.component || 'section';

        // Get if container is fluid or boxed
        let classnames = `container`;
        if (this.props.fluid) classnames += `-fluid`;

        // Get all classnames
        classnames = getClassNames(this.props, classnames);

        // Render Container
        return (
            <TagName className={classnames}>
                {this.props.children}
            </TagName>
        );
    }
}

export class Row extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        // Allow custom tag names
        const TagName = this.props.component || 'div';

        // Get all classnames
        let classnames = getClassNames(this.props, 'row');

        // Render Row
        return (
            <TagName className={classnames}>
                {this.props.children}
            </TagName>
        );
    }
}

export class Col extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        // Allow custom tag names
        const TagName = this.props.component || 'div';

        // Get all classnames
        let classnames = getClassNames(this.props, 'col');

        // Render Column
        return (
            <TagName className={classnames}>
                {this.props.children}
            </TagName>
        );
    }
}