Skip to content

Instantly share code, notes, and snippets.

View andrelandgraf's full-sized avatar
🎯
Focusing

Andre andrelandgraf

🎯
Focusing
View GitHub Profile
@andrelandgraf
andrelandgraf / markdown.tsx
Last active June 15, 2022 03:20
How to process markdown without async code to make it work with server-side React and common-js (e.g. in Remix.run)
/*
* DEPRECATION NOTICE: This workaround is no longer needed. You can now use ESM packages with Remix by
* tracking all ESM packages in your remix.config.js file. This means we can now use react-markdown
* and are not required to reimplement everything from scratch.
* Find a nice example implementation here: https://stackblitz.com/edit/node-ydjuwx?file=remix.config.js
*/
/*
* react-remark does not support cjs anymore but Remix.run will not work with esm just yet (without async imports)
* Unfortunately, the older versions of react-remark do not implement useRemarkSync
@andrelandgraf
andrelandgraf / useLoaderStore.ts
Last active November 19, 2022 06:52
Wrapper hook for useMatches to quickly access loader data across components in Remix.run
import { useMatches } from 'remix';
// this base hook is used in other hooks to quickly search for specific data across all loaderData using useMatches
// see in action: https://codesandbox.io/s/usematches-loader-data-2h798?file=/app/db.server.ts
export default function useLoaderStore<T>(key: string): T | undefined {
const matchingRoutes = useMatches();
const route = matchingRoutes.find((route) => route.data && route.data[key]);
if (!route || !route.data || route.data[key] === undefined) {
return undefined;
}
@andrelandgraf
andrelandgraf / pre.tsx
Created December 26, 2021 17:35
PrismJS custom component
​import​ ​type​ ​{​ ​FC​,​ ​HTMLAttributes​,​ ​ReactElement​ ​}​ ​from​ ​'react'​;
​import​ ​{​ ​Children​ ​}​ ​from​ ​'react'​;
​import​ ​invariant​ ​from​ ​'tiny-invariant'​;
​import​ ​Highlight​,​ ​{​ ​Language​,​ ​defaultProps​ ​}​ ​from​ ​'prism-react-renderer'​;
​import​ ​CopyClipboardButton​ ​from​ ​'../button/copyClipboardButton'​;
​function​ ​getLanguageFromClassName​(​className​: ​string​)​ ​{
​  ​const​ ​match​ ​=​ ​className​.​match​(​/​language-​(​\w​+​)​/​)​;
​  ​return​ ​match​ ? ​match​[​1​]​ : ​''​;
@andrelandgraf
andrelandgraf / createSitemap.ts
Last active January 29, 2024 08:36
sitemap.xml generator for remix.run
import childProcess from 'child_process';
import fs from 'fs';
import dotenv from 'dotenv';
import prettier from 'prettier';
const rootDir = process.cwd();
dotenv.config({
path: `${rootDir}/.env.production`,
});
@andrelandgraf
andrelandgraf / useErrorNotifications.tsx
Last active July 6, 2021 20:54
Communication of status / errors codes between client and server via URLSearchParams
import { useCallback, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
export default function useErrorNotifications() {
const { pushNotification } = useContext(NotificationsContext);
const [searchParams, setSearchParams] = useSearchParams();
const errorCode = searchParams.get('error');
const onClose = useCallback(() => {
searchParams.delete('error');
@andrelandgraf
andrelandgraf / form.tsx
Last active December 28, 2021 18:35
working with URLSearchParams in remix.run
import { Form as RemixForm } from 'remix';
import type { FC } from 'react';
import type { FormProps, Request } from 'remix';
type FormReqBody = { method: 'get' | 'post' | 'put' | 'delete' } & Record<string, string>;
export async function parseURLSearchParams(request: Request): Promise<Partial<FormReqBody>>;
export async function parseURLSearchParams<ReqBody>(request: Request): Promise<Partial<ReqBody & FormReqBody>>;
@andrelandgraf
andrelandgraf / index.js
Last active July 29, 2018 16:38
working over arrays with for loops in js
// summarized and added comments, original source: https://es6.io/ course by Wes Bos
// messing with the prototype
Array.prototype.myFunction = function(){
// add some array functionality
};
// initialising our array
const names = ["Alice", "Foo", "Bar", "Jon Doe"];
// adding some further properties
@andrelandgraf
andrelandgraf / index.js
Last active July 30, 2018 20:27
working with function expressions and chaining of promises
/*
* working with resolve()
*/
const doSomethingChained = (name) => {
console.log('1');
return new Promise((resolve, reject) => setTimeout(() => {console.log(name); resolve();}, 1500, name));
};
doSomethingChained('Alice').then(() => {
console.log('2');
@andrelandgraf
andrelandgraf / index.js
Last active July 29, 2018 15:50
working with async await
/**
* implementing return value of setTimeout() from callback to promise
* @param ms
* @returns {Promise<function>}
*/
const sleep = function (ms) {
// 4.) task 1: we create a new promise and call setTimeout(),
// set timeout creates a new taks 2 that will run after taks 1 has finished & 1500 milliseconds have passed
// new Promise(function(resolve, reject) { ... });
return new Promise(resolve => {
@andrelandgraf
andrelandgraf / index.js
Created July 29, 2018 15:44
timeout and the event loop
/*
* what happens if task 1 takes longer than 1500 milliseconds to be executed? Does task 2 has to wait?
*/
function doSomethingLonger(name, callback){
// 2.) task 1: we execute console.log('1');
console.log('1');
// 3.) task 1: we execute setTimeout. Set timeout creates a new task (task 2) that will be executed in 1500 milliseconds from now on
setTimeout(callback, 1500, name);
// 4.) task 1: we execute console.log('2');
while(true);