Skip to content

Instantly share code, notes, and snippets.

View donaldpipowitch's full-sized avatar

Donald Pipowitch donaldpipowitch

View GitHub Profile
@donaldpipowitch
donaldpipowitch / use-breakpoints.tsx
Created September 11, 2019 12:52
useBreakpoints hook for React
import React, { createContext, useContext, useMemo, FC } from 'react';
import { useMedia } from 'use-media';
enum Breakpoints {
small = 'min-width: 768px',
medium = 'min-width: 992px',
large = 'min-width: 1200px'
}
type BreakpointsContextValue = {
@donaldpipowitch
donaldpipowitch / use-match-media.tsx
Last active February 10, 2023 17:48
useMatchMedia - a React hook for matchMedia / media queries
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 / my-component.tsx
Created September 12, 2019 12:46
Children.map with unwrapping/flattening Fragments in React
import React, { FC, Children, ReactNode } from 'react';
import { isFragment } from 'react-is';
import styled from 'styled-components';
const SomeContainer = styled.div`
/* add some styling */
`;
const WrappedItem = styled.div`
/* add some styling */
@donaldpipowitch
donaldpipowitch / use-touched-handler.tsx
Created October 1, 2019 13:43
Change touch behavior of Formik
import { useState, useEffect } from 'react';
import { useFormikContext, FieldMetaProps } from 'formik';
export function useTouchedHandler(name: string, meta: FieldMetaProps<any>) {
const { setFieldTouched } = useFormikContext<any>();
// use meta.touched as the initial value to keep the state,
// in case this field was unmounted
const [wasChanged, setWasChanged] = useState(meta.touched);
@donaldpipowitch
donaldpipowitch / README.md
Last active February 18, 2024 09:43
Handle server errors in Formik

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 / data.json
Last active October 4, 2019 21:25
Country code to Country name in JSON
// from https://en.wikipedia.org/wiki/ISO_3166-2#cite_note-iso31661-2, 4th Oct. 2019
[
{
"code": "AD",
"name": "Andorra"
},
{
"code": "AE",
"name": "United Arab Emirates"
},
@donaldpipowitch
donaldpipowitch / README.md
Created October 8, 2019 06:09
A React hook to create Axios Mocks

A simple hook which can be used to create Axios mock. The hook will throw an error if an unmocked route was found.

Works great in Storybook stories:

export const EmptyResult = () => {
  useMock((mock) => {
    const result = [];
    mock.onGet(searchUrl).reply(200, result);
 });
@donaldpipowitch
donaldpipowitch / README.md
Last active April 2, 2022 01:35
Example for a codemod which can run on a TypeScript code base

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 / README.md
Last active January 12, 2024 04:07
Use GitLab Pages to deploy a Storybook per branch

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 / example.tsx
Created November 6, 2019 07:43
Mock Upload Progress with axios-mock-adapter
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) {