Skip to content

Instantly share code, notes, and snippets.

View guillermodlpa's full-sized avatar

Guillermo guillermodlpa

View GitHub Profile
@guillermodlpa
guillermodlpa / HMAC.js
Last active April 23, 2024 11:10 — forked from stevendesu/HMAC.js
A simple, open-source, HMAC-SHA256 implementation in pure TypeScript. Designed for efficient minification.
// From https://gist.github.com/stevendesu/2d52f7b5e1f1184af3b667c0b5e054b8
// To ensure cross-browser support even without a proper SubtleCrypto
// impelmentation (or without access to the impelmentation, as is the case with
// Chrome loaded over HTTP instead of HTTPS), this library can create SHA-256
// HMAC signatures using nothing but raw JavaScript
/* eslint-disable no-magic-numbers, id-length, no-param-reassign, new-cap */
// By giving internal functions names that we can mangle, future calls to
@guillermodlpa
guillermodlpa / useAutoplay.ts
Created August 21, 2023 10:49
hook to autoplay a video
import { MutableRefObject, useEffect } from 'react';
const AUTO_PLAY_DELAY = 1500;
const PLAY_ERROR_NO_INTERACTION =
"play() failed because the user didn't interact with the document first";
export default function useAutoplay(
videoRef: MutableRefObject<HTMLVideoElement | HTMLAudioElement | undefined>,
isActive: boolean,
) {
@guillermodlpa
guillermodlpa / useResponsiveGridWithLastRowCentering.tsx
Last active September 8, 2023 10:21
React hook to render a responsive CSS grid centering the elements in the last row
import useBreakpointValueWithDeviceType from '@/hooks/useBreakpointValueWithUADetection/useBreakpointValueWithDeviceType';
import { BoxProps } from '@chakra-ui/react';
import { useMemo } from 'react';
// Controlling Leftover Grid Items with Pseudo-selectors
// @see https://css-irl.info/controlling-leftover-grid-items/
function generateCenteredGridStyles(columnCount: number): BoxProps['sx'] {
const itemStyles: Record<string, string | Record<string, string>> = {
gridColumn: 'span 2',
@guillermodlpa
guillermodlpa / Compose.tsx
Created August 7, 2023 08:41
Component to compose context providers and pass separate props to each of them
type Components =
| React.ElementType
| [React.ElementType, { [key: string]: unknown }];
const Compose = ({
components,
children,
}: {
components: Components[];
children: JSX.Element;
export default function composeContextProviders(providers: React.ElementType[]) {
return providers.reduce(
(Prev, Curr) =>
function ComposedProviderWrapper({ children }) {
return (
<Prev>
<Curr>{children}</Curr>
</Prev>
);
},
@guillermodlpa
guillermodlpa / createDialogContext.tsx
Created July 6, 2023 09:58
Utility function to create a dialog context in MUI v5, for dialogs opened across the application that need their state in context
import { createContext, useContext, useState } from 'react';
class NoContextProviderError extends Error {
constructor() {
super('Context value was undefined');
}
}
/**
* Utility to create a context for a dialog, to reduce boilerplate
/**
* Get the dimensions of an image file
* Check the mime type before calling this function
*/
export default function getImageFileDimensions(
imageFile: File,
): Promise<{ width: number; height: number }> {
return new Promise((resolve, reject) => {
if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
reject(
@guillermodlpa
guillermodlpa / marketing-site-render.ts
Created June 6, 2023 15:22
Next.js API route that fetches a page from another site and renders it. Combined with a rewrite fallback rule, this can help integrate pages from a CMS into a Next.js app
import type { NextApiRequest, NextApiResponse } from 'next';
function replaceUrlsInHtmlPage(htmlPage: string, urls: string[], newUrl: string) {
return urls.reduce((memo, url) => memo.replace(new RegExp(url, 'g'), newUrl), htmlPage);
}
/**
* This endpoint is used as a fallback for any route that is not handled by Next.js.
* This way, we can mix a marketing site hosted in WordPress and the app in the same domain
*/
@guillermodlpa
guillermodlpa / smoothScroll.ts
Last active June 13, 2023 10:37
smooth scroll function. native scrollTo or scrollIntoView conflict with each other if there are different horizontal and vertical scrolls happening
/**
* Inspired by https://codepen.io/oxleberry/pen/BOEBaB
*
* With added support for horizontal scrolling, scrolling the window, and linear easing
*
* native scrollTo or scrollIntoView conflict with each other if there are different horizontal and vertical scrolls happening
*/
// Easing equations, http://www.gizma.com/easing/
function easeOutCubic(t: number, b: number, c: number, d: number) {
@guillermodlpa
guillermodlpa / export_env_vars.sh
Created March 7, 2023 13:25
Exports a list of env vars to the environment, supporting spaces, newline chars and quotes in the value
#!/bin/sh
# wraps the env var values in quotes and handles newlines
# It's a more sohisticated version from just doing export $($ENV_VARS)
# and it doesn't break with newline characters, quotes or spaces in the values (note the encoding with sed)
eval "$(
printf '%s\n' "$ENV_VARS" | while IFS='' read -r line; do
key=$(printf '%s\n' "$line"| sed 's/"/\\"/g' | cut -d '=' -f 1)
value=$(printf '%s\n' "$line" | cut -d '=' -f 2- | sed 's/"/\\\"/g')