-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f42796b
commit fd1eb90
Showing
40 changed files
with
274 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 4 additions & 4 deletions
8
exercises/03.compound-components/02.solution.validation/README.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# Compound Components Validation | ||
|
||
Runtime validation isn't the best (it would be better if we could enforce this | ||
statically via TypeScript), but unfortunately it's the best we can do with the | ||
composition model offered by React. That said, we it's unlikely people will mess | ||
this up now that we have this runtime validation in place. | ||
👨💼 Runtime validation isn't the best (it would be better if we could enforce | ||
this statically via TypeScript), but unfortunately it's the best we can do with | ||
the composition model offered by React. That said, we it's unlikely people will | ||
mess this up now that we have this runtime validation in place. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
# Compound Components | ||
|
||
👨💼 Great work! You now know how to create one of the best composition APIs for | ||
UI component libraries. The vast majority of component libraries employ this | ||
pattern and even if you don't build your own, you'll be much better able to use | ||
these libraries because you understand how they work. Good job! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,27 @@ | ||
# Slot Context | ||
|
||
👨💼 It's a tale as old as time. Our `label` and `input` are not properly | ||
associated in this form and so clicking the `label` will not focus the `input` | ||
as expected (in addition to other accessibility issues). | ||
|
||
But we don't want developers to be able to make this mistake. So we've made a | ||
`TextField` component which will generate the `id` for the relationship (if one | ||
is not provided). The tricky bit is we want people to be able to structure their | ||
label and input however they want, so we can't render the `input` and `label` | ||
for them. Instead, we want to be able to provide the `id` and `htmlFor` props to | ||
the `label` and `input`. | ||
|
||
So what we want you to do is first create a `SlotContext` and `useSlotProps` | ||
hook in <InlineFile file="slots.tsx" />, then use those in the `Label` and | ||
`Input` components to retrieve the necessary props. | ||
|
||
The `useSlotProps` hook should accept a props object and a slot name and return | ||
the props to be applied to the element for that slot. It should merge the props | ||
it's been given with the props from the `SlotContext` for that slot. | ||
|
||
Once you've finished that, then render the `SlotContext` provider in the | ||
`TextField` component in <InlineFile file="text-field.tsx" /> to provide slot | ||
props for the `label` and `input`. | ||
|
||
When you're finished, the label and input should be properly associated and | ||
clicking the label should focus the input. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
# Slot Context | ||
|
||
👨💼 That's a great start! Now we have that in place, I think we can use this in | ||
our toggle component! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,15 @@ | ||
# Generic Slot Components | ||
|
||
👨💼 You'll notice our party mode toggle button is using `useId` to properly | ||
associate the toggle button with its label. We'd like to make that implicit and | ||
reuse the `Label` component for the `Toggle` as well. | ||
|
||
Please update the `Toggle` component in <InlineFile file="toggle.tsx" /> to | ||
render a `SlotContext` provider (in addition to the `ToggleContext` provider | ||
it's already rendering) so it can provide props for a `label` slot (the slot | ||
name for a `Label`). You'll also want to put the `id` in the `ToggleContext` so | ||
the `ToggleButton` can grab it. | ||
|
||
Once you're finished with that, you can remove the manual `id`/`htmlFor` props | ||
in the <InlineFile file="app.tsx" /> file and the `id` should be provided | ||
automatically. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
# Generic Slot Components | ||
|
||
👨💼 Great! Now we can reuse the `Label` component in our set of `Toggle` compound | ||
components. Let's go a step further with a generic `Text` component. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,43 @@ | ||
# Slot Prop | ||
|
||
👨💼 We have `ToggleOn` and `ToggleOff` components, but really we could make those | ||
components a simple `Text` component that accepts a `slot` prop. Then the | ||
`Toggle` component could define the props that the individual `Text` components | ||
should have based on which slot they're taking. | ||
|
||
In fact, we could do this with the `Switch` as well! | ||
|
||
🧝♂️ I've added `Text` and `Switch` components to the | ||
<InlineFile file="slots.tsx" /> file for you to use. These are both already | ||
wired up to consume a `slot` named `text` and `switch`. You can | ||
<DiffLink app1={-1}>check the diff</DiffLink> for details. | ||
|
||
What we want to do in this exercise is add a `slot` prop to each of our slot | ||
components so the slot they're taking can be defined by the parent component. | ||
|
||
Then you'll need to update `Toggle` to get rid of the `ToggleContext` provider | ||
and instead use the `SlotProvider` for all the components it wants to send props | ||
to: | ||
|
||
- `label` - `htmlFor` | ||
- `onText` - `hidden` (`undefined` if `isOn` is true, and `true` if `isOn` is | ||
`false`) | ||
- `offText` - `hidden` (`undefined` if `isOn` is false, and `true` if `isOn` is | ||
`true`) | ||
- `switch` - `id`, `on`, and `onClick` | ||
|
||
So by the end of all of this, here's what I want the API to be like: | ||
|
||
```tsx | ||
<Toggle> | ||
<Label>Party mode</Label> | ||
<Switch /> | ||
<Text slot="onText">Let's party 🥳</Text> | ||
<Text slot="offText">Sad town 😭</Text> | ||
</Toggle> | ||
``` | ||
|
||
Once that's been updated, you can delete the `useToggle` hook and the | ||
`ToggleOn`, `ToggleOff`, and `ToggleButton` components. | ||
|
||
Reusability FTW! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
# Slot Prop | ||
|
||
👨💼 Great! Now we can use the same component for multiple slots! | ||
|
||
One thing to note is that there's not a great way to have good type safety on | ||
these props, though if you're creative, you could add nice runtime errors, | ||
[for example](https://github.com/adobe/react-spectrum/blob/3db98d2d378f977a88d94e9f2501feca8ef8ce51/packages/react-aria-components/src/utils.tsx#L169-L181). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
# Slots | ||
|
||
👨💼 This is a really nice pattern if you find yourself building a library of | ||
components that have a lot of common components. Great job! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Prop Collections | ||
|
||
Prop collections are great for handling common use cases for your hooks, but | ||
👨💼 Prop collections are great for handling common use cases for your hooks, but | ||
there's a subtle but important limitation with them that we should address next. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# Prop Getters | ||
|
||
Great, now users don't have to worry about whether they're overriding us or | ||
👨💼 Great, now users don't have to worry about whether they're overriding us or | ||
we're overriding them and everything can be an implementation detail which we | ||
can change as needed without worrying about breaking people's expectations. | ||
Composition FTW! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
# Prop Collections and Getters | ||
|
||
👨💼 Great work! This is a highly flexible pattern that gives consumers a great | ||
deal of control over how the component is rendered while also handling common | ||
cases with ease. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,17 @@ | ||
# State Reducer | ||
|
||
In this exercise, we want to prevent the toggle from updating the toggle state | ||
after it's been clicked 4 times in a row before resetting. We could easily add | ||
that logic to our reducer, but instead we're going to apply a computer science | ||
pattern called "Inversion of Control" where we effectively say: "Here you go! | ||
You have complete control over how this thing works. It's now your | ||
👨💼 In this exercise, we want to prevent the toggle from updating the toggle | ||
state after it's been clicked 4 times in a row before resetting. We could easily | ||
add that logic to our reducer, but instead we're going to apply a computer | ||
science pattern called "Inversion of Control" where we effectively say: "Here | ||
you go! You have complete control over how this thing works. It's now your | ||
responsibility." | ||
|
||
> As an aside, before React Hooks were a thing, this was pretty tricky to | ||
> implement and resulted in pretty weird code, but with useReducer, this is WAY | ||
> better. I ❤️ hooks. 😍 | ||
Your job is to enable people to provide a custom `reducer` so they can have | ||
complete control over how state updates happen in our `<Toggle />` component. | ||
|
||
<callout-info class="aside"> | ||
As an aside, before React Hooks were a thing, this was pretty tricky to | ||
implement and resulted in pretty weird code, but with useReducer, this is WAY | ||
better. I ❤️ hooks. 😍 | ||
</callout-info> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# State Reducer | ||
|
||
This is a powerful example of inversion of control that allows users to | ||
👨💼 This is a powerful example of inversion of control that allows users to | ||
overwrite our entire reducer. But it could be exhausting to users to have to | ||
duplicate most of our reducer just to change a few things. So let's address that | ||
common scenario next. |
Oops, something went wrong.