Skip to content

Instantly share code, notes, and snippets.

View web-crab's full-sized avatar

Andrey Klimash web-crab

View GitHub Profile
export type EventMap = Record<string, unknown>;
export type Arguments<Arg> = Arg extends void ? [] : [Arg];
export type Listener<Arg> = (...args: Arguments<Arg>) => void;
export class EventEmitter<
Map extends EventMap,
K extends keyof Map = keyof Map,
> {
private map: {
[E in K]?: Set<Listener<Map[E]>>;
import { useEffect, useRef, useState } from 'react';
export function useAbort(init?: (controller: AbortController) => void) {
const [aborter] = useState(() => new AbortController());
const initRef = useRef();
initRef.current = init;
useEffect(() => {
initRef.current?.(aborter);
import { useState, useRef, useCallback } from 'react';
function parseError(error: unknown): Error {
if (error instanceof Error) return error;
if (typeof error === 'string') return new Error(error);
return new Error('Unknown error');
}
export function useAsync<Data, Args extends unknown[]>(
fn: (...params: Args) => Promise<Data>,
<!--
https://csswizardry.com/2020/05/the-fastest-google-fonts/
- 1. Preemptively warm up the fonts’ origin.
-
- 2. Initiate a high-priority, asynchronous fetch for the CSS file. Works in
- most modern browsers.
-
- 3. Initiate a low-priority, asynchronous fetch that gets applied to the page
- only after it’s arrived. Works in all browsers with JavaScript enabled.
-
$min-mobile-width = 320
$max-desktop-width = 1200
html
font-size: 10px
@media (max-width: $min-mobile-width)
font-size calc((100vw / $min-mobile-width) * 10)
@media(orientation: landscape)
font-size calc(10px - (100vw - 100vh) / 100)
import Vue from 'vue'
export default (api) => ({
namespaced: true,
state: {
list: []
},
getters: {
idxMap: state => state.list.reduce((map, { id }, i) => {
map[id] = i
<template functional>
<div class="loader">
<div></div>
<div></div>
<div></div>
</div>
</template>
<style>
@keyframes loader {
^[a-zA-Z0-9!#$%&'*+\\\-/=?^_`{|}~.]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*$
const FOCUSABLE = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"]), [contenteditable]'
export default class Modal {
  constructor (options) {
    const focusableChildren = options.el.querySelectorAll(FOCUSABLE)
    this.el = options.el
    this.activeClass = options.activeClass
    this.firstFocusableChild = focusableChildren[0]
    this.lastFocusableChild = focusableChildren[focusableChildren.length - 1]
    this.elBeforeOpen = null
var names = ['John Doe'];
for (var i = 0; i < names.length; i++) {
app.activeDocument.activeLayer.textItem.contents = names[i];
app.activeDocument.saveAs(
new File('~/Desktop/' + names[i] + '.tif'), 10),
new TiffSaveOptions(),
true
);
}