Skip to content

Instantly share code, notes, and snippets.

@tkrotoff
tkrotoff / font.md
Last active March 30, 2025 22:38
What font to use? Web or system font?

What font to use? Web or system font?

Context and Problem Statement

@tkrotoff
tkrotoff / ImageFormat.md
Last active March 12, 2025 00:18
What image format to use?
flowchart TD
  format["What image format to use?"] --> source{"Analog or digital source?"}

  source -- "analog<br>(photo from a camera)" --> jpeg["JPEG lossy<br><br>(also AVIF, WebP, HEIF/HEIC, JPEG XL...)<br><br>Like MP3 format</span>"]
  source -- "digital<br>(using a software to draw the picture)" --> staticOrAnimated["Static or animated?"]

  staticOrAnimated -- "static" --> vectorOrRaster{"Can you make it scalable (vector based)?"}
  staticOrAnimated -- "animated" --> gif["GIF<br><br>(also APNG, AVIF, WebP, MNG, HEIF, video formats like MP4...)"]
@tkrotoff
tkrotoff / #parseCookie.ts
Created January 23, 2025 10:42
Parses a `Cookie` HTTP header value or `document.cookie` into an object
function decode(str: string) {
try {
return decodeURIComponent(str);
} catch {
return str;
}
}
/**
* Parses a `Cookie` HTTP header value or `document.cookie` into an object.
@tkrotoff
tkrotoff / MinimalSVG.md
Last active March 11, 2025 23:28
Minimal SVG structure
<svg xmlns="http://www.w3.org/2000/svg" />
@tkrotoff
tkrotoff / #mockWindowLocation.ts
Last active March 21, 2025 20:20
Jest/Vitest mocks for JSDOM window.location & window.history
/* eslint-disable unicorn/no-null */
/*
* Resetting window.location between tests is unfortunately a hard topic with JSDOM.
*
* https://gist.github.com/tkrotoff/52f4a29e919445d6e97f9a9e44ada449
*
* FIXME JSDOM leaves the history in place after every test, so the history will be dirty.
* Also its implementations for window.location and window.history are lacking.
* - https://github.com/jsdom/jsdom/blob/22.1.0/lib/jsdom/living/window/Location-impl.js
@tkrotoff
tkrotoff / git-staged-warn-binaries.sh
Last active August 10, 2023 08:51
Warns about Git staged binary files
#!/usr/bin/env sh
# Warns about Git staged binary files
# https://gist.github.com/tkrotoff/dc49a8e501b6fdea5a4b66301f7682fc
# Capture the output of "git diff" in a temporary file
tmpfile=$(mktemp)
# https://stackoverflow.com/q/28109520
git diff -z --staged --name-only --diff-filter=ACMR > "$tmpfile"
@tkrotoff
tkrotoff / #deepFreeze.ts
Last active March 19, 2025 18:11
Deeply freezes an object
import { ReadonlyDeep } from 'type-fest';
/**
* Deeply freezes an object by recursively freezing all of its properties.
*
* - https://gist.github.com/tkrotoff/e997cd6ff8d6cf6e51e6bb6146407fc3
* - https://stackoverflow.com/a/69656011
*
* FIXME Should be part of Lodash and friends: https://github.com/Maggi64/moderndash/issues/139
*
@tkrotoff
tkrotoff / #FormValidationErrorMessageHack.tsx
Last active June 18, 2023 10:29
I want an error tooltip on a button when clicked, let's use the browser native input validation error message
import { forwardRef } from 'react';
// ref is optional with forwardRef(), I want it to be mandatory
// type ... = ReturnType<typeof forwardRef<T, P>>;
type ForwardMandatoryRefComponent<T, P> = React.ForwardRefExoticComponent<
React.PropsWithoutRef<P> & React.RefAttributes<T> & { ref: React.Ref<T> }
>;
type Props = {
// Why? https://stackoverflow.com/a/25367640
@tkrotoff
tkrotoff / #ObjectValues.ts
Last active June 18, 2023 08:42
Recursively converts all values from null to undefined and vice versa
/* eslint-disable guard-for-in, @typescript-eslint/ban-types, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */
import { Primitive } from 'type-fest';
// [Generic way to convert all instances of null to undefined in TypeScript](https://stackoverflow.com/q/50374869)
// ["I intend to stop using `null` in my JS code in favor of `undefined`"](https://github.com/sindresorhus/meta/discussions/7)
// [Proposal: NullToUndefined and UndefinedToNull](https://github.com/sindresorhus/type-fest/issues/603)
// Types implementation inspired by
@tkrotoff
tkrotoff / #getRandomNumber.ts
Last active April 9, 2024 14:39
getRandomInt() & getRandomFloat()
// https://gist.github.com/tkrotoff/f3f36926edeeb3f4ce4411151bde37b2
// Exported for testing purposes only
// https://stackoverflow.com/a/45736131
export function getNumberWithDecimalPlaces(num: number, decimalPlaces: number) {
const power = 10 ** decimalPlaces;
return Math.floor(num * power) / power;
}
type GetRandomNumberOptions = {