<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Notebook — Talentedunicorn</title><description>Programmer, artist, unicorn person.</description><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/</link><item><title>Changing author information on a git commit</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/changing-author-information-on-a-git-commit/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/changing-author-information-on-a-git-commit/</guid><description>There might be times where you need to &quot;rewrite&quot; history on Git. The most common case is updating the commit message to fix typos or change the message, but there...</description><pubDate>Fri, 13 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There might be times where you need to “rewrite” history on Git. The most common case is updating the commit message to fix typos or change the message, but there might be times one would want to update the author information - this is how you go about it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; do this on published/pushed commits (&lt;em&gt;unless you know what you are doing&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To change the author of the last commit:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git commit --amend --author &quot;NAME &amp;#x3C;EMAIL_ADDRESS&gt;&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And that’s it, your commit author will be updated. For earlier commits, you could rebase then run commit amend.&lt;/p&gt;
&lt;h3 id=&quot;extra-git-tip-rebasing-the-first-commit-of-a-repository&quot;&gt;Extra git tip: Rebasing the first commit of a repository&lt;/h3&gt;
&lt;p&gt;Usually rebase looks like &lt;code&gt;git rebase -i COMMIT_TO_START_FROM&lt;/code&gt; but if you wanted to change the first commit &lt;code&gt;COMMIT_TO_START_FROM&lt;/code&gt; can’t be the commit you are changing (first commit). To be able to do that the command changes to:
&lt;code&gt;git rebase -i --root&lt;/code&gt;. ;)&lt;/p&gt;</content:encoded></item><item><title>Culture Shock by Cultprint jolts Telawi back to life</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/culture-shock/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/culture-shock/</guid><description>Penang’s celebrated art collective Cultprint makes its mark in Kuala Lumpur with Culture Shock, a dynamic group exhibition showcasing bold collaborations, diverse mediums, and unfiltered artistic expression.</description><pubDate>Thu, 21 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;small&gt;Words by: &lt;a href=&quot;https://instagram.com/alifomahfix&quot;&gt;Alfonso&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Running from &lt;code&gt;15 November 2024&lt;/code&gt; to &lt;code&gt;12 January 2025&lt;/code&gt; at &lt;strong&gt;3, Jalan Telawi 3&lt;/strong&gt;, Cultprint’s group exhibition Culture Shock offers a creative counterpoint to the area’s reputation as a watering hole for expats and partygoers, injecting the street with culture and conversation amid its late-night revelries.&lt;/p&gt;
&lt;div class=&quot;two-columns&quot;&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Horsing around - Ernest Zacharevic.CnxTFME3.jpg&quot; alt=&quot;Horsing around - Ernest Zacharevic&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Horsing around - Ernest Zacharevic&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Cultprint, founded by Lithuanian public artist &lt;strong&gt;Ernest Zacharevic&lt;/strong&gt; and Malaysian embroidery artist &lt;strong&gt;Sheena Liam&lt;/strong&gt;, began as a printing studio in Penang before evolving into a dynamic space for residencies, exhibitions, and community engagement. With Culture Shock, its debut in Kuala Lumpur, Cultprint reimagines the former CzipLee store as a gallery that mirrors both Bangsar’s evolving cultural identity and its own ethos of independent artistic expression.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Curated by Zacharevic, the exhibition showcases 16 celebrated and emerging artists, each bringing unique perspectives through a variety of mediums. They include Zacharevic himself, renowned for his interactive public murals, and partner Liam, whose minimalistic embroidery explores themes of identity and self-reflection.&lt;/p&gt;
&lt;div class=&quot;two-columns&quot;&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Sliz.D4UjyUxO.jpg&quot; alt=&quot;Sliz&quot; width=&quot;3891&quot; height=&quot;5836&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Sliz&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Insomnia - Sheena Liam.Bq8hJZzI.jpg&quot; alt=&quot;Insomnia - Sheena Liam&quot; width=&quot;4843&quot; height=&quot;3229&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Insomnia - Sheena Liam&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;The exhibition showcases a dynamic blend of local and international talents, with a strong emphasis on Penang-grown and Penang-based artists. Among them are &lt;strong&gt;Azmi Hussin&lt;/strong&gt;, known for his witty caricatures; multidisciplinary artist &lt;strong&gt;Bibichun&lt;/strong&gt;, whose works explore cultural narratives; &lt;strong&gt;Low Chee Peng&lt;/strong&gt;, whose fine art reflects intricate detail and emotional depth; &lt;strong&gt;TAZONE&lt;/strong&gt;, a rising talent in high-risk graffiti art; and text artist &lt;strong&gt;Trina Teoh&lt;/strong&gt;, who bridges prose and visual art.&lt;/p&gt;
&lt;div class=&quot;two-columns&quot;&gt;
&lt;div&gt;
&lt;p&gt;Outside of the island city, other homegrown artists include &lt;strong&gt;Cloakwork&lt;/strong&gt;, whose humorous and energetic graffiti murals are beloved globally; &lt;strong&gt;Kenji Chai&lt;/strong&gt;, creator of the iconic Chaigo character graffitied throughout KL; &lt;strong&gt;Teebai&lt;/strong&gt;, whose pieces tackle socio-political themes; &lt;strong&gt;Bono Stellar&lt;/strong&gt;, known for vibrant, light-filled sculptural installations; and &lt;strong&gt;Sliz&lt;/strong&gt;, who blends surrealism and street art.&lt;/p&gt;
&lt;/div&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Inner Chaos - Kenji Chai.DafLmpWC.jpg&quot; alt=&quot;Inner Chaos - Kenji Chai&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Inner Chaos - Kenji Chai&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div class=&quot;two-columns&quot;&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Cloakwork.KeIdsNeP.jpg&quot; alt=&quot;Cloakwork&quot; width=&quot;3849&quot; height=&quot;5773&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Cloakwork&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Blossom - Teebai.DCq8TeBc.jpg&quot; alt=&quot;Blossom - Teebai&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Blossom - Teebai&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;Rounding out the exhibition are &lt;strong&gt;Martha Cooper&lt;/strong&gt;, the legendary American photographer of street art culture; &lt;strong&gt;Isaac Cordal&lt;/strong&gt;, the Spanish sculptor famous for his poignant miniature installations; &lt;strong&gt;Yok &amp;#x26; Sheryo&lt;/strong&gt;, a New York-based duo fusing folk motifs and urban art; and finally Singapore’s &lt;strong&gt;Sam Lo&lt;/strong&gt;, affectionately dubbed the “Sticker Lady” for their provocative works.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Follow the leaders (1) - Isaac Cordal.CRaH9Hsi.jpg&quot; alt=&quot;Follow the leader - Isaac Cordal&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Follow the leader (1) - Isaac Cordal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Follow the leaders (2) - Isaac Cordal.Ctw7oMLO.jpg&quot; alt=&quot;Follow the leader - Isaac Cordal&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Follow the leader (2) - Isaac Cordal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The exhibition’s layout reflects its theme of cultural collisions. The ground floor is alive with vibrant, collaborative works while the upper level offers a quieter, more introspective atmosphere, showcasing the range of styles and voices united under Cultprint’s vision.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Lost postcards (1) - Isaac Cordal.BbchP6K-.jpg&quot; alt=&quot;Lost postcards (1) - Isaac Cordal&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Lost postcards (1) - Isaac Cordal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div class=&quot;two-columns&quot;&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Lost postcards (2) - Isaac Cordal.D4bQ5Sr_.jpg&quot; alt=&quot;Lost postcards (2) - Isaac Cordal&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Lost postcards (2) - Isaac Cordal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/Lost postcards (3) - Isaac Cordal.By4C70qx.jpg&quot; alt=&quot;Lost postcards (3) - Isaac Cordal&quot; width=&quot;6240&quot; height=&quot;4160&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;Lost postcards (3) - Isaac Cordal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;For more information, follow Cultprint on &lt;a href=&quot;https://www.instagram.com/cultprint/&quot;&gt;Instagram&lt;/a&gt;, check out their &lt;a href=&quot;https://www.cultprint.co/&quot;&gt;website&lt;/a&gt;, or visit the exhibition space at 3, Jalan Telawi 3.&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title>Mockup resources and tools in web development</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/mockup-resources-and-tools/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/mockup-resources-and-tools/</guid><description>Design on the Web has changed a lot since the days of marquee scroll and table layouts...</description><pubDate>Thu, 01 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Design on the Web has changed a lot since the days of marquee scroll and &lt;a href=&quot;http://blog.froont.com/brief-history-of-web-design-for-designers/%5D&quot;&gt;table layouts&lt;/a&gt; and this has also changed way we display designs.&lt;/p&gt;
&lt;p&gt;There is a lot that goes into designing a web interface, from storyboarding to a sketch/wireframe/whatever-hip-thing-kids-use-now(&lt;strong&gt;&lt;em&gt;cough&lt;/em&gt;&lt;/strong&gt; sketch)/ a &lt;strong&gt;pretty static&lt;/strong&gt; Photoshop document. Eventually your designs will end up on …&lt;strong&gt;the web&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/mockups.CEzbL5Js.png&quot; alt=&quot;Mockup devices&quot; width=&quot;3471&quot; height=&quot;1939&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Mockup devices&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Since the designs will be used on a device like a computer, mobile or future toasters that connect to the Internet, it makes sense to showcase your designs with those devices.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;apart from giving context to the design, mockups with devices look more natural and prettier&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also we can all agree apart from giving context to the design, mockups with devices look more natural and prettier.&lt;/p&gt;
&lt;p&gt;There are a few ways to generate a mockup of your shiny designs with a device template&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generators&lt;/strong&gt; — Generating mockups from uploaded screenshots
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://placeit.net/&quot;&gt;Placeit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTML5 templates&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pixelsign.github.io/html5-device-mockups/&quot;&gt;Pixelsign HTML5 device mockups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mockuphone.com&quot;&gt;MockuPhone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Photoshop&lt;/strong&gt; — Manual way using blank templates
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://facebook.design/devices&quot;&gt;Facebook design resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sketchappsources.com/category/device.html&quot;&gt;Sketchappsources&lt;/a&gt; — Device mockup resources for Sketch&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’d like to hear more on your experiences with presenting web designs and other tools you use.&lt;/p&gt;</content:encoded></item><item><title>Coffee or Tmux</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/coffee-or-tmux/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/coffee-or-tmux/</guid><description>tmux is a terminal multiplexer for Unix-like operating systems...</description><pubDate>Wed, 11 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;According to &lt;a href=&quot;https://en.wikipedia.org/wiki/Tmux&quot;&gt;Wikipedia - tmux is a terminal multiplexer for Unix-like operating systems.&lt;/a&gt; But to me; tmux is a complex tool to have on the terminal. Using tmux gives your terminal &lt;em&gt;super-powers&lt;/em&gt; (if you may), from being able to split your terminal &lt;em&gt;window&lt;/em&gt; into multiple panes to creating tabs (also known as windows on tmux).&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/5/50/Tmux.png&quot; alt=&quot;Image of tmux with split panes&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;Image of tmux with split panes&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I have been using tmux for a while now and here’s a few things i’ve learnt so far that might be useful to a beginner&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changing the default prefix key&lt;/li&gt;
&lt;li&gt;Panes&lt;/li&gt;
&lt;li&gt;How to copy and paste on tmux&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;changing-the-default-prefix-key&quot;&gt;Changing the default prefix key&lt;/h3&gt;
&lt;p&gt;Tmux uses a &lt;a href=&quot;https://github.com/tmux/tmux/wiki/Getting-Started#the-prefix-key&quot;&gt;prefix key&lt;/a&gt; for global commands, the default key is &lt;code&gt;CTRL + b&lt;/code&gt; or &lt;code&gt;Cmd + b&lt;/code&gt; which I find to be a hard combination to reach, so it’s probably the first thing you’d want to change after &lt;a href=&quot;https://github.com/tmux/tmux/wiki/Installing&quot;&gt;installing tmux&lt;/a&gt; on your computer.&lt;/p&gt;
&lt;p&gt;This can be done in the tmux configuration file &lt;code&gt;.tmux.conf&lt;/code&gt; on the &lt;em&gt;Home directory&lt;/em&gt; of your user account. Edit this file and add/replace the line similar to below:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;unbind C-b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;set -g prefix C-a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will set the prefix to &lt;code&gt;CTRL + a&lt;/code&gt; key. Now you could split the window vertically by pressing &lt;code&gt;CTRL + a&lt;/code&gt; and &lt;code&gt;&quot;&lt;/code&gt; and will have two panes.&lt;/p&gt;
&lt;h3 id=&quot;panes&quot;&gt;Panes&lt;/h3&gt;
&lt;p&gt;By default a window starts with one pane. The window can then be split into multiple panes that appear on the screen. This is common to the “window splitting” feature on popular terminal emulators like &lt;a href=&quot;https://github.com/gnome-terminator/terminator&quot;&gt;terminator&lt;/a&gt; or &lt;a href=&quot;https://hyper.is&quot;&gt;hyper&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/wiki/tmux/tmux/images/tmux_pane_diagram.png&quot; alt=&quot;A tmux window with three panes&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;A tmux window with three panes&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here are a few commands I use a lot with panes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Moving between panes
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[PREFIX]+[DIRECTION] // so for Up = CTRL+A then Up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Zooming in and out
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[PREFIX]+Z // or in our case CTRL+A then Z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Splitting
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[PREFIX]+% // for a horizontal split&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[PREFIX]+&quot; // for a vertical split&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tmux/tmux/wiki/Getting-Started#sessions-windows-and-panes&quot;&gt;Read more about panes here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;copy-and-paste&quot;&gt;Copy and paste&lt;/h3&gt;
&lt;p&gt;This is especially useful if you need to copy output from one pane to another or within the same pane.&lt;/p&gt;
&lt;p&gt;Sophia Brandt wrote a nice &lt;a href=&quot;https://www.rockyourcode.com/copy-and-paste-in-tmux/&quot;&gt;article on how that works and more&lt;/a&gt; but in a nutshell, here’s the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enter &lt;em&gt;copy mode&lt;/em&gt; by pressing &lt;code&gt;CTRL+b&lt;/code&gt;, &lt;code&gt;[&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use the arrow keys to go to the position from where you want to start copying. Press &lt;code&gt;CTRL+SPACE&lt;/code&gt; to start copying.&lt;/li&gt;
&lt;li&gt;Use arrow keys to go to the end of text you want to copy. Press &lt;code&gt;ALT+w&lt;/code&gt; or &lt;code&gt;CTRL+w&lt;/code&gt;to copy into Tmux buffer.&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;CTRL+b&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt; to paste in a possibly different Tmux pane/window.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hope you learned something useful and are using tmux in your terminal. Feel free to share what you like about tmux ;)&lt;/p&gt;</content:encoded></item><item><title>CSS variables</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/css-variables/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/css-variables/</guid><description>Using css custom property a.k.a CSS variables...</description><pubDate>Wed, 27 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the modern web&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; things aren’t fixed as they were a few years ago. Responsive design is now a standard that directly impacts not just how your users experience your website but also ranking in search engines.&lt;/p&gt;
&lt;p&gt;Website performance is more so important especially now that being able to build things isn’t enough if those things don’t perform well and the distinction between &lt;em&gt;application&lt;/em&gt; and &lt;em&gt;website&lt;/em&gt; is getting more a more blurred. Exciting new features are available now on this robust platform making working with the web easier, less-hacky and fun&lt;/p&gt;
&lt;p&gt;Cascading Style Sheets (CSS) has mostly been on the backseat when it comes to “languages” on the web (atleast HTML has &lt;em&gt;language&lt;/em&gt; in it’s name) but this has been changing with the things we are now able to do with CSS. We had come up with ways to make CSS more robust but most of those ways have been non-native and require extra setup on build; Sass and LESS will have limitations when it comes to changes needed on runtime. In early 2018, the W3C put out &lt;a href=&quot;https://drafts.csswg.org/css-variables&quot;&gt;a draft for the cascading variables module&lt;/a&gt; which allows for reusable variables in CSS.&lt;/p&gt;
&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;/h3&gt;
&lt;p&gt;As of the current date of writing this post; &lt;a href=&quot;https://caniuse.com/#feat=css-variables&quot;&gt;support for CSS variables&lt;/a&gt; is available on most browsers&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;To declare a variable the syntax is &lt;code&gt;--[variable-name]: [value];&lt;/code&gt; and can then be used in a cascading fashion in place of values.&lt;/p&gt;
&lt;h5 id=&quot;example&quot;&gt;Example&lt;/h5&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;:root&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  --global-padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--global-padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;default-values&quot;&gt;Default values&lt;/h4&gt;
&lt;p&gt;Cascading variables supports a default fallback value which will be applied if the variable specified is invalid.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  --spacing&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  background&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--spacing&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;yellow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;yellow&lt;/strong&gt; will be applied since 2rem is not a valid color&lt;/p&gt;
&lt;h3 id=&quot;common-gotchas&quot;&gt;Common Gotchas&lt;/h3&gt;
&lt;p&gt;As of writing this post, there’s a few things that aren’t (yet) possible with CSS variables.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can’t be used in media queries. So &lt;code&gt;@media(var(--breakpoint)){ ... }&lt;/code&gt; won’t work&lt;/li&gt;
&lt;li&gt;Concatenation without calc. &lt;code&gt;padding: var(--space-unit)px;&lt;/code&gt; won’t work instead &lt;code&gt;padding: calc(var(--space-unit) * 1px);&lt;/code&gt; works&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Depending on your project and users of your product, it’s definitely worth considering using CSS variables. I’d like to know your experiences and use cases for CSS variables.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Modern, to the time of writing this post &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;Unfortunately Internet Explorer doesn’t have good support…yet &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>How width and max-width work</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/how-width-and-max-width-work/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/how-width-and-max-width-work/</guid><description>We explore the difference betweet max-width and width properties in CSS</description><pubDate>Fri, 29 Jul 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For most Front-end developers on the web implementing layout designs; setting the width property is a frequent part of the task. Understanding the property saves a lot of time during development and improves &lt;strong&gt;&lt;em&gt;code quality&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Recently &lt;a href=&quot;http://chriscoyier.net/&quot;&gt;Chris Coiyer&lt;/a&gt; of &lt;a href=&quot;//www.css-tricks.com&quot;&gt;CSS-Tricks&lt;/a&gt; published a post titled &lt;strong&gt;A Tale of `width` and `max-width`&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In the article he demonstrates how the &lt;strong&gt;width&lt;/strong&gt; and &lt;strong&gt;max-width&lt;/strong&gt; CSS properties work with the subject of a modal module, although the technique can be applied on other elements.&lt;/p&gt;
&lt;div class=&quot;mb3 pa3 pb0 ba bw2 b--primary&quot;&gt;
&lt;p&gt;&lt;strong&gt;Chris Coiyer:&lt;/strong&gt; You might want to limit the width of a modal, right? Kinda gives it that “modal” look on larger screens. Let’s say 600px sounds right. But, you want to make sure it doesn’t bust outside of its parent element. For example, avoid causing horizontal scrolling on a mobile screen.&lt;/p&gt;
&lt;p&gt;How would you do that?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;element&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;600&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  max-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;element&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  max-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;600&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;The answer:&lt;/strong&gt; it doesn’t really matter, they are the same thing.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;He demonstrates it with this reduced test case&lt;/p&gt;
&lt;iframe height=&quot;500&quot; scrolling=&quot;no&quot; title=&quot;No difference between these&quot; src=&quot;//codepen.io/chriscoyier/embed/pbaQvG/?height=265&amp;#x26;theme-id=light&amp;#x26;default-tab=html,result&amp;#x26;embed-version=2&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot; style=&quot;width: 100%;&quot;&gt;See the Pen &amp;#x3C;a href=&apos;https://codepen.io/chriscoyier/pen/pbaQvG/&apos;&gt;No difference between these&amp;#x3C;/a&gt; by Chris Coyier  (&amp;#x3C;a href=&apos;https://codepen.io/chriscoyier&apos;&gt;@chriscoyier&amp;#x3C;/a&gt;) on &amp;#x3C;a href=&apos;https://codepen.io&apos;&gt;CodePen&amp;#x3C;/a&gt;.
&lt;/iframe&gt;
&lt;p&gt;Read the full article &lt;a href=&quot;https://css-tricks.com/tale-width-max-width/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Using Google analytics on Astro</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/astro-google-analytics-setup/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/astro-google-analytics-setup/</guid><description>How to add Google analytics script tags to Astro</description><pubDate>Wed, 16 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you’ve been keeping up with the extensive number of tools to build your website with; you may have come across &lt;a href=&quot;https://astro.build&quot;&gt;Astro&lt;/a&gt; — the all-in-one web framework designed for speed.&lt;/p&gt;
&lt;p&gt;Like a number of similar frameworks&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;; Astro embraces the &lt;a href=&quot;https://docs.astro.build/en/concepts/why-astro/#server-first&quot;&gt;server-first approach&lt;/a&gt; by rendering HTML on the server making websites faster to load. This makes Astro perfect for content-focused websites.&lt;/p&gt;
&lt;p&gt;I recently needed to add a Google Analytics tracking tag to a fun Astro project and this is how I did it.&lt;/p&gt;
&lt;h2 id=&quot;all-about-the-layout&quot;&gt;All about the layout&lt;/h2&gt;
&lt;p&gt;I needed to add the script tags to &lt;a href=&quot;https://docs.astro.build/en/core-concepts/layouts/&quot;&gt;the layout&lt;/a&gt; so they get rendered on pages using the layout. But rather than pasting the analytics scripts right into the layout template I created a component that gets rendered in &lt;code&gt;production&lt;/code&gt; only.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;import Analytics from &quot;components/analytics.astro&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;const isProd = import.meta.env.MODE === &apos;production&apos;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ... {isProd &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;Analytics&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;analytics-component&quot;&gt;Analytics component&lt;/h3&gt;
&lt;p&gt;The component itself needed to be reusable so I extracted the tag ID to an environment variable named &lt;code&gt;GTAG&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;const tagId = import.meta.env.GTAG;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;Fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;	&amp;#x3C;!-- Google tag (gtag.js) --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; is:inline&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=`&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;https:&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;//www.googletagmanager.com/gtag/js?id=${tagId}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; is:inline&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; define:vars&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;{{&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; tagId:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; tagId&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; }}&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;		window.dataLayer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; window.dataLayer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;		function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; gtag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;			dataLayer.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;arguments&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;		}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;		gtag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;js&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;		gtag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;config&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, tagId);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;Fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You may have noticed the &lt;a href=&quot;https://docs.astro.build/en/reference/directives-reference/#definevars&quot;&gt;&lt;code&gt;define:vars&lt;/code&gt; directive&lt;/a&gt; on the second script tag — this allows us to use server-side variables inside &lt;code&gt;&amp;#x3C;script&gt;&lt;/code&gt; and &lt;code&gt;&amp;#x3C;style&gt;&lt;/code&gt; tags.&lt;/p&gt;
&lt;p&gt;We use the &lt;code&gt;is:inline&lt;/code&gt; directive for the script to be rendered inline on the HTML.&lt;/p&gt;
&lt;p&gt;You could alternatively &lt;a href=&quot;https://docs.astro.build/en/guides/client-side-scripts/#pass-frontmatter-variables-to-scripts&quot;&gt;pass the variables manually&lt;/a&gt; through data attributes &lt;code&gt;data-*&lt;/code&gt; and then reading the values with &lt;code&gt;this.dataset.[variable-name]&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Cover photo: a red and white rocket ship flying through the sky — &lt;a href=&quot;https://unsplash.com/@kolamdigital&quot;&gt;Andy Hermawan&lt;/a&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Frameworks like &lt;a href=&quot;https://gatsbyjs.com/&quot;&gt;GatsbyJs&lt;/a&gt; or &lt;a href=&quot;https://nextjs.org/&quot;&gt;NextJs&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Tabs</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/displaying-data-with-tabs/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/displaying-data-with-tabs/</guid><description>Making tabs UI semantically</description><pubDate>Thu, 14 Sep 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Tabs are one of those UI components that make it easier to access a lot of information on a single window compared to other approaches i.e. Scrolling, links to different screens/windows etc.&lt;/p&gt;
&lt;p&gt;They are quite essential most UI frameworks include tabs as part of the package.&lt;/p&gt;
&lt;h3 id=&quot;some-tabs-from-some-of-the-popular-frameworks&quot;&gt;Some tabs from some of the &lt;a href=&quot;//www.keycdn.com/blog/front-end-frameworks/&quot;&gt;popular frameworks&lt;/a&gt;&lt;/h3&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/bootstrap.DFFgqV0C.png&quot; alt=&quot;Bootstrap tabs&quot; width=&quot;647&quot; height=&quot;275&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Bootstrap tabs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/foundation.Cpfb0jq5.png&quot; alt=&quot;Zurb Foundation tabs&quot; width=&quot;561&quot; height=&quot;233&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Zurb Foundation tabs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/semantic-ui.RPZO-UtC.png&quot; alt=&quot;Semantic UI tabs&quot; width=&quot;677&quot; height=&quot;198&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Semantic UI tabs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For the past few months my workflow has been moving towards having less dependency on third-party frameworks and libraries. This gave me more control on what goes into my codebase and hence reduce HTTP calls, overall file sizes and library debugging.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…less dependency on third-party frameworks and libraries…reduce HTTP calls, overall file sizes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While working on a project I needed to have a component that can display data on a tabbed container. With no support for HTML tabs element I decided to attempt making the simplest tab component I could.&lt;/p&gt;
&lt;h4 id=&quot;the-requirements&quot;&gt;The requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Clean semantic markup&lt;/li&gt;
&lt;li&gt;Minimal style dependency&lt;/li&gt;
&lt;li&gt;Supporting JavaScript for necessary interactions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With that I started working towards building the &lt;strong&gt;simple tabs&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;marking-up&quot;&gt;Marking up&lt;/h3&gt;
&lt;p&gt;The idea was to have a &lt;code&gt;.tab&lt;/code&gt; wrapper containing &lt;code&gt;.tab-header&lt;/code&gt; for links and &lt;code&gt;.tab-content&lt;/code&gt; for the content.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tab&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tab-header&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;..&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;...&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;..&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;...&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tab-content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;....&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;styles&quot;&gt;Styles&lt;/h3&gt;
&lt;p&gt;This was mostly done with &lt;a href=&quot;//tachyons.io&quot;&gt;Tachyons&lt;/a&gt;&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; with a bit of some custom bells and whistles. With that said; there’s not much to describe here as far as styling goes&lt;/p&gt;
&lt;h3 id=&quot;scripting&quot;&gt;Scripting&lt;/h3&gt;
&lt;p&gt;As mentioned earlier, I set out to write minimal JavaScript as possible&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. Essentially I had to break what’s needed into&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Showing active tab content when links are clicked&lt;/li&gt;
&lt;li&gt;Toggle active state for active link&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After a few iterations, I arrived at this class structure&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Tabs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  constructor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Initialize constants and initial call&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  bindClick&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;links&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Binding click events to handler&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  activate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;activeLink&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Activate link based on activeLink&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  showTab&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;tabName&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Display tab content&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;demo&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;Here’s everything put together on CodePen where you can play around with the code.&lt;/p&gt;
&lt;iframe height=&quot;500&quot; scrolling=&quot;no&quot; title=&quot;Simple tabs&quot; src=&quot;//codepen.io/talentedunicorn/embed/VzyMzg/?height=500&amp;#x26;theme-id=light&amp;#x26;default-tab=result&amp;#x26;embed-version=2&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot; style=&quot;width: 100%;&quot;&gt;See the Pen &amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn/pen/VzyMzg/&apos;&gt;Simple tabs&amp;#x3C;/a&gt; by Ezekiel (&amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn&apos;&gt;@talentedunicorn&amp;#x3C;/a&gt;) on &amp;#x3C;a href=&apos;https://codepen.io&apos;&gt;CodePen&amp;#x3C;/a&gt;.
&lt;/iframe&gt;
&lt;p&gt;If you enjoyed (or hated) this article, do leave me a line below and please do &lt;strong&gt;fork&lt;/strong&gt; the pen and share your version ;)&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Tachyons uses semantic classes that describe styles…almost like writing inline css &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;There’s “mushroom” for improvement of course &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Star rating component</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/rating-component-with-meter/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/rating-component-with-meter/</guid><description>An attempt to build rating components semantically using the meter element and styling with CSS</description><pubDate>Sun, 26 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently when working on a project I came across a design that included rating information on the interface. The UI included some “stars” representing the rating with the value shown as the colored in part of the star and the total rating being the number of stars.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/rating.CVSu4UxG.png&quot; alt=&quot;Rating stars&quot; width=&quot;206&quot; height=&quot;74&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Rating stars&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;First thing first, the markup structure of the indicator HAD to be semantic and accesssible before anything else&lt;/p&gt;
&lt;h3 id=&quot;markup&quot;&gt;Markup&lt;/h3&gt;
&lt;p&gt;Rating indicators have been around for a while on the Internet but there hasn’t been much standardization of the markup used in these elements. I did some digging and found different methods used by current popular websites.&lt;/p&gt;
&lt;p&gt;For example &lt;a href=&quot;https://airbnb.com&quot;&gt;Airbnb&lt;/a&gt; uses &lt;code&gt;svg&lt;/code&gt; inside multiple spans&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/airbnb_rating.DuEpsjLN.png&quot; alt=&quot;Airbnb rating&quot; width=&quot;143&quot; height=&quot;22&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Airbnb rating&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;img&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Rating 5 out of 5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While &lt;a href=&quot;https://amazon.com&quot;&gt;Amazon&lt;/a&gt; uses the &lt;code&gt;&amp;#x3C;i&gt;&lt;/code&gt; element with a &lt;code&gt;&amp;#x3C;span&gt;&lt;/code&gt; for the label&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/amazon_rating.Dk7kEs0j.png&quot; alt=&quot;Amazon rating&quot; width=&quot;115&quot; height=&quot;39&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;Amazon rating&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;a-icon&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;a-icon-alt&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;3.6 out of 5 stars&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I needed something that would be semantic and accessible to users. I came across the &lt;code&gt;&amp;#x3C;meter&gt;&lt;/code&gt; element that had most of the semantic aspects; if you are new to the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter&quot;&gt;meter element&lt;/a&gt; it is described as “representing either a scalar value within a known range or a fractional value.”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Meter element represents either a scalar value within a known range or a fractional value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The markup for the rating element would look something like this&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meter&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;3.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;Rating 3.5 out of 5&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, the meter element has a bar similar to the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress&quot;&gt;progress&lt;/a&gt; element.&lt;/p&gt;
&lt;p&gt;&lt;meter min=&quot;0&quot; max=&quot;5&quot; value=&quot;3.5&quot;&gt;Rating 3.5 out of 5&lt;/meter&gt;&lt;/p&gt;
&lt;p&gt;What we need is “stars” to represent our rating, we’ll get this done with the styles&lt;/p&gt;
&lt;h3 id=&quot;styling&quot;&gt;Styling&lt;/h3&gt;
&lt;p&gt;The meter element is &lt;a href=&quot;https://caniuse.com/#feat=meter&quot;&gt;well supported&lt;/a&gt; across a lot of browsers (with exception of Internet Explorer at the time of this post). Styling the meter element is covered quite extensively on &lt;a href=&quot;https://css-tricks.com/html5-meter-element/&quot;&gt;this article&lt;/a&gt; by Pankaj Parashar but I was not pleased with the number of vendor prefixes needed to change the look of the element.&lt;/p&gt;
&lt;p&gt;In addition to consistent experience across browsers; maintaining semantics and accessibility is of high priority. According to the article; pseudo-elements for the meter element are only supported on webkit browsers so I decided to take a leaf out of amazon’s book and wrap the meter element in a &lt;code&gt;&amp;#x3C;span&gt;&lt;/code&gt; which resulted to the following markup:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;meter&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Rating 3.5 out of 5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;--currentIndex: 3.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meter&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;3.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;Rating 3.5 out of 5&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;preparing-the-star-graphic&quot;&gt;Preparing the star graphic&lt;/h4&gt;
&lt;p&gt;For the stars, I found an svg which I had optimized and converted to a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs&quot;&gt;data-uri&lt;/a&gt; then used that as my background.&lt;/p&gt;
&lt;h4 id=&quot;binding-the-data-to-styles&quot;&gt;Binding the data to styles&lt;/h4&gt;
&lt;p&gt;To communicate the value between my markup and styles I used &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables&quot;&gt;CSS variables&lt;/a&gt; with the rating value in an inline style attribute.&lt;/p&gt;
&lt;p&gt;I would later on use that value to render the correct representation of the rating. Here’s how my styles looked like&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Some variables */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;:root&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  --size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  --max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  --inactive&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;gray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  --active&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;yellow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.meter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  meter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    display&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  display: &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;inline-block&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  width: calc(var(--size) &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; var(--max));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  height: var(--size);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  position: relative;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;::before&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;::after&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    position&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    left&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    right&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    mask&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;left&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; center&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;contain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    mask-image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--star&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;::before&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    background&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--inactive&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;::after&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    z-index&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    background&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--active&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    right&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--currentIndex&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;--max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I needed two “layers”, one for the base stars which I used the &lt;code&gt;&amp;#x26;::before&lt;/code&gt; pseudo-element and for the active state I used the &lt;code&gt;&amp;#x26;::after&lt;/code&gt;. Below is a pen demonstration:&lt;/p&gt;
&lt;iframe height=&quot;265&quot; scrolling=&quot;no&quot; title=&quot;Rating with Meter element&quot; src=&quot;//codepen.io/talentedunicorn/embed/qMBBdE/?height=265&amp;#x26;theme-id=0&amp;#x26;default-tab=result&amp;#x26;embed-version=2&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot; style=&quot;width: 100%;&quot;&gt;See the Pen &amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn/pen/qMBBdE/&apos;&gt;Rating with Meter element&amp;#x3C;/a&gt; by Ezekiel (&amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn&apos;&gt;@talentedunicorn&amp;#x3C;/a&gt;) on &amp;#x3C;a href=&apos;https://codepen.io&apos;&gt;CodePen&amp;#x3C;/a&gt;.
&lt;/iframe&gt;</content:encoded></item><item><title>Configure Auth0 JWT on CouchDB</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/setup-auth0-jwt-on-couchdb/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/setup-auth0-jwt-on-couchdb/</guid><description>CouchDB is an OpenSource NoSQL document database developed by Apache; it as built-in data replication which makes it great for offline-first applications.</description><pubDate>Wed, 01 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt; is an OpenSource NoSQL document database developed by &lt;a href=&quot;https://apache.org&quot;&gt;Apache&lt;/a&gt;; it has &lt;a href=&quot;https://docs.couchdb.org/en/stable/replication/index.html&quot;&gt;built-in data replication&lt;/a&gt; which makes it great for offline-first applications.&lt;/p&gt;
&lt;p&gt;Data replication allows users to continue using your application with a local copy of the database while offline — then once they are back online; their changes are automatically replicated (synchronized) with the remote database.&lt;/p&gt;
&lt;p&gt;To replicate data securely users need to be authenticated on the remote CouchDB server. There are a few ways to do this;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a user in the &lt;a href=&quot;https://docs.couchdb.org/en/stable/intro/security.html#authentication-database&quot;&gt;&lt;strong&gt;_users&lt;/strong&gt; authentication database&lt;/a&gt; and using Basic Authentication or Cookies with each request&lt;/li&gt;
&lt;li&gt;Using an extenal JSON Web Token (JWT)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;using-external-jwt-tokens-on-couchdb&quot;&gt;Using external JWT tokens on CouchDB&lt;/h2&gt;
&lt;p&gt;You can use any JWT provider; in this example I will be using &lt;a href=&quot;https://auth0.com&quot;&gt;Auth0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Firstly you need to have the following prerequisites;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An account on Auth0&lt;/li&gt;
&lt;li&gt;An application on Auth0. See &lt;a href=&quot;https://auth0.com/docs/quickstarts&quot;&gt;Quickstart guides&lt;/a&gt; for examples on how to create one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After creating your application on Auth0 you should have a &lt;strong&gt;JSON Web Key Set&lt;/strong&gt; url similar to this one&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://your-domain.auth0.com/.well-known/jwks.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To find this on Auth0; navigate to the &lt;strong&gt;Advanced Settings&lt;/strong&gt; section on your app and select the &lt;strong&gt;Endpoints&lt;/strong&gt; tab.&lt;/p&gt;
&lt;h3 id=&quot;enable-jwt-authentication-on-couchdb&quot;&gt;Enable JWT authentication on CouchDB&lt;/h3&gt;
&lt;p&gt;Log into your CouchDB instance using &lt;a href=&quot;https://docs.couchdb.org/en/stable/fauxton/index.html&quot;&gt;Fauxton&lt;/a&gt; or REST API and enable JWT authentication by adding &lt;code&gt;{chttpd_auth, jwt_authentication_handler}&lt;/code&gt;
to &lt;a href=&quot;https://docs.couchdb.org/en/stable/config/http.html#chttpd/authentication_handlers&quot;&gt;authentication handlers&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;set-up-public-keys-on-couchdb&quot;&gt;Set up public keys on CouchDB&lt;/h3&gt;
&lt;p&gt;Then add your public keys to the &lt;code&gt;jwt_keys&lt;/code&gt; section of the configuration&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[jwt_keys]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rsa:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;YOUR_KEY_ID&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; = -----BEGIN PUBLIC KEY-----\n&amp;#x3C;YOUR_PUBLIC_KEY_FROM_JWK_SET&gt;\n-----END PUBLIC KEY-----\n&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Get the PEM format of your public key from the JWT key set url with the &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;openssl&lt;/code&gt; commands&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; https://your-domain.auth0.com/pem&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -s&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; openssl&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; x509&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -pubkey&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -noout&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Get the key IDs from the JWT key set url using the &lt;code&gt;kid&lt;/code&gt; value&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;    keys&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;            kid&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;KEY_ID&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your changes should be applied and you can make requests with a &lt;code&gt;Bearer {jwt_token}&lt;/code&gt; in the &lt;code&gt;Authorization&lt;/code&gt; header.
You may need to restart your CouchDB server if you made the changes locally to the &lt;code&gt;default.ini&lt;/code&gt; or &lt;code&gt;local.ini&lt;/code&gt; files.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  -H&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Authorization: Bearer AUTH0_JWT_TOKEN&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; https://your-couchdb-server/_session&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If everything went well you should get a response like this&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;userCtx&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;USER_ID&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;roles&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:[]},&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;authentication_handlers&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookie&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;jwt&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]}}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;authorizing-access-to-a-database&quot;&gt;Authorizing access to a database&lt;/h3&gt;
&lt;p&gt;Since we may have multiple databases in our CouchDB instance we would want only authorized users have access to a database.&lt;/p&gt;
&lt;p&gt;In CouchDB you can get authorized into either a &lt;em&gt;member&lt;/em&gt; or &lt;em&gt;admin&lt;/em&gt; class. To authorize a user add the &lt;code&gt;USER_ID&lt;/code&gt; to either the member or admin fields. Alternatively you can define roles in your JWT provider and use those instead of individually adding usernames.&lt;/p&gt;
&lt;p&gt;For Auth0, refer to the &lt;strong&gt;user_id&lt;/strong&gt; field in the &lt;a href=&quot;https://auth0.com/docs/manage-users/user-accounts/view-user-details#user-details-details-tab&quot;&gt;user details tab&lt;/a&gt; under &lt;strong&gt;Indetity provider attributes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You should be able to make a request to the database and get a successful response&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  -H&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Authorization: Bearer AUTH0_JWT_TOKEN&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; https://your-couchdb-server/your-database/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s all for now.&lt;/p&gt;</content:encoded></item><item><title>Testing React applications with Github Actions</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/testing-react-with-github-actions/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/testing-react-with-github-actions/</guid><description>It goes without saying that code testing is beneficial for a variety of reasons. But most developers (me included) tend to skip testing when working on a project...</description><pubDate>Sat, 16 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It goes without saying that code testing is beneficial for a &lt;a href=&quot;https://dev.to/flippedcoding/its-important-to-test-your-code-3lid&quot;&gt;variety of reasons&lt;/a&gt;. But most developers (me included) tend to skip testing when working on a project mostly due to the technical effort of setting them up &lt;em&gt;&lt;del&gt;or pure laziness&lt;/del&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If you are &lt;em&gt;super&lt;/em&gt; new to testing; the minimal setup would include a &lt;strong&gt;test runner&lt;/strong&gt; and &lt;strong&gt;test coverage&lt;/strong&gt;. There is a helpful &lt;a href=&quot;https://www.javascriptjanuary.com/blog/getting-started-with-front-end-testing&quot;&gt;article&lt;/a&gt; by &lt;strong&gt;JavasScipt January&lt;/strong&gt; to get you started.&lt;/p&gt;
&lt;h3 id=&quot;test-runners&quot;&gt;Test runners&lt;/h3&gt;
&lt;p&gt;These are programs that specifically run tests, they vary &lt;em&gt;mostly&lt;/em&gt; in syntax and setup. Some of the most commonly used test runners on ReactJs are &lt;a href=&quot;https://jest.io&quot;&gt;Jest&lt;/a&gt;, &lt;a href=&quot;https://mochajs.org&quot;&gt;Mocha&lt;/a&gt; and &lt;a href=&quot;https://github.com/avajs/ava&quot;&gt;Ava&lt;/a&gt;. We will be using Jest to do testing.&lt;/p&gt;
&lt;h3 id=&quot;test-coverage&quot;&gt;Test coverage&lt;/h3&gt;
&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Code_coverage&quot;&gt;test coverage / code coverage&lt;/a&gt; is a report of how much of the code has been executed when a test suite has completed.
When writing tests, we need to know what pieces of the code to test. This is because the overall codebase includes dependencies (e.g. libraries) and your source code and therefore there needs to be a way to know if you’ve tested your source code.&lt;/p&gt;
&lt;h2 id=&quot;example-application&quot;&gt;Example application&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/github-status-checker.Zq4Fq4K-.png&quot; alt=&quot;GitHub status checking application&quot; width=&quot;699&quot; height=&quot;381&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The app we will build will have the following requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To display the current status of GitHub website&lt;/li&gt;
&lt;li&gt;To display the time of the status reported&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;scaffolding-the-application&quot;&gt;Scaffolding the application&lt;/h3&gt;
&lt;p&gt;We will start with creating a basic React application using &lt;a href=&quot;https://create-react-app.dev&quot;&gt;Create React App (CRA)&lt;/a&gt; by running the command &lt;code&gt;npx create-react-app github-status&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After the process has completed, navigate to the folder &lt;strong&gt;github-status&lt;/strong&gt; and start setting up tests.&lt;/p&gt;
&lt;h3 id=&quot;setup-and-running-tests&quot;&gt;Setup and running tests&lt;/h3&gt;
&lt;p&gt;As of the time of writing, CRA comes with an initial test and bundled with &lt;a href=&quot;https://testing-library.com/&quot;&gt;Testing library&lt;/a&gt; to help with DOM queries.&lt;/p&gt;
&lt;p&gt;We can run tests using the command &lt;code&gt;$ npm run test&lt;/code&gt; inside the root of our project. The results of the test would be displayed and are refreshed when there are changes to the code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To run tests with coverage run the command &lt;code&gt;npm run test --coverage&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;testing-requirements&quot;&gt;Testing requirements&lt;/h3&gt;
&lt;p&gt;Before testing we mock the fetch API in the tests and reset after each test.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;beforeEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	global.fetch &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; jest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;mockResolvedValue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;({ status: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, text: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;up&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;afterEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	global.fetch &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; jest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we will use &lt;code&gt;waitForElement&lt;/code&gt; function to handle the async fetch function before we can assert results. &lt;code&gt;waitForElement&lt;/code&gt; &lt;a href=&quot;https://testing-library.com/docs/dom-testing-library/api-async#waitforelement-deprecated-use-find-queries-or-waitfor&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;waitForElement&lt;/code&gt; is deprecated on testing library and is replaced by &lt;code&gt;waitFor&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;writing-tests&quot;&gt;Writing tests&lt;/h3&gt;
&lt;p&gt;We shall begin by writing tests for our requirements by adding two more tests to the file &lt;code&gt;./src/__tests__/App.test.js&lt;/code&gt; in our project.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;To display the current status of GitHub website&lt;/strong&gt;
We will use a &lt;a href=&quot;https://testing-library.com/docs/dom-testing-library/api-queries#bytestid&quot;&gt;test id&lt;/a&gt; &lt;code&gt;status&lt;/code&gt; to detect the status element&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;should display github status&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;getByTestId&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; render&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;App&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; waitForElement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getByTestId&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getByTestId&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toBeTruthy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;To display the time of the status reported&lt;/strong&gt;
For the time we will use the test id &lt;code&gt;status-time&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;should display github status time&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;getByTestId&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; render&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;App&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getByTestId&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;status-time&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toBeTruthy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;running-tests&quot;&gt;Running tests&lt;/h3&gt;
&lt;p&gt;After writing the tests, run the command &lt;code&gt;npm run test&lt;/code&gt; and we can see the tests failing. We can now build the necessary code until all our tests have passed. See the &lt;a href=&quot;https://codesandbox.io/embed/github-status-checker-rw0wz?fontsize=14&amp;#x26;hidenavigation=1&amp;#x26;module=/src/__tests__/App.test.js&amp;#x26;previewwindow=tests&amp;#x26;theme=dark&quot;&gt;codesandbox example&lt;/a&gt; for the code.&lt;/p&gt;
&lt;iframe src=&quot;https://codesandbox.io/embed/github-status-checker-rw0wz?fontsize=14&amp;#x26;hidenavigation=1&amp;#x26;module=%2Fsrc%2F__tests__%2FApp.test.js&amp;#x26;previewwindow=tests&amp;#x26;theme=dark&quot; style=&quot;width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;&quot; title=&quot;GitHub status checker&quot; allow=&quot;accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr&quot; sandbox=&quot;allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts&quot;&gt;&lt;/iframe&gt;
&lt;h2 id=&quot;github-actions&quot;&gt;GitHub Actions&lt;/h2&gt;
&lt;p&gt;If you are not familiar with GitHub Actions, it is a way to execute workflows against code on GitHub. There is &lt;a href=&quot;https://css-tricks.com/introducing-github-actions/&quot;&gt;an article&lt;/a&gt; from CSS-Tricks about GitHub Actions that go in depth. Since &lt;a href=&quot;https://github.blog/changelog/2019-11-11-github-actions-is-generally-available/&quot;&gt;November 2019&lt;/a&gt; GitHub opened up Actions for free to public repositories.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-the-workflow&quot;&gt;Setting up the workflow&lt;/h3&gt;
&lt;p&gt;We will create a workflow that does the following on each &lt;strong&gt;push&lt;/strong&gt; event to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;run our tests&lt;/li&gt;
&lt;li&gt;build the code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To setup a workflow, we create a YAML file on the workflows directory &lt;code&gt;.github/workflows/push.yml&lt;/code&gt; in our case we name it &lt;code&gt;push.yml&lt;/code&gt; with the following content:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Test and build code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    branches&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;master&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;staging&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;jobs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  unit-test&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Run tests and build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    runs-on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ubuntu-latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    steps&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/checkout@v2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/setup-node@v1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          node-version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;10.x&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;npm install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;npm run test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;npm run build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The file specifies actions to run the workflow when certain events occur on the repository through the &lt;code&gt;on:&lt;/code&gt; key, in our case the &lt;strong&gt;push&lt;/strong&gt; event. GitHub Actions documentation has a list of current &lt;a href=&quot;https://help.github.com/en/actions/reference/events-that-trigger-workflows&quot;&gt;supported event&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We will run the jobs on the &lt;strong&gt;master&lt;/strong&gt; and &lt;strong&gt;staging&lt;/strong&gt; branches using the &lt;code&gt;branches&lt;/code&gt; configuration. We defined a job with ID &lt;code&gt;unit-test&lt;/code&gt; which will run on an &lt;code&gt;ubuntu-latest&lt;/code&gt; container. The next line describes the steps to take:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Using &lt;code&gt;actions/checkout@v2&lt;/code&gt; a &lt;a href=&quot;https://help.github.com/en/actions/getting-started-with-github-actions/using-community-workflows-and-actions&quot;&gt;community action&lt;/a&gt; to checkout our code in the container.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;actions/setup-node@v1&lt;/code&gt; to setup a node environment on the container.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When we push the code, we are able to see under the actions tab on GitHub our tests and build running.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/github-actions-running-tests.Ewjo31eV.png&quot; alt=&quot;GitHub Actions running tests and build&quot; width=&quot;1267&quot; height=&quot;319&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;GitHub Actions running tests and build&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We can view more details by clicking on the workflow, in this case the tests and build had been executed and completed successfully.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/github-actions-completed.DRZ07U2Y.png&quot; alt=&quot;GitHub Actions completed&quot; width=&quot;932&quot; height=&quot;490&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;GitHub Actions running tests and build&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This is just one example of GitHub Actions, you can create your own workflows or use something in the &lt;a href=&quot;https://github.com/marketplace?type=actions&quot;&gt;marketplace&lt;/a&gt;. Hope this was fun and informative.&lt;/p&gt;</content:encoded></item><item><title>The sass, the style &amp; the ampersand</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/the-sass-the-style-and-the-ampersand/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/the-sass-the-style-and-the-ampersand/</guid><description>While browsing through my news feed I recently came across an article by Rich Finelli on the Sass ampersand covering neat techniques...</description><pubDate>Tue, 08 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;While browsing through my news feed I recently came across an &lt;a href=&quot;https://css-tricks.com/the-sass-ampersand/&quot;&gt;article&lt;/a&gt; by &lt;a href=&quot;http://www.richfinelli.com/&quot;&gt;Rich Finelli&lt;/a&gt; on the &lt;strong&gt;Sass ampersand&lt;/strong&gt; covering neat techniques to using the Sass ampersand. I would recommend reading if you use Sass in development.&lt;/p&gt;
&lt;p&gt;Among the examples given these are my favorite:&lt;/p&gt;
&lt;h3 id=&quot;overriding-styles&quot;&gt;Overriding styles&lt;/h3&gt;
&lt;p&gt;To override styles on a selector you can add a parent selector with a suffix &lt;code&gt;&amp;#x26;&lt;/code&gt;&lt;/p&gt;
&lt;iframe height=&quot;265&quot; scrolling=&quot;no&quot; title=&quot;Sass ampersand: Overriding styles&quot; src=&quot;//codepen.io/talentedunicorn/embed/xVZvEY/?height=265&amp;#x26;theme-id=light&amp;#x26;default-tab=css,result&amp;#x26;embed-version=2&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot; style=&quot;width: 100%;&quot;&gt;See the Pen &amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn/pen/xVZvEY/&apos;&gt;Sass ampersand: Overriding styles&amp;#x3C;/a&gt; by Ezekiel (&amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn&apos;&gt;@talentedunicorn&amp;#x3C;/a&gt;) on &amp;#x3C;a href=&apos;https://codepen.io&apos;&gt;CodePen&amp;#x3C;/a&gt;.
&lt;/iframe&gt;
&lt;h3 id=&quot;adding-modifiers-to-selectors&quot;&gt;Adding modifiers to selectors&lt;/h3&gt;
&lt;p&gt;To add a selector &lt;code&gt;.class-modified&lt;/code&gt; you can nest the &lt;code&gt;&amp;#x26;-modifier&lt;/code&gt; inside &lt;code&gt;.class&lt;/code&gt;&lt;/p&gt;
&lt;iframe height=&quot;265&quot; scrolling=&quot;no&quot; title=&quot;Sass ampersand: Adding modifier&quot; src=&quot;//codepen.io/talentedunicorn/embed/qZbeoJ/?height=265&amp;#x26;theme-id=light&amp;#x26;default-tab=css,result&amp;#x26;embed-version=2&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot; style=&quot;width: 100%;&quot;&gt;See the Pen &amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn/pen/qZbeoJ/&apos;&gt;Sass ampersand: Adding modifier&amp;#x3C;/a&gt; by Ezekiel (&amp;#x3C;a href=&apos;https://codepen.io/talentedunicorn&apos;&gt;@talentedunicorn&amp;#x3C;/a&gt;) on &amp;#x3C;a href=&apos;https://codepen.io&apos;&gt;CodePen&amp;#x3C;/a&gt;.
&lt;/iframe&gt;</content:encoded></item><item><title>Using React useState with form inputs</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/using-react-usestate-with-form-inputs/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/using-react-usestate-with-form-inputs/</guid><description>s of React 16.8, ReactJs added hooks. State hooks is a way to have functional components and state at the same time...</description><pubDate>Mon, 23 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As of React 16.8, ReactJs added hooks. &lt;a href=&quot;https://reactjs.org/docs/hooks-overview.html#state-hook&quot;&gt;State hooks&lt;/a&gt; is a way to have functional components and state at the same time (prior to this you had to have a class declaration if you needed internal state management in your component).&lt;/p&gt;
&lt;p&gt;I won’t go into details about hooks but if you are keen, i recommend reading &lt;a href=&quot;https://tylermcginnis.com/why-react-hooks/&quot;&gt;this article by Tyler McGinnis&lt;/a&gt; which covers the topic very well.&lt;/p&gt;
&lt;p&gt;What I’d like to point out is something I came across recently when implementing state on a form input using the &lt;code&gt;useState&lt;/code&gt; hook. I’ll skip some markup but here is a &lt;a href=&quot;https://codesandbox.io/s/usestate-on-input-8zft0&quot;&gt;sandbox implementation&lt;/a&gt; of this use case you can play around with ;)&lt;/p&gt;
&lt;p&gt;I start by declaring the state using &lt;code&gt;useState&lt;/code&gt; hook:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; React, { useState } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;react&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [ &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;setUsername&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; useState&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the markup looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{username}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  onChange&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; setUsername&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(e.target.value)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;input’s value is initialized with a value of &lt;code&gt;undefined&lt;/code&gt; if the hook is defined without a value&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In a nutshell, the value of the &lt;code&gt;username&lt;/code&gt; input should be updated to whatever the input target value is by &lt;code&gt;setUsername&lt;/code&gt; function. When you try to edit the input you will get a warning like this:&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/904501/65312673-88458680-db82-11e9-82c4-868f63dfc056.png&quot; alt=&quot;Warning&quot;&gt;&lt;/p&gt;
  &lt;figcaption&gt;React warning about changing uncontrolled input of type undefined&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The reason this happens is because the input’s value is initialized with a value of &lt;code&gt;undefined&lt;/code&gt; if the hook is defined without a value i.e. &lt;code&gt;const [var, setVar] = useState()&lt;/code&gt;. This can be easily resolved by initializing the &lt;code&gt;username&lt;/code&gt; to an empty string instead like so:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;setUsername&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; useState&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that change the warning will disappear and your input will work as expected. Hope this helps anyone facing issues implementing &lt;em&gt;useState&lt;/em&gt; with controlled form inputs.&lt;/p&gt;</content:encoded></item><item><title>Where are you Form - Understanding forms on the web</title><link>https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/where-are-you-form/</link><guid isPermaLink="true">https://talentedunicorn-1i14i99tp-talentedunicorn-team.vercel.app/blog/where-are-you-form/</guid><description>If you have used a website in the last 10+ years you have most likely come across a form...</description><pubDate>Mon, 24 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you have used a website in the last 10+ years you have most likely come across a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form&quot;&gt;form&lt;/a&gt;. They have been a vital part of how we interact with websites (in today’s case) webapps. The most common ways to send information across the Internet is through a form of some sort, whether it being sending emails, tweeting or taking a test online mostly you will be using a form.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The most common ways to send information across the Internet is through a form&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are even websites that are &lt;strong&gt;mostly&lt;/strong&gt; a form &lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; yet most people who have had bad user experience on the internet was most likely using a form.&lt;/p&gt;
&lt;p&gt;Even with newer technologies like augmented reality (AR) and virtual reality (VR) technologies adding on the the various ways we can interact with interfaces; forms still remain present in many products.&lt;/p&gt;
&lt;p&gt;I made a small collection of some useful articles and resources while trying to understand forms&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/multipage/forms.html#the-form-element&quot;&gt;HTML Form element specifications&lt;/a&gt; a living standard of the HTML form element&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://funwithforms.com/&quot;&gt;Fun with forms by …&lt;/a&gt; all things forms by &lt;a href=&quot;https://twitter.com/justmarkup&quot;&gt;@justmarkup&lt;/a&gt;; my favourite was the use of &lt;a href=&quot;https://funwithforms.com/posts/form-attribute/&quot;&gt;&lt;code&gt;form&lt;/code&gt; and &lt;code&gt;formAction&lt;/code&gt; attributes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://adamsilver.io/articles&quot;&gt;Adam Silver’s blog&lt;/a&gt; has great articles on form design&lt;/li&gt;
&lt;/ul&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Most search engines are forms &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item></channel></rss>