<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kaeden Wile</title>
    <description>The latest articles on DEV Community by Kaeden Wile (@kaedenwile).</description>
    <link>https://dev.to/kaedenwile</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F943078%2F3b8a983c-2e27-4050-bac4-1a6c5ec6d553.png</url>
      <title>DEV Community: Kaeden Wile</title>
      <link>https://dev.to/kaedenwile</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kaedenwile"/>
    <language>en</language>
    <item>
      <title>Tips to Build React Components that Devs will LOVE</title>
      <dc:creator>Kaeden Wile</dc:creator>
      <pubDate>Wed, 22 May 2024 20:48:40 +0000</pubDate>
      <link>https://dev.to/devsatasurion/tips-to-build-react-components-that-devs-will-love-4l62</link>
      <guid>https://dev.to/devsatasurion/tips-to-build-react-components-that-devs-will-love-4l62</guid>
      <description>&lt;p&gt;I lead the engineering team responsible for building our company’s design system and component library. Our components are not only seen by millions of users, they’re used by my fellow developers across dozens of repositories. After building, supporting, updating, bug fixing, and deprecating many React components with a wide audience, I’ve learned a ton of lessons and distilled my experiences into a few best practices I try to follow.&lt;/p&gt;

&lt;p&gt;These best-practices don’t just apply to React front-end development; in fact, they’re common across software development and even engineering in general. They’re not ground-breaking, and I doubt you’ll find them shocking. But it is amazing how much of a difference keeping these simple guidelines in mind can actually make.&lt;/p&gt;

&lt;p&gt;If you add these to your tech-design process and PR check-list, your teammates, consumers, and future self will thank you.&lt;/p&gt;




&lt;p&gt;It all boils down to this: &lt;strong&gt;Simplify your API.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;When I’m building a React component, my primary audience is the developer who will be using it. To give them the best experience, I need to &lt;strong&gt;minimize complexity&lt;/strong&gt;. That means as I weigh all the possible ways to build a component, simplicity in the API is the most important factor.&lt;/p&gt;

&lt;p&gt;A simple API is not the same as simple code. In fact, creating a simple API for our consumers often leads to &lt;em&gt;increased&lt;/em&gt; complexity within our codebase, as we add additional logic behind the scenes. That’s a tradeoff we have to weigh during our tech design process.&lt;/p&gt;

&lt;p&gt;What does it look like to create a simple API? There can be a lot of factors involved, but for React components I primarily look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimizing the total lines of code a developer has to write&lt;/li&gt;
&lt;li&gt;Minimizing the average number of props that are used&lt;/li&gt;
&lt;li&gt;Simplifying the types and depth of my props — i.e. using strings and numbers over objects and arrays&lt;/li&gt;
&lt;li&gt;Matching standard HTML prop naming conventions&lt;/li&gt;
&lt;li&gt;Eliminate edge cases with strong typing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dig into each of these.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimize total lines of code
&lt;/h3&gt;

&lt;p&gt;This should be pretty straight-forward. In React, less code often means less complexity, although that isn’t universally true in programming. I have seen some cases where it takes 10+ lines of code to fill out the props for a simple button component, which makes it difficult and time-consuming to build even simple flows.&lt;/p&gt;

&lt;p&gt;To help with this, I suggest avoiding redundancy and providing default values. Never use 2 props when 1 prop will do. Similarly, never use 1 prop when 0 props will do. If one prop’s value can be inferred from another, build that logic into your component. Hide the complexity behind the scenes so that your consumer doesn’t have to think about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimize the average number of props
&lt;/h3&gt;

&lt;p&gt;My team builds components that are highly versatile and flexible. There are often many different ways to configure a given component, but there is one way that is the most common. I optimize for this most-common case.&lt;/p&gt;

&lt;p&gt;Set up default behaviors and prop values so that most of the time, a developer won’t need to think about that prop at all. The holy grail is when a component can be used with &lt;em&gt;no&lt;/em&gt; props—and it still does exactly what they need it to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simplifying type and depth of props
&lt;/h3&gt;

&lt;p&gt;One tempting approach to minimize the number of props is by cramming all the less common options into some catch-all prop that accepts an object. I have found that this doesn’t scale. Accepting &lt;code&gt;object&lt;/code&gt;s for props is an anti-pattern on our team, because it’s difficult to document well and almost always creates more complexity.&lt;/p&gt;

&lt;p&gt;I recommend using &lt;code&gt;string&lt;/code&gt; and &lt;code&gt;number&lt;/code&gt; types for props and moving all complexity to the &lt;code&gt;children&lt;/code&gt; prop. There’s often a way to expose subcomponents with configuration of their own instead of accepting &lt;code&gt;object&lt;/code&gt; or &lt;code&gt;Array&lt;/code&gt;s as props. It makes consumer’s code simpler to read and understand and gives them more flexibility and control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Match HTML prop naming conventions
&lt;/h3&gt;

&lt;p&gt;Naming is important in programming. With higher-quality names, we can spend less time consulting documentation. In React, we’re already working with common HTML elements that have standardized names and types. If my API matches the HTML standard, there’s less for me to document. Where it deviates, I have to document.&lt;/p&gt;

&lt;p&gt;Our team uses object destructuring and spreading (&lt;code&gt;{ ...props}&lt;/code&gt;) extensively to pass through standard HTML props to the component. For event handlers, we use the “on” prefix. We use “disabled” and “checked” props to match the standards on &lt;code&gt;input&lt;/code&gt;elements. Any time we can avoid introducing a new prop name, we keep our API surface area that much smaller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Eliminate edge cases
&lt;/h3&gt;

&lt;p&gt;Even in a simple component with just a few props, the total permutations of configuration can quickly get out of hand. My goal is to avoid the permutations that don’t make sense—for example, when “readonly” and “disabled” are set on a Button, or when “selected” is used on a non-selectable variant of Card. &lt;/p&gt;

&lt;p&gt;We take two approaches to making these situations impossible: first, consolidating conflicting props. If “readonly”, “disabled”, and “loading” are all conflicting props on my Button, why not move them into a single “state” prop? Otherwise, when consolidation isn’t possible, we lean on TypeScript and other tooling to catch those configurations at build time.&lt;/p&gt;




&lt;p&gt;Keep these guidelines in mind as you update and build new React components and watch how easy it is for other developers to use your components! &lt;/p&gt;

&lt;p&gt;Hope you enjoyed! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://wile.xyz"&gt;https://wile.xyz&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Make PRs the BEST PART of Programming</title>
      <dc:creator>Kaeden Wile</dc:creator>
      <pubDate>Tue, 29 Nov 2022 19:07:54 +0000</pubDate>
      <link>https://dev.to/devsatasurion/make-prs-the-best-part-of-programming-1l95</link>
      <guid>https://dev.to/devsatasurion/make-prs-the-best-part-of-programming-1l95</guid>
      <description>&lt;p&gt;In this blog post, I'd like to share some of my thoughts on &lt;em&gt;how&lt;/em&gt; I've been able to effectively think about software development.&lt;/p&gt;

&lt;p&gt;What I'm suggesting is not all that new--most of us do something similar already. I'm not advocating for a revolution. Rather,  I hope to empower teams with a mindset the transforms the rote, painful, and mundane into something powerful and efficient.&lt;/p&gt;

&lt;p&gt;Introducing: PRO Programming.&lt;/p&gt;




&lt;p&gt;In our early days as developers, we often find ourselves searching for information on &lt;em&gt;what&lt;/em&gt; to program. "Where is this type error coming from?" "How am I supposed to use this poorly documented library?" Or even, "What does this horrible JavaScript snippet actually do?" But as we mature and grow in our careers, we become more confident in writing code. &lt;/p&gt;

&lt;p&gt;At some point we transition from thinking about &lt;em&gt;what&lt;/em&gt; to program and begin asking &lt;em&gt;how&lt;/em&gt; we should program. We start to ask more challenging questions, like "How can multiple developers work together on the same task?" "How do I write code changes so as to have the lowest chance of causing a production outage?" "What's the most efficient way of running a software development team?" &lt;/p&gt;

&lt;p&gt;PRO Programming falls into this second category: it helps us know &lt;em&gt;how&lt;/em&gt; to program, not &lt;em&gt;what&lt;/em&gt; to program.&lt;/p&gt;




&lt;h1&gt;
  
  
  PRO
&lt;/h1&gt;

&lt;p&gt;P.R.O. (aka Pull Request Oriented) Programming is a way to prioritize developer time and quantize the delivery of code.&lt;/p&gt;

&lt;p&gt;The Pull Request is a developer's discrete unit of code.&lt;/p&gt;

&lt;p&gt;On a PRO team, each developer has the following 3 priorities:&lt;br&gt;
    1. Top Priority: "Deliver Excellent PRs"&lt;br&gt;
    2. Second Priority: "Unblock teammate PRs"&lt;br&gt;
    3. Third Priority: "Protect the high-quality codebase"&lt;/p&gt;




&lt;p&gt;Now let's go through and break down how each of these tenants works in practice. First off, what is a pull request?&lt;/p&gt;

&lt;h1&gt;
  
  
  The Pull Request is a developer's discrete unit of code.
&lt;/h1&gt;

&lt;p&gt;If you've developed using git in any kind of team environment, you probably understand why everyone pushing to the main branch is a bad idea. Pull Requests (aka Merge Requests or Code Reviews, depending on your stack) are the gatekeeper for the "official"  codebase, protecting against merge conflicts and silly bugs. I've yet to work on a team that doesn't use this model, where automated tests and other team members must approve your changes before they become part of the codebase.&lt;/p&gt;

&lt;p&gt;If a developer's job is to deliver a feature, fix a bug, or to some other end modify a technical asset, the way they do it is by making a code change. Under PRO, we no longer think of Pull Requests as a necessary evil, or even just as the process by which I get my code-change in. &lt;strong&gt;The Pull Request &lt;em&gt;is&lt;/em&gt; the deliverable.&lt;/strong&gt; (Or rather, a series of pull requests is the deliverable.) Importantly, the pull request includes more than just making a code change. &lt;/p&gt;

&lt;p&gt;Pull requests include:&lt;br&gt;
    1. The code change&lt;br&gt;
    2. The documentation&lt;br&gt;
    3. Comprehensive and documented testing steps&lt;br&gt;
    3. Evidence of all automated checks passing&lt;br&gt;
    4. Approval from code-owners&lt;br&gt;
    5. A successful merge and deployment&lt;/p&gt;

&lt;p&gt;When I pick up a task on a PRO team, I'm not finished with that task until the Pull Request is complete. As the author, I'm responsible to make sure tests are passing, I've received approval from code-owners, and, even after merging, that the deployment was successful. &lt;/p&gt;

&lt;p&gt;PRs may rely on one another. They must necessarily be the product of multiple developers (approvals). But at the end of the day, they are the fundamental, smallest quanta of code; and through the sum of them the codebase is built.&lt;/p&gt;

&lt;p&gt;As a Developer, this distillation of responsibilities into the PR unit allows for the following straightforward priorities:&lt;/p&gt;

&lt;h1&gt;
  
  
  Deliver Excellent PRs
&lt;/h1&gt;

&lt;p&gt;To be as effective as possible, a developer's primary area of focus should be the tasks they've been assigned. We don't want to get bogged down in a long review cycle, so we need to make PRs as easy to review as possible. The goal of a PR is to &lt;em&gt;convince&lt;/em&gt; other developers that this change will improve the codebase.&lt;/p&gt;

&lt;p&gt;Excellent PRs are:&lt;br&gt;
    1. As small and focused as possible&lt;br&gt;
    2. Well tested and documented&lt;br&gt;
    3. Free from bugs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small and focused PRs&lt;/strong&gt; are easier to develop, test, and review. Don't include any code changes that aren't directly involved in the task you're solving. Only solve one task at a time. Prioritize limiting the number of files and number of lines changed, to make it easier for reviewers. Smaller scope also makes it easier to debug and fix broken tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well tested and documented PRs&lt;/strong&gt; help reviewers now and the whole team in the future. You tested your changes; share how you tested. Explain why the change is happening and include a link to your issue tracker. That makes it easier for reviewers, and 6 months from now you'll be able to remember why you made the change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug-free PRs&lt;/strong&gt; seem like a no-brainer, but hear me out. The code review process is &lt;strong&gt;not&lt;/strong&gt; a time for teammates to catch your typos. Before submitting a PR, you should &lt;em&gt;code-review your own PR&lt;/em&gt;. Asking code-owners to catch simple bugs, syntax errors, and typos in your PR is a waste of their time and, frankly, is disrespectful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: When you ask others for PR reviews, you are presenting a finished product that is ready to be merged as soon as they approve. You should be 100% confident in the code &lt;em&gt;before you ask for reviews&lt;/em&gt;.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Unblock teammate PRs
&lt;/h1&gt;

&lt;p&gt;Few great projects are built in isolation... and still fewer projects that pay a good salary. As a team member, I am responsible for doing everything I can to unblock the PRs of my teammates. The most straightforward way of doing this is by submitting code reviews, but it's not the only way. Pair programming, team discussions, and shipping high-quality internal tooling are all important tasks as well. That said, here are a few tips on giving high-quality code reviews:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High quality code reviews are timely.&lt;/strong&gt; When a teammate requests a code review, a code-owner should submit a review within 1 work day. I find it's easiest to have a daily routine of reviewing all open PRs. This applies both for initial reviews and for re-reviews. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: It is the PR author's responsibility to request reviews. This can be tedious to request manually on every PR, but &lt;a href="https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team"&gt;Github allows you to auto-assign reviewers&lt;/a&gt;.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;High-quality code reviews have a certain tone to them.&lt;/strong&gt; Writing comments in a way that is respectful, humble, and, as often as possible, open-ended, can lead to more efficient collaboration and faster code changes. Defensiveness and arguing dramatically slow down the PR process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reviews should look at the PR holistically,&lt;/strong&gt; but also keep in mind the goal of limiting the scope of each PR. Don't ask for changes to things that aren't part of the original scope--opt instead for opening a tech-debt ticket. Call out changes that are too broad in scope or seem irrelevant. More small PRs are better than fewer big PRs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: If a developer repeatedly receives the same feedback on their PRs, they should discuss offline with senior team members how they can prioritize delivering excellent PRs.  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Protect the high-quality codebase
&lt;/h1&gt;

&lt;p&gt;The metaphor of PRs as a gatekeeper for the codebase was used earlier in this post, and it still stands. Each and every PR could be a trojan horse for debilitating technical debt. There's a balance to draw between delivering code quickly, unblocking teammates, and enforcing the high standards we have for our codebase.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: PR reviews around code quality, style, and functionality can be one of the most effective ways of sharing knowledge within the team. If you don't understand something, post a comment asking a question. If the PR author made some mistake, help them understand your team's best practices.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Be a stickler.&lt;/strong&gt; Read every line of code in a PR you approve. If you approve a PR with tech debt or a bug in it, you are just as much responsible as the author if the PR -- if not more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validate the functionality.&lt;/strong&gt; A comprehensive test suite can confirm a lot of things, but it often can't confirm that a PR does what it says it will do. Manually validating the changes in a test or local environment is the best way to confirm the quality of a PR.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automate the things humans are bad at&lt;/strong&gt;: formatting, import sorting, unit testing, etc. &lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode"&gt;IDE extensions&lt;/a&gt;, &lt;a href="https://typicode.github.io/husky/#/"&gt;git hooks&lt;/a&gt;, and &lt;a href="https://docs.github.com/en/actions/examples/using-scripts-to-test-your-code-on-a-runner"&gt;automated workflows&lt;/a&gt; are highly effective at this sort of task. You shouldn't ever need to post a PR comment asking someone to fix indentation or import order -- use tooling. Whether you use Github Actions, Circle CI, Travis, or something else, automated tests are vital for maintaining code quality.&lt;/p&gt;




&lt;p&gt;The principles and best practices of PRO Programming have empowered me and the teams I'm part of to write code quickly and effectively. I hope they give you clarity and level up your teams too.&lt;/p&gt;

&lt;p&gt;Kaeden Wile&lt;br&gt;
&lt;a href="https://wile.xyz"&gt;https://wile.xyz&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>productivity</category>
      <category>codereview</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Best Way To Build Big React Components 🤯</title>
      <dc:creator>Kaeden Wile</dc:creator>
      <pubDate>Mon, 31 Oct 2022 16:30:00 +0000</pubDate>
      <link>https://dev.to/devsatasurion/the-best-way-to-build-big-react-components-5295</link>
      <guid>https://dev.to/devsatasurion/the-best-way-to-build-big-react-components-5295</guid>
      <description>&lt;p&gt;With my current development team, I'm building a reusable react component library. Some of these components, like our &lt;code&gt;&amp;lt;Button/&amp;gt;&lt;/code&gt;, are fairly simple. I can easily expose all the Button's options and functionalities through its props. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"my-cool-button"&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I got clicked!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"secondary"&lt;/span&gt;
    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"large"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    Press Me!
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But even for such a simple example, we end up with quite a few lines of code. This problem of having too many props gets far more dramatic when we begin looking at complex "composed-components" which are made up of many different pieces.&lt;/p&gt;

&lt;p&gt;Take, for example, the &lt;code&gt;&amp;lt;Modal/&amp;gt;&lt;/code&gt;. Our design includes: a header with multiple configurations including primary title, subtitle, a hero image, and/or a close button; a call-to-action footer allowing a variable number of buttons in different layouts; and a primary content section. In addition to the standard props of each Text, Image, and Button component for all of these items, our consumers have asked for the ability to do additional layout and style customization.&lt;/p&gt;

&lt;p&gt;That's a lot of props!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/LKTTAzGboJGzC/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/LKTTAzGboJGzC/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There has to be a better way to do this -- and there is! This blog post aims to cover the solution that our team has taken in answering the following question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can we build "composed-components" to provide default styles, customizability, and a clean API?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And how to do you do it all in TypeScript? 😉&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;First, let's dig a little deeper into exactly what we want to accomplish.&lt;/p&gt;

&lt;p&gt;To start consuming our library, all a team has to do is &lt;code&gt;yarn add "our-react-library"&lt;/code&gt; and &lt;code&gt;import { Component } from "our-react-library";&lt;/code&gt;. Most developers won't ever look at our code; instead, they'll browse component documentation in our interactive &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt;. As we prioritize ease-of-use, we want all of our components to look great out of the box. &lt;/p&gt;

&lt;p&gt;In addition to a React library, our team also publishes global design standards and a design component library for use across the company. However, there are often edge cases or situations where a team wants to make tweaks or changes. Those are easy enough to approve in design, but often require us to expose many layers of classNames (eww) or add even more props in React. Our solution for the modal needs to support multiple variants, but avoid introducing an ungainly number of props.&lt;/p&gt;

&lt;p&gt;Finally, we always want to provide a great developer experience -- that means delivering an API that allows our users to write clean, concise code. Using long component names like &lt;code&gt;ModalPrimaryTitle&lt;/code&gt; or polluting our package namespace with generic &lt;code&gt;PrimaryTitle&lt;/code&gt; aren't acceptable solutions. Neither is using nested objects as props to hide config or options, which is difficult to document and doesn't work well with Storybook. And of course, we want to build TypeScript-first 🦸‍♂️.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/HjPbLbmep2aJO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/HjPbLbmep2aJO/giphy.gif" width="500" height="331"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Process
&lt;/h2&gt;

&lt;p&gt;I started this journey with our &lt;em&gt;old modal&lt;/em&gt;, which had a lot of props and still was very challenging to customize. And, the new design our team came up with included more options and flexibility than before. &lt;/p&gt;

&lt;p&gt;We knew very early on that we wanted to avoid any solution that was too prop-heavy, which pushed us towards exposing multiple elements to the user. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Main Title&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Subtitle&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;bodyContent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;CTA 1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One early suggestion was to update our code-snippet generator in Storybook to return raw HTML that looked like a modal, so we didn't even &lt;em&gt;need&lt;/em&gt; to make a component. But, that solution would detach our consumers code from our library, rendering us unable to push new features or fixes without them updating their code. It would also be difficult to style, because we used &lt;a href="https://styled-components.com/"&gt;styled-components&lt;/a&gt; instead of relying on class names or bundling a stylesheet.&lt;/p&gt;

&lt;p&gt;Still, we liked the direction we were headed in. The next suggestion was to provide a simple Modal that acted as a container, allowing users to pass our other existing components into it. But the layout was too complex to tackle without additional wrappers for the header and footer, so we added those which gave us greater customizability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ModalHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ModalContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ModalFooter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Button&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;our-react-library&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ModalHeader&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Main Title&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Subtitle&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Subtitle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ModalHeader&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ModalContent&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;bodyContent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ModalContent&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ModalFooter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; 
            &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clicked!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            Go forth and prosper
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ModalFooter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is looking better, but it still had a few issues. Namely, we were (1) asking our users to manually apply default styles to the title, subtitle, call to action buttons, and more; and (2) we were polluting our namespace with lots of Modal-specific components. The solution to the 1st problem is easy, but it exasperates the second problem: introduce a &lt;code&gt;ModalTitle&lt;/code&gt; component, a &lt;code&gt;ModalSubtitle&lt;/code&gt; component, a &lt;code&gt;ModalCTA&lt;/code&gt; component, etc. Now if we can just find a simple place to put all those pesky components, we would have a pretty good solution!&lt;/p&gt;

&lt;p&gt;What if we put the sub-components on &lt;code&gt;Modal&lt;/code&gt; itself?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/VStxBrCyssRPO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/VStxBrCyssRPO/giphy.gif" width="500" height="447"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;Below is the API we decided on. Every component matches our design out of the box, but also allows for customization using CSS classes or styled-components. Adding or removing full sections or adding custom components anywhere in the flow is fully supported. The API is clean and concise and &lt;del&gt;most importantly&lt;/del&gt; the namespace is immaculate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Modal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;our-react-library&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Main Title&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Subtitle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Subtitle&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Subtitle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        This is my body content
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CTA&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CTA&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I know what you're thinking, "That looks great, but how can you make that work in TypeScript?" &lt;/p&gt;

&lt;p&gt;I'm glad you asked.&lt;/p&gt;

&lt;p&gt;We use React functional components to build most of our library, so inside the library, our files look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jumbo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StyledButton&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;StyledButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript, however, does not allow us to assign additional props to a &lt;strong&gt;const&lt;/strong&gt;, especially after we export it. This poses a problem. Somehow we have to attach props to what is essentially a function without writing a ton of duplicate code. Another pesky problem is setting correct displayNames for React DevTools and, more importantly, our Storybook code generator.&lt;/p&gt;

&lt;p&gt;Here's the magic function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Attaches subcomponents to a parent component for use in
 * composed components. Example:
 * 
 * &amp;lt;Parent&amp;gt;
 *    &amp;lt;Parent.Title&amp;gt;abc&amp;lt;/Parent.Title&amp;gt;
 *    &amp;lt;Parent.Body prop1="foobar"/&amp;gt;
 * &amp;lt;/Parent&amp;gt;
 * 
 *
 * This function also sets displayname on the parent component
 * and all children component, and has the correct return type
 * for typescript.
 *
 * @param displayName topLevelComponent's displayName
 * @param topLevelComponent the parent element of the composed component
 * @param otherComponents an object of child components (keys are the names of the child components)
 * @returns the top level component with otherComponents as static properties
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;attachSubComponents&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;topLevelComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;otherComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;topLevelComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;otherComponents&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topLevelComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;otherComponents&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code lives in a util file and can easily be imported within our library any time we want to use sub-components. That allows us to write a modal component file that is very easy on the eyes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Modal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;attachSubComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Modal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ModalProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Subtitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HeroImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://i.giphy.com/media/3LM2UW56Eh2TK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3LM2UW56Eh2TK/giphy.gif" width="500" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And best of all, it's a great solution for all of our users!&lt;/p&gt;




&lt;p&gt;Thanks for reading! I hope this technique for creating clean composed components in React will level-up you and your team.&lt;/p&gt;

&lt;p&gt;Kaeden Wile&lt;br&gt;
&lt;a href="https://wile.xyz"&gt;wile.xyz&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
