Skip to content

Instantly share code, notes, and snippets.

@thedumbtechguy
Last active June 5, 2024 13:06
Show Gist options
  • Save thedumbtechguy/e7d1480ab11c832442783052510e5745 to your computer and use it in GitHub Desktop.
Save thedumbtechguy/e7d1480ab11c832442783052510e5745 to your computer and use it in GitHub Desktop.
<div data-controller="has-many-panel frame-navigator">
<div class="relative bg-white dark:bg-gray-800 shadow-md sm:rounded-lg my-3 overflow-hidden">
<div class="p-4">
<div class="flex justify-between items-center mb-4">
<h5 class="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
Client admins
</h5>
<div class="flex">
<button title="Back" class="mr-2 text-gray-600 dark:text-gray-300" style="display:none" data-frame-navigator-target="backButton">
<svg class="w-8 h-8" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m14 8-4 4 4 4"/>
</svg>
</button>
<button title="Home" class="mr-2 text-gray-600 dark:text-gray-300" style="display:none" data-frame-navigator-target="homeButton">
<svg class="w-8 h-8" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m4 12 8-8 8 8M6 10.5V19a1 1 0 0 0 1 1h3v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h3a1 1 0 0 0 1-1v-8.5"/>
</svg>
</button>
<button title="Refresh" data-frame-navigator-target="refreshButton" style="display:none" class="text-gray-600 dark:text-gray-300">
<svg class="w-8 h-8" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.651 7.65a7.131 7.131 0 0 0-12.68 3.15M18.001 4v4h-4m-7.652 8.35a7.13 7.13 0 0 0 12.68-3.15M6 20v-4h4"/>
</svg>
</button>
</div>
</div>
<turbo-frame data-frame-navigator-target="frame" loading="lazy" id="9f3d62de496c1a970b7da6a74191a03f" src="https://your_url_goes_here">
<div role="status" class="p-4 space-y-4 border border-gray-200 divide-y divide-gray-200 rounded shadow motion-safe:animate-pulse dark:divide-gray-700 md:p-6 dark:border-gray-700">
<div class="flex items-center justify-between">
<div>
<div class="h-2.5 bg-gray-300 rounded-full dark:bg-gray-600 w-24 mb-2.5"></div>
<div class="w-32 h-2 bg-gray-200 rounded-full dark:bg-gray-700"></div>
</div>
<div class="h-2.5 bg-gray-300 rounded-full dark:bg-gray-700 w-12"></div>
</div>
<div class="flex items-center justify-between pt-4">
<div>
<div class="h-2.5 bg-gray-300 rounded-full dark:bg-gray-600 w-24 mb-2.5"></div>
<div class="w-32 h-2 bg-gray-200 rounded-full dark:bg-gray-700"></div>
</div>
<div class="h-2.5 bg-gray-300 rounded-full dark:bg-gray-700 w-12"></div>
</div>
<span class="sr-only">Loading...</span>
</div>
</turbo-frame>
</div>
</div>
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="frame-navigator"
export default class extends Controller {
static targets = ["frame", "refreshButton", "backButton", "homeButton"];
connect() {
console.log(`frame-navigator connected: ${this.element}`)
this.srcHistory = []
this.originalFrameSrc = this.frameTarget.src
if (this.hasRefreshButtonTarget) {
this.refreshButtonTarget.style.display = ''
this.refreshButtonClicked = this.refreshButtonClicked.bind(this);
this.refreshButtonTarget.addEventListener("click", this.refreshButtonClicked);
}
if (this.hasBackButtonTarget) {
this.backButtonClicked = this.backButtonClicked.bind(this);
this.backButtonTarget.addEventListener("click", this.backButtonClicked);
}
if (this.hasHomeButtonTarget) {
this.homeButtonClicked = this.homeButtonClicked.bind(this);
this.homeButtonTarget.addEventListener("click", this.homeButtonClicked);
}
this.frameLoaded = this.frameLoaded.bind(this);
this.frameTarget.addEventListener("turbo:frame-load", this.frameLoaded);
this.frameLoading = this.frameLoading.bind(this);
this.frameTarget.addEventListener("turbo:click", this.frameLoading);
this.frameTarget.addEventListener("turbo:submit-start", this.frameLoading);
}
disconnect() {
if (this.hasRefreshButtonTarget) this.refreshButtonTarget.removeEventListener("click", this.refreshButtonClicked);
if (this.hasBackButtonTarget) this.backButtonTarget.removeEventListener("click", this.backButtonClicked);
if (this.hasHomeButtonTarget) this.homeButtonTarget.removeEventListener("click", this.homeButtonClicked);
this.frameTarget.removeEventListener("turbo:frame-load", this.frameLoaded);
this.frameTarget.removeEventListener("turbo:click", this.frameLoading);
this.frameTarget.removeEventListener("turbo:submit-start", this.frameLoading);
}
frameLoading(event) {
if (this.hasRefreshButtonTarget) this.refreshButtonTarget.classList.add("motion-safe:animate-spin")
this.frameTarget.classList.add("motion-safe:animate-pulse")
}
frameLoaded(event) {
if (this.hasRefreshButtonTarget) this.refreshButtonTarget.classList.remove("motion-safe:animate-spin")
this.frameTarget.classList.remove("motion-safe:animate-pulse")
let src = event.target.src
if (src == this.currentSrc) {
// this must be a refresh
// do nothing
}
else if (src == this.originalFrameSrc)
this.srcHistory = [src]
else
this.srcHistory.push(src)
this.updateNavigationButtonsDisplay()
}
refreshButtonClicked(event) {
this.frameLoading(null)
this.frameTarget.reload()
}
backButtonClicked(event) {
this.frameLoading(null)
this.srcHistory.pop()
this.frameTarget.src = this.currentSrc
}
homeButtonClicked(event) {
this.frameLoading(null)
this.frameTarget.src = this.originalFrameSrc
}
get currentSrc() { return this.srcHistory[this.srcHistory.length - 1] }
updateNavigationButtonsDisplay() {
if (this.hasHomeButtonTarget) {
this.homeButtonTarget.style.display = this.srcHistory.length > 1 ? '' : 'none'
}
if (this.hasBackButtonTarget) {
this.backButtonTarget.style.display = this.srcHistory.length > 2 ? '' : 'none'
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment