Skip to content

Instantly share code, notes, and snippets.

View SanichKotikov's full-sized avatar
🤔
Working...

Sanich SanichKotikov

🤔
Working...
View GitHub Profile
import boundariesPlugin from 'eslint-plugin-boundaries';
export default {
plugins: {
boundaries: boundariesPlugin,
},
settings: {
'boundaries/elements': [
// segments
{ type: 'type', pattern: 'src/*/type/**' },
@SanichKotikov
SanichKotikov / use-list-state.ts
Last active February 8, 2025 08:42
useListState hook for React
import { type SetStateAction, useMemo, useRef, useState } from "react";
type TListState<T extends object, K extends keyof T, U extends T[K]> = [
items: T[],
handlers: Readonly<{
list: () => T[];
has: (id: U) => boolean;
add: (item: T) => void;
concat: (items: T[]) => void;
clear: VoidFunction;
// utils/types.ts
type KeysOfType<O, T> = { [K in keyof O]: O[K] extends T ? K : never }[keyof O];
// utils/array.ts
function inAbcOrderBy<T extends object, K extends KeysOfType<T, string>>(prop: K) {
return (a: T, b: T): number => {
return (a[prop] as string).localeCompare(b[prop] as string);
};
}
for file in *; do
if [ -f "$file" ]; then
if [ "$file" = "convert_images.sh" ];
then
continue
fi
sips -s format heic -s formatOptions 100 $file --out ./
fi
done
import { createElement, lazy, useEffect, useMemo, ComponentType, ReactElement } from 'react';
export function withAwaitData<T extends {}, K extends keyof T, P extends T[K][]>(
component: ComponentType<T>,
fetcher: (...args: P) => Promise<void>,
keys?: K[],
): (props: T) => ReactElement<T>;
export function withAwaitData<T extends {}, K extends keyof T, P extends T[K][]>(
component: ComponentType<T>,
fetcher: (...args: P) => Promise<void>,
import React, {useEffect, useState, useCallback} from 'react';
import Sticky from 'react-stickynode';
type TFilter = {
name: string;
value: string;
component: React.ReactElement;
};
interface IProps {
function calc(num: number, lines: number = 3) {
const step = (num + (num * 2 / 100)) / lines;
const shift = 10 ** (Math.ceil(Math.log10(Math.ceil(step) + 1)) - 2);
return Math.floor((Math.ceil(step / shift) * shift) * 10) / 10;
}
function round(num: number, low: number) {
return Math.max(calc(num), calc(low * -1));
}
const URL = 'https://www.google-analytics.com/collect';
export function ga(category: string, action: string) {
return new Promise((res) => {
const data = {
v: 1,
tid: 'UA-XXXXX-Y',
t: 'event',
ec: category,
ea: action,
const SECOND = 1000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;
const TIME = {
second: SECOND,
minute: MINUTE,
hour: HOUR,
day: DAY,
performance.mark('custom_start');
// do some staff here...
performance.mark('custom_end');
// https://www.w3.org/TR/navigation-timing/#sec-navigation-timing-interface
performance.measure('custom', 'custom_start', 'custom_end');
performance.clearMeasures('custom');