Skip to content

Instantly share code, notes, and snippets.

View kyleshevlin's full-sized avatar

Kyle Shevlin kyleshevlin

View GitHub Profile
@kyleshevlin
kyleshevlin / arrayLengthGotcha.js
Created March 10, 2021 16:39
Array.length gotcha
// 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
function getInitialValues({
thing,
slug,
}): {
return {
_id: thing?._id ?? "",
birb: thing?.workingThing?.birb
? JSON.parse(thing?.workingThing?.birb)
: undefined,
doge: thing?.workingThing?.doge ?? "",
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 / asPropFacade.js
Last active January 23, 2021 10:51
`as` prop and the facade pattern
// 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 October 5, 2020 16:59
Scheme prefix operators as functions with reduce()
// 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 September 25, 2020 21:41
Boolean operators don't distribute
// 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
@kyleshevlin
kyleshevlin / index.js
Last active September 22, 2020 12:39
Recolor your GH contribution graph
// Run this in your console with whatever `newColors` you choose.
function recolorContributionGraph(newColors) {
const days = [...document.querySelectorAll('.day')]
const legendItems = [...document.querySelectorAll('.legend > li')]
const colors = [
...days.reduce((acc, day) => {
acc.add(day.getAttribute('fill'))
return acc
}, new Set()),
]
@kyleshevlin
kyleshevlin / index.js
Created August 16, 2020 17:41
renderless component example
import React from 'react'
export default function PrismHack() {
React.useEffect(() => {
const diffs = [...document.querySelectorAll('.language-diff-javascript')]
diffs.forEach(diff => {
diff.setAttribute('class', 'language-diff-javascript diff-highlight')
})
}, [])
function flattenFolderTree(folders) {
return folders.reduce((acc, folder) => {
const {children, ...rest} = folder;
if (!children || !children.length) {
return [...acc, rest];
}
return [...acc, rest, ...flattenFolderTree(children)];
}, []);
@kyleshevlin
kyleshevlin / justUseAForLoop.js
Last active August 6, 2020 20:38
Recursive Reducer done imperatively
function flattenFolderTree(folders, gatheringArray = []) {
folders.forEach(folder => {
const {children, ...rest} = folder
gatheringArray.push(rest)
if (children && children.length) {
flattenFolderTree(children, gatheringArray)
}
})