Skip to content

Instantly share code, notes, and snippets.

@pete-murphy
Last active January 18, 2025 16:37
Show Gist options
  • Save pete-murphy/c2a72fcf55ec93fe6ca3e5ea8c49b57f to your computer and use it in GitHub Desktop.
Save pete-murphy/c2a72fcf55ec93fe6ca3e5ea8c49b57f to your computer and use it in GitHub Desktop.
Custom elements
sentinel props =
Html.Styled.node "intersection-sentinel"
[ Attributes.class "h-8 block"
, Attributes.style "background-color" "red"
, Attributes.disabled props.disabled
, Attributes.attribute "disabled"
(if props.disabled then
"true"
else
"false"
)
, Json.Decode.at [ "detail", "intersectionRatio" ] Json.Decode.float
|> Json.Decode.map props.onIntersect
|> Html.Styled.Events.on "intersection"
]
[]
class IntersectionSentinel extends HTMLElement {
observer: IntersectionObserver | null
constructor() {
super()
this.observer = null
}
static get observedAttributes() {
return ["root", "root-margin", "threshold", "disabled"]
}
connectedCallback() {
this.subscribe()
}
disconnectedCallback() {
this.unsubscribe()
}
attributeChangedCallback(name: string, _: string, newValue: string) {
console.log(name, newValue)
if (name === "disabled") {
if (newValue === "true") {
this.unsubscribe()
} else {
this.subscribe()
}
}
}
subscribe() {
if (this.observer == null) {
const rootAttribute = this.getAttribute("root")
const root =
rootAttribute != null ? document.getElementById(rootAttribute) : null
const rootMargin = this.getAttribute("root-margin") ?? "0px"
const threshold = parseFloat(this.getAttribute("threshold") ?? "0.5")
this.observer = new IntersectionObserver(
(entries) => {
console.log("IntersectionSentinel intersection", entries)
entries.forEach((entry) => {
if (entry.isIntersecting) {
this.dispatchEvent(
new CustomEvent("intersection", {
detail: entry,
})
)
}
})
},
{
root,
rootMargin,
threshold,
}
)
this.observer.observe(this)
}
}
unsubscribe() {
if (this.observer != null) {
this.observer.disconnect()
this.observer = null
}
}
}
customElements.define("intersection-sentinel", IntersectionSentinel)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment