11'use client'
22
3- import { createContext , useContext , useState , useCallback , useMemo , useRef , type ReactNode } from 'react'
4-
5- export type DeviceFrame = 'responsive' | 'iphone-15' | 'pixel-8' | 'ipad-air' | 'macbook-14' | 'desktop-1080'
3+ import {
4+ createContext ,
5+ useContext ,
6+ useState ,
7+ useCallback ,
8+ useMemo ,
9+ useRef ,
10+ type ReactNode ,
11+ } from 'react'
12+
13+ export type DeviceFrame =
14+ | 'responsive'
15+ | 'iphone-15'
16+ | 'pixel-8'
17+ | 'ipad-air'
18+ | 'macbook-14'
19+ | 'desktop-1080'
620
721export interface DeviceSpec {
822 id : DeviceFrame
@@ -15,12 +29,60 @@ export interface DeviceSpec {
1529}
1630
1731export const DEVICES : DeviceSpec [ ] = [
18- { id : 'responsive' , label : 'Responsive' , width : 0 , height : 0 , scale : 1 , bezel : false , icon : 'lucide:maximize' } ,
19- { id : 'iphone-15' , label : 'iPhone 15' , width : 393 , height : 852 , scale : 0.7 , bezel : true , icon : 'lucide:smartphone' } ,
20- { id : 'pixel-8' , label : 'Pixel 8' , width : 412 , height : 915 , scale : 0.7 , bezel : true , icon : 'lucide:smartphone' } ,
21- { id : 'ipad-air' , label : 'iPad Air' , width : 820 , height : 1180 , scale : 0.5 , bezel : true , icon : 'lucide:tablet' } ,
22- { id : 'macbook-14' , label : 'MacBook 14"' , width : 1512 , height : 982 , scale : 0.45 , bezel : true , icon : 'lucide:laptop' } ,
23- { id : 'desktop-1080' , label : '1080p' , width : 1920 , height : 1080 , scale : 0.4 , bezel : false , icon : 'lucide:monitor' } ,
32+ {
33+ id : 'responsive' ,
34+ label : 'Responsive' ,
35+ width : 0 ,
36+ height : 0 ,
37+ scale : 1 ,
38+ bezel : false ,
39+ icon : 'lucide:maximize' ,
40+ } ,
41+ {
42+ id : 'iphone-15' ,
43+ label : 'iPhone 15' ,
44+ width : 393 ,
45+ height : 852 ,
46+ scale : 0.7 ,
47+ bezel : true ,
48+ icon : 'lucide:smartphone' ,
49+ } ,
50+ {
51+ id : 'pixel-8' ,
52+ label : 'Pixel 8' ,
53+ width : 412 ,
54+ height : 915 ,
55+ scale : 0.7 ,
56+ bezel : true ,
57+ icon : 'lucide:smartphone' ,
58+ } ,
59+ {
60+ id : 'ipad-air' ,
61+ label : 'iPad Air' ,
62+ width : 820 ,
63+ height : 1180 ,
64+ scale : 0.5 ,
65+ bezel : true ,
66+ icon : 'lucide:tablet' ,
67+ } ,
68+ {
69+ id : 'macbook-14' ,
70+ label : 'MacBook 14"' ,
71+ width : 1512 ,
72+ height : 982 ,
73+ scale : 0.45 ,
74+ bezel : true ,
75+ icon : 'lucide:laptop' ,
76+ } ,
77+ {
78+ id : 'desktop-1080' ,
79+ label : '1080p' ,
80+ width : 1920 ,
81+ height : 1080 ,
82+ scale : 0.4 ,
83+ bezel : false ,
84+ icon : 'lucide:monitor' ,
85+ } ,
2486]
2587
2688export const ZOOM_MIN = 0.1
@@ -55,7 +117,7 @@ interface PreviewContextValue {
55117const PreviewContext = createContext < PreviewContextValue | null > ( null )
56118
57119export function PreviewProvider ( { children } : { children : ReactNode } ) {
58- const [ previewUrl , setPreviewUrl ] = useState ( 'http://localhost:3000 ' )
120+ const [ previewUrl , setPreviewUrl ] = useState ( 'http://localhost:3080 ' )
59121 const [ visible , setVisible ] = useState ( false )
60122 const [ pip , setPip ] = useState ( false )
61123 const [ activeDevice , setActiveDevice ] = useState < DeviceFrame > ( 'responsive' )
@@ -66,11 +128,10 @@ export function PreviewProvider({ children }: { children: ReactNode }) {
66128 const [ panY , setPanY ] = useState ( 0 )
67129 const fitToScreenRef = useRef < ( ( ) => void ) | null > ( null )
68130
69-
70- const refresh = useCallback ( ( ) => setRefreshKey ( k => k + 1 ) , [ ] )
131+ const refresh = useCallback ( ( ) => setRefreshKey ( ( k ) => k + 1 ) , [ ] )
71132
72133 const setZoom = useCallback ( ( z : number | ( ( prev : number ) => number ) ) => {
73- setZoomRaw ( prev => {
134+ setZoomRaw ( ( prev ) => {
74135 const next = typeof z === 'function' ? z ( prev ) : z
75136 return Math . round ( Math . min ( ZOOM_MAX , Math . max ( ZOOM_MIN , next ) ) * 100 ) / 100
76137 } )
@@ -88,15 +149,15 @@ export function PreviewProvider({ children }: { children: ReactNode }) {
88149 } , [ ] )
89150
90151 const zoomIn = useCallback ( ( ) => {
91- setZoom ( prev => {
92- const next = ZOOM_PRESETS . find ( p => p > prev + 0.01 )
152+ setZoom ( ( prev ) => {
153+ const next = ZOOM_PRESETS . find ( ( p ) => p > prev + 0.01 )
93154 return next ?? Math . min ( prev + ZOOM_STEP , ZOOM_MAX )
94155 } )
95156 } , [ setZoom ] )
96157
97158 const zoomOut = useCallback ( ( ) => {
98- setZoom ( prev => {
99- const next = [ ...ZOOM_PRESETS ] . reverse ( ) . find ( p => p < prev - 0.01 )
159+ setZoom ( ( prev ) => {
160+ const next = [ ...ZOOM_PRESETS ] . reverse ( ) . find ( ( p ) => p < prev - 0.01 )
100161 return next ?? Math . max ( prev - ZOOM_STEP , ZOOM_MIN )
101162 } )
102163 } , [ setZoom ] )
@@ -109,22 +170,50 @@ export function PreviewProvider({ children }: { children: ReactNode }) {
109170 fitToScreenRef . current = fn
110171 } , [ ] )
111172
112- const value = useMemo < PreviewContextValue > ( ( ) => ( {
113- previewUrl, setPreviewUrl, visible, setVisible, pip, setPip,
114- activeDevice, setActiveDevice,
115- refreshKey, refresh,
116- zoom, setZoom, panX, panY, setPan, resetView, zoomIn, zoomOut, fitToScreen, setFitToScreenFn,
117- } ) , [
118- previewUrl , visible , pip , activeDevice ,
119- refreshKey , refresh ,
120- zoom , setZoom , panX , panY , setPan , resetView , zoomIn , zoomOut , fitToScreen , setFitToScreenFn ,
121- ] )
122-
123- return (
124- < PreviewContext . Provider value = { value } >
125- { children }
126- </ PreviewContext . Provider >
173+ const value = useMemo < PreviewContextValue > (
174+ ( ) => ( {
175+ previewUrl,
176+ setPreviewUrl,
177+ visible,
178+ setVisible,
179+ pip,
180+ setPip,
181+ activeDevice,
182+ setActiveDevice,
183+ refreshKey,
184+ refresh,
185+ zoom,
186+ setZoom,
187+ panX,
188+ panY,
189+ setPan,
190+ resetView,
191+ zoomIn,
192+ zoomOut,
193+ fitToScreen,
194+ setFitToScreenFn,
195+ } ) ,
196+ [
197+ previewUrl ,
198+ visible ,
199+ pip ,
200+ activeDevice ,
201+ refreshKey ,
202+ refresh ,
203+ zoom ,
204+ setZoom ,
205+ panX ,
206+ panY ,
207+ setPan ,
208+ resetView ,
209+ zoomIn ,
210+ zoomOut ,
211+ fitToScreen ,
212+ setFitToScreenFn ,
213+ ] ,
127214 )
215+
216+ return < PreviewContext . Provider value = { value } > { children } </ PreviewContext . Provider >
128217}
129218
130219export function usePreview ( ) {
0 commit comments