<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: chantastic</title>
    <description>The latest articles on DEV Community by chantastic (@chantastic).</description>
    <link>https://dev.to/chantastic</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%2F50756%2F245a8d36-6fd8-437b-bf34-6637f0f3d79b.png</url>
      <title>DEV Community: chantastic</title>
      <link>https://dev.to/chantastic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chantastic"/>
    <language>en</language>
    <item>
      <title>A Universal Terminal alias for bun, pnpm, npm, and yarn.</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Wed, 27 Sep 2023 16:59:11 +0000</pubDate>
      <link>https://dev.to/chantastic/a-universal-terminal-alias-for-bun-pnpm-npm-and-yarn-48f8</link>
      <guid>https://dev.to/chantastic/a-universal-terminal-alias-for-bun-pnpm-npm-and-yarn-48f8</guid>
      <description>&lt;p&gt;I've typed npm for the last time.&lt;/p&gt;

&lt;p&gt;As JavaScript developers, we have four package managers to choose from. And between personal, work, and open source projects, I use every last one of them. This is a problem because typing the wrong command costs time and irritation.&lt;/p&gt;

&lt;p&gt;Below is zsh function that I've used to eliminate package manager context switching heartache — typing npm start when we meant bun start or npm when I mean ::shudders:: yarn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p() {
  if [[ -f bun.lockb ]]; then
    command bun "$@"
  elif [[ -f pnpm-lock.yaml ]]; then
    command pnpm "$@"
  elif [[ -f yarn.lock ]]; then
    command yarn "$@"
  elif [[ -f package-lock.json ]]; then
    command npm "$@"
  else
    command pnpm "$@"
  fi
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What this command does
&lt;/h2&gt;

&lt;p&gt;zsh functions can be used like fancy aliases with the addition of a runtime check. This function checks for the existence of a lock file and runs the stated command with the correct package manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this command does not do
&lt;/h2&gt;

&lt;p&gt;This function does not create a universal interface around the varied package managers. I don't find universal interfaces helpful.&lt;/p&gt;

&lt;p&gt;And I enjoy utilizing the subtleties in each package manager. My problem is the muscle memory around common commands (start, install, and test) and those actions inadvertently spawn confusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn more
&lt;/h2&gt;

&lt;p&gt;Check out these references if you want to learn more about zsh functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://zsh.sourceforge.io/Intro/intro_4.html"&gt;Intro to zsh functions&lt;/a&gt;&lt;br&gt;
&lt;a href="https://unix.stackexchange.com/questions/33255/how-to-define-and-load-your-own-shell-function-in-zsh"&gt;How to define and load your own shell function in zsh&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>react</category>
      <category>webdev</category>
      <category>coding</category>
    </item>
    <item>
      <title>Storybook Actions in Action</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Fri, 25 Aug 2023 00:53:59 +0000</pubDate>
      <link>https://dev.to/chantastic/storybook-actions-in-action-4b7h</link>
      <guid>https://dev.to/chantastic/storybook-actions-in-action-4b7h</guid>
      <description>&lt;p&gt;Let's talk about &lt;code&gt;console.log&lt;/code&gt;-driven development. We all do it. So, instead of fighting it, let's &lt;em&gt;upgrade&lt;/em&gt; it with Storybook Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Feature instability and mitigations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Storybook actions are a feature of Storybook 6 and 7.&lt;/p&gt;

&lt;p&gt;There's an &lt;a href="https://github.com/storybookjs/storybook/discussions/23649" rel="noopener noreferrer"&gt;&lt;strong&gt;active design proposal&lt;/strong&gt;&lt;/a&gt; to make them work like conventional testing mocks. This would be a welcome change, imo.&lt;/p&gt;

&lt;p&gt;Knowing that a change is on the horizon, let's focus on the features of the current API that will remain (or migrate easily with codemods).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Feature Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a fresh Storybook 7 installation (&lt;a href="https://storybook.new/" rel="noopener noreferrer"&gt;&lt;strong&gt;sandboxes here&lt;/strong&gt;&lt;/a&gt;), we find two example components configured to use Storybook actions.&lt;/p&gt;

&lt;p&gt;The included Button stories log the common event — &lt;code&gt;onClick&lt;/code&gt; — when clicked. Logs can then be expanded to show full event details.&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%2Fdllhku9ot91k2whebzje.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%2Fdllhku9ot91k2whebzje.png" alt="Story for Button that has been clicked. The Actions tab shows a logged onClick common event. This includes the React Event details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;​Heading stories also log events but this time with custom events &lt;code&gt;onLogin&lt;/code&gt; and &lt;code&gt;onCreateAccount&lt;/code&gt;. These events are logged when the respective buttons are clicked.&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%2Fy7uh6brf62eucqcljy22.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%2Fy7uh6brf62eucqcljy22.png" alt="Story for Heading that has had Login and Sign up buttons clicked. The Actions tab shows a logged onLogin and onCreateAccount custom events. These include the React Event details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actions pair perfectly with &lt;a href="https://storybook.js.org/docs/react/essentials/interactions#page-top" rel="noopener noreferrer"&gt;&lt;strong&gt;Storybook interactions&lt;/strong&gt;&lt;/a&gt;. Interactions are a way to document component states thru simulated user input. Interactions trigger their corresponding 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%2Fgqnkbzompnkwuip4yq70.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%2Fgqnkbzompnkwuip4yq70.png" alt="Story for Page that has had Login and Sign up buttons. The Log in button was clicked via Storybook interactions (play function), using testing-library/dom. The Interactions tab shows that the event was executed. And the Actions tab shows that the callback was called, with the React Event details."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Add actions with argTypes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's define actions for the example Button component.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open the story file and locate component &lt;code&gt;meta&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an &lt;code&gt;argTypes&lt;/code&gt; property if one doesn't exist.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an &lt;code&gt;onClick&lt;/code&gt; property (this needs to match the component prop name).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the value to &lt;code&gt;{ action: "clicked" }&lt;/code&gt;. (The logged text can be anything we like.)&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.stories.tsx&lt;/span&gt;
&lt;span class="c1"&gt;// (surronding code omitted)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Example/Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;autodocs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;argTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onClick&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="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;Meta&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="o"&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;Now click your button in Storybook and watch the Actions log!&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%2F6mcfauqqsr70uij731mf.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%2F6mcfauqqsr70uij731mf.gif" alt="Animated gif of React Events being logged as the Button story is clicked"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Test actions with interactions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's add an interaction to the example Button component.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create or find a new story.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a &lt;code&gt;play&lt;/code&gt; function to the story object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Within the &lt;code&gt;canvasElement&lt;/code&gt;, find the button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;then simulate a click event.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.stories.tsx&lt;/span&gt;
&lt;span class="c1"&gt;// (surronding code omitted)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Story&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Button&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="na"&gt;play&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;canvasElement&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;within&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvasElement&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;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/Button/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="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;Now the story will run the interaction when it loads. Logging both the interaction and the action — in their respective tabs.&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%2Fcxxps2admrdhuxtgag91.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%2Fcxxps2admrdhuxtgag91.png" alt="Image of an interaction story that automatically plays a user event over a story. An interaction is logged and an 1 action is showing as logged in the Actions tab."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Lessons learned&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;console.log&lt;/code&gt;-driven development is something I do when driving out a component implementation. It's a quick, cheap way to ensure that events are hooked up (early in the process).&lt;/p&gt;

&lt;p&gt;But log statements has one &lt;strong&gt;huge drawback&lt;/strong&gt;: they live in component code. And I'm guilty of pushing a log (or a few dozen) into production.&lt;/p&gt;

&lt;p&gt;Storybook actions let you validate implementation in story files, leaving component code alone.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Polymorphic as prop in Astro</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Wed, 23 Aug 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/chantastic/polymorphic-as-prop-in-astro-2713</link>
      <guid>https://dev.to/chantastic/polymorphic-as-prop-in-astro-2713</guid>
      <description>&lt;p&gt;Astro has &lt;a href="https://docs.astro.build/en/core-concepts/astro-syntax/#dynamic-tags"&gt;dynamic tags&lt;/a&gt; — a way to take an element or component as a prop.&lt;/p&gt;

&lt;p&gt;I had trouble finding the feature because the React community calls this pattern the "polymorphic as prop". &lt;em&gt;Because we enjoy our pseudo-computer-science bullshit artisinally.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dynamic tags are simple to implement in Astro.&lt;/p&gt;

&lt;h2&gt;
  
  
  No-fuss implementation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Take a &lt;em&gt;capitalized&lt;/em&gt; &lt;code&gt;Element&lt;/code&gt; prop as a local variable.&lt;/li&gt;
&lt;li&gt;Render that prop as a template tag.&lt;/li&gt;
&lt;li&gt;Take and spread rest-props.&lt;/li&gt;
&lt;li&gt;Render children using Astro's un-named &lt;a href="https://docs.astro.build/en/core-concepts/astro-components/#slots"&gt;&lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt;&lt;/a&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
const { Element, ...props } = Astro.props;
---

&amp;lt;Element {...props}&amp;gt;&amp;lt;slot /&amp;gt;&amp;lt;/Element&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Destructure and rename the element prop (for convenience or convention)
&lt;/h2&gt;

&lt;p&gt;Uppercase prop names can look out of place in templates. Destructure and rename the &lt;code&gt;Element&lt;/code&gt; prop in one to provide a more ergonomic/conventional authoring experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
const { as: Element, ...props } = Astro.props;
---

&amp;lt;Element {...props}&amp;gt;&amp;lt;slot /&amp;gt;&amp;lt;/Element&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Astro templates require that dynamic tags be capitalized. Renaming the element prop is a convent way to follow that requirement while providing a more conventional API to consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accept and de-duplicate classes with &lt;code&gt;class:list&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Astro has a &lt;a href="https://docs.astro.build/en/reference/directives-reference/#classlist"&gt;&lt;code&gt;class:list&lt;/code&gt; directive&lt;/a&gt; for orchestrating dynamic classes. Provide the &lt;code&gt;class:list&lt;/code&gt; directive an array with both &lt;em&gt;provided&lt;/em&gt; and &lt;em&gt;component&lt;/em&gt; classes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;class:list&lt;/code&gt; is smart and automatically removes duplicate classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
const {
  as: Element = "div",
  class: providedProps,
  ...props
} = Astro.props;
const componentClasses = "prose prose-slate dark:prose-invert";
---

&amp;lt;Element {...props} class:list={[componentClasses, providedProps]}&amp;gt;
  &amp;lt;slot /&amp;gt;
&amp;lt;/Element&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: &lt;code&gt;class&lt;/code&gt; needs to be renamed when destructured because values can not be assigned to reserved words.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete with TypeScript interface
&lt;/h2&gt;

&lt;p&gt;This is my completed component, with the TypeScript interface.&lt;/p&gt;

&lt;p&gt;Yours needs will likely vary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
interface Props {
  as?: "body" | "main" | "article";
  class?: "string";
}

const {
  as: Element = "div",
  class: providedProps,
  ...props
} = Astro.props;
---

&amp;lt;Element {...props} class:list={[componentClasses, providedProps]}&amp;gt;
  &amp;lt;slot /&amp;gt;
&amp;lt;/Element&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  BEWARE: dynamic tags don't honor hydration client directives
&lt;/h2&gt;

&lt;p&gt;Astro provides &lt;a href="https://docs.astro.build/en/reference/directives-reference/#client-directives"&gt;client directives&lt;/a&gt; for hydrating client-side UI. Those don't work with dynamic tags.&lt;/p&gt;

&lt;p&gt;If you're using dynamic tags for static layouts — like me — this isn't an issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;Astro supports the "polymorphic as prop" pattern popular in React. And the additional standard tooling of TypeScript and &lt;a href="https://docs.astro.build/en/reference/directives-reference/#classlist"&gt;&lt;code&gt;class:list&lt;/code&gt; directive&lt;/a&gt; make it even easier to consistently implement.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Doc blocks for design system documentation</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Thu, 10 Aug 2023 04:09:59 +0000</pubDate>
      <link>https://dev.to/chantastic/doc-blocks-for-design-system-documentation-2n74</link>
      <guid>https://dev.to/chantastic/doc-blocks-for-design-system-documentation-2n74</guid>
      <description>&lt;p&gt;If you document design systems, I'm about to save you a &lt;em&gt;ton&lt;/em&gt; of time.&lt;br&gt;
Because Storybook comes with lesser-known components for organizing colors, typography, and icons.&lt;/p&gt;
&lt;h2&gt;
  
  
  ColorPalette
&lt;/h2&gt;

&lt;p&gt;Display color systems with the &lt;code&gt;ColorPalette&lt;/code&gt; component.&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%2Fn06x6y1tl70ke2fw5281.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%2Fn06x6y1tl70ke2fw5281.png" alt="Storybook component library showing sample color-system documentation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import &lt;code&gt;"@storybook/blocks"&lt;/code&gt;.&lt;br&gt;
Then render a &lt;code&gt;ColorPalette&lt;/code&gt; with a single &lt;code&gt;ColorItem&lt;/code&gt; inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// system/colors.mdx&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;ColorPalette&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ColorItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@storybook/blocks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ColorPalette&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;ColorItem&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="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;ColorPalette&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;Create an object with a key and color value.&lt;br&gt;
And pass it to the &lt;code&gt;ColorItem&lt;/code&gt; component via the &lt;code&gt;color&lt;/code&gt; prop.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Both key and value are displayed in the UI.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ColorItem&lt;/span&gt; &lt;span class="na"&gt;colors&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="na"&gt;Apple&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#66bf3c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Describe &lt;code&gt;ColorItems&lt;/code&gt; with &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;subtitle&lt;/code&gt; props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;ColorItem
&lt;span class="gi"&gt;+  title="Apple"
+  subtitle="A delicious brand color."
&lt;/span&gt;  colors={{ Apple: "#66bf3c" }}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add as many colors to the &lt;code&gt;colors&lt;/code&gt; prop as needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;ColorItem
  title="Apple"
  subtitle="A delicious brand color."
  colors={{
    Apple: "#66bf3c",
&lt;span class="gi"&gt;+    AppleDark: "#46991f",
+    AppleLight: "#83da5a"
&lt;/span&gt;  }}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use any CSS-supported color value.&lt;br&gt;&lt;br&gt;
&lt;code&gt;ColorItem&lt;/code&gt; adds gray cross-hatches to indicate translucency — where color functions with non-&lt;code&gt;1&lt;/code&gt; alpha values are used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;ColorItem
  title="Apple"
  subtitle="A delicious brand color."
  colors={{
&lt;span class="gi"&gt;+    Apple: "rgba(102,191,60,1)",
+    Apple60: "rgba(102,191,60,.6)",
+    Apple30: "rgba(102,191,60,.3)",
&lt;/span&gt;  }}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See full &lt;a href="https://storybook.js.org/docs/react/api/doc-block-colorpalette" rel="noopener noreferrer"&gt;&lt;code&gt;ColorPalette&lt;/code&gt; API reference&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typeset
&lt;/h2&gt;

&lt;p&gt;Display typography systems with the &lt;code&gt;Typeset&lt;/code&gt; component.&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%2F1uhs8nrbue4dagnauv11.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%2F1uhs8nrbue4dagnauv11.png" alt="Storybook component library showing sample typography documentation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import the &lt;code&gt;Typeset&lt;/code&gt; component from &lt;code&gt;@storybook/blocks&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// system/typography.mdx&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;Typeset&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@storybook/blocks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Typeset&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* required props */&lt;/span&gt;&lt;span class="si"&gt;}&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;code&gt;Typeset&lt;/code&gt; requires four props to render: &lt;code&gt;fontSizes&lt;/code&gt;, &lt;code&gt;fontWeight&lt;/code&gt;, &lt;code&gt;sampleText&lt;/code&gt;, and &lt;code&gt;fontFamily&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;fontSizes&lt;/code&gt; and &lt;code&gt;fontWeight&lt;/code&gt; support any supported CSS value (and numbers).&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;Typeset
&lt;span class="gi"&gt;+  fontSizes={["2.875em", "2em", "1.375em", "1em"]}
+  fontWeight="900"
+  sampleText="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
+  fontFamily='"Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif'
&lt;/span&gt;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new &lt;code&gt;Typeset&lt;/code&gt; block for every discrete typographical subset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;## Code
&lt;span class="err"&gt;
&lt;/span&gt;&amp;lt;Typeset
  fontSizes={[16]}
  fontWeight={400}
  sampleText="let var = 'const';"
  fontFamily='ui-monospace,
             Menlo, Monaco,
             "Cascadia Mono", "Segoe UI Mono",
             "Roboto Mono",
             "Oxygen Mono",
             "Ubuntu Monospace",
             "Source Code Pro",
             "Fira Mono",
             "Droid Sans Mono",
             "Courier New", monospace;'
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See full &lt;a href="https://storybook.js.org/docs/react/api/doc-block-typeset" rel="noopener noreferrer"&gt;&lt;code&gt;Typeset&lt;/code&gt; API reference&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  IconGallery
&lt;/h2&gt;

&lt;p&gt;Display icons with the &lt;code&gt;IconGallery&lt;/code&gt; component.&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%2F3kefnnz6opatt77kyq4u.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%2F3kefnnz6opatt77kyq4u.png" alt="Storybook component library showing sample typography documentation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import &lt;code&gt;"@storybook/blocks"&lt;/code&gt;.&lt;br&gt;
Then render a &lt;code&gt;IconGallery&lt;/code&gt; with a single &lt;code&gt;IconItem&lt;/code&gt; inside it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// system/icons.mdx&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;IconGallery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IconItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@storybook/blocks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IconGallery&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;IconItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;IconItem&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="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;IconGallery&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;Place an icon inside &lt;code&gt;IconItem&lt;/code&gt;.&lt;br&gt;
Then display that icon's name with the &lt;code&gt;name&lt;/code&gt; prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+ import * as Icons from "@storybook/icons";
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&amp;lt;IconGallery&amp;gt;
  &amp;lt;IconItem name="Accessibility"&amp;gt;
&lt;span class="gi"&gt;+    &amp;lt;Icons.Accessibility /&amp;gt;
&lt;/span&gt;  &amp;lt;/IconItem&amp;gt;
&amp;lt;/IconGallery&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take this further — in React — by dynamically generating all available icons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Storybook icons

&amp;lt;IconGallery&amp;gt;
  {Object.entries(Icons)
    .filter(([name]) =&amp;gt; name !== "iconList")
    .map(([name, Icon]) =&amp;gt; (
      &amp;lt;IconItem name={name}&amp;gt;
        &amp;lt;Icon /&amp;gt;
      &amp;lt;/IconItem&amp;gt;
    ))}
&amp;lt;/IconGallery&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See full &lt;a href="https://storybook.js.org/docs/react/api/doc-block-icongallery" rel="noopener noreferrer"&gt;&lt;code&gt;IconGallery&lt;/code&gt; API reference&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn more…
&lt;/h2&gt;

&lt;p&gt;Find in-depth references for each component on the &lt;a href="https://storybook.js.org/docs/" rel="noopener noreferrer"&gt;Storybook docs page&lt;/a&gt; and &lt;a href="https://www.youtube.com/@chromaticui" rel="noopener noreferrer"&gt;Chromatic YouTube channel&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>storybook</category>
      <category>systems</category>
      <category>coding</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Add Lucide Icons to Astro</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Tue, 01 Aug 2023 16:57:01 +0000</pubDate>
      <link>https://dev.to/chantastic/add-lucide-icons-to-astro-42el</link>
      <guid>https://dev.to/chantastic/add-lucide-icons-to-astro-42el</guid>
      <description>&lt;p&gt;There's no first-class &lt;a href="https://lucide.dev/"&gt;Lucide&lt;/a&gt; integration for &lt;a href="https://astro.build/"&gt;Astro&lt;/a&gt;. But making a custom one isn't too hard.&lt;/p&gt;

&lt;p&gt;This is the component I made to do the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
const { icon, ...props } = Astro.props;

const [, attributes, children] = icon;

const componentChildren = children
  ?.map(
    ([shape, attributes]) =&amp;gt;
      `&amp;lt;${shape} ${Object.entries(attributes)
        .map(([k, v]) =&amp;gt; `${k}="${v}"`)
        .join(" ")} /&amp;gt;`
  )
  .join("");

const componentAttributes = {...attributes, ...props}
---

&amp;lt;svg
  {...componentAttributes}
  set:html={componentChildren}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this component looks reasonable to you,&lt;br&gt;
copy it and go forth.&lt;/p&gt;

&lt;p&gt;If you'd like to learn how it works, let's get it!&lt;/p&gt;
&lt;h2&gt;
  
  
  Our goal
&lt;/h2&gt;

&lt;p&gt;For this build, our goal is to render icons directly into an Astro site — converting Lucide's JSON files to inline &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt;s at build time.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://lucide.dev/packages"&gt;is just one of many ways to add Lucide icons to a site&lt;/a&gt; — the one that fits my needs best.&lt;/p&gt;
&lt;h2&gt;
  
  
  Initial setup
&lt;/h2&gt;

&lt;p&gt;Add the &lt;code&gt;lucide&lt;/code&gt; package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm install lucide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the standard &lt;code&gt;lucide&lt;/code&gt; package, icons are exported as JSON arrays with the following contents:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[0]&lt;/code&gt;: &lt;code&gt;"svg"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;[1]&lt;/code&gt;: element attributes&lt;br&gt;
&lt;code&gt;[2]&lt;/code&gt;: children&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svg&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="na"&gt;xmlns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://www.w3.org/2000/svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;viewBox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 0 24 24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currentColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stroke-width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stroke-linecap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stroke-linejoin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&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="nb"&gt;Object&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;We need to import these JSON files and render their data as &lt;code&gt;HTML&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Render a single icon
&lt;/h2&gt;

&lt;p&gt;To render a single Lucide icon:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import any &lt;code&gt;lucide&lt;/code&gt; icon&lt;/li&gt;
&lt;li&gt;Destructure &lt;code&gt;attributes&lt;/code&gt; and &lt;code&gt;children&lt;/code&gt; array items from that icon&lt;/li&gt;
&lt;li&gt;Reduce children nodes to HTML string&lt;/li&gt;
&lt;li&gt;Render an &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; component

&lt;ul&gt;
&lt;li&gt;Spread &lt;code&gt;attributes&lt;/code&gt; directly on the element&lt;/li&gt;
&lt;li&gt;Apply &lt;code&gt;childElements&lt;/code&gt; with the &lt;code&gt;set:html&lt;/code&gt; directive
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 1. Import any `lucide` icon
import { Accessibility } from "lucide";

// 2. Destructure the `attributes` and `children` array items
const [, attributes, children] = Accessibility;

// 3. Reduce children nodes to HTML string
const componentChildren = children
  ?.map(
    ([child, attributes]) =&amp;gt;
      `&amp;lt;${child} ${Object.entries(attributes)
        .map(([k, v]) =&amp;gt; `${k}="${v}"`)
        .join(" ")} /&amp;gt;`
  )
  .join("\n");
---

&amp;lt;!-- 4. render svg element --&amp;gt;
&amp;lt;svg
  {/* 4.1. Spread `attributes` directly on the element */}
  {...attributes}
  {/* 4.2. Apply `childElements` with the `set:html` directive */}
  set:html={childrenElements}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extract &lt;code&gt;LucideIcon&lt;/code&gt; component
&lt;/h2&gt;

&lt;p&gt;Now that we can render icons, let's extract this code as a reusable component.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Move the relevant code to &lt;code&gt;src/components/lucide-icon.astro&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Refactor to &lt;code&gt;icon&lt;/code&gt; as a prop&lt;/li&gt;
&lt;li&gt;Take rest &lt;code&gt;...props&lt;/code&gt; so HTML and SVG attributes can be applied at the call site&lt;/li&gt;
&lt;li&gt;Merge icon &lt;code&gt;attributes&lt;/code&gt; and component &lt;code&gt;props&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Apply munged attributes-props to exported &lt;code&gt;svg&lt;/code&gt; element
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;---
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt; 1. Take `icon` as a prop
&lt;span class="err"&gt;//&lt;/span&gt; 2. Take rest `props`
&lt;span class="gd"&gt;- import { Accessibility } from "lucide";
&lt;/span&gt;&lt;span class="gi"&gt;+ const { icon, ...props } = Astro.props;
&lt;/span&gt;
const componentChildren = children
  ?.map(
    ([child, attributes]) =&amp;gt;
      `&amp;lt;${child} ${Object.entries(attributes)
        .map(([k, v]) =&amp;gt; `${k}="${v}"`)
        .join(" ")} /&amp;gt;`
  )
  .join("\n");

// 3. Merge `attributes` and `props`
&lt;span class="gi"&gt;+ const componentAttributes = {...attributes, ...props}
&lt;/span&gt;&lt;span class="p"&gt;---
&lt;/span&gt;
&amp;lt;svg
  {/* 4. Apply munged `componentAttributes` to svg */}
&lt;span class="gd"&gt;-  {...attributes}
&lt;/span&gt;&lt;span class="gi"&gt;+  {...componentAttributes}
&lt;/span&gt;  set:html={childrenElements}
&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use the &lt;code&gt;LucideIcon&lt;/code&gt; component
&lt;/h2&gt;

&lt;p&gt;To use our new &lt;code&gt;LucideIcon&lt;/code&gt; component, import it along with any &lt;code&gt;lucide&lt;/code&gt; icon.&lt;br&gt;
Provide the icon JSON to &lt;code&gt;LucideIcon&lt;/code&gt; using the &lt;code&gt;icon&lt;/code&gt; prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
import LucideIcon from "@components/lucide-icon.astro";
import { Accessibility } from "lucide";
---

&amp;lt;LucideIcon icon={Accessibility} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Apply attributes to &lt;code&gt;LucideIcon&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;LucideIcon&lt;/code&gt; receives props that it merges with the default &lt;code&gt;lucide&lt;/code&gt; values.&lt;br&gt;
Use these to change SVG attributes like &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;fill&lt;/code&gt;, and &lt;code&gt;stroke-width&lt;/code&gt;.&lt;br&gt;
Or apply common attributes like &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
import LucideIcon from "@components/lucide-icon.astro";
import { Accessibility } from "lucide";
---

&amp;lt;LucideIcon icon={Accessibility} width="56" height="56" stroke-width="4" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Taking it further
&lt;/h2&gt;

&lt;p&gt;My preference is to keep icon importing and SVG rendering separated.&lt;br&gt;
But you may find this cumbersome.&lt;/p&gt;

&lt;p&gt;If so, create a facade for &lt;code&gt;LucideIcon&lt;/code&gt; that exposes your favorite icons via &lt;code&gt;string&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;This could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
import {
  Github as github,
  Youtube as youtube,
  Twitter as twitter,
  Instagram as instagram
} from "lucide";

const icons = {
  github,
  youtube,
  twitter,
  instagram
}

const { name = "github", ...props } = Astro.props;

if !(icons[name]) { return null }

const [, attributes, children] = icons[name];

const componentChildren = children
  ?.map(
    ([child, attributes]) =&amp;gt;
      `&amp;lt;${child} ${Object.entries(attributes)
        .map(([k, v]) =&amp;gt; `${k}="${v}"`)
        .join(" ")} /&amp;gt;`
  )
  .join("\n");

const componentAttributes = {...attributes, ...props}
---

&amp;lt;svg
  {...componentAttributes}
  set:html={childrenElements}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Go further with TypeScript
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;lucide&lt;/code&gt; does not expose its &lt;code&gt;IconNode&lt;/code&gt; type for external use.&lt;/p&gt;

&lt;p&gt;So, if you want to use my code above in TypeScript, you'll need to get clever:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import just the type of any component.&lt;/li&gt;
&lt;li&gt;Infer the &lt;code&gt;IconNode&lt;/code&gt; for that icon in the &lt;code&gt;LucideIcon&lt;/code&gt; type declaration.&lt;/li&gt;
&lt;li&gt;Add any optional &lt;code&gt;svg&lt;/code&gt; attributes you'd like to support.
(e.g., &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;stroke-width&lt;/code&gt;, etc.)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
// 1. Import just the type of any component.
import type { Accessibility } from "lucide";

type Props = {
  // 2. Infer the `IconNode` for that icon in the `LucideIcon` type declaration
  icon: typeof Accessibility;
};
---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's it!
&lt;/h2&gt;

&lt;p&gt;I hope that you found this useful in building an Astro site.&lt;br&gt;
If you'd like to see more Astro tips and tricks, bug me on Twitter/X or Discord. 😄&lt;/p&gt;

</description>
      <category>astro</category>
      <category>svg</category>
      <category>webdev</category>
      <category>coding</category>
    </item>
    <item>
      <title>Fix VS Code Explorer for Content Projects</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Tue, 25 Jul 2023 16:48:23 +0000</pubDate>
      <link>https://dev.to/chantastic/fix-vs-code-explorer-for-content-projects-21p0</link>
      <guid>https://dev.to/chantastic/fix-vs-code-explorer-for-content-projects-21p0</guid>
      <description>&lt;p&gt;The &lt;a href="https://code.visualstudio.com/docs/getstarted/userinterface#_explorer" rel="noopener noreferrer"&gt;VS Code explorer&lt;/a&gt; displays folders at the top of a directory.&lt;br&gt;
This is a common hierarchy that I like in &lt;em&gt;most&lt;/em&gt; cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But I hate it for content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For content sites — like &lt;a href="https://chan.dev/" rel="noopener noreferrer"&gt;chan.dev&lt;/a&gt; — I prefer alphabetical order.&lt;br&gt;
I want to see my files and folders all &lt;em&gt;mixed&lt;/em&gt; up together.&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%2Fwjt86nho0oz6mk391tt3.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%2Fwjt86nho0oz6mk391tt3.png" alt="Screenshot of the Visual Studio Code Explorer, showing several markdown posts. With  raw `explorer.sortOrder: mixed` endraw , a directory of the same name as a post appears next to a post with the same name."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How to change the setting
&lt;/h2&gt;

&lt;p&gt;To change the default behavior, open Settings and find the option for &lt;code&gt;Explorer: Sort Order&lt;/code&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%2Fdqa22p6ero83idnwwzbq.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%2Fdqa22p6ero83idnwwzbq.png" alt="Screenshot of VS Code Settings, for the option Explorer: Sort Order. Selected is the  raw `mixed` endraw  option."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this option enabled, files and folders are interwoven in the explorer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I prefer mixed sort order
&lt;/h2&gt;

&lt;p&gt;On &lt;a href="https://chan.dev/" rel="noopener noreferrer"&gt;chan.dev&lt;/a&gt;, I have lots of markdown files.&lt;br&gt;
Some of them have images.&lt;br&gt;
And I want to keep those images in a folder nearby.&lt;br&gt;
I ain't tryna faff with Cloudinary or hunt down shared &lt;code&gt;/assets/images&lt;/code&gt; folder.&lt;br&gt;
&lt;em&gt;I want them right next to my post.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This makes it easy to keep my place on the file system.&lt;/p&gt;
&lt;h2&gt;
  
  
  Take it further with workspaces
&lt;/h2&gt;

&lt;p&gt;As mentioned, I prefer the default sort order for most projects.&lt;br&gt;
So, I keep this setting stored in my &lt;a href="https://chan.dev/" rel="noopener noreferrer"&gt;chan.dev&lt;/a&gt; &lt;a href="https://code.visualstudio.com/docs/editor/workspaces" rel="noopener noreferrer"&gt;workspace&lt;/a&gt;.&lt;br&gt;
And only &lt;em&gt;this&lt;/em&gt; project is impacted by the setting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;chan.dev/.vscode/settings.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"explorer.sortOrder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mixed"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/RvYvyzsnFm8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>coding</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Embed YouTube videos responsively</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Thu, 13 Jul 2023 19:10:17 +0000</pubDate>
      <link>https://dev.to/chantastic/embed-youtube-videos-responsively-1hda</link>
      <guid>https://dev.to/chantastic/embed-youtube-videos-responsively-1hda</guid>
      <description>&lt;p&gt;YouTube makes it easy to copy-paste a video embed.&lt;br&gt;
LOVE THAT!&lt;/p&gt;

&lt;p&gt;But, the default embed isn't responsive so it is guaranteed to look shit wherever you embed it.&lt;/p&gt;

&lt;p&gt;I've drug this snippet around the internet with me for years.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* youtube embed wrapper */&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-responsive-youtube-container&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;56.25%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-responsive-youtube-container&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;iframe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&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;I adapted it to use &lt;a href="https://dev.to/avo-a-bem-dialect-using-data-attributes/"&gt;AVO 🥑 CSS&lt;/a&gt;, my data attributes specification of &lt;a href="https://en.bem.info/methodology/css/"&gt;BEM&lt;/a&gt;.&lt;br&gt;
But I didn't write the styles.&lt;br&gt;
I hate magic numbers like &lt;code&gt;56.25%&lt;/code&gt;, and I would have tried to avoid it until giving up 😆&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Copy a YouTube embed from the share sheet.&lt;/li&gt;
&lt;li&gt;Paste that embed in an HTML or markdown file.&lt;/li&gt;
&lt;li&gt;Wrap it in a block-element container with the &lt;code&gt;data-responsive-youtube-container&lt;/code&gt; selector.&lt;/li&gt;
&lt;li&gt;Enjoy cointainer-aware responsive videos!
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-responsive-youtube-container&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"560"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"315"&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/u63pOK6Zyog"&lt;/span&gt;
    &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"YouTube video player"&lt;/span&gt;
    &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
    &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"&lt;/span&gt;
    &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Embed responsively!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;This works with layouts as well.&lt;br&gt;
Around &lt;a href="https://dev.to/marchdown/container-plugin"&gt;chan.dev&lt;/a&gt;, you'll see this paired with a flex and grid layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Help me attribute this
&lt;/h2&gt;

&lt;p&gt;If you know where I originally swiped this from, let me know so I can give the author credit here.&lt;/p&gt;

&lt;p&gt;I'm &lt;code&gt;@chantastic&lt;/code&gt; on twitter and discord.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>blog</category>
      <category>socialmedia</category>
    </item>
    <item>
      <title>Concurrent Mode is Dead. Long live Concurrent React</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Wed, 09 Jun 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/chantastic/concurrent-mode-is-dead-long-live-concurrent-react-41ee</link>
      <guid>https://dev.to/chantastic/concurrent-mode-is-dead-long-live-concurrent-react-41ee</guid>
      <description>&lt;p&gt;Three years ago &lt;a href="https://mobile.twitter.com/dan_abramov/"&gt;Dan Abramov&lt;/a&gt; introduced &lt;a href="https://www.youtube.com/watch?v=nLF0n9SACd4"&gt;Suspense and Async Rendering with React&lt;/a&gt; at &lt;a href="https://2018.jsconf.is/speakers/dan-abramov/"&gt;JSConf Iceland 2018&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the three years since, terminology took some twists and turns.&lt;/p&gt;

&lt;p&gt;"Suspense" was limited to &lt;code&gt;React.lazy&lt;/code&gt; in versions 16 and 17.&lt;/p&gt;

&lt;p&gt;"Async React" became "Concurrent Mode" — a top-down rendering mode that could be enabled for &lt;code&gt;Strict Mode&lt;/code&gt;-compatible applications.&lt;/p&gt;

&lt;p&gt;React 18 has new-new language. And I'd like to start my tour of React 18 changes by rebasing on new terminology used in the &lt;a href="http://github.com/reactwg"&gt;ReactWG&lt;/a&gt; (React Working Group).&lt;/p&gt;

&lt;h2&gt;
  
  
  Concurrent Mode =&amp;gt; Concurrent everything
&lt;/h2&gt;

&lt;p&gt;"Concurrent Mode" is no more. Bye 👋. We barely knew ya!&lt;/p&gt;

&lt;p&gt;Instead of a concurrent mode, concurrency is possible in all React 18 apps.&lt;/p&gt;

&lt;p&gt;React 18 adds a set of new features, sometimes called "concurrent features" or "concurrent APIs". These features rely on a new mechanism called "concurrent rendering" that weren't possible before it.&lt;/p&gt;

&lt;p&gt;It's a subtle but important change.&lt;br&gt;
Concurrency is no longer something that you opt into at the root of your application. It's an enrichment that happens as you use "Concurrent features and APIs" like &lt;code&gt;startTransition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Concurrent rendering is not a mode.&lt;br&gt;
Concurrent rendering is React.&lt;/p&gt;

&lt;h2&gt;
  
  
  New-new, React 18 terminology
&lt;/h2&gt;

&lt;p&gt;Here's the state of React 18 terminology shifts I've seen in &lt;a href="https://github.com/reactwg/react-18/discussions"&gt;ReactWG discussions&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Fired:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Concurrent Mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hired:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Concurrent React&lt;/li&gt;
&lt;li&gt;✅ Concurrent rendering&lt;/li&gt;
&lt;li&gt;✅ Concurrent features and APIs&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In React 18, Concurrent React is React. Concurrent features and APIs — like &lt;code&gt;startTransition&lt;/code&gt; — expose controls for opting into concurrent rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowladgements
&lt;/h2&gt;

&lt;p&gt;This post was reviewed and improved by the fantastic folks in the reactwg. Lessons learned while writing this post are available via the &lt;a href="https://github.com/reactwg/react-18/discussions/45#discussioncomment-848441"&gt;reactwg GitHub discussions&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>react18</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Comprehending YAML</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Thu, 11 Feb 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/chantastic/comprehending-yaml-4k82</link>
      <guid>https://dev.to/chantastic/comprehending-yaml-4k82</guid>
      <description>&lt;p&gt;YAML is a little clever for my taste but I'm starting to get it.&lt;/p&gt;

&lt;p&gt;Before &lt;a href="//../a-non-comprehensive-guide-to-yaml-for-folks-who-like-json-just-fine"&gt;yesterday's post&lt;/a&gt;, I had no idea how it related to JSON. In that post I personalized a few examples from the YAML docs and manually converted them.&lt;/p&gt;

&lt;p&gt;And after sleeping on my exercise, I have a better picture of what's going on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;YAML infers complex types&lt;/li&gt;
&lt;li&gt;YAML infers simple types&lt;/li&gt;
&lt;li&gt;YAML shorthand can be confusing&lt;/li&gt;
&lt;li&gt;
YAML patterns

&lt;ul&gt;
&lt;li&gt;Arrays of arrays&lt;/li&gt;
&lt;li&gt;Arrays of objects&lt;/li&gt;
&lt;li&gt;Objects of arrays&lt;/li&gt;
&lt;li&gt;Objects of objects&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;All mixed up&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  YAML infers complex types
&lt;/h2&gt;

&lt;p&gt;As much as possible, YAML infers complex data structures by the data it composes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Evermore&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Folklore&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Lover&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a sequence and the containing Array structure is implied.&lt;br&gt;
Here's how it looks in JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Evermore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Love"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare this to a YAML mapping, where the root structure is implied to be an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Evermore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="na"&gt;Folklore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="na"&gt;Lover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, here's what that looks like in JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Evermore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Lover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what happens if we try to mix sequences and mappings at the root level?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;-Evermore&lt;/span&gt;
&lt;span class="na"&gt;Folklore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="na"&gt;Lover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It breaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;YAMLException: end of the stream or a document separator is expected at line 2, column 9: Folklore: 2020
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tracks because something can't be both an object AND an array.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding inference
&lt;/h3&gt;

&lt;p&gt;Indentifying when you're describing an Array (sequence) and when you're describing an Object (mapping) is critically important. And it's not always clear.&lt;/p&gt;

&lt;p&gt;Can you guess what the JSON equivalent for this YAML is?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Evermore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Folklore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Lover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashes &lt;code&gt;-&lt;/code&gt; indicate that the root structure is an array (sequence). But each array item comprises a descrete object (mapping) with a key-value pair. This is inferred from the colon &lt;code&gt;:&lt;/code&gt; between values in each array item.&lt;/p&gt;

&lt;p&gt;So the JSON output for the YAML above is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Evermore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Lover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An array of objects (or "sequence of mappings").&lt;/p&gt;

&lt;p&gt;Now that I understand it, I see the dash (&lt;code&gt;-&lt;/code&gt;) like list-items in Markdown.&lt;/p&gt;

&lt;h2&gt;
  
  
  YAML infers simple types
&lt;/h2&gt;

&lt;p&gt;Let's take an array (sequence) of objects (mappings).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Evermore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Folklore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Lover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The keys are strings and the values are numbers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Evermore&lt;/code&gt; becomes &lt;code&gt;"Evermore"&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
&lt;code&gt;2020&lt;/code&gt; stays &lt;code&gt;2020&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
&lt;code&gt;Taylor Swift&lt;/code&gt; becomes &lt;code&gt;"Taylor Swift"&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;After looking at so much JavaScript and JSON, this is a little unsettling but — in simple examples like this — there's a simplicity to the representation.&lt;/p&gt;
&lt;h2&gt;
  
  
  YAML shorthand can be confusing
&lt;/h2&gt;

&lt;p&gt;Below we have an array (sequence) of objects (mappings).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The National&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSON looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The National"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does it look like to add more properties to the these objects?&lt;/p&gt;

&lt;p&gt;YAML allows us to use JSON object syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;Taylor Swift&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;9&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;The National&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;8&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it's not super YAML-y. So there's an alternative that uses newlines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The National&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is challenging for me to interpret. Because the dash (&lt;code&gt;-&lt;/code&gt;) is separating discrete objects (mappings) in the array (sequence). So it &lt;em&gt;feels&lt;/em&gt; like the dash (&lt;code&gt;-&lt;/code&gt;) is a directive for the object (mapping). But it's not, it's communicating that the containing structure is an array.&lt;/p&gt;

&lt;p&gt;Pressing into the confusion, consider this array (sequence) containing a string, number, object, and array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1989&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
  &lt;span class="na"&gt;nationality&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;American&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Big Machine&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Republic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is that same file in JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="mi"&gt;1989&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"album_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"nationality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"American"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Big Machine"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Republic"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;The presence of dash (&lt;code&gt;-&lt;/code&gt;) and colon (&lt;code&gt;:&lt;/code&gt;) describe the &lt;em&gt;surrounding&lt;/em&gt; structure.&lt;/p&gt;

&lt;p&gt;In the case of arrays (sequences) of objects (mappings), with multiple key-value pairs, this terseness can be unclear. At least until you've trained ourselves to see the invisble structures that (&lt;code&gt;-&lt;/code&gt;) and (&lt;code&gt;:&lt;/code&gt;) represent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For me, learning to interpret the above line as &lt;code&gt;an object in an array&lt;/code&gt; has made the biggest difference in my ability to quickly parse YAML.&lt;/p&gt;

&lt;h2&gt;
  
  
  YAML patterns
&lt;/h2&gt;

&lt;p&gt;Identifying patterns is helpful.&lt;/p&gt;

&lt;p&gt;Here are a few complex handoffs that I had trouble with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Array of arrays : sequence of sequences
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Evermore&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Folklore&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Lover&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;I Am Easy to Find&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Sleep Well Beast&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Trouble Will Find Me&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This YAML file is an array (sequence) containing two arrays (sequences) each with three strings (scalars).&lt;/p&gt;

&lt;h3&gt;
  
  
  Array of objects : sequence of mappings
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The National&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This YAML file is an array (sequence) referencing two objects (mappings) each with two key-value pairs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Object of arrays : mapping of sequences
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Taylor Swift&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Evermore&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Folklore&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Lover&lt;/span&gt;
&lt;span class="na"&gt;The National&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;I Am Easy to Find&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Sleep Well Beast&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Trouble Will Find Me&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This YAML file is an object (mapping) with two key-value pairs, each key referencing an array (sequence) of strings (scalars).&lt;/p&gt;

&lt;h3&gt;
  
  
  Object of objects : mapping of mappings
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Taylor Swift&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Republic&lt;/span&gt;
&lt;span class="na"&gt;The National&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4AD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This YAML file is an object (mapping) with two key-value pairs, each key referencing another object with two key-value pairs with mixed strings and numbers (scalars) as values.&lt;/p&gt;

&lt;h2&gt;
  
  
  All mixed up
&lt;/h2&gt;

&lt;p&gt;Parse isolated patterns is a good start but the big game is reading entire YAML files.&lt;/p&gt;

&lt;p&gt;Look at this GitHub Actions workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Netlify Rebuild&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;21&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;MON-FRI"&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Netlify Rebuild&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Curl request&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;curl -X POST -d {} https://api.netlify.com/build_hooks/601321b7879709a8b8874175&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what we can evaluate.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The root structure is an object with three properties&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; references a string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on&lt;/code&gt; references an object with one property

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;schedule&lt;/code&gt; references an array with one object containing one property&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cron&lt;/code&gt; references a string&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jobs&lt;/code&gt; referencs an object with one property

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt; references an object with three properties&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; references a string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;runs-on&lt;/code&gt; references a string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;steps&lt;/code&gt; references array with an object containing two properties

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; references a string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;run&lt;/code&gt; references a string&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I think I understand YAML enough to move on with my life. I hope you feel the same way.&lt;/p&gt;

&lt;p&gt;Learning how to identify the implied structures has made all the difference.&lt;/p&gt;

</description>
      <category>yaml</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A Non-Comprehensive Guide to YAML for Folks Who Like JSON Just Fine</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Wed, 10 Feb 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/chantastic/a-non-comprehensive-guide-to-yaml-for-folks-who-like-json-just-fine-22f3</link>
      <guid>https://dev.to/chantastic/a-non-comprehensive-guide-to-yaml-for-folks-who-like-json-just-fine-22f3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;YAML is a human friendly data serialization standard for all programming languages.&lt;br&gt;
— &lt;a href="https://yaml.org"&gt;https://yaml.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don't know precisely which humans YAML is friendly to but I'm not one of them.&lt;/p&gt;

&lt;p&gt;And it looks like the people who run in my circles are also excluded.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1359601176434544640-859" src="https://platform.twitter.com/embed/Tweet.html?id=1359601176434544640"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1359601176434544640-859');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1359601176434544640&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping to JSON
&lt;/h2&gt;

&lt;p&gt;Between Eleventy, GitHub Actions, and a recent foray into serverless, I'm using a more YAML. And I don't understand it.&lt;/p&gt;

&lt;p&gt;This is mapping for my JSON-acquainted brain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comments&lt;/li&gt;
&lt;li&gt;Array of strings&lt;/li&gt;
&lt;li&gt;Array of objects — one value&lt;/li&gt;
&lt;li&gt;Array of objects — many values&lt;/li&gt;
&lt;li&gt;Object of keyed arrays of strings&lt;/li&gt;
&lt;li&gt;Object of keyed objects with mixed values&lt;/li&gt;
&lt;li&gt;Array of arrays with mixed values&lt;/li&gt;
&lt;li&gt;Nodes (variables)&lt;/li&gt;
&lt;li&gt;Sample GitHub Action&lt;/li&gt;
&lt;li&gt;Takeaways&lt;/li&gt;
&lt;li&gt;Resources and further reading&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comments
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# you can put these p much anywhere&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JSON doesn't support comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array of strings
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Sequence of Scalars&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Evermore&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Folklore&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Lover&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Evermore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Love"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Array of objects — single value
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Mapping Scalars to Scalars&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Evermore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Folklore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Lover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Evermore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Lover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Array of objects — many values
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Sequence of Mappings&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Republic&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The National&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4AD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"album_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Republic"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The National"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"album_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4AD"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This syntax confused the shit out of me.&lt;br&gt;&lt;br&gt;
This code is auto-formatted by prettier putting the dash and the first property on the same line.&lt;/p&gt;

&lt;p&gt;YAML docs show the dash and first property on different lines which is much more legible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-
  name: Taylor Swift
  album_count: 9
  label: Republic
-
  name: The National
  album_count: 8
  label: 4AD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Object of keyed arrays of strings
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Mapping Scalars to Sequences&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Taylor Swift&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Evermore&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Folklore&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Lover&lt;/span&gt;
&lt;span class="na"&gt;The National&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;I Am Easy to Find&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Sleep Well Beast&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Trouble Will Find Me&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Evermore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lover"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"The National"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"I Am Easy to Find"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Sleep Well Beast"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Trouble Will Find Me"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Object of keyed objects with mixed values
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Mapping of Mappings&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Taylor Swift&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Republic&lt;/span&gt;
&lt;span class="na"&gt;The National&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4AD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"album_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Republic"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"The National"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"album_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4AD"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Array of arrays with mixed values
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Sequence of Sequences&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;album_count&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Taylor Swift&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;9&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Republic&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;The National&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;8&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;4AD&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"album_count"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Republic"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"The National"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4AD"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nodes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Folklore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Following node labeled TS and AD&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;TS&lt;/span&gt; &lt;span class="s"&gt;Taylor Swift&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;AD&lt;/span&gt; &lt;span class="s"&gt;Aaron Dressner&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Jack Antonoff&lt;/span&gt;
&lt;span class="na"&gt;Lover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;*TS&lt;/span&gt; &lt;span class="c1"&gt;# Subsequent occurrence&lt;/span&gt;
&lt;span class="na"&gt;I Am Easy to Find&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;*AD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No JSON equivalent.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;But this is the output from the above YAML.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Folklore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aaron Dressner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jack Antonoff"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Lover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Taylor Swift"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"I Am Easy to Find"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Aaron Dressner"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sample GitHub Action
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Netlify Rebuild&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;21&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;MON-FRI"&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Netlify Rebuild&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Curl request&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;curl -X POST -d {} https://api.netlify.com/build_hooks/601321b7879709a8b8874175&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Netlify Rebuild"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"on"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"schedule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cron"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0 21 * * MON-FRI"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Netlify Rebuild"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"runs-on"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ubuntu-latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"steps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Curl request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl -X POST -d {} https://api.netlify.com/build_hooks/601321b7879709a8b8874175"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complex types are inferred
&lt;/h3&gt;

&lt;p&gt;The structures of complex types are hidden in YAML.&lt;br&gt;&lt;br&gt;
They get inferred by the structure of included data.&lt;/p&gt;

&lt;p&gt;Keep a look out for &lt;code&gt;-&lt;/code&gt; and &lt;code&gt;:&lt;/code&gt; which indicate the containing structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dash &lt;code&gt;-&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you see a dash &lt;code&gt;-&lt;/code&gt;, it means you're describing a single array item.&lt;br&gt;&lt;br&gt;
This means you're in an array.&lt;/p&gt;

&lt;h3&gt;
  
  
  Colon &lt;code&gt;:&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you see a color &lt;code&gt;:&lt;/code&gt; separating two values, it means your describing a key-value pair.&lt;br&gt;
This means you're in an object.&lt;/p&gt;

&lt;h3&gt;
  
  
  In the wild
&lt;/h3&gt;

&lt;p&gt;Since YAML is used often for configuration, it's likely that your root type is &lt;code&gt;object&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
At least that's the case for Markdown Frontmatter, GitHub Actions, and CloudFormation templates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources and further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://yaml.org/spec/1.2/spec.html#Preview"&gt;Official YAML 1.2 Documentation at yaml.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;YAML to JSON web converters

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jsonformatter.org/yaml-to-json"&gt;https://jsonformatter.org/yaml-to-json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onlineyamltools.com/convert-yaml-to-json"&gt;https://onlineyamltools.com/convert-yaml-to-json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Import Both Default and Named Exports</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Sat, 06 Feb 2021 16:21:15 +0000</pubDate>
      <link>https://dev.to/chantastic/import-both-default-and-named-exports-ml2</link>
      <guid>https://dev.to/chantastic/import-both-default-and-named-exports-ml2</guid>
      <description>&lt;p&gt;We can mix and match import styles to keep code tidy and direct.&lt;/p&gt;

&lt;p&gt;The code below imports both the default export (as &lt;code&gt;cheesburger&lt;/code&gt;) as well as all named exports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cheeseburger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cheese&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;patty&lt;/span&gt;&lt;span class="p"&gt;,}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./cheeseburger.mjs&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;We can tidy it up a smidge by splitting the default export and named export import statements — using a comma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- import {
- default as cheeseburger,
- bun,
- cheese,
- patty,
- } from "./cheeseburger.mjs";
&lt;/span&gt;&lt;span class="gi"&gt;+ import cheeseburger, { bun, cheese, patty } from "./cheeseburger.mjs";
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This eliminates the need to rename the &lt;code&gt;default&lt;/code&gt; on import with &lt;code&gt;as&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What mixed imports are not #
&lt;/h2&gt;

&lt;p&gt;The import position of default and named exports cannot be swapped. When mixing the two, it's always default first then named exports.&lt;/p&gt;

&lt;p&gt;When I first saw this syntax, I assumed that every comma was like a repeaet — a new opportunity to assign local variables. That's not how it is. One comma, after the default, and before the named.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go pro #
&lt;/h2&gt;

&lt;p&gt;This is part of a course I'm building on modules at &lt;a href="https://www.lunch.dev/"&gt;lunch.dev&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
When live, members get access to this and other courses on React.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.lunch.dev/member"&gt;Join lunch.dev for videos&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>modules</category>
    </item>
    <item>
      <title>Import Default From Named Export</title>
      <dc:creator>chantastic</dc:creator>
      <pubDate>Thu, 04 Feb 2021 07:48:02 +0000</pubDate>
      <link>https://dev.to/chantastic/import-default-from-named-export-3j88</link>
      <guid>https://dev.to/chantastic/import-default-from-named-export-3j88</guid>
      <description>&lt;p&gt;Importing &lt;code&gt;default&lt;/code&gt; can be nuanced. There are just so many ways to do it.&lt;/p&gt;

&lt;p&gt;I like to think of &lt;code&gt;default&lt;/code&gt; as a named export with a fixed (non-customizeable) name.&lt;/p&gt;

&lt;p&gt;Check out how we can import &lt;code&gt;default&lt;/code&gt; like a named export.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Highlander&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./highlander.js&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;The lines below yield identical results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- import Highlander from "./highlander.js";
&lt;/span&gt;&lt;span class="gi"&gt;+ import { default as Highlander } from "./highlander.js";
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike named exports, you can't import &lt;code&gt;default&lt;/code&gt; and use it directly. It &lt;strong&gt;must&lt;/strong&gt; be remaned at import. This is why the more ergonomic option of &lt;code&gt;import MyAlias from "…";&lt;/code&gt; exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use default thru a module alias #
&lt;/h2&gt;

&lt;p&gt;We've discussed &lt;a href="https://chan.dev/posts/import-all-named-exports-into-one-variable/"&gt;module aliases in past posts&lt;/a&gt;. And they have some overlap with the &lt;code&gt;default&lt;/code&gt; export.&lt;/p&gt;

&lt;p&gt;Check out this totally valid use of Module aliases and &lt;code&gt;default&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Highlander&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./highlander.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Highlander&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Technically, you're not using the &lt;code&gt;default&lt;/code&gt; keyward because we're accessing the reference as a property.&lt;/p&gt;

&lt;p&gt;Of course, this looks a little strange when used in frameworks like React.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Highlander&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;default&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;Highlander&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  My take #
&lt;/h2&gt;

&lt;p&gt;I don't use &lt;code&gt;default as&lt;/code&gt; or &lt;code&gt;ModuleAlias.default()&lt;/code&gt; import styles in practice. I just find it helpful to remember how &lt;code&gt;default&lt;/code&gt; is exported from modules.&lt;/p&gt;

&lt;p&gt;In future posts, we'll cover two, more ergonomic alternatives capturing both default and named exports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go pro #
&lt;/h2&gt;

&lt;p&gt;This is part of a course I'm creating on modules at &lt;a href="https://www.lunch.dev/"&gt;lunch.dev&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
When live, members get access to this and other courses on React.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.lunch.dev/member"&gt;Join lunch.dev for videos&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>modules</category>
    </item>
  </channel>
</rss>
