Skip to content

Commit

Permalink
Add social links to Footer and other extra props to components
Browse files Browse the repository at this point in the history
  • Loading branch information
moroshko committed Feb 4, 2020
1 parent c47d2ea commit e1f3d26
Show file tree
Hide file tree
Showing 40 changed files with 1,039 additions and 405 deletions.
33 changes: 22 additions & 11 deletions src/components/Button.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from "react";
import PropTypes from "prop-types";
import useTheme from "../hooks/useTheme";
import useContainer from "../hooks/useContainer";
import { responsiveMargin } from "../utils/css";
import { responsiveMarginType } from "../hooks/useResponsiveProp";
import useBackground from "../hooks/useBackground";
import useResponsivePropsCSS from "../hooks/useResponsivePropsCSS";
import { responsiveMarginType } from "../hooks/useResponsiveProp";
import { responsiveMargin } from "../utils/css";
import { mergeProps } from "../utils/component";

const VARIANTS = ["primary", "secondary", "icon"];
const COLORS = ["highlight.blue.t100", "white"];
Expand All @@ -23,10 +24,24 @@ Button.COLORS = COLORS;
Button.TYPES = TYPES;
Button.DEFAULT_PROPS = DEFAULT_PROPS;

function Button(_props) {
const props = { ...DEFAULT_PROPS, ..._props };
function Button(props) {
const theme = useTheme();
const { background } = useBackground();
const inheritedColor =
background === "primary.blue.t100" ? "white" : "highlight.blue.t100";
const inheritedProps = {
color: inheritedColor
};
const mergedProps = mergeProps(props, DEFAULT_PROPS, inheritedProps, {
variant: variant => VARIANTS.includes(variant),
color: color => COLORS.includes(color),
isFullWidth: isFullWidth => typeof isFullWidth === "boolean",
isDisabled: isDisabled => typeof isDisabled === "boolean",
type: type => TYPES.includes(type)
});
const {
variant,
color,
isFullWidth,
isDisabled,
type,
Expand All @@ -36,14 +51,10 @@ function Button(_props) {
__internal__keyboardFocus,
__internal__hover,
__internal__active
} = props;
const theme = useTheme();
const { buttonColor } = useContainer();
const responsivePropsCSS = useResponsivePropsCSS(props, DEFAULT_PROPS, {
} = mergedProps;
const responsivePropsCSS = useResponsivePropsCSS(mergedProps, DEFAULT_PROPS, {
margin: responsiveMargin
});
const color =
!COLORS.includes(_props.color) && buttonColor ? buttonColor : props.color;
const colorStr = color === DEFAULT_PROPS.color ? "default" : color;
const css = {
...theme.button,
Expand Down
27 changes: 17 additions & 10 deletions src/components/Checkbox.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import nanoid from "nanoid";
import Field from "./internal/Field";
import VisuallyHidden from "./VisuallyHidden";
import useContainer from "../hooks/useContainer";
import useTheme from "../hooks/useTheme";
import useBackground from "../hooks/useBackground";
import useValidation from "../hooks/useValidation";
import { mergeProps } from "../utils/component";
import Field from "./internal/Field";
import VisuallyHidden from "./VisuallyHidden";

const COLORS = ["grey.t05", "white"];

Expand Down Expand Up @@ -69,10 +70,19 @@ CheckboxIcon.propTypes = {
isChecked: PropTypes.bool.isRequired
};

function Checkbox(_props) {
const props = { ...DEFAULT_PROPS, ..._props };
function Checkbox(props) {
const { inputColor } = useBackground();
const inheritedProps = {
color: inputColor
};
const mergedProps = mergeProps(props, DEFAULT_PROPS, inheritedProps, {
color: color => COLORS.includes(color),
isOptional: isOptional => typeof isOptional === "boolean",
isDisabled: isDisabled => typeof isDisabled === "boolean"
});
const {
label,
color,
isOptional,
helpText,
isDisabled,
Expand All @@ -81,18 +91,15 @@ function Checkbox(_props) {
children,
testId,
__internal__keyboardFocus
} = props;
} = mergedProps;
const theme = useTheme();
const { inputColor } = useContainer();
const color =
!COLORS.includes(_props.color) && inputColor ? inputColor : props.color;
const [labelId] = useState(() => `radio-group-label-${nanoid()}`);
const [inputId] = useState(() => `checkbox-${nanoid()}`);
const [auxId] = useState(() => `checkbox-aux-${nanoid()}`);
const [isTouched, setIsTouched] = useState(false);
const { value: isChecked, errors } = data;
const validate = useValidation({
props,
props: mergedProps,
extraData: {
isTouched
}
Expand Down
52 changes: 35 additions & 17 deletions src/components/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from "react";
import PropTypes from "prop-types";
import Text from "./Text";
import useTheme from "../hooks/useTheme";
import { ContainerProvider } from "../hooks/useContainer";
import { TextStyleProvider } from "../hooks/useTextStyle";
import { BackgroundProvider } from "../hooks/useBackground";
import {
responsiveMarginType,
responsivePaddingType,
Expand Down Expand Up @@ -42,7 +43,14 @@ Container.DEFAULT_PROPS = DEFAULT_PROPS;

function Container(_props) {
const props = { ...DEFAULT_PROPS, ..._props };
const { bg, boxShadow, hasBreakpointWidth, children, testId } = props;
const {
bg,
boxShadow,
hasBreakpointWidth,
textStyle,
children,
testId
} = props;
const theme = useTheme();
const responsivePropsCSS = useResponsivePropsCSS(props, DEFAULT_PROPS, {
margin: responsiveMargin,
Expand Down Expand Up @@ -88,22 +96,31 @@ function Container(_props) {
: {
boxShadow: tokens.shadows[boxShadow] || null
};

return (
<ContainerProvider value={{ bg }}>
<div
css={{
boxSizing: "border-box",
backgroundColor: theme.getColor(bg),
...responsiveCSS,
...boxShadowCSS
}}
data-testid={testId}
>
{children}
</div>
</ContainerProvider>
let container = (
<div
css={{
boxSizing: "border-box",
backgroundColor: theme.getColor(bg),
...responsiveCSS,
...boxShadowCSS
}}
data-testid={testId}
>
{children}
</div>
);

if (textStyle) {
container = (
<TextStyleProvider value={textStyle}>{container}</TextStyleProvider>
);
}

if (bg) {
container = <BackgroundProvider value={bg}>{container}</BackgroundProvider>;
}

return container;
}

Container.propTypes = {
Expand All @@ -127,6 +144,7 @@ Container.propTypes = {
...responsivePaddingType,
...responsiveWidthType,
...responsiveHeightType,
...responsivePropType("textStyle", PropTypes.oneOf(Text.TEXT_STYLES)),
...responsivePropType("textAlign", PropTypes.oneOf(Text.ALIGNS)),
hasBreakpointWidth: PropTypes.bool,
children: PropTypes.node,
Expand Down
29 changes: 29 additions & 0 deletions src/components/Container.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { render } from "../utils/test";
import "@testing-library/jest-dom/extend-expect";
import Container from "./Container";
import Text from "./Text";

describe("Container", () => {
it("no props", () => {
Expand Down Expand Up @@ -53,6 +54,34 @@ describe("Container", () => {
`);
});

it("with textStyle parent", () => {
const { getByText } = render(
<Container textStyle="legal">
<Text>Hello World</Text>
</Container>
);
const text = getByText("Hello World");

expect(text).toHaveStyle(`
font-size: 14px;
`);
});

it("with textStyle grandparent", () => {
const { getByText } = render(
<Container textStyle="hero">
<Container>
<Text>Hello World</Text>
</Container>
</Container>
);
const text = getByText("Hello World");

expect(text).toHaveStyle(`
font-size: 104px;
`);
});

it("with textAlign", () => {
const { getByText } = render(
<Container textAlign="right">Hello World</Container>
Expand Down
27 changes: 17 additions & 10 deletions src/components/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import {
format as formatDate
} from "date-fns";
import nanoid from "nanoid";
import useBackground from "../hooks/useBackground";
import useValidation from "../hooks/useValidation";
import { mergeProps } from "../utils/component";
import Field from "./internal/Field";
import useContainer from "../hooks/useContainer";
import Grid from "./Grid";
import Input from "./Input";
import useValidation from "../hooks/useValidation";
import Grid from "./Grid";

const COLORS = ["grey.t05", "white"];

Expand Down Expand Up @@ -118,20 +119,26 @@ function getHelpText(day, month, year, defaultHelpText) {
return formatDate(new Date(yearInt, monthInt - 1, dayInt), "d MMMM, yyyy");
}

function DatePicker(_props) {
const props = { ...DEFAULT_PROPS, ..._props };
function DatePicker(props) {
const { inputColor } = useBackground();
const inheritedProps = {
color: inputColor
};
const mergedProps = mergeProps(props, DEFAULT_PROPS, inheritedProps, {
color: color => COLORS.includes(color),
isOptional: isOptional => typeof isOptional === "boolean",
isDisabled: isDisabled => typeof isDisabled === "boolean"
});
const {
color,
label,
isOptional,
helpText: helpTextProp,
isDisabled,
data,
onChange,
testId
} = props;
const { inputColor } = useContainer();
const color =
!COLORS.includes(_props.color) && inputColor ? inputColor : props.color;
} = mergedProps;
const [labelId] = useState(() => `date-picker-${nanoid()}`);
const [auxId] = useState(() => `date-picker-aux-${nanoid()}`);
const [isTouched, setIsTouched] = useState({
Expand All @@ -145,7 +152,7 @@ function DatePicker(_props) {
[value.day, value.month, value.year, helpTextProp]
);
const validate = useValidation({
props,
props: mergedProps,
extraData: {
isTouched
}
Expand Down
50 changes: 36 additions & 14 deletions src/components/Flex.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import React from "react";
import PropTypes from "prop-types";
import useResponsivePropsCSS from "../hooks/useResponsivePropsCSS";
import {
responsiveMarginType,
responsiveWidthType,
responsiveHeightType,
responsivePropType
} from "../hooks/useResponsiveProp";
import {
responsiveMargin,
responsiveWidth,
responsiveHeight,
responsiveFlexDirection,
responsiveFlexGutter,
Expand Down Expand Up @@ -39,6 +43,7 @@ const PLACE_ITEMS = [

const DEFAULT_PROPS = {
direction: "row",
wrap: false,
placeItems: "top left"
};

Expand All @@ -48,44 +53,61 @@ Flex.DEFAULT_PROPS = DEFAULT_PROPS;

function Flex(_props) {
const props = { ...DEFAULT_PROPS, ..._props };
const { children, testId } = props;
const { wrap, children, testId } = props;
const childrenArray = React.Children.toArray(children);
const wrapperCSS = useResponsivePropsCSS(props, DEFAULT_PROPS, {
margin: responsiveMargin,
width: responsiveWidth,
height: responsiveHeight
});
const flexCSS = useResponsivePropsCSS(props, DEFAULT_PROPS, {
height: responsiveHeight,
gutter: responsiveFlexGutter("items-container"),
placeItems: responsiveFlexPlaceItems,
direction: responsiveFlexDirection
});
const flexItemCSS = useResponsivePropsCSS(props, DEFAULT_PROPS, {
gutter: responsiveFlexGutter
gutter: responsiveFlexGutter("item")
});

return (
<div
css={{
display: "flex",
boxSizing: "border-box",
...flexCSS
display: "flex", // Without it, parent and child margins collapse. See: https://stackoverflow.com/a/19719427/247243
...wrapperCSS
}}
data-testid={testId}
>
{isObjectEmpty(flexItemCSS)
? childrenArray
: childrenArray.map((child, index) => (
<div css={flexItemCSS} key={index}>
{child}
</div>
))}
<div
css={{
display: "flex",
width: "100%",
height: "100%",
flexWrap: wrap === true ? "wrap" : "nowrap",
...flexCSS
}}
>
{isObjectEmpty(flexItemCSS)
? childrenArray
: childrenArray.map((child, index) => (
<div css={flexItemCSS} key={index}>
{child}
</div>
))}
</div>
</div>
);
}

Flex.propTypes = {
...responsivePropType("direction", PropTypes.oneOf(DIRECTIONS)),
...responsiveMarginType,
...responsiveWidthType,
...responsiveHeightType,
...responsivePropType("direction", PropTypes.oneOf(DIRECTIONS)),
...responsivePropType(
"gutter",
PropTypes.oneOfType([PropTypes.number, PropTypes.string])
),
wrap: PropTypes.bool,
...responsivePropType("placeItems", PropTypes.oneOf(PLACE_ITEMS)),
children: PropTypes.node.isRequired,
testId: PropTypes.string
Expand Down
Loading

0 comments on commit e1f3d26

Please sign in to comment.