nexxtway/react-rainbow

View on GitHub
library/pages/CustomizationPage/index.js

Summary

Maintainability
F
4 days
Test Coverage
/* eslint-disable react/no-unescaped-entities, import/no-extraneous-dependencies */
import React, { useState, useContext, useRef } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faList } from '@fortawesome/free-solid-svg-icons';
import styled, { ThemeContext } from 'styled-components';
import Tabset from '../../../src/components/Tabset';
import Tab from '../../../src/components/Tab';
import Table from '../../../src/components/Table';
import Column from '../../../src/components/Column';
import Badge from '../../../src/components/Badge';
import RenderIf from '../../../src/components/RenderIf';
import CodeEditor from '../components/CodeEditor';
import CarbonAds from '../components/CarbonAds';
import Playground from 'rsg-components/Playground';
import {
    COLOR_WHITE,
    COLOR_GRAY_1,
    COLOR_BRAND,
    COLOR_SUCCESS,
    COLOR_ERROR,
    COLOR_WARNING,
    COLOR_DARK_1,
} from '../../../src/styles/colors';
import './styles.css';

const defaultTheme = `const theme = {
    rainbow: {
        palette: { 
            brand: {
                main: String,
                dark: String,
                light: String,
            },
            success: {
                main: String,
                dark: String,
                light: String,
            },
            error: {
                main: String,
                dark: String,
                light: String,
            },
            warning: {
                main: String,
            },
            background: {
                main: String,
                highlight: String,
                secondary: String,
                disabled: String,
            },
            text: {
                main: String,
                title: String,
                header: String,
                label: String,
                disabled: String,
            },
            border: {
                main: String,
                divider: String,
                disabled: String,
            },
            action: {
                active: String,
                hover: String,
            },
        },
        shadows: {
            brand: String,
            success: String,
            error: String,
            shadow_1: String,
            shadow_2: String,
            shadow_3: String,
            shadow_4: String,
            shadow_5: String,
            shadow_6: String,
            shadow_7: String,
            shadow_8: String,
            shadow_9: String,
            shadow_10: String,
        },
    },
};
`;

const data = [
    {
        name: 'brand',
        type: 'string',
        required: '',
        default: COLOR_BRAND,
        description: 'Represent the predominant color of your brand.',
    },
    {
        name: 'error',
        type: 'string',
        required: '',
        default: COLOR_ERROR,
        description: 'Represent interface elements that the user should be made aware of.',
    },
    {
        name: 'warning',
        type: 'string',
        required: '',
        default: COLOR_WARNING,
        description: 'Represent potentially dangerous actions or important messages.',
    },
    {
        name: 'success',
        type: 'string',
        required: '',
        default: COLOR_SUCCESS,
        description: 'Indicate the successful completion of an action that user triggered.',
    },
    {
        name: 'mainBackground',
        type: 'string',
        required: '',
        default: COLOR_WHITE,
        description: 'Used to represent primary interface elements for an app.',
    },
];

const StyledPanel = styled.div`
    border: 1px solid ${props => props.theme.rainbow.palette.border.divider};
    border-radius: 14px;
    padding-bottom: 12px;
`;

const StyledDefaultBadge = styled(Badge)`
    ${props => {
        const contrastColor = props.theme.rainbow.palette.getContrastText(props.color);
        return `
            color: ${contrastColor};
            background-color: ${props.color};
            border-color: ${props.theme.rainbow.palette.border.divider};
        `;
    }}
`;

const DefaultBadge = ({ value }) => (
    <StyledDefaultBadge label={value} variant="brand" color={value} />
);

const StyledBadge = styled.span`
    color: ${COLOR_DARK_1};
    background-color: ${COLOR_GRAY_1};
    border: 1px solid ${COLOR_GRAY_1};
    padding: 0.1rem 0.25rem 0.1rem 0.25rem;
    margin: 0 0.15rem;
    border-radius: 4px;
    font-family: Consolas, 'Liberation Mono', Menlo, monospace;
    font-size: 14px;
`;

const StyledTable = styled(Table)`
    font-family: Consolas, 'Liberation Mono', Menlo, monospace;
    font-size: 12px;
`;
const scrollTo = elem => window.scrollTo(0, elem.current.offsetTop - 70);

export default function CustomizationPage(props) {
    const { examples, name, exampleMode, codeRevision } = props;
    const [activeTab, setActiveTab] = useState('overview');
    const example5Ref = useRef();
    const example7Ref = useRef();
    const example9Ref = useRef();
    const theme = useContext(ThemeContext);

    return (
        <div className="react-rainbow-customization_top-container">
            <Tabset
                className="react-rainbow-customization_top-container-tabset"
                activeTabName={activeTab}
                onSelect={(e, tapName) => setActiveTab(tapName)}
            >
                <Tab
                    name="overview"
                    label="OVERVIEW"
                    className="react-rainbow-customization_top-container-tab"
                />
                <Tab
                    name="qa"
                    label="Q&A"
                    className="react-rainbow-customization_top-container-tab"
                />
            </Tabset>
            <section className="react-rainbow-customization_container">
                <RenderIf isTrue={activeTab === 'overview'}>
                    <div>
                        <div className="rainbow-flex rainbow-flex_column rainbow-m-bottom_large">
                            <div className="react-rainbow-customization_section-heading-container">
                                <h3 className="react-rainbow-getting-started_section-heading rainbow-m-right_medium">
                                    If you are using React Rainbow on your app, sometimes you may
                                    need to customize the default styles to satisfy your UI/UX based
                                    on business or brand requirements. Either you will need to use
                                    the color of a specific business brand or a specific color
                                    palette or you will need additional support for a dark or custom
                                    theme on your app.
                                </h3>
                                <CarbonAds className="react-rainbow-customization_carbon-ad" />
                            </div>
                        </div>
                        <h2 className="react-rainbow-customization_section-heading-2">
                            How can you customize React Rainbow Components?
                        </h2>
                        <h3 className="react-rainbow-customization_section-text">
                            Customization is allowed by using our{' '}
                            <StyledBadge>{'<Application />'}</StyledBadge> component as a wrapper of
                            your entire application, the component property theme will accept an
                            object where you can specify your palette of colors.
                        </h3>

                        <br />

                        <h3 className="react-rainbow-customization_section-heading">Example</h3>
                        <Playground
                            code={examples[1].content}
                            evalInContext={examples[1].evalInContext}
                            key={`${codeRevision}/1`}
                            name={name}
                            index={1}
                            settings={examples[1].settings}
                            exampleMode={exampleMode}
                        />

                        <br />
                        <div className="rainbow-flex rainbow-align_end">
                            <h2 className="react-rainbow-customization_section-heading-2">
                                Theme API
                            </h2>
                            <Badge
                                className="rainbow-m-left_small rainbow-m-bottom_medium"
                                label="BETA"
                            />
                        </div>
                        <h3 className="react-rainbow-customization_section-heading">Palette</h3>
                        <h3 className="react-rainbow-customization_section-text">
                            The palette enables you to modify the color of the components.
                        </h3>

                        <br />

                        <StyledPanel>
                            <h3 className="react-rainbow-customization_section-text rainbow-m-vertical_medium rainbow-m-horizontal_small">
                                <FontAwesomeIcon
                                    className="rainbow-m-right_small"
                                    icon={faList}
                                    color={theme.rainbow.palette.brand.main}
                                />{' '}
                                Props
                            </h3>
                            <StyledTable data={data} keyField="name" resizeColumnDisabled>
                                <Column header="Prop Name" field="name" defaultWidth={160} />
                                <Column header="Type" field="type" defaultWidth={80} />
                                <Column header="Required" field="required" defaultWidth={120} />
                                <Column
                                    header="Default"
                                    field="default"
                                    defaultWidth={130}
                                    component={DefaultBadge}
                                />
                                <Column header="Description" field="description" />
                            </StyledTable>
                        </StyledPanel>

                        <br />

                        <div className="rainbow-flex rainbow-align_end">
                            <h2 className="react-rainbow-customization_section-heading-2">
                                Theme generate API
                            </h2>
                            <Badge
                                className="rainbow-m-left_small rainbow-m-bottom_medium"
                                label="BETA"
                            />
                        </div>
                        <h3 className="react-rainbow-customization_section-text">
                            You might wonder how all the components colors are being set based on
                            five colors
                            <StyledBadge>brand</StyledBadge> <StyledBadge>success</StyledBadge>{' '}
                            <StyledBadge>warning</StyledBadge> <StyledBadge>error</StyledBadge> and{' '}
                            <StyledBadge>mainBackground</StyledBadge>
                        </h3>
                        <h3 className="react-rainbow-customization_section-text rainbow-m-bottom_medium">
                            Well, we do compute the rest of the color we use in our internal
                            implementation based on accessibility standards and also we expose those
                            generated values to you through the react context because you might want
                            to make use of those values in order to be consistent with the colors of
                            your app.
                        </h3>
                        <CodeEditor code={defaultTheme} />

                        <h3 className="react-rainbow-customization_section-heading">Example</h3>

                        <Playground
                            code={examples[3].content}
                            evalInContext={examples[3].evalInContext}
                            key={`${codeRevision}/3`}
                            name={name}
                            index={3}
                            settings={examples[3].settings}
                            exampleMode="collapse"
                        />
                    </div>
                </RenderIf>
                <RenderIf isTrue={activeTab === 'qa'}>
                    <div className="rainbow-flex rainbow-flex_column">
                        <div className="react-rainbow-customization_section-heading-container">
                            <div className="rainbow-m-right_medium">
                                <h3 className="react-rainbow-getting-started_section-heading rainbow-m-right_medium rainbow-m-bottom_medium">
                                    Here are the frequent questions and answers about how to
                                    implement the theme on React Rainbow and that you should look up
                                    before you ask in the community or create a new issue.
                                </h3>
                                <h2 className="react-rainbow-getting-started_section-heading-2">
                                    Q&A
                                </h2>
                            </div>
                            <CarbonAds className="react-rainbow-customization_carbon-ad" />
                        </div>
                        <div>
                            <a
                                className="react-rainbow-customization_link"
                                onClick={() => scrollTo(example5Ref)}
                            >
                                How customize the main color for all the components on my app?
                            </a>
                            <a
                                className="react-rainbow-customization_link"
                                onClick={() => scrollTo(example7Ref)}
                            >
                                How to do a variation with a specific color for only one component
                                on my app?
                            </a>
                            <a
                                className="react-rainbow-customization_link"
                                onClick={() => scrollTo(example9Ref)}
                            >
                                How use the colors defined on the theme on my own elements of my
                                app?
                            </a>
                        </div>
                        <section ref={example5Ref}>
                            <h3 className="react-rainbow-customization_section-heading">
                                How customize the main color for all the components on my app?
                            </h3>
                            <Playground
                                code={examples[5].content}
                                evalInContext={examples[5].evalInContext}
                                key={`${codeRevision}/5`}
                                name={name}
                                index={5}
                                settings={examples[5].settings}
                                exampleMode="collapse"
                            />
                        </section>
                        <section ref={example7Ref}>
                            <h3 className="react-rainbow-customization_section-heading">
                                How to do a variation with a specific color for only one component
                                on my app?
                            </h3>
                            <Playground
                                code={examples[7].content}
                                evalInContext={examples[7].evalInContext}
                                key={`${codeRevision}/7`}
                                name={name}
                                index={7}
                                settings={examples[7].settings}
                                exampleMode="collapse"
                            />
                        </section>
                        <section ref={example9Ref}>
                            <h3 className="react-rainbow-customization_section-heading">
                                How use the colors defined on the theme on my own elements of my
                                app?
                            </h3>
                            <Playground
                                code={examples[9].content}
                                evalInContext={examples[9].evalInContext}
                                key={`${codeRevision}/9`}
                                name={name}
                                index={9}
                                settings={examples[9].settings}
                                exampleMode="collapse"
                            />
                        </section>
                    </div>
                </RenderIf>
            </section>
        </div>
    );
}

CustomizationPage.propTypes = {
    examples: PropTypes.array.isRequired,
    name: PropTypes.string.isRequired,
    exampleMode: PropTypes.string.isRequired,
    codeRevision: PropTypes.number.isRequired,
};

CustomizationPage.defaultProps = {
    examples: null,
    name: undefined,
    exampleMode: undefined,
    codeRevision: undefined,
};