Skip to content

Instantly share code, notes, and snippets.

View lachlanjc's full-sized avatar
🏳️‍🌈
(they/them)

Lachlan Campbell lachlanjc

🏳️‍🌈
(they/them)
View GitHub Profile
import React, { useCallback, useState } from "react";
const EnvironmentVariables = () => {
const [variables, setVariables] = useState([{ key: '', value: '' }]);
const handleInputChange = useCallback((index, field, value) => {
setVariables((prevVariables) => {
const newVariables = [...prevVariables];
newVariables[index][field] = value;
return newVariables;
export const chaosTestStrings = (): void => {
const textNodes = getAllTextNodes(document.body);
for (const node of textNodes) {
const textNodeLength = node.textContent ? node.textContent.length : 0;
if (node.textContent === null) {
return;
}
if (node.parentElement instanceof Element) {
if (node.parentElement.dataset.originalText === undefined) {
@jed
jed / resolve_tco.js
Last active April 30, 2024 01:33
t.co resolver for twitter archives
// this script replaces all t.co links in the data/tweets.js file of an unzipped twitter archive with their resolved urls.
// it replaces all text inline, so be sure to make a backup of the file before running.
// usage: deno run -A resolve_tco.js {path to data/tweets.js}
let file = Deno.args[0]
let text = await Deno.readTextFile(file)
let matches = text.match(/"https:\/\/t\.co\/\w+"/g)
let unique = [...new Set(matches)]
console.log('%s urls found.', unique.length)
if (unique.length) for (let match of matches) {
const minute = 60;
const hour = minute * 60;
const day = hour * 24;
const week = day * 7;
const month = day * 30;
const year = day * 365;
/**
* Convert a date to a relative time string, such as
* "a minute ago", "in 2 hours", "yesterday", "3 months ago", etc.
@jacob-ebey
jacob-ebey / image.ts
Last active September 18, 2024 19:12
Remix Image Component
import { createHash } from "crypto";
import fs from "fs";
import fsp from "fs/promises";
import path from "path";
import https from "https";
import { PassThrough } from "stream";
import type { Readable } from "stream";
import type { LoaderFunction } from "remix";
import sharp from "sharp";
import type { Request as NodeRequest } from "@remix-run/node";
@skullface
skullface / lint-autofix.yml
Created November 19, 2021 03:21
Teensy GitHub Action to autofix linting errors (from the script defined in your package.json) per https://mskelton.medium.com/auto-formatting-code-using-prettier-and-github-actions-ed458f58b7df
name: Lint and autofix
on:
pull_request:
branches: [main]
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
function CopyButton({ value }) {
let [copied, setCopied] = React.useState();
let hydrated = usePageIsHydrated();
React.useEffect(() => {
let id = setTimeout(() => setCopied(false), 2000);
return () => clearTimeout(id);
}, [copied]);
return (
<button
@tannerlinsley
tannerlinsley / README.md
Last active April 12, 2024 17:04
Replacing Create React App with the Next.js CLI

Replacing Create React App with the Next.js CLI

How dare you make a jab at Create React App!?

Firstly, Create React App is good. But it's a very rigid CLI, primarily designed for projects that require very little to no configuration. This makes it great for beginners and simple projects but unfortunately, this means that it's pretty non-extensible. Despite the involvement from big names and a ton of great devs, it has left me wanting a much better developer experience with a lot more polish when it comes to hot reloading, babel configuration, webpack configuration, etc. It's definitely simple and good, but not amazing.

Now, compare that experience to Next.js which for starters has a much larger team behind it provided by a world-class company (Vercel) who are all financially dedicated to making it the best DX you could imagine to build any React application. Next.js is the 💣-diggity. It has amazing docs, great support, can grow with your requirements into SSR or static site generation, etc.

So why

import * as React from "react";
import { useMousePosition } from "~/hooks/useMousePosition";
/** Component to cover the area between the mouse cursor and the sub-menu, to allow moving cursor to lower parts of sub-menu without the sub-menu disappearing. */
export function MouseSafeArea(props: { parentRef: React.RefObject<HTMLDivElement> }) {
const { x = 0, y = 0, height: h = 0, width: w = 0 } = props.parentRef.current?.getBoundingClientRect() || {};
const [mouseX, mouseY] = useMousePosition();
const positions = { x, y, h, w, mouseX, mouseY };
return (
<div
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
@State var gradientAngle: Double = 0
var colors = [
Color(UIColor.systemRed),
Color(UIColor.systemOrange),
Color(UIColor.systemYellow),
Color(UIColor.systemGreen),