
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://adamjohnston.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://adamjohnston.dev/" rel="alternate" type="text/html" /><updated>2025-12-28T14:33:42+00:00</updated><id>https://adamjohnston.dev/feed.xml</id><title type="html">Adam Johnston</title><subtitle>Hi, I&apos;m Adam, a software engineer living in London, working at Bulb. I typically work with JS/TS, React &amp; enjoy learning and using FP. Currently getting back into regular writing.</subtitle><author><name>Adam Johnston</name></author><entry><title type="html">Team values matter</title><link href="https://adamjohnston.dev/posts/team-values-matter" rel="alternate" type="text/html" title="Team values matter" /><published>2024-01-16T00:00:00+00:00</published><updated>2024-01-16T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/team-values-matter</id><content type="html" xml:base="https://adamjohnston.dev/posts/team-values-matter"><![CDATA[<p>For me, team values are a great way to understand what is important to the team and provide context for the things we believe in. When I set out to create the values for my team I wanted to build a foundation for the team to grow from, based on the values that most resonated with all of us. After some consoltation and some creative writing we defined the following three team values.</p>

<h2 id="the-values">The values</h2>

<h3 id="be-a-pillar">Be a pillar</h3>

<p>The team is there for one another, be it to help with day-to-day work or something more personal, we strive to support one-another through good and bad times.</p>

<p>It means understanding that people in the team have strengths and weaknesses and we grow together. We tackle problems head-on as a group to get the best outcomes.</p>

<p>We trust one another that we’re doing the right things at the right times. We avoid micro managing and we assume best intentions when something goes wrong. We work together to find a solution but we accept some of us need space to themselves at times.</p>

<h3 id="courage-to-be-curious">Courage to be curious</h3>

<p>We challenge ourselves to question how can we make things better? Where can we add value? How do we grow, develop and change? We use curiosity as an antidote to stagnation as a product and as a team.</p>

<p>We stay curious to keep work interesting and stretch ourselves to achieve new things. We’ll get things wrong and we’ll fail but we don’t point fingers and single others out. Instead we come together as a team to fix and make them better.</p>

<p>When mistakes are made we assume they were made with the best of intentions. We keep disagreements respectful and we don’t put others down. If we’re scared to experiment we won’t try new things.</p>

<h3 id="ave-a-laff">‘Ave a laff!</h3>

<p>We work in a light-hearted way, do our best not to let things worry us, keep our humour and find times have a laugh and a joke inside and outside of work.</p>

<p>We like to keep our work exciting and aim to involve all members of the team in our process. We don’t expect people to be code monkeys, pixel pushers or gantt chart trackers.</p>

<p>Fun strengthens the bonds between us and playfulness builds trust. With all this said we take what we do seriously when it matters.</p>

<h2 id="why-values-matter">Why values matter</h2>

<p>I’ve worked at many companies that have missions and values, but I haven’t worked in teams that had them. It’s not that those teams didn’t have any values but what values they had were implicit and/or ambiguous. Company values have helped coordinate a group of individuals and steered these companies. I think team values can do the same.</p>

<p>A personal favourite company value of mine was Kahoot!’s ‘make learning awesome’. A value so core to the company at the time that it featured promonately at the top of the homepage. I remember several times during discussions where someone may ask the question, ‘is this making learning awesome?’. That wouldn’t just come from the CEO or CPO but from designers, product managers and engineers.</p>

<p>So while reading through some of the opening pages of <a href="https://g.co/kgs/N2pb2cG">Sarah Drasner’s Engineering Management for the Rest of Us</a> it inspired me to realise the benefits of what values could bring to a team. I recommend reading the book if you’re also starting out as an engineering manager too.</p>

<figure>
  <img src="/assets/images/kahoot-make-learning-awesome.jpeg" alt="Kahoot! webpage banner from 2016" />
  <figcaption>Kahoot!'s webpage banner with the value; Make learning awesome from 2016</figcaption>
</figure>

<h2 id="defining-the-values">Defining the values</h2>

<p>Following the suggestion outlined in Sarah Drasner’s book I created a Miro with a collection of various words. Some taken directly from the book and some of my own additions. Here’s a few examples of the kind of words that were included. Accountability, fun, vision, trust &amp; curiosity.</p>

<p>Once the collection was gathered, I invited the team to vote for three of the words that most resonated with them. With all the votes cast we then organised a follow-up discussion. We began by digging into the most voted for word to the least and I took notes based on what the team reflected upon.</p>

<p>Here are some of the raw notes I took from that discussion:</p>

<blockquote>
  <p><strong>Curiosity</strong>: Love curiosity in general as it can be a good antidote to judgement. When we’re in a challenging environment it’s healthy.</p>
</blockquote>

<blockquote>
  <p><strong>Fun</strong>: The way we work is light hearted. We don’t let things worry us and we get through difficulties. Find time to have a laugh.</p>
</blockquote>

<blockquote>
  <p><strong>Blame free</strong>: It’s okay to fail. It’s okay to make mistakes. If you’re scared of making mistakes then you won’t try things, you’ll be less curious and reluctant.</p>
</blockquote>

<p>From these notes I then put on my creative writing hat and got to work grouping and distilling the essence of what I had heard into three to five values. Once I was happy with what I had, I shared it with the team to further refine them together. This process repeated until we were all in agreement and we had the three values you read above.</p>

<h2 id="reflections-on-team-values">Reflections on team values</h2>

<p>I was very happy with the values that we defined as a team. I think they captured how the team was at the time and I found myself referring back to them on occasion during one to ones with various members of my team.</p>

<p>I do believe there was more I could have done to have made them more impactful on a regular basis. When a worry was flagged to me from a member of the team, I could have cited our team values back to them as a way of saying, you don’t need to worry, as a team we expect these things, we understand them and we’ve accounted for them in our values.</p>

<p>Onboarding new people to the team could be made easier by providing them with the team values ahead of them joining. I think that could give them an idea of the ways we work and what behaviours they can expect.</p>

<p>Values don’t need to be set in stone. Teams change, companies change and people come and go. While values form a good basis for working together, I think they should be adaptable. If you’re a start-up or rapidly experimenting then some of your values may reflect this but when you’ve matured you might find the same values no longer reflect as well as they once had. I think it’s okay to repeat the process and define new ones.</p>

<p>So that’s what I have on values. I hope this got you to consider your team’s values and whether codifying and making them explicit would be beneficial to you. I know I will certainly look to define future values with future teams.</p>]]></content><author><name>Adam Johnston</name></author><category term="eng management" /><category term="values" /><summary type="html"><![CDATA[For me, team values are a great way to understand what is important to the team and provide context for the things we believe in. When I set out to create the values for my team I wanted to build a foundation for the team to grow from, based on the values that most resonated with all of us. After some consoltation and some creative writing we defined the following three team values.]]></summary></entry><entry><title type="html">Mapping components in Svelte vs React</title><link href="https://adamjohnston.dev/posts/mapping-components-svelte-vs-react" rel="alternate" type="text/html" title="Mapping components in Svelte vs React" /><published>2023-09-24T00:00:00+00:00</published><updated>2023-09-24T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/mapping-components-svelte-vs-react</id><content type="html" xml:base="https://adamjohnston.dev/posts/mapping-components-svelte-vs-react"><![CDATA[<h2 id="intro">Intro</h2>

<p>I recently made the switch from React over to Svelte (something I might write about in the future but that’ll need to be for another day).</p>

<p>While working on a personal project I am learning about Svelte &amp; SvelteKit as I go while mostly rely on my existing React knowledge and then trying to understand the Svelte approach when things don’t work as I expect them to.</p>

<p>I wanted on a reusable <code class="language-plaintext highlighter-rouge">List</code> component. The idea of this component is that it takes a list of items as a prop and then loops over them creating a HTML structure of a <code class="language-plaintext highlighter-rouge">ul</code> with content contained within <code class="language-plaintext highlighter-rouge">li</code>s.</p>

<p>The benefit of this component is that you can put anything you want within the <code class="language-plaintext highlighter-rouge">li</code> but the styling of the list has already been defined.</p>

<p>It’s pretty straightforward but making this component in Svelte was a little more involved than I was expecting it to be and required the use of some Svelte that I had not seen before so I thought I’d document what I needed to do.</p>

<h2 id="react">React</h2>

<p>First let’s look at how I would typically build this kind of component in React. Our <code class="language-plaintext highlighter-rouge">List</code> component is responsible for looping over a list of items it receives via props. We do this using the <code class="language-plaintext highlighter-rouge">map</code> method and returning a new list with an <code class="language-plaintext highlighter-rouge">li</code> and the item inside:</p>

<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="kd">type</span> <span class="nx">ReactNode</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">react</span><span class="dl">'</span>

<span class="kd">type</span> <span class="nx">Props</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">items</span><span class="p">:</span> <span class="nx">ReactNode</span><span class="p">[]</span>
<span class="p">}</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">List</span><span class="p">:</span> <span class="nx">React</span><span class="p">.</span><span class="nx">FC</span><span class="o">&lt;</span><span class="nx">Props</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">items</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return </span><span class="p">(</span>
    <span class="p">&lt;</span><span class="nt">ul</span> <span class="na">style</span><span class="p">=&gt;</span>
      <span class="si">{</span><span class="nx">items</span><span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">item</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span>
        <span class="p">&lt;</span><span class="nt">li</span> <span class="na">style</span><span class="p">=&gt;</span><span class="si">{</span><span class="nx">item</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
      <span class="p">))</span><span class="si">}</span>
    <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
  <span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The basic component we want to put within our <code class="language-plaintext highlighter-rouge">li</code> for this example is a <code class="language-plaintext highlighter-rouge">Card</code> component. It simply has some padding and border and takes some copy via props:</p>

<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Props</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">copy</span><span class="p">:</span> <span class="kr">string</span>
<span class="p">}</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">Card</span><span class="p">:</span> <span class="nx">React</span><span class="p">.</span><span class="nx">FC</span><span class="o">&lt;</span><span class="nx">Props</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">copy</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return </span><span class="p">(</span>
    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">style</span><span class="p">=&gt;</span><span class="si">{</span><span class="nx">copy</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
  <span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>To then use our <code class="language-plaintext highlighter-rouge">List</code> component we just need to add a list of React components, in this case <code class="language-plaintext highlighter-rouge">Card</code>. The cards and their copy will then be rendered within our <code class="language-plaintext highlighter-rouge">ul</code> and <code class="language-plaintext highlighter-rouge">li</code>s:</p>

<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">root</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span>
  <span class="p">&lt;</span><span class="nc">React</span><span class="p">.</span><span class="nc">StrictMode</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nc">List</span> <span class="na">items</span><span class="p">=</span><span class="si">{</span><span class="p">[&lt;</span><span class="nc">Card</span> <span class="na">copy</span><span class="p">=</span><span class="s">"a"</span> <span class="p">/&gt;,</span> <span class="p">&lt;</span><span class="nc">Card</span> <span class="na">copy</span><span class="p">=</span><span class="s">"b"</span> <span class="p">/&gt;,</span> <span class="p">&lt;</span><span class="nc">Card</span> <span class="na">copy</span><span class="p">=</span><span class="s">"c"</span> <span class="p">/&gt;]</span><span class="si">}</span> <span class="p">/&gt;</span>
  <span class="p">&lt;/</span><span class="nc">React</span><span class="p">.</span><span class="nc">StrictMode</span><span class="p">&gt;</span>
<span class="p">)</span>
</code></pre></div></div>

<p>This will then show a list of cards with <code class="language-plaintext highlighter-rouge">a</code>, <code class="language-plaintext highlighter-rouge">b</code> &amp; <code class="language-plaintext highlighter-rouge">c</code> in the browser. You can <a href="https://codesandbox.io/s/react-list-component-example-zvc2wp" target="_blank" no-referrer="" no-opener="">view the example in Codesandbox</a>.</p>

<h2 id="svelte">Svelte</h2>

<p>So how do we do the same in Svelte? Well it’s a little different than it is in React. We need to make use of a special Svelte element called <a href="https://svelte.dev/docs/special-elements#svelte-component" target="_blank" no-referrer="" no-opener="">svelte:component<a></a>.</a></p>

<p>This special element allows for dynamic component rendering. Using the <code class="language-plaintext highlighter-rouge">this</code> prop we can tell the <code class="language-plaintext highlighter-rouge">svelte:component</code> what component it needs to be. We can then pass any props we want to it.</p>

<p>Since we can’t know what props will be needed for all components ahead of time we need to spread all the props and leave the component to figure it:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
  <span class="k">export</span> <span class="kd">let</span> <span class="nx">items</span><span class="p">;</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span>
<span class="o">&lt;</span><span class="nx">style</span><span class="o">&gt;</span>
  <span class="nx">ul</span> <span class="p">{</span>
    <span class="nl">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span>
    <span class="nl">padding</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span>
    <span class="nx">list</span><span class="o">-</span><span class="nx">style</span><span class="p">:</span> <span class="nx">none</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="nx">li</span> <span class="o">+</span> <span class="nx">li</span> <span class="p">{</span>
    <span class="nx">margin</span><span class="o">-</span><span class="nx">top</span><span class="p">:</span> <span class="mi">1</span><span class="nx">rem</span><span class="p">;</span>
  <span class="p">}</span>
<span class="o">&lt;</span><span class="sr">/style</span><span class="err">&gt;
</span>
<span class="o">&lt;</span><span class="nx">ul</span><span class="o">&gt;</span>
  <span class="p">{</span><span class="nx">#each</span> <span class="nx">items</span> <span class="kd">as </span><span class="nx">item</span><span class="p">}</span>
    <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;</span>
      <span class="o">&lt;</span><span class="nx">svelte</span><span class="p">:</span><span class="nx">component</span> <span class="k">this</span><span class="o">=</span><span class="p">{</span><span class="nx">item</span><span class="p">.</span><span class="nx">component</span><span class="p">}</span> <span class="p">{...</span><span class="nx">item</span><span class="p">}</span> <span class="sr">/</span><span class="err">&gt;
</span>    <span class="o">&lt;</span><span class="sr">/li</span><span class="err">&gt;
</span>  <span class="p">{</span><span class="sr">/each</span><span class="err">}
</span><span class="o">&lt;</span><span class="sr">/ul</span><span class="err">&gt;
</span></code></pre></div></div>

<p>Our <code class="language-plaintext highlighter-rouge">Card</code> component in Svelte is very similar to the React version. It expects a <code class="language-plaintext highlighter-rouge">copy</code> prop to be passed so that it can render it within a <code class="language-plaintext highlighter-rouge">div</code> and applies some basic styling:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
  <span class="k">export</span> <span class="kd">let</span> <span class="nx">copy</span><span class="p">;</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span>
<span class="o">&lt;</span><span class="nx">style</span><span class="o">&gt;</span>
  <span class="nx">div</span> <span class="p">{</span>
    <span class="nl">padding</span><span class="p">:</span> <span class="mi">1</span><span class="nx">rem</span><span class="p">;</span>
    <span class="nl">border</span><span class="p">:</span> <span class="mi">1</span><span class="nx">px</span> <span class="nx">solid</span> <span class="nx">grey</span><span class="p">;</span>
  <span class="p">}</span>
<span class="o">&lt;</span><span class="sr">/style</span><span class="err">&gt;
</span>
<span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
  <span class="p">{</span><span class="nx">copy</span><span class="p">}</span>
<span class="o">&lt;</span><span class="sr">/div</span><span class="err">&gt;
</span></code></pre></div></div>

<p>Usage of the <code class="language-plaintext highlighter-rouge">List</code> component then requires us to pass a list of objects. One that states which component to use; in our case, <code class="language-plaintext highlighter-rouge">Card</code> and then any of the expected props that it needs.</p>

<p>It’s a little more verbose compared to the React version but in principle, it’s the same:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
  <span class="k">import</span> <span class="nx">Card</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./Card.svelte</span><span class="dl">'</span>
  <span class="k">import</span> <span class="nx">List</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./List.svelte</span><span class="dl">'</span>

  <span class="kd">let</span> <span class="nx">items</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">{</span>
      <span class="na">component</span><span class="p">:</span> <span class="nx">Card</span><span class="p">,</span>
      <span class="na">copy</span><span class="p">:</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span>
    <span class="p">},</span>
    <span class="p">{</span>
      <span class="na">component</span><span class="p">:</span> <span class="nx">Card</span><span class="p">,</span>
      <span class="na">copy</span><span class="p">:</span> <span class="dl">'</span><span class="s1">b</span><span class="dl">'</span>
    <span class="p">},</span>
    <span class="p">{</span>
      <span class="na">component</span><span class="p">:</span> <span class="nx">Card</span><span class="p">,</span>
      <span class="na">copy</span><span class="p">:</span> <span class="dl">'</span><span class="s1">c</span><span class="dl">'</span>
    <span class="p">}</span>
  <span class="p">]</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span>
<span class="o">&lt;</span><span class="nx">main</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="nx">List</span> <span class="p">{</span><span class="nx">items</span><span class="p">}</span> <span class="sr">/</span><span class="err">&gt;
</span><span class="o">&lt;</span><span class="sr">/main</span><span class="err">&gt;
</span></code></pre></div></div>

<p>This will then show a list of cards with <code class="language-plaintext highlighter-rouge">a</code>, <code class="language-plaintext highlighter-rouge">b</code> &amp; <code class="language-plaintext highlighter-rouge">c</code> in the browser. You can <a href="https://codesandbox.io/s/svelte-list-component-example-l279yw" target="_blank" no-referrer="" no-opener="">view the example in Codesandbox</a>.</p>

<p>Hopefully this is helpful for others since it took a bit of googling to find out how to do this kind of component in Svelte.</p>]]></content><author><name>Adam Johnston</name></author><category term="svelte" /><category term="react" /><category term="frontend" /><summary type="html"><![CDATA[Intro]]></summary></entry><entry><title type="html">VSpace component using Vanilla Extract</title><link href="https://adamjohnston.dev/posts/vspace-component-using-vanilla-extract" rel="alternate" type="text/html" title="VSpace component using Vanilla Extract" /><published>2023-04-08T00:00:00+00:00</published><updated>2023-04-08T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/vspace-component-using-vanilla-extract</id><content type="html" xml:base="https://adamjohnston.dev/posts/vspace-component-using-vanilla-extract"><![CDATA[<h2 id="what-is-a-vspace">What is a VSpace?</h2>

<p>VSpace is a utility component that I learned of and used quite a bit during my time at Bulb. Essentially it provides vertical space/rhythm to its direct descendants. You can <a href="https://design.bulb.co.uk/components/vspace/">read more about VSpace on the Bulb design system website</a>.</p>

<p>It’s a useful component for controlling layout without writing lots of styling and it is versatile as it allows you to render it as any element of your choosing using an <code class="language-plaintext highlighter-rouge">as</code> prop and provide different spacing tokens. The one thing it relies heavily on is lobotomised owls.</p>

<h2 id="lobotomised-owls">Lobotomised owls?</h2>

<p>Lobotomised owls is a slightly odd looking combination of <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors">CSS selectors</a>. The CSS selector is <code class="language-plaintext highlighter-rouge">* + *</code> which according to the author (who also briefly worked for Bulb) thinks it looks like an owl that’s had a lobotomy.</p>

<p>A quick break down of this selector; The <code class="language-plaintext highlighter-rouge">*</code> is the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors">universal selector</a> which means it will match against any element, followed by the <code class="language-plaintext highlighter-rouge">+</code> which is the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator">adjacent sibling combinator</a> and finally another universal selector. All this together means, whatever the first element is, apply some styling to whatever sibling element follows after it and any element after that and so on and so on.</p>

<h2 id="vanilla-extract">Vanilla Extract?</h2>

<p>So what’s the deal with <a href="https://vanilla-extract.style/">Vanilla Extract</a>? It describes itself as:</p>

<quote>Use TypeScript as your preprocessor. Write type‑safe, locally scoped classes, variables and themes, then generate static CSS files at build time.</quote>

<p>It seems like a cool library but today is my first time using it. One thing that makes creating the lobotomised owl selector difficult with Vanilla Extract is the bit about “locally scoped classes, variables and themes”.</p>

<p>Because the selector relies on affecting child elements, that’s considered a no, no to Vanilla Extract, although they do provide some escape hatches that allow it to be done but figuring out how was quite an interesting bit of learning.</p>

<h2 id="implementation">Implementation</h2>

<h3 id="the-vspace-react-component">The VSpace React component</h3>

<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * VSpace.tsx
 */</span>

<span class="k">import</span> <span class="p">{</span> <span class="nx">createElement</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">react</span><span class="dl">'</span>
<span class="k">import</span> <span class="o">*</span> <span class="kd">as </span><span class="nx">styles</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./VSpace.css</span><span class="dl">'</span>

<span class="kd">type</span> <span class="nx">Props</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">PropsWithChildren</span><span class="o">&lt;</span><span class="p">{</span>
  <span class="nx">spacing</span><span class="p">?:</span> <span class="kr">keyof</span> <span class="k">typeof</span> <span class="nx">styles</span><span class="p">.</span><span class="nx">spacings</span>
  <span class="nx">as</span><span class="p">?:</span> <span class="kr">keyof</span> <span class="nx">React</span><span class="p">.</span><span class="nx">ReactHTML</span>
<span class="p">}</span><span class="o">&gt;</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">VSpace</span><span class="p">:</span> <span class="nx">React</span><span class="p">.</span><span class="nx">FC</span><span class="o">&lt;</span><span class="nx">Props</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">({</span>
  <span class="nx">children</span><span class="p">,</span>
  <span class="nx">spacing</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">s_1</span><span class="dl">'</span><span class="p">,</span>
  <span class="kd">as </span><span class="o">=</span> <span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">,</span>
<span class="p">})</span> <span class="o">=&gt;</span> <span class="nf">createElement</span><span class="p">(</span><span class="nx">as</span><span class="p">,</span> <span class="p">{</span> <span class="na">className</span><span class="p">:</span> <span class="nx">styles</span><span class="p">.</span><span class="nx">spacer</span><span class="p">[</span><span class="nx">spacing</span><span class="p">]</span> <span class="p">},</span> <span class="nx">children</span><span class="p">)</span>
</code></pre></div></div>

<p>The component takes three props, <code class="language-plaintext highlighter-rouge">children</code> which are any child components. <code class="language-plaintext highlighter-rouge">as</code> is used to change the element type that will be rendered. Since this is used for layout I default to <code class="language-plaintext highlighter-rouge">div</code>. Lastly <code class="language-plaintext highlighter-rouge">spacing</code> which represents a design token for our spacings. In this example we default to <code class="language-plaintext highlighter-rouge">s_1</code> which maps to <code class="language-plaintext highlighter-rouge">1rem</code>. I’ve used <code class="language-plaintext highlighter-rouge">createElement</code> as I find it makes it easier to use <code class="language-plaintext highlighter-rouge">as</code> with and I’ve also explicitly not allowed additional props to be passed in.</p>

<h3 id="styles">Styles</h3>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * VSpace.css.ts
 */</span>

<span class="k">import</span> <span class="p">{</span>
  <span class="nx">createVar</span><span class="p">,</span>
  <span class="nx">globalStyle</span><span class="p">,</span>
  <span class="nx">style</span><span class="p">,</span>
  <span class="nx">styleVariants</span><span class="p">,</span>
<span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@vanilla-extract/css</span><span class="dl">'</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">spacings</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">s_0_25</span><span class="p">:</span> <span class="dl">'</span><span class="s1">0.25rem</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">s_0_5</span><span class="p">:</span> <span class="dl">'</span><span class="s1">0.5rem</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">s_1</span><span class="p">:</span> <span class="dl">'</span><span class="s1">1rem</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">s_2</span><span class="p">:</span> <span class="dl">'</span><span class="s1">2rem</span><span class="dl">'</span><span class="p">,</span>
  <span class="c1">// …</span>
<span class="p">}</span>

<span class="cm">/**
 * CSS custom property that will be passed to the lobotomised owl as margin-top.
 */</span>
<span class="kd">const</span> <span class="nx">spacing</span> <span class="o">=</span> <span class="nf">createVar</span><span class="p">()</span>

<span class="cm">/**
 * Base styling to compose with the variants.
 */</span>
<span class="kd">const</span> <span class="nx">base</span> <span class="o">=</span> <span class="nf">style</span><span class="p">({})</span>

<span class="cm">/**
 * The spacer gets the custom property and assigns the desired spacing to it.
 */</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">spacer</span> <span class="o">=</span> <span class="nf">styleVariants</span><span class="p">(</span><span class="nx">spacings</span><span class="p">,</span> <span class="p">(</span><span class="nx">spacingKey</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span>
  <span class="nx">base</span><span class="p">,</span>
  <span class="p">{</span>
    <span class="na">vars</span><span class="p">:</span> <span class="p">{</span>
      <span class="p">[</span><span class="nx">spacing</span><span class="p">]:</span> <span class="nx">spacingKey</span><span class="p">,</span>
    <span class="p">},</span>
  <span class="p">},</span>
<span class="p">])</span>

<span class="cm">/**
 * Global styles are required due to affecting children and so break the
 * component isolation enforced by vanilla extract.
 */</span>
<span class="nf">globalStyle</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">base</span><span class="p">}</span><span class="s2"> &gt; * + *`</span><span class="p">,</span> <span class="p">{</span>
  <span class="na">margin</span><span class="p">:</span> <span class="s2">`</span><span class="p">${</span><span class="nx">spacing</span><span class="p">}</span><span class="s2"> 0 0`</span><span class="p">,</span>
<span class="p">})</span>

</code></pre></div></div>]]></content><author><name>Adam Johnston</name></author><category term="react" /><category term="css" /><summary type="html"><![CDATA[What is a VSpace?]]></summary></entry><entry><title type="html">Learning Rust №1 - Writing a map function</title><link href="https://adamjohnston.dev/posts/learning-rust-1-writing-a-map-function" rel="alternate" type="text/html" title="Learning Rust №1 - Writing a map function" /><published>2022-12-18T00:00:00+00:00</published><updated>2022-12-18T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/learning-rust-1-writing-a-map-function</id><content type="html" xml:base="https://adamjohnston.dev/posts/learning-rust-1-writing-a-map-function"><![CDATA[<h2 id="what-is-map">What is map?</h2>

<p>Map is a common higher order function which takes a list, loops over said list and applies a given function against each item creating a new list from the results. For example, say we have a list of numbers <code class="language-plaintext highlighter-rouge">[1, 2, 3]</code> and we have a function that adds one to a number <code class="language-plaintext highlighter-rouge">number =&gt; number + 1</code>, when we loop over our list with this function we will have a new list containing <code class="language-plaintext highlighter-rouge">[2, 3, 4]</code>. <a href="https://en.wikipedia.org/wiki/Map_(higher-order_function)">Read more about Map on Wikipedia</a></p>

<h2 id="writing-a-map-function-in-rust">Writing a map function in Rust</h2>

<p>Something to note is that <a href="https://doc.rust-lang.org/std/iter/struct.Map.html">Rust ships its own Map function in its standard library</a> but as a learning exercise I feel a good way to learn the language is to implement things you already know. So this is my current understanding of how to implement map in Rust. Not sure it’s the most performant it could be or even very elegant code but I think it’s readable for the most part.</p>

<div class="language-rs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="o">&gt;</span><span class="p">(</span><span class="n">list</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">mapper</span><span class="p">:</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span> <span class="nf">Fn</span><span class="p">(</span><span class="o">&amp;</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">B</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">B</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">mapped</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">B</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nn">Vec</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

    <span class="k">for</span> <span class="n">item</span> <span class="k">in</span> <span class="n">list</span> <span class="p">{</span>
        <span class="n">mapped</span><span class="nf">.push</span><span class="p">(</span><span class="nf">mapper</span><span class="p">(</span><span class="n">item</span><span class="p">));</span>
    <span class="p">}</span>

    <span class="n">mapped</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">numbers</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">];</span>
    <span class="k">let</span> <span class="n">squared</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nf">map</span><span class="p">(</span><span class="o">&amp;</span><span class="n">numbers</span><span class="p">,</span> <span class="nn">Box</span><span class="p">::</span><span class="nf">new</span><span class="p">(|</span> <span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">u32</span> <span class="p">|</span> <span class="n">x</span> <span class="o">*</span> <span class="n">x</span><span class="p">));</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Mapped {:?}"</span><span class="p">,</span> <span class="n">squared</span><span class="p">);</span> <span class="c1">// [4, 9, 16]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So lets break this down and share my current understanding of how this works. I’ll skip over <code class="language-plaintext highlighter-rouge">main</code> as its purpose is to run the program and simply print the result which is <code class="language-plaintext highlighter-rouge">[4, 9, 16]</code>.</p>

<h2 id="passing-values-by-reference-or-borrowing">Passing values by reference or borrowing</h2>

<p>One unique aspect of Rust is its ownership system. We don’t want to give the <code class="language-plaintext highlighter-rouge">map</code> function the ownership of the original list, in the example <code class="language-plaintext highlighter-rouge">numbers</code>. The reason for this is we expect to return a new list which would mean that <code class="language-plaintext highlighter-rouge">numbers</code> would go out of scope and be cleared. If we passed the original list then you’d not be able to use the after calling <code class="language-plaintext highlighter-rouge">map</code> with it. To avoid this we pass it by reference.</p>

<div class="language-rs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// list is owned by map.</span>
<span class="k">fn</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="o">&gt;</span><span class="p">(</span><span class="n">list</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">mapper</span><span class="p">:</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span> <span class="nf">Fn</span><span class="p">(</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">B</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">B</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="c1">// …</span>
<span class="p">}</span>

<span class="c1">// list is borrowed as denoted by &amp;Vec&lt;A&gt; which also means that the </span>
<span class="c1">// closure that is provided as a mapper fn receives an item value </span>
<span class="c1">// also by reference.</span>
<span class="k">fn</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="o">&gt;</span><span class="p">(</span><span class="n">list</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">mapper</span><span class="p">:</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span> <span class="nf">Fn</span><span class="p">(</span><span class="o">&amp;</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">B</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">B</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="c1">// …</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="box-and-dynamic-values-at-runtime">Box and dynamic values at runtime</h2>

<p>For values that cannot be determined (<a href="https://doc.rust-lang.org/std/marker/trait.Sized.html">maybe sized</a>) at runtime, you need to wrap it in <code class="language-plaintext highlighter-rouge">Box</code> along with the <code class="language-plaintext highlighter-rouge">dyn</code> keyword. This means this value will be allocated to heap memory rather than the stack. This makes writing the closure function a bit annoying and likely less performant. I am sure there’s ways around this but I am not sure how right now.</p>

<div class="language-rs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">Box</span><span class="p">::</span><span class="nf">new</span><span class="p">(|</span> <span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">u32</span> <span class="p">|</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<h2 id="using-rusts-map-function">Using Rust’s map function</h2>

<p>To do the above with Rust’s built in map function would look something like this:</p>

<div class="language-rs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">numbers</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">];</span>
    <span class="k">let</span> <span class="n">squared</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">numbers</span><span class="nf">.iter</span><span class="p">()</span><span class="nf">.map</span><span class="p">(|</span><span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">u32</span><span class="p">|</span> <span class="n">x</span> <span class="o">*</span> <span class="n">x</span><span class="p">)</span><span class="py">.collect</span><span class="p">::</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;&gt;</span><span class="p">();</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Mapped {:?}"</span><span class="p">,</span> <span class="n">squared</span><span class="p">)</span> <span class="c1">// [4, 9, 16]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So let’s dig into this. We take our vector which is a collection, we turn it into an iterator by calling <code class="language-plaintext highlighter-rouge">.iter()</code>, once we have an iterator we can call <code class="language-plaintext highlighter-rouge">.map()</code> which returns a new iterator so finally we call <code class="language-plaintext highlighter-rouge">.collect()</code> to turn it back into a collection.</p>]]></content><author><name>Adam Johnston</name></author><category term="rust" /><summary type="html"><![CDATA[What is map?]]></summary></entry><entry><title type="html">Connecting to a PostgreSQL Docker container using Node &amp;amp; Slonik</title><link href="https://adamjohnston.dev/posts/connecting-to-a-postgresql-docker-container-using-node-and-slonik" rel="alternate" type="text/html" title="Connecting to a PostgreSQL Docker container using Node &amp;amp; Slonik" /><published>2021-12-31T00:00:00+00:00</published><updated>2021-12-31T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/connecting-to-a-postgresql-docker-container-using-node-and-slonik</id><content type="html" xml:base="https://adamjohnston.dev/posts/connecting-to-a-postgresql-docker-container-using-node-and-slonik"><![CDATA[<p>So I recently started a new project (which I will totally see through to completion). In the course of reliving the joys of configuring a project from scratch, I reached the point where I was ready to hook up my web <acronym title="Application Programming Interface">API</acronym> to a database. It turned out to be a little more frustrating than I’d expected it to be, after all I’d done it once before about a year ago so of course it should be fresh in my mind. Sarcasm aside I’m writing this to hopefully solidify it in my brain and failing that at least have this as a reference.</p>

<h2 id="some-context">Some context</h2>

<p>Before jumping in I just wanted to add some context. I am approaching the architecture of this project in a micro-service-like way. The project is a single mono-repo broken into clients (<abbr title="User Interface">UI</abbr>s), services (<acronym title="Application Programming Interface">API</acronym>s) and utils (Shareable code). I think the benefit to this is approach will be to keep different parts of the project isolated and individually deployable, however it could always be bundled as a single image (I think so anyway, I guess I’ll find out).</p>

<p>Below is a snapshot of the rough shape of the project with some files not shown as they’re mostly configuration:</p>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">clients</span>
<span class="n">utils</span>
<span class="n">services</span> <span class="err">↴</span>
<span class="err">··</span><span class="n">service</span> <span class="n">A</span> <span class="err">↴</span>
<span class="err">····</span><span class="n">src</span> <span class="err">↴</span>
<span class="err">······</span><span class="n">api</span> <span class="err">↴</span>
<span class="err">········</span><span class="n">api</span>
<span class="err">········</span><span class="n">routes</span>
<span class="err">········</span><span class="n">controller</span>
<span class="err">········</span><span class="n">service</span>
<span class="err">······</span><span class="n">db</span>
<span class="err">······</span><span class="n">config</span>
<span class="err">······</span><span class="n">main</span>
<span class="err">····</span><span class="n">tests</span> <span class="err">↴</span>
<span class="err">······</span><span class="n">integration</span>
<span class="err">····</span><span class="p">.</span><span class="n">env</span>
<span class="err">····</span><span class="n">docker</span><span class="o">-</span><span class="n">compose</span><span class="p">.</span><span class="n">yml</span>
<span class="err">····</span><span class="n">package</span><span class="p">.</span><span class="n">json</span>
</code></pre></div></div>

<h2 id="docker-compose-configuration-file">Docker Compose configuration file</h2>

<p>So in keeping with the idea of isolation each service will have it’s own <acronym title="Database">DB</acronym> (again, potentially since each service could be configured to point to a single <acronym title="Database">DB</acronym> at deployment) I opted to use Docker Compose to easily grab a PostgreSQL image and spin it up when the service starts. Here’s a look at the <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> as I have it right now. I’ll walk through and point out things that might be of interest if you’re not familiar with using Docker Compose.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">3.9'</span>

<span class="na">services</span><span class="pi">:</span>
  <span class="na">db</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s1">'</span><span class="s">postgres:14.1-alpine'</span>
    <span class="na">container_name</span><span class="pi">:</span> <span class="s">service_a_db</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">always</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="na">POSTGRES_USER</span><span class="pi">:</span> <span class="s">service_a</span>
      <span class="na">POSTGRES_PASSWORD</span><span class="pi">:</span> <span class="s">super_secret</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">5000:5432</span>
</code></pre></div></div>

<h3 id="config-breakdown">Config breakdown</h3>

<ul>
  <li>
    <p><strong>version</strong><br />
The version is optional since v1.27.0 of Docker Compose however I feel it doesn’t hurt to include it.</p>
  </li>
  <li>
    <p><strong>services</strong><br />
This is a list of services you want to spin up using Docker. In my case I just want a single service, a <acronym title="Database">DB</acronym>, that service being the one I’ve named <code class="language-plaintext highlighter-rouge">db</code>. You can call yours Jim if you prefer.</p>
  </li>
  <li>
    <p><a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#image"><strong>image</strong></a><br />
This if the Docker image I want to create a container from. It’s an <a href="https://hub.docker.com/_/postgres">official image on DockerHub for PostgreSQL</a>. I’ve used the version tag so I can be certain that as new versions of PostgreSQL are released I am still developing and testing against the same as what my production environment is using. <em>alpine</em> denotes that this is a minimal sized container.</p>
  </li>
  <li>
    <p><a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#container_name"><strong>container_name</strong></a><br />
This is optional but it is handy to help find your container once it’s up and running. If you omit it you’ll be given a default name. To check this is set correctly you can run the following command; <code class="language-plaintext highlighter-rouge">docker ps</code>. <code class="language-plaintext highlighter-rouge">docker ps</code> shows you a list of containers. You should see something like this:</p>

    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CONTAINER ID   IMAGE                  COMMAND                  CREATED        STATUS       PORTS                    NAMES
51f30726c405   postgres:14.1-alpine   <span class="s2">"docker-entrypoint.s…"</span>   26 hours ago   Up 9 hours   0.0.0.0:5000-&gt;5432/tcp   service_a_db
</code></pre></div>    </div>
  </li>
  <li>
    <p><a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#restart"><strong>restart</strong></a><br />
I’m honestly not sure why this should be set to <strong>always</strong> after reading the Docker Compose docs but it is set this way according to the Docker Hub example but I’ll go with what they suggest.</p>
  </li>
  <li>
    <p><a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#environment"><strong>environment</strong></a><br />
The <code class="language-plaintext highlighter-rouge">environment</code> allows for passing environment variables into the container. <code class="language-plaintext highlighter-rouge">POSTGRES_PASSWORD</code> is required by the official PostgreSQL image. For security reasons there is no <code class="language-plaintext highlighter-rouge">root</code> user when the <acronym title="Database">DB</acronym> starts. For my needs I’ve included a specific user with <code class="language-plaintext highlighter-rouge">POSTGRES_USER</code>. This also has the effect of creating a database of the same name. If this variable is omitted then <code class="language-plaintext highlighter-rouge">postgres</code> will be used instead.</p>
  </li>
  <li>
    <p><a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#ports"><strong>ports</strong></a><br />
The ports expose network ports within the container to an “outside world”. By default, PostgreSQL runs on port <code class="language-plaintext highlighter-rouge">5432</code>. In the case above I’ve mapped <code class="language-plaintext highlighter-rouge">5000</code> as each of my services will increment, so Service A’s <acronym title="Application Programming Interface">API</acronym> will be 8000 with the <acronym title="Database">DB</acronym> on 5000 while Service B will be 8001 &amp; 5001. Not exposing these ports when I initially wrote the config lead to which you can read about in <a href="#troubleshooting">Troubleshooting</a>.</p>
  </li>
</ul>

<h2 id="working-with-the-db-service">Working with the <acronym title="Database">DB</acronym> service</h2>

<p>Now that we’ve got our config we’re ready to get our <acronym title="Database">DB</acronym> started. To do this we can run the command <code class="language-plaintext highlighter-rouge">docker-compose up</code>. This command will build the image, create a container and start it. You’ll get a bunch of output but ideally you’ll see a final log that looks something like the following:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>service_a_db  | 2021-12-31 10:07:50.025 UTC <span class="o">[</span>1] LOG:  database system is ready to accept connections
</code></pre></div></div>

<p>You can optionally run this in the background using the detach flag; <code class="language-plaintext highlighter-rouge">-d</code>, e.g. <code class="language-plaintext highlighter-rouge">docker-compose up -d</code>. While this will let you use your terminal you’ll not see the logs. At times though you might want to see logs and you can do this with the following command; <code class="language-plaintext highlighter-rouge">docker logs [CONTAINER_NAME]</code> for a one off look or with an optional follow flag; <code class="language-plaintext highlighter-rouge">-f</code> to give you realtime updates.</p>

<p>To stop the service and remove any data you can run <code class="language-plaintext highlighter-rouge">docker-compose down</code>.</p>

<p>If you want to mess around with the <acronym title="Database">DB</acronym> running in the container there’s two ways I do this. The first way is to use Docker’s <code class="language-plaintext highlighter-rouge">exec</code> command to call <code class="language-plaintext highlighter-rouge">psql</code>. Using <code class="language-plaintext highlighter-rouge">docker exec -it [CONTAINER_NAME] psql -U [POSTGRES_USER]</code>, i.e. <code class="language-plaintext highlighter-rouge">docker exec -it service_a_db psql -U service_a</code> or you can use the <acronym title="Database">DB</acronym>’s connection string, i.e. <code class="language-plaintext highlighter-rouge">docker exec -it service_a_db psql postgres://service_a:super_secret@localhost:5432/service_a</code>. This should then give you access to <code class="language-plaintext highlighter-rouge">psql</code> tooling.</p>

<p>Another approach is to access the container’s shell and then access <code class="language-plaintext highlighter-rouge">psql</code> with it. This offers you more access to the container environment beyond just <code class="language-plaintext highlighter-rouge">psql</code>. To do this use <code class="language-plaintext highlighter-rouge">docker exec -it /bin/bash</code> and then connect to the <acronym title="Database">DB</acronym> in the same way as above.</p>

<h2 id="connecting-to-db-in-node">Connecting to <acronym title="Database">DB</acronym> in Node</h2>

<p>Now that the service is running we can attempt to connect the Node <acronym title="Application Programming Interface">API</acronym> to the running instance. For this I use <a href="https://github.com/gajus/slonik">Slonik</a>. First of all though we’ll want to add the <acronym title="Database">DB</acronym>’s connection string to the <abbr title="environment">env</abbr> variables for the <acronym title="Application Programming Interface">API</acronym>. I am using <a href="https://github.com/motdotla/dotenv">dotenv</a> so I just need to edit my <code class="language-plaintext highlighter-rouge">.env</code> file to include it.</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">DB_CONNECTION_STRING</span><span class="o">=</span>postgres://service_a:super_secret@localhost:5000/service_a
</code></pre></div></div>

<p>Notice that we’re using the port that we set in <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> and not the one that PostgreSQL uses by default. This tripped me up a bit an I’ll cover it in <a href="#troubleshooting">troubleshooting</a>. Once the <abbr title="environment">env</abbr> variable is added, I access it using a <code class="language-plaintext highlighter-rouge">config.ts</code> which looks something like this:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">MissingConnectionStringError</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./errors</span><span class="dl">'</span>

<span class="kd">const</span> <span class="p">{</span> <span class="na">DB_CONNECTION_STRING</span><span class="p">:</span> <span class="nx">dbConnectionString</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span>

<span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">dbConnectionString</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">throw</span> <span class="k">new</span> <span class="nc">MissingConnectionStringError</span><span class="p">()</span>
<span class="p">}</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">dbConnectionString</span><span class="p">,</span>
<span class="p">}</span> <span class="kd">as const</span>
</code></pre></div></div>

<p>A couple of things to note here. I’ve created a custom error to be thrown if the <abbr title="environment">env</abbr> variable has not been loaded correctly. I then export a <code class="language-plaintext highlighter-rouge">config</code> object with the connection string so it can be accessed more easily and mark the <code class="language-plaintext highlighter-rouge">config</code> <code class="language-plaintext highlighter-rouge">as const</code> to avoid any unexpected attempts to overwrite the values within it. Using <code class="language-plaintext highlighter-rouge">as const</code> will mark each property of the object as <code class="language-plaintext highlighter-rouge">readonly</code>.</p>

<p>Finally I have a <code class="language-plaintext highlighter-rouge">db.ts</code> which is where we’ll hook up Slonik to our <acronym title="Database">DB</acronym> and export a <code class="language-plaintext highlighter-rouge">pool</code> that will allow us to connect and query the <acronym title="Database">DB</acronym>. The pool can then be imported into our services to make queries against the <acronym title="Database">DB</acronym>.</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">createPool</span><span class="p">,</span> <span class="kd">type</span> <span class="nx">DatabasePool</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">slonik</span><span class="dl">'</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">config</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./config</span><span class="dl">'</span>

<span class="k">export</span> <span class="kd">const</span> <span class="nx">pool</span><span class="p">:</span> <span class="nx">DatabasePool</span> <span class="o">=</span> <span class="nf">createPool</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">dbConnectionString</span><span class="p">)</span>
</code></pre></div></div>

<h2 id="troubleshooting">Troubleshooting</h2>

<h3 id="not-exposing-ports">Not exposing ports</h3>

<p>The first time I did this I didn’t expose the ports in the Docker compose config and my connection string used <code class="language-plaintext highlighter-rouge">5432</code> which resulted in a red herring of an error message. I would get the following error stack in my <acronym title="Application Programming Interface">API</acronym>:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/…/node_modules/slonik/src/factories/createConnection.ts:128
  throw new ConnectionError<span class="o">(</span>error.message<span class="o">)</span><span class="p">;</span>
                 ^
ConnectionError: password authentication failed <span class="k">for </span>user <span class="s2">"service_a"</span>
  at createConnection <span class="o">(</span>/…/node_modules/slonik/src/factories/createConnection.ts:128:15<span class="o">)</span>
  at processTicksAndRejections <span class="o">(</span>node:internal/process/task_queues:96:5<span class="o">)</span>
</code></pre></div></div>

<p>This lead my down the path of wondering whether I had configured the environment variables for PostgreSQL correctly but it was resolved by exposing the ports correctly.</p>]]></content><author><name>Adam Johnston</name></author><category term="node" /><category term="docker" /><category term="postgresql" /><category term="slonik" /><summary type="html"><![CDATA[So I recently started a new project (which I will totally see through to completion). In the course of reliving the joys of configuring a project from scratch, I reached the point where I was ready to hook up my web API to a database. It turned out to be a little more frustrating than I’d expected it to be, after all I’d done it once before about a year ago so of course it should be fresh in my mind. Sarcasm aside I’m writing this to hopefully solidify it in my brain and failing that at least have this as a reference.]]></summary></entry><entry><title type="html">Ramda Add</title><link href="https://adamjohnston.dev/posts/ramda-add" rel="alternate" type="text/html" title="Ramda Add" /><published>2020-01-31T00:00:00+00:00</published><updated>2020-01-31T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/ramda-add</id><content type="html" xml:base="https://adamjohnston.dev/posts/ramda-add"><![CDATA[<p><a href="https://ramdajs.com/docs/#add">https://ramdajs.com/docs/#add</a></p>

<p>Ramda is full of useful functions and add is the first in the list. It helps by being one of the most simple functions (there are others that are even smaller). The aim of these little posts are to visit each function at a time and better understand how it is written and why it is useful.</p>

<p>Add is one of the more straightforward functions in Ramda. It is used to <em>add</em> two numbers together. Like all functions in Ramda it is automagically curried and and can be written in few ways. You can pass a single value and create a whole new function, pass both arguments to get a new value or call add twice with a single argument each time to get a value. Take a look below for some examples:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">add2</span> <span class="o">=</span> <span class="nf">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c1">// (x) =&gt; y</span>
<span class="kd">const</span> <span class="nx">sumA</span> <span class="o">=</span> <span class="nf">add</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="c1">// 4</span>
<span class="kd">const</span> <span class="nx">sumB</span> <span class="o">=</span> <span class="nf">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)(</span><span class="mi">2</span><span class="p">)</span> <span class="c1">// 4</span>
</code></pre></div></div>

<h2 id="example-use-cases">Example use-cases</h2>

<p>Add a standard fee to a product price:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">bookingFee</span> <span class="o">=</span> <span class="mf">1.99</span>
<span class="kd">const</span> <span class="nx">calculateTotal</span> <span class="o">=</span> <span class="nf">add</span><span class="p">(</span><span class="nx">bookingFee</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">total</span> <span class="o">=</span> <span class="nf">calculateTotal</span><span class="p">(</span><span class="mf">19.99</span><span class="p">)</span> <span class="c1">// 21.98</span>
</code></pre></div></div>

<p>A ticket for every time someone joins a queue:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">increment</span> <span class="o">=</span> <span class="nf">add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">peopleQueueing</span> <span class="o">=</span> <span class="mi">12</span>
<span class="kd">const</span> <span class="nx">takeTicket</span> <span class="o">=</span> <span class="p">(</span><span class="nx">peopleQueuing</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">increment</span><span class="p">(</span><span class="nx">peopleQueuing</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">yourNumber</span> <span class="o">=</span> <span class="nf">takeTicket</span><span class="p">(</span><span class="nx">peopleInQueue</span><span class="p">)</span> <span class="c1">// 13</span>
</code></pre></div></div>

<h2 id="how-to-write-your-own">How to write your own</h2>

<p>You can always check out Ramda’s implementation but they have an entire library to work with and writing your own you might not have those benefits. Since I am doing this as a process for learning we’ll take a look at a simple implementation and then a curried version.</p>

<h3 id="simple">Simple</h3>

<p>The simple version of add will be a function that takes two arguments and adds those numbers together.</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// es6</span>
<span class="kd">const</span> <span class="nx">add</span> <span class="o">=</span> <span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span>

<span class="c1">// es5</span>
<span class="kd">function</span> <span class="nf">add</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span>
<span class="p">}</span>

<span class="c1">// TS</span>
<span class="kd">const</span> <span class="nx">add</span> <span class="o">=</span> <span class="p">(</span><span class="nx">x</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">y</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="o">=&gt;</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span>
</code></pre></div></div>

<h3 id="curried">Curried</h3>

<p>The curried version is very similar to the above. If you don’t know what currying is there is <a href="https://mostly-adequate.gitbooks.io/mostly-adequate-guide/ch04.html">a chapter on currying in the Mostly Adequate Guide to Functional Programming book</a>. If you prefer short videos then <a href="https://www.youtube.com/watch?v=iZLP4qOwY8I">FunFunFunction’s episode on currying</a> is worth a watch.</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// es6</span>
<span class="kd">const</span> <span class="nx">add</span> <span class="o">=</span> <span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="nx">y</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span>

<span class="c1">// es5</span>
<span class="kd">function</span> <span class="nf">add</span><span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="kd">function</span> <span class="nf">add</span><span class="p">(</span><span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// TS</span>
<span class="kd">const</span> <span class="nx">add</span> <span class="o">=</span>
  <span class="p">(</span><span class="nx">x</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span>
  <span class="p">(</span><span class="nx">y</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="o">=&gt;</span>
    <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span>
</code></pre></div></div>]]></content><author><name>Adam Johnston</name></author><category term="ramda" /><category term="fp" /><summary type="html"><![CDATA[https://ramdajs.com/docs/#add]]></summary></entry><entry><title type="html">Why Pair Code Review?</title><link href="https://adamjohnston.dev/posts/why-pair-code-review" rel="alternate" type="text/html" title="Why Pair Code Review?" /><published>2017-11-17T00:00:00+00:00</published><updated>2017-11-17T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/why-pair-code-review</id><content type="html" xml:base="https://adamjohnston.dev/posts/why-pair-code-review"><![CDATA[<p>What percentage of development teams carry out code reviews? Do you have a number in mind? Because a few months ago I happened across a tweet by Mattias Petter Johansson and I was honestly a little surprised by the results of his poll.</p>

<p>At just a little over 50% requiring code reviews to be part of their team’s engineering process from a pool of nearly 1900 respondents, perhaps you can understand my surprise.</p>

<p>I am a big believer in code reviews, in particular; paired code reviews. I have found them to offer great benefits and in this article I want to outline three of those I think are the most important. With pros must come cons and there are, so I will touch upon them also.</p>

<p>The original tweet &amp; poll from Mattias Petter Johansson</p>

<hr />

<h2 id="why-do-code-reviews">Why Do Code Reviews</h2>

<p>To give a bit more context, I’ll start by outlining the process of code reviews that I am familiar with. Many of the developers are comfortable with working in isolation. We’ll discuss approaches to solving problems and provide help to one another when called on but we rarely pair program. However, we do code review in pairs. All developers are encouraged to be the code reviewer, regardless of their seniority.</p>

<h3 id="knowledge-share--developer-growth">Knowledge Share &amp; Developer Growth</h3>

<p>This is, I believe, one of the most important reasons to code review. One scenario might be that the reviewer’s skillset is more expansive than the developer’s which allows for the opportunity to offer improvements, guidance and insights. This is an excellent way to boost a skill you may not be as strong in, at least not yet. Or, perhaps, the developer in need of a review may be more senior and the reviewer junior or vice versa. This is a fantastic opportunity for one developer to pass on any pearls of wisdom to another. In fact it’s a win-win situation and a learning loop. The developer will have learnt of new techniques and can pass this knowledge on to others. Both developers get to learn, teach and grow.</p>

<h3 id="onboarding-practices--culture">Onboarding, Practices &amp; Culture</h3>

<p>Introducing new developers to your team, explaining workflows, processes and the way you’d like to work together can take time. Doing code reviews across the wider team will allow newcomers to meet other developers and also learn about the engineering teams practices without having to go through pages of documentation. It’s certainly more fun, and, as a consequence, they get the knowledge needed in a faster and more engaging way.</p>

<p>We work in distributed teams so jumping on a hangout and sharing a screen has the benefit for all of us to stay in regular contact and hopefully feel like just a single engineering team.</p>

<h3 id="quality-assurance">Quality Assurance</h3>

<p>Code review is a great form of quality assurance, two heads are better than one and when you’ve been working on something for some time, you may have missed something. A bug that slips through that you’re sure you would have noticed. Having a fresh pair of eyes look through the code will help to catch that sneaky one.</p>

<p>A lot of the time just the practice of going over your code with other developers will shine a light on problem code. Does this make sense to you? Could this be improved? Are there alternatives that we should consider? These control questions can be asked to the reviewer. After a long day I’ve gone back to code and not been able to make sense of it myself and so here’s a chance to put that right. As I stated in the beginning of this article, the system is not perfect. Let’s look at the cons and discuss ways to deal with them.</p>

<h2 id="why-not-to-do-code-reviews">Why Not to do Code Reviews</h2>

<p>So with the good must come the bad. I’d be disingenuous if I didn’t cover them but with that said I don’t believe that any of the bad is enough of a reason to not code review.</p>

<h3 id="time">Time</h3>

<p>When you’re using your time to look over someone else’s code you’re not going to be working on your own. Of course in the grand scheme of things, if you’re pushing fewer bugs and you’re creating less tech debt you’re potentially saving time in the long run. However, in an agile environment with a bunch of tickets waiting to be done I can see how it might feel like it’s hard to spend that time. You can try and time box the code reviews. Smaller commits with good descriptions of the changes should help keep the code reviews short. Besides, completing small tasks one after another is a good feeling.</p>

<h3 id="only-human">Only Human</h3>

<p>While having someone else to look over your code can lead to finding bugs early and even improving it before it goes into production, it’s definitely not infallible. We’re only human and so mistakes can slip through. Code reviews won’t replace an acceptable test suite and even a second QA process that will check your product, but they’ll hopefully catch issues sooner.</p>

<hr />

<h2 id="to-sum-up">To Sum Up</h2>

<p>Using code reviews in my current position has given me the opportunity to learn and teach. I can share my knowledge to others when I review their code and I regularly learn something new when people review my code. Even if it’s not a perfect system, it has led to great, constructive debates and made my day-to-day job of coding more collaborative, engaging and fun.</p>]]></content><author><name>Adam Johnston</name></author><category term="work practices" /><summary type="html"><![CDATA[What percentage of development teams carry out code reviews? Do you have a number in mind? Because a few months ago I happened across a tweet by Mattias Petter Johansson and I was honestly a little surprised by the results of his poll.]]></summary></entry><entry><title type="html">Working with Pattern Libraries</title><link href="https://adamjohnston.dev/posts/working-with-pattern-libraries" rel="alternate" type="text/html" title="Working with Pattern Libraries" /><published>2016-01-18T00:00:00+00:00</published><updated>2016-01-18T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/working-with-pattern-libraries</id><content type="html" xml:base="https://adamjohnston.dev/posts/working-with-pattern-libraries"><![CDATA[<p>For a few years now I’ve had the benefit of building, maintaining and using pattern libraries in the workplace. I’ve seen them connect developers and designers, allow the sharing of insights through the wider team and lead to a more cohesive and collaborative product. With modular, component based architecture becoming ever more popular, pattern libraries are invaluable.</p>

<p>A pattern library is a collection of reusable components that can be used together to create an application. I tend to focus on web applications but a pattern library shouldn’t be limited to the web. I like to imagine a pattern library as a big box of Lego, full of blocks of different shapes, colours and usages that I can build lots of cool things with.</p>

<p>An example would be <a href="https://ux.mailchimp.com/patterns">Mailchimp’s excellent pattern library</a> and <a href="https://www.futurelearn.com/pattern-library">FutureLearn’s extensive pattern library</a>. Both split their libraries modularly. Grid system, typography, forms, navigation and more. They show use cases, markup and notes left by designers and developers. A developer implementing a component into an app has all the information they need.</p>

<hr />

<p>The way I approach creating a new pattern library is to look at the existing product (if there is one) or designs and discern common patterns, hence a pattern library. Patterns of an app are pieces that look or function very similar to other elements. I split these parts out as a component and begin to normalise them. Here’s a rather specific example:</p>

<p>Very rough and specific but hopefully a useful</p>

<p>Even at this early stage we can see a pattern (with more designs we’d certainly see more). The buttons are slightly different but both look and work in a similar way, as in I click one and it does some sort of action.</p>

<p>My approach would be to give this pattern a name, e.g. <strong>.btn</strong>, <strong>.action-button</strong> or simply <strong>.button</strong> and this naming should be agreed by the team. Then I’d discuss this with a designer. I’d try and reach an agreement on what could be normalised, such as border-radius, background-color or height.</p>

<p>Doing so makes the naming of components become much easier. When it comes to CSS styling, this process aids with <a href="https://getbem.com/introduction">BEM naming</a> or through <a href="https://glenmaddern.com/articles/css-modules">CSS module composition</a>. We might end up something like this:</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$button-colours</span><span class="p">:</span> <span class="p">(</span>
  <span class="nb">default</span><span class="o">:</span> <span class="mh">#2a8fbd</span><span class="o">,</span>
<span class="p">);</span>

<span class="nc">.action-button</span> <span class="p">{</span>
  <span class="k">@include</span> <span class="nd">button-reset</span><span class="p">;</span>

  <span class="nl">height</span><span class="p">:</span> <span class="m">2rem</span><span class="p">;</span>
  <span class="nl">padding</span><span class="p">:</span> <span class="m">0</span> <span class="m">0</span><span class="mi">.5rem</span><span class="p">;</span>
  <span class="nl">background</span><span class="p">:</span> <span class="nf">map-get</span><span class="p">(</span><span class="nv">$button-colours</span><span class="o">,</span> <span class="nb">default</span><span class="p">);</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="nf">darken</span><span class="p">(</span><span class="nf">map-get</span><span class="p">(</span><span class="nv">$button-colours</span><span class="o">,</span> <span class="nb">default</span><span class="p">)</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
  <span class="nl">border-radius</span><span class="p">:</span> <span class="nf">px2rem</span><span class="p">(</span><span class="m">3px</span><span class="p">);</span>

  <span class="k">&amp;</span><span class="nt">--square</span> <span class="p">{</span>
    <span class="nl">width</span><span class="p">:</span> <span class="m">2rem</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nt">--large</span> <span class="p">{</span>
    <span class="nl">height</span><span class="p">:</span> <span class="m">3</span><span class="mi">.5rem</span><span class="p">;</span>
    <span class="nl">padding</span><span class="p">:</span> <span class="m">0</span> <span class="m">1rem</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nt">--square</span><span class="si">#{</span><span class="o">&amp;</span><span class="si">}</span><span class="nt">--large</span> <span class="p">{</span>
    <span class="nl">width</span><span class="p">:</span> <span class="m">3</span><span class="mi">.5rem</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Once you have your pattern library, at the very minimum it needs to be spread throughout the company. Both designers and developers need to be aware of it and work closely with it. This leads to a shared language between designers and developers but also other members of the team.</p>

<p>If a designer is creating a new section of an app, they should be wire-framing or prototyping with components from the pattern library, not creating completely new designs. Iterations and feedback can be made faster and functionality isn’t a concern as it will already have been defined.</p>

<p>For developers, the creation of reusable components means that concerns about the look and functionality would have been previously addressed so the implementation and testing can be the focus.</p>

<hr />

<p>These are what I believe are some great benefits that come from the use of a pattern library.</p>

<ul>
  <li><strong>A shared language throughout the company</strong>. I think this can be understated but when everyone shares the same language, communication is much easier.</li>
  <li><strong>Spend more time prototyping, implementing, testing and iterating</strong>. When you understand the patterns it takes less time to prototype and implement aspects of an app. Adding a new section? You shouldn’t need to worry about how buttons and inputs look and work.</li>
  <li><strong>It acts as documentation</strong>. Giving examples, markup, use cases and notes makes it much easier to document the architecture of an app and is especially useful for new developers joining the team.</li>
  <li><strong>It’s an ongoing process</strong>. A pattern library should never be finished. Components can safely be improved upon or redesigned within the confines of the pattern library before affecting the app itself.</li>
  <li><strong>Visual regression testing</strong>. Visual regression testing can be made on each component individually. You have a greater safety net when making changes to a component since you will have more granular diffing.</li>
  <li><strong>Style in isolation</strong>. Because your components is a single piece of an app you should style them on their own. A component should look good and function correctly without the context of other components.</li>
</ul>

<hr />

<p>Here a few other articles you may find useful in your learning of pattern libraries.</p>

<ul>
  <li><a href="https://alistapart.com/blog/post/getting-started-with-pattern-libraries">Getting Started with Pattern Libraries</a> — Anna Debenham</li>
  <li><a href="https://about.futurelearn.com/blog/pattern-library">Building our First Pattern Library</a> — Alla Kholmatova</li>
  <li><a href="https://bradfrost.com/blog/post/atomic-web-design">Atomic Web Design</a> — Brad Frost</li>
  <li><a href="https://boagworld.com/design/pattern-library">How and why to Create a Pattern library</a> — Paul Boag</li>
</ul>]]></content><author><name>Adam Johnston</name></author><category term="architecture" /><summary type="html"><![CDATA[For a few years now I’ve had the benefit of building, maintaining and using pattern libraries in the workplace. I’ve seen them connect developers and designers, allow the sharing of insights through the wider team and lead to a more cohesive and collaborative product. With modular, component based architecture becoming ever more popular, pattern libraries are invaluable.]]></summary></entry><entry><title type="html">Propa Sass</title><link href="https://adamjohnston.dev/posts/propa-sass" rel="alternate" type="text/html" title="Propa Sass" /><published>2015-09-25T00:00:00+00:00</published><updated>2015-09-25T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/propa-sass</id><content type="html" xml:base="https://adamjohnston.dev/posts/propa-sass"><![CDATA[<p>I’ll readily admit I’ve been a bit out of the loop. I recently started a new job so I’m working with new people, learning new practices, and well, new Sass. Sass I hadn’t had the opportunity to use before, in this case it’s Sass maps.</p>

<p>I won’t go on about Sass maps, they’ve been around since Sass 3.3 (7th March 2014) and I am sure me raving about their usefulness is not going to be of much interest. What I did want to write about, which I hope, is going to be interesting is a little experiment into how far I could take Sass maps and what I learnt from doing so.</p>

<h2 id="let-the-experiment-begin">Let the Experiment Begin!</h2>

<p>Using a preprocessor is all about simplification. “How can I get the most done for as little effort?”. That’s why we now have loops, functions, mixins, nesting and variables in our CSS now (there’s plenty more but you get the idea). Maps are just one more tool in the Sass shed. Take this button example below:</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">.btn</span> <span class="p">{</span>
  <span class="nl">width</span><span class="p">:</span> <span class="m">150px</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="m">40px</span><span class="p">;</span>
  <span class="nl">background</span><span class="p">:</span> <span class="n">grey</span><span class="p">;</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="nf">darken</span><span class="p">(</span><span class="n">grey</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
  <span class="nl">color</span><span class="p">:</span> <span class="n">white</span><span class="p">;</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">inline-block</span><span class="p">;</span>
  <span class="nl">vertical-align</span><span class="p">:</span> <span class="nb">bottom</span><span class="p">;</span>

  <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
    <span class="nl">outline</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nd">:hover</span><span class="o">,</span>
  <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
    <span class="nl">height</span><span class="p">:</span> <span class="m">38px</span><span class="p">;</span>
    <span class="nl">margin-top</span><span class="p">:</span> <span class="m">2px</span><span class="p">;</span>
    <span class="nl">background</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">grey</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nd">:active</span> <span class="p">{</span>
    <span class="nl">height</span><span class="p">:</span> <span class="m">36px</span><span class="p">;</span>
    <span class="nl">margin-top</span><span class="p">:</span> <span class="m">4px</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nt">--primary</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="n">blue</span><span class="p">;</span>
    <span class="nl">border-color</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">blue</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>

    <span class="k">&amp;</span><span class="nd">:hover</span><span class="o">,</span>
    <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
      <span class="nl">background</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">blue</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nt">--warning</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="n">red</span><span class="p">;</span>
    <span class="nl">border-color</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">red</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>

    <span class="k">&amp;</span><span class="nd">:hover</span><span class="o">,</span>
    <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
      <span class="nl">background</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">red</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nc">.is-active</span> <span class="p">{</span>
    <span class="nl">animation</span><span class="p">:</span> <span class="n">glow</span> <span class="nb">infinite</span> <span class="m">3s</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chars : 667 | words : 75 | lines: 49
</code></pre></div></div>

<p><a href="https://codepen.io/adjohnston/pen/BoKWvZ">PropaSass Button example 01</a></p>

<p>We can use Sass maps and lists here to DRY things up a little and make our button class a little more maintainable.</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$states</span><span class="p">:</span> <span class="p">(</span>
  <span class="n">hover</span><span class="o">:</span> <span class="p">(</span>
    <span class="m">38px</span><span class="o">,</span>
    <span class="m">2px</span><span class="o">,</span>
  <span class="p">)</span><span class="o">,</span>
  <span class="n">focus</span><span class="o">:</span> <span class="p">(</span>
    <span class="m">38px</span><span class="o">,</span>
    <span class="m">2px</span><span class="o">,</span>
  <span class="p">)</span><span class="o">,</span>
  <span class="n">active</span><span class="o">:</span> <span class="p">(</span>
    <span class="m">36px</span><span class="o">,</span>
    <span class="m">4px</span><span class="o">,</span>
  <span class="p">)</span><span class="o">,</span>
<span class="p">);</span>

<span class="nv">$modifiers</span><span class="p">:</span> <span class="p">(</span>
  <span class="n">primary</span><span class="o">:</span> <span class="n">blue</span><span class="o">,</span>
  <span class="n">warning</span><span class="o">:</span> <span class="n">red</span><span class="o">,</span>
<span class="p">);</span>

<span class="nc">.btn</span> <span class="p">{</span>
  <span class="nl">width</span><span class="p">:</span> <span class="m">150px</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="m">40px</span><span class="p">;</span>
  <span class="nl">background</span><span class="p">:</span> <span class="n">grey</span><span class="p">;</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="nf">darken</span><span class="p">(</span><span class="n">grey</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
  <span class="nl">color</span><span class="p">:</span> <span class="n">white</span><span class="p">;</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">inline-block</span><span class="p">;</span>
  <span class="nl">vertical-align</span><span class="p">:</span> <span class="nb">bottom</span><span class="p">;</span>

  <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
    <span class="nl">outline</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nd">:hover</span><span class="o">,</span>
  <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">grey</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">@each</span> <span class="nv">$state</span><span class="o">,</span> <span class="nv">$styles</span> <span class="n">in</span> <span class="nv">$states</span> <span class="p">{</span>
    <span class="k">&amp;</span><span class="nd">:</span><span class="si">#{</span><span class="nv">$state</span><span class="si">}</span> <span class="p">{</span>
      <span class="nl">height</span><span class="p">:</span> <span class="nf">nth</span><span class="p">(</span><span class="nv">$styles</span><span class="o">,</span> <span class="m">1</span><span class="p">);</span>
      <span class="nl">margin-top</span><span class="p">:</span> <span class="nf">nth</span><span class="p">(</span><span class="nv">$styles</span><span class="o">,</span> <span class="m">2</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">@each</span> <span class="nv">$modifier</span><span class="o">,</span> <span class="nv">$colour</span> <span class="n">in</span> <span class="nv">$modifiers</span> <span class="p">{</span>
    <span class="k">&amp;</span><span class="nt">--</span><span class="si">#{</span><span class="nv">$modifier</span><span class="si">}</span> <span class="p">{</span>
      <span class="nl">background</span><span class="p">:</span> <span class="nv">$colour</span><span class="p">;</span>
      <span class="nl">border-color</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="nv">$colour</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>

      <span class="k">&amp;</span><span class="nd">:hover</span><span class="o">,</span>
      <span class="k">&amp;</span><span class="nd">:focus</span> <span class="p">{</span>
        <span class="nl">background</span><span class="p">:</span> <span class="nf">darken</span><span class="p">(</span><span class="nv">$colour</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">&amp;</span><span class="nc">.is-active</span> <span class="p">{</span>
    <span class="nl">animation</span><span class="p">:</span> <span class="n">glow</span> <span class="nb">infinite</span> <span class="m">3s</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chars : 757 (+90) | words : 85 (+10) | lines: 49 (N/A)
</code></pre></div></div>

<p><a href="https://codepen.io/adjohnston/pen/BoKRoJ">PropaSass Button example 02</a></p>

<p>We’ve added a few characters and some words but I believe there are some benefits. In my opinion we have abstracted out the modifiers to the top of our class so from a basic overview we can see how our button styles will change on state and how our button is being modified.</p>

<p>Changing state or adding new modifiers should be easy peasy and won’t require us to make changes to our button class. But what if we took this just a little further?</p>

<hr />

<h2 id="its-alive-its-alive">It’s Alive, IT’S ALIVE!</h2>

<p>I think perhaps it’s best to show an early idea of what I am choosing to call PropaSass (The idea of passing ‘props’ is taken from React and a play on words of proper or as some fellow East Londoners may pronounce it, ‘propa’.)</p>

<p>We need to define a function and a couple of mixins which should be added with your other functions and mixins. These handle looping and conversion.</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">@function</span> <span class="nf">class-name</span><span class="p">(</span><span class="nv">$prefix</span><span class="o">,</span> <span class="nv">$modifier</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">@if</span> <span class="ow">not</span> <span class="nv">$prefix</span> <span class="p">{</span>
    <span class="nv">$prefix</span><span class="p">:</span> <span class="s1">''</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">@if</span> <span class="ow">not</span> <span class="nv">$modifier</span> <span class="p">{</span>
    <span class="nv">$modifier</span><span class="p">:</span> <span class="s1">''</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">@return</span> <span class="nv">$prefix</span> <span class="o">+</span> <span class="nv">$modifier</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">@mixin</span> <span class="nf">style-with</span><span class="p">(</span><span class="nv">$styles</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">@if</span> <span class="ow">not</span> <span class="nv">$props</span> <span class="p">{</span>
    <span class="k">@warn</span> <span class="s1">'No styles were defined'</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">@each</span> <span class="nv">$style</span> <span class="n">in</span> <span class="nv">$styles</span> <span class="p">{</span>
    <span class="si">#{</span><span class="nf">nth</span><span class="p">(</span><span class="nv">$style</span><span class="o">,</span> <span class="m">1</span><span class="p">)</span><span class="si">}</span><span class="nd">:</span> <span class="nt">nth</span><span class="o">(</span><span class="err">$</span><span class="nt">style</span><span class="o">,</span> <span class="nt">2</span><span class="o">)</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="k">@mixin</span> <span class="nf">modify-with</span><span class="p">(</span><span class="nv">$props</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">@if</span> <span class="ow">not</span> <span class="nv">$props</span> <span class="p">{</span>
    <span class="k">@warn</span> <span class="s1">'No props were defined'</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">@each</span> <span class="nv">$prefix</span><span class="o">,</span> <span class="nv">$modifiers</span> <span class="n">in</span> <span class="nv">$props</span> <span class="p">{</span>
    <span class="k">@each</span> <span class="nv">$modifier</span><span class="o">,</span> <span class="nv">$styles</span> <span class="n">in</span> <span class="nv">$modifiers</span> <span class="p">{</span>
      <span class="k">&amp;</span><span class="si">#{</span><span class="nf">class-name</span><span class="p">(</span><span class="nv">$prefix</span><span class="o">,</span> <span class="nv">$modifier</span><span class="p">)</span><span class="si">}</span> <span class="p">{</span>
        <span class="k">@include</span> <span class="nd">style-with</span><span class="p">(</span><span class="nv">$styles</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So once we have these helpers defined, let’s re-write our button class and put those helpers to work!</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$props</span><span class="p">:</span> <span class="p">(</span>
  <span class="o">&amp;:</span> <span class="p">(</span>
    <span class="s1">':hover, :focus'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">height</span><span class="o">:</span> <span class="m">38px</span><span class="o">,</span>
      <span class="n">margin-top</span><span class="o">:</span> <span class="m">2px</span><span class="o">,</span>
      <span class="n">background</span><span class="o">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">grey</span><span class="o">,</span> <span class="m">10%</span><span class="p">)</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
    <span class="s1">':focus'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">outline</span><span class="o">:</span> <span class="nb">none</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
    <span class="s1">':active'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">height</span><span class="o">:</span> <span class="m">36px</span><span class="o">,</span>
      <span class="n">margin-top</span><span class="o">:</span> <span class="m">4px</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
  <span class="p">)</span><span class="o">,</span>
  <span class="s1">'--'</span><span class="o">:</span> <span class="p">(</span>
    <span class="s1">'primary'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">background</span><span class="o">:</span> <span class="n">blue</span><span class="o">,</span>
      <span class="n">border-color</span><span class="o">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">blue</span><span class="o">,</span> <span class="m">10%</span><span class="p">)</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
    <span class="s1">'primary:hover, primary:focus'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">background</span><span class="o">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">blue</span><span class="o">,</span> <span class="m">10%</span><span class="p">)</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
    <span class="s1">'warning'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">background</span><span class="o">:</span> <span class="n">red</span><span class="o">,</span>
      <span class="n">border-color</span><span class="o">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">red</span><span class="o">,</span> <span class="m">10%</span><span class="p">)</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
    <span class="s1">'warning:hover, warning:focus'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">background</span><span class="o">:</span> <span class="nf">darken</span><span class="p">(</span><span class="n">red</span><span class="o">,</span> <span class="m">10%</span><span class="p">)</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
  <span class="p">)</span><span class="o">,</span>
  <span class="s1">'.is-'</span><span class="o">:</span> <span class="p">(</span>
    <span class="s1">'active'</span><span class="o">:</span> <span class="p">(</span>
      <span class="n">animation</span><span class="o">:</span> <span class="n">glow</span> <span class="nb">infinite</span> <span class="m">3s</span><span class="o">,</span>
    <span class="p">)</span><span class="o">,</span>
  <span class="p">)</span><span class="o">,</span>
<span class="p">);</span>

<span class="nc">.btn</span> <span class="p">{</span>
  <span class="nl">width</span><span class="p">:</span> <span class="m">150px</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="m">40px</span><span class="p">;</span>
  <span class="nl">background</span><span class="p">:</span> <span class="n">grey</span><span class="p">;</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="nf">darken</span><span class="p">(</span><span class="n">grey</span><span class="o">,</span> <span class="m">10%</span><span class="p">);</span>
  <span class="nl">color</span><span class="p">:</span> <span class="n">white</span><span class="p">;</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">inline-block</span><span class="p">;</span>
  <span class="nl">vertical-align</span><span class="p">:</span> <span class="nb">bottom</span><span class="p">;</span>

  <span class="k">@include</span> <span class="nd">modify-with</span><span class="p">(</span><span class="nv">$props</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chars : 787 (+120) | words : 84 (+9) | lines: 44 (-5)
</code></pre></div></div>

<p><a href="https://codepen.io/adjohnston/pen/jbrNbx">PropaSass button example 03</a></p>

<p>I want to point out that I am not suggesting this is a good way to write Sass, or that this should even be used but I quite like it and I think it has benefits.
We define our base styles and then define our modifier sass map called <code class="language-plaintext highlighter-rouge">props</code>, passing them to our new <code class="language-plaintext highlighter-rouge">modify-with</code> mixin. We now have a clear separation of how our <code class="language-plaintext highlighter-rouge">props</code> will change our button class’ styling. We also avoid any confusing nesting.</p>

<p>Making changes are a little easier and if we want to change how our base style is modified, let’s say for example you really dislike BEM naming (c’mon double hyphen isn’t so bad) you can make that change easily.</p>

<p>One arguable drawback is now though we are defining CSS properties with a weird, Frankenstein’s monster, JSON-like syntax written using a Sass map. (Sass Map Notation? SAMN? Salmon syntax? Whatever, I kinda like it but then I am the mad scientist that created it.)</p>

<hr />

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A less verbose look in an editor: chars : 719 | words : 86| lines: 28 |
</code></pre></div></div>

<hr />

<h2 id="summary">Summary</h2>

<p>I never set out to create anything along the lines of what you see above (although if you think it’ll be useful, please let me know). I saw a new feature (to me at least) and I wanted to see how far I could take it.</p>

<p>I think this little exercise has given me insights in to how effective the use of maps can be and how they can DRY up Sass.
I’d also recommend this kind of experimentation when you find a new feature as there were plenty of problems that needed solving and meant gaining knowledge of new built in SassScript functions that I hadn’t used befor such as <code class="language-plaintext highlighter-rouge">map-get</code> and <code class="language-plaintext highlighter-rouge">nth</code>.</p>

<p>If you’d like to see the code, I’ve created a Github repo and if you’ve liked what you’ve seen and read, feel free to contribute and improve <a href="https://github.com/adjohnston/propasass">PropaSass</a>.</p>]]></content><author><name>Adam Johnston</name></author><category term="css" /><category term="sass" /><category term="fun" /><summary type="html"><![CDATA[I’ll readily admit I’ve been a bit out of the loop. I recently started a new job so I’m working with new people, learning new practices, and well, new Sass. Sass I hadn’t had the opportunity to use before, in this case it’s Sass maps.]]></summary></entry><entry><title type="html">Using WebDriver.IO + Jasmine + PhantomJS</title><link href="https://adamjohnston.dev/posts/my-first-few-hours-using-webdriver-io-jasmine-phantomjs" rel="alternate" type="text/html" title="Using WebDriver.IO + Jasmine + PhantomJS" /><published>2015-07-16T00:00:00+00:00</published><updated>2015-07-16T00:00:00+00:00</updated><id>https://adamjohnston.dev/posts/my-first-few-hours-using-webdriver.io-jasmine-phantomjs</id><content type="html" xml:base="https://adamjohnston.dev/posts/my-first-few-hours-using-webdriver-io-jasmine-phantomjs"><![CDATA[<p>To develop my skills as a front end developer I wanted to start adding acceptance testing to the web apps that I build. For a while I have found the wide selection of tools to be somewhat daunting. I found WebDriver.IO, (a NodeJS wrapper for Selenium 2.0 or WebDriver I discovered) and I thought I would give it a try and record my experience. <!-- more --></p>

<hr />

<h3 id="author-notice">Author notice!</h3>

<p>At the time of writing this very line I have not even installed WebDriver.IO and so please do not consider this a ‘how to’, it’s simply my experience using WebDriver.IO along with Jasmine and PhantomJS (which I am also fairly unfamiliar with), for good or bad.</p>

<p>If you find anything within this article that is incorrect or could be improved upon, please don’t hesitate to let me know. I am still new to testing so any help is greatly appreciated. Thank you!</p>

<hr />

<h2 id="installation">Installation</h2>

<p>The documentation asks you to install Selenium Server Standalone via Curl but I used HomeBrew since I am working with Mac OSX and the version is the same as the Curl version so I assume it’s safe to do so.</p>

<p>HomeBrew will also give you some instructions on how to start the Selenium Server. Since I am trying it out I don’t want Selenium Server to run every time I start my Mac so inside terminal I will just use:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>selenium-server
</code></pre></div></div>

<p>Doing so will fire up Selenium Server, ready for use. To install WebDriver.IO it’s as easy as using NPM (Node Package Manager).</p>

<p>Using the terminal:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>//  adds webdriverio to a <span class="nb">local </span>project
<span class="nv">$ </span>npm <span class="nb">install </span>webdriverio
</code></pre></div></div>

<p>Inside of test.js:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">webdriverio</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">webdriverio</span><span class="dl">'</span><span class="p">)</span>
</code></pre></div></div>

<p>Once the server was up and running I put together an exact version of the demo from WebDriver.IO’s documentation. Something to note, the first time I ran the test it took quite some time for it to return the value, subsequent tests were noticeable quicker.</p>

<p>On the whole installation was very quick and very simply which is always good in my book. Now though I want to add it to a potential test suite.</p>

<hr />

<h2 id="writing-my-first-tiny-jasmine-webdriverio--phantomjs-spec">Writing my first tiny Jasmine, WebDriver.IO &amp; PhantomJS spec</h2>

<p>I am going to be using Jasmine as my spec framework, I am familiar with RSpec and Jasmine seemed like a natural JavaScript alternative and also WebDriver.IO supports it (min version 2.0), I’ll also be using PhantomJS to have a browser to run the specs in. If you haven’t already installed them, it’s simply a case of using NPM again. Also to gain access to WebDriver.IO’s cli tools and test runner you’ll need to add it as a global package.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>npm <span class="nb">install</span> <span class="nt">-g</span> webdriverio jasmine phantomjs
</code></pre></div></div>

<p>At this stage I don’t plan on adding it to an existing project because I want to learn more of the WebDriver.IO API and I want to start small so I am going to create a single spec file and create a WebDriver.IO config file.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>//  creates a jasmine framework file structure
<span class="nv">$ </span>jasmine init

//  goes through the process of create a webdriver.io config
<span class="nv">$ </span>wdio config
</code></pre></div></div>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// subsequent config (minus comments)</span>
<span class="nx">exports</span><span class="p">.</span><span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">specs</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">spec/**/*.js</span><span class="dl">'</span><span class="p">],</span>
  <span class="na">exclude</span><span class="p">:</span> <span class="p">[</span>
    <span class="c1">// 'path/to/excluded/files'</span>
  <span class="p">],</span>
  <span class="na">capabilities</span><span class="p">:</span> <span class="p">[</span>
    <span class="p">{</span>
      <span class="na">browserName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">phantomjs</span><span class="dl">'</span><span class="p">,</span>
    <span class="p">},</span>
  <span class="p">],</span>
  <span class="na">logLevel</span><span class="p">:</span> <span class="dl">'</span><span class="s1">silent</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">coloredLogs</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="na">screenshotPath</span><span class="p">:</span> <span class="dl">'</span><span class="s1">./errorShots/</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">baseUrl</span><span class="p">:</span> <span class="dl">'</span><span class="s1">http://adamjohnston.co.uk</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">waitforTimeout</span><span class="p">:</span> <span class="mi">10000</span><span class="p">,</span>
  <span class="na">framework</span><span class="p">:</span> <span class="dl">'</span><span class="s1">jasmine</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">reporter</span><span class="p">:</span> <span class="dl">'</span><span class="s1">dot</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">jasmineNodeOpts</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">defaultTimeoutInterval</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span>
    <span class="na">expectationResultHandler</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">passed</span><span class="p">,</span> <span class="nx">assertion</span><span class="p">)</span> <span class="p">{</span>
      <span class="c1">// do something</span>
    <span class="p">},</span>
    <span class="na">grep</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
    <span class="na">invertGrep</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
  <span class="p">},</span>

  <span class="na">onPrepare</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// do something</span>
  <span class="p">},</span>

  <span class="na">before</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// do something</span>
  <span class="p">},</span>

  <span class="na">after</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// do something</span>
  <span class="p">},</span>

  <span class="na">onComplete</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// do something</span>
  <span class="p">},</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So with that said, I am going to test my portfolio site. I have a menu button that when clicked will show a list of articles. These are my specs:</p>

<ul>
  <li>When I visit the page I shouldn’t see any navigation.</li>
  <li>When I click the menu button, I want to see the navigation.</li>
  <li>When I click the menu button a second time, I stop seeing the navigation.</li>
</ul>

<p>Also at this point I am going to introduce Jasmine to handle breaking the specs up. WebDriver.IO provides many examples including a Jasmine specific example, but this is where I ran in to some issues. I was getting the following error:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Started /Users/adrjohnston/Sites/webdriver-test/node_modules/webdriverio/node_modules/q/q.js:141
throw e<span class="p">;</span>
Error: POST /session//url
Build info: version: <span class="s1">'2.46.0'</span>, revision: <span class="s1">'87c69e2'</span>, <span class="nb">time</span>: <span class="s1">'2015–06–04 16:16:47'</span>
System info: host: <span class="s1">'Adams-MBP'</span>, ip: <span class="s1">'192.168.0.4'</span>, os.name: <span class="s1">'Mac OS X'</span>, os.arch: <span class="s1">'x86_64'</span>, os.version: <span class="s1">'10.10.3'</span>, java.version: <span class="s1">'1.8.0_45'</span>
Driver info: driver.version: unknown
at new ErrorHandler.RuntimeError <span class="o">(</span>/Users/adrjohnston/Sites/webdriver-test/node_modules/webdriverio/lib/utils/ErrorHandler.js:92:12<span class="o">)</span>
at RequestHandler.&lt;anonymous&gt; <span class="o">(</span>/Users/adrjohnston/Sites/webdriver-test/node_modules/webdriverio/lib/utils/RequestHandler.js:168:25<span class="o">)</span>
at Request.self.callback <span class="o">(</span>/Users/adrjohnston/Sites/webdriver-test/node_modules/webdriverio/node_modules/request/request.js:373:22<span class="o">)</span>
at Request.emit <span class="o">(</span>events.js:110:17<span class="o">)</span>
at Request.&lt;anonymous&gt; <span class="o">(</span>/Users/adrjohnston/Sites/webdriver-test/node_modules/webdriverio/node_modules/request/request.js:1318:14<span class="o">)</span>
at Request.emit <span class="o">(</span>events.js:129:20<span class="o">)</span>
at IncomingMessage.&lt;anonymous&gt; <span class="o">(</span>/Users/adrjohnston/Sites/webdriver-test/node_modules/webdriverio/node_modules/request/request.js:1266:12<span class="o">)</span>
at IncomingMessage.emit <span class="o">(</span>events.js:129:20<span class="o">)</span>
at _stream_readable.js:908:16
at process._tickCallback <span class="o">(</span>node.js:355:11<span class="o">)</span>
</code></pre></div></div>

<p>So turns out that the documentation and the examples confused me somewhat and after a few of hours trying to figure things out I now have everything working.</p>

<p>I was following through the example and was trying to run it with WebDriver.IO’s test runner and when that failed, trying Jasmine’s runner but the error persisted. I think because I used wdio config it’s a way of using WebDriver.IO’s test runner which works a little bit differently and I found how to use the WebDriver.IO’s test runner in this example elsewhere. I prefer this approach so I am going to continue using:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wdio wdio.config.js
</code></pre></div></div>

<p>One thing to note. I currently don’t know what is setting the browser object. I cannot find a reference to it on the WebDriver.IO docs and so I am assuming it comes from Selenium or PhantomJS.</p>

<p>One last little issue I ran into. I was not calling Jasmine’s done callback after my specs and thus would cause a timeout exception.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Timeout — Async callback was not invoked within <span class="nb">timeout </span>specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
</code></pre></div></div>

<p>I am not super familiar with Jasmine either so this is something worth reading into. So without further-ado here’s my spec with notes or just the basic version:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// ====== nav-menu.spec.js ======</span>
<span class="nf">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">adamjohnston.co.uk</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">beforeAll</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">browser</span><span class="p">.</span><span class="nf">url</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">).</span><span class="nf">call</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
  <span class="p">})</span>

  <span class="nf">afterAll</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">browser</span><span class="p">.</span><span class="nf">end</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
  <span class="p">})</span>

  <span class="nf">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">when a user visits index</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nf">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">should not have navigation visible</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">browser</span>
        <span class="p">.</span><span class="nf">getCssProperty</span><span class="p">(</span><span class="dl">'</span><span class="s1">nav[role=”navigation”]</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">opacity</span><span class="dl">'</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">opacity</span><span class="p">)</span> <span class="p">{</span>
          <span class="nf">expect</span><span class="p">(</span><span class="nx">opacity</span><span class="p">.</span><span class="nx">value</span><span class="p">).</span><span class="nf">toBe</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="p">})</span>
        <span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
    <span class="p">})</span>
  <span class="p">})</span>

  <span class="nf">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">when a user clicks the menu button</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nf">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">should show the navigation</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">browser</span>
        <span class="p">.</span><span class="nf">click</span><span class="p">(</span><span class="dl">'</span><span class="s1">#jsNavBtn</span><span class="dl">'</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">getCssProperty</span><span class="p">(</span><span class="dl">'</span><span class="s1">nav[role=”navigation”]</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">opacity</span><span class="dl">'</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">opacity</span><span class="p">)</span> <span class="p">{</span>
          <span class="nf">expect</span><span class="p">(</span><span class="nx">opacity</span><span class="p">.</span><span class="nx">value</span><span class="p">).</span><span class="nf">toBe</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="p">})</span>
        <span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
    <span class="p">})</span>

    <span class="nf">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">should hide navigation if clicked again</span><span class="dl">'</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">done</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">browser</span>
        <span class="p">.</span><span class="nf">click</span><span class="p">(</span><span class="dl">'</span><span class="s1">#jsNavBtn</span><span class="dl">'</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">getCssProperty</span><span class="p">(</span><span class="dl">'</span><span class="s1">nav[role=”navigation”]</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">opacity</span><span class="dl">'</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">opacity</span><span class="p">)</span> <span class="p">{</span>
          <span class="nf">expect</span><span class="p">(</span><span class="nx">opacity</span><span class="p">.</span><span class="nx">value</span><span class="p">).</span><span class="nf">toBe</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="p">})</span>
        <span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
    <span class="p">})</span>
  <span class="p">})</span>
<span class="p">})</span>
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>//  <span class="o">======</span>  terminal output  <span class="o">======</span>
<span class="nv">$ </span>wdio wdio.conf.js
․․․
3 passing <span class="o">(</span>6.20s<span class="o">)</span>
</code></pre></div></div>

<hr />

<h2 id="summary">Summary</h2>

<p>All in all not a bad couple of hours of work and a toolset that I definitely think I will invest more time in knowing. I think acceptance testing is very important and the combination of WebDriver.IO + Jasmine + PhantomJS seems promising.</p>

<p>I think my next steps will be to look into using it with Gulp (another tool WebDriver.IO supports) and try testing out a MeteorJS application (There are few WebDriver.IO packages on Atmosphere). Surely not long before I am JS acceptance testing machine!</p>]]></content><author><name>Adam Johnston</name></author><category term="js" /><category term="testing" /><summary type="html"><![CDATA[To develop my skills as a front end developer I wanted to start adding acceptance testing to the web apps that I build. For a while I have found the wide selection of tools to be somewhat daunting. I found WebDriver.IO, (a NodeJS wrapper for Selenium 2.0 or WebDriver I discovered) and I thought I would give it a try and record my experience.]]></summary></entry></feed>