Skip to content

Instantly share code, notes, and snippets.

View joshwcomeau's full-sized avatar

Joshua Comeau joshwcomeau

View GitHub Profile
@joshwcomeau
joshwcomeau / find-elem-with-breakout-width.js
Created November 3, 2021 20:06 — forked from SSHari/find-elem-with-breakout-width.js
Paste this in your browser console to search for HTML elements which extend past the window's width and create a horizontal scrollbar.
function findBreakoutElem(rootElem = document.body) {
function checkElemWidth(elem) {
if (elem.clientWidth > window.outerWidth) {
console.log("The following element has a larger width than the window's outer width");
console.log(elem);
console.log('<-------------------------------------------------------------------->');
} else if (elem.scrollWidth > window.outerWidth) {
console.log("The following element has a larger width than the window's scroll width");
console.log(elem);
console.log('<-------------------------------------------------------------------->');
@joshwcomeau
joshwcomeau / use-change-log.hook.js
Last active December 12, 2021 04:29
ChangeLog Hook
/**
`useChangeLog` - dev-mode helper hook to let you
know why a memoized component re-rendered!
Usage example:
const YourComponent = React.memo((props) => {
// Just drop this fella into your memo component's body.
useChangeLog(props);
@joshwcomeau
joshwcomeau / FitText.js
Created December 29, 2017 00:24
FitText port
// @flow
// Reimplementation of the jQuery plugin "FitText"
// https://github.com/davatron5000/FitText.js/blob/master/jquery.fittext.js
import React, { PureComponent } from 'react';
type Props = {
compressor: number,
children: React$Node,
};
const casetteStatusReducer = constructReducer('idle', () => ({
[VIEW_CASETTES]: 'selecting',
[EJECT_CASETTE]: 'idle',
[HIDE_CASETTES]: 'idle',
[SELECT_CASETTE]: 'loaded',
}));
const selectedReducer = constructReducer(null, (state, action) => ({
[SELECT_CASETTE]: action.id,
}));
@joshwcomeau
joshwcomeau / construct-reducer.js
Last active August 11, 2016 12:58
Disappointing Ducks
const noop = function noop() {};
export default function constructReducer(initialState, caseCreator = noop) {
// Because this function creates a reducer, it needs to return a reducer.
return (state = initialState, action) => {
// caseCreator is a function that returns an object, representing all
// of our former cases in the switch statement. It's a function so that
// the cases have access to the state and the action.
const cases = caseCreator(state, action);
@joshwcomeau
joshwcomeau / refactored-reducer.js
Last active August 11, 2016 12:16
Disappointing Ducks
function statusReducer(state = 'idle', action) {
switch (action.type) {
case VIEW_CASETTES:
return 'selecting';
case EJECT_CASETTE:
case HIDE_CASETTES:
return 'idle';
case SELECT_CASETTE:
return 'loaded';
default:
@joshwcomeau
joshwcomeau / original-reducer.js
Created August 11, 2016 12:11
Disappointing Ducks
const initialState = {
casettes: {},
selectedCasette: null,
casetteStatus: 'idle', // One of 'idle', 'selecting', 'loaded'
casettePageNumber: 0,
casettePageLimit: 3,
};
export default function reducer(state = initialState, action) {
switch (action.type) {
const flipMatrix = matrix => (
matrix[0].map((column, index) => (
matrix.map(row => row[index])
))
);
const rotateMatrixCounterClockwise = matrix => (
flipMatrix(matrix).reverse()
);
const compose = (a, b) => x => a(b(x));
const reverse = array => [...array].reverse();
// `get` is a simple accessor function, used for selecting an item in an array.
const get = id => array => array[id];
// This functional version of map accepts our function first.
const map = (fn, array) => array.map(fn);
// `pluck` allows us to map through a matrix, gathering all the items at a
const reverse = array => [...array].reverse();
const compose = (a, b) => x => a(b(x));
const flipMatrix = matrix => (
matrix[0].map((column, index) => (
matrix.map(row => row[index])
))
);
const rotateMatrix = compose(flipMatrix, reverse);