Swoff Swoff

Components

UI components for Swoff — UpdatePrompt, SWProgressBar, InstallButton.

Svelte Components

These components use Svelte stores to provide ready-to-use UI elements. See Component Specs for behavioral details.

UpdatePrompt

@/components/UpdatePrompt.svelte
<script>
import { updateStatus, availableVersion, currentVersion, progress, forceUpdate, acceptUpdate, dismissUpdate } from '../stores/pwaUpdate'
</script>

{#if $updateStatus !== 'idle'}
  <div class="update-prompt {$forceUpdate ? 'fullscreen' : 'bottom-sheet'}">
    <p>Update available: v{$currentVersion} → v{$availableVersion}</p>
    {#if $updateStatus === 'downloading'}
      <div class="progress-bar" style="width: {$progress}%" />
    {:else}
      <button on:click={acceptUpdate}>Update</button>
      {#if !$forceUpdate}
        <button on:click={dismissUpdate}>Later</button>
      {/if}
    {/if}
  </div>
{/if}

SWProgressBar

@/components/SWProgressBar.svelte
<script>
import { progress, status } from '../stores/swProgress'
</script>

{#if $status === 'installing'}
  <div class="fixed top-0 left-0 w-full h-1 bg-gray-200">
    <div class="h-full bg-blue-500 transition-all" style="width: {$progress}%" />
  </div>
{/if}

InstallButton

@/components/InstallButton.svelte
<script>
import { onMount } from 'svelte'

let deferredPrompt = null

onMount(() => {
  window.addEventListener('beforeinstallprompt', (e) => {
    e.preventDefault()
    deferredPrompt = e
  })
})

async function handleInstall() {
  if (!deferredPrompt) return
  deferredPrompt.prompt()
  const { outcome } = await deferredPrompt.userChoice
  if (outcome === 'accepted') deferredPrompt = null
}
</script>

{#if deferredPrompt}
  <button on:click={handleInstall}>Install App</button>
{/if}

Next Steps

On this page