@theroutingcompany/components 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -84
- package/dist/trc-components.es.js +5739 -5521
- package/dist/trc-components.es.js.map +1 -1
- package/dist/trc-components.umd.js +293 -224
- package/dist/trc-components.umd.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -18
- package/types/components/Button/Button.d.ts +1 -1
- package/types/components/Button/ButtonBase.d.ts +4 -0
- package/types/components/IconButton/IconButton.d.ts +1 -1
- package/types/components/Page/Page.d.ts +2 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Styling is done with [styled-components](https://styled-components.com/), a CSS-
|
|
|
20
20
|
The approach is roughly:
|
|
21
21
|
|
|
22
22
|
1. A "base" styled component with shared styles: `ButtonBase`
|
|
23
|
-
2. Each variant in the
|
|
23
|
+
2. Each variant in the Figma designs is a styled component 'extending' the base component: ` const PrimaryButton = styled(ButtonBase)`` `
|
|
24
24
|
|
|
25
25
|
- All variant are placed in an object (a map but not a `Map()`)
|
|
26
26
|
- The exported takes a `variant` prop and uses it to get the right styled component from the object map
|
|
@@ -29,42 +29,43 @@ The approach is roughly:
|
|
|
29
29
|
|
|
30
30
|
This component library is very much a work in progress and has many gaps.
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
- A component that exposes the spacing design tokens in an easy-to-use, type-safe way. Usually this is called `Box`.
|
|
33
|
+
- Far from all components in the Components Figma have been implemented
|
|
34
|
+
- For existing component, we need more documentation. Often, design systems include a "Guidelines" or "When to Use" section" on the component doc page.
|
|
35
|
+
- Tests!
|
|
36
36
|
|
|
37
37
|
## Guiding Principles
|
|
38
38
|
|
|
39
39
|
Partly inspired by these
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
- [Notes on maintaining an internal React component library](https://www.gabe.pizza/notes-on-component-libraries/)
|
|
42
|
+
- [Component API Standards](https://jonambas.com/posts/component-api-standards)
|
|
43
43
|
|
|
44
44
|
### Start Simple
|
|
45
45
|
|
|
46
46
|
Or the “Principle of Least Power”.
|
|
47
47
|
|
|
48
|
-
For example, don’t start building a table component that covers many use-cases. Instead start with just the reusable parts of the table that can be shared between many use-cases.
|
|
48
|
+
For example, don’t start building a table component that covers many use-cases. Instead, start with just the reusable parts of the table that can be shared between many use-cases.
|
|
49
49
|
|
|
50
50
|
### For content, prefer composition over props
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
- ❌ `<Text variant="body" text="Some text" />`
|
|
53
|
+
- ✅ `<Text variant="body">Some text</Text>`
|
|
54
54
|
|
|
55
|
-
### Prefer
|
|
55
|
+
### Prefer 'compound components' over one large component with many props
|
|
56
56
|
|
|
57
57
|
Similar to last point. Compound components scale better.
|
|
58
58
|
|
|
59
|
-
❌
|
|
59
|
+
❌
|
|
60
|
+
|
|
60
61
|
```jsx
|
|
61
62
|
<AlertDialog
|
|
62
|
-
title=
|
|
63
|
-
description=
|
|
64
|
-
cancelButtonText=
|
|
63
|
+
title='Header'
|
|
64
|
+
description='Optional description'
|
|
65
|
+
cancelButtonText='Close'
|
|
65
66
|
onCancel={() => {}}
|
|
66
|
-
confirmButtonText=
|
|
67
|
-
confirmButtonVariant=
|
|
67
|
+
confirmButtonText='Delete'
|
|
68
|
+
confirmButtonVariant='primary'
|
|
68
69
|
onDelete={() => {}}
|
|
69
70
|
// ... and so on
|
|
70
71
|
>
|
|
@@ -76,37 +77,43 @@ Similar to last point. Compound components scale better.
|
|
|
76
77
|
```
|
|
77
78
|
|
|
78
79
|
✅
|
|
80
|
+
|
|
79
81
|
```jsx
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
82
|
+
<AlertDialog>
|
|
83
|
+
<AlertDialogTrigger asChild>
|
|
84
|
+
<Button>Open dialog</Button>
|
|
85
|
+
</AlertDialogTrigger>
|
|
86
|
+
<AlertDialogContent size={size}>
|
|
87
|
+
<AlertDialogTitle>Header</AlertDialogTitle>
|
|
88
|
+
<AlertDialogDescription>Optional description</AlertDialogDescription>
|
|
89
|
+
<Text type='body'>
|
|
90
|
+
Powering the next generation of transit We help build more sustainable
|
|
91
|
+
cities with convenient and reliable transit for all
|
|
92
|
+
</Text>
|
|
93
|
+
<AlertDialogFooter>
|
|
94
|
+
<AlertDialogCancel asChild>
|
|
95
|
+
<Button size='large' variant='primary' emphasis='medium'>
|
|
96
|
+
Close
|
|
97
|
+
</Button>
|
|
98
|
+
</AlertDialogCancel>
|
|
99
|
+
<AlertDialogAction asChild>
|
|
100
|
+
<Button size='large' variant='danger'>
|
|
101
|
+
Delete
|
|
102
|
+
</Button>
|
|
103
|
+
</AlertDialogAction>
|
|
104
|
+
</AlertDialogFooter>
|
|
105
|
+
</AlertDialogContent>
|
|
106
|
+
</AlertDialog>
|
|
105
107
|
```
|
|
106
108
|
|
|
107
109
|
### Prefer React Context for components that depend on each other
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
Compound components are components that <q cite="https://kentcdodds.com/blog/compound-components-with-react-hooks">components that work together to accomplish a useful task</q>.
|
|
112
|
+
Radix makes extensive use of compound components.
|
|
113
|
+
|
|
114
|
+
Also see [Most of the time, it’s a good idea to use React context for components that depend on each other.](https://www.gabe.pizza/notes-on-component-libraries/#most-of-the-time-its-a-good-idea-to-use-react-context-for-components-that-depend-on-each-other) for an example.
|
|
115
|
+
|
|
116
|
+
The context should only be consumed within the library component and not exported.
|
|
110
117
|
|
|
111
118
|
<figure>
|
|
112
119
|
> [T]he context should be kept internal to the library. Allowing the naked context to be imported and handled by applications creates a brittle coupling that will easily break in future upgrades.
|
|
@@ -125,13 +132,12 @@ Avoid the Children API and `cloneElement`.
|
|
|
125
132
|
The Children API is a <q>leaky abstraction</q> and in [maintenance mode](https://github.com/reactjs/rfcs/pull/61#issuecomment-431247764).
|
|
126
133
|
<small>At the moment it's only used in the breadcrumbs component.</small>
|
|
127
134
|
|
|
128
|
-
The [React docs](https://beta.reactjs.org/reference/react/cloneElement#cloneelement) discourages the use of `cloneElement` because <q cite="https://beta.reactjs.org/reference/react/cloneElement#cloneelement">Cloning children makes it hard to tell how the data flows through your app.</q> and <q cite="https://beta.reactjs.org/reference/react/cloneElement#cloneelement">Using cloneElement is uncommon and can lead to fragile code</q
|
|
129
|
-
|
|
135
|
+
The [React docs](https://beta.reactjs.org/reference/react/cloneElement#cloneelement) discourages the use of `cloneElement` because <q cite="https://beta.reactjs.org/reference/react/cloneElement#cloneelement">Cloning children makes it hard to tell how the data flows through your app.</q> and <q cite="https://beta.reactjs.org/reference/react/cloneElement#cloneelement">Using cloneElement is uncommon and can lead to fragile code</q>.
|
|
130
136
|
|
|
131
137
|
### Don't rename HTML attributes
|
|
132
138
|
|
|
133
139
|
<figure>
|
|
134
|
-
> Native attributes or common props, such as `className`, `id` or `onClick`, should not be renamed. Don't force your engineers to learn APIs they already know
|
|
140
|
+
<blockquote> Native attributes or common props, such as `className`, `id` or `onClick`, should not be renamed. Don't force your engineers to learn APIs they already know.</blockquote>
|
|
135
141
|
<figcaption>
|
|
136
142
|
<cite>
|
|
137
143
|
<a href="https://www.jonambas.com/posts/component-api-standards">React Component API Standards — Native Attributes</a>
|
|
@@ -148,47 +154,52 @@ It is unfortunate that react-aria breaks with this principle. Therefore we have
|
|
|
148
154
|
|
|
149
155
|
Using design tokens consistently will make it easier to change values at scale in the future.
|
|
150
156
|
|
|
151
|
-
- ❌
|
|
152
|
-
- ✅
|
|
157
|
+
- ❌ `color: black;`
|
|
158
|
+
- ✅ `color: ${tokens.color_black};`
|
|
153
159
|
|
|
154
160
|
## Prefer meaningful tokens
|
|
155
161
|
|
|
156
162
|
For example, if we ever decide to implement dark mode, meaningfully-named tokens will make this switch easier.
|
|
157
163
|
|
|
158
|
-
- ❌
|
|
159
|
-
- ✅
|
|
164
|
+
- ❌ `color: ${tokens.color_black};`
|
|
165
|
+
- ✅ `color: ${tokens.tokens.color_text_strong};`
|
|
160
166
|
|
|
161
167
|
### Use HSL colors
|
|
162
168
|
|
|
163
169
|
[HSL notation](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) is more readable and more intuitive. Prefer it over other color notations like hex codes or `rgb()`
|
|
164
170
|
|
|
165
|
-
- ❌
|
|
166
|
-
- ❌
|
|
167
|
-
- ✅
|
|
171
|
+
- ❌ `color: #4287f5;`
|
|
172
|
+
- ❌ `color: rgb(66, 135, 245);`
|
|
173
|
+
- ✅ `color: hsl(217deg 90% 61%);`
|
|
168
174
|
|
|
169
175
|
Prefer modern [`hsl()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) over `hsla()`. `hsla` is legacy syntax. Add the alpha channel at the end after a `/`.
|
|
170
176
|
|
|
171
|
-
- ❌
|
|
172
|
-
- ✅
|
|
177
|
+
- ❌ `color: hsla(217deg, 90%, 61%, 0.8);`
|
|
178
|
+
- ✅ `color: hsl(217deg 90% 61% / 0.8);`
|
|
173
179
|
|
|
174
180
|
Some reading material on this:
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
|
|
182
|
+
- [Why you should use HSL over other colour formats in your CSS.](https://sujansundareswaran.com/blog/why-hsl-is-better-than-hex-and-rgb)
|
|
183
|
+
- [Using HSL Colors In CSS](https://www.smashingmagazine.com/2021/07/hsl-colors-css/)
|
|
178
184
|
|
|
179
185
|
## Style variants
|
|
180
186
|
|
|
181
|
-
Style styled-components usingg CSS variables defined in the component.
|
|
182
|
-
|
|
183
187
|
> **Warning**
|
|
184
188
|
> This is not settled and this pattern is not followed consistently (yet?).
|
|
185
189
|
|
|
190
|
+
Use CSS variables for the dynamic parts in styled-components using.
|
|
191
|
+
|
|
186
192
|
See [The styled-components Happy Path](https://www.joshwcomeau.com/css/styled-components/)
|
|
187
193
|
|
|
194
|
+
### Merge props
|
|
195
|
+
|
|
196
|
+
Use the [`mergeProps`](https://react-spectrum.adobe.com/react-aria/mergeProps.html) function from `@react-aria/util` to merge props correctly.
|
|
197
|
+
For example, Radix adds events handlers to buttons inside a `*Trigger` components with an `asChild` prop, `mergeProps` ensures there are chained instead of overwritten which enables functionality to be composed.
|
|
198
|
+
|
|
188
199
|
### Forward refs
|
|
189
200
|
|
|
190
201
|
<figure>
|
|
191
|
-
>
|
|
202
|
+
<blockquote>Refs should always be forwarded, either to the outermost DOM element, or to the most applicable element of the component. For example form components should forward refs to `<input/>`.</blockquote>
|
|
192
203
|
<figcaption>
|
|
193
204
|
<cite>
|
|
194
205
|
<a href="https://www.jonambas.com/posts/component-api-standards">React Component API Standards — Refs</a>
|
|
@@ -199,7 +210,7 @@ See [The styled-components Happy Path](https://www.joshwcomeau.com/css/styled-co
|
|
|
199
210
|
This is very important for components based on RadixUI and react-aria to work correctly.
|
|
200
211
|
|
|
201
212
|
<figure>
|
|
202
|
-
>
|
|
213
|
+
<blockquote>All component parts that render a DOM element have an `asChild` prop. This is useful when you want a part to attach its accessibility and functional requirements onto your own element instead.</blockquote>
|
|
203
214
|
<figcaption>
|
|
204
215
|
<cite>
|
|
205
216
|
<a href="https://www.radix-ui.com/docs/primitives/overview/styling#changing-the-rendered-element">React Component API Standards — Changing the rendered element</a>
|
|
@@ -218,10 +229,10 @@ For compound states, e.g `date-state='selected on'` the latter will not work.
|
|
|
218
229
|
|
|
219
230
|
(I like to think of it like `[...strings.split(" ")].includes(value)`. vs `strings === value`)
|
|
220
231
|
|
|
221
|
-
- ❌
|
|
222
|
-
- ✅
|
|
223
|
-
|
|
224
|
-
Radix adds a custom attribute with the state automatically. The attribute names and values are listed on each component's doc page ([example](https://www.radix-ui.com/docs/primitives/components/toggle#root)).
|
|
232
|
+
- ❌ `[data-state='selected']`.
|
|
233
|
+
- ✅ `[data-state~='selected']`
|
|
234
|
+
|
|
235
|
+
Radix adds a custom attribute with the state automatically. The attribute names and values are listed on each component's doc page ([example](https://www.radix-ui.com/docs/primitives/components/toggle#root)).
|
|
225
236
|
For component built on react-aria, we need to add `data-` attribute ourselves.
|
|
226
237
|
|
|
227
238
|
Recommended reads:
|
|
@@ -241,7 +252,6 @@ There are also a few react-aria hooks to handle these interaction state ([useFoc
|
|
|
241
252
|
> **Warning**
|
|
242
253
|
> Unfinished
|
|
243
254
|
|
|
244
|
-
|
|
245
255
|
Only write TypeScript files.
|
|
246
256
|
The linting config is also quite strict with `@typescript-eslint`.
|
|
247
257
|
|
|
@@ -251,8 +261,12 @@ Correct component types make it easier to use components without having to look
|
|
|
251
261
|
Exact types for props (for editor autocomplete) is a necessity, not a nice-to-have. Be as detailed as possible.
|
|
252
262
|
|
|
253
263
|
<figure>
|
|
254
|
-
>
|
|
255
|
-
>
|
|
264
|
+
<blockquote>
|
|
265
|
+
<ul>
|
|
266
|
+
<li>Avoid “stringly typed” code. Prefer more appropriate types where not every string is a possibility.</li>
|
|
267
|
+
<li>Prefer a union of string literal types to string if that more accurately describes the domain of a variable. You’ll get stricter type checking and improve the development experience.</li>
|
|
268
|
+
</ul>
|
|
269
|
+
</blockquote>
|
|
256
270
|
<figcaption>
|
|
257
271
|
<cite>
|
|
258
272
|
<a href="https://www.oreilly.com/library/view/effective-typescript/9781492053736/ch04.html#avoid-strings">Effective TypeScript - Prefer More Precise Alternatives to String Types</a>
|
|
@@ -261,16 +275,15 @@ Exact types for props (for editor autocomplete) is a necessity, not a nice-to-ha
|
|
|
261
275
|
</figure>
|
|
262
276
|
</figure>
|
|
263
277
|
|
|
264
|
-
|
|
265
|
-
-
|
|
266
|
-
- ✅ `type Variant = 'primary' | 'secondary' | 'danger' | 'inverse';`
|
|
278
|
+
- ❌ `type Variant = string;`
|
|
279
|
+
- ✅ `type Variant = 'primary' | 'secondary' | 'danger' | 'inverse';`
|
|
267
280
|
|
|
268
281
|
### Avoid spreads on native JSX elements
|
|
269
282
|
|
|
270
283
|
> **Warning**
|
|
271
|
-
> This is a principle we don't currently abide by but should!
|
|
284
|
+
> This is a principle we don't currently abide by but should!
|
|
272
285
|
|
|
273
|
-
See [Avoiding JSX spread on foreign data prevents weird bugs sometimes.](https://www.gabe.pizza/notes-on-component-libraries/#avoiding-jsx-spread-on-foreign-data-prevents-weird-bugs-sometimes).
|
|
286
|
+
See [Avoiding JSX spread on foreign data prevents weird bugs sometimes.](https://www.gabe.pizza/notes-on-component-libraries/#avoiding-jsx-spread-on-foreign-data-prevents-weird-bugs-sometimes).
|
|
274
287
|
|
|
275
288
|
Two ways we can solve this
|
|
276
289
|
|
|
@@ -279,34 +292,27 @@ Two ways we can solve this
|
|
|
279
292
|
|
|
280
293
|
> I recommend, whenever possible, to destructure the props object and forward keys as needed. Breaking the props down removes excessive keys, allows setting defaults, and makes grepping the code easier.
|
|
281
294
|
|
|
282
|
-
One downside I see the #2 is that
|
|
283
|
-
|
|
284
295
|
## Examples
|
|
285
296
|
|
|
286
297
|
- [the component gallery](https://component.gallery/) "Designed to be a reference for anyone building component-based user interfaces, The Component Gallery is an up-to-date repository of interface components based on examples from the world of design systems."
|
|
287
298
|
- [Storybook showcase](https://storybook.js.org/showcase)
|
|
299
|
+
- [Shopify Polaris](https://polaris.shopify.com/)
|
|
288
300
|
- [Primer: React implementation of GitHub's Primer Design System](https://primer.style/react/)
|
|
289
301
|
- [Paste: The Design System for building Twilio customer experiences](https://paste.twilio.design/)
|
|
290
302
|
- [Spectrum: Adobe’s design system.](https://react-spectrum.adobe.com/react-spectrum/)
|
|
291
303
|
- [Evergreen: Segment’s design system](https://evergreen.segment.com/)
|
|
292
304
|
- [awesome-react-design-systems](https://github.com/jbranchaud/awesome-react-design-systems)
|
|
293
305
|
|
|
294
|
-
## Reading
|
|
306
|
+
## Misc Reading
|
|
295
307
|
|
|
296
308
|
- [The styled-components Happy Path](https://www.joshwcomeau.com/css/styled-components/)
|
|
309
|
+
- [Demystifying styled-components](https://www.joshwcomeau.com/react/demystifying-styled-components/)
|
|
297
310
|
- [CSS Variables for React Devs](https://www.joshwcomeau.com/css/css-variables-for-react-devs/)
|
|
298
|
-
|
|
299
311
|
- [You Don’t Need A UI Framework](https://www.smashingmagazine.com/2022/05/you-dont-need-ui-framework/)
|
|
300
|
-
|
|
301
|
-
###
|
|
302
|
-
|
|
303
312
|
- [Vadim Demedes Design system tips](https://twitter.com/i/events/1577907596966641665)
|
|
304
|
-
- [
|
|
305
|
-
|
|
313
|
+
- [The difference between correct-ness and useful-ness in a design system/](https://www.robinrendle.com/notes/the-difference-between-correct-ness-and-useful-ness-in-a-design-system/)
|
|
306
314
|
- [Apple Developer: Layout - Foundations - Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/foundations/layout/)
|
|
307
315
|
|
|
308
|
-
|
|
309
|
-
|
|
310
316
|
#### TypeScript
|
|
311
317
|
|
|
312
318
|
- [TypeScript + React: Typing Generic forwardRefs](https://fettblog.eu/typescript-react-generic-forward-refs/)
|