diff --git a/.eslintrc.json b/.eslintrc.json index c521cee7d2c..0935ade6a80 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,7 +23,8 @@ "lib/**/*", "lib-*/**/*", "types/**/*", - "consumer-test/**/*" + "consumer-test/**/*", + "contributor-docs/adrs/*" ], "globals": { "__DEV__": "readonly" diff --git a/contributor-docs/adrs/adr-005-box-sx.md b/contributor-docs/adrs/adr-005-box-sx.md new file mode 100644 index 00000000000..4b0f81e55b8 --- /dev/null +++ b/contributor-docs/adrs/adr-005-box-sx.md @@ -0,0 +1,62 @@ +# ADR 005: Use Box as a building block for all other components + +## Status + +Approved + +## Context + +In Primer React and consuming applications, we use many different patterns for creating React components. Two common patterns are: + +1. Creating components with styled-components + + ```tsx + const Avatar = styled.img.attrs(props => ({ + height: props.size, + width: props.size + }))` + display: inline-block; + overflow: hidden; + line-height: ${get('lineHeights.condensedUltra')}; + border-radius: ${props => getBorderRadius(props)}; + ${sx} + ` + ``` + + [Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0) + +2. Creating components with Box + + ```tsx + const Avatar: React.FC = ({size = 20, alt = '', square = false, sx = {}, ...props}) => { + const styles:BetterSystemStyleObject = { + display: 'inline-block', + overflow: 'hidden', + lineHeight: 'condensedUltra', + borderRadius: getBorderRadius({size, square}) + } + + return ( + (styles, sx)} // styles needs to merge with props.sx + {...props} + /> + ) + } + ``` + + [Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0) + +  + +## Decision + +Prefer using method #2: Creating components with Box for the following reasons: + +- 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) +- 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) +- We have had issues with exporting types, we can increase confidence by keeping the exported types close to what we author. + +See diff for moving Avatar from approach 1 to 2: https://github.com/primer/react/pull/2019/files?diff=split&w=0