Skip to content

Instantly share code, notes, and snippets.

View codemile's full-sized avatar

Nick Foscarini codemile

View GitHub Profile
@codemile
codemile / useGeoLocation.tsx
Created July 27, 2021 10:54
Hook for watching the users current location as geo coordinates.
import {useEffect, useState} from 'react';
const useGeoLocation = (options?: PositionOptions) => {
const [geo, setGeo] = useState<GeolocationPosition>();
const [err, setError] = useState<GeolocationPositionError>();
useEffect(() => {
const id = navigator.geolocation.watchPosition(
(pos) => {
setGeo(pos);
err && setError(undefined);
@codemile
codemile / useAudio.tsx
Created July 20, 2021 12:26
Hook that plays an audio file from a source URL.
import {useEffect, useMemo} from 'react';
export const useAudio = (
src: string,
play: boolean,
volume: number,
loop: boolean,
onDone?: () => void
) => {
const audio = useMemo(() => {
@codemile
codemile / Button.tsx
Created July 19, 2021 12:20
Basic example of a Button component in ReactJs.
import {ButtonHTMLAttributes, forwardRef} from 'react';
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
primary?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({className, primary, children, ...props}, ref) => {
return (
<button
@codemile
codemile / useClickOutside.tsx
Last active December 30, 2021 20:12
Hook that adds a click listener outside of an element.
import {DependencyList, useCallback, useEffect, useRef} from 'react';
export const useClickOutside = <T extends (...args: any[]) => any>(
cb: T,
dep: DependencyList
) => {
const ref = useRef<HTMLElement>(null);
// eslint-disable-next-line react-hooks/exhaustive-deps
const callback = useCallback(cb, dep);
@codemile
codemile / useArrayJoin.tsx
Created July 12, 2021 11:54
ReactJs hook that joins an Array of Elements with a separating Element.
export const useArrayJoin = (
arr: Array<JSX.Element>,
join: (key: number) => JSX.Element
) => {
return useMemo(() => {
return arr.reduce(
(acc: null | Array<JSX.Element>, next: JSX.Element, key) =>
acc === null ? [next] : [...acc, join(key), next],
null
);
@codemile
codemile / useCSSVariable.tsx
Created July 8, 2021 11:09
Hook that reads/writes #CSS variables. Turns a CSS variable into a useState() hook for your web components and lets you change them at run-time.
export const useCSSVariable = (name: string) => {
const [value, setState] = useState(
window.getComputedStyle(document.documentElement).getPropertyValue(name)
);
const setValue = useCallback(
(newValue: string) => {
setState(newValue);
document.documentElement.style.setProperty(name, newValue);
},
@codemile
codemile / useTickerTape.tsx
Created July 7, 2021 11:43
Hook that rotates the items of an Array over time like a news ticker tape.
const useTickerTape = <TType extends any>(
values: Iterable<TType>,
speed: number
) => {
const [tape, setTape] = useState([...values]);
useEffect(() => {
const id = setTimeout(() => {
const first = tape.shift();
setTape([...tape, first]);
@codemile
codemile / useDraggable.tsx
Created July 6, 2021 12:21
Hook that makes a DOM element draggable.
import {
MouseEventHandler,
RefObject,
useCallback,
useEffect,
useRef,
useState
} from 'react';
export type DraggableHandler = (coords: [number, number]) => void;
@codemile
codemile / useStateDebounce.tsx
Last active December 30, 2021 20:13
Hook that debounces useState() changes.
import {useCallback, useEffect, useRef, useState} from 'react';
export const useStateDebounce = <TType extends any>(ms: number, initialState?: TType) => {
const [state, setState] = useState(initialState);
const ref = useRef(0);
const setValue = useCallback(value => {
window.clearTimeout(ref.current);
ref.current = window.setTimeout(() => setState(value), ms);
}, [ms]);
useEffect(() => () => window.clearTimeout(ref.current), []);
@codemile
codemile / useStateJson.tsx
Last active December 30, 2021 20:14
Hook that stores a state value as a JSON string to prevent render updates when an object value is mutated but doesn't change.
import {useCallback, useMemo, useState} from 'react';
export const useStateJson = <TType extends any>(initialState?: TType) => {
const [json, setState] = useState<string>(
JSON.stringify(initialState ?? '')
);
const value = useMemo(() => JSON.parse(json), [json]);
const setValue = useCallback(
(next: TType) => setState(JSON.stringify(next ?? '')),
[]