Skip to content

Instantly share code, notes, and snippets.

View deebloo's full-sized avatar
👋
Hello!

Danny Blue deebloo

👋
Hello!
View GitHub Profile
class MySelectElement extends HTMLElement {
constructor() {
super();
const observer = new MutationObserver((records) => {
for (let record of records) {
this.addItem(record.addedNodes);
this.removeItem(record.removedNodes);
}
});
@deebloo
deebloo / shadow-element.ts
Last active January 25, 2023 22:04
Small utility for apply html template and construct-able stylesheets to custom elements.
import { shadow, ShadowTemplate, html, css } from './shadow.js';
const template: ShadowTemplate = {
css: css`
:host {
display: contents;
}
`.
html: html`
<slot></slot>
function* windowed<T>(arr: T[], size: number) {
for (let i = 0; i < arr.length; i++) {
yield arr.slice(i, size + i);
}
}
let thing = windowed([0, 1, 2, 3], 2);
for (let [a, b] of thing) {
console.log(a, b);
// Freezes document scrolling without remove scrollbar.
// This gets rid of the annoying jump that happens when you set the body overflow to hidden
// Maintains scroll position on the page
export function freezeScroll() {
document.body.style.top = -document.documentElement.scrollTop + 'px';
document.body.style.position = 'fixed';
document.body.style.left = '0';
document.body.style.right = '0';
document.body.style.overflowY = 'scroll';
}
@deebloo
deebloo / focus-trap.ts
Created August 12, 2021 13:01
A utility class for creating and interacting with a focus trap. (ex. keep focus in a modal)
export function getFocusableEls(element: HTMLElement) {
return element.querySelectorAll<HTMLElement>(
'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])'
);
}
export class FocusTrap {
private focusableEls!: NodeListOf<HTMLElement>;
private firstFocusableEl?: HTMLElement;
private lastFocusableEl?: HTMLElement;
import { component, State, handle, JoistElement, get, HandlerCtx } from '@joist/component';
import { template, html } from '@joist/component/lit-html';
@component({
tagName: 'my-counter',
state: 0,
render: template(({ state, run }) => {
return html`
<button @click=${run('dec_btn_clicked', -1)}>-</button>
<span>${state}</span>
import { component, State, handle, JoistElement, get } from '@joist/component';
import { template, html } from '@joist/component/lit-html';
@component({
tagName: 'my-counter',
state: 0,
render: template(({ state, run }) => {
return html`
<button @click=${run('dec_btn_clicked', -1)}>-</button>
<span>${state}</span>
import { component, State, handle, JoistElement, get } from '@joist/component';
import { template, html } from '@joist/component/lit-html';
@component({
tagName: 'my-counter',
state: 0,
render: template(({ state, run }) => {
return html`
<button @click=${run('dec_btn_clicked', -1)}>-</button>
<span>${state}</span>
import { component, State, handle, JoistElement, get } from '@joist/component';
import { template, html } from '@joist/component/lit-html';
@component({
tagName: 'my-counter',
state: 0,
render: template(({ state, run }) => {
return html`
<button @click=${run('decrement')}>-</button>
<span>${state}</span>
import { component, property, JoistElement } from '@joist/component';
function isString(val: unknown) {
if (typeof val === 'string') {
return null;
}
return { message: 'error' };
}