Skip to content

Instantly share code, notes, and snippets.

View guillermodlpa's full-sized avatar

Guillermo guillermodlpa

View GitHub Profile
/**
* A set of utilities to operate with money amounts with decimals
*
* A piece of advice: don't use this! Instead, just work with integer values ALWAYS.
* Even doing the conversion to integer can cause issues (4.02 * 100 = 401.9999)
* So it's better to just always work with integers in a JavaScript/TypeScript codebase.
*
* Cheers
*/
@guillermodlpa
guillermodlpa / HMAC.js
Last active August 20, 2024 19:35 — 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) {