Skip to content

Commit bbd436e

Browse files
siddharthkpcolebemistalum
authored
ADR: Use Box + sx to author components - DEADLINE: Friday 22 April (#2020)
* ADR: Use Box to author new components * replace long example with PR link * add ADRs to eslint ignore * better phrasing of intro, thanks Cole! Co-authored-by: Cole Bemis <colebemis@github.com> * sentence case, thanks Cole! Co-authored-by: Cole Bemis <colebemis@github.com> * Apply suggestions from code review thanks Cole! Co-authored-by: Cole Bemis <colebemis@github.com> * Apply suggestions from code review, thanks @talum Co-authored-by: Tracy Lum <11878752+talum@users.noreply.github.com> * Remove overriding styles from this ADR * Link sx API research * use BetterSystemStyleObject for types * Change status to Approved Co-authored-by: Cole Bemis <colebemis@github.com> Co-authored-by: Tracy Lum <11878752+talum@users.noreply.github.com>
1 parent a69a72a commit bbd436e

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"lib/**/*",
2424
"lib-*/**/*",
2525
"types/**/*",
26-
"consumer-test/**/*"
26+
"consumer-test/**/*",
27+
"contributor-docs/adrs/*"
2728
],
2829
"globals": {
2930
"__DEV__": "readonly"
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# ADR 005: Use Box as a building block for all other components
2+
3+
## Status
4+
5+
Approved
6+
7+
## Context
8+
9+
In Primer React and consuming applications, we use many different patterns for creating React components. Two common patterns are:
10+
11+
1. Creating components with styled-components
12+
13+
```tsx
14+
const Avatar = styled.img.attrs<StyledAvatarProps>(props => ({
15+
height: props.size,
16+
width: props.size
17+
}))<StyledAvatarProps>`
18+
display: inline-block;
19+
overflow: hidden;
20+
line-height: ${get('lineHeights.condensedUltra')};
21+
border-radius: ${props => getBorderRadius(props)};
22+
${sx}
23+
`
24+
```
25+
26+
[Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0)
27+
28+
2. Creating components with Box
29+
30+
```tsx
31+
const Avatar: React.FC<AvatarProps> = ({size = 20, alt = '', square = false, sx = {}, ...props}) => {
32+
const styles:BetterSystemStyleObject = {
33+
display: 'inline-block',
34+
overflow: 'hidden',
35+
lineHeight: 'condensedUltra',
36+
borderRadius: getBorderRadius({size, square})
37+
}
38+
39+
return (
40+
<Box
41+
as="img"
42+
alt={alt}
43+
sx={merge<BetterSystemStyleObject>(styles, sx)} // styles needs to merge with props.sx
44+
{...props}
45+
/>
46+
)
47+
}
48+
```
49+
50+
[Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0)
51+
52+
&nbsp;
53+
54+
## Decision
55+
56+
Prefer using method #2: Creating components with Box for the following reasons:
57+
58+
- Better authoring experience with Typescript. With Box, we can improve the API and autocomplete for consuming primitives. [See research](https://github.com/github/primer/discussions/755#discussioncomment-2318144)
59+
- The styling library (i.e. styled-components) becomes an implementation detail and can be changed later with minimal breaking changes for consumers. (Avoids leaky abstractions)
60+
- We have had issues with exporting types, we can increase confidence by keeping the exported types close to what we author.
61+
62+
See diff for moving Avatar from approach 1 to 2: https://github.com/primer/react/pull/2019/files?diff=split&w=0

0 commit comments

Comments
 (0)