Skip to content

Instantly share code, notes, and snippets.

View audunolsen's full-sized avatar
🌷
Made a new avatar with Midjourney lmao

Audun Meek Olsen audunolsen

🌷
Made a new avatar with Midjourney lmao
View GitHub Profile
@audunolsen
audunolsen / containers.scss
Created December 10, 2022 02:02
Solution: The CSS container "inside" problem
/*
Best solution I've so far come up with for
the inner/outer container issue.
https://css-tricks.com/the-inside-problem/
*/
@mixin default($width: 500px, $padding: 30px) {
width: 100%;
// Intentionally does not use shorthand as it would easily collide
@audunolsen
audunolsen / zod-generic-parser.ts
Created November 28, 2022 11:26
Just an idea for utilizing zod in a generic manner
import * as z from 'zod'
import { Schema } from 'zod'
export async function parse<T extends Schema>(
schema: T | ((zod: typeof z) => T),
) {
const codec = schema instanceof Schema ? schema : schema(z)
return async function (input: Response) {
const json = await input.json()
/* eslint-disable prettier/prettier */
// type Input = { code : ErrorMessageKind } | { code: 'illegalWeekday', weekday?: string }
// code: 'illegalEmailDomain', email: string, allowedDomains: string[]
type ErrorMessageKind = "networkError" | "generalError" | 'illegalWeekday'
interface Message {
NO: string
EN: string
}
const sortDevices = (devices: MediaDeviceInfo[]) =>
devices.reduce<Record<MediaDeviceKind, MediaDeviceInfo[]>>(
(a, d) => (a[d.kind].push(d), a),
{
videoinput: [],
audioinput: [],
audiooutput: [],
},
)
@audunolsen
audunolsen / usePortal.ts
Created December 6, 2021 08:59
usePortalV2.tsx
/*
Benefits over v1:
1. No intermidiate portal div. The portal is the immidiate descendant of the parent/mounting div
2. Portal element can be rendered as any valid React.ElementType
3. Portal can be given ref
4. Portal can be given a className and any other valid html attribute
5. Portal supports fully reactive classes for both body and parent divs. (Useful for locking scroll etc…)
6. More flexible mounting options. can e.g. list many fallbacks. Mount will update on subsequent portal openings if dom changes
import React, { createElement } from "react";
/*
Tired of writing ((blabla && blabla) && <>blabla</>)
*/
interface Props extends React.HTMLAttributes<HTMLElement> {
if: any;
as?: React.ElementType;
children?: React.ReactNode;
@audunolsen
audunolsen / Icon.tsx
Created November 4, 2021 12:05
Dynamically import SVG files as React components
import React, { useState, useEffect } from "react";
import { err } from "src/utils/async";
interface Props extends React.SVGProps<SVGSVGElement> {
// path relative to src/assets/icons. omit svg extension
name: string;
}
interface Module {
default: React.FC<React.SVGProps<SVGSVGElement>>;
@audunolsen
audunolsen / useIntersectionObserver.js
Last active July 1, 2021 10:24
useIntersectionObserver hook with additional extended data regarding element visibility
import { useCallback, useEffect, useMemo, useRef } from 'react';
import visibility from './visibility';
import debounceFn from 'lodash.debounce';
import throttleFn from 'lodash.throttle';
/*
Performance tip:
Rememeber to memoize the callback! (or any other dynamic config opts)
Or else every re-render will trigger a cb dependency
update deleting and reinstantiating the observers
import { useCallback } from 'react';
import useResizeObserver from 'hooks/useResizeObserver';
export default () => {
const onResize = useCallback((entries = []) => {
console.log(entries.map(e => e.target));
}, []);
const [observerRef, setObserverRef] = useResizeObserver({
@audunolsen
audunolsen / fetch-data.js
Last active May 6, 2022 07:14
For when you don't know the response type
/*
Needed in evaluation/Form.js because successful calls to server but
w/ empty data (null from java which fetch retrieves as empty string)
will throw errors because fetch can't parse it as json.
Retrieves either json or text depending on what's available
Didn't change already existing fetchJson to not
risk breaking any exisitng api calls
*/