Here is an interesting question; are the types in your Typescript project enough documentation, on their own, to allow someone to learn the library?
That was the question I asked myself when I saw the Amazon had released a React UI library for AWS. They only released the code and the Typescript types. No documentation. No storybook
or styleguidist
. Just the code and the types.
Now I love digging into UI libraries. And this was a fun challenge. Can I learn the library from just the source? So I started a Create React App using the typescript
template, then installed the @awsui/components-react
library and started my sleuthing.
The first thing to realize is that VS Code loves Typescript, and in this journey it will be your invaluable partner. For example, you can right click on the import and ask for the definitions, as shown in the screenshot below.
And that takes you to the central definitions file that lists all the components and their properties.
Jackpot! Now I know what’s in there. But how to use it?
Getting The Layout Right
Right away what captured my eye was AppLayout
because, really, there are two types of toys in a UI library; layout components and interactive components. And job number one is creating the layout, and job two is putting stuff in that layout.
Naming is important, right? AppLayout
. Sounds good! I’m making an App
, check. And I need a Layout
, double check. AppLayout
it is! It also helped that it was alphabetical and in the A's.
So I dropped an AppLayout
on the page and right away I got a three column layout with a collapsible navigation
panel to the left and a tools
panel to the right, with a content
section between. How did I know that? Because of the types!
So this is not only telling me what sections are available, but also the kind of content they are expecting, in this case ReactNode
types which are, basically, anything renderable in React.
I replaced the entire contents of the canned App
component with this code:
function App() {
return (
<AppLayout
navigation={<div>Navigation</div>}
content={<div>Content</div>}
tools={<div>Tools</div>}
/>
);
}
Then I ran yarn start
and right away I got a pretty decent looking responsive layout with three columns and collapsible sections. I was off to the races!
As Expected, With Exceptions
I’m not one to just play with components, I want to build something real-ish. So I created a Pokemon filter application. Some things, like Button
were very straightforward.
<Button onClick={() => alert("hello!")}>Say Hello</Button>
This worked out of the box, but the button itself wasn’t very visually appealing by default. Once again, Typescript to the rescue!
Using Go To Definition
in VSCode I was able to select a Button
component and drill until I found the ButtonProps
which showed me that there is a variant
prop that I could use to select different styles of button. I ended up going with link
.
Another moment came when I was working with the Input
component, which, as you might guess is a text input. Everything was going great until I got to onChange
where the event structure was a little different from what we expect.
In this case event.target.value
wasn’t there. Once again, VS Code to the rescue and I was able to find event.detail.value
was the droid I was looking for instead.
Finding a New Pattern
Eventually I needed to put up a list of the Pokemon. I not only found a great Cards
component to do that, I also found a great way of defining generic React components. Check this out!
So you give Cards
an array of items and then you provide content functions that render the content for each item.
Anyway, because Typescript, the AWS team defined Card
as a generic and when you pass an array in for that items
property Typescript automatically infers the type of the array and then applies it to the other parts of the property definitions as required. In your content
function you get type safety and hinting around the type from the array of items. And you don’t, as a consumer, need to do any additional work to make that happen. It just works, for free, just the way you’d expect it.
Seeing this was the most exciting moment of discovery on this journey. For some reason or another I hadn’t really thought about using generics for React components. So it was a genuine “Ah ha!” moment that I got from reading the code. This is not something I would have gotten from the documentation (most likely).
In addition to generics, seeing this pattern where you give the component some data and a render function (which is a pattern throughout the toolkit) was great to see. I’d seen it before in toolkits like Apple’s iOS List component. But I’ve rarely seen it on the web and I think it’s a good architectural pattern that’s worthy of more extensive use.
Video Version
If you want to see my exploration of the AWS UI toolkit for yourself check out the YouTube version.
Conclusion
The two big takeaways I learned from this sleuthing experience was:
- Learn To Read Code — Code is truth. And learning how to read someone else’s code can be a source of information, inspiration, education, all the good stuff. And what’s even better is that when you build that code reading muscle you can start to look at Github not just as a place to “grab code” but as the best code reading library the Universe has ever known.
- Typescript Is Documentation — Sure typing doesn’t answer all the questions. But it answers a lot of them very quickly, and it’s free. So the cost/benefit ratio is outstanding. Typescript is worth it, y’all.
- Bonus: Naming Is Really Important — I only scratched the surface on this library. There are tons of components. The only moments that I really struggled was with the naming on some of these components. For example; what’s a “Tile”? (Turns out it’s a radio button). Now that’s not really a fault of the folks at AWS. Naming is tough. But as frontend developers it would probably benefit us, at some point, to normalize what we name our UI elements, beyond Button.
Top comments (0)