Skip to content

Commit 9805355

Browse files
committed
feat(hub-ui): extract iframe loading placeholder into a storied component
1 parent fb45bcf commit 9805355

3 files changed

Lines changed: 48 additions & 9 deletions

File tree

packages/hub-ui/src/client/components/views/ViewIframe.vue

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { DEVFRAME_REMOTE_ASSETS_ERROR_MESSAGE_TYPE, REMOTE_CONNECTION_KEY } from
88
import { computed, nextTick, onMounted, onUnmounted, ref, useTemplateRef, watchEffect } from 'vue'
99
import { sharedStateToRef } from '../../state/docks'
1010
import ViewAssetsError from './ViewAssetsError.vue'
11+
import ViewIframeLoading from './ViewIframeLoading.vue'
1112
1213
const props = defineProps<{
1314
context: DocksContext
@@ -383,15 +384,7 @@ onUnmounted(() => {
383384
ref="viewFrame"
384385
class="devframes-view-iframe relative w-full h-full flex-1 items-center justify-center"
385386
>
386-
<div
387-
v-if="showLoadingPlaceholder"
388-
class="devframes-view-iframe-loading absolute inset-0 flex flex-col items-center justify-center gap-2 bg-base"
389-
>
390-
<div class="i-ph:circle-notch-duotone animate-spin text-3xl color-faint" />
391-
<div class="text-sm color-muted">
392-
Loading…
393-
</div>
394-
</div>
387+
<ViewIframeLoading v-if="showLoadingPlaceholder" />
395388
<ViewAssetsError
396389
v-if="assetsError"
397390
:error="assetsError"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
2+
import { h } from 'vue'
3+
import ViewIframeLoading from './ViewIframeLoading.vue'
4+
5+
// The placeholder fills its positioned parent (`absolute inset-0`), so the
6+
// stage mirrors the iframe view frame it renders into at runtime.
7+
function stage(children: any) {
8+
return h('div', { class: 'relative h-100 bg-base color-base border border-base rounded-lg overflow-hidden font-sans' }, children)
9+
}
10+
11+
const meta = {
12+
title: 'Views/IframeLoading',
13+
component: ViewIframeLoading,
14+
tags: ['autodocs'],
15+
parameters: {
16+
docs: {
17+
description: {
18+
component: 'Shown over an iframe view while it loads its content. A blank iframe paints white during load, so `ViewIframe` reveals this placeholder by hiding the pane — the same layering trick as the assets-error panel. It covers the initial load and any hard navigation or refresh.',
19+
},
20+
},
21+
},
22+
} satisfies Meta
23+
24+
export default meta
25+
type Story = StoryObj
26+
27+
export const Loading: Story = {
28+
render: () => ({
29+
setup: () => () => stage(h(ViewIframeLoading)),
30+
}),
31+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
// Placeholder shown while an iframe view loads its content. A blank iframe
3+
// paints white during load, so this is only visible once the pane steps aside
4+
// (`pane.hide()` in `ViewIframe`) — the same layering trick `ViewAssetsError`
5+
// relies on. It covers the initial load and any hard navigation/refresh.
6+
</script>
7+
8+
<template>
9+
<div class="devframes-view-iframe-loading absolute inset-0 flex flex-col items-center justify-center gap-2 bg-base">
10+
<div class="i-ph:circle-notch-duotone animate-spin text-3xl color-faint" />
11+
<div class="text-sm color-muted">
12+
Loading…
13+
</div>
14+
</div>
15+
</template>

0 commit comments

Comments
 (0)