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;
@deebloo
deebloo / web-component.js
Last active January 4, 2021 12:34
A pattern for creating vanilla web components. no library. just a pattern I am rolling around.
(function () {
expose('createMyComponent', register, factory);
/**
* Exposes your new component to the window or to a module
*
* @param {string} name - the factory name to expose
* @param {function} definition - the definition of your web component. registers to the document
* @param {function} factory - method for programmatically creating web component
*/
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, JoistElement, property, get, PropChange } from '@joist/component';
@component({
tagName: 'app-root',
state: ''
})
class AppElement extends JoistElement {
@get(State)
private state!: State<string>;
import { component, State, handle, JoistElement, get } from '@joist/component';
import { template, html } from '@joist/component/lit-html';
@component<number>({
tagName: 'app-root',
state: 0,
render: template(({ state, run }) => {
return html`
<button @click=${run('dec')}>-</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>