<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Taran "tearing it up" Bains Blog</title>
        <link>https://taranveerbains.ca/til</link>
        <description>Today Taran learned about...</description>
        <lastBuildDate>Tue, 30 Jun 2026 07:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>Taran "tearing it up" Bains</copyright>
        <item>
            <title><![CDATA[MOSH]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-30-mosh#2026-06-30-mosh</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-30-mosh#2026-06-30-mosh</guid>
            <pubDate>Tue, 30 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a replacement for `ssh`, it's `mosh`! `mosh` (Mobile shell) has more features than `ssh` that improve usability!

[Check it out](https://raphamorim.io/mosh-a-replacement-for-ssh/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Shimmer From Structure]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-29-shimmer-from-structure#2026-06-29-shimmer-from-structure</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-29-shimmer-from-structure#2026-06-29-shimmer-from-structure</guid>
            <pubDate>Mon, 29 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about shimmer-from-structure! A context aware skeleton loader that mirrors your rendered UI at runtime 💀.

[Check it out](https://github.com/darula-hpp/shimmer-from-structure)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hydration errors and extensions]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-29-hydration-errors-and-extensions#2026-06-29-hydration-errors-and-extensions</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-29-hydration-errors-and-extensions#2026-06-29-hydration-errors-and-extensions</guid>
            <pubDate>Mon, 29 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Don't forget that your browser extensions can be a cause of hydration issues for your React apps. We had some
false positives in production where we thought we introduced some hydration issues but it was actually
one of our custom extensions causing the problem!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Self-hosted Wanderlog]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-25-self-hosted-wanderlog#2026-06-25-self-hosted-wanderlog</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-25-self-hosted-wanderlog#2026-06-25-self-hosted-wanderlog</guid>
            <pubDate>Thu, 25 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a self-hosted trip planner that's just like Wanderlog! 

[Check it out](https://github.com/mauriceboe/TREK)

]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[cnfast]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-23-cnfast#2026-06-23-cnfast</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-23-cnfast#2026-06-23-cnfast</guid>
            <pubDate>Tue, 23 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about cnfast! A fast drop in replacement for `cn`! It's roughly 3.8x faster than `tailwind-merge` ❤️.

[Check it out](https://github.com/aidenybai/cnfast)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cooler prefetching]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-22-cooler-prefetching#2026-06-22-cooler-prefetching</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-22-cooler-prefetching#2026-06-22-cooler-prefetching</guid>
            <pubDate>Mon, 22 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a cool new way to handle prefetching things in the browser!

[Check it out](https://foresightjs.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Code review, in your terminal.]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-06-19-code-review-in-your-terminal#2026-06-19-code-review-in-your-terminal</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-06-19-code-review-in-your-terminal#2026-06-19-code-review-in-your-terminal</guid>
            <pubDate>Fri, 19 Jun 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about tuicr!

It's a TUI for code review with vim keybindings (you know we love that ❤️)! More and more,
I find myself living in the terminal, and my overall satisfaction with my work is
increasing 😂.

[Check it out](https://tuicr.dev/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[herdr]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-05-28-herdr#2026-05-28-herdr</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-05-28-herdr#2026-05-28-herdr</guid>
            <pubDate>Thu, 28 May 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about herdr! It's a great terminal multiplexer when working with AI agents!

I'm still and probably will always be a tmux fanboy, but when working on my home server, using this over
herdr has been great, because let's be real, I ain't gonna spend the time to throw up my entire `dotfiles` config
in an ephemeral VM that I'll probably delete by the end of the month lol. 😂

[Check it out](https://herdr.dev/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react hook forms]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-05-04-react-hook-forms#2026-05-04-react-hook-forms</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-05-04-react-hook-forms#2026-05-04-react-hook-forms</guid>
            <pubDate>Mon, 04 May 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a useful library for forms! It seems pretty lightweight and great for SPAs and no SPAs alike!

[Check it out](https://github.com/react-hook-form/react-hook-form)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[reactive resume]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-04-26-reactive-resume#2026-04-26-reactive-resume</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-04-26-reactive-resume#2026-04-26-reactive-resume</guid>
            <pubDate>Sun, 26 Apr 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about reactive resume! A free open source resume builder; no more paying for my brother's resume updates!

[Check it out](https://rxresu.me/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[skills marketplace]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-04-20-skills-marketplace#2026-04-20-skills-marketplace</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-04-20-skills-marketplace#2026-04-20-skills-marketplace</guid>
            <pubDate>Mon, 20 Apr 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about skills.sh; it's an open agent skills ecosystem!

[Check it out](https://skills.sh/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[product vs engineering]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-04-07-product-vs-engineering#2026-04-07-product-vs-engineering</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-04-07-product-vs-engineering#2026-04-07-product-vs-engineering</guid>
            <pubDate>Tue, 07 Apr 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Product is about building the **right thing**.
Engineering used to be (and still largely is) about building the **thing right**.

Building the thing right is downstream from buiding the right thing.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Forgejo]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-04-03-forgejo#2026-04-03-forgejo</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-04-03-forgejo#2026-04-03-forgejo</guid>
            <pubDate>Fri, 03 Apr 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Foregjo (pronounced like "for-jay-oh") is a lightweight, self-hosted github alternative. It's free and open source!
Cards on the table 😅, I reached for this project because I could not justify spending actual money on something like Laravel Cloud
or Fly.io for hosting a **hobby** project that generates no revenue.

Forgejo ships with docker registry support so I was able to containerize my Laravel app and deploy it as a
Docker container managed by Dockge. Pair this up with something like cloudflare tunnels (which we all know I'm using) and
you've got free hosting friends!

[Check it out](https://forgejo.org/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react joyride]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-03-27-react-joyride#2026-03-27-react-joyride</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-03-27-react-joyride#2026-03-27-react-joyride</guid>
            <pubDate>Fri, 27 Mar 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about react joyride! A sick way to add in a tour to your app!

[Check it out](https://react-joyride.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Easing wizard]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-03-13-easing-wizard#2026-03-13-easing-wizard</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-03-13-easing-wizard#2026-03-13-easing-wizard</guid>
            <pubDate>Fri, 13 Mar 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a neat website that helps you get cool custom transition timing functions for your css needs; it even
gives you Tailwind classes that you can use!

[Check it out](https://easingwizard.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Starting Style]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-03-11-starting-style#2026-03-11-starting-style</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-03-11-starting-style#2026-03-11-starting-style</guid>
            <pubDate>Wed, 11 Mar 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `@starting-style`; it lets you define the initial styles of an element before its first style is applied
— essentially giving you a "from" state for CSS transitions on elements that are
being added to the DOM or transitioning from display: none.

```css {5-8}
.card {
	transition:
		opacity 0.3s,
		transform 0.3s;

	@starting-style {
		opacity: 0;
		transform: translateY(10px);
	}
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Impeccable Design Skills]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-03-10-impeccable-design-skills#2026-03-10-impeccable-design-skills</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-03-10-impeccable-design-skills#2026-03-10-impeccable-design-skills</guid>
            <pubDate>Tue, 10 Mar 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the Impeccable skills; a design fluency for our AI harnesses! Let's see how she goes.

[Check it out](https://impeccable.style)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Flow]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-03-09-react-flow#2026-03-09-react-flow</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-03-09-react-flow#2026-03-09-react-flow</guid>
            <pubDate>Mon, 09 Mar 2026 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about React Flow! A customizable React component for building node-based editors
and interactive diagrams (yes, this was pulled directly from their website)😆.

[Check it out](https://reactflow.dev/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[npmx]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-03-03-npmx#2026-03-03-npmx</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-03-03-npmx#2026-03-03-npmx</guid>
            <pubDate>Tue, 03 Mar 2026 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [npmx](https://npmx.dev/); a fast, modern browswer for the npm registry!

I think a lot of the hype around it is that it's cool people doing cool things together. That adage of
"you can just do stuff" really encompasses what npmx is about. They want to make things better and
they want to do it with a team of real humans that really care.

[Check it out](https://npmx.dev/blog/alpha-release)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS Specificity Calculator]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-02-26-css-specificity-calculator#2026-02-26-css-specificity-calculator</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-02-26-css-specificity-calculator#2026-02-26-css-specificity-calculator</guid>
            <pubDate>Thu, 26 Feb 2026 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a handy mathematical formula for determining and calculating CSS specificity. It's a triad: A, B, C.

A is `id`-like (#main), B is `class`-like (.yolo), and C is `element`-like (div). It's often represented as (A, B, C) notation. There are
even handy calculators to use online!

```CSS
/* (0, 0, 1) */
p { color: red; }

/* (0, 1, 0) */
.intro { color: blue; }

/* (0, 1, 1) */
p.intro { color: green; }

/* (1, 0, 0) */
#main { color: purple; }

```

[Check it out](https://specificity.keegan.st/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tailwind CSS Color Generator]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-02-21-tailwind-css-color-generator#2026-02-21-tailwind-css-color-generator</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-02-21-tailwind-css-color-generator#2026-02-21-tailwind-css-color-generator</guid>
            <pubDate>Sat, 21 Feb 2026 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a tool that'll help you generate sick color palettes as well as the CSS variables for your tailwind v4 config!

[Check it out](https://uicolors.app/generate/6af8fc)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modern CSS]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-02-18-modern-css#2026-02-18-modern-css</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-02-18-modern-css#2026-02-18-modern-css</guid>
            <pubDate>Wed, 18 Feb 2026 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [modern-css.com](https://modern-css.com); it's a website meant to show us how to STOP writing CSS like it's 2015!
No more hacks; we have useful CSS properties we can apply now. Here's a freebie for you 😆:

```css {2-3}
/* babe, babe, it's so easy to center stuff now! */
display: grid;
place-items: center;
/* no more nasty transforms */
```

[Check it out](https://modern-css.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Bits]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-02-13-react-bits#2026-02-13-react-bits</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-02-13-react-bits#2026-02-13-react-bits</guid>
            <pubDate>Fri, 13 Feb 2026 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a nifty new way to add some nice creativity and slick animations/experiences to your react app. React Bits ain't
just another component library; it's for cool stuff like descrambling text or blob cursors!

[Check it out](https://reactbits.dev/get-started/introduction)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS Box Shadow List]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2026-01-28-css-box-shadow-list#2026-01-28-css-box-shadow-list</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2026-01-28-css-box-shadow-list#2026-01-28-css-box-shadow-list</guid>
            <pubDate>Wed, 28 Jan 2026 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a cool place to check out example box-shadows that you can totally use in your own apps!

[Check it out](https://getcssscan.com/css-box-shadow-examples)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[emoji favicon]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-12-15-emoji-favicon#2025-12-15-emoji-favicon</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-12-15-emoji-favicon#2025-12-15-emoji-favicon</guid>
            <pubDate>Mon, 15 Dec 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `favicon farm`; it lets you get cool little emojis for your favicons.

[Check it out](https://fav.farm/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[light-dark]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-11-19-light-dark#2025-11-19-light-dark</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-11-19-light-dark#2025-11-19-light-dark</guid>
            <pubDate>Wed, 19 Nov 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the `light-dark` function in CSS! It allows us to set two color values for a property, returning one based on if the developer has set
a light or dark color scheme or the user has requested a light or dark color scheme. 🤩

```css
:root {
	color-scheme: light dark;
}

body {
	color: light-dark(#333b3c, #efefec);
	background-color: light-dark(#efedea, #223a2c);
}
```

[Check it out](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/light-dark)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OKLCH color model]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-11-13-oklch-color-model#2025-11-13-oklch-color-model</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-11-13-oklch-color-model#2025-11-13-oklch-color-model</guid>
            <pubDate>Thu, 13 Nov 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the OKLCH colour model! It's designed to be perceptually uniform meaning that we get colours that are more accurate
in how humans perceive them! Honestly, just check out the below link to get a better understanding but be forewarned, you might end
up going down a truly deep rabbit hole 🐇.

[Check it out](https://oklch.fyi/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[shadcn registries]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-11-06-shadcn-registries#2025-11-06-shadcn-registries</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-11-06-shadcn-registries#2025-11-06-shadcn-registries</guid>
            <pubDate>Thu, 06 Nov 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that shadcn has public registries! This means folks can create and share their components via
the shadcn cli so that we all can benefit from their awesome work!

[Check it out](https://ui.shadcn.com/docs/directory)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[output tag]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-10-29-output-tag#2025-10-29-output-tag</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-10-29-output-tag#2025-10-29-output-tag</guid>
            <pubDate>Wed, 29 Oct 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the `output` tag! The `<output>` element represents the result of a calculation performed by the application, or the result of a user action.

```html
<form id="example-form">
	<input type="range" id="b" name="b" value="50" />
	+
	<input type="number" id="a" name="a" value="10" />
	=
	<output name="result" for="a b">60</output>
</form>

<script>
	const form = document.getElementById('example-form')
	const a = form.elements['a']
	const b = form.elements['b']
	const result = form.elements['result']

	function updateResult() {
		const aValue = a.valueAsNumber
		const bValue = b.valueAsNumber
		result.value = aValue + bValue
	}

	form.addEventListener('input', updateResult)

	updateResult()
</script>
```

[Check it out](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/output)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ArkRegex]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-10-28-ark-regex#2025-10-28-ark-regex</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-10-28-ark-regex#2025-10-28-ark-regex</guid>
            <pubDate>Tue, 28 Oct 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Babe, babe, `ArkRegex` just droppped 🎉!

It improves the ergonomics of regexes by providing a type-safe API for building regexes.

```js
import { regex } from 'arkregex'

const ok = regex('^ok$', 'i')
// Regex<"ok" | "oK" | "Ok" | "OK", { flags: "i" }>

const semver = regex('^(\\d*)\\.(\\d*)\\.(\\d*)$')
// Regex<`${bigint}.${bigint}.${bigint}`, { captures: [`${bigint}`, `${bigint}`, `${bigint}`] }>

const email = regex('^(?<name>\\w+)@(?<domain>\\w+\\.\\w+)$')
// Regex<`${string}@${string}.${string}`, { names: { name: string; domain: `${string}.${string}`; }; ...>
```

[Check it out](https://arktype.io/docs/blog/arkregex)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[passkeys]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-10-27-passkeys#2025-10-27-passkeys</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-10-27-passkeys#2025-10-27-passkeys</guid>
            <pubDate>Mon, 27 Oct 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
You know how people say _don't_ roll your own auth? Well, maybe, now with passkeys,
you could roll your own auth and stop paying for things like Auth0, Okta, etc.

That's not me saying that, that's Kyle Simpson 😅.

https://www.youtube.com/watch?v=GVH8X_QOlKg
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[will-change]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-10-22-will-change#2025-10-22-will-change</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-10-22-will-change#2025-10-22-will-change</guid>
            <pubDate>Wed, 22 Oct 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `will-change` in CSS. It's a way to hint to browsers that certain CSS properties of an element
are likely to change. It's mostly used for animations, but it can be used for other things too.

It should be noted that it should be used `sparingly` but if you're ever coming across a janky animation,
remember that you should be animating transforms and opacities and maybe throw in a `will-change` for good measure.
Maybe even consider removing `will-change` after animations complete, since leaving it on can waste memory.

https://youtu.be/zwaanTsSH2M
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[scroll margin top]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-10-04-scroll-margin-top#2025-10-04-scroll-margin-top</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-10-04-scroll-margin-top#2025-10-04-scroll-margin-top</guid>
            <pubDate>Sat, 04 Oct 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that you can use `scroll-margin` to define outsets for the defined scroll area. It's very much
like `margin` but it only applies it whenever there is a scroll to mechanism.

```css
.scroll-margin-top {
	scroll-margin-top: 100px;
}
```

[Check it out](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fetch Credentials]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-10-01-fetch-credentials#2025-10-01-fetch-credentials</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-10-01-fetch-credentials#2025-10-01-fetch-credentials</guid>
            <pubDate>Wed, 01 Oct 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that within the cotenxt of the `Fetch API`, you can use the `credentials` property
to specify whether or not the request should extra data long with the request that the
server can use to authenticate the user.

```jsx
// always include credentials, even cross-origin.
fetch('https://jsonplaceholder.typicode.com/todos/1', {
	credentials: 'include',
})

// never send credentials in the request or include credentials in the response.
fetch('https://jsonplaceholder.typicode.com/todos/1', {
	credentials: 'omit',
})

// (the default): only send and include credentials for same-origin requests.
fetch('https://jsonplaceholder.typicode.com/todos/1', {
	credentials: 'same-origin',
})
```

[Check it out](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[google stitch]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-09-28-google-stitch#2025-09-28-google-stitch</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-09-28-google-stitch#2025-09-28-google-stitch</guid>
            <pubDate>Sun, 28 Sep 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about Stitch, an AI-powered tool that helps application developers (like me 😎) build pretty high-quality UIs
that we can then export to Figma.

I'm using it right now to help me build out a UI for a course platform for [our jiu-jitsu school](https://grapplecity.ca).

[Check it out](https://stitch.withgoogle.com)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[:user-valid and :user-invalid]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-09-17-user-valid-and-user-invalid#2025-09-17-user-valid-and-user-invalid</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-09-17-user-valid-and-user-invalid#2025-09-17-user-valid-and-user-invalid</guid>
            <pubDate>Wed, 17 Sep 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
import { ValidationDemo } from './validation-demo'

TIL about `:user-valid` and `:user-invalid` pseudo-class selectors! They function
similarly to `:valid` and `:invalid` but `:user-valid` and `:user-invalid` are only
applied only after a user has significantly interacted with the input.

In the example below, you'll notice that the first two inputs will not have
any border styling applied until the user has interacted with the input. Conversely,
the last two inputs will have border styling applied immediately 🫢.

<ValidationDemo />

[Check it out](https://web.dev/articles/user-valid-and-user-invalid-pseudo-classes)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[css nth tester]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-09-12-css-nth-tester#2025-09-12-css-nth-tester</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-09-12-css-nth-tester#2025-09-12-css-nth-tester</guid>
            <pubDate>Fri, 12 Sep 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about this neat little tool that lets you test your CSS nth-child and nth-of-type selectors.

[Check it out](https://css-tricks.com/examples/nth-child-tester/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Beacon API]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-08-31-beacon-api#2025-08-31-beacon-api</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-08-31-beacon-api#2025-08-31-beacon-api</guid>
            <pubDate>Sun, 31 Aug 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the `Beacon` API! It's a way to send asynchronous and non-blocking requests to a web server.

It's useful for sending analytics data to a server before the page is unloaded!

```jsx
document.addEventListener('visibilitychange', () => {
	if (document.visibilityState === 'hidden') {
		navigator.sendBeacon('/log', analyticsData)
	}
})
```

[Check it out](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ebooks to audiobooks]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-08-27-ebooks-to-audiobooks#2025-08-27-ebooks-to-audiobooks</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-08-27-ebooks-to-audiobooks#2025-08-27-ebooks-to-audiobooks</guid>
            <pubDate>Wed, 27 Aug 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that you can convert ebooks to audiobooks with `audiblez` 📚!

[Check it out](https://github.com/santinic/audiblez)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[dyad]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-08-14-dyad#2025-08-14-dyad</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-08-14-dyad#2025-08-14-dyad</guid>
            <pubDate>Thu, 14 Aug 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `dyad`, a free and open source alternative to things like V0, Lovable, and Bolt. If you
don't know what these tools are, they're basically AI powered web app builders that allow people to
create apps with natural language.

[Check it out](https://www.dyad.sh/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[es-toolkit]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-08-04-es-toolkit#2025-08-04-es-toolkit</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-08-04-es-toolkit#2025-08-04-es-toolkit</guid>
            <pubDate>Mon, 04 Aug 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `es-toolkit`, a modern alternative to `lodash` and `underscore`.

It promises improved performance (potentially 2-3 times faster),
smaller bundle size (~97% less than lodash), and even offers a comptability layer to ease the transition for
existing codebases from `lodash` to `es-toolkit`.

```ts
import { chunk } from 'es-toolkit/array'

// Splits an array of numbers into sub-arrays of length 2
chunk([1, 2, 3, 4, 5], 2)
// Returns: [[1, 2], [3, 4], [5]]

// Splits an array of strings into sub-arrays of length 3
chunk(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3)
// Returns: [['a', 'b', 'c'], ['d', 'e', 'f'], ['g']]
```

[Check it out](https://es-toolkit.dev/intro.html)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[tldr]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-07-28-tldr#2025-07-28-tldr</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-07-28-tldr#2025-07-28-tldr</guid>
            <pubDate>Mon, 28 Jul 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `tldr`; a community driven endeavour that compliments the traditional `man` pages!

```bash
~/blog main !1 ?1 > tldr clear                                                                                                                                                          11:35:28
warning: 1 page(s) found for other platforms:
1. windows (tldr --platform windows clear)

  clear

  Clears the screen of the terminal.
  More information: https://manned.org/clear.

  Clear the screen:

    clear

  Clear the screen but keep the terminal's scrollback buffer (equivalent to pressing <Ctrl l> in Bash):

    clear -x

  Indicate the type of terminal to clean (defaults to the value of the environment variable TERM):

    clear -T type_of_terminal

  Display the version of ncurses used by clear:

    clear -V

```

[Check it out](https://github.com/tldr-pages/tldr)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ai Resume Matcher]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-07-23-ai-resume-matcher#2025-07-23-ai-resume-matcher</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-07-23-ai-resume-matcher#2025-07-23-ai-resume-matcher</guid>
            <pubDate>Wed, 23 Jul 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [Resume Matcher](https://resumematcher.fyi/), a full stack web app, that you have to run locally,
that will reveal your resumes compatibility score and crucial keywords 😎.

It's still in active development, and to be honest, I had to do a little finagling to get it to work locally,
but I'm really excited to see how it evolves. With the resumes I've used and job descriptions I've uploaded,
I think the original scores that I got were pretty good but the updates the app suggested, like adding numerical
data and percentages, definitely would have improved the overall appeal of my resume.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[open source secrets management]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-29-open-source-secrets-management#2025-05-29-open-source-secrets-management</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-29-open-source-secrets-management#2025-05-29-open-source-secrets-management</guid>
            <pubDate>Thu, 29 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [infisical](https://infisical.com/), an open source secrets management platform.

It allows you to easily store and manage your secrets across your team and tech stack. And oh,
did I mention that you can self-host it too? 😎

[Check it out](https://infisical.com/docs/documentation/getting-started/introduction)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[clipboard.js]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-28-clipboard-js#2025-05-28-clipboard-js</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-28-clipboard-js#2025-05-28-clipboard-js</guid>
            <pubDate>Wed, 28 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [clipboard.js](https://clipboardjs.com/), a library that allows you to copy text to the clipboard.

It's pretty simple to use, it's also pretty lightweight, and it's declarative af.

```html
<!-- Target -->
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git" />

<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo">
	<img src="assets/clippy.svg" alt="Copy to clipboard" />
</button>
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[supabase]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-19-supabase#2025-05-19-supabase</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-19-supabase#2025-05-19-supabase</guid>
            <pubDate>Mon, 19 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Today I learned about Supabase, an open source alternative to Firebase.
It being open source also means I can self-host it, which I love ❤️.

But anyways, I played around with it this weekend in an attempt to build out a proof of concept
for a course platform I want to build out for my Brazilian Jujutsu business, and I have to say I'm quite impressed 🤯.

[Check it out](https://supabase.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[So. Much. Raycast]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-09-so-much-raycast#2025-05-09-so-much-raycast</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-09-so-much-raycast#2025-05-09-so-much-raycast</guid>
            <pubDate>Fri, 09 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Okay, I know what you're thinking. Another today I learned about Raycast 😅.
But hear me out, this YouTube video that I'm about to link you to is bonkers.
Like I said before, this is the tool that our Macs should have shipped with because
finder just can't compare!

There are over a hundred cool things you can do with Raycast... and I've just scratched the surface because, oof,
there's so much cool stuff and so little time 😂.

https://youtu.be/NuIpZoQwuVY
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[threadreader]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-07-threadreader#2025-05-07-threadreader</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-07-threadreader#2025-05-07-threadreader</guid>
            <pubDate>Wed, 07 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `Threadreader`, a tool that helps you read Twitter threads _way_ more easily. Oh sorry,
it's not Twitter anymore, it's X. Whatever, Elon.

Whatever the hell it's called now, `Threadreader` will unroll the tweet storm into a single,
cohesive, consumable chunk of content.

[Check it out](https://threadreaderapp.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ts-reset]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-05-ts-reset#2025-05-05-ts-reset</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-05-ts-reset#2025-05-05-ts-reset</guid>
            <pubDate>Mon, 05 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `ts-reset` - it's like CSS resets but for TypeScript! Shout out to Matt Pocock (and the team) for this!

Here's an example of one of the rules:

```tsx
import '@total-typescript/ts-reset/array-includes'

const users = ['matt', 'sofia', 'waqas'] as const

// .includes now takes a string as the first parameter
// BEFORE, it would have complained about the type of the first parameter
users.includes('bryan')
```

There are way more rules so I encourage you to give it a read and maybe incorporate it into your project!

[Check it out](https://www.totaltypescript.com/ts-reset)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Show your react router routes]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-05-show-your-react-router-routes#2025-05-05-show-your-react-router-routes</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-05-show-your-react-router-routes#2025-05-05-show-your-react-router-routes</guid>
            <pubDate>Mon, 05 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that you can utilize `npx react-router routes` to see all the routes in your app!

For my site, here's what I get:

```jsx:title=taranveerbains.ca
<Routes>
  <Route file="root.tsx">
    <Route path="newsletter/rss.xml" file="routes/_extras.newsletter.rss[.xml].tsx" />
    <Route path="action/old-refresh-cache" file="routes/action.old-refresh-cache.tsx" />
    <Route path="blog/rss.xml" file="routes/_extras.blog.rss[.xml].tsx" />
    <Route path="til/rss.xml" file="routes/_extras.til.rss[.xml].tsx" />
    <Route path="action/theme-switcher" file="routes/action.theme-switcher.tsx" />
    <Route path="action/refresh-cache" file="routes/action.refresh-cache.tsx" />
    <Route path="action/newsletter" file="routes/action.newsletter.tsx" />
    <Route path="blog" index file="routes/blog._index/route.tsx" />
    <Route path="tags" index file="routes/tags._index.tsx" />
    <Route path="blog/:slug" file="routes/blog.$slug/route.tsx" />
    <Route path="tags/:slug" file="routes/tags.$slug.tsx" />
    <Route path="inngest" file="routes/inngest.ts" />
    <Route index file="routes/_index.tsx" />
    <Route path="health" file="routes/health.tsx" />
    <Route path=":page" file="routes/$page.tsx" />
    <Route path="about" file="routes/about/route.tsx" />
    <Route path="til" file="routes/til/route.tsx" />
    <Route path="*" file="routes/$.tsx" />
  </Route>
</Routes>
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[headless ui]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-05-02-headless-ui#2025-05-02-headless-ui</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-05-02-headless-ui#2025-05-02-headless-ui</guid>
            <pubDate>Fri, 02 May 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about headless ui - a library from `tailwindlabs` that gives you access to
unstyled ui components that integrate beautifully with `tailwind`. If you're wondering how I found out
about this, [Wapplyzer](https://www.wappalyzer.com/) revelead it to me 😆!

[Check it out](https://headlessui.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[c15t (consent management)]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-04-25-c15t-consent-management#2025-04-25-c15t-consent-management</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-04-25-c15t-consent-management#2025-04-25-c15t-consent-management</guid>
            <pubDate>Fri, 25 Apr 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about c15t, a new consent management framework with some awesome React support! You can even self-host it (which is a major win for nerds like me)

[Check it out](https://c15t.com/docs/storing-consent/overview)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RBAC in JS]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-04-22-rbac-in-js#2025-04-22-rbac-in-js</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-04-22-rbac-in-js#2025-04-22-rbac-in-js</guid>
            <pubDate>Tue, 22 Apr 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a role based access control (RBAC) library in JavaScript. [`CASL`](https://casl.js.org/v6/en/guide/intro)
is a library that allows us to declaratively restrict access to resources based on roles and permissions.

```jsx
import { createContext } from 'react'
import { createContextualCan } from '@casl/react'

export const AbilityContext = createContext()
export const Can = createContextualCan(AbilityContext.Consumer)

export default () => {
	const createTodo = () => {
		/* logic to show new todo form */
	}
	const ability = useContext(AbilityContext)

	return (
		<div>
			{ability.can('create', 'Todo') && (
				<button onClick={createTodo}>Create Todo</button>
			)}
		</div>
	)
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[easy stacking in css]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-04-07-easy-stacking-in-css#2025-04-07-easy-stacking-in-css</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-04-07-easy-stacking-in-css#2025-04-07-easy-stacking-in-css</guid>
            <pubDate>Mon, 07 Apr 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
import CardStack from './stacking-example.jsx'

TIL, it's pretty easy to stack elements in CSS, without having to use positioning! It's a litle bit more verbose to do it in tailwind, but it's the same idea.

```css

.parent {
  display: grid;
}

.child {
  grid-area 1 / 1
}

```

<CardStack />
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[rss feed generator]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-24-rss-feed-generator#2025-03-24-rss-feed-generator</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-24-rss-feed-generator#2025-03-24-rss-feed-generator</guid>
            <pubDate>Mon, 24 Mar 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `feed`, an npm package that allows you to quickly generate an RSS feed for your website!

I used it to generate an RSS feed for my blog and my TIL feeds! It's pretty simple and super easy to plug into your existing project.

[Check it out](https://www.npmx.dev/package/feed)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[coolors.co]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-22-coolors-co#2025-03-22-coolors-co</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-22-coolors-co#2025-03-22-coolors-co</guid>
            <pubDate>Sat, 22 Mar 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `coolors.co` — a superfast color palette generator. If you're anything like me,
you'll probably use it whenever you need to generate a color palette for your side projects, you know,
those side projects that you're totally working on and not abandoning for a while.

[Check it out](https://coolors.co/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Optional chaining]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-21-optional-chaining#2025-03-21-optional-chaining</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-21-optional-chaining#2025-03-21-optional-chaining</guid>
            <pubDate>Fri, 21 Mar 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I learned this hard lesson today. _Optional chaining is for uncertain values — not uncertain existence._

If I'm not sure if a global object exists, I can't rely on optional chaining to access it. I have to check for existence first.

```js
// 👇 this is a valid expression in node
// we check to see if window exists
if (typeof window !== 'undefined') {
	window.localStorage.setItem('key', 'value')
}

// 👇 this is not a valid expression in node
// window is undefined (its existence is uncertain)
window?.localStorage.setItem('key', 'value')
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Node Modules Inspector]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-14-node-modules-inspector#2025-03-14-node-modules-inspector</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-14-node-modules-inspector#2025-03-14-node-modules-inspector</guid>
            <pubDate>Fri, 14 Mar 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the `node-modules-inspector` -- a package that allows you to visualize your node_modules folder,
inspect your dependencies, and so much more 🤯! I'm a big fan of the visualizations, since I'm more of a
visual kinda person. You can use it in your own project with this simple command: `npx node-modules-inspector`.

[Check it out](https://github.com/antfu/node-modules-inspector)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Typescript Ported To Go]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-13-typescript-ported-to-go#2025-03-13-typescript-ported-to-go</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-13-typescript-ported-to-go#2025-03-13-typescript-ported-to-go</guid>
            <pubDate>Thu, 13 Mar 2025 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TypeScript's compiler is being reimagined.
Currently at version 5.8, TypeScript is still written in TypeScript itself,
but there are plans to port it to Go for version 7.

This change promises to improve compilation times—by up to 10 times faster! True, the speed boost
is something we probably won't see for a few months or years, but I'm super excited to see `Go`
get some much needed love and attention, since you know, it's my secondary language of choice.

https://www.youtube.com/watch?v=PQ2WjtaPfXU
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Better Sleep]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-07-better-sleep#2025-03-07-better-sleep</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-07-better-sleep#2025-03-07-better-sleep</guid>
            <pubDate>Fri, 07 Mar 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `Magnesium Glycinate`, a supplement that helps promote better sleep! I've been having a tough time
falling asleep lately, especially after a tough Brazilian Jiu Jitsu practice, or an intense workout. One of my
friends recommended `Magnesium Glycinate` as a way to help me sleep better. Let's see how it works... I just ordered
some today 😆!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fontsource]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-05-fontsource#2025-03-05-fontsource</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-05-fontsource#2025-03-05-fontsource</guid>
            <pubDate>Wed, 05 Mar 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `Fontsource`, a free Vercel resource that provides you with information on how to easily
install and `self-host` web fonts. They support all Google Fonts, as well as open source ones!

[Check it out](https://fontsource.org/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tanstack Form]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-04-tanstack-form#2025-03-04-tanstack-form</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-04-tanstack-form#2025-03-04-tanstack-form</guid>
            <pubDate>Tue, 04 Mar 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL: Tanner Linsley, the creator of TanStack Query, Router, and Start, just dropped TanStack Form!

True to form, _it’s framework-agnostic, headless, and has zero dependencies_. It also handles deeply nested objects out of the box, making it a powerful alternative to traditional form libraries.

[Check it out](https://tanstack.com/form/latest)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[System Font Stack]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-03-03-system-font-stack#2025-03-03-system-font-stack</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-03-03-system-font-stack#2025-03-03-system-font-stack</guid>
            <pubDate>Mon, 03 Mar 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a growing movement on the web where people are choosing to use system fonts instead of loading custom fonts.
Over the years, the default system fonts included with operating systems have become quite robust and visually appealing.
If you’re concerned about performance or don’t require a fancy web font, this could be a great solution for you.

[Check it out](https://systemfontstack.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Data attribute state management]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-19-data-attribute-state-management#2025-02-19-data-attribute-state-management</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-19-data-attribute-state-management#2025-02-19-data-attribute-state-management</guid>
            <pubDate>Wed, 19 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
This one's pretty sweet and I've been reaching for it a lot lately at work!
Rather than having multiple `className` conditions, you can use a
`data-attribute` to manage your state.

This is not only a _great_ way to keep your component clean but also allows you
to target any state pertinent to your component without JavaScript! Mind you,
I'm assuming you're using something like `Tailwind` for your styling.

```tsx
// no reliance on utility functions like `twMerge`
<div
	data-state-can-scroll={canScroll}
	className="data-[state-can-scroll=false]:hidden"
>
	Hidden when canScroll is false!
</div>
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[web extension framework]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-16-web-extension-framework#2025-02-16-web-extension-framework</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-16-web-extension-framework#2025-02-16-web-extension-framework</guid>
            <pubDate>Sun, 16 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [wxt](https://github.com/wxt-dev/wxt)! It's like Nuxt but for web
extensions.

[Check it out](https://github.com/wxt-dev/wxt?tab=readme-ov-file#demo)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[sqoosh]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-14-sqoosh#2025-02-14-sqoosh</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-14-sqoosh#2025-02-14-sqoosh</guid>
            <pubDate>Fri, 14 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a local first tool for image compression called `sqoosh`. No more
sending images to random servers just to compress them! 😆.

[Check it out](https://squoosh.app/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[bolt.new]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-09-bolt-new#2025-02-09-bolt-new</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-09-bolt-new#2025-02-09-bolt-new</guid>
            <pubDate>Sun, 09 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `bolt.new`, an AI-powered web agent that lets you deploy apps via
Stackblitz. It's a pretty sick way to throw up a demo of a new app to illustrate
a concept.

[Check it out](https://bolt.new/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS tidbits]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-08-css-tidbits#2025-02-08-css-tidbits</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-08-css-tidbits#2025-02-08-css-tidbits</guid>
            <pubDate>Sat, 08 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the following...

```css:title=inset-property.css
    /* top, left, right, button, are all set to to the same value */
    .box {
      inset: 0;
    }
```

1. The `inset` property is a shorthand for `top`, `right`, `bottom`, and `left`
   properties.
2. Absolute elements can only be contained by other elements using Positioned
   layout.
3. Positioned elements will always render on top of non-positioned ones
4. [Stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context)
   is the stacking order of elements that are positioned.
   - We can create a stacking context by combining a non-static position with a
     z-index. So position `absolute` and `z-index` will create a stacking
     context.
   - We can also create one by setting opacity to less than 1.
   - Check out the link above for more info.
5. The `isolation` property allows you to create a stacking context. We can add
   this to a parent element and then we can forget about having to add a
   `position: relative` and `z-index` to the children. It is the lightest weight
   way to create a stacking context.
6. The `z-index` property can be used in a flexbox the same way as it can be
   used with a positioned element.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS stacking context inspector]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-08-css-stacking-context-inspector#2025-02-08-css-stacking-context-inspector</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-08-css-stacking-context-inspector#2025-02-08-css-stacking-context-inspector</guid>
            <pubDate>Sat, 08 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the stacking context inspector. It's a tool that allows you to inspect
the stacking context of an element.

[Check it out](https://github.com/andreadev-it/stacking-contexts-inspector)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Leave.Comments.]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-02-05-leave-comments#2025-02-05-leave-comments</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-02-05-leave-comments#2025-02-05-leave-comments</guid>
            <pubDate>Wed, 05 Feb 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
More of a public service announcement and a reminder to myself (especially for
my personal projects), to leave comments on any funky things you're doing in
code. I wasted an hour battling a bug in my blog because I didn't leave a
comment regarding a `@ts-ignore` directive.

Leave. Comments. Please.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[reach.tech]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-01-30-reach-tech#2025-01-30-reach-tech</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-01-30-reach-tech#2025-01-30-reach-tech</guid>
            <pubDate>Thu, 30 Jan 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Kent showed me a great way to have a stable id for my react components, between
server and client renders.

Ideally, you would be reaching for `useId` from `react` but if you're using an
older version of react, like `17` or `16`, then you can use `auto-id` from
`reach.tech` instead.

[Check it out](https://reach.tech/auto-id/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[zoxide]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-01-29-zoxide#2025-01-29-zoxide</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-01-29-zoxide#2025-01-29-zoxide</guid>
            <pubDate>Wed, 29 Jan 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Til about `zoxide` which is a faster and more robust `cd` alternative; it lets
you navigate your filesystem faster and more reliably.

```bash:title=zoxide-examples
 z ~/Documents/new-blog
 z ~/Documents/rehype-code-titles

# Go back to the last directory (new-blog)
z -

# Go to the `new-blog` directory
z rehype-code-titles

# Go back to your home directory
z

# open a fzf menu of possible entries that begin with `re`
zi re<SPACE><TAB>
```

[Check it out](https://github.com/ajeetdsouza/zoxide)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Standard Schema]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-01-27-standard-schema#2025-01-27-standard-schema</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-01-27-standard-schema#2025-01-27-standard-schema</guid>
            <pubDate>Mon, 27 Jan 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the [Standard Schema](https://standardschema.dev/)! It's an effort to
standardize the interface of TypeScript validation libraries.

To pull directly from the docs, The goal is to make it easier for ecosystem
tools to accept user-defined type validators, without needing to write custom
logic or adapters for each supported library.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[editing the whole document]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-01-14-editing-the-whole-document#2025-01-14-editing-the-whole-document</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-01-14-editing-the-whole-document#2025-01-14-editing-the-whole-document</guid>
            <pubDate>Tue, 14 Jan 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
import { DesignModeToggle } from './design-mode-button'

TIL that you can edit the whole document with `document.designMode = 'on'`!

<DesignModeToggle />

[Check it out](https://developer.mozilla.org/en-US/docs/Web/API/Document/designMode)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[happiness one liner]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2025-01-08-happiness-one-liner#2025-01-08-happiness-one-liner</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2025-01-08-happiness-one-liner#2025-01-08-happiness-one-liner</guid>
            <pubDate>Wed, 08 Jan 2025 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
<BlockQuote author="unknown">Happiness = results - expectations</BlockQuote>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[array with method]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-12-08-array-prototype-with#2024-12-08-array-prototype-with</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-12-08-array-prototype-with#2024-12-08-array-prototype-with</guid>
            <pubDate>Sun, 08 Dec 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Today I learned about the `with` method on the `Array.prototype` object. This
method is used to create a shallow copy of an array but with one element
replaced at a given index.

```js
const arr = [1, 2, 3]
const newArr = arr.with(0, 5)

console.log(arr) // [1, 2, 3]
console.log(newArr) // [5, 2, 3]
```

This is useful when you want to replace elements in an array without mutating
the original array.

[Check it out](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/with)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[docsify]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-12-07-docsify#2024-12-07-docsify</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-12-07-docsify#2024-12-07-docsify</guid>
            <pubDate>Sat, 07 Dec 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So it's even easier now to add a documentation website to your project! While
looking over the `Zod` github repo, I saw that they were using `docsify` to
house their documentation. It's pretty slick and I intend to use it for my own
projects... well at least the work ones 😆.

[Check it out](https://docsify.js.org/#/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react-error-boundary]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-12-04-react-error-boundary#2024-12-04-react-error-boundary</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-12-04-react-error-boundary#2024-12-04-react-error-boundary</guid>
            <pubDate>Wed, 04 Dec 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you're not using a meta framework like Next.js or Remix, I'd high suggest you
check out
[react-error-boundary](https://github.com/bvaughn/react-error-boundary).

Seriously, Taran, use this at work.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TS satisfies without satsify]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-12-03-ts-satisfies-without-satsify#2024-12-03-ts-satisfies-without-satsify</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-12-03-ts-satisfies-without-satsify#2024-12-03-ts-satisfies-without-satsify</guid>
            <pubDate>Tue, 03 Dec 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about how one can use `satisfies` in typescript, without `satisfy` at all!

```typescript
// taken right from Kent's blog
type OperationFn = (left: number, right: number) => number

// this is a restriction on the operations object
// but with satisfies, I leave myself room to add more operations and don't need to manage another type
const operations = {
	'+': (left, right) => left + right,
	'-': (left, right) => left - right,
	'*': (left, right) => left * right,
	'/': (left, right) => left / right,
} satisfies Record<string, OperationFn>
```

[Check it out](https://kentcdodds.com/blog/how-to-write-a-constrained-identity-function-in-typescript)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[arethetypeswrong]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-11-13-arethetypeswrong#2024-11-13-arethetypeswrong</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-11-13-arethetypeswrong#2024-11-13-arethetypeswrong</guid>
            <pubDate>Wed, 13 Nov 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL there's a tool that can help you find out if your types are wrong for your
library!

[Check it out](https://www.npmx.dev/package/@arethetypeswrong/cli)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[raycast]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-11-07-raycast#2024-11-07-raycast</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-11-07-raycast#2024-11-07-raycast</guid>
            <pubDate>Thu, 07 Nov 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Til about raycast! The productivity tool that our macs should have shipped with
❤️

[Check it out](https://www.raycast.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[choose your license]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-11-06-choose-your-license#2024-11-06-choose-your-license</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-11-06-choose-your-license#2024-11-06-choose-your-license</guid>
            <pubDate>Wed, 06 Nov 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Struggling to choose the right license for your project? There's a great tool
for that!

[Check it out](https://choosealicense.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[wave app]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-10-22-wave-app#2024-10-22-wave-app</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-10-22-wave-app#2024-10-22-wave-app</guid>
            <pubDate>Tue, 22 Oct 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about wave app! I'm using it to track my expenses and the invoices for my
company! It's pretty cool.

[Check it out](https://www.waveapps.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Better node objects logging!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-10-11-better-node-objects-logging#2024-10-11-better-node-objects-logging</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-10-11-better-node-objects-logging#2024-10-11-better-node-objects-logging</guid>
            <pubDate>Fri, 11 Oct 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Sick of seeing truncated `Objects` in Node? I got you bro (well Matt Pocock has
got you).

```js
let deepNesting = {
	level1: {
		level2: {
			level3: {
				level4: {
					level5: {
						name: 'Moderately Nested Object',
						value: 42,
						attributes: {
							created: '2023-10-01',
							modified: '2023-10-15',
							tags: ['demo', 'test', 'nested'],
							metadata: {
								author: 'Jane Doe',
								version: '1.0',
								license: 'MIT',
							},
						},
						items: [
							{
								id: 1,
								description: 'First item',
								status: 'active',
							},
							{
								id: 2,
								description: 'Second item',
								status: 'inactive',
							},
						],
					},
				},
			},
		},
	},
}

// logs: { level1: { level2: { level3: [Object] } } }
console.log(deepNesting)

// You get the whole object!
console.dir(deepNesting, { depth: Infinity })
```

Matt is the man!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[bulletproof react]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-10-03-bulletproof-react#2024-10-03-bulletproof-react</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-10-03-bulletproof-react#2024-10-03-bulletproof-react</guid>
            <pubDate>Thu, 03 Oct 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL there's a useful github repo for
[bulletproof react](https://github.com/alan2207/bulletproof-react)!

It gives you a bunch of useufl tips and explanantions on how to make your react
code bulletproof.

[Check it out](https://github.com/alan2207/bulletproof-react)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[colored console log]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-10-02-colored-console-log#2024-10-02-colored-console-log</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-10-02-colored-console-log#2024-10-02-colored-console-log</guid>
            <pubDate>Wed, 02 Oct 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that you can use `console.log` with color!

```js
console.log(
	'This is %cMy stylish message',
	'color: yellow; font-style: italic; background-color: blue;padding: 2px',
)
```

[Check it out](https://developer.mozilla.org/en-US/docs/Web/API/console)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[changesets]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-09-25-changesets#2024-09-25-changesets</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-09-25-changesets#2024-09-25-changesets</guid>
            <pubDate>Wed, 25 Sep 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Need a tool to help you manage your versioning and changelogs? Check out
[changesets](https://github.com/changesets/changesets)!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Multiple Neovim Configs]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-09-22-multiple-neovim-configs#2024-09-22-multiple-neovim-configs</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-09-22-multiple-neovim-configs#2024-09-22-multiple-neovim-configs</guid>
            <pubDate>Sun, 22 Sep 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Today I learned how to create multiple Neovim Configs. I've set up a home and
work config respectively.

https://www.youtube.com/watch?v=LkHjJlSgKZY
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[git recent]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-09-11-git-recent#2024-09-11-git-recent</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-09-11-git-recent#2024-09-11-git-recent</guid>
            <pubDate>Wed, 11 Sep 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `git recent` by Paul Irish. It's a command that shows you your latest
local git branches! Super useful when you're at work and got a lot of stuff on
the go.

```bash
 git recent

# example output
:'
* main                         7167899 (19 hours ago) Taranveer Bains
                               new til

  feature/partytown            548eaf3 (2 days ago) Taranveer Bains
                               chore(dev-server): update dev script
'
```

[Check it out](https://github.com/paulirish/git-recent)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[interpolation]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-09-10-interpolation#2024-09-10-interpolation</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-09-10-interpolation#2024-09-10-interpolation</guid>
            <pubDate>Tue, 10 Sep 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Interpolation is defined as "the insertion of something of a different nature
into something else."
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[orbstack]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-09-09-orbstack#2024-09-09-orbstack</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-09-09-orbstack#2024-09-09-orbstack</guid>
            <pubDate>Mon, 09 Sep 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [orbstack](https://docs.orbstack.dev/) -- a fast and lightweight way
to run containers on a Mac!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[css-color-filter-generator]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-08-27-css-color-filter-generator#2024-08-27-css-color-filter-generator</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-08-27-css-color-filter-generator#2024-08-27-css-color-filter-generator</guid>
            <pubDate>Tue, 27 Aug 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there's a tool to help you apply color filters to your dom nodes!

[Check it out](https://angel-rs.github.io/css-color-filter-generator/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Storybook ArgeTypes]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-08-26-storybook-arge-types#2024-08-26-storybook-arge-types</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-08-26-storybook-arge-types#2024-08-26-storybook-arge-types</guid>
            <pubDate>Mon, 26 Aug 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that Storybook has a way to specify the behavior of `args` -- `ArgeTypes`.
This is a great way to constrain the values that your component can accept and
provides information about `args` that aren't explicitly set in the story.

```tsx title="preview.ts"
// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import type { Preview } from '@storybook/your-renderer'

const preview: Preview = {
	argTypes: {
		// 👇 All stories expect a label arg
		label: {
			control: 'text',
			description: 'Overwritten description',
		},
	},
}

export default preview
```

[Check it out](https://storybook.js.org/docs/api/arg-types)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[stay away]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-08-19-stay-away#2024-08-19-stay-away</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-08-19-stay-away#2024-08-19-stay-away</guid>
            <pubDate>Mon, 19 Aug 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
<BlockQuote author="Mark Twain">
	Keep away from people who try to belittle your ambitions. Small people always
	do that, but the really great make you feel that you, too, can become great.
</BlockQuote>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ecosystem Performance]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-08-15-ecosystem-performance#2024-08-15-ecosystem-performance</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-08-15-ecosystem-performance#2024-08-15-ecosystem-performance</guid>
            <pubDate>Thu, 15 Aug 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about e18e (Ecosystem Performance). It's an initiative to connect folks and
projects working on improving JS package performance.

[Check it out](https://e18e.dev/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[deepClone... nah, structuredClone]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-08-09-deep-clone-nah-structured-clone#2024-08-09-deep-clone-nah-structured-clone</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-08-09-deep-clone-nah-structured-clone#2024-08-09-deep-clone-nah-structured-clone</guid>
            <pubDate>Fri, 09 Aug 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that if we want to make a `deepClone` of an object in JS, there's a built in
method in most browsers: `structuredClone`!

The old one (which works but doesn't account for things like `Set` and `Map` or
even `Date`)

```js:title=the-old-and-new-way
const originalObject = {
  name: "John",
  age: 30,
  date: new Date(),
  details: {
    hobbies: ["reading", "gaming"],
    address: {
      city: "New York",
      zip: "10001",
    },
  },
};

const clonedObjectOldWay = JSON.parse(JSON.stringify(originalObject));

// what do you think happened to the date? 😏
// hint... no longer a string!
console.log(clonedObjectOldWay);

console.log(originalObject.date instanceof Date); // true
console.log(clonedObjectOldWay.date instanceof Date); // false (Date is not preserved)

```

Shout out to [Matt Pocock](https://www.totaltypescript.com/) -- the person
behind Total Typescript -- for the twitter thread that exposed me to this
function!

[Check it out](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[do what matters]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-07-31-do-what-matters#2024-07-31-do-what-matters</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-07-31-do-what-matters#2024-07-31-do-what-matters</guid>
            <pubDate>Wed, 31 Jul 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Don't forget this brother. My guy hit me hard with this; it was too damn early
in the morning for them ninjas to be chopping onions 🥲!

<BlockQuote author="Mark Techson">
	Do what matters with who matters, while it matters.
</BlockQuote>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[button form attribute]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-07-29-button-form-attribute#2024-07-29-button-form-attribute</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-07-29-button-form-attribute#2024-07-29-button-form-attribute</guid>
            <pubDate>Mon, 29 Jul 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that the `button` html element accepts a `form` attribute. This is cool
because it allows you to associate a `button` with any form, even if it's not a
direct ancestor of our button! How cool is that ❤️!

[Check it out](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#form)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[margin vs padding]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-07-13-margin-vs-padding#2024-07-13-margin-vs-padding</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-07-13-margin-vs-padding#2024-07-13-margin-vs-padding</guid>
            <pubDate>Sat, 13 Jul 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL `margin` is meant to increase the distance between **siblings**. It is not
meant to increase the gap between a child and its parent's bounding box; that's
what `padding` is for.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[css height and width tidbit]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-07-13-css-height-and-width-tidbit#2024-07-13-css-height-and-width-tidbit</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-07-13-css-height-and-width-tidbit#2024-07-13-css-height-and-width-tidbit</guid>
            <pubDate>Sat, 13 Jul 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
`width` looks up the tree but `height` looks down the tree. An element's width
is calculated based on its parent's size, but an element's height is calculated
based on its children.

Thanks Josh Comeau!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[css list of mistakes]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-07-12-css-list-of-mistakes#2024-07-12-css-list-of-mistakes</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-07-12-css-list-of-mistakes#2024-07-12-css-list-of-mistakes</guid>
            <pubDate>Fri, 12 Jul 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
😆 while going through a CSS workshop, I came across this
[list](https://wiki.csswg.org/ideas/mistakes) of CSS mistakes. Be humble folks.
We all mistakes.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[css inheritable]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-07-12-css-inheritable#2024-07-12-css-inheritable</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-07-12-css-inheritable#2024-07-12-css-inheritable</guid>
            <pubDate>Fri, 12 Jul 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
[Here's](https://www.sitepoint.com/css-inheritance-introduction/#list-css-properties-inherit)
a list (probably not complete) set of inheritable css properties.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[observables api]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-06-21-observables-api#2024-06-21-observables-api</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-06-21-observables-api#2024-06-21-observables-api</guid>
            <pubDate>Fri, 21 Jun 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL, from Dom Farolino that he's trying to make `addEventListener` extinct with
the [observables api](https://github.com/WICG/observable)!

```js
// Filtering and mapping:
element
	.on('click')
	.filter((e) => e.target.matches('.foo'))
	.map((e) => ({ x: e.clientX, y: e.clientY }))
	.subscribe({ next: handleClickAtPoint })
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react internals explorer]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-06-18-react-internals-explorer#2024-06-18-react-internals-explorer</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-06-18-react-internals-explorer#2024-06-18-react-internals-explorer</guid>
            <pubDate>Tue, 18 Jun 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Check out this dope tool for understanding the React internals!
[So dope!](https://jser.dev/2024-05-11-introducing-rie/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Anger and happiness]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-06-09-anger-and-happiness#2024-06-09-anger-and-happiness</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-06-09-anger-and-happiness#2024-06-09-anger-and-happiness</guid>
            <pubDate>Sun, 09 Jun 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
<BlockQuote author="Imam Ali Ibn Abi Talib">
	Never make a decision in anger, and never make a promise in happiness
</BlockQuote>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Better prose editing]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-05-24-betting-prose-editing#2024-05-24-betting-prose-editing</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-05-24-betting-prose-editing#2024-05-24-betting-prose-editing</guid>
            <pubDate>Fri, 24 May 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about an app that'll edit your prose for you!
[Hemingway App](https://hemingwayapp.com/) should be able to help me write with
better clarity and conciseness. I'm a wordy son of a gun.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[patch-package]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-05-08-patch-package#2024-05-08-patch-package</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-05-08-patch-package#2024-05-08-patch-package</guid>
            <pubDate>Wed, 08 May 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Got a `node_module` giving you a headache? Need to give it a band-aid? Thank
your lucky stars for
[patch-package](https://www.npmx.dev/package/patch-package).

It's a vital band-aid for the bleeding edge!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Suffer anger]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-05-07-suffer-anger#2024-05-07-suffer-anger</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-05-07-suffer-anger#2024-05-07-suffer-anger</guid>
            <pubDate>Tue, 07 May 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
You must be willing to suffer the _anger_ of your opponent, and yet not return
_anger_. You must not become bitter. No matter how emotional your opponents are,
you must be _calm_.

**Anger is incompatible with joy.**
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setbacks without suffering]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-05-05-setbacks-without-suffering#2024-05-05-setbacks-without-suffering</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-05-05-setbacks-without-suffering#2024-05-05-setbacks-without-suffering</guid>
            <pubDate>Sun, 05 May 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Our goal is not to remain calm **while** suffering but rather to experience a
setback **without thereby suffering**.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[unset]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-05-01-unset#2024-05-01-unset</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-05-01-unset#2024-05-01-unset</guid>
            <pubDate>Wed, 01 May 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about the `unset` keyword in CSS; it resets the property value from the one
it inherited from its parent and it it doesn't natrually inherit from its
parent, it sets it to its initial value.

[Check it out](https://developer.mozilla.org/en-US/docs/Web/CSS/unset)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[bundlephobia]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-30-bundlephobia#2024-04-30-bundlephobia</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-30-bundlephobia#2024-04-30-bundlephobia</guid>
            <pubDate>Tue, 30 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you ever want to know (sort of) the cost of adding a package to your node
app, you can use [bundlephobia](https://bundlephobia.com/)!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[kanak di rakhi]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-28-kanak-di-rakhi#2024-04-28-kanak-di-rakhi</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-28-kanak-di-rakhi#2024-04-28-kanak-di-rakhi</guid>
            <pubDate>Sun, 28 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that `Kanak Di Rakhi` is a Punjabi song that me and the Boys wild out to.
It's a banger. It came out in 1959 and is a must listen to and dance to at any
reception.

https://www.youtube.com/watch?v=izQzQFMpY3g
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Project wide replace in neovim]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-26-project-wide-replace-in-neovim#2024-04-26-project-wide-replace-in-neovim</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-26-project-wide-replace-in-neovim#2024-04-26-project-wide-replace-in-neovim</guid>
            <pubDate>Fri, 26 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
```vim:title=how-to-find-and-replace-in-vim
"while in your quick list
:cdo s/your-search-term/thing-to-replace-with/g

"go to quick list after changes
:wa <CR>
```

<br />
<br />

https://www.youtube.com/shorts/Ofxlqz88pPA
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Semver Calculator]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-25-semver-calculator#2024-04-25-semver-calculator</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-25-semver-calculator#2024-04-25-semver-calculator</guid>
            <pubDate>Thu, 25 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
During office hours with Kent, I learned about
[semver calculator](https://semver.npmjs.com/)!

It seems pretty dope and I'm going to use it in the future!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GROQ]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-10-groq#2024-04-10-groq</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-10-groq#2024-04-10-groq</guid>
            <pubDate>Wed, 10 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I also learned that `Sanity` has their own query language for working with JSON.
Might be worth looking into if you need to do some transformations and just move
it into the query versus doing it in the code.

[Check it out](https://www.npmx.dev/package/groq)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fluid frontvibe]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-10-fluid-frontvibe#2024-04-10-fluid-frontvibe</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-10-fluid-frontvibe#2024-04-10-fluid-frontvibe</guid>
            <pubDate>Wed, 10 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about a sick template for building a headless shopify theme with Sanity and
Hydrogen.

[Check it out](https://fluid.frontvibe.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[details name attribute]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-04-10-details-name-attribute#2024-04-10-details-name-attribute</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-04-10-details-name-attribute#2024-04-10-details-name-attribute</guid>
            <pubDate>Wed, 10 Apr 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you pass in a name, it'll behave like an actual accordion. Thanks Adam
Argyle!

[Check it out](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#name)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[trigger.dev]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-03-14-trigger-dev#2024-03-14-trigger-dev</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-03-14-trigger-dev#2024-03-14-trigger-dev</guid>
            <pubDate>Thu, 14 Mar 2024 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Need to run background jobs? Not writing Ruby On Rails and therefore not using
`Sidekiq`? Check out [trigger.dev](https://www.youtube.com/watch?v=cT1pfsaZtdA)

I can _probably_ use this somewhere in the future but TBD 🤔!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[dotenv shared]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-02-19-dotenv-shared#2024-02-19-dotenv-shared</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-02-19-dotenv-shared#2024-02-19-dotenv-shared</guid>
            <pubDate>Mon, 19 Feb 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [dotenv.org](https://www.dotenv.org/pricing/)! You can use this to
share and sync your `.env` files across machines/teammates. They also allow for
the ability to encrypt your secrets and use them in your CI/CD pipelines.

The neat thing about this if someone leaves your company and you don't have a
fancy IT setup, you can just change the keys on the `dotenv` side of things and
the keys the user has on their local machine will no longer be valid!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS variables in media queries]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-01-24-css-variables-in-media-queries#2024-01-24-css-variables-in-media-queries</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-01-24-css-variables-in-media-queries#2024-01-24-css-variables-in-media-queries</guid>
            <pubDate>Wed, 24 Jan 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
We tried to use some CSS variables we defined inside of the `:root` with our
tailwind config and even though tailwind let's you do that, the outputted CSS
isn't actually valid 🤯! The media query declarations are processed while our
CSS is being parsed!

```css:title=wont-work.css
:root {
	--mobile-breakpoint: 600px;
	--tablet-breakpoint: 900px;
}

/* This gets processed before the CSS is parsed */
/* So the media query is invalid */
@media(max-width: var(--mobile-breakpoint)) {
	.showMeGoing {
    visibility: visible;
  }
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[stylex]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2024-01-19-stylex#2024-01-19-stylex</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2024-01-19-stylex#2024-01-19-stylex</guid>
            <pubDate>Fri, 19 Jan 2024 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So there's a _kind of_ new styling solution for the web called
[stylex](https://stylexjs.com/) brought to you by Facebook. I haven't used it
yet, but damn, it looks neat y'all.

[Check it out](https://stylexjs.com/docs/learn/thinking-in-stylex/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SVG foreignObject]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-12-07-svg-foreign-object#2023-12-07-svg-foreign-object</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-12-07-svg-foreign-object#2023-12-07-svg-foreign-object</guid>
            <pubDate>Thu, 07 Dec 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that you can inject other non SVG XML into an SVG document. From our
context, that means we can inject some HTML elements in the SVG. I've used it
once at work and it was kind of nice 😃.

[Check it out](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Humiliation]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-12-05-humiliation#2023-12-05-humiliation</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-12-05-humiliation#2023-12-05-humiliation</guid>
            <pubDate>Tue, 05 Dec 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
To gamble on yourself is to risk failure. To do it in public is to risk
humiliation.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fear directs]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-12-05-fear-directs#2023-12-05-fear-directs</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-12-05-fear-directs#2023-12-05-fear-directs</guid>
            <pubDate>Tue, 05 Dec 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Our fear, like a self-indicating arrow, points to the things we ought to do.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[typescript string hack]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-12-01-typescript-string-hack#2023-12-01-typescript-string-hack</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-12-01-typescript-string-hack#2023-12-01-typescript-string-hack</guid>
            <pubDate>Fri, 01 Dec 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Want to have some type hinting for a union but allow any string value?!

Use this hack bruh:

```ts
type color = 'red' | 'blue' | 'green' | (string & {})

function getColor(c: color) {
	console.log(c)
}

getColor('red') // editor will code complete this for you
getColor('yolo') // this works!
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS Grid, but fun]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-21-css-grid-but-fun#2023-11-21-css-grid-but-fun</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-21-css-grid-but-fun#2023-11-21-css-grid-but-fun</guid>
            <pubDate>Tue, 21 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Alright, I'm not the greatest at CSS, but I respect those people, such as
`Josh Comeau` that are! TIL (from reading his blog post) the following about
some CSS attributes and how they relate to grid:

- `justify`: deals with _columns_
- `align`: deals with _rows_
- `content`: deals with the _grid struture_
- `items`: deals with the _DOM nodes_ within the grid structure

For example, `align-items: center` can loosely be translated into:
`In the context of the row, these DOM nodes, center them... bro`. Seriously, go
read his article.

[Check it out](https://www.joshwcomeau.com/css/interactive-guide-to-grid/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Easy to judge. Hard to know.]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-19-easy-to-judge-hard-to-know#2023-11-19-easy-to-judge-hard-to-know</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-19-easy-to-judge-hard-to-know#2023-11-19-easy-to-judge-hard-to-know</guid>
            <pubDate>Sun, 19 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
It's easy to judge. It's hard to _know_. Until we know the reasons why a man
acted the way he acted, we cannot say that he acted wrongly.

Waste not a moment questioning a man's courage. Put the scrutiny solely on your
own.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[browser session cookie]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-14-browser-session-cookie#2023-11-14-browser-session-cookie</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-14-browser-session-cookie#2023-11-14-browser-session-cookie</guid>
            <pubDate>Tue, 14 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that if you don't set a `max-age` or `expiration` attribute with a cookie
you're trying to set with `document.cookie`, the browser wil default to expiring
at the end of the session (when the browser is closed).

This isn't necessarily the case for all browsers, such as `Firefox` but most
browsers will default to this behavior.

[Check it out](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Be not afraid.]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-12-be-not-afraid#2023-11-12-be-not-afraid</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-12-be-not-afraid#2023-11-12-be-not-afraid</guid>
            <pubDate>Sun, 12 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
It's okay to be scared, but, be not afraid. Being scared is a reaction to an
event; it's an ephemeral feeling. Be scared when something pops out of a haunted
house, but, be not afraid of ghosts. Be scared when you are about to go give a
presentation but be not afraid of speaking your mind.

It's okay -- being scared alerts you, wakes you up, and brings danger to your
awareness. Being afraid though? This is a state of being. It weakens you, drags
you down, and sometimes, paralyzes you.

**Be not afraid.**
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AST Explorer]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-12-ast-explorer#2023-11-12-ast-explorer</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-12-ast-explorer#2023-11-12-ast-explorer</guid>
            <pubDate>Sun, 12 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out you can not only transform JS into an AST, but even SQL statements!
Pretty nifty.

[Check it out](https://astexplorer.net/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[the obstacle]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-08-the-obstacle#2023-11-08-the-obstacle</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-08-the-obstacle#2023-11-08-the-obstacle</guid>
            <pubDate>Wed, 08 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
<BlockQuote>
	See things for what they are. Do what you can. Endure and bear what you must.
</BlockQuote>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[neovim cache]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-11-08-neovim-cache#2023-11-08-neovim-cache</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-11-08-neovim-cache#2023-11-08-neovim-cache</guid>
            <pubDate>Wed, 08 Nov 2023 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you're ever having issues with neovim, it might help to clear out the cache.
I recently was running into issues after switching from `packer` for my
dependency management to `lazy` and there was a sneaky little devil 😈 in the
cache directory causing issues.

You can view the cache directory here: `$HOME/.cache/nvim/`.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OAuth and OpenIDConnect]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-10-31-o-auth-and-open-id-connect#2023-10-31-o-auth-and-open-id-connect</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-10-31-o-auth-and-open-id-connect#2023-10-31-o-auth-and-open-id-connect</guid>
            <pubDate>Tue, 31 Oct 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working on my `todo` app, written in `go, htmx, and lit`, I forced myself
to get a better idea of how OAuth worked! I've used it before, but I never
really understood the flow.

This youtube video really does a good job summarizing exactly what's going on ❤️
!

https://www.youtube.com/watch?v=996OiexHze0
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react-reverse-portal]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-10-12-react-reverse-portal#2023-10-12-react-reverse-portal</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-10-12-react-reverse-portal#2023-10-12-react-reverse-portal</guid>
            <pubDate>Thu, 12 Oct 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Not gonna lie, I'll probably never need to reach for this tool 😂, but I heard
about it while watching a video on Youtube and thought it was cool.
`react-reverse-portal` allows you to render a react node and then take it out of
the dom entirely and return it later, without having to unmount the component.
It's pretty neat!

[Check it out](https://github.com/httptoolkit/react-reverse-portal)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[vercel serve]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-10-11-vercel-serve#2023-10-11-vercel-serve</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-10-11-vercel-serve#2023-10-11-vercel-serve</guid>
            <pubDate>Wed, 11 Oct 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about `serve` by vercel. It lets you serve your SPA/static files, incredibly
easily! We may or may not be using it at work for some of our SPAs 😉.

[Check it out!](https://github.com/vercel/serve)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[golang empty switch]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-10-10-golang-empty-switch#2023-10-10-golang-empty-switch</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-10-10-golang-empty-switch#2023-10-10-golang-empty-switch</guid>
            <pubDate>Tue, 10 Oct 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that golang allows for empty switch statements in the condition block. This
is not possible in JavaScript! The reasoning behind this is that the switch
statement in golang is not limited to only comparing values. Below you can see
two versions of branching logic -- one with the switch and one with else ifs 😊.

```go:title=with-switch.go
package main
import "fmt"
func main() {
    i := 10
    switch {
    case i < 0:
        fmt.Println("Negative number")
    case i == 0:
        fmt.Println("Zero")
    case i > 0:
        fmt.Println("Positive number")
    }
}
```

```go:title=no-switch.go
package main
import "fmt"
func main() {
    i := 10
    if i < 0 {
        fmt.Println("Negative number")
    } else if i == 0 {
        fmt.Println("Zero")
    } else if i > 0 {
        fmt.Println("Positive number")
    }
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Perplexity AI]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-09-24-perplexity-ai#2023-09-24-perplexity-ai</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-09-24-perplexity-ai#2023-09-24-perplexity-ai</guid>
            <pubDate>Sun, 24 Sep 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL about [Perplexity AI](https://www.perplexity.ai/about)! It's pretty slick
and useful for web development and research 😊.

https://youtu.be/cT8k9ECJ-2k
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS Variables and fallbacks]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-09-21-css-vars-and-fallbacks#2023-09-21-css-vars-and-fallbacks</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-09-21-css-vars-and-fallbacks#2023-09-21-css-vars-and-fallbacks</guid>
            <pubDate>Thu, 21 Sep 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that css `var` can accept a fallback! If we're setting the variable with
some JS and this JS code for some reason or another fails to run, we can set a
sensible fallback and present our users with at least _something_ adjacent to
what we wanted😊!

```css
color: var(--someVariable, #888888);
```

[Check it out](https://defensivecss.dev/tip/css-variable-fallback/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The acquisition of knowledge]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-09-20-the-acquisition-of-knowledge#2023-09-20-the-acquisition-of-knowledge</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-09-20-the-acquisition-of-knowledge#2023-09-20-the-acquisition-of-knowledge</guid>
            <pubDate>Wed, 20 Sep 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
The acquisition of knowledge brings about **satisfaction**, but it's application
brings about **fulfillment**.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[every returns true for empty arrays]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-09-14-every-returns-true-for-empty-arrays#2023-09-14-every-returns-true-for-empty-arrays</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-09-14-every-returns-true-for-empty-arrays#2023-09-14-every-returns-true-for-empty-arrays</guid>
            <pubDate>Thu, 14 Sep 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
`every` on the JavaScript Array object is great since it checks to see if a
given callback function is true for _every_ value in the array... but there's
some caveats to it. Namely, `every` will return true for the empty array, and it
does not take into consideration empty slots during its processing.

Refer to the following code to get an understanding of the caveats:

```js
const isNumber = (v) => typeof v === 'number'

[].every(isNumber) // true
[1, ,2].every(isNumber) // true
[1, null, 2].every(isNumber) // false

```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[scroll driven css animation]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-08-24-scroll-driven-css-animation#2023-08-24-scroll-driven-css-animation</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-08-24-scroll-driven-css-animation#2023-08-24-scroll-driven-css-animation</guid>
            <pubDate>Thu, 24 Aug 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there is
[CSS scroll driven animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll-driven_animations).
They don't have great browser support (still experimental) but I'm using it on
my site 🤣.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Davinci's childhood]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-08-10-davinci-s-childhood#2023-08-10-davinci-s-childhood</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-08-10-davinci-s-childhood#2023-08-10-davinci-s-childhood</guid>
            <pubDate>Thu, 10 Aug 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that Leondard Davinci was the illegitimate son of a notary and a prostitute
😯!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[node require cache]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-07-27-node-require-cache#2023-07-27-node-require-cache</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-07-27-node-require-cache#2023-07-27-node-require-cache</guid>
            <pubDate>Thu, 27 Jul 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that `commonjs` has a `require` cache. Basically, if you require a module
once in the file, it gets cached and if you attempt to require the module a
second time, EVEN IF THE CONTENT HAS CHANGED, you'll get the cached version.

Usually this isn't a problem but it bit me in the butt when I moved my remix app
over to be using express. I had to call this function inside of my server code
when remix finished rebundling.

```tsx
function clearRequireCache() {
	Object.keys(require.cache).forEach(function (key) {
		delete require.cache[key]
	})
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[tsx (the runtime)]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-07-13-tsx-the-runtime#2023-07-13-tsx-the-runtime</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-07-13-tsx-the-runtime#2023-07-13-tsx-the-runtime</guid>
            <pubDate>Thu, 13 Jul 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Today I learned about Typescript execute (I'm using it on my website now too
😆). It's a CLI alternative to node for running Typescript & ESM!

[Check it out](https://www.npmx.dev/package/tsx)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AgentGPT]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-07-06-agent-gpt#2023-07-06-agent-gpt</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-07-06-agent-gpt#2023-07-06-agent-gpt</guid>
            <pubDate>Thu, 06 Jul 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
My coworker told me about
[AgentGPT](https://docs.reworkd.ai/essentials/usecases). It'll be super helpful
with things like Code Assistance and Email and Communication.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[shadcn]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-06-28-shadcn#2023-06-28-shadcn</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-06-28-shadcn#2023-06-28-shadcn</guid>
            <pubDate>Wed, 28 Jun 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Check out [Shadcn](https://ui.shadcn.com/docs) to learn more about re-usable
components built using Radix UI and Tailwind CSS! It's not a component library;
you copy pasta the code you need into your project 😛!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Panda - a new spin on css-in-js]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-06-21-panda-a-new-spin-on-css-in-js#2023-06-21-panda-a-new-spin-on-css-in-js</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-06-21-panda-a-new-spin-on-css-in-js#2023-06-21-panda-a-new-spin-on-css-in-js</guid>
            <pubDate>Wed, 21 Jun 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a new kid on the block and this new kid is a game changer!
[Panda](https://panda-css.com/) is a new css-in-js solution that works in the
server-first framework era!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[neovim and chatgpt]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-06-15-neovim-and-chatgpt#2023-06-15-neovim-and-chatgpt</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-06-15-neovim-and-chatgpt#2023-06-15-neovim-and-chatgpt</guid>
            <pubDate>Thu, 15 Jun 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I was googling around and saw that there was a plugin created to allow me to use
chatgpt inside of neovim! I just downloaded it and I got to say, it is quite
nice 😊!

<TilInlineImage
	containerClassName="mx-0 lg:mx-0"
	imgDivClassName="aspect-[6/4]"
	alt="neovim and chatgpt together"
	src="https://res.cloudinary.com/dinypqsgl/image/upload/v1686872150/blog/neovim_chatgpt_clutj4.png"
/>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ripgrep and chatgpt]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-06-14-ripgrep-and-chatgpt#2023-06-14-ripgrep-and-chatgpt</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-06-14-ripgrep-and-chatgpt#2023-06-14-ripgrep-and-chatgpt</guid>
            <pubDate>Wed, 14 Jun 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So I switched over to neovim as my editor quite a while ago but to be honest,
I've had a hard time grasping how to use telescope and ripgrep effectively.
Thank god I have chatgpt around to help me figure out and explain basic
commands!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Zahavian Signal]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-05-06-zahavian-signal#2023-05-06-zahavian-signal</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-05-06-zahavian-signal#2023-05-06-zahavian-signal</guid>
            <pubDate>Sat, 06 May 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a theory that for a signal to be honest, it has to be costly, otherwise
everybody could imitate it. It's why we spend a 1/4 of our salary on an
engagement ring (that and being duped by the diamond companies) 😆.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Amor Fati]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-05-01-amor-fati#2023-05-01-amor-fati</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-05-01-amor-fati#2023-05-01-amor-fati</guid>
            <pubDate>Mon, 01 May 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Amor fati is a Latin phrase that may be translated as "love of fate" or "love of
one's fate". This stoic concept mirrors similar philosophies such as `Taqdeer`
in Arabic, loosley translated as the absolute decree of the Divine or
`Chardi Kala` in Sikhism.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[tailwind-merge]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-26-tailwind-merge#2023-04-26-tailwind-merge</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-26-tailwind-merge#2023-04-26-tailwind-merge</guid>
            <pubDate>Wed, 26 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working on my site, I realized that there was a nifty utility that handles
merging my tailwind classes for me!

[On NPM](https://www.npmx.dev/package/tailwind-merge)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[develobears]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-24-develobears#2023-04-24-develobears</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-24-develobears#2023-04-24-develobears</guid>
            <pubDate>Mon, 24 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Check it out; thank me later! Gotta love my besties!

[Check it out](https://www.google.ca/search?q=https://www.develobears.com/&sxsrf=APwXEdccw03wNB7VuvRI_0Dz9KxOWDwW2A:1682368986515&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjZ3snusMP-AhWUFzQIHV-5DmUQ_AUoAnoECAEQBA&biw=1512&bih=776&dpr=2#imgrc=4ZQxYS9CnKpiHM)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[cloudflare status headers]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-24-cloudflare-status-headers#2023-04-24-cloudflare-status-headers</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-24-cloudflare-status-headers#2023-04-24-cloudflare-status-headers</guid>
            <pubDate>Mon, 24 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So I've been trying to add in some `cache-control` headers to my remix site and
I'm using cloudflare as my CDN.

In order to determine if the cache is being hit, cloudflare adds a
`cf-cache-status` header to the response. You can find out more about it in the
below blog post!

[Check it out](https://www.getfishtank.com/blog/cloudflare-cdn-cf-cache-status-headers-explained)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Say hello in Paris]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-20-say-hello-in-paris#2023-04-20-say-hello-in-paris</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-20-say-hello-in-paris#2023-04-20-say-hello-in-paris</guid>
            <pubDate>Thu, 20 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Heading to Paris with a friend group soon and our research revealed that we
should say Bonjour to folks as we encounter them in our travels. Stark contrast
to Vancouver where no one says anything to anyone 🤣.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[wails.io]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-12-wails-io#2023-04-12-wails-io</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-12-wails-io#2023-04-12-wails-io</guid>
            <pubDate>Wed, 12 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
At a recent go meetup, I learned about a a cool thing to create cross platform
applications in Go: `wails`.

[Check it out](https://wails.io/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[@loadable/component]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-12-loadable-component#2023-04-12-loadable-component</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-12-loadable-component#2023-04-12-loadable-component</guid>
            <pubDate>Wed, 12 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working through my webpack config at work, I noticed the usage of
`@loadable/component`. It's similar to `React.Lazy` but solves the issue of SSR
(which is a requirement for my work's platform).

[Check it out](https://www.npmx.dev/package/@loadable/component)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Object.fromEntries]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-09-object-from-entries#2023-04-09-object-from-entries</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-09-object-from-entries#2023-04-09-object-from-entries</guid>
            <pubDate>Sun, 09 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there's a nifty methd on the `Object` type in JS: `fromEntries`. It's
the counterpart of `entries` method that exists on the `Object`.

Here's an example for you:

```js
let obj = { foo: 'bar', baz: 42 }
const entries = Object.entries(obj)
console.log(entries)
// Expected output: [["foo", "bar"], ["baz", 42]]

obj = {}
console.log(obj)
// Expected output: {} 😆

obj = Object.fromEntries(entries)
console.log(obj)
// Expected output: Object { foo: "bar", baz: 42 }
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Air - live reload for Go apps]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-08-air-live-reload-for-go-apps#2023-04-08-air-live-reload-for-go-apps</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-08-air-live-reload-for-go-apps#2023-04-08-air-live-reload-for-go-apps</guid>
            <pubDate>Sat, 08 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working through my golang course, I came across a tool for live-reloading
golang apps: `Air`

[Check it out](https://github.com/cosmtrek/air)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[wanderlog]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2023-04-05-wanderlog#2023-04-05-wanderlog</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2023-04-05-wanderlog#2023-04-05-wanderlog</guid>
            <pubDate>Wed, 05 Apr 2023 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
A few good friends and I are going on a trip to Europe. Sheelz (one of my
besties), found this awesome app to help us with planning our itinerary.

[Check it out](https://wanderlog.com/home)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fusejs 🔥]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-12-14-fusejs#2022-12-14-fusejs</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-12-14-fusejs#2022-12-14-fusejs</guid>
            <pubDate>Wed, 14 Dec 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
As I was thinking about how I would migrate my search index for my site to
remix, I came across an alternative to Lunrjs... and yes I know I can use
Algolia but I personally think it's overkill for what I want for my site.

[Check it out](https://fusejs.io/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[unifiedjs]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-12-07-unifiedjs#2022-12-07-unifiedjs</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-12-07-unifiedjs#2022-12-07-unifiedjs</guid>
            <pubDate>Wed, 07 Dec 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So there's this thing called `unified` that allows us to take things like
Markdown, HTML, or plain text and turns it into structured data (AST) so that we
can apply transformations on said data. Its rich plugin pipeline allows us to
typically write one line of code to chain a feature into a process.

It's more than this though as it is `collective` that spans multiple
organizations and an ecosystem that includes:

- remark
- rehype
- retext
- redot

[ Check it out ](https://unifiedjs.com/learn/guide/introduction-to-unified/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[fieldset element]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-12-05-fieldset-element#2022-12-05-fieldset-element</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-12-05-fieldset-element#2022-12-05-fieldset-element</guid>
            <pubDate>Mon, 05 Dec 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there's a `fieldset` element in HTML that allows for grouping of
several elements in a web form.

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[IndexedDB]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-12-01-indexed-db#2022-12-01-indexed-db</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-12-01-indexed-db#2022-12-01-indexed-db</guid>
            <pubDate>Thu, 01 Dec 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
This technology has been around for a while (> 3 years) and I haven't used it
personally, but it's pretty damn slick. IndexedDB is a low-level API for client
side storage. Its more popular brother, `localStorage` has its limitations and
if you're ever running into them, you might want to take a look at `IndexedDB`.
In a nutshell, `IndexedDB` is a transactional database system that allows us to
permanently store data inside a user's browser. It would be useful for
applications that store a large amount of data and applications that don't need
persistent internet connectivity to function.

Keep these key things in mind:

- It stores key-value pairs.
- It's built on a transactional database model.
- The API is mostly async.
- It's object-oriented 😲.
- It's not SQL
- It adheres to the same origin policy.

https://www.youtube.com/watch?v=VNFDoawcmNc
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[container son]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-11-30-container-son#2022-11-30-container-son</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-11-30-container-son#2022-11-30-container-son</guid>
            <pubDate>Wed, 30 Nov 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there's a sick new css feature dropping soon: `container queries`. I
haven't played around with them much myself but based on what I've seen, they
allow developers to now not only make layout changes via css based on the
viewport but also based on the size of an elements containining element.

A lot of people are pretty hyped about this feature and calling it the next
evolution of responsive design on the web.

[ Check it out ](https://css-tricks.com/next-gen-css-container/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[camel camel camel - save your money]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-11-21-camel-camel-camel-save-your-money#2022-11-21-camel-camel-camel-save-your-money</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-11-21-camel-camel-camel-save-your-money#2022-11-21-camel-camel-camel-save-your-money</guid>
            <pubDate>Mon, 21 Nov 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
It's that time of the year again where we'll be forking over some of our hard
earned cash to retailers in preparation for the holidays. TIL
[camelcamelcamel](https://camelcamelcamel.com/) exists and keeps pricing history
of all amazon products.

Whenever you see a "sale" being listed on Amazon, make sure to check this site
first 😊!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[twix for tailwind and react]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-11-20-twix-for-tailwind-and-react#2022-11-20-twix-for-tailwind-and-react</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-11-20-twix-for-tailwind-and-react#2022-11-20-twix-for-tailwind-and-react</guid>
            <pubDate>Sun, 20 Nov 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I haven't used this yet and today I didn't have much going on as I had to work
on some stuff around the house (renovations and all) but there's a
[project](https://github.com/Idered/twix) that tries to make it a little bit
more ergonomic to work with tailwind and React 😊.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[lazygit]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-11-19-lazygit#2022-11-19-lazygit</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-11-19-lazygit#2022-11-19-lazygit</guid>
            <pubDate>Sat, 19 Nov 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So I've been going pretty hard on my neovim settings and trying to really
embrace the command line when doing any sort of development work. Today I
learned about something called
[lazygit](https://github.com/jesseduffield/lazygit) which is a terminal gui for
git.

https://www.youtube.com/watch?v=CPLdltN7wgE
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[NeoVim is pretty damn fun]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-11-18-neovim-is-pretty-damn-fun#2022-11-18-neovim-is-pretty-damn-fun</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-11-18-neovim-is-pretty-damn-fun#2022-11-18-neovim-is-pretty-damn-fun</guid>
            <pubDate>Fri, 18 Nov 2022 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
After being laid off from Productboard, I've been spending time thinking about
how I want to continue with my career and what to do with my spare time. Of
course landing a job is my priority, but during my time off, I want to devote
time to learning skills and technology that I've never been able to make the
time for in the past.

One thing I've always wanted to do (for the "by the way factor") was setting up
vim for my local development work. I devoted the entire day today to set up my
neovim config; I'm pretty happy with it so far.

[ Here's the config ](https://github.com/tearingItUp786/nvim-config)

https://www.youtube.com/watch?v=vdn_pKJUda8&t=3335s
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DomMatrix]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-10-17-dom-matrix#2022-10-17-dom-matrix</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-10-17-dom-matrix#2022-10-17-dom-matrix</guid>
            <pubDate>Mon, 17 Oct 2022 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I was once asked about matrices in an interview. Still unsure how they work but
we've got them in the browser specs 🤣.

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[matchMedia]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-10-11-match-media#2022-10-11-match-media</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-10-11-match-media#2022-10-11-match-media</guid>
            <pubDate>Tue, 11 Oct 2022 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
My mind was blown today when I learned that browsers now ship with a native way
to easily check if the window matches a specific media query. 🤯

Essentially, you can pass in a media query into `window.matchMedia` and the
returned object will tell you if the window matches you media query. It also
ships with event listeners so you can handle resizing out of the box ❤️ .

Shout out to my main man Vepor for this piece of knowledge!

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TS Utility: Extract]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-07-29-ts-utility-extract#2022-07-29-ts-utility-extract</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-07-29-ts-utility-extract#2022-07-29-ts-utility-extract</guid>
            <pubDate>Fri, 29 Jul 2022 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TypeScript has a handy utility type to `extract` types from a union type 🤭.

```tsx
type MyUnion = 'Hello' | 'Mom' | 'I' | 'Love' | 'You'
type WithoutMom = Extract<MyUnion, 'Mom'>
// the above will be the type "Hello" | "I" | "Love" | "You"
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[HTML attribute - inert]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2022-07-27-html-attribute-inert#2022-07-27-html-attribute-inert</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2022-07-27-html-attribute-inert#2022-07-27-html-attribute-inert</guid>
            <pubDate>Wed, 27 Jul 2022 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TLDR; this property, when applied to an html element will make it so that the
element ignores user input (this also applies to screen readers).

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React event.code]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-12-29-react-event-code#2021-12-29-react-event-code</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-12-29-react-event-code#2021-12-29-react-event-code</guid>
            <pubDate>Wed, 29 Dec 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out (at least at the time of writing this TIL), that react doesn't include
the `code` property on their Synthetic Events.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[determining which bug caused an issue]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-11-26-determining-which-bug-caused-an-issue#2021-11-26-determining-which-bug-caused-an-issue</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-11-26-determining-which-bug-caused-an-issue#2021-11-26-determining-which-bug-caused-an-issue</guid>
            <pubDate>Fri, 26 Nov 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So if you wanna figure out which commit in a repo caused an issue, git has a
useful command to do just that.

`git bisect`

[ Check it out... ](https://git-scm.com/docs/git-bisect#_basic_bisect_commands_start_bad_good)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Improving Scroll Performance]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-10-24-improving-scroll-performance#2021-10-24-improving-scroll-performance</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-10-24-improving-scroll-performance#2021-10-24-improving-scroll-performance</guid>
            <pubDate>Sun, 24 Oct 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out there's a way to improve event listeners that are tied to the
scrolling event in the browser.

```javascript
const onScroll = (e) => console.log('sup', e)
window.addEventListener('scroll', onScroll, { passive: true })
```

This will make it so that our scroll handler will not block the main thread
(yay!).

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Intelligence and Wisdom]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-09-01-intelligence-and-wisdom#2021-09-01-intelligence-and-wisdom</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-09-01-intelligence-and-wisdom#2021-09-01-intelligence-and-wisdom</guid>
            <pubDate>Wed, 01 Sep 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Intelligence is knowing a tomato is a fruit. Wisdom is knowing you don't put a
tomato in a fruit salad. Charisma is convincing everyone that it's a salsa.

Brought to you by Christine.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[esbuild-loader]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-07-15-esbuild-loader#2021-07-15-esbuild-loader</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-07-15-esbuild-loader#2021-07-15-esbuild-loader</guid>
            <pubDate>Thu, 15 Jul 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's been a lot of new developments in the space of package bundlers. From
the OG [Webpack](https://webpack.js.org/) to, [Rollup](https://rollupjs.org/) to
the new kid on the block [esbuild](https://github.com/evanw/esbuild) each of
them have their own unique set of features.

esbuild offers better build times as it is written in Go, which is compiled to
JavaScript. The tradeoff here is that es5 isn't supported (but that's okay if
you're not supporting IE11). It's pretty awesome but as it's in active
development and fairly new, it's not as widely used as the other bundlers and
therefore doesn't have the rich plugin resource that somethings like webpack
has.

However, you can leverage esbuild and plug it into a webpack config and via
[esbuild-loader](https://github.com/privatenumber/esbuild-loader) I did this at
work today and it helped with devserver startup times and greatly improved the
production build times.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recursive vs iterative approach]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-07-14-recursive-vs-iterative-approach#2021-07-14-recursive-vs-iterative-approach</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-07-14-recursive-vs-iterative-approach#2021-07-14-recursive-vs-iterative-approach</guid>
            <pubDate>Wed, 14 Jul 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a reason why React is moving toward a linked list approach and moving
away the recursive approach used in the current reconciler.

Recursion requires an O(n) call stack (causes jank). But if you do things
iteratively, you can stop relying on stacks and push all object references into
the heap. Arguably this is harder to reason about and harder to understand but
the perf gains are totally worth it.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Document Fragment]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-07-12-document-fragment#2021-07-12-document-fragment</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-07-12-document-fragment#2021-07-12-document-fragment</guid>
            <pubDate>Mon, 12 Jul 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So there's this really handy web api that allows you to create a lightweight
version of a Document and append nodes to said lightweight Document. The beauty
with this is you can create this tree, make changes to it, and then all at once
append the lightweight tree to the DOM.

This is much better than continually writing to the DOM and causing a shit ton
of reflows.

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recursion]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-07-01-recursion#2021-07-01-recursion</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-07-01-recursion#2021-07-01-recursion</guid>
            <pubDate>Thu, 01 Jul 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Never forget, recursion occurs when a thing is defined in terms of itself.

**YOU CAN HAVE ITERATION INSIDE OF A RECURSIVE FUNCTION.**

Iteration and recursion aren't mutually exclusive.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Feelings]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-29-feelings#2021-06-29-feelings</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-29-feelings#2021-06-29-feelings</guid>
            <pubDate>Tue, 29 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
**It's normal to sit down with a few negative feelings about beginning your
work. It's how you handle those feelings that matters.**
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[History scrollRestoration]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-28-history-scroll-restoration#2021-06-28-history-scroll-restoration</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-28-history-scroll-restoration#2021-06-28-history-scroll-restoration</guid>
            <pubDate>Mon, 28 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out you can set up auto scroll restoration with browser APIs (yay!).

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/History/scrollRestoration)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Post-Order Tree Traversal]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-24-post-order-tree-traversal#2021-06-24-post-order-tree-traversal</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-24-post-order-tree-traversal#2021-06-24-post-order-tree-traversal</guid>
            <pubDate>Thu, 24 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Learned about another way to traverse a tree! It's called Post-Order.

Essentially:

1. Go left as far as you can
2. Go right as far as you can
3. Visit Node

https://www.youtube.com/watch?v=4zVdfkpcT6U
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GET vs POST]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-18-get-vs-post#2021-06-18-get-vs-post</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-18-get-vs-post#2021-06-18-get-vs-post</guid>
            <pubDate>Fri, 18 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
All you need to keep in mind for a `GET` vs a `POST`. Basically, POST bodies are
not limited whereas the GET values are limited by a character limit for the
value.

<TilInlineImage
	imgDivClassName="aspect-[640/231]"
	alt="Get and Post"
	src="https://res.cloudinary.com/dinypqsgl/image/upload/f_auto/v1680029007/blog/get-vs-post_gfpc07.png"
/>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TypeScript Utility - Required]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-15-type-script-utility-required#2021-06-15-type-script-utility-required</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-15-type-script-utility-required#2021-06-15-type-script-utility-required</guid>
            <pubDate>Tue, 15 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there's a TS utility type that does the opposite of `Partial`.

[ Check it out ](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Require Generic]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-14-require-generic#2021-06-14-require-generic</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-14-require-generic#2021-06-14-require-generic</guid>
            <pubDate>Mon, 14 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Want to make it so that people need to provide some sort of generic argument if
they don't use some predefined defaults for your TS code. Check this out:

```ts
type NoInfer<T> = [T][T extends any ? 0 : never]

type QT<T> = 'first' | 'second' | T
type Yolo<T> = {
	data: QT<T>
}

function doSomething<T = void>(args: Yolo<NoInfer<T>>): null {
	// do something
	return null
}

doSomething({ data: 'first' }) // okay
doSomething({ data: 'three' }) // not okay
doSomething<'three'>({ data: 'three' }) //okay
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RTK query and React Query]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-11-rtk-query-and-react-query#2021-06-11-rtk-query-and-react-query</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-11-rtk-query-and-react-query#2021-06-11-rtk-query-and-react-query</guid>
            <pubDate>Fri, 11 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
State management is hard but there's a difference between state management in
our apps versus managing our app's server cache. Luckily, there are two
libraries that we can use to help us with our server side state needs.

React query and RTK Query. We're using React Query at work but RTK query looks
cool too!

I'll probably do a small POC this weekend to get a feel for the ergonomics.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dates and stuff]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-06-01-dates-and-stuff#2021-06-01-dates-and-stuff</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-06-01-dates-and-stuff#2021-06-01-dates-and-stuff</guid>
            <pubDate>Tue, 01 Jun 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Whenever you're going to be talking about dates, keep these things in mind:

1. Formatting (locale)
2. Timezone (this dictates how much time to add based on UTC)
3. UTC (know what this is)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Easier shell scripts]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-05-31-easier-shell-scripts#2021-05-31-easier-shell-scripts</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-05-31-easier-shell-scripts#2021-05-31-easier-shell-scripts</guid>
            <pubDate>Mon, 31 May 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a nifty little library to write shell scripts using node. Yay for less
hassle!

[Check it out](https://github.com/google/zx)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DateTimeFormat]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-05-27-date-time-format#2021-05-27-date-time-format</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-05-27-date-time-format#2021-05-27-date-time-format</guid>
            <pubDate>Thu, 27 May 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out that there's a neat little time formatter that most browsers ship with
that allows us to do locale specific time formatting. It's inside of the Intl.

```js
Intl.DateTimeFormat('en-US').format(Date.now())
```

[ Check it out... ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Carl Sagan + Weed]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-05-22-carl-sagan-weed#2021-05-22-carl-sagan-weed</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-05-22-carl-sagan-weed#2021-05-22-carl-sagan-weed</guid>
            <pubDate>Sat, 22 May 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out Carl Sagan was a big proponent of Marijuana. Who knew lolz.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to deal with a stye]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-05-04-how-to-deal-with-a-stye#2021-05-04-how-to-deal-with-a-stye</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-05-04-how-to-deal-with-a-stye#2021-05-04-how-to-deal-with-a-stye</guid>
            <pubDate>Tue, 04 May 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
<Callout
	type="warning"
	description="Not a doctor and this is not medical advice"
/>

Lol so I got a stye and a home remedy that I've been using is a tea bag.

You steep the tea bag for one minute and when it's bearable, rest the teabag on
the affected eye for 5-10 minutes. Preferably use black tea.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ambient TS files (*.d.ts)]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-04-29-ambient-ts-files-d-ts#2021-04-29-ambient-ts-files-d-ts</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-04-29-ambient-ts-files-d-ts#2021-04-29-ambient-ts-files-d-ts</guid>
            <pubDate>Thu, 29 Apr 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Alright, so I've been writing TS for a while and was never really sure why we
needed these `.d.ts` files... until today.

The purpose of these files is so that authors/the community can backport popular
JS libraries with TS type definitions. This allows library authors the freedom
to keep on writing their JS code but allows users of TS to benefit with working
code and the typings they need.

These typings probably exist in something like Definitely Typed. However, at
work, we're using a mix of JS and TS (JS is for the jest setup code) and
therefore we were required to have ambient TS files so that our TS test code
could benefit from the typings related to our JS files.

We are using module aliasing for our `TestUtils` so that we can do things like
`import { render } from 'TestUtils'`. Under the hood, the render function is
just a nicely wrapped render function from react-testing-library and so the
return types are the same. There was a bug where if I tried to import the
`RenderResult` from the testing library, VS code's TS language server would yell
at me for having an undefined module. The following code highlights the
fix/issue.

```ts:title=working.d.ts
// TYPESCRIPT IS A PAIN
// https://stackoverflow.com/questions/39040108/import-class-in-definition-file-d-ts/51114250#51114251
declare module "TestUtils" {
  export function render(
    v: any,
    other?: { initialState?: any }
  ): import("@testing-library/react").RenderResult
}
```

```ts:title=not-working.d.ts
// doesn't work
import { RenderResult } from "@testing-library/react"

declare module "TestUtils" {
  export function render(v: any, other?: { initialState?: any }): RenderResult
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[document.activeElement]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-04-23-document-active-element#2021-04-23-document-active-element</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-04-23-document-active-element#2021-04-23-document-active-element</guid>
            <pubDate>Fri, 23 Apr 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you want to know what element on the page currently has focus, you can use
`document.activeElement` to get access to the reference of the currently focused
element.

I'm using it to handle the `/` key to force my website to move focus onto the
search input (similar to what github does) and to not try to make the site
refocus the search if is the currently active element.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React.FC - don't bother]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-04-21-react-fc-don-t-bother#2021-04-21-react-fc-don-t-bother</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-04-21-react-fc-don-t-bother#2021-04-21-react-fc-don-t-bother</guid>
            <pubDate>Wed, 21 Apr 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
`React.FC` was more meant to help beginners get more comfortable writing React
components with TS but honestly, the cons of using it (always having the ability
to pass `children` to your component even though you might not be rendering said
`children`) make me want to not use it.

If you're wanting to type `children`, you can do:

```tsx
type Props = {
	children?: React.ReactNode
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Typescript Conditional Types]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-04-09-typescript-conditional-types#2021-04-09-typescript-conditional-types</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-04-09-typescript-conditional-types#2021-04-09-typescript-conditional-types</guid>
            <pubDate>Fri, 09 Apr 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out TS has some conditional types!

```ts
T extends U ? X : Y
```

If T extends U, then T is type X otherwise it is type Y.

[ Check it out ](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TypesScript Utility Type - Parameters]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-03-29-types-script-utility-type-parameters#2021-03-29-types-script-utility-type-parameters</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-03-29-types-script-utility-type-parameters#2021-03-29-types-script-utility-type-parameters</guid>
            <pubDate>Mon, 29 Mar 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a neat little utility type in TypeScript that lets you reach into a
function and discern the types of the function arguments.

```ts
Parameters<(s: string) => void>
// [s: string]
```

[ Check it out ](https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[attr]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-03-23-attr#2021-03-23-attr</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-03-23-attr#2021-03-23-attr</guid>
            <pubDate>Tue, 23 Mar 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a neat little css function that lets you retrieve the value of an
attribute of the selected element and use it in the stylesheet!

For example:

```jsx
<h1 data-color="red">Hello</h1>
```

```css
h1 {
	color: attr(data-color);
}
```

Would generate an h1 with red text!

[ Check it out ](<https://developer.mozilla.org/en-US/docs/Web/CSS/attr()>)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react-testing-library screen]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-03-18-react-testing-library-screen#2021-03-18-react-testing-library-screen</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-03-18-react-testing-library-screen#2021-03-18-react-testing-library-screen</guid>
            <pubDate>Thu, 18 Mar 2021 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So turns out there's a handy
[screen](https://testing-library.com/docs/queries/about/#screen) that
react-testing-library exports. Don't always have to use the container!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Good design]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-03-11-good-design#2021-03-11-good-design</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-03-11-good-design#2021-03-11-good-design</guid>
            <pubDate>Thu, 11 Mar 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working my way through _The Pragmatic Programmer_ I came by a tip that
really struck a chord with me. **Good design is easier to change than bad
design.**

Make things _easier to change_. Why is decoupling good? By isolating concerns,
we make each easier to change. Why is the single responsibility principle good?
A change in requirements is mirrored by a change in one module.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Wood filler]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-03-07-wood-filler#2021-03-07-wood-filler</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-03-07-wood-filler#2021-03-07-wood-filler</guid>
            <pubDate>Sun, 07 Mar 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you've created too large of a hole inside of your drywall and you want to
reuse the same hole for perhaps a drywall anchor, using spackle as filling won't
be enough.

Use **wood filler**; this'll give you the consistency and strength you need for
loadbearing purposes in the drywall.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Namespace pattern in React]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-03-04-namespace-pattern-in-react#2021-03-04-namespace-pattern-in-react</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-03-04-namespace-pattern-in-react#2021-03-04-namespace-pattern-in-react</guid>
            <pubDate>Thu, 04 Mar 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So I've seen this pattern around but didn't know it had a name! If you've ever
used Context in React, you're aware of there being a `Provider` and a `Consumer`
and those two are namespaced to a specific Context. Keep in mind, this is
assuming you're using React < 16.8.0.

I'm still trying to figure out when this _should_ be used.

```jsx:title=namespace-pattern.js
const SomeContext = React.createContext()

const SomeContextProvider = ({children}) => {
  const [yolo, setYolo] = React.useState(false)

  // highlight-next-line
  return <SomeContext.Provider>{children}</SomeContext.Provider>
}

const SomeContextConsumer = ({children}) => {
  return (
    // highlight-next-line
    <SomeContext.Consumer>
      {context => {
        if (context === undefined)
          throw new Error('Must be used within a SomeContextProvider')

        return children(context)
      }}
    </SomeContext.Consumer>
  )
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[overflow, position absolute, stop hiding]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-02-23-overflow-position-absolute-stop-hiding#2021-02-23-overflow-position-absolute-stop-hiding</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-02-23-overflow-position-absolute-stop-hiding#2021-02-23-overflow-position-absolute-stop-hiding</guid>
            <pubDate>Tue, 23 Feb 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So if you have an element positioned absolutely in a container and the container
has overflow hidden the absolute element is gonna be hidden.

Need a structure of grandparent (relative position) > parent (overflow hidden) >
child (position absolute)

[ Check it out ](https://stackoverflow.com/questions/5513382/absolute-position-and-overflowhidden)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSS ID's cannot start with numbers!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-02-23-css-id-s-cannot-start-with-numbers#2021-02-23-css-id-s-cannot-start-with-numbers</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-02-23-css-id-s-cannot-start-with-numbers#2021-02-23-css-id-s-cannot-start-with-numbers</guid>
            <pubDate>Tue, 23 Feb 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Bruh, you can't do something like `document.querySelector('#1')` and expect it
to work. The browser will yell at you! You have to do
`document.querySelector([id='1'])`

[ Check it out ](https://css-tricks.com/ids-cannot-start-with-a-number/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Valid header values]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-02-22-valid-header-values#2021-02-22-valid-header-values</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-02-22-valid-header-values#2021-02-22-valid-header-values</guid>
            <pubDate>Mon, 22 Feb 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out header values are always strings. So if there's a header value like
x-header and you want to see if it is true or false in JS, doing
Boolean(req.header['x-header']) would be `true` regardless because "true" and
"false" are both true for `Boolean` constructor.

You can do something like req.header['x-header'] === 'true'
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[4 tools from twitter]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-02-20-4-tools-from-twitter#2021-02-20-4-tools-from-twitter</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-02-20-4-tools-from-twitter#2021-02-20-4-tools-from-twitter</guid>
            <pubDate>Sat, 20 Feb 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
[ This is from the Twitters ](https://twitter.com/nickbulljs/status/1342784851339059203)

For posterity:

1. [I Hate Regex](https://ihateregex.io/)
2. [Free Drawings](https://www.drawkit.io/)
3. [Ngrok](https://ngrok.com/)
4. [ JSON placeholder Data ](http://jsonplaceholder.typicode.com/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Massive SVG and art board sizes]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-02-16-massive-svg-and-art-board-sizes#2021-02-16-massive-svg-and-art-board-sizes</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-02-16-massive-svg-and-art-board-sizes#2021-02-16-massive-svg-and-art-board-sizes</guid>
            <pubDate>Tue, 16 Feb 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So lol when I was exporting an SVG from Affinity, I noticed that the svg size
was around 3 mb. Reducing the art board size made the export size waaaay better.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[affinity designer]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-02-09-affinity-designer#2021-02-09-affinity-designer</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-02-09-affinity-designer#2021-02-09-affinity-designer</guid>
            <pubDate>Tue, 09 Feb 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out we aren't forced to be shackled to the Adobe suite 🤣. There's similar
software called Affinity that does pretty much what Adobe does (without the arm
and leg payment).

[Check it out](https://affinity.serif.com/en-gb/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[VSCode regions]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-01-18-vs-code-regions#2021-01-18-vs-code-regions</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-01-18-vs-code-regions#2021-01-18-vs-code-regions</guid>
            <pubDate>Mon, 18 Jan 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that vscode has region folding! It's like this:

```tsx
//#region
const y = () => {}
const x = () => {}
//#endregion
```

[ Check it out ](https://code.visualstudio.com/docs/editor/codebasics#_folding)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don't forget about closure]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-01-08-don-t-forget-about-closure#2021-01-08-don-t-forget-about-closure</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-01-08-don-t-forget-about-closure#2021-01-08-don-t-forget-about-closure</guid>
            <pubDate>Fri, 08 Jan 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Not really a TIL but more of a reminder to myself to not forget about the damn
concept of closure and to leverage it in Scala. Just because you have one
function to handle sorting, doesn't mean that function can't have some helper
functions defined within its body.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[content-editable]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2021-01-01-content-editable#2021-01-01-content-editable</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2021-01-01-content-editable#2021-01-01-content-editable</guid>
            <pubDate>Fri, 01 Jan 2021 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out you can have a `contenteditable` attribute on your html and that'll
make (you guessed it), your content editable lol.

...go ahead... try it out on the list below... you know you want to. 🤪

<ul
	contentEditable={true}
	suppressContentEditableWarning={true}
	onBlur={(e) =>
		window.alert(
			JSON.stringify(
				Array.from(e?.target?.children).reduce(
					(acc, curr) => [...acc, curr?.innerText],
					[],
				),
			),
		)
	}
>
	<li>Food</li>
	<li>Food</li>
	<li>Food</li>
</ul>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Collapsing Margins]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-12-29-collapsing-margins#2020-12-29-collapsing-margins</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-12-29-collapsing-margins#2020-12-29-collapsing-margins</guid>
            <pubDate>Tue, 29 Dec 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So today at work I noticed that I was not getting the spacing I expected from
block level elements. The reason this was occuring was because my team and I
were relying on margins for spacing out elements, but we should have been
relying on padding instead.

Margins collapse in on each other (for siblings). If element A has a margin
bottom and element b is its sibling and underneath and has a margin top, we
would see the margin bottom of element A "collapse" (not be applied) and only
see the margin top of element B.

[ Check it out ](https://stackoverflow.com/questions/9519841/why-does-this-css-margin-top-style-not-work)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Printer ink]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-12-26-printer-ink#2020-12-26-printer-ink</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-12-26-printer-ink#2020-12-26-printer-ink</guid>
            <pubDate>Sat, 26 Dec 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that printer ink requires a vehicle (a resin like honey) and a pigment (a
powder). There's a lot that goes into this process and it is pretty **damn**
cool.

[How's it made](https://youtu.be/Fypi6dAJB8E)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Credit card skimmers and shimmers]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-12-22-credit-card-skimmers-and-shimmers#2020-12-22-credit-card-skimmers-and-shimmers</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-12-22-credit-card-skimmers-and-shimmers#2020-12-22-credit-card-skimmers-and-shimmers</guid>
            <pubDate>Tue, 22 Dec 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there are credit card scams around like skimmers and shimmers that
oftentimes show up at gas station pumps and other brick-and-mortar shops.

To avoid being a victim, do not pay at the pump if they require you to insert
the card at the pump (these pumps can be tampered with whilst the inside card
reader most likely will not be). **Pay with tap when you can**

Also, don't forget to check your transactions regularly and check out free
credit reporting services like Borrowell.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstract classes vs Traits]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-12-21-abstract-classes-vs-traits#2020-12-21-abstract-classes-vs-traits</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-12-21-abstract-classes-vs-traits#2020-12-21-abstract-classes-vs-traits</guid>
            <pubDate>Mon, 21 Dec 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So Scala is a single inheritance language but allows classes to utilize multiple
traits (these are like interfaces in Java). `Traits` and `Abstract` classes in
Scala are essentially the same but there are some key differences.

1. Traits cannot have constructor parameters (you can't do a new trait)
2. A class can inherit from multiple traits.
3. Traits are for behaviors. Abstract classes are for things.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[toFixed vs toPrecision]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-12-15-to-fixed-vs-to-precision#2020-12-15-to-fixed-vs-to-precision</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-12-15-to-fixed-vs-to-precision#2020-12-15-to-fixed-vs-to-precision</guid>
            <pubDate>Tue, 15 Dec 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
`toFixed(n)` provides n length after the decimal point; `toPrecision(x)`
provides x total length. Both will round! Both are functions that exist on the
Number prototype!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[learning-repos]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-12-14-learning-repos#2020-12-14-learning-repos</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-12-14-learning-repos#2020-12-14-learning-repos</guid>
            <pubDate>Mon, 14 Dec 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's so much to learn and more than enough time! Here are some cool links to
check out.

<ul>
	<li>
		[ General ](https://nicedoc.io/lauragift21/awesome-learning-resources)
	</li>
	<li>
		[ Best websites
		](https://github.com/sdmg15/Best-websites-a-programmer-should-visit)
	</li>
	<li>[ Dev Roadmap ](https://github.com/kamranahmedse/developer-roadmap)</li>
</ul>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[volta]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-30-volta#2020-11-30-volta</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-30-volta#2020-11-30-volta</guid>
            <pubDate>Mon, 30 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working on a javascript monorepos course, I was exposed to
[Volta](https://docs.volta.sh/guide/).

Volta eases the node development process by allowing developers to easily pin
node versions to a project and will automatically switch the development machine
to the right version when switching between contexts 😃.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mac emoji keyboard]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-30-mac-emoji-keyboard#2020-11-30-mac-emoji-keyboard</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-30-mac-emoji-keyboard#2020-11-30-mac-emoji-keyboard</guid>
            <pubDate>Mon, 30 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL keyboard shorcut for emojis on a mac is: **Command-Control-Space**
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[s-max-age]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-23-s-max-age#2020-11-23-s-max-age</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-23-s-max-age#2020-11-23-s-max-age</guid>
            <pubDate>Mon, 23 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there is a cache control header for a shared cache. The **s-max-age**
is similar to the **max-age** in that they both set a timer to invalidate a
cache for a particular resource. The difference between the two is that the
**s-max-age** applies to **shared** content and therefore applies to content on
a CDN.

This is better in circumstances where we want to force an invalidation for a
particular resource. This is not possible with **max-age**.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Resort Area!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-20-resort-area#2020-11-20-resort-area</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-20-resort-area#2020-11-20-resort-area</guid>
            <pubDate>Fri, 20 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there's a dope resort spot in South Asia. Maldives.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[npm i prefix]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-16-npm-i-prefix#2020-11-16-npm-i-prefix</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-16-npm-i-prefix#2020-11-16-npm-i-prefix</guid>
            <pubDate>Mon, 16 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So you can actually run an npm install for a directory without having to
actually change directories. Look: `npm install --prefix /my/project/root`
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Netlify Identity Widget]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-16-netlify-identity-widget#2020-11-16-netlify-identity-widget</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-16-netlify-identity-widget#2020-11-16-netlify-identity-widget</guid>
            <pubDate>Mon, 16 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There's a Netlify Identity Widget (that is framework agnostic) which can be
leveraged to add some authentication to web apps deployed to Netlify.

There's a limit of 1000 people but for a small e-commerce business that's more
than enough.

[ Here it is ](https://github.com/netlify/netlify-identity-widget)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[react-window]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-11-12-react-window#2020-11-12-react-window</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-11-12-react-window#2020-11-12-react-window</guid>
            <pubDate>Thu, 12 Nov 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you're rendering over 50 rows in react-table and messing around with
complicated filter logic, it's wise to utilize something like `react-window` to
get some performance gains as users are not going to be interacting with
elements not in the viewport so we shouldn't tax them for the rendering costs
behind such frivolous elements.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[toLocaleString]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-29-to-locale-string#2020-10-29-to-locale-string</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-29-to-locale-string#2020-10-29-to-locale-string</guid>
            <pubDate>Thu, 29 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that there is a method built into the Date object `toLocaleString`. It
essentially allows us convert a date string to a locale specific string.

[ {' '} Check it out ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[useLayoutEffect vs useEffect]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-use-layout-effect-vs-use-effect#2020-10-20-use-layout-effect-vs-use-effect</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-use-layout-effect-vs-use-effect#2020-10-20-use-layout-effect-vs-use-effect</guid>
            <pubDate>Tue, 20 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
99% of the time you want to be using `useEffect` but there are some rare use
cases for `useLayoutEffect` and I incidentally ran into one today at work 😂.

- `useLayoutEffect` if you need to mutate the DOM and/or perform some
  measurements
- `useEffect` if you don't interact with the DOM at all.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Scala pattern matching. If on steriods]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-scala-pattern-matching-if-on-steriods#2020-10-20-scala-pattern-matching-if-on-steriods</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-scala-pattern-matching-if-on-steriods#2020-10-20-scala-pattern-matching-if-on-steriods</guid>
            <pubDate>Tue, 20 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Pattern matching in Scala allows us to do some very nifty things. This is all
possible due to the fact that the comparison of objects is not done at the
reference level but at the value level.

Refer to the TIL regarding Scala's case classes😁.

```Scala
case class Cat(color: String, food: String)

val oswald = Cat("black", "Chips")

object ChipShop {
  def willServe(c: Cat): Boolean = {
    c match {
      case Cat(_, "Chips") => true //don't care about the first argument
      case Cat(_, _) => false // don't care about any arguments (this is the default case essentially)
    }
  }
}

ChipShop.willServe(oswald) // true
```

A pattern can be one of

1. a name, binding any value to that name;
2. an underscore, matching any value and ignoring it;
3. a literal, matching the value the literal denotes; or
4. a constructor-style pattern for a case class.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Scala comparisons]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-scala-comparisons#2020-10-20-scala-comparisons</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-scala-comparisons#2020-10-20-scala-comparisons</guid>
            <pubDate>Tue, 20 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
For Scala’s `case classes` we get a sensible `==` operator which is different
from Java’s—it delegates to equals rather than comparing values on reference
identity.

Soooo.

```Scala
new Person("Noel", "Welsh") == new Person("Noel", "Welsh")
// res4: Boolean = true
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Scala Case Classes]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-scala-case-classes#2020-10-20-scala-case-classes</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-20-scala-case-classes#2020-10-20-scala-case-classes</guid>
            <pubDate>Tue, 20 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Scala `case classes` are the bread and butter of Scala data types! Learn them ye
fool.

The syntax is as normal but with a case prefix. By using the `case` word before
class, Scala provides us some functionality out of the box, including but not
limited to:

1. the ability to omit the val keyword in constructor calls. (A field for each
   constructor argument)
2. a nicer toString method for classes
3. a sensible equals which operates on the field values of an object
4. a copy method that creates a new object with the same field values as the
   current one

```Scala
case class Cat(color: String, food: String)

// vs

class Cat(val color: String, val food: String)
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[window.open and max width/height]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-19-window-open-and-max-width-height#2020-10-19-window-open-and-max-width-height</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-19-window-open-and-max-width-height#2020-10-19-window-open-and-max-width-height</guid>
            <pubDate>Mon, 19 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that you can't open a window in full screen with `window.open`

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/API/Window/open)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why React Elements have a "$$typeof" Property]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-10-why-react-elements-have-a-typeof-property#2020-10-10-why-react-elements-have-a-typeof-property</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-10-why-react-elements-have-a-typeof-property#2020-10-10-why-react-elements-have-a-typeof-property</guid>
            <pubDate>Sat, 10 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While making my way through a new React course, I learned that React elements
have a `$$typeof` property to help mitigate issues with XSS attacks.

In essence, the `$$typeof` prevents anyone from trying to get React to create
invalid elements via JSON. Even if a user passed in some JSON that mimicked what
a React Node looks like, the value of `$$typeof` is a `Symbol` and this cannot
be mocked by JSON!

[ Check it out ](https://overreacted.io/why-do-react-elements-have-typeof-property/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Promise Extensions for JavaScript (prex)]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-10-01-promise-extensions-for-java-script-prex#2020-10-01-promise-extensions-for-java-script-prex</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-10-01-promise-extensions-for-java-script-prex#2020-10-01-promise-extensions-for-java-script-prex</guid>
            <pubDate>Thu, 01 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While I was working on something at my day job, I learned about

[prex](https://www.npmx.dev/package/prex).

It essentially allows us to cancel our promises (think axios or some other xhr).

```tsx:title=token-example
return new Promise<void>((resolve, reject) => {
      const request = http.get(from);

      // abort the request if canceled.
      const registration = token.register(() => {
          request.abort();
          reject(new Error("Operation canceled."));
      });

      request.on("error", err => {
          registration.unregister();
          reject(err);
      });
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Preapproval and a line of credit]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-09-21-preapproval-and-a-line-of-credit#2020-09-21-preapproval-and-a-line-of-credit</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-09-21-preapproval-and-a-line-of-credit#2020-09-21-preapproval-and-a-line-of-credit</guid>
            <pubDate>Mon, 21 Sep 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL it's better to apply for a limit increase on a line of credit (LOC) if
there's a legitimate reason that this increase is required. Regardless of the
approval of the LOC increase, one's credit score takes a hit so it makes sense
to try and increase one's odds of being approved.

Having a reason for a limit increase (like a home reno) is more likely to get
approved than someone who just wants some more backup funds.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Start with why]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-09-15-start-with-why#2020-09-15-start-with-why</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-09-15-start-with-why#2020-09-15-start-with-why</guid>
            <pubDate>Tue, 15 Sep 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Whenever you're talking about setting up a business or a new venture, it's
important to start with _why_. Start with why, then move to how, and then move
to what... it might be worth reading this book:

[ Start With Why ](https://simonsinek.com/product/start-with-why/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Graceful Shutdown]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-09-10-graceful-shutdown#2020-09-10-graceful-shutdown</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-09-10-graceful-shutdown#2020-09-10-graceful-shutdown</guid>
            <pubDate>Thu, 10 Sep 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Basically, avoid having to do any major logic from the _SIGTERM_ signal or any
other EXIT signals in node because they can often times be fired twice. It's
much better to run any clean up code that you want in the start of the process
versus the end.

Also check out **death** on npm. It's a handy helper library.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[pascal-triangle]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-09-03-pascal-triangle#2020-09-03-pascal-triangle</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-09-03-pascal-triangle#2020-09-03-pascal-triangle</guid>
            <pubDate>Thu, 03 Sep 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
While working through my functional programming course, I encountered a fun
little leet code exercise. It's fucking computer science so I'm not even
surprised I had to solve a problem like this -.-

Anyway, here's how the pascal triangle code will work in JS and in Scala

```JS:title=js-example
function run() {
  for (let row = 0; row <= 10; row++) {
    const rec = []
    for (let col = 0; col <= row; col++) {
      rec.push(pascal(col, row))
    }
    console.log(rec)
  }
}

const pascal = (col, row) => {
  if (col === 0 || row < 1 || col === row) return 1
  else return pascal(col, row - 1) + pascal(col - 1, row - 1)
}

run()
```

```Scala:title=scala-example
def main(args: Array[String]): Unit = {
  println("Pascal's Triangle")
  for (row <- 0 to 10) {
    for (col <- 0 to row)
      print(s"${pascal(col, row)} ")
    println()
  }
}

/**
  * Exercise 1
  */
def pascal(c: Int, r: Int): Int = {
  // base case is if c = 0, just 1
  if (c == 0 || r < 2 || c == r) 1
  else pascal(c, r -1) + pascal(c - 1, r - 1)
}

```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Xpaths and Shadow DOM]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-09-01-xpaths-and-shadow-dom#2020-09-01-xpaths-and-shadow-dom</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-09-01-xpaths-and-shadow-dom#2020-09-01-xpaths-and-shadow-dom</guid>
            <pubDate>Tue, 01 Sep 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out you can't use Xpaths to access elements in a shadow dom.

[ Don't use xpaths ](https://stackoverflow.com/questions/49763626/can-xpath-expressions-access-shadow-root-elements)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Shadow DOM]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-08-18-shadow-dom#2020-08-18-shadow-dom</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-08-18-shadow-dom#2020-08-18-shadow-dom</guid>
            <pubDate>Tue, 18 Aug 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Encapsulation in the web is hard (especially when it comes to CSS)... thank god
for the Shadow DOM.

The Shadow DOM allows us the ability to keep the markup structure, styling, and
behavior (JS) so that different parts of the application do not clash. This is
entirely important for a micro frontend architecture -- **we do not want style
clashing**.

My colleague Danny and I were able to utilize the Shadow DOM and Single SPA to
create an encapsulated navbar. 😁

![Shadow](https://media.prod.mdn.mozit.cloud/attachments/2018/01/29/15788/9d23f749f26b93a00f5c2aa72f00e720/shadow-dom.png)

[ Check it out about it here ](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Simple grape tomato breakfast]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-08-16-simple-grape-tomato-breakfast#2020-08-16-simple-grape-tomato-breakfast</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-08-16-simple-grape-tomato-breakfast#2020-08-16-simple-grape-tomato-breakfast</guid>
            <pubDate>Sun, 16 Aug 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
My friend Anil showed me an awesome breakfast recipe that incorporates grape
tomatoes and ricotta cheese (both things I hardly eat...until now 😼)

[Check it out](https://youtu.be/4arNJoJ98Og)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[console.info]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-08-06-console-info#2020-08-06-console-info</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-08-06-console-info#2020-08-06-console-info</guid>
            <pubDate>Thu, 06 Aug 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that `Jest` will buffer console.log statements but this is not true for
console.info.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[lodash fp]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-08-05-lodash-fp#2020-08-05-lodash-fp</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-08-05-lodash-fp#2020-08-05-lodash-fp</guid>
            <pubDate>Wed, 05 Aug 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that lodash-fp was merged into lodash but there are some discrepancies. For
example, `compose` is `flow` and they both have `curry`.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Proactive]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-07-29-proactive#2020-07-29-proactive</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-07-29-proactive#2020-07-29-proactive</guid>
            <pubDate>Wed, 29 Jul 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Be proactive! Stay ready so you don't have to get ready 😁
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[express-middleware]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-06-03-express-middleware#2020-06-03-express-middleware</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-06-03-express-middleware#2020-06-03-express-middleware</guid>
            <pubDate>Wed, 03 Jun 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Express middleware is broken up into different types based on the number of
arguments your middleware function takes. A middleware function that takes 4
arguments is classified as "error handling middleware", and will only get called
if an error occurs.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[supertest]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-05-25-supertest#2020-05-25-supertest</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-05-25-supertest#2020-05-25-supertest</guid>
            <pubDate>Mon, 25 May 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Check out [supertest](https://www.npmx.dev/package/supertest) when you're doing
api development :)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[tsconfigs]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-05-19-tsconfigs#2020-05-19-tsconfigs</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-05-19-tsconfigs#2020-05-19-tsconfigs</guid>
            <pubDate>Tue, 19 May 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Ever run into the problem of having your `__tests__` directory sitting outside
of your `src` causing issues with TypeScript? I'm a big fan of colocating tests
but if you're ever working on a codebase that doesn't embrace this philosophy
and instead has a `__tests__` directory that sits at the same level as `src`,
you may need a a separate `tsconfig` for your tests.

This is possible thanks to the `-p` flag in TS and the fact that we can `extend`
tsconfig files. For the project in question, we used:

1. tsconfig.json
2. tsconfig.build.json
3. tsconfig.test.json

[ Check it out ](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Risk and reward]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-05-15-risk-and-reward#2020-05-15-risk-and-reward</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-05-15-risk-and-reward#2020-05-15-risk-and-reward</guid>
            <pubDate>Fri, 15 May 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Risk is the dancing partner of reward.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Struggling]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-05-09-struggling#2020-05-09-struggling</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-05-09-struggling#2020-05-09-struggling</guid>
            <pubDate>Sat, 09 May 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Struggling is not failing. Struggling is **succeeding** on not giving up.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Free HTTPS certs]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-05-07-free-https-certs#2020-05-07-free-https-certs</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-05-07-free-https-certs#2020-05-07-free-https-certs</guid>
            <pubDate>Thu, 07 May 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Don't be a sucka! TIL that you can get free HTTPS on your server thanks to a
handy tool called [Certbot](https://certbot.eff.org/).

Suck on that people who tried to charge me for HTTPS.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Promise Based Node Functions]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-05-04-promise-based-node-functions#2020-05-04-promise-based-node-functions</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-05-04-promise-based-node-functions#2020-05-04-promise-based-node-functions</guid>
            <pubDate>Mon, 04 May 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL during a basic async node training video, that the node core api exposes
promisified (I think that's a word) functions. For example `fs` provides a
promise based API.

[ Check it out ](https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_promises_api)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Checkbox read-only]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-04-30-checkbox-read-only#2020-04-30-checkbox-read-only</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-04-30-checkbox-read-only#2020-04-30-checkbox-read-only</guid>
            <pubDate>Thu, 30 Apr 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that input of type of "checkbox" is not an html element that can receive a
`read-only` attribute. 😖

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TypeScript declarations]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-04-27-type-script-declarations#2020-04-27-type-script-declarations</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-04-27-type-script-declarations#2020-04-27-type-script-declarations</guid>
            <pubDate>Mon, 27 Apr 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
My colleague Danny taught me how to easily create exportable interfaces for
react components.

Rather than exporting interfaces in a component (imperatively), you can set up a
`typings.d.ts` inside of a directory and it will be available to all components
that reside in subdirectories. 😁

```text
GeneralComponent
|--> GeneralComponent.tsx
|--> typings.d.ts
|--> Specialized // has access to interfaces in typings
     |---> Specialized.tsx
     |---> __tests__
```

Another valid way to do things is split typings in this way.

```text
src/types
|--> canvas.d.ts
|--> interfaces.d.ts
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Model vs Controller]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-04-21-model-vs-controller#2020-04-21-model-vs-controller</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-04-21-model-vs-controller#2020-04-21-model-vs-controller</guid>
            <pubDate>Tue, 21 Apr 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
After a brief conversation with Darnell, TIL that a controller should only be
concerned with the processing of a request. Database logic etc. should live in
the Model.

I'm such a noob 😆
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Internationalization in React]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-04-16-internationalization-in-react#2020-04-16-internationalization-in-react</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-04-16-internationalization-in-react#2020-04-16-internationalization-in-react</guid>
            <pubDate>Thu, 16 Apr 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
This technically isn't something that I learned "today" but it is something that
I wanted to make note of! If you're ever working on a project and need to
support internationalization, your library of choice— assuming you're writing in
React— should be [react-i18next](https://react.i18next.com/)!

Why? My coworker [Vincent](https://ca.linkedin.com/in/vincent-sheu) wrote up a
great ADR (Architectural Decision Record) and evaluated the library and some of
the benefits it totes is...

1. It has a hooks implementation so there's no change needed to be made to the
   render portion (the view) of your React components.
2. It generates translation files in a directory that can be easily handed off
   to a translator to populate
3. There's enterprise options available if ye need em!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Keyboard events, divs, and tabIndex]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-02-18-keyboard-events-divs-and-tab-index#2020-02-18-keyboard-events-divs-and-tab-index</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-02-18-keyboard-events-divs-and-tab-index#2020-02-18-keyboard-events-divs-and-tab-index</guid>
            <pubDate>Tue, 18 Feb 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Vincent and I learned that if you're attempting to add keyboard events to
`divs`, you'll want to supply a `role` and a `tab-index` if you're wanting to
react 😉.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Axios and Content-Type]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-02-11-axios-and-content-type#2020-02-11-axios-and-content-type</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-02-11-axios-and-content-type#2020-02-11-axios-and-content-type</guid>
            <pubDate>Tue, 11 Feb 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
During work today, my colleague Mo and I were having issues making `DELETE`
requests to a micro service that he had created. In Postman and the standard XHR
function that ships with Google Chrome, the delete requests were going through
with no problem but when we tried to make a call via `axios.delete(url/id)`, the
server kept returning a 400 error.

The truly peculiar thing was that making a call in the following manner worked:

```js
axios({
	method: 'DELETE',
	url: `url/${id}`,
	headers: {
		'Content-Type': 'application/json',
		Authorization: 'Bearer SOME_TOKEN',
	},
})
```

However, this failed:

```js
axios.delete(`url/${id}`, {
	headers: {
		'Content-Type': 'application/json',
		Authorization: 'Bearer SOME_TOKEN',
	},
})
```

Long story short, TIL: `axios.delete` will drop the content-type header (which
is the right behavior) so my buddy Mo had to change up his micro service
endpoint to not expect a content type 😁!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[California stop]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-02-06-california-stop#2020-02-06-california-stop</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-02-06-california-stop#2020-02-06-california-stop</guid>
            <pubDate>Thu, 06 Feb 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
My girl taught me about the California stop; it's essentially the same thing as
a rolling stop but cooler sounding.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WW2, Jews, and a Homeless Woman]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-02-02-ww2-jews-and-a-homeless-woman#2020-02-02-ww2-jews-and-a-homeless-woman</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-02-02-ww2-jews-and-a-homeless-woman#2020-02-02-ww2-jews-and-a-homeless-woman</guid>
            <pubDate>Sun, 02 Feb 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I've always believed wholeheartedly in the following quote,

<BlockQuote>
	A fool will learn nothing from a wise man. But a wise man will learn much from
	a fool.
</BlockQuote>

Yesterday evening, I was approached by a visibly homeless woman and amidst her
musings about how Canada is a flawed nation where people are left to suffer as
corporate greed consumes the very essence of the city and about how one doesn't
necessarily need a highschool education to be intelligent, she dropped a nugget
of wisdom on me that I'll carry with me for quite some time.

According to this woman, and I googled this after to make sure that it was in
fact true, the people of Denmark actively assisted in helping Jewish Danes
[escape from Hitler by evacuating them to neutral Sweden.](https://en.m.wikipedia.org/wiki/Rescue_of_the_Danish_Jews)

By no means am I saying that this woman is a fool; please don't misunderstand
me. What I'm trying to hit home with this TIL is that wisdom can come from
anywhere, whether it's a college professor or a homeless woman who, and I can't
make this up, began urinating in her pants mid conversation... everyone has got
something to offer.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[EC2 tiers]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-01-27-ec2-tiers#2020-01-27-ec2-tiers</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-01-27-ec2-tiers#2020-01-27-ec2-tiers</guid>
            <pubDate>Mon, 27 Jan 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Long story short, `t` tiers of ec2 instances are spotty and unreliable; stick to
using `m` series at the very least
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Focusing in with focus-within]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-01-16-focusing-in-with-focus-within#2020-01-16-focusing-in-with-focus-within</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-01-16-focusing-in-with-focus-within#2020-01-16-focusing-in-with-focus-within</guid>
            <pubDate>Thu, 16 Jan 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
The `focus-within` pseduo class represents an element that has received focus or
**contains** an element that has received focus.

```css
/* Selects a <div> when one of its descendants is focused */
div:focus-within {
	background: cyan;
}
```

[ Check it out ](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-within)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Single sign-on]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2020-01-11-single-sign-on#2020-01-11-single-sign-on</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2020-01-11-single-sign-on#2020-01-11-single-sign-on</guid>
            <pubDate>Sat, 11 Jan 2020 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Single sign-on (SSO) is a property of access control of multiple related, yet
indepdent records. Thanks to this property, users can log in with a single ID
and password to gain access to any of several related systems.

If you're working in a corporate setting, this is how you're able to seamlessly
switch between applications (maybe in the browser) and not have to log in
despite the fact that all these systems have some sort of authentication and
authorization piece associated with them.

[ Check it out about it here! ](https://www.onelogin.com/learn/how-single-sign-on-works)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[package.json main vs module]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=202-10-05-package-json-main-vs-module#202-10-05-package-json-main-vs-module</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=202-10-05-package-json-main-vs-module#202-10-05-package-json-main-vs-module</guid>
            <pubDate>Mon, 05 Oct 2020 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
TIL that the `main` attribute in package.json refers to the entry point for a
commonjs node module and that the `module` attribute refers to the es module
that can be used by bundlers such as `wepback` and `rollup`.

[ Check it out ](https://rollupjs.org/guide/en/#outputformat)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don't call React Components like they're functions]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-12-13-don-t-call-react-components-like-they-re-functions#2019-12-13-don-t-call-react-components-like-they-re-functions</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-12-13-don-t-call-react-components-like-they-re-functions#2019-12-13-don-t-call-react-components-like-they-re-functions</guid>
            <pubDate>Fri, 13 Dec 2019 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
The title sums it up but to learn more about it,
[visit this link](https://kentcdodds.com/blog/dont-call-a-react-function-component)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Components and Inversion of Control]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-11-21-components-and-inversion-of-control#2019-11-21-components-and-inversion-of-control</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-11-21-components-and-inversion-of-control#2019-11-21-components-and-inversion-of-control</guid>
            <pubDate>Thu, 21 Nov 2019 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
A neat little concept that I learned about (just briefly) today is this idea of
inversion of control. Essentially, assuming that we're talking about React/Vue
components, instead of having a mega component that accepts several different
props to handle various things like position, aligment, etc, it sometimes make
more sense to have a component that inverts control to the caller.

This means that we can extract out our business logic to a base component and
then have specialized components that utilize the inversion of control to create
a huge combination of different specializations/configurations. For exampe, we
could have a `Base Accordion` that implements some core business logic and the
rendering/extending can be left to a specialized implementation like
`Left aligned accordion` or `All can open acccordion`.

The benefits of this pattern are the following:

1. We no longer have to ship unncessary code to users -- people only get the
   code that's relevant to their use case
2. Our bundle sizes will drop considerabley because of number 1
3. We don't fall victim to the "it's only one more if statement" trap... if
   someone wants to extend our base component we expose the API'S they need to
   easily do this.

[ Thanks to Kent for the blog post! ](https://kentcdodds.com/blog/inversion-of-control)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[UTF-8 and encodings]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-11-17-utf-8-and-encodings#2019-11-17-utf-8-and-encodings</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-11-17-utf-8-and-encodings#2019-11-17-utf-8-and-encodings</guid>
            <pubDate>Sun, 17 Nov 2019 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
I'll be honest, up until today, I never really cared about character encodings
and didn't ever bother to learn anything about them... what a huge mistake!
Character encodings are the unsung heroes that allow us to display languages
(besides English) reliabely on computer systems.

The gist of UTF-8 is that it is an encoding that allows us to take Unicode code
and map said codes to meaningful linguinstic representations. Codes that are
between 0 and 127 occupy 8 bits -- a single byte -- and then any codes above
this upper bound can use up to 6 bytes. The beauty of this system is that
strings encoded in UTF-8 look exactly the same as strings encoded in ASCII.
Americans are chilling and don't need to worry about squat, while the rest of
the world has to "jump through hoops" to make sure that they're alphhabet will
work across computer systems.

[ Check it out ](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Plop JS -- making your project structure consistent!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-11-14-plop-js#2019-11-14-plop-js</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-11-14-plop-js#2019-11-14-plop-js</guid>
            <pubDate>Thu, 14 Nov 2019 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
So here is a nice little thing I'm going to try and get people using at work, I
hope! [PLOP js!](https://plopjs.com/)

It allows us to keep our project structure consistent by creating a CLI tool
that will help automate the creation of files that should exist for various
modules in our codebase. For example, if we are creating a `React` component, a
structure that we'd like to enforce in order to keep our project neat and tidy
is:

1. componentName > file name
2. componentName > index.js
3. componentName > \_\_tests\_\_
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setting up your own private registry!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-11-13-private-npm-registry#2019-11-13-private-npm-registry</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-11-13-private-npm-registry#2019-11-13-private-npm-registry</guid>
            <pubDate>Wed, 13 Nov 2019 08:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
When it comes to managing npm packages for your organization, there' a great
little package called: [Verdaccio](https://github.com/verdaccio/verdaccio).
Verdaccio is a light-weight npm proxy registry. It allows us to **host private
Node.js packages** and is compatible with all client package managers, such as
Yarn and npm. There's even a `Docker` image you can use to get you up and
running!
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Headless UI Components]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-10-25-headless-ui-components#2019-10-25-headless-ui-components</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-10-25-headless-ui-components#2019-10-25-headless-ui-components</guid>
            <pubDate>Fri, 25 Oct 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
import CheckboxExample from './Example'

A headless UI component is a component that offers up maximum flexibility by
providing no interface itself! This sounds like a radical idea but for library
authors, it's a great pattern to provide their users with all that sweet sweet
functionality that they're craving without any of the bloat/stylystic decisions
that come with interface decisions.

**This pattern works great when the logic of a component is complex and can be
decoupled from its visual representation.**

From a `React` perspective, this can be acheived via an HOC, render props, or if
you're using `React > 16.8`, hooks. Below is an example of two different
interface implementation of a very simple toggle -- the state isn't complicated
but since we created this headless interface, the UI can easily be
changed/edited and does not suffer from the opinions of the library author!

### The Example

<CheckboxExample />

```jsx:title=renderProps
class Toggle extends React.Component {
  state = {
    on: false,
  }

  handleClick = (cb = () => {}) => evt => {
    this.setState({ on: !this.state.on }, () => cb(evt))
  }

  render() {
    const { state, handleClick } = this
    return this.props.children({ state, handleClick })
  }
}

function CheckBox() {
  return (
    <Toggle>
      {({ state, handleClick }) => {
        return (
          <input
            type="checkbox"
            id="scales"
            name="scales"
            checked={state.on}
            onChange={handleClick()}
          />
        )
      }}
    </Toggle>
  )
}

// Just some simple styled components
// to illustrate how we can decouple the styling from the logic
const Label = styled.label``
const Input = styled.input``
const Slider = styled.span``

function PrettyToggle() {
  return (
    <Toggle>
      {({ state, handleClick }) => {
        const appliedHandleClick = handleClick(console.log)
        return (
          <Label>
            <Input
              type="checkbox"
              checked={state.on}
              onChange={appliedHandleClick}
            />
            <Slider />
          </Label>
        )
      }}
    </Toggle>
  )
}
```

```jsx:title=hooks
function useToggle(cb = () => {}) {
  const [on, updateClick] = React.useState(false)
  const event = React.useRef()

  React.useEffect(() => {
    cb(event)
  }, [on])

  return {
    on,
    handleClick(evt) {
      event.current = evt
      updateClick(!on)
    },
  }
}

function HookPrettyToggle() {
  const { on, handleClick } = useToggle(console.log)

  return (
    <label class="switch">
      <input type="checkbox" checked={on} onChange={handleClick} />
      <span class="slider round"></span>
    </label>
  )
}

function HookCheckBox() {
  const { on, handleClick } = useToggle()

  return (
    <input
      type="checkbox"
      id="scales"
      name="scales"
      checked={on}
      onChange={handleClick}
    />
  )
}
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hypermedia 🤔]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-10-22-hypermedia#2019-10-22-hypermedia</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-10-22-hypermedia#2019-10-22-hypermedia</guid>
            <pubDate>Tue, 22 Oct 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
In the Rest maturity model, Hypermedia is considered to be the most mature --
the highest level.

0. The swamp of Pox (XML)
1. Resources
1. HTTP Verbs
1. Hypermedia

In a nutshell, Hypermedia has REST endpoints expose links to other related data.
For instance, if there was an endpoint that existed to fetch all the products in
a particular catalog, each product resource in the payload would have a `_links`
property that had attributes that would allow users of the API via `self` to
navigate to the respected product. Just by visiting products, I'd have a way of
getting to a specific product without having to store the API endpoint in my
source code; the initial API call would prove it to me.

```json:title=products.json
{
  "_embedded": {
    "products": [
      {
        "title": "Navy blue stone wash jeans",
        "seller": "Revtown Jeans",
        "_links": {
          "self": {
            "href": "/products/42"
          }
        }
      }
      // more products ...
    ]
  }
}
```

[Check it out](https://reflectoring.io/rest-hypermedia/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A taste of Node]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-08-10-a-taste-of-node#2019-08-10-a-taste-of-node</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-08-10-a-taste-of-node#2019-08-10-a-taste-of-node</guid>
            <pubDate>Sat, 10 Aug 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Node is super useful for doing high throughput low latency I/O tasks! Here's a
diagram that roughly describes how Node works (I omitted libuv but you can bet
it's there):

```text
Server/A machine                                               World/Another machine
+-----------------------------------------------+              +-------------+
| +-------------+                               |              |             |
| |JS           |                               |              |             |
| |             |                               +-------------->             |
| |             |                               |              |             |
| |             |                               |              |             |
| |             |                               |              +-----+-------+
| +---+--^------+                               |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|  +--v--+------------+  +------------------+   |                    |
|  |Node (C++)        |  |OSS               |   |                    |
|  |                  |  |                  |   |                    |
|  |                  <--+                  |   |                    |
|  |                  +-->                  |   |                    |
|  |                  |  |                  |   |<-------------------+
|  |                  |  |                  |   |
|  +------------------+  +------------------+   |
|                                               |
+-----------------------------------------------+
```
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Axios, a DAM, and preflight]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-07-30-axios-and-preflight#2019-07-30-axios-and-preflight</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-07-30-axios-and-preflight#2019-07-30-axios-and-preflight</guid>
            <pubDate>Tue, 30 Jul 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
When making a request to a server, if they aren't accepting OPTIONS requests,
you're going to have a bad time. Axios and Fetch make preflight requests by
default so if you want to circumvent this, you'll have to use the vanilla XHR
capabilities.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Call a Spade a Spade]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-07-27-spade-shovel#2019-07-27-spade-shovel</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-07-27-spade-shovel#2019-07-27-spade-shovel</guid>
            <pubDate>Sat, 27 Jul 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Turns out a spade is also a suit for cards and a type of shovel! 😱.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Potato seeds are actually just rotten potatoes!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-07-26-potato-seed#2019-07-26-potato-seed</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-07-26-potato-seed#2019-07-26-potato-seed</guid>
            <pubDate>Fri, 26 Jul 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
There is no such thing as "potato seeds"... it's just a "seed potato"! That
is... there are only potatoes in this world 😱.
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don't use the unload event!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-07-14-visibility-change#2019-07-14-visibility-change</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-07-14-visibility-change#2019-07-14-visibility-change</guid>
            <pubDate>Sun, 14 Jul 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
The `unload` event that is available to us web developers isn't consistent
across browsers (but we already know that many things arent 😂). Really, if you
want to have predictable behavior and need to fire off some event/code when a
user leaves/closes your page, you should be listening to a page
`visbility change`.

[ Check it out ](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Buddy works!]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-07-05-buddy-works#2019-07-05-buddy-works</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-07-05-buddy-works#2019-07-05-buddy-works</guid>
            <pubDate>Fri, 05 Jul 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
Buddy works allows us to create pipelines for our projects! Similar to how
envoyer and deploybot works!  
It comes with a bunch of prebuilt recipes for when you try to set up your
actions. We're using it to do deployments to a project site after PRs are merged
and firing off notifications on slack!

[Check it out](https://buddy.works/)
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Make the right thing the easy thing]]></title>
            <link>https://taranveerbains.ca/til?offset=14&amp;til=2019-07-04-best-defaults#2019-07-04-best-defaults</link>
            <guid isPermaLink="false">https://taranveerbains.ca/til?offset=14&amp;til=2019-07-04-best-defaults#2019-07-04-best-defaults</guid>
            <pubDate>Thu, 04 Jul 2019 07:00:00 GMT</pubDate>
            <content:encoded><![CDATA[
If you want your code to be tested, _make it easy to test!_  
If you want people to do the right thing, _make the right thing the easy
thing!_  
When people get lazy, we can't rely on discipline -- _make the lazy thing the
right thing!_
]]></content:encoded>
        </item>
    </channel>
</rss>