Skip to content

Instantly share code, notes, and snippets.

@karol-majewski
karol-majewski / getStyles.ts
Created September 28, 2023 09:52
Function composition
import { FlattenSimpleInterpolation } from 'styled-components';
import { pick } from './objects';
type Stylesheet<K extends string> = Record<K, FlattenSimpleInterpolation>;
/**
* CSS-in-JS equivalent for `classNames`.
*
* @example
interface Response<T> {
status: 'success' | 'pending' | 'error';
data: T | null;
}
/**
* A promise tracker that will be updated
* when promise resolves or rejects
*/
const response: Response<unknown> = {
import * as React from 'react';
const NON_BREAKING_SPACE_CHARACTER = '\u00A0';
interface Props {
children: string;
/**
* If the text is shorter than this, it will not be processed.
*/
requiredLength?: number;
import React from 'react';
import createPersistedState from 'use-persisted-state';
import { storage } from '../utilities/storage';
import { hasElements, head, isDefined } from '@rhim/utils';
const usePersistedEntityId = createPersistedState('some-entity-key', storage);
@karol-majewski
karol-majewski / bound.ts
Last active March 30, 2023 13:12
Decorator that binds class methods compatible with TypeScript 5.0
function bound<This extends object, Args extends any[], Return>(
target: (this: This, ...args: Args) => Return,
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
const methodName = String(context.name);
if (context.private) {
throw new Error(`${bound.name} cannot decorate private properties like ${methodName}.`);
}
@karol-majewski
karol-majewski / withValidationState.ts
Created December 20, 2022 16:08
Higher-order adapter for react-aria components used inside Ant Design forms
import React from 'react';
import { Form } from 'antd';
import { ValidationState } from '@react-types/shared';
type PropsAreEqual<P> = (prevProps: Readonly<P>, nextProps: Readonly<P>) => boolean;
/**
* When the wrapped component is placed inside an Ant Design form, this higher-order component
* will grab the validation status from the nearest form field and translate it to `ValidationState`.
*
@karol-majewski
karol-majewski / GenericClassComponent.tsx
Last active December 2, 2022 14:13
The easiest way to use generic Props<T>
import * as React from 'react';
enum Tao { Yin, Yang }
interface Props<T> {
value: T;
onClick(value: T): void;
}
class GenericClassComponent<T> extends React.Component<Props<T>> {
@karol-majewski
karol-majewski / usePrefetch.ts
Last active May 6, 2022 01:23
Easy prefetching with react-query
import { FetchQueryOptions, PayloadType, PrefetchableHook, useQueryClient } from 'react-query';
import { useDeepCompareEffect } from 'react-use';
/**
* Prefetches a query. Cancels any outgoing queries on unmount.
*
* @param hook Hook that returns a `UseQueryResult`.
* @param dependencies List of parameters required to build the key for the hook.
* @param options
*
@karol-majewski
karol-majewski / withProps.ts
Created November 12, 2021 14:47
withProps with support for forwardRef
import * as React from 'react';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function withProps<C extends React.ComponentType<any>, D extends Partial<React.ComponentPropsWithoutRef<C>> & JSX.IntrinsicAttributes>(
Component: C,
defaults: D
): React.ForwardRefExoticComponent<React.PropsWithoutRef<Omit<React.ComponentProps<C>, keyof D>> & React.RefAttributes<React.ElementRef<C>>> {
const renderFunction: React.ForwardRefRenderFunction<React.ElementRef<C>, Omit<React.ComponentProps<C>, keyof D>> = (props, ref) => {
return React.createElement(Component, { ...props, defaults, ref });
};
type NonEmptyArray<T> = [T, ...T[]];
const names: NonEmptyArray<string> = ['Sheldon', 'Leonard', 'Penny', 'Rajesh', 'Howard'];
function main(names: NonEmptyArray<string>, n: number){
let index = n - 1;
while (index >= names.length) {
index = Math.floor((index - names.length) / 2);
}