Skip to content

Instantly share code, notes, and snippets.

@tvler
tvler / useSystemTheme.ts
Last active October 12, 2023 16:23
useSystemTheme.ts
import * as React from "react";
function getMediaQuery(): MediaQueryList {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
return mediaQuery;
}
function subscribe(onStoreChange: () => void): () => void {
const mediaQuery = getMediaQuery();
mediaQuery.addEventListener("change", onStoreChange);
@tvler
tvler / getChainFromId.ts
Created May 5, 2023 18:50
Fast way to get a wagmi chain from a chainId
import * as chains from '@wagmi/chains'
import type { Chain } from 'wagmi'
const chainValues = Object.values(chains)
const chainMap = new Map<number, Chain>()
for (const chain of chainValues) {
chainMap.set(chain.id, chain)
}
@tvler
tvler / machine.js
Created December 1, 2022 19:55
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
@tvler
tvler / getLinkifiedString.tsx
Last active October 29, 2022 01:04
Turn a string into JSX with autolinks
type LinkifiedString = Array<string | JSX.Element> | string | null | undefined
/**
* Turn a string into JSX with autolinks
*/
export function getLinkifiedString(str: string | null | undefined): LinkifiedString {
try {
// Group by whitespace (wrapping regex in parens keeps matched results in the array)
const substrings = str?.split(/(\s+)/g)
import * as React from 'react'
import { SpringValue, easings, useSpring } from 'react-spring'
/**
* Hook that animates height when args.animationKey changes
*
* Ex:
* const animatedBlock = useAnimatedHeight({
* animationKey: key,
* })
function useGetterState<T>(value: T) {
const [state, setState] = React.useState<T>(value)
const stateRef = React.useRef<T>(state)
React.useEffect(() => {
stateRef.current = state
}, [state])
const getter = React.useCallback(function (newValue?: React.SetStateAction<T>): T {
// use arguments.length because it's the only way to
@tvler
tvler / hoc.tsx
Last active November 7, 2021 01:06
A type-safe high-order-component creator that injects a prop named a given string, with a type inferred by a given hook's return value.
/**
* A type-safe high-order-component creator
* that injects a prop named a given string,
* with a type inferred by a given hook's
* return value.
*
* Ex:
* const Component = ({ name }) => {
* return <>Hello {name}</>;
* };
@tvler
tvler / guard.ts
Created June 9, 2021 16:16
A way to test if a Type adheres to a wider Supertype, without widening the initial Type
type Guard<Type extends SuperType, SuperType> = Type;
const tuple = [1, 2, 3] as const;
type Test = Guard<typeof tuple, ReadonlyArray<number>>;
@tvler
tvler / shallowEqualWarnInDev.ts
Last active May 20, 2021 12:43
A custom React.memo memoization function that throws an error (in dev) if props change between renders.
/**
* A strict React.memo memoization function, built off
* the one that comes built-in, that throws an error
* (in dev) if props change between renders. Props you
* want to allow can be passed in as arguments.
*
* This "don't allow by default" model makes it so
* further changes to a component don't silently
* undo any memoization optimizations done before.
*
@tvler
tvler / inferTuple.ts
Created March 24, 2021 21:30
Infer an array argument as a tuple in typescript
// TS playground:
// https://www.typescriptlang.org/play?#code/PTAElByAoAzBXA7AxgFwJYHt6lfaBTAJwBVYAHAGzwB5JRQSK9Q8APZPeAEwGdRvkCOAOYBtALoAaUJAB8ACmRlKALlAiAdJoaUxASlABvWqAJ5FBLIsaQAvgG5IiTP2y5C2vETwuAvK-zESnhyIgDkAIahUqEARlGgoYihepCQwABUtOmgABKETOGmfOgAtkzc5KhCABbkAJ58qCWo5IWgcEhomFmgnHjQOKhd8LzI1eHI7eEtoMjo-oSg4bNBWcCpIKCAvBuA1XswCCgYWIQE6AQAjApBqhqa-ILwomJ6hsam5par9o7Okydn5y8vmYBFOFxCEXisShSRSaTAu32nSOILBACYqB55FYVPQgvojHR3rALCtrN8nCM-qCzmigZM-P8CGiIZFonForDdBsEXsOodMKizgBmTFBZhsDg8PgCYTibHXPGMAlvMwkz7khyUlxM4X00CMmkEYWsqEchJcoA
// ✅
function inferTuple<
Tuple extends string[],
>(tuple: [...Tuple]) {
return tuple
};
const inferTupleTest = inferTuple(['a', 'b', 'c'])