Last active
March 30, 2024 09:17
-
-
Save Neophen/27a694155c430acfb8e9be3433887a47 to your computer and use it in GitHub Desktop.
LiveView Hooks vs WebComponents
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class MarkoNativeShare extends HTMLElement { | |
pictureElement?: HTMLPictureElement | null | |
images?: HTMLImageElement[] | null | |
loaded = false | |
connectedCallback() { | |
this.pictureElement = this.querySelector('picture') | |
if (!this.pictureElement) { | |
throw new Error('<x-image>: requires a <picture> element') | |
} | |
this.images = Array.from(this.pictureElement.querySelectorAll('img')) | |
if (this.images.length === 0) { | |
throw new Error('<x-image>: requires an <img> element inside <picture>') | |
} | |
const complete = this.images.some((image) => image.complete) | |
if (complete) { | |
this.onLoad() | |
} else { | |
this.images.forEach((image) => { | |
image.addEventListener('load', this.onLoad) | |
}) | |
} | |
} | |
disconnectedCallback() { | |
this.onLoad() | |
} | |
onLoad = () => { | |
if (this.loaded || !this.pictureElement) return | |
this.loaded = true | |
this.images?.forEach((image) => image.removeEventListener('load', this.onLoad)) | |
this.pictureElement?.style.setProperty('--preview-image', 'none') | |
this.pictureElement = null | |
this.images = null | |
} | |
} | |
customElements.define('marko-image', MarkoNativeShare) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class XCounter extends HTMLElement { | |
connectedCallback() { | |
this.inputElement = this.querySelector('input') ?? this.querySelector('textarea') | |
if (!this.inputElement) { | |
throw new Error('<x-counter>: requires an <input> or a <textarea> element') | |
} | |
this.counterElement = this.querySelector('[x-counter-value]') | |
if (!this.counterElement) { | |
throw new Error('<x-counter>: requires an element with the [x-counter-value] attribute') | |
} | |
this.inputElement.addEventListener('input', this.onInput) | |
this.onInput() | |
} | |
disconnectedCallback() { | |
this.inputElement?.removeEventListener('input', this.onInput) | |
} | |
onInput = () => { | |
this.counterElement.textContent = this.inputElement?.value?.length ?? 0 | |
} | |
} | |
customElements.define('x-counter', XCounter) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ViewHook } from 'phoenix_live_view' | |
const XImage: Partial<ViewHook> & { | |
pictureElement?: HTMLPictureElement | |
image?: HTMLImageElement | null | |
init: () => void | |
onLoad: () => void | |
} = { | |
mounted() { | |
this.init() | |
}, | |
updated() { | |
this.destroyed?.() | |
this.init() | |
}, | |
destroyed() { | |
if (!this.image) return | |
this.image.removeEventListener('load', this.onLoad) | |
this.image = undefined | |
this.pictureElement = undefined | |
}, | |
// ___________________________________________________________________________________________________________________ | |
init() { | |
this.pictureElement = this.el | |
if (!(this.pictureElement instanceof HTMLPictureElement)) return | |
this.onLoad = this.onLoad.bind(this) | |
this.image = this.pictureElement.querySelector('img') | |
if (!this.image) return | |
if (this.image.complete) { | |
this.onLoad() | |
return | |
} | |
this.image.addEventListener('load', this.onLoad) | |
}, | |
onLoad() { | |
if (!this.pictureElement) return | |
if (this.image) { | |
this.image.removeEventListener('load', this.onLoad) | |
} | |
this.pictureElement.style.setProperty('--preview-image', 'none') | |
} | |
} | |
export default XImage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment