<?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>Forem: Nayaab Khan</title>
    <description>The latest articles on Forem by Nayaab Khan (@nayaabkhan).</description>
    <link>https://forem.com/nayaabkhan</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%2F158630%2Fb45ade28-4b2c-4264-972f-6ac75a63ab16.jpeg</url>
      <title>Forem: Nayaab Khan</title>
      <link>https://forem.com/nayaabkhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nayaabkhan"/>
    <language>en</language>
    <item>
      <title>Swift-like React: Can We? Should We?</title>
      <dc:creator>Nayaab Khan</dc:creator>
      <pubDate>Tue, 12 Apr 2022 05:04:05 +0000</pubDate>
      <link>https://forem.com/nayaabkhan/swift-like-react-can-we-should-we-3571</link>
      <guid>https://forem.com/nayaabkhan/swift-like-react-can-we-should-we-3571</guid>
      <description>&lt;p&gt;⚠️ This is just an experiment that is clearly not meant for production.&lt;/p&gt;

&lt;p&gt;After playing with SwiftUI for a few days I was impressed by its syntax and&lt;br&gt;
wanted to see if I can write React this way. Possibly an absurd thought, but why not.&lt;/p&gt;

&lt;p&gt;It turned out like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SandwichItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sandwich&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Sandwich&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;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sandwich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnailName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rounded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="nx"&gt;VStack&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;sandwich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h2&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;variant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sandwich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ingredientCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ingredients`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&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;variant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subtitle&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="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&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;spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sandwiches&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SandwichItem&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To compare, this is what it would look like in &lt;strong&gt;JSX&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SandwichItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;sandwich&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;SandwichItemProps&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HStack&lt;/span&gt; &lt;span class="na"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt; &lt;span class="na"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"medium"&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;Image&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sandwich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnailName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&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;VStack&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="s"&gt;"h2"&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;"title"&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;sandwich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;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="s"&gt;"small"&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;"subtitle"&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;sandwich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ingredientCount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; ingredients
      &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;VStack&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;HStack&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;root&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;List&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sandwiches&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;renderItem&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="nx"&gt;sandwich&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SandwichItem&lt;/span&gt; &lt;span class="na"&gt;sandwich&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sandwich&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="p"&gt;/&amp;gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Syntax is subjective. I’m sure some of you will prefer one over the other for&lt;br&gt;
various reasons. Besides personal preferences, a few things do stand out with this syntax:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is a composition of &lt;strong&gt;function&lt;/strong&gt; calls, nothing on top of JavaScript.&lt;/li&gt;
&lt;li&gt;Components take required &lt;strong&gt;inputs&lt;/strong&gt; as arguments.&lt;/li&gt;
&lt;li&gt;Modifications are done through chained-functions, called &lt;strong&gt;modifiers&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I particularly like the separation between inputs and modifiers. In JSX, both would be &lt;strong&gt;props&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Professional photographer&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;variant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subtitle&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;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;muted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inputs could be primitive types like a &lt;code&gt;string&lt;/code&gt; or object types like an array of components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;VStack&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your Messages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; messages`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subtitle&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Polymorphic, Chain-able Modifiers
&lt;/h2&gt;

&lt;p&gt;Modifiers are just functions. What makes them interesting is that they can be shared by multiple components and implemented independently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&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;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;muted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&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;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;muted&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;align&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&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;spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gutter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;AutoGrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&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;minWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see a couple of &lt;strong&gt;modifier&lt;/strong&gt; implementations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Colorable.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Colorable&lt;/span&gt; &lt;span class="kd"&gt;extends&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&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;T&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt; &lt;span class="na"&gt;Colorable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;(this: T, color: string) =&amp;gt; T
}

export function color&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt; &lt;span class="na"&gt;Colorable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;(this: T, color: string) &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&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;this&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;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&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;this&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;style&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="k"&gt;this&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fontable.ts&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Font&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;fontVariants&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Fontable&lt;/span&gt; &lt;span class="kd"&gt;extends&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font&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;T&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt; &lt;span class="na"&gt;Fontable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;(this: T, font: Font) =&amp;gt; T
}

export function font&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt; &lt;span class="na"&gt;Fontable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;(this: T, font: Font) &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&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;this&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;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fontVariants&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&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;this&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;style&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="k"&gt;this&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A component can now implement these traits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Text.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fontable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;font&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="s1"&gt;@modifiers/Fontable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Colorable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&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="s1"&gt;@modifiers/Colorable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&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;text&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;Fontable&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Colorable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&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;text&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;span&lt;/span&gt;&lt;span class="p"&gt;&amp;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;...&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;color&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;And now the component could be invoked using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, world!&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;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&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;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hotpink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A component can implement multiple modifiers which can be chained. Also, a modifier could be implemented by many components, making them polymorphic.&lt;/p&gt;

&lt;p&gt;ℹ️ You can see more components and modifiers at &lt;a href="https://github.com/nayaabkhan/swift-react"&gt;https://github.com/nayaabkhan/swift-react&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems
&lt;/h2&gt;

&lt;p&gt;There are a few things I noticed that don’t work. Very likely, there are be more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;useContext&lt;/strong&gt; doesn’t work. But &lt;code&gt;&amp;lt;Context.Consumer /&amp;gt;&lt;/code&gt; works fine.&lt;/li&gt;
&lt;li&gt;React Developer Tools doesn’t show the components in the inspector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I suspect this is because React cannot identify our components as we don’t use either JSX or &lt;code&gt;createElement&lt;/code&gt; when creating them. If you find more problems, please report them in the comments. And if you know work-arounds, they’re very welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  But, Why?
&lt;/h2&gt;

&lt;p&gt;Finally, let’s address the elephant in the room. Why all this trouble?&lt;/p&gt;

&lt;p&gt;Maybe I’m &lt;a href="https://thedecisionlab.com/biases/bikeshedding"&gt;bike shedding&lt;/a&gt;. But experimenting and sharing with everyone is the only way to know. Maybe this resonates with others and becomes a thing. Or gets buried in the rubble of bad ideas. Who knows, but it was worth it for the fun I had.&lt;/p&gt;

&lt;p&gt;I had a great time authoring React this way. Maybe this kind of syntactic change can have unexpected, but useful impact.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow component API designers to be very specific of expected input types. For instance, &lt;code&gt;Text&lt;/code&gt; only accepts strings or markdown instead of any kind of &lt;strong&gt;ReactNode&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Make it easier to share the common API along with its implementation using modifiers.&lt;/li&gt;
&lt;li&gt;Introduce higher-level constructs like &lt;a href="https://github.com/nayaabkhan/swift-react/blob/main/library/components/layout/List.tsx#L8"&gt;Identifiers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Swap React with something else without any impact on the users of the library.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In closing, I hope you &lt;a href="https://codesandbox.io/s/swifty-react-5vvpgi"&gt;try it out on CodeSandbox&lt;/a&gt;, have fun, and share your thoughts.&lt;/p&gt;

&lt;p&gt;Until next time 👋.&lt;/p&gt;

</description>
      <category>react</category>
      <category>swift</category>
    </item>
    <item>
      <title>Benefits Of Categorising Components By Use-Case</title>
      <dc:creator>Nayaab Khan</dc:creator>
      <pubDate>Mon, 28 Mar 2022 11:08:20 +0000</pubDate>
      <link>https://forem.com/nayaabkhan/benefits-of-categorising-components-by-use-case-33g</link>
      <guid>https://forem.com/nayaabkhan/benefits-of-categorising-components-by-use-case-33g</guid>
      <description>&lt;p&gt;Organising things feels good. If you have a design system, you might have organised the components with categories.&lt;/p&gt;

&lt;p&gt;Besides cleaner organisation, is there something that we can get out of good categorisation?&lt;/p&gt;

&lt;p&gt;It turns out there's a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet the Categories
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4htva0r81fkrt4xr29mc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4htva0r81fkrt4xr29mc.png" alt="Visualisation of different categories of components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the years, these are the categories I've come up. This categorisation is based on use case. Almost all components fall into one of these.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Structural.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the visible or invisible components that provide structure to your app. Examples include &lt;code&gt;Stack&lt;/code&gt;, &lt;code&gt;Grid&lt;/code&gt;, and &lt;code&gt;Columns&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Informational.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These components are used to display information to the users. They may display this information using text, icons, colors, and so on. Examples include &lt;code&gt;Badge&lt;/code&gt; and &lt;code&gt;Tooltip&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Input.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These components are used to get information from the users and often used inside a form. Examples include &lt;code&gt;TextField&lt;/code&gt;, &lt;code&gt;AutoComplete&lt;/code&gt;, &lt;code&gt;CheckboxList&lt;/code&gt;, and &lt;code&gt;Select&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Action.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These components are used to perform an action immediately. Examples include &lt;code&gt;Button&lt;/code&gt; and &lt;code&gt;Menu&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Feedback.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These components are used to provide a feedback as a response. Examples include &lt;code&gt;Toast&lt;/code&gt; and &lt;code&gt;Progress&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Navigational.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These components are used to provide navigational aid to the users. Examples include &lt;code&gt;Link&lt;/code&gt;, &lt;code&gt;Breadcrumb&lt;/code&gt;, and &lt;code&gt;Pagination&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's go through the benefits of this kind of categorisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefit 1: Clear Distinction
&lt;/h2&gt;

&lt;p&gt;Often we find components used in a way they're not meant to be. A very common one is the use of dropdowns as menu of actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3wxte7r6f6duhih4kau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3wxte7r6f6duhih4kau.png" alt="Difference between a select and menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depending on your designs, they may even look very similar. But functionally, they are different, and the astute among you would already know it.&lt;/p&gt;

&lt;p&gt;If you try to sort them in one of the categories we saw before, they start making sense. One provides a menu to &lt;strong&gt;input&lt;/strong&gt; a selection, but not act immediately upon it, while the other provides a menu for &lt;strong&gt;actions&lt;/strong&gt; that happens immediately on selection.&lt;/p&gt;

&lt;p&gt;Naming is hard and cannot be decoupled from opinions. In the wild, often they're called &lt;strong&gt;select&lt;/strong&gt; and &lt;strong&gt;menu&lt;/strong&gt; respectively. If you're looking to get insipred, the &lt;a href="https://open-ui.org/research/component-matrix" rel="noopener noreferrer"&gt;Component Name Matrix&lt;/a&gt; is a great place to start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp571pzb6fe1xqwopa9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp571pzb6fe1xqwopa9j.png" alt="A link that looks like a button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another common mistake is using a button that looks like a link to &lt;strong&gt;navigate&lt;/strong&gt; to another page. Or using a link that looks like a button to perform an &lt;strong&gt;action&lt;/strong&gt;. While it is okay to have such variants, categorising them thoughtfully can help you avoid misuse and help you write clear do's and dont's.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefit 2: Precise Semantics
&lt;/h2&gt;

&lt;p&gt;A lot of components that fall in the same category share semantic traits. Informational components like &lt;strong&gt;Badge&lt;/strong&gt; and &lt;strong&gt;Alert&lt;/strong&gt; display part of their information using colors, often called the tone of the information they're displaying. Similarly, actions share the nature of the action being performed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fampmu8m5vkkbijhhftkk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fampmu8m5vkkbijhhftkk.png" alt="Using tonality instead of palette colors"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Once you have a category, you can easily find the components that share the same semantic traits and create semantic tokens for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefit 3: Correct Features By Common Traits
&lt;/h2&gt;

&lt;p&gt;Similar to how the category can surface the semantics of the components, it also helps in aiding the API design and features of a component. More precisely, what should and should not be in the API.&lt;/p&gt;

&lt;p&gt;Going back to the example of &lt;strong&gt;LinkButton&lt;/strong&gt; and &lt;strong&gt;ButtonLink&lt;/strong&gt;. The former should support actional properties like &lt;code&gt;onClick&lt;/code&gt; while the later should support navigational properties like &lt;code&gt;href&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This can help you avoid common pitfalls found on the web. Like in this case, using a button as a link and vice-versa. Have you even tried opening a link in a new tab just to find out that you're looking at a button disguised as a link? It is a frustrating experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;I find this topic very interesting and certainly intend to write more in-depth posts on it. There's so much more to uncover.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fira1vpd80j9ajtyhfagf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fira1vpd80j9ajtyhfagf.png" alt="Common traits of various choice inputs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, the input components &lt;strong&gt;Select&lt;/strong&gt;, &lt;strong&gt;CheckboxList&lt;/strong&gt;, and &lt;strong&gt;RadioList&lt;/strong&gt; are all &lt;em&gt;choice&lt;/em&gt; components and could be used interchangeably depending on the space available, amount of choices, and ability to select multiple choices.&lt;/p&gt;

&lt;p&gt;Once you start seeing the patterns, interesting facts emerge. And I hope to keep sharing them as I discover them.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>react</category>
      <category>design</category>
      <category>ux</category>
    </item>
    <item>
      <title>Essential Layout Components For Your Design System</title>
      <dc:creator>Nayaab Khan</dc:creator>
      <pubDate>Sun, 20 Mar 2022 09:25:20 +0000</pubDate>
      <link>https://forem.com/nayaabkhan/essential-layout-components-for-your-design-system-26p</link>
      <guid>https://forem.com/nayaabkhan/essential-layout-components-for-your-design-system-26p</guid>
      <description>&lt;p&gt;If your app uses a component based library/framework like React, Vue, or Svelte, leverage the power of re-usable layout components. Go a level higher in the abstraction ladder.&lt;/p&gt;

&lt;p&gt;In this article, I'll show you a system of solid layout components with their features and API. These are common &lt;em&gt;and&lt;/em&gt; versatile enough to be used for most products and teams. I promise you once you meet these layout, you'll start seeing them everywhere.&lt;/p&gt;

&lt;p&gt;In the end, there's a CodeSandbox that uses all these components to build a real use case: a responsive listing of product cards.&lt;/p&gt;




&lt;p&gt;I'd like to credit upfront the excellent &lt;a href="https://seek-oss.github.io/braid-design-system/" rel="noopener noreferrer"&gt;Braid Design System&lt;/a&gt; by &lt;a href="https://github.com/seek-oss" rel="noopener noreferrer"&gt;Seek-OSS&lt;/a&gt;. All the components are heavily inspired from it. You should definitely check it out.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Stack
&lt;/h2&gt;

&lt;p&gt;The most common way to layout your interface elements is a vertical &lt;strong&gt;Stack&lt;/strong&gt;. They are everywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="na"&gt;space&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;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="si"&gt;}&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="si"&gt;}&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="si"&gt;}&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;Stack&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0fcqdq30zvt0kuo67lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0fcqdq30zvt0kuo67lu.png" alt="A vertical stack with 3 placeholders."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  API
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The element used for the root node.&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// Feel free to change these as per your uses&lt;/span&gt;
  &lt;span class="c1"&gt;// Defines the spacing between the items.&lt;/span&gt;
  &lt;span class="nx"&gt;space&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// All of your spacing tokens&lt;/span&gt;
  &lt;span class="c1"&gt;// Sets the horizontal alignment of the items.&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stretch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// The items to layout in the stack.&lt;/span&gt;
  &lt;span class="na"&gt;children&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;ReactNode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2. Columns and Column
&lt;/h2&gt;

&lt;p&gt;The next most common layout is a single row of &lt;strong&gt;Columns&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Columns&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"medium"&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;Column&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Column&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;Column&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Column&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;Columns&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foriwwkes35yktd3bvju8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foriwwkes35yktd3bvju8.png" alt="Two columns with placeholders side-by-side"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Collapsing
&lt;/h3&gt;

&lt;p&gt;A common need is to collapse the columns to a stack below a certain size. This can be implemented using &lt;code&gt;ResizeObserver&lt;/code&gt; (and hopefully soon using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries" rel="noopener noreferrer"&gt;&lt;strong&gt;Container Queries&lt;/strong&gt;&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqj4w7yh2e7o1y8wj1l2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqj4w7yh2e7o1y8wj1l2.gif" alt="A video of columns collapsing to a stack below certain size."&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Alignments
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Columns&lt;/strong&gt; support alignments in both directions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1u7h1a65mdddava4vqp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1u7h1a65mdddava4vqp1.png" alt="Columns with all three possible vertical alignments: start, center, and end"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ee4nzn7z7go5bgbxtbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ee4nzn7z7go5bgbxtbb.png" alt="Columns with all three possible horizontal alignments: start, center, and end"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Individual column sizing
&lt;/h3&gt;

&lt;p&gt;We have a &lt;strong&gt;Column&lt;/strong&gt; component to wrap each column that provides ability to size itself in different implicit and explicit sizes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"medium"&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;Columns&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xsmall"&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;Column&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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;Column&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;Column&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fluid"&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;Column&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;Columns&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;Columns&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xsmall"&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;Column&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1/5"&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1/5"&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;Column&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;Column&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fluid"&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;Column&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;Columns&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;Columns&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xsmall"&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;Column&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1/4"&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1/4"&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;Column&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;Column&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fluid"&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;Column&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;Columns&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;Columns&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xsmall"&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;Column&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1/3"&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1/3"&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;Column&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;Column&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;Placeholder&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fluid"&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;Column&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;Columns&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;Stack&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5goopa38da3an0ce3rbj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5goopa38da3an0ce3rbj.png" alt="Multiple rows of columns with different implicit and explicit sizes."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  API
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ColumnsProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The element used for the root node.&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Defines the spacing between the items.&lt;/span&gt;
  &lt;span class="nx"&gt;space&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// All of your spacing tokens&lt;/span&gt;
  &lt;span class="c1"&gt;// Collapse items to a stack below this size.&lt;/span&gt;
  &lt;span class="nx"&gt;collapseBelow&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="c1"&gt;// Sets the horizontal alignment of the items.&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stretch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Sets the vertical alignment of the items.&lt;/span&gt;
  &lt;span class="nx"&gt;alignY&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// The columns.&lt;/span&gt;
  &lt;span class="na"&gt;children&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;ReactNode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Cluster
&lt;/h2&gt;

&lt;p&gt;This is very similar to &lt;strong&gt;Columns&lt;/strong&gt; but it allows the items to wrap if needed. Most commonly used to show a list of badges.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Cluster&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"small"&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;Tag&lt;/span&gt; &lt;span class="na"&gt;tone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"positive"&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"subtle"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Confirmed"&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"IconCalendar"&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;Tag&lt;/span&gt; &lt;span class="na"&gt;tone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cautional"&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"subtle"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Pending"&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"IconApple"&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;Tag&lt;/span&gt; &lt;span class="na"&gt;tone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"informational"&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"subtle"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Hired"&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"IconRemote"&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;Tag&lt;/span&gt; &lt;span class="na"&gt;tone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"neutral"&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"subtle"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Refunded"&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"IconLike"&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;Tag&lt;/span&gt; &lt;span class="na"&gt;tone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"promotional"&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"subtle"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"New"&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"IconHeart"&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;Cluster&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk612s6zi9zniv9o6frpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk612s6zi9zniv9o6frpl.png" alt="A list of badges within a cluster that wrap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clusters&lt;/strong&gt; also support collapsing and alignments in both directions just like &lt;strong&gt;Columns&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  API
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ClusterProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The element used for the root node.&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Defines the spacing between the items.&lt;/span&gt;
  &lt;span class="nx"&gt;space&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Collapse items to a stack below this size.&lt;/span&gt;
  &lt;span class="nx"&gt;collapseBelow&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="c1"&gt;// Sets the horizontal alignment of the items.&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Sets the vertical alignment of the items.&lt;/span&gt;
  &lt;span class="nx"&gt;alignY&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// The items to lay out in this cluster.&lt;/span&gt;
  &lt;span class="na"&gt;children&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;ReactNode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  AutoGrid
&lt;/h2&gt;

&lt;p&gt;Auto grid is basically a component abstraction for &lt;a href="https://web.dev/patterns/layout/repeat-auto-minmax/" rel="noopener noreferrer"&gt;&lt;strong&gt;repeat-auto-minmax&lt;/strong&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AutoGrid&lt;/span&gt; &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"medium"&lt;/span&gt; &lt;span class="na"&gt;minItemWidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="si"&gt;}&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;Placeholder&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;Placeholder&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;Placeholder&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;Placeholder&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;Placeholder&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;Placeholder&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;Placeholder&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;AutoGrid&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqa4yk7vzk0aqwn486th.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqa4yk7vzk0aqwn486th.gif" alt="An AutoGrid that responsively lays out its items."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  API
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AutoGridProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The element used for the root node.&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;section&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// The minimum width for items to shrink to before the grid starts wrapping to make space.&lt;/span&gt;
  &lt;span class="na"&gt;minItemWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="c1"&gt;// The gap between the items or the column gap if spaceY is present.&lt;/span&gt;
  &lt;span class="nx"&gt;space&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// The row gap between the items.&lt;/span&gt;
  &lt;span class="nx"&gt;spaceY&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Items inside the AutoGrid.&lt;/span&gt;
  &lt;span class="na"&gt;children&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;ReactNode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Layout Components In Action
&lt;/h2&gt;

&lt;p&gt;Now that we've seen the components. Let's see them in action.&lt;/p&gt;

&lt;p&gt;I've used NextJS and Vanilla-Extract to style the components. But you can, of course, use any solution down to plain CSS.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://codesandbox.io/p/sandbox/jolly-darkness-d7v17x?embed=1" rel="noopener noreferrer"&gt;
      codesandbox.io
    &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;Let's appreciate all the functionality going on in the demo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We have a sidebar that collapses on smaller screens.&lt;/li&gt;
&lt;li&gt;The product grid is responsive&lt;/li&gt;
&lt;li&gt;The card itself has two layouts: horizontal and vertical and it responds based on available space.&lt;/li&gt;
&lt;li&gt;The badges inside the &lt;strong&gt;Cluster can wrap if required&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The buttons also respond to available size and collapse if too narrow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All this with just a system of well thought out components. Totally declarative, readable, and re-usable.&lt;/p&gt;

&lt;p&gt;And we've only covered the most basic common denominator of layout components. You can do much more depending on your use case. Like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a &lt;strong&gt;Spacer&lt;/strong&gt; component to create flexible space between &lt;strong&gt;Stack&lt;/strong&gt; or &lt;strong&gt;Column&lt;/strong&gt; items.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;prop&lt;/strong&gt; to make column items fill the available space inside the &lt;strong&gt;Column&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;FixedGrid&lt;/strong&gt; with explicit column and row counts to create a rigid grid.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I hope that you find this system inspiring and already have ideas to build on top of this. Feel free to fork the sandbox or the repo to use it as a starting point.&lt;/p&gt;

&lt;p&gt;I'll see you next time! 👋🏻&lt;/p&gt;

</description>
      <category>design</category>
      <category>react</category>
      <category>css</category>
    </item>
    <item>
      <title>Vanilla-Extract &amp; Stitches: A Comparison</title>
      <dc:creator>Nayaab Khan</dc:creator>
      <pubDate>Mon, 14 Mar 2022 08:37:16 +0000</pubDate>
      <link>https://forem.com/nayaabkhan/vanilla-extract-stitches-a-comparison-58c2</link>
      <guid>https://forem.com/nayaabkhan/vanilla-extract-stitches-a-comparison-58c2</guid>
      <description>&lt;p&gt;&lt;strong&gt;How do you pick between these two great options?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both focus on providing the best-in-class developer experience with minimal runtime.&lt;/p&gt;

&lt;p&gt;So, how do they compare? If you had to pick one which one would you pick &lt;strong&gt;given your context&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Let’s get the similarities out of the way first.&lt;/p&gt;




&lt;h2&gt;
  
  
  Similarities
&lt;/h2&gt;

&lt;p&gt;Both libraries support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type-safe API:&lt;/strong&gt; Both have a typed library API to assist the developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token-based theming:&lt;/strong&gt; Tokens are the building block of a system, both libraries provide a first-class support for typed tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variants:&lt;/strong&gt; Both libraries provide an API to add variants to a component.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS custom properties:&lt;/strong&gt; Both libraries convert theme tokens to CSS custom properties. They also provide API for user-defined CSS custom properties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a gist, they provide a very comparable developer experience. So what’s different?&lt;/p&gt;




&lt;h2&gt;
  
  
  Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Library Runtime
&lt;/h3&gt;

&lt;p&gt;This is the amount of JavaScript the libraries ship by default.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches&lt;/strong&gt; claims a “near-zero runtime.” Bundlephobia reports 6 kB gzipped which is quite slim.&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract&lt;/strong&gt; runs at build-time. So no runtime is added. If you use the &lt;code&gt;@vanilla-extract/dynamic&lt;/code&gt; package, it’d add &lt;a href="https://bundlephobia.com/package/@vanilla-extract/dynamic@2.0.2" rel="noopener noreferrer"&gt;718 bytes&lt;/a&gt; to your bundle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Userland Runtime
&lt;/h3&gt;

&lt;p&gt;This is the amount of runtime added due to the user-land code.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches:&lt;/strong&gt; User-land runtime code scales linearly as CSS is bundled in JavaScript. Theoretically, this will be as big as the design system itself.&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract:&lt;/strong&gt; None if you use the &lt;a href="https://vanilla-extract.style/documentation/styling-api/" rel="noopener noreferrer"&gt;styling API&lt;/a&gt; only. If you use the &lt;a href="https://vanilla-extract.style/documentation/sprinkles-api/" rel="noopener noreferrer"&gt;Sprinkles API&lt;/a&gt; for generating Atoms, it generates a script to look-up the classnames which doesn’t impact rendering performance. This script grows along with the amount of atoms generated which usually stop growing over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering Performance
&lt;/h3&gt;

&lt;p&gt;The way in which CSS is delivered to the users can have an impact on several metrics like &lt;strong&gt;FCP&lt;/strong&gt; and &lt;strong&gt;TTI&lt;/strong&gt; of the first page and subsequent pages.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Because the styles are rendered inline, &lt;strong&gt;FCP&lt;/strong&gt; happens much earlier for the first page load.&lt;/p&gt;

&lt;p&gt;New styles are injected dynamically which invalidates a lot of the work that has already been done by the browser, no matter how little CSS was injected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TTI&lt;/strong&gt; happens later because a significant time of main thread is spent on &lt;a href="https://web.dev/mainthread-work-breakdown/#how-the-lighthouse-main-thread-work-audit-fails" rel="noopener noreferrer"&gt;“Style &amp;amp; Layout”&lt;/a&gt;. The &lt;a href="https://crystallize.com/blog/frontend-performance-react-ssr-and-the-uncanny-valley" rel="noopener noreferrer"&gt;“uncanny valley”&lt;/a&gt; is quite wide.&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because CSS files are generated statically and are &lt;code&gt;&amp;lt;link /&amp;gt;&lt;/code&gt;ed and requested separately, &lt;strong&gt;&lt;a href="https://web.dev/fcp/" rel="noopener noreferrer"&gt;FCP&lt;/a&gt;&lt;/strong&gt; happens later in comparison to Stitches for the first page load.&lt;/p&gt;

&lt;p&gt;Subsequent renders are fast as the common CSS (atoms) are cached on the first request. Only new styles are fetched, if any.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://web.dev/tti/" rel="noopener noreferrer"&gt;TTI&lt;/a&gt;&lt;/strong&gt; isn’t delayed because the main thread isn’t busy with &lt;a href="https://web.dev/mainthread-work-breakdown/#how-the-lighthouse-main-thread-work-audit-fails" rel="noopener noreferrer"&gt;“Style &amp;amp; Layout.”&lt;/a&gt; The “uncanny valley” is narrow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token typing and mapping
&lt;/h3&gt;

&lt;p&gt;This is whether the tokens themselves are strictly typed and any deviations from token usage are reported.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches&lt;/strong&gt; &lt;a href="https://stitches.dev/docs/tokens#property-mapping" rel="noopener noreferrer"&gt;sensibly and conveniently maps the tokens&lt;/a&gt; to the CSS properties. But they are not typed to be limited to the tokens only. Though, there is a &lt;a href="https://stitches.dev/docs/typescript#stricter-experience" rel="noopener noreferrer"&gt;provision&lt;/a&gt; to have a stricter experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthgyq4qra2d3ajj7chhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthgyq4qra2d3ajj7chhg.png" alt="You may use any string and the type-checker won’t complain."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract&lt;/strong&gt; doesn’t give you any mappings if you use the &lt;a href="https://vanilla-extract.style/documentation/styling-api/" rel="noopener noreferrer"&gt;styling API&lt;/a&gt;. Though, if you use  &lt;a href="https://vanilla-extract.style/documentation/sprinkles-api/" rel="noopener noreferrer"&gt;Sprinkles&lt;/a&gt; (for atoms), which you should, you can do your own mapping. The CSS properties are strictly limited to the tokens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7sy205tjo7d7xd6jwhm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7sy205tjo7d7xd6jwhm.png" alt="CSS Properties are strictly typed to the tokens when using Sprinkles"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Component Debug-ability (React Developer Tools)
&lt;/h3&gt;

&lt;p&gt;The library should not come in the way of debug-ability using Devtools.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches:&lt;/strong&gt; Using &lt;code&gt;styled&lt;/code&gt; API causes component names to be mangled, also you cannot view component source code if you use &lt;code&gt;styled&lt;/code&gt;.  However, using the &lt;a href="https://stitches.dev/docs/api#css" rel="noopener noreferrer"&gt;css&lt;/a&gt; function doesn’t have any of these problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zzujl3hawvzrysjhr3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zzujl3hawvzrysjhr3y.png" alt="When using the styled API, the components names are lost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract:&lt;/strong&gt; No negative impact on React Developer Tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhdmjg2011k1nx63atzb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhdmjg2011k1nx63atzb.png" alt="Component names are preserved with Vanilla-Extract"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;How thorough and thoughtful the library documentation is.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches&lt;/strong&gt; comes with an excellent documentation. Even the, otherwise usually neglected, &lt;a href="https://stitches.dev/docs/typescript" rel="noopener noreferrer"&gt;TypeScript experience&lt;/a&gt; is given full attention.&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract&lt;/strong&gt; has terse and &lt;em&gt;API like&lt;/em&gt; docs. They’re difficult to get started with and require a lot of jumping around.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Tokens and Names
&lt;/h3&gt;

&lt;p&gt;Does the libary allow custom tokens and token names (e.g., &lt;code&gt;spacings&lt;/code&gt; instead of &lt;code&gt;space&lt;/code&gt;) as per the vocabulary that suits their team? E.g., &lt;code&gt;timingFunctions&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches&lt;/strong&gt; only supports tokens from &lt;a href="https://system-ui.com/theme" rel="noopener noreferrer"&gt;system-ui specs&lt;/a&gt;. Also not possible to customise token names either.&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract&lt;/strong&gt; supports custom tokens with custom names.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atomic style generation
&lt;/h3&gt;

&lt;p&gt;Does the library provide a way to generate a set of atomic classes to reuse and reduce the amount of CSS to be shipped?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblmvh9dq96qawc2f8wqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblmvh9dq96qawc2f8wqd.png" alt="Atomic CSS stops growing after a while"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🧵 &lt;strong&gt;Stitches&lt;/strong&gt; doesn’t support atomic generation at this time.&lt;/p&gt;

&lt;p&gt;🧁 &lt;strong&gt;Vanilla-Extract&lt;/strong&gt; supports atomic generation using &lt;a href="https://vanilla-extract.style/documentation/sprinkles-api/" rel="noopener noreferrer"&gt;Sprinkles&lt;/a&gt;. You can even use the atoms inside variants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;For us, performance and user experience are important as a lot of our users come from a low powered mobile device. The choice was obvious, we decided to go with &lt;strong&gt;Vanilla-Extract&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero runtime&lt;/li&gt;
&lt;li&gt;Ability to generate atoms that helps in limiting the amount of CSS we ship to our users&lt;/li&gt;
&lt;li&gt;Better rendering performance overall&lt;/li&gt;
&lt;li&gt;Ability to use expensive libraries like &lt;a href="https://polished.js.org" rel="noopener noreferrer"&gt;Polished&lt;/a&gt; in &lt;code&gt;.css.ts&lt;/code&gt; files without worrying about the impact on bundle-size as they’re evaluated at build time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Note On React 18
&lt;/h2&gt;

&lt;p&gt;If you care about performance and the nitty-gritty details, you should definitely read the library upgrade guides by the React Working Group:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/reactwg/react-18/discussions/110" rel="noopener noreferrer"&gt;Library Upgrade Guide: &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; (most CSS-in-JS libs)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reactwg/react-18/discussions/108" rel="noopener noreferrer"&gt;Library Upgrade Guide: &lt;code&gt;&amp;lt;link rel="stylesheet"&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s an interesting excerpt from the upgrade guide for &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While this technique for generating CSS is popular today, we’ve found that it has a number of problems that we’d like to avoid. Therefore we don’t have plans for adding any solutions upstream to handle this in React. For the time being, we expect this to have to be handled by third-party libraries such as in this guide.&lt;/p&gt;

&lt;p&gt;Our preferred solution is to use &lt;code&gt;&amp;lt;link rel="stylesheet"&amp;gt;&lt;/code&gt; for statically extracted styles and plain inline styles for dynamic values. E.g. &lt;code&gt;&amp;lt;div style={{...}}&amp;gt;&lt;/code&gt;. You could however build a CSS-in-JS library that extracts static rules into external files using a compiler. That’s what we use at Facebook.&lt;/p&gt;

&lt;p&gt;It’s tempting to use dynamically generated style sheets since it contains only the rules that are active on the page right now. However, this comes at a cost. Usually at the expense of runtime cost. It also comes at a cost of inserting new rules frequently which invalidates a lot of the work that has already been done.&lt;/p&gt;

&lt;p&gt;Shared stylesheets are efficient to parse and are very cacheable. By extracting them into shared styles you are also effectively batching a lot of that work up front. This lets you avoid doing that work later on as the user starts interacting with the page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/andreipfeiffer/css-in-js" rel="noopener noreferrer"&gt;A thorough analysis of all the current CSS-in-JS solutions with SSR &amp;amp; TypeScript support for Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/tFFn39lLO-U" rel="noopener noreferrer"&gt;How React-Native-Web uses atomic styles and high-level DOM-agnostic abstractions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/9JZHodNR184" rel="noopener noreferrer"&gt;How Facebook uses atomic styles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/ur-sGzUWId4" rel="noopener noreferrer"&gt;RF21 – Naman Goel – Rethinking CSS - Introducing Stylex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/23VqED_kO2Q" rel="noopener noreferrer"&gt;RF21 – Mark Dalgleish – Zero-runtime CSS-in-TypeScript with vanilla-extract&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Add Command Palette (CMD+P) To Any App!</title>
      <dc:creator>Nayaab Khan</dc:creator>
      <pubDate>Thu, 18 Nov 2021 09:36:11 +0000</pubDate>
      <link>https://forem.com/nayaabkhan/add-command-palette-p-to-any-app-38hj</link>
      <guid>https://forem.com/nayaabkhan/add-command-palette-p-to-any-app-38hj</guid>
      <description>&lt;h2&gt;
  
  
  tldr;
&lt;/h2&gt;

&lt;p&gt;Use &lt;a href="https://www.raycast.com"&gt;Raycast's&lt;/a&gt; “Search Menu Items” from any app and get a command palette.&lt;/p&gt;

&lt;p&gt;If you love Alfred or can‘t switch, you can use a workflow like &lt;a href="https://github.com/BenziAhamed/Menu-Bar-Search"&gt;BenziAhamed/Menu-Bar-Search&lt;/a&gt; to do the same.&lt;/p&gt;




&lt;p&gt;Command palettes from Sublime Text and Visual Studio Code are awesome. They give quick access to commands with fuzzy search. It sucks when apps don’t have it.&lt;/p&gt;

&lt;p&gt;Recently, I switched to &lt;strong&gt;Raycast&lt;/strong&gt; which is a great alternative to the fantastic app that &lt;a href="https://www.alfredapp.com"&gt;Alfred&lt;/a&gt; is.&lt;/p&gt;

&lt;p&gt;It has a fantastic command called &lt;strong&gt;“Search Menu Items”&lt;/strong&gt;. It gives me a searchable list of commands with their shortcuts keys. For example, this is what it gives me on iTerm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vAd7AYUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzp4jpb11k7cdkhz720o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vAd7AYUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzp4jpb11k7cdkhz720o.png" alt="Raycast's “Search Menu Items” when run from iTerm with a search for “split” showing results to split panes with shortcuts keys" width="880" height="617"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Hotkey
&lt;/h2&gt;

&lt;p&gt;I've set up a hotkey to quick access the commands as well. This saves me a few keystrokes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fJNjziK_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru6dhpwyshubj3kgg6k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fJNjziK_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru6dhpwyshubj3kgg6k0.png" alt="Raycast's settings where you can set a hotkey to quickly access its commands" width="880" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus, one less app
&lt;/h2&gt;

&lt;p&gt;It has also replaced &lt;a href="https://www.mediaatelier.com/CheatSheet/"&gt;Cheatsheet&lt;/a&gt; for me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--22x25gnn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj9jx7k37ullkx14fabg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--22x25gnn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj9jx7k37ullkx14fabg.png" alt="Cheatsheet displays all the commands in one window but it is not searchable" width="880" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>macos</category>
      <category>tools</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
