Skip to content

Commit d9ebccf

Browse files
authored
Add labels to the global styles variations (#39322)
1 parent 8edcf37 commit d9ebccf

File tree

6 files changed

+205
-37
lines changed

6 files changed

+205
-37
lines changed

lib/compat/wordpress-6.0/class-gutenberg-rest-global-styles-controller.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,11 @@ public function get_theme_items( $request ) {
231231
foreach ( $nested_html_files as $path => $file ) {
232232
$decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) );
233233
if ( is_array( $decoded_file ) ) {
234-
$variations[] = ( new WP_Theme_JSON_Gutenberg( $decoded_file ) )->get_raw_data();
234+
$variation = ( new WP_Theme_JSON_Gutenberg( $decoded_file ) )->get_raw_data();
235+
if ( empty( $variation['name'] ) ) {
236+
$variation['name'] = basename( $path, '.json' );
237+
}
238+
$variations[] = $variation;
235239
}
236240
}
237241
}

lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class WP_Theme_JSON_Gutenberg extends WP_Theme_JSON_5_9 {
2828
'styles',
2929
'templateParts',
3030
'version',
31+
'name',
3132
);
3233

3334
/**

packages/edit-site/src/components/global-styles/preview.js

+177-28
Original file line numberDiff line numberDiff line change
@@ -5,65 +5,214 @@ import {
55
__unstableIframe as Iframe,
66
__unstableEditorStyles as EditorStyles,
77
} 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';
815

916
/**
1017
* Internal dependencies
1118
*/
12-
import { useStyle } from './hooks';
19+
import { useSetting, useStyle } from './hooks';
1320
import { useGlobalStylesOutput } from './use-global-styles-output';
1421

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' );
1648
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+
);
1755
const [ textColor = 'black' ] = useStyle( 'color.text' );
56+
const [ headingColor = textColor ] = useStyle( 'elements.h1.color.text' );
1857
const [ linkColor = 'blue' ] = useStyle( 'elements.link.color.text' );
1958
const [ backgroundColor = 'white' ] = useStyle( 'color.background' );
2059
const [ gradientValue ] = useStyle( 'color.gradient' );
2160
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 );
2278

2379
return (
2480
<Iframe
2581
className="edit-site-global-styles-preview__iframe"
2682
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 }
2890
>
29-
<div
91+
{ containerResizeListener }
92+
<motion.div
3093
style={ {
31-
display: 'flex',
32-
gap: 20,
33-
alignItems: 'center',
34-
justifyContent: 'center',
3594
height: '100%',
36-
transform: `scale(${ height / 150 })`,
95+
width: '100%',
3796
background: gradientValue ?? backgroundColor,
3897
cursor: 'pointer',
3998
} }
99+
initial="start"
100+
animate={
101+
( isHovered || isFocused ) && ! disableMotion
102+
? 'hover'
103+
: 'start'
104+
}
40105
>
41-
<div style={ { fontFamily, fontSize: '80px' } }>Aa</div>
42-
<div
106+
<motion.div
107+
variants={ firstFrame }
43108
style={ {
44-
display: 'flex',
45-
gap: 20,
46-
flexDirection: 'column',
109+
height: '100%',
110+
overflow: 'hidden',
47111
} }
48112
>
49-
<div
113+
<HStack
114+
spacing={ 10 * ratio }
115+
justify="center"
50116
style={ {
51-
height: 40,
52-
width: 40,
53-
background: textColor,
54-
borderRadius: 20,
117+
height: '100%',
118+
overflow: 'hidden',
55119
} }
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"
58156
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',
63161
} }
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>
67216
</Iframe>
68217
);
69218
};

packages/edit-site/src/components/global-styles/screen-style-variations.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import classnames from 'classnames';
99
*/
1010
import { store as coreStore } from '@wordpress/core-data';
1111
import { useSelect } from '@wordpress/data';
12-
import { useMemo, useContext } from '@wordpress/element';
12+
import { useMemo, useContext, useState } from '@wordpress/element';
1313
import { ENTER } from '@wordpress/keycodes';
1414
import {
1515
__experimentalGrid as Grid,
@@ -31,6 +31,7 @@ function compareVariations( a, b ) {
3131
}
3232

3333
function Variation( { variation } ) {
34+
const [ isFocused, setIsFocused ] = useState( false );
3435
const { base, user, setUserConfig } = useContext( GlobalStylesContext );
3536
const context = useMemo( () => {
3637
return {
@@ -77,8 +78,16 @@ function Variation( { variation } ) {
7778
onClick={ selectVariation }
7879
onKeyDown={ selectOnEnter }
7980
tabIndex="0"
81+
aria-label={ variation?.name }
82+
onFocus={ () => setIsFocused( true ) }
83+
onBlur={ () => setIsFocused( false ) }
8084
>
81-
<StylesPreview height={ 100 } />
85+
<div className="edit-site-global-styles-variations_item-preview">
86+
<StylesPreview
87+
label={ variation?.name }
88+
isFocused={ isFocused }
89+
/>
90+
</div>
8291
</div>
8392
</GlobalStylesContext.Provider>
8493
);

packages/edit-site/src/components/global-styles/style.scss

+10-6
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,23 @@
7373

7474
.edit-site-global-styles-variations_item {
7575
box-sizing: border-box;
76-
padding: $border-width * 2;
77-
border-radius: $radius-block-ui;
78-
border: $gray-200 $border-width solid;
7976

80-
&.is-active {
77+
.edit-site-global-styles-variations_item-preview {
78+
padding: $border-width * 2;
79+
border-radius: $radius-block-ui;
80+
border: $gray-200 $border-width solid;
81+
}
82+
83+
&.is-active .edit-site-global-styles-variations_item-preview {
8184
border: $gray-900 $border-width solid;
8285
}
8386

84-
&:hover {
87+
&:hover .edit-site-global-styles-variations_item-preview {
8588
border: var(--wp-admin-theme-color) $border-width solid;
8689
}
8790

88-
&:focus {
91+
&:focus .edit-site-global-styles-variations_item-preview {
8992
border: var(--wp-admin-theme-color) $border-width solid;
9093
}
9194
}
95+

phpunit/class-gutenberg-rest-global-styles-controller-test.php

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public function test_get_theme_items() {
110110
),
111111
),
112112
),
113+
'name' => 'variation',
113114
),
114115
);
115116
$this->assertSameSetsWithIndex( $data, $expected );

0 commit comments

Comments
 (0)