Skip to content

Instantly share code, notes, and snippets.

Avatar

Kyle Shevlin kyleshevlin

View GitHub Profile
View createRectFromPortion.js
function createRectFromPortion(portion, areaName) {
const sqrt = Math.sqrt(portion)
const upper = Math.ceil(sqrt)
const lower = Math.floor(sqrt)
const square = upper ** 2
const squareDiff = square - portion
const rect = lower * upper
const rectDiff = rect - portion
View index.tsx
import { styled } from '@stitches/react'
const clamp = (min: number, max: number) => (num: number) =>
Math.min(Math.max(min, num), max)
const optionize = fn => (options = {}) => fn(options)
const hslColor = (hue: number, sat: number, lum: number) => ({
brighten = 0,
darken = 0,
@kyleshevlin
kyleshevlin / rareCreateElementPreferred.ts
Created May 28, 2021
Sometimes createElement makes more sense
View rareCreateElementPreferred.ts
import { ComponentType, createElement, CSSProperties } from 'react'
interface HasKey {
key: string
}
type HomogenousListProps<T> = {
as?: 'ol' | 'ul'
component: ComponentType<T>
items?: Array<T>
View arrayLengthGotcha.js
// The gotcha
function List({ items }) {
return (
items.length && items.map((item) => <Item key={item.id} item={item} />)
);
}
// What will happen when the length of `items` is 0?
// It'll render a 0 as text in a Text Node, because JSX has to be able
View iHaveSoManyQuestions.js
function getInitialValues({
thing,
slug,
}): {
return {
_id: thing?._id ?? "",
birb: thing?.workingThing?.birb
? JSON.parse(thing?.workingThing?.birb)
: undefined,
doge: thing?.workingThing?.doge ?? "",
View tagIcon.js
import React from 'react'
const WIDTH = 20
const HEIGHT = 14
const CX = WIDTH / 3
const CY = HEIGHT / 2
const RADIUS = 2
export default function Tag({ fill = 'black', width = WIDTH }) {
const height = HEIGHT * (width / WIDTH)
@kyleshevlin
kyleshevlin / memoizedHandlers.js
Created Jan 22, 2021
Using React.useMemo to create a `handlers` object
View memoizedHandlers.js
// One of my new favorite React Hook patternms is to create handler
// functions for a custom hook using `React.useMemo` instead of
// `React.useCallback`, like so:
function useBool(initialState = false) {
const [state, setState] = React.useState(initialState)
// Instead of individual React.useCallbacks gathered into an object
// Let's memoize the whole object. Then, we can destructure the
// methods we need in our consuming component.
@kyleshevlin
kyleshevlin / asPropFacade.js
Last active Jan 23, 2021
`as` prop and the facade pattern
View asPropFacade.js
// Sometimes you'll have a component that you want to allow the consumer
// to render a different HTML element for semantic purposes. Use an `as`
// prop and a facade pattern to make it happen.
export function CallToAction({as = 'button', ...props}) {
return <CallToActionFacade as={as} {...props} />
}
function CallToActionFacade({ as, ...props }) {
switch (as) {
@kyleshevlin
kyleshevlin / index.js
Created Oct 5, 2020
Scheme prefix operators as functions with reduce()
View index.js
// I'm reading SICP at the moment, and they use a LISP called Scheme.
// In a LISP based language, the function or operator is in the "prefix" position
// To add numbers, you first write the operator `+` (hence prefix, it comes first)
// and then the arguments.
//
// In JavaScript, many of our operators come in the "infix" position, that is in the
// middle of two arguments. This limits how many arguments we can give that operation.
//
// What's nice about the prefix position is that you can then give the expression
// as many arguments as you would like and it will apply the operation to all of those
@kyleshevlin
kyleshevlin / index.js
Created Sep 25, 2020
Boolean operators don't distribute
View index.js
// I see this mistake often (and have made it myself before)
// What's the bug with this function?
function isFavSeason(season) {
return season === 'spring' || 'summer' ? 'yes' : 'no'
}
// Let's try it and find out
console.log(isFavSeason('spring')) // yes
console.log(isFavSeason('summer')) // yes