Skip to content

Instantly share code, notes, and snippets.

@dominictobias
dominictobias / useScrollPos.ts
Created March 12, 2020 15:25
useScrollPos - React hook for scroll position
import { RefObject, useEffect, useState } from 'react';
export interface ScrollPos {
top: number;
left: number;
}
export function useScrollPos(elRef: RefObject<HTMLElement>, disabled?: boolean): ScrollPos {
const [scrollPos, setScrollPos] = useState({ top: 0, left: 0 });
@dominictobias
dominictobias / CSS.tsx
Last active March 9, 2020 15:23
Simple no-frills CSS-In-JSS in React
/*
Why?
- Tiny compared to existing solutions
- No frills or stupid class hashing, just for portability of providing components with CSS included
- Discourage dynamism -> While the CSS will update if you pass in variables, `insertRule` is more
efficient for highly dynamic CSS. But highly dynamic CSS is a code smell. Conditional selectors and
CSS Variables can achieve most use cases whilst being far more performant.
*/
import { useRef, useEffect } from 'react';
@dominictobias
dominictobias / MyApp.jsx
Last active September 15, 2020 08:30
React CSS Theme
function MyApp({ theme }) {
const cssTheme = useMemo(() => makeCssTheme(theme, 'xx'), [theme]);
return (
<div style={cssTheme}>
{/*
Any component in here now has access to:
var(--xx-buttonPadding), var(--xx-background) etc.
*/}
</div>
@dominictobias
dominictobias / app.js
Last active January 29, 2020 15:38
App using useGlobalState
export default function App() {
const [theme, dispatch] = useGlobalState(appState, state => state.theme);
return (
<div style={{ background: theme.background }}>
<button onClick={() => dispatch('toggleTheme')}>Toggle theme</button>
<p style={{ color: theme.text }}>
You're enjoying the {theme.name} theme
</p>
</div>
@dominictobias
dominictobias / appState.js
Last active January 29, 2020 15:35
appState
const darkTheme = {
name: 'dark',
background: 'black',
text: 'white',
}
const lightTheme = {
name: 'light',
background: 'white',
text: 'black',
@dominictobias
dominictobias / useGlobalState.js
Last active January 29, 2020 14:51
useGlobalState
function useGlobalState(globalState, stateGetter) {
const [state, setState] = useState(stateGetter(globalState.state));
// We don't want to re-create the listener as we want to unlisten on unmount
// of the component which uses this hook, so we "tunnel" the state in.
const stateRef = useRef(state);
stateRef.current = state;
const listener = useRef(nextState => {
const stateUpdate = stateGetter(nextState);
@dominictobias
dominictobias / GlobalState.js
Last active January 29, 2020 15:22
GlobalState
class GlobalState {
state = {};
listeners = [];
constructor(reducer, initialState = {}) {
this.reducer = reducer;
this.state = initialState;
this.devTools = typeof window !== 'undefined' && window?.__REDUX_DEVTOOLS_EXTENSION__?.connect();
}
@dominictobias
dominictobias / swipeDetection.js
Last active January 20, 2020 07:18
Native JS swipe detection
let startX = 0;
let startY = 0;
function handleTouchStart(e) {
startX = e.changedTouches[0].screenX;
startY = e.changedTouches[0].screenY;
}
function handleTouchEnd(e) {
const diffX = e.changedTouches[0].screenX - startX;
@dominictobias
dominictobias / ResizeObserver.ts
Last active January 21, 2020 12:59
ResizeObserver type
declare global {
interface DOMRectReadOnly {
readonly x: number;
readonly y: number;
readonly width: number;
readonly height: number;
readonly top: number;
readonly right: number;
readonly bottom: number;
readonly left: number;
@dominictobias
dominictobias / useResizeObserver.js
Last active July 28, 2022 06:55
useResizeObserver hook for React
import { useRef, useCallback, useEffect, useState } from 'react';
import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer';
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
export default function useResizeObserver() {
const [size, setSize] = useState({ width: 0, height: 0 });
const resizeObserver = useRef(null);
const onResize = useCallback(entries => {