mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
133 lines
3.6 KiB
Vue
133 lines
3.6 KiB
Vue
<script setup lang="ts">
|
|
import type { ViewportSize } from '~/composables/browser'
|
|
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
|
import { viewport } from '~/composables/browser'
|
|
import { browserState } from '~/composables/client'
|
|
import {
|
|
detailsPanelVisible,
|
|
detailsPosition,
|
|
panels,
|
|
showNavigationPanel,
|
|
updateBrowserPanel,
|
|
} from '~/composables/navigation'
|
|
import IconButton from './IconButton.vue'
|
|
|
|
const sizes: Record<ViewportSize, [width: number, height: number]> = {
|
|
'small-mobile': [320, 568],
|
|
'large-mobile': [414, 896],
|
|
'tablet': [834, 1112],
|
|
}
|
|
|
|
function isViewport(name: ViewportSize) {
|
|
const preset = sizes[name]
|
|
return viewport.value[0] === preset[0] && viewport.value[1] === preset[1]
|
|
}
|
|
|
|
async function changeViewport(name: ViewportSize) {
|
|
viewport.value = sizes[name]
|
|
if (browserState?.provider === 'webdriverio') {
|
|
updateBrowserPanel()
|
|
}
|
|
}
|
|
|
|
const testContainer = useTemplateRef('tester-ui')
|
|
const testContainerRect = ref<DOMRectReadOnly | null>(null)
|
|
|
|
const observer = new ResizeObserver(([entry]) => {
|
|
testContainerRect.value = entry.contentRect
|
|
})
|
|
onMounted(() => {
|
|
if (testContainer.value) {
|
|
observer.observe(testContainer.value)
|
|
}
|
|
})
|
|
onUnmounted(() => {
|
|
observer.disconnect()
|
|
})
|
|
|
|
const scale = computed(() =>
|
|
testContainerRect.value
|
|
? Math.floor(
|
|
Math.min(
|
|
testContainerRect.value.width / viewport.value[0],
|
|
testContainerRect.value.height / viewport.value[1],
|
|
) * 100,
|
|
)
|
|
: 100,
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<div id="browser-frame" h="full" flex="~ col">
|
|
<div p="3" h-10 flex="~ gap-2" items-center bg-header border="b base">
|
|
<IconButton
|
|
v-show="panels.navigation <= 15"
|
|
v-tooltip.bottom="'Show Navigation Panel'"
|
|
title="Show Navigation Panel"
|
|
rotate-180
|
|
icon="i-carbon:side-panel-close"
|
|
@click="showNavigationPanel()"
|
|
/>
|
|
<div class="i-carbon-content-delivery-network" />
|
|
<span pl-1 font-bold text-sm flex-auto ws-nowrap overflow-hidden truncate>Browser UI</span>
|
|
<IconButton
|
|
v-show="detailsPosition === 'right' && !detailsPanelVisible"
|
|
v-tooltip.bottom="'Show Details Panel'"
|
|
title="Show Details Panel"
|
|
icon="i-carbon:side-panel-close"
|
|
@click="detailsPanelVisible = true"
|
|
/>
|
|
</div>
|
|
<div p="l3 y2 r2" flex="~ gap-2" items-center bg-header border="b-2 base">
|
|
<!-- TODO: these are only for preview (thank you Storybook!), we need to support more different and custom sizes (as a dropdown) -->
|
|
<IconButton
|
|
v-tooltip.bottom="'Small mobile'"
|
|
title="Small mobile"
|
|
icon="i-carbon:mobile"
|
|
:active="isViewport('small-mobile')"
|
|
@click="changeViewport('small-mobile')"
|
|
/>
|
|
<IconButton
|
|
v-tooltip.bottom="'Large mobile'"
|
|
title="Large mobile"
|
|
icon="i-carbon:mobile-add"
|
|
:active="isViewport('large-mobile')"
|
|
@click="changeViewport('large-mobile')"
|
|
/>
|
|
<IconButton
|
|
v-tooltip.bottom="'Tablet'"
|
|
title="Tablet"
|
|
icon="i-carbon:tablet"
|
|
:active="isViewport('tablet')"
|
|
@click="changeViewport('tablet')"
|
|
/>
|
|
<span class="pointer-events-none" text-sm>
|
|
{{ viewport[0] }}x{{ viewport[1] }}px
|
|
<span v-if="scale < 100">({{ scale }}%)</span>
|
|
</span>
|
|
</div>
|
|
<div id="tester-ui" ref="tester-ui">
|
|
Select a test to run
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
#tester-ui {
|
|
height: 100%;
|
|
container-type: size;
|
|
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
#tester-ui:not([data-ready]) {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
opacity: 0.7;
|
|
|
|
font-weight: 300;
|
|
}
|
|
</style>
|