@@ -5,65 +5,214 @@ import {
5
5
__unstableIframe as Iframe ,
6
6
__unstableEditorStyles as EditorStyles ,
7
7
} from '@wordpress/block-editor' ;
8
+ import {
9
+ __unstableMotion as motion ,
10
+ __experimentalHStack as HStack ,
11
+ __experimentalVStack as VStack ,
12
+ } from '@wordpress/components' ;
13
+ import { useReducedMotion , useResizeObserver } from '@wordpress/compose' ;
14
+ import { useState } from '@wordpress/element' ;
8
15
9
16
/**
10
17
* Internal dependencies
11
18
*/
12
- import { useStyle } from './hooks' ;
19
+ import { useSetting , useStyle } from './hooks' ;
13
20
import { useGlobalStylesOutput } from './use-global-styles-output' ;
14
21
15
- const StylesPreview = ( { height = 150 } ) => {
22
+ const firstFrame = {
23
+ start : {
24
+ opacity : 1 ,
25
+ display : 'block' ,
26
+ } ,
27
+ hover : {
28
+ opacity : 0 ,
29
+ display : 'none' ,
30
+ } ,
31
+ } ;
32
+
33
+ const secondFrame = {
34
+ hover : {
35
+ opacity : 1 ,
36
+ display : 'block' ,
37
+ } ,
38
+ start : {
39
+ opacity : 0 ,
40
+ display : 'none' ,
41
+ } ,
42
+ } ;
43
+
44
+ const normalizedWidth = 250 ;
45
+
46
+ const StylesPreview = ( { label, isFocused } ) => {
47
+ const [ fontWeight ] = useStyle ( 'typography.fontWeight' ) ;
16
48
const [ fontFamily = 'serif' ] = useStyle ( 'typography.fontFamily' ) ;
49
+ const [ headingFontFamily = fontFamily ] = useStyle (
50
+ 'elements.h1.typography.fontFamily'
51
+ ) ;
52
+ const [ headingFontWeight = fontWeight ] = useStyle (
53
+ 'elements.h1.typography.fontWeight'
54
+ ) ;
17
55
const [ textColor = 'black' ] = useStyle ( 'color.text' ) ;
56
+ const [ headingColor = textColor ] = useStyle ( 'elements.h1.color.text' ) ;
18
57
const [ linkColor = 'blue' ] = useStyle ( 'elements.link.color.text' ) ;
19
58
const [ backgroundColor = 'white' ] = useStyle ( 'color.background' ) ;
20
59
const [ gradientValue ] = useStyle ( 'color.gradient' ) ;
21
60
const [ styles ] = useGlobalStylesOutput ( ) ;
61
+ const disableMotion = useReducedMotion ( ) ;
62
+ const [ coreColors ] = useSetting ( 'color.palette.core' ) ;
63
+ const [ themeColors ] = useSetting ( 'color.palette.theme' ) ;
64
+ const [ customColors ] = useSetting ( 'color.palette.custom' ) ;
65
+ const [ isHovered , setIsHovered ] = useState ( false ) ;
66
+ const [ containerResizeListener , { width } ] = useResizeObserver ( ) ;
67
+ const ratio = width ? width / normalizedWidth : 1 ;
68
+
69
+ const paletteColors = ( themeColors ?? [ ] )
70
+ . concat ( customColors ?? [ ] )
71
+ . concat ( coreColors ?? [ ] ) ;
72
+ const highlightedColors = paletteColors
73
+ . filter (
74
+ // we exclude these two colors because they are already visible in the preview.
75
+ ( { color } ) => color !== backgroundColor && color !== headingColor
76
+ )
77
+ . slice ( 0 , 2 ) ;
22
78
23
79
return (
24
80
< Iframe
25
81
className = "edit-site-global-styles-preview__iframe"
26
82
head = { < EditorStyles styles = { styles } /> }
27
- style = { { height } }
83
+ style = { {
84
+ height : 150 * ratio ,
85
+ visibility : ! width ? 'hidden' : 'visible' ,
86
+ } }
87
+ onMouseEnter = { ( ) => setIsHovered ( true ) }
88
+ onMouseLeave = { ( ) => setIsHovered ( false ) }
89
+ tabIndex = { - 1 }
28
90
>
29
- < div
91
+ { containerResizeListener }
92
+ < motion . div
30
93
style = { {
31
- display : 'flex' ,
32
- gap : 20 ,
33
- alignItems : 'center' ,
34
- justifyContent : 'center' ,
35
94
height : '100%' ,
36
- transform : `scale( ${ height / 150 } )` ,
95
+ width : '100%' ,
37
96
background : gradientValue ?? backgroundColor ,
38
97
cursor : 'pointer' ,
39
98
} }
99
+ initial = "start"
100
+ animate = {
101
+ ( isHovered || isFocused ) && ! disableMotion
102
+ ? 'hover'
103
+ : 'start'
104
+ }
40
105
>
41
- < div style = { { fontFamily , fontSize : '80px' } } > Aa </ div >
42
- < div
106
+ < motion . div
107
+ variants = { firstFrame }
43
108
style = { {
44
- display : 'flex' ,
45
- gap : 20 ,
46
- flexDirection : 'column' ,
109
+ height : '100%' ,
110
+ overflow : 'hidden' ,
47
111
} }
48
112
>
49
- < div
113
+ < HStack
114
+ spacing = { 10 * ratio }
115
+ justify = "center"
50
116
style = { {
51
- height : 40 ,
52
- width : 40 ,
53
- background : textColor ,
54
- borderRadius : 20 ,
117
+ height : '100%' ,
118
+ overflow : 'hidden' ,
55
119
} }
56
- /> { ' ' }
57
- < div
120
+ >
121
+ < div
122
+ style = { {
123
+ fontFamily : headingFontFamily ,
124
+ fontSize : 65 * ratio ,
125
+ color : headingColor ,
126
+ fontWeight : headingFontWeight ,
127
+ } }
128
+ >
129
+ Aa
130
+ </ div >
131
+ < VStack spacing = { 2 * ratio } >
132
+ { highlightedColors . map ( ( { slug, color } ) => (
133
+ < div
134
+ key = { slug }
135
+ style = { {
136
+ height : 30 * ratio ,
137
+ width : 30 * ratio ,
138
+ background : color ,
139
+ borderRadius : 15 * ratio ,
140
+ } }
141
+ />
142
+ ) ) }
143
+ </ VStack >
144
+ </ HStack >
145
+ </ motion . div >
146
+ < motion . div
147
+ variants = { secondFrame }
148
+ style = { {
149
+ height : '100%' ,
150
+ overflow : 'hidden' ,
151
+ } }
152
+ >
153
+ < VStack
154
+ spacing = { 3 * ratio }
155
+ justify = "center"
58
156
style = { {
59
- height : 40 ,
60
- width : 40 ,
61
- background : linkColor ,
62
- borderRadius : 20 ,
157
+ height : '100%' ,
158
+ overflow : 'hidden' ,
159
+ padding : 10 * ratio ,
160
+ boxSizing : 'border-box' ,
63
161
} }
64
- />
65
- </ div >
66
- </ div >
162
+ >
163
+ { label && (
164
+ < div
165
+ style = { {
166
+ fontSize : 35 * ratio ,
167
+ fontFamily : headingFontFamily ,
168
+ color : headingColor ,
169
+ fontWeight : headingFontWeight ,
170
+ lineHeight : '1em' ,
171
+ } }
172
+ >
173
+ { label }
174
+ </ div >
175
+ ) }
176
+ < HStack spacing = { 2 * ratio } justify = "flex-start" >
177
+ < div
178
+ style = { {
179
+ fontFamily,
180
+ fontSize : 24 * ratio ,
181
+ color : textColor ,
182
+ } }
183
+ >
184
+ Aa
185
+ </ div >
186
+ < div
187
+ style = { {
188
+ fontFamily,
189
+ fontSize : 24 * ratio ,
190
+ color : linkColor ,
191
+ } }
192
+ >
193
+ Aa
194
+ </ div >
195
+ </ HStack >
196
+ { paletteColors && (
197
+ < HStack spacing = { 0 } >
198
+ { paletteColors
199
+ . slice ( 0 , 4 )
200
+ . map ( ( { color } , index ) => (
201
+ < div
202
+ key = { index }
203
+ style = { {
204
+ height : 10 * ratio ,
205
+ width : 30 * ratio ,
206
+ background : color ,
207
+ flexGrow : 1 ,
208
+ } }
209
+ />
210
+ ) ) }
211
+ </ HStack >
212
+ ) }
213
+ </ VStack >
214
+ </ motion . div >
215
+ </ motion . div >
67
216
</ Iframe >
68
217
) ;
69
218
} ;
0 commit comments