Skip to content
tinytip

Latest tips / 2

Scope your CSS imports with meta.load-css in Sass

June 27, 2023
#scss

In contrast to the old @import rule to import SCSS files in Sass, the newer @use rule can only be used at the top level of a file, before any other statements. Using it inside a CSS selector is not allowed. For example:

.dark-theme {
// Works
@import "./dark-theme.scss";

// Does NOT work
@use "./dark-theme.scss";
}

But there is still a way for scoped imports. The meta.load-css function allows you to import a SCSS file inside a CSS selector and scope it to that selector:

@use "sass:meta";

.dark-theme {
@include meta.load-css("./dark-theme.scss");
}

Unlike @import, meta.load-css does not affect the parent selector & in the imported file. Given the following file:

// dark-theme.scss
button {
& + & {
margin-inline-start: 1rem;
}
}

Importing it with @import would result in a CSS selector that is technically valid but likely not what you want:

// Using @import results in:
.dark-theme button + .dark-theme button {
margin-inline-start: 1rem;
}

Using meta.load-css however does not break the parent selector:

// Using meta.load-css results in:
.dark-theme button + button {
margin-inline-start: 1rem;
}

Get IANA timezone of user

June 27, 2023
#javascript

If you ever have to work with timezones in JavaScript, you can use Intl.DateTimeFormat to get the IANA timezone of the user:

const timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
// Result: "Europe/Zurich"

Custom hooks should return named tuples and not use "as const"

March 19, 2023
#react #typescript

When you create a custom hook in React that returns a tuple, like setState does, you must tell TypeScript that you are returning a tuple and not just an array of arbitrary length. For example, the following code will not work:

function usePromise<T>(fn: () => Promise<T>) {
// ...
return [value, isReady];
}

TypeScript will tell you that the return type of the hook is (T | boolean)[]. To make the return value type-safe, you can use as const:

function usePromise<T>(fn: () => Promise<T>) {
// ...
return [value, isReady] as const;
}

The return type is now readonly [T, boolean]. However, as a consumer of the hook you don't know what these values mean. What's that boolean value? Does it indicate if the promise is ready or if it failed? You can solve this by explicitly defining the return value and giving the tuple items a name:

function usePromise<T>(fn: () => Promise<T>): [value: T, isReady: boolean] {
// ...
return [value, isReady];
}

This way, the return type is [value: T, isReady: boolean] and the consumer of the hook knows what the values mean.

Find previous commands in the terminal

January 19, 2023
#terminal

When you want to rerun a previously executed command in the terminal, you can use the up and down arrow keys to navigate through the history of commands. If you want to search for a specific command, press Ctrl + R and start typing. The terminal will search through the history and show you the latest matching command. Press Ctrl + R again to search for older commands.

Create QR codes in Chrome to send URLs to your smartphone

January 19, 2023
#chrome

If you want to open a website on your smartphone, i.e. to test it on a mobile device, you can use the sharing feature of Chrome to create a QR code that you can scan with your smartphone. Click on the share icon in the address bar and select "Create QR Code". Then scan the QR code with the camera app of your smartphone to open the website.

Generate QR code in Chrome