Skip to content

Instantly share code, notes, and snippets.

Avatar

Donald Pipowitch donaldpipowitch

View GitHub Profile
@donaldpipowitch
donaldpipowitch / example.tsx
Created Nov 6, 2019
Mock Upload Progress with axios-mock-adapter
View example.tsx
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
const mock = new MockAdapter(axios);
// this mocks a request which is always at 40% progress
mock.onPost('/upload-1').reply((config) => {
const total = 1024; // mocked file size
const progress = 0.4;
if (config.onUploadProgress) {
@donaldpipowitch
donaldpipowitch / README.md
Last active Jun 7, 2021
Handle server errors in Formik
View README.md

Whenever the server returns validation errors and we would set them with setFieldError they would be lost if any field would get a change or blur event. But we want to keep these kind of errors until the specific field changes. Additional we want to handle generic server errors (which are not specific to a field, but the whole form).

With these hooks field specific server side errors should be added like this:

const { setStatus } = useFormikContext();

const errors = {};
// adjust serverErrors to your own responses
// in this case they look like this: Array<{ name: string, error: string }>
@donaldpipowitch
donaldpipowitch / README.md
Last active May 25, 2021
Create a codemod with Prettier and Babel
View README.md

Every now and then I'd like to apply a so called codemod to my a codebase. A codemod is a piece of code which modifies other code. Very often this is done by running some transformation on the abstract syntax tree (AST).

Whenever I need to do this I look for "What is the best way to apply a codemod on my TS code base right now?", because when I only do this every couple of month I either have forgotten about how to do it or tools have changed and my old way stopped working... or both. Surprisingly every time I search for that I found the existing tools bloated or quirky or not matching my workflow.

As I already use Babel to compile our source code I would like to create a Babel plugin which transforms my code. Sadly Babel alone is not good in preserving whitespace and formatting. Thankfully I use Prettier for that and because Prettier uses Babel internally I can create a Babel visitor to transform my source code.

The actually easiest and _most r

@donaldpipowitch
donaldpipowitch / README.md
Last active May 18, 2021
Use GitLab Pages to deploy a Storybook per branch
View README.md

It's quite straightforward to use GitLab Pages to deploy a Storybook instance per branch (and remove it whenever the branch will be removed). And yeah, it's irony to document this in a GitHub Gist 😅

You just need a .gitlab-ci.yml like this one:

stages:
  - setup
  - build-and-test
  - deployment
  - pages
@donaldpipowitch
donaldpipowitch / use-match-media.tsx
Last active Apr 27, 2021
useMatchMedia - a React hook for matchMedia / media queries
View use-match-media.tsx
import { useState, useEffect } from 'react';
// pass a query like `(min-width: 768px)`
export function useMatchMedia(query: string) {
const [matches, setMatches] = useState(() => matchMedia(query).matches);
useEffect(() => {
const mediaQueryList = matchMedia(query);
const onChange = (event: MediaQueryListEvent) => setMatches(event.matches);
@donaldpipowitch
donaldpipowitch / get-nice-upper-bound.ts
Created Nov 13, 2020
Nice upper bound (e.g. for charts, ticks, scales)
View get-nice-upper-bound.ts
function getNiceUpperBound(value: number) {
const zeroCount = String(Math.round(value)).length - 1;
const factor = Math.pow(10, zeroCount);
return Math.ceil(value / factor) * factor;
}
const upperBound = getNiceUpperBound(3464634); // 4000000
View use-stable-memo.ts
import { DependencyList, useState, useEffect, useRef } from 'react';
// use this instead of useMemo of you need a stable value
// see https://twitter.com/0xca0a/status/1314326386555924480
export function useStableMemo<T>(factory: () => T, deps: DependencyList): T {
const [value, setValue] = useState<T>(factory);
const firstRun = useRef(true);
useEffect(
() => {
@donaldpipowitch
donaldpipowitch / README.md
Last active Oct 3, 2020
Example for a codemod which can run on a TypeScript code base
View README.md

Install @codemod/cli globally:

$ npm install -g @codemod/cli
# or
$ yarn global add @codemod/cli

This package works out of the box with most code bases, because it comes bundled with @babel/preset-env and @babel/preset-typescript. If you need other presets or plugins for parsing your source code you can use a custom Babel config as well. Note that the codemod will not apply the transformations from these presets and plugins - they are only used for parsing. Therefor you keep your TypeScript types in your source code for example. Formatting will be kept the same as much as possible.

@donaldpipowitch
donaldpipowitch / mocked-storage.tsx
Last active Jul 22, 2020
useSessionStorage and useLocalStorage for easy mocking - similar to MemoryRouter in react-router, but for storage
View mocked-storage.tsx
import React, { FC, useMemo } from 'react';
import {
LocalStorageProvider,
SessionStorageProvider,
} from './use-storage';
// this is just a dumb mock of the storage interface
class MemoryStorage implements Storage {
private data: Record<string, string> = {};
@donaldpipowitch
donaldpipowitch / use-location-state.ts
Created Jul 22, 2020
useLocationState: a glorified location.state for React Router as a hook
View use-location-state.ts
import { useState, useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { useSessionStorage } from './use-storage'; // see https://gist.github.com/donaldpipowitch/7310d7b9e4b6d467134c425e8732adc6
type UseLocationStateOptions<T> = {
defaultValue?: T;
scope?: string;
filter?: (value: T) => boolean;
};