File size: 5,016 Bytes
6bcb42f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import stylePropType from 'react-style-proptype';
import styles from './box.css';

const getRandomColor = (function () {
    // In "DEBUG" mode this is used to output a random background color for each
    // box. The function gives the same "random" set for each seed, allowing re-
    // renders of the same content to give the same random display.
    const random = (function (seed) {
        let mW = seed;
        let mZ = 987654321;
        const mask = 0xffffffff;
        return function () {
            mZ = ((36969 * (mZ & 65535)) + (mZ >> 16)) & mask;
            mW = ((18000 * (mW & 65535)) + (mW >> 16)) & mask;
            let result = ((mZ << 16) + mW) & mask;
            result /= 4294967296;
            return result + 1;
        };
    }(601));
    return function () {
        const r = Math.max(parseInt(random() * 100, 10) % 256, 1);
        const g = Math.max(parseInt(random() * 100, 10) % 256, 1);
        const b = Math.max(parseInt(random() * 100, 10) % 256, 1);
        return `rgb(${r},${g},${b})`;
    };
}());

const Box = props => {
    const {
        alignContent,
        alignItems,
        alignSelf,
        basis,
        children,
        className,
        componentRef,
        direction,
        element,
        grow,
        height,
        justifyContent,
        width,
        wrap,
        shrink,
        style,
        ...componentProps
    } = props;
    return React.createElement(element, {
        className: classNames(className, styles.box),
        ref: componentRef,
        style: Object.assign(
            {
                alignContent: alignContent,
                alignItems: alignItems,
                alignSelf: alignSelf,
                flexBasis: basis,
                flexDirection: direction,
                flexGrow: grow,
                flexShrink: shrink,
                flexWrap: wrap,
                justifyContent: justifyContent,
                width: width,
                height: height
            },
            process.env.DEBUG ? {
                backgroundColor: getRandomColor(),
                outline: `1px solid black`
            } : {},
            style
        ),
        ...componentProps
    }, children);
};
Box.propTypes = {
    /** Defines how the browser distributes space between and around content items vertically within this box. */
    alignContent: PropTypes.oneOf([
        'flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'stretch'
    ]),
    /** Defines how the browser distributes space between and around flex items horizontally within this box. */
    alignItems: PropTypes.oneOf([
        'flex-start', 'flex-end', 'center', 'baseline', 'stretch'
    ]),
    /** Specifies how this box should be aligned inside of its container (requires the container to be flexable). */
    alignSelf: PropTypes.oneOf([
        'auto', 'flex-start', 'flex-end', 'center', 'baseline', 'stretch'
    ]),
    /** Specifies the initial length of this box */
    basis: PropTypes.oneOfType([
        PropTypes.number,
        PropTypes.oneOf(['auto'])
    ]),
    /** Specifies the the HTML nodes which will be child elements of this box. */
    children: PropTypes.node,
    /** Specifies the class name that will be set on this box */
    className: PropTypes.string,
    /**
     * A callback function whose first parameter is the underlying dom elements.
     * This call back will be executed immediately after the component is mounted or unmounted
     */
    componentRef: PropTypes.func,
    /** https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction */
    direction: PropTypes.oneOf([
        'row', 'row-reverse', 'column', 'column-reverse'
    ]),
    /** Specifies the type of HTML element of this box. Defaults to div. */
    element: PropTypes.string,
    /** Specifies the flex grow factor of a flex item. */
    grow: PropTypes.number,
    /** The height in pixels (if specified as a number) or a string if different units are required. */
    height: PropTypes.oneOfType([
        PropTypes.number,
        PropTypes.string
    ]),
    /** https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content */
    justifyContent: PropTypes.oneOf([
        'flex-start', 'flex-end', 'center', 'space-between', 'space-around'
    ]),
    /** Specifies the flex shrink factor of a flex item. */
    shrink: PropTypes.number,
    /** An object whose keys are css property names and whose values correspond the the css property. */
    style: stylePropType,
    /** The width in pixels (if specified as a number) or a string if different units are required. */
    width: PropTypes.oneOfType([
        PropTypes.number,
        PropTypes.string
    ]),
    /** How whitespace should wrap within this block. */
    wrap: PropTypes.oneOf([
        'nowrap', 'wrap', 'wrap-reverse'
    ])
};
Box.defaultProps = {
    element: 'div',
    style: {}
};
export default Box;