Skip to content
This repository has been archived by the owner on Dec 6, 2022. It is now read-only.

Commit

Permalink
Merge pull request #554 from rrrahal/main
Browse files Browse the repository at this point in the history
Add columns Prop to ChoiceCardGroup
  • Loading branch information
SiAdcock authored Oct 5, 2020
2 parents 435d3ad + c147353 commit 8af55ef
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/core/components/choice-card/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ Whether choice card is checked. This is necessary when using the [controlled app

**Note:** if you pass the `checked` prop, you **must** also pass an `onChange` handler, or the field will be rendered as read-only.

### `columns`

**`number`**

To render a grid of choice cards, specify the number of columns. If this prop is not set, cards will appear on a single line.


## Supported themes

### Standard
Expand Down
9 changes: 8 additions & 1 deletion src/core/components/choice-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { SerializedStyles } from "@emotion/core"
import {
fieldset,
flexContainer,
gridContainer,
gridColumns,
groupLabel,
input,
tickAnimation,
Expand All @@ -31,12 +33,16 @@ const SupportingText = ({ children }: { children: ReactNode }) => {
</div>
)
}

export type Columns = 2 | 3 | 4 | 5

interface ChoiceCardGroupProps extends Props {
name: string
label?: string
supporting?: string
multi?: boolean
error?: string
columns?: Columns
children: JSX.Element | JSX.Element[]
cssOverrides?: SerializedStyles | SerializedStyles[]
}
Expand All @@ -47,6 +53,7 @@ const ChoiceCardGroup = ({
supporting,
multi,
error,
columns,
cssOverrides,
children,
...props
Expand All @@ -62,7 +69,7 @@ const ChoiceCardGroup = ({
)}
{supporting ? <SupportingText>{supporting}</SupportingText> : ""}
{typeof error === "string" && <InlineError>{error}</InlineError>}
<div css={flexContainer}>
<div css={columns ? [gridContainer, gridColumns[columns] ] : flexContainer}>
{React.Children.map(children, (child) => {
return React.cloneElement(
child,
Expand Down
1 change: 1 addition & 0 deletions src/core/components/choice-card/stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from "./stories/single-state-mobile"
export * from "./stories/single-state-payment-icon"
export * from "./stories/single-state-payment-icon-mobile"
export * from "./stories/wildly-varying-length"
export * from "./stories/with-columns"
72 changes: 72 additions & 0 deletions src/core/components/choice-card/stories/with-columns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useState } from "react"
import { css } from "@emotion/core"
import { textSans } from "@guardian/src-foundations/typography"
import { text } from "@guardian/src-foundations/palette"
import { space } from "@guardian/src-foundations"
import { ChoiceCardGroup, ChoiceCard } from "../index"

const medium = css`
width: 30em;
`

const spaced = css`
margin-bottom: ${space[3]}px;
`

const message = css`
${textSans.medium()};
color: ${text.primary};
`

export const singleStateControlledWithColumns = () => {
const [selected, setSelected] = useState<string | null>("green")

return (
<div css={medium}>
<div css={spaced}>
<ChoiceCardGroup name="colours" columns={2}>
<ChoiceCard
value="red"
label="Red"
id="default-red"
checked={selected === "red"}
onChange={() => setSelected("red")}
/>
<ChoiceCard
value="green"
label="Green"
id="default-green"
checked={selected === "green"}
onChange={() => setSelected("green")}
/>
<ChoiceCard
value="blue"
label="Blue"
id="default-blue"
checked={selected === "blue"}
onChange={() => setSelected("blue")}
/>
<ChoiceCard
value="orange"
label="Orange"
id="default-orange"
checked={selected === "orange"}
onChange={() => setSelected("orange")}
/>
<ChoiceCard
value="yellow"
label="Yellow"
id="default-yellow"
checked={selected === "yellow"}
onChange={() => setSelected("yellow")}
/>
</ChoiceCardGroup>
</div>
<span css={message}>{selected} is selected</span>
</div>
)
}

singleStateControlledWithColumns.story = {
name: `single state controlled with columns example`
}
30 changes: 28 additions & 2 deletions src/core/components/choice-card/styles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { css } from "@emotion/core"
import { css, SerializedStyles } from "@emotion/core"
import { space, transitions } from "@guardian/src-foundations"
import { visuallyHidden } from "@guardian/src-foundations/accessibility"
import { textSans } from "@guardian/src-foundations/typography"
Expand All @@ -9,6 +9,7 @@ import {
choiceCardDefault,
} from "@guardian/src-foundations/themes"
import { width, height } from "@guardian/src-foundations/size"
import { Columns } from './index'

export const fieldset = css`
border: 0;
Expand All @@ -29,6 +30,32 @@ export const flexContainer = css`
}
`

export const gridContainer = css`
width: 100%;
${from.mobileLandscape} {
@supports (display: grid) {
display: grid;
row-gap: ${space[2]}px;
column-gap: ${space[2]}px;
& > label {
margin: 0;
}
}
}
`

const gridColumnsStyle = (columns: Columns) => css`
${from.mobileLandscape} {
grid-template-columns: repeat(${columns}, 1fr);
}
`
export const gridColumns: {[key in Columns]: SerializedStyles } = {
2: gridColumnsStyle(2),
3: gridColumnsStyle(3),
4: gridColumnsStyle(4),
5: gridColumnsStyle(5),
}

export const groupLabel = ({
choiceCard,
}: { choiceCard: ChoiceCardTheme } = choiceCardDefault) => css`
Expand Down Expand Up @@ -135,7 +162,6 @@ export const choiceCard = ({
${from.mobileLandscape} {
margin: 0 ${space[2]}px 0 0;
&:last-child {
margin: 0;
}
Expand Down

0 comments on commit 8af55ef

Please sign in to comment.