1
1
<script lang="ts" setup>
2
+ import type { NavListItem } from ' @fiction/core'
2
3
import type { FrameUtility } from ' @fiction/ui/frame/elBrowserFrameUtil'
3
4
import type { Site } from ' ../site'
4
5
import type { FramePostMessageList } from ' ../utils/frame'
5
6
import { toLabel , vue } from ' @fiction/core'
6
7
import XButton from ' @fiction/ui/buttons/XButton.vue'
7
8
import ElTooltip from ' @fiction/ui/common/ElTooltip.vue'
9
+ import XDropDown from ' @fiction/ui/common/XDropDown.vue'
8
10
import ElBrowserFrameDevice from ' @fiction/ui/frame/ElBrowserFrameDevice.vue'
9
11
10
12
const props = defineProps ({
@@ -13,16 +15,20 @@ const props = defineProps({
13
15
14
16
const frameRef = vue .ref <HTMLElement & { frameUtility: FrameUtility <FramePostMessageList > }>() // Reference to the child component
15
17
16
- const deviceModes = [
17
- { name: ' desktop' , icon: ' i-tabler-device-desktop' , wrapClass: ' w-full' },
18
- { name: ' mobile' , icon: ' i-tabler-device-mobile' , wrapClass: ' w-[60%] max-w-sm' },
19
- { name: ' tablet' , icon: ' i-tabler-device-ipad' , wrapClass: ' w-[85%] max-w-xl' },
20
- { name: ' landscape' , icon: ' i-tabler-device-ipad-horizontal' , wrapClass: ' w-[90%] max-w-2xl' },
21
- ] as const
18
+ type DeviceModeKeys = ' desktop' | ' mobile' | ' tablet' | ' landscape'
19
+ const activeDeviceModeKey = vue .ref <DeviceMode >(' desktop' )
20
+ const deviceModes: (NavListItem & { wrapClass: string , value: DeviceModeKeys })[] = [
21
+ { value: ' desktop' , icon: { class: ' i-tabler-device-desktop' }, wrapClass: ' w-full' },
22
+ { value: ' mobile' , icon: { class: ' i-tabler-device-mobile' }, wrapClass: ' w-[60%] max-w-sm' },
23
+ { value: ' tablet' , icon: { class: ' i-tabler-device-ipad' }, wrapClass: ' w-[85%] max-w-xl' },
24
+ { value: ' landscape' , icon: { class: ' i-tabler-device-ipad-horizontal' }, wrapClass: ' w-[90%] max-w-2xl' },
25
+ ]
22
26
23
- type DeviceMode = typeof deviceModes [number ][' name' ]
24
- const activeDeviceMode = vue .ref <DeviceMode >(' desktop' )
25
- const deviceModeConfig = vue .computed (() => deviceModes .find (mode => mode .name === activeDeviceMode .value ))
27
+ const activeDeviceMode = vue .computed (() => deviceModes .find (mode => mode .value === activeDeviceModeKey .value ) || deviceModes [0 ])
28
+
29
+ type DeviceMode = typeof deviceModes [number ][' value' ]
30
+
31
+ const deviceModeConfig = vue .computed (() => deviceModes .find (mode => mode .value === activeDeviceModeKey .value ))
26
32
27
33
// Watch for changes in frameRef and assign frameUtility
28
34
vue .watch (
@@ -60,18 +66,21 @@ function toggleEditingStyle() {
60
66
class =" flex justify-between space-x-2 "
61
67
>
62
68
<div class =" flex items-center gap-2" >
63
- <XButton
64
- v-for =" (mode, i) in deviceModes"
65
- :key =" i"
66
- rounding =" full"
67
- respond =" icon:xl"
68
- :theme =" activeDeviceMode === mode.name ? 'theme' : 'default'"
69
- :icon =" mode.icon"
70
- size =" xs"
71
- @click.stop =" activeDeviceMode = mode.name"
69
+
70
+ <XDropDown
71
+ mode =" click"
72
+ :items =" deviceModes"
73
+ v-model =" activeDeviceModeKey"
72
74
>
73
- {{ toLabel(mode.name) }}
74
- </XButton >
75
+ <XButton
76
+ rounding =" full"
77
+ :icon =" activeDeviceMode?.icon"
78
+ size =" xs"
79
+ icon-after =" i-tabler-chevron-down"
80
+ >
81
+ {{ toLabel(activeDeviceMode?.value) }}
82
+ </XButton >
83
+ </XDropDown >
75
84
</div >
76
85
77
86
<div class =" flex items-center gap-2" >
@@ -142,7 +151,7 @@ function toggleEditingStyle() {
142
151
<div v-if =" site" class =" min-h-0 h-full relative mx-auto pb-10 flex flex-col" :class =" deviceModeConfig?.wrapClass" >
143
152
<ElBrowserFrameDevice
144
153
ref =" frameRef"
145
- :device-mode =" activeDeviceMode "
154
+ :device-mode =" activeDeviceModeKey "
146
155
class =" rounded-md shadow-lg border border-theme-200"
147
156
:url =" site.frame.frameUrl.value"
148
157
frame-id =" site-builder-iframe"
0 commit comments