Skip to content

Commit

Permalink
use custom element
Browse files Browse the repository at this point in the history
  • Loading branch information
Lehoczky committed Aug 10, 2024
1 parent 079b37d commit c9edfff
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 49 deletions.
59 changes: 53 additions & 6 deletions packages/demo/src/components/ResizableWindow.astro
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface Props extends HTMLAttributes<"div"> {}
const { class: className, ...attrs } = Astro.props
---

<div
<resizable-window
class={cn(
"flex min-w-[10rem] max-w-[896px] resize-x flex-col overflow-x-auto rounded-xl @container sm:overflow-hidden",
className,
Expand All @@ -19,12 +19,59 @@ const { class: className, ...attrs } = Astro.props
>
<ResizableWindowHeader />

<div
data-resizable-window=""
class="relative grid place-items-stretch bg-base-600"
>
<div data-frame class="relative grid place-items-stretch bg-base-600">
<slot />

<ResizableWindowDimensions class="absolute right-0 top-px" />
</div>
</div>
</resizable-window>

<script>
import { debounce } from "perfect-debounce"

class ResizableWindow extends HTMLElement {
constructor() {
super()

const frame = this.querySelector("[data-frame]")
const dimensionContainer = this.querySelector("[data-dimensions]")

const numberFormatter = Intl.NumberFormat("en", {
maximumFractionDigits: 2,
})
const dimensionText = (width: number, height: number) => {
return `${numberFormatter.format(width)} x ${numberFormatter.format(height)}`
}

const hideDimensionContainer = debounce(
(element: Element) => element.classList.add("invisible"),
1500,
)

// We want to skip the first resize callback, because it fires
// immediately on page load thanks to the iframe content being loaded.
let isFirstUpdate = true

const resizeObserver = new ResizeObserver((entries) => {
if (isFirstUpdate) {
isFirstUpdate = false
return
}

const { width, height } = entries[0].contentRect

if (dimensionContainer) {
dimensionContainer.classList.remove("invisible")
dimensionContainer.textContent = dimensionText(width, height)
hideDimensionContainer(dimensionContainer)
}
})

if (frame) {
resizeObserver.observe(frame)
}
}
}

customElements.define("resizable-window", ResizableWindow)
</script>
43 changes: 0 additions & 43 deletions packages/demo/src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -102,46 +102,3 @@ import DemoSection from "../components/DemoSection.astro"
</div>
</div>
</MainLayout>

<script>
import { debounce } from "perfect-debounce"

const resizableWindows = document.querySelectorAll("[data-resizable-window]")

const numberFormatter = Intl.NumberFormat("en", {
maximumFractionDigits: 2,
})
const dimensionText = (width: number, height: number) => {
return `${numberFormatter.format(width)} x ${numberFormatter.format(height)}`
}

const hideDimensionContainer = debounce(
(element: Element) => element.classList.add("invisible"),
1500,
)

// We want to skip the first resize callback, because it fires
// immediately on page load thanks to the iframe content being loaded.
let isFirstUpdate = true

const resizeObserver = new ResizeObserver((entries) => {
if (isFirstUpdate) {
isFirstUpdate = false
return
}

const entry = entries[0]
const { width, height } = entry.contentRect
const dimensionContainer = entry.target.querySelector("[data-dimensions]")

if (dimensionContainer) {
dimensionContainer.classList.remove("invisible")
dimensionContainer.textContent = dimensionText(width, height)
hideDimensionContainer(dimensionContainer)
}
})

for (const window of resizableWindows) {
resizeObserver.observe(window)
}
</script>

0 comments on commit c9edfff

Please sign in to comment.