Skip to content

Commit afbab6c

Browse files
authored
Add Testimonial and Stack components (#82)
1 parent a6fee37 commit afbab6c

32 files changed

+1590
-12
lines changed

.changeset/lucky-dolls-arrive.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
'@primer/react-brand': minor
3+
---
4+
5+
Added `Testimonial` component.
6+
7+
Usage example:
8+
9+
```jsx
10+
<Testimonial>
11+
<Testimonial.Quote>
12+
GitHub helps us ensure that we have our security controls baked into our
13+
pipelines all the way from the first line of code we&apos;re writing.
14+
</Testimonial.Quote>
15+
<Testimonial.Name position="Staff Security Engineer">
16+
David Ross
17+
</Testimonial.Name>
18+
<Testimonial.Avatar
19+
src="https://avatars.githubusercontent.com/u/92997159?v=4"
20+
alt="Circular avatar from David Ross's GitHub profile"
21+
/>
22+
</Testimonial>
23+
```
24+
25+
See the [documentation](https://primer.style/brand/components/Testimonial) or [Storybook](https://primer.style/brand/storybook/?path=/story/components-testimonial--playground) for more usage examples.

.changeset/unlucky-hats-scream.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
'@primer/react-brand': minor
3+
---
4+
5+
Added `Stack` component.
6+
7+
Usage example:
8+
9+
```jsx
10+
<Stack direction="horizontal" gap="spacious" padding="spacious">
11+
<div>
12+
<img
13+
src="https://via.placeholder.com/300x150/f5f5f5/f5f5f5.png"
14+
alt="placeholder with gray background and no foreground text"
15+
/>
16+
</div>
17+
<div>
18+
<img
19+
src="https://via.placeholder.com/300x150/f5f5f5/f5f5f5.png"
20+
alt="placeholder with gray background and no foreground text"
21+
/>
22+
</div>
23+
<div>
24+
<img
25+
src="https://via.placeholder.com/300x150/f5f5f5/f5f5f5.png"
26+
alt="placeholder with gray background and no foreground text"
27+
/>
28+
</div>
29+
</Stack>
30+
```
31+
32+
See [Storybook](https://primer.style/brand/storybook/?path=/story/components-stack--playground) for more usage examples.

docs/content/components/Stack.mdx

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: Stack
3+
status: Experimental
4+
source: https://github.com/primer/brand/tree/main/src/Text/Text.tsx
5+
storybook: '/brand/storybook/?path=/story/components-stack--playground'
6+
description: Stack enables layout of its immediate children along the vertical or horizontal axis
7+
---
8+
9+
import {
10+
defaultStackDirection,
11+
defaultStackSpacing,
12+
StackAlignItemVariants,
13+
StackSpacingVariants,
14+
StackDirectionVariants,
15+
StackJustifyContentVariants,
16+
} from '@primer/react-brand'
17+
import {PropTableValues} from '../../src/components'
18+
19+
```js
20+
import {Stack} from '@primer/react-brand'
21+
```
22+
23+
## Examples
24+
25+
### Default
26+
27+
`Stack` is a layout helper component intended for rendering `children` in a single direction.
28+
29+
Use the `direction` prop to alternate between `vertical` and `horizontal` directions.
30+
31+
Many `Stack` props - including `direction` - accept both `string` and `Object` values. The former will apply the value across all viewports, while the latter will permit granular control at specific breakpoints. See [Responsive](#Responsive) below for more details.
32+
33+
```jsx live
34+
<Stack direction="horizontal">
35+
<img
36+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
37+
alt="placeholder with gray background and no foreground text"
38+
/>
39+
<img
40+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
41+
alt="placeholder with gray background and no foreground text"
42+
/>
43+
<img
44+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
45+
alt="placeholder with gray background and no foreground text"
46+
/>
47+
</Stack>
48+
```
49+
50+
### Alignment
51+
52+
`Stack` provides `alignItems` and `justifyContent` props for determining the rendering direction on the cross-axis and main-axis respectively.
53+
54+
Use the playground below to experiment with the various options.
55+
56+
```javascript live noinline
57+
const App = () => {
58+
const [alignItemsValue, setAlignItemsValue] = React.useState('center')
59+
const [justifyContentValue, setJustifyContentValue] =
60+
React.useState('space-between')
61+
62+
const handleMainAxisChange = (event) =>
63+
setJustifyContentValue(event.target.value)
64+
const handleCrossAxisChange = (event) =>
65+
setAlignItemsValue(event.target.value)
66+
67+
return (
68+
<Container>
69+
<Stack
70+
direction="horizontal"
71+
alignItems={alignItemsValue}
72+
justifyContent={justifyContentValue}
73+
style={{height: 400}}
74+
>
75+
<img
76+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
77+
alt="placeholder with gray background and no foreground text"
78+
/>
79+
<img
80+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
81+
alt="placeholder with gray background and no foreground text"
82+
/>
83+
<img
84+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
85+
alt="placeholder with gray background and no foreground text"
86+
/>
87+
</Stack>
88+
89+
<Stack direction="horizontal" gap="spacious" justifyContent="center">
90+
<FormControl>
91+
<FormControl.Label>Main axis</FormControl.Label>
92+
<Select
93+
defaultValue={justifyContentValue}
94+
onChange={handleMainAxisChange}
95+
>
96+
<Select.Option value="center">center</Select.Option>
97+
<Select.Option value="flex-start">flex-start</Select.Option>
98+
<Select.Option value="flex-end">flex-end</Select.Option>
99+
<Select.Option value="space-between">space-between</Select.Option>
100+
<Select.Option value="space-around">space-around</Select.Option>
101+
<Select.Option value="space-evenly">space-evenly</Select.Option>
102+
</Select>
103+
</FormControl>
104+
105+
<FormControl>
106+
<FormControl.Label>Cross axis</FormControl.Label>
107+
<Select
108+
defaultValue={alignItemsValue}
109+
onChange={handleCrossAxisChange}
110+
>
111+
<Select.Option value="center">center</Select.Option>
112+
<Select.Option value="flex-start">flex-start</Select.Option>
113+
<Select.Option value="flex-end">flex-end</Select.Option>
114+
</Select>
115+
</FormControl>
116+
</Stack>
117+
</Container>
118+
)
119+
}
120+
121+
render(App)
122+
```
123+
124+
### Responsive
125+
126+
Passing an Object of a particular shape will allow granular control of `direction`, `gap`, `alignItems`, `justifyContent` and `padding` at various supported breakpoints.
127+
128+
Supported breakpoints are `narrow`, `regular` and `wide`.
129+
130+
The Object value does not require all properties be passed, but rather operates on the basis of `min-width`.
131+
132+
E.g. Providing only `narrow` will apply that value to all larger breakpoints, but not the other way.
133+
134+
```jsx live
135+
<Stack
136+
direction={{
137+
narrow: 'vertical',
138+
regular: 'vertical',
139+
wide: 'horizontal',
140+
}}
141+
gap={{
142+
narrow: 'condensed',
143+
regular: 'normal',
144+
wide: 'spacious',
145+
}}
146+
padding={{
147+
narrow: 'condensed',
148+
regular: 'normal',
149+
wide: 'spacious',
150+
}}
151+
>
152+
<img
153+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
154+
alt="placeholder with gray background and no foreground text"
155+
/>
156+
<img
157+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
158+
alt="placeholder with gray background and no foreground text"
159+
/>
160+
<img
161+
src="https://via.placeholder.com/150x75/f5f5f5/f5f5f5.png"
162+
alt="placeholder with gray background and no foreground text"
163+
/>
164+
</Stack>
165+
```
166+
167+
## Component props
168+
169+
### Stack
170+
171+
| Name | Type | Default | Description |
172+
| :--------------- | :--------------------------------------------------------------------- | :--------------------------------------------------: | :----------------------------------------- |
173+
| `direction` | <PropTableValues values={StackDirectionVariants} addLineBreaks /> | <PropTableValues values={[defaultStackDirection]} /> | Determines layout direction |
174+
| `gap` | <PropTableValues values={StackSpacingVariants} addLineBreaks /> | <PropTableValues values={[defaultStackSpacing]} /> | Determines gap between items |
175+
| `padding` | <PropTableValues values={StackSpacingVariants} addLineBreaks /> | <PropTableValues values={[defaultStackSpacing]} /> | Determines padding applied to Stack parent |
176+
| `justifyContent` | <PropTableValues values={StackJustifyContentVariants} addLineBreaks /> | | Determines rendering on the main-axis |
177+
| `alignItems` | <PropTableValues values={StackAlignItemVariants} addLineBreaks /> | | Determines rendering on the cross-axis |

0 commit comments

Comments
 (0)