@wordpress/edit-site 4.10.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/build/components/add-new-template/add-custom-template-modal.js +22 -42
- package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
- package/build/components/add-new-template/new-template.js +17 -20
- package/build/components/add-new-template/new-template.js.map +1 -1
- package/build/components/add-new-template/utils.js +366 -239
- package/build/components/add-new-template/utils.js.map +1 -1
- package/build/components/block-editor/index.js +1 -3
- package/build/components/block-editor/index.js.map +1 -1
- package/build/components/global-styles/dimensions-panel.js +183 -13
- package/build/components/global-styles/dimensions-panel.js.map +1 -1
- package/build/components/global-styles/hooks.js +1 -1
- package/build/components/global-styles/hooks.js.map +1 -1
- package/build/components/global-styles/use-global-styles-output.js +95 -17
- package/build/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build/components/global-styles/utils.js +31 -0
- package/build/components/global-styles/utils.js.map +1 -1
- package/build/components/header/index.js +7 -6
- package/build/components/header/index.js.map +1 -1
- package/build/hooks/index.js +2 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/template-part-edit.js +86 -0
- package/build/hooks/template-part-edit.js.map +1 -0
- package/build-module/components/add-new-template/add-custom-template-modal.js +23 -43
- package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
- package/build-module/components/add-new-template/new-template.js +18 -21
- package/build-module/components/add-new-template/new-template.js.map +1 -1
- package/build-module/components/add-new-template/utils.js +365 -227
- package/build-module/components/add-new-template/utils.js.map +1 -1
- package/build-module/components/block-editor/index.js +1 -2
- package/build-module/components/block-editor/index.js.map +1 -1
- package/build-module/components/global-styles/dimensions-panel.js +183 -14
- package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
- package/build-module/components/global-styles/hooks.js +1 -1
- package/build-module/components/global-styles/hooks.js.map +1 -1
- package/build-module/components/global-styles/use-global-styles-output.js +94 -22
- package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build-module/components/global-styles/utils.js +29 -0
- package/build-module/components/global-styles/utils.js.map +1 -1
- package/build-module/components/header/index.js +8 -6
- package/build-module/components/header/index.js.map +1 -1
- package/build-module/hooks/index.js +1 -0
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/template-part-edit.js +67 -0
- package/build-module/hooks/template-part-edit.js.map +1 -0
- package/build-style/style-rtl.css +25 -25
- package/build-style/style.css +25 -25
- package/package.json +29 -29
- package/src/components/add-new-template/add-custom-template-modal.js +27 -45
- package/src/components/add-new-template/new-template.js +27 -64
- package/src/components/add-new-template/style.scss +20 -8
- package/src/components/add-new-template/utils.js +398 -229
- package/src/components/block-editor/index.js +0 -2
- package/src/components/global-styles/dimensions-panel.js +207 -14
- package/src/components/global-styles/hooks.js +2 -0
- package/src/components/global-styles/test/use-global-styles-output.js +64 -1
- package/src/components/global-styles/use-global-styles-output.js +100 -8
- package/src/components/global-styles/utils.js +31 -0
- package/src/components/header/index.js +9 -10
- package/src/components/header/style.scss +5 -3
- package/src/components/sidebar/style.scss +4 -0
- package/src/hooks/index.js +1 -0
- package/src/hooks/template-part-edit.js +82 -0
- package/src/style.scss +0 -1
- package/build/components/edit-template-part-menu-button/index.js +0 -90
- package/build/components/edit-template-part-menu-button/index.js.map +0 -1
- package/build-module/components/edit-template-part-menu-button/index.js +0 -72
- package/build-module/components/edit-template-part-menu-button/index.js.map +0 -1
- package/src/components/edit-template-part-menu-button/index.js +0 -82
|
@@ -38,7 +38,6 @@ import NavigateToLink from '../navigate-to-link';
|
|
|
38
38
|
import { SidebarInspectorFill } from '../sidebar';
|
|
39
39
|
import { store as editSiteStore } from '../../store';
|
|
40
40
|
import BlockInspectorButton from './block-inspector-button';
|
|
41
|
-
import EditTemplatePartMenuButton from '../edit-template-part-menu-button';
|
|
42
41
|
import BackButton from './back-button';
|
|
43
42
|
import ResizableEditor from './resizable-editor';
|
|
44
43
|
|
|
@@ -155,7 +154,6 @@ export default function BlockEditor( { setIsInserterOpen } ) {
|
|
|
155
154
|
onChange={ onChange }
|
|
156
155
|
useSubRegistry={ false }
|
|
157
156
|
>
|
|
158
|
-
<EditTemplatePartMenuButton />
|
|
159
157
|
<TemplatePartConverter />
|
|
160
158
|
<__experimentalLinkControl.ViewerFill>
|
|
161
159
|
{ useCallback(
|
|
@@ -6,10 +6,13 @@ import {
|
|
|
6
6
|
__experimentalToolsPanel as ToolsPanel,
|
|
7
7
|
__experimentalToolsPanelItem as ToolsPanelItem,
|
|
8
8
|
__experimentalBoxControl as BoxControl,
|
|
9
|
+
__experimentalHStack as HStack,
|
|
9
10
|
__experimentalUnitControl as UnitControl,
|
|
10
11
|
__experimentalUseCustomUnits as useCustomUnits,
|
|
12
|
+
__experimentalView as View,
|
|
11
13
|
} from '@wordpress/components';
|
|
12
14
|
import { __experimentalUseCustomSides as useCustomSides } from '@wordpress/block-editor';
|
|
15
|
+
import { Icon, positionCenter, stretchWide } from '@wordpress/icons';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* Internal dependencies
|
|
@@ -19,11 +22,27 @@ import { getSupportedGlobalStylesPanels, useSetting, useStyle } from './hooks';
|
|
|
19
22
|
const AXIAL_SIDES = [ 'horizontal', 'vertical' ];
|
|
20
23
|
|
|
21
24
|
export function useHasDimensionsPanel( name ) {
|
|
25
|
+
const hasContentSize = useHasContentSize( name );
|
|
26
|
+
const hasWideSize = useHasWideSize( name );
|
|
22
27
|
const hasPadding = useHasPadding( name );
|
|
23
28
|
const hasMargin = useHasMargin( name );
|
|
24
29
|
const hasGap = useHasGap( name );
|
|
25
30
|
|
|
26
|
-
return hasPadding || hasMargin || hasGap;
|
|
31
|
+
return hasContentSize || hasWideSize || hasPadding || hasMargin || hasGap;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function useHasContentSize( name ) {
|
|
35
|
+
const supports = getSupportedGlobalStylesPanels( name );
|
|
36
|
+
const [ settings ] = useSetting( 'layout.contentSize', name );
|
|
37
|
+
|
|
38
|
+
return settings && supports.includes( 'contentSize' );
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function useHasWideSize( name ) {
|
|
42
|
+
const supports = getSupportedGlobalStylesPanels( name );
|
|
43
|
+
const [ settings ] = useSetting( 'layout.wideSize', name );
|
|
44
|
+
|
|
45
|
+
return settings && supports.includes( 'wideSize' );
|
|
27
46
|
}
|
|
28
47
|
|
|
29
48
|
function useHasPadding( name ) {
|
|
@@ -85,20 +104,50 @@ function splitStyleValue( value ) {
|
|
|
85
104
|
return value;
|
|
86
105
|
}
|
|
87
106
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
// Props for managing `layout.contentSize`.
|
|
108
|
+
function useContentSizeProps( name ) {
|
|
109
|
+
const [ contentSizeValue, setContentSizeValue ] = useSetting(
|
|
110
|
+
'layout.contentSize',
|
|
111
|
+
name
|
|
112
|
+
);
|
|
113
|
+
const [ userSetContentSizeValue ] = useSetting(
|
|
114
|
+
'layout.contentSize',
|
|
115
|
+
name,
|
|
116
|
+
'user'
|
|
117
|
+
);
|
|
118
|
+
const hasUserSetContentSizeValue = () => !! userSetContentSizeValue;
|
|
119
|
+
const resetContentSizeValue = () => setContentSizeValue( '' );
|
|
120
|
+
return {
|
|
121
|
+
contentSizeValue,
|
|
122
|
+
setContentSizeValue,
|
|
123
|
+
hasUserSetContentSizeValue,
|
|
124
|
+
resetContentSizeValue,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
101
127
|
|
|
128
|
+
// Props for managing `layout.wideSize`.
|
|
129
|
+
function useWideSizeProps( name ) {
|
|
130
|
+
const [ wideSizeValue, setWideSizeValue ] = useSetting(
|
|
131
|
+
'layout.wideSize',
|
|
132
|
+
name
|
|
133
|
+
);
|
|
134
|
+
const [ userSetWideSizeValue ] = useSetting(
|
|
135
|
+
'layout.wideSize',
|
|
136
|
+
name,
|
|
137
|
+
'user'
|
|
138
|
+
);
|
|
139
|
+
const hasUserSetWideSizeValue = () => !! userSetWideSizeValue;
|
|
140
|
+
const resetWideSizeValue = () => setWideSizeValue( '' );
|
|
141
|
+
return {
|
|
142
|
+
wideSizeValue,
|
|
143
|
+
setWideSizeValue,
|
|
144
|
+
hasUserSetWideSizeValue,
|
|
145
|
+
resetWideSizeValue,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Props for managing `spacing.padding`.
|
|
150
|
+
function usePaddingProps( name ) {
|
|
102
151
|
const [ rawPadding, setRawPadding ] = useStyle( 'spacing.padding', name );
|
|
103
152
|
const paddingValues = splitStyleValue( rawPadding );
|
|
104
153
|
const paddingSides = useCustomSides( name, 'padding' );
|
|
@@ -114,6 +163,18 @@ export default function DimensionsPanel( { name } ) {
|
|
|
114
163
|
const hasPaddingValue = () =>
|
|
115
164
|
!! paddingValues && Object.keys( paddingValues ).length;
|
|
116
165
|
|
|
166
|
+
return {
|
|
167
|
+
paddingValues,
|
|
168
|
+
paddingSides,
|
|
169
|
+
isAxialPadding,
|
|
170
|
+
setPaddingValues,
|
|
171
|
+
resetPaddingValue,
|
|
172
|
+
hasPaddingValue,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Props for managing `spacing.margin`.
|
|
177
|
+
function useMarginProps( name ) {
|
|
117
178
|
const [ rawMargin, setRawMargin ] = useStyle( 'spacing.margin', name );
|
|
118
179
|
const marginValues = splitStyleValue( rawMargin );
|
|
119
180
|
const marginSides = useCustomSides( name, 'margin' );
|
|
@@ -129,18 +190,150 @@ export default function DimensionsPanel( { name } ) {
|
|
|
129
190
|
const hasMarginValue = () =>
|
|
130
191
|
!! marginValues && Object.keys( marginValues ).length;
|
|
131
192
|
|
|
193
|
+
return {
|
|
194
|
+
marginValues,
|
|
195
|
+
marginSides,
|
|
196
|
+
isAxialMargin,
|
|
197
|
+
setMarginValues,
|
|
198
|
+
resetMarginValue,
|
|
199
|
+
hasMarginValue,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Props for managing `spacing.blockGap`.
|
|
204
|
+
function useBlockGapProps( name ) {
|
|
132
205
|
const [ gapValue, setGapValue ] = useStyle( 'spacing.blockGap', name );
|
|
133
206
|
const resetGapValue = () => setGapValue( undefined );
|
|
134
207
|
const hasGapValue = () => !! gapValue;
|
|
208
|
+
return {
|
|
209
|
+
gapValue,
|
|
210
|
+
setGapValue,
|
|
211
|
+
resetGapValue,
|
|
212
|
+
hasGapValue,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export default function DimensionsPanel( { name } ) {
|
|
217
|
+
const showContentSizeControl = useHasContentSize( name );
|
|
218
|
+
const showWideSizeControl = useHasWideSize( name );
|
|
219
|
+
const showPaddingControl = useHasPadding( name );
|
|
220
|
+
const showMarginControl = useHasMargin( name );
|
|
221
|
+
const showGapControl = useHasGap( name );
|
|
222
|
+
const units = useCustomUnits( {
|
|
223
|
+
availableUnits: useSetting( 'spacing.units', name )[ 0 ] || [
|
|
224
|
+
'%',
|
|
225
|
+
'px',
|
|
226
|
+
'em',
|
|
227
|
+
'rem',
|
|
228
|
+
'vw',
|
|
229
|
+
],
|
|
230
|
+
} );
|
|
231
|
+
|
|
232
|
+
// Props for managing `layout.contentSize`.
|
|
233
|
+
const {
|
|
234
|
+
contentSizeValue,
|
|
235
|
+
setContentSizeValue,
|
|
236
|
+
hasUserSetContentSizeValue,
|
|
237
|
+
resetContentSizeValue,
|
|
238
|
+
} = useContentSizeProps( name );
|
|
239
|
+
|
|
240
|
+
// Props for managing `layout.wideSize`.
|
|
241
|
+
const {
|
|
242
|
+
wideSizeValue,
|
|
243
|
+
setWideSizeValue,
|
|
244
|
+
hasUserSetWideSizeValue,
|
|
245
|
+
resetWideSizeValue,
|
|
246
|
+
} = useWideSizeProps( name );
|
|
247
|
+
|
|
248
|
+
// Props for managing `spacing.padding`.
|
|
249
|
+
const {
|
|
250
|
+
paddingValues,
|
|
251
|
+
paddingSides,
|
|
252
|
+
isAxialPadding,
|
|
253
|
+
setPaddingValues,
|
|
254
|
+
resetPaddingValue,
|
|
255
|
+
hasPaddingValue,
|
|
256
|
+
} = usePaddingProps( name );
|
|
257
|
+
|
|
258
|
+
// Props for managing `spacing.margin`.
|
|
259
|
+
const {
|
|
260
|
+
marginValues,
|
|
261
|
+
marginSides,
|
|
262
|
+
isAxialMargin,
|
|
263
|
+
setMarginValues,
|
|
264
|
+
resetMarginValue,
|
|
265
|
+
hasMarginValue,
|
|
266
|
+
} = useMarginProps( name );
|
|
267
|
+
|
|
268
|
+
// Props for managing `spacing.blockGap`.
|
|
269
|
+
const { gapValue, setGapValue, resetGapValue, hasGapValue } =
|
|
270
|
+
useBlockGapProps( name );
|
|
135
271
|
|
|
136
272
|
const resetAll = () => {
|
|
137
273
|
resetPaddingValue();
|
|
138
274
|
resetMarginValue();
|
|
139
275
|
resetGapValue();
|
|
276
|
+
resetContentSizeValue();
|
|
277
|
+
resetWideSizeValue();
|
|
140
278
|
};
|
|
141
279
|
|
|
142
280
|
return (
|
|
143
281
|
<ToolsPanel label={ __( 'Dimensions' ) } resetAll={ resetAll }>
|
|
282
|
+
{ ( showContentSizeControl || showWideSizeControl ) && (
|
|
283
|
+
<span className="span-columns">
|
|
284
|
+
{ __( 'Set the width of the main content area.' ) }
|
|
285
|
+
</span>
|
|
286
|
+
) }
|
|
287
|
+
{ showContentSizeControl && (
|
|
288
|
+
<ToolsPanelItem
|
|
289
|
+
className="single-column"
|
|
290
|
+
label={ __( 'Content size' ) }
|
|
291
|
+
hasValue={ hasUserSetContentSizeValue }
|
|
292
|
+
onDeselect={ resetContentSizeValue }
|
|
293
|
+
isShownByDefault={ true }
|
|
294
|
+
>
|
|
295
|
+
<HStack alignment="flex-end" justify="flex-start">
|
|
296
|
+
<UnitControl
|
|
297
|
+
label={ __( 'Content' ) }
|
|
298
|
+
labelPosition="top"
|
|
299
|
+
__unstableInputWidth="80px"
|
|
300
|
+
value={ contentSizeValue || '' }
|
|
301
|
+
onChange={ ( nextContentSize ) => {
|
|
302
|
+
setContentSizeValue( nextContentSize );
|
|
303
|
+
} }
|
|
304
|
+
units={ units }
|
|
305
|
+
/>
|
|
306
|
+
<View>
|
|
307
|
+
<Icon icon={ positionCenter } />
|
|
308
|
+
</View>
|
|
309
|
+
</HStack>
|
|
310
|
+
</ToolsPanelItem>
|
|
311
|
+
) }
|
|
312
|
+
{ showWideSizeControl && (
|
|
313
|
+
<ToolsPanelItem
|
|
314
|
+
className="single-column"
|
|
315
|
+
label={ __( 'Wide size' ) }
|
|
316
|
+
hasValue={ hasUserSetWideSizeValue }
|
|
317
|
+
onDeselect={ resetWideSizeValue }
|
|
318
|
+
isShownByDefault={ true }
|
|
319
|
+
>
|
|
320
|
+
<HStack alignment="flex-end" justify="flex-start">
|
|
321
|
+
<UnitControl
|
|
322
|
+
label={ __( 'Wide' ) }
|
|
323
|
+
labelPosition="top"
|
|
324
|
+
__unstableInputWidth="80px"
|
|
325
|
+
value={ wideSizeValue || '' }
|
|
326
|
+
onChange={ ( nextWideSize ) => {
|
|
327
|
+
setWideSizeValue( nextWideSize );
|
|
328
|
+
} }
|
|
329
|
+
units={ units }
|
|
330
|
+
/>
|
|
331
|
+
<View>
|
|
332
|
+
<Icon icon={ stretchWide } />
|
|
333
|
+
</View>
|
|
334
|
+
</HStack>
|
|
335
|
+
</ToolsPanelItem>
|
|
336
|
+
) }
|
|
144
337
|
{ showPaddingControl && (
|
|
145
338
|
<ToolsPanelItem
|
|
146
339
|
hasValue={ hasPaddingValue }
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getLayoutStyles,
|
|
11
11
|
getNodesWithSettings,
|
|
12
12
|
getNodesWithStyles,
|
|
13
|
+
getBlockSelectors,
|
|
13
14
|
toCustomProperties,
|
|
14
15
|
toStyles,
|
|
15
16
|
} from '../use-global-styles-output';
|
|
@@ -57,6 +58,11 @@ describe( 'global styles renderer', () => {
|
|
|
57
58
|
},
|
|
58
59
|
},
|
|
59
60
|
},
|
|
61
|
+
'core/image': {
|
|
62
|
+
border: {
|
|
63
|
+
radius: '9999px',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
60
66
|
},
|
|
61
67
|
elements: {
|
|
62
68
|
link: {
|
|
@@ -84,6 +90,10 @@ describe( 'global styles renderer', () => {
|
|
|
84
90
|
'core/heading': {
|
|
85
91
|
selector: '.my-heading1, .my-heading2',
|
|
86
92
|
},
|
|
93
|
+
'core/image': {
|
|
94
|
+
selector: '.my-image',
|
|
95
|
+
featureSelectors: '.my-image img, .my-image .crop-area',
|
|
96
|
+
},
|
|
87
97
|
};
|
|
88
98
|
|
|
89
99
|
expect( getNodesWithStyles( tree, blockSelectors ) ).toEqual( [
|
|
@@ -159,6 +169,15 @@ describe( 'global styles renderer', () => {
|
|
|
159
169
|
},
|
|
160
170
|
selector: '.my-heading1 a, .my-heading2 a',
|
|
161
171
|
},
|
|
172
|
+
{
|
|
173
|
+
styles: {
|
|
174
|
+
border: {
|
|
175
|
+
radius: '9999px',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
selector: '.my-image',
|
|
179
|
+
featureSelectors: '.my-image img, .my-image .crop-area',
|
|
180
|
+
},
|
|
162
181
|
] );
|
|
163
182
|
} );
|
|
164
183
|
} );
|
|
@@ -430,6 +449,14 @@ describe( 'global styles renderer', () => {
|
|
|
430
449
|
},
|
|
431
450
|
},
|
|
432
451
|
},
|
|
452
|
+
'core/image': {
|
|
453
|
+
color: {
|
|
454
|
+
text: 'red',
|
|
455
|
+
},
|
|
456
|
+
border: {
|
|
457
|
+
radius: '9999px',
|
|
458
|
+
},
|
|
459
|
+
},
|
|
433
460
|
},
|
|
434
461
|
},
|
|
435
462
|
};
|
|
@@ -441,12 +468,18 @@ describe( 'global styles renderer', () => {
|
|
|
441
468
|
'core/heading': {
|
|
442
469
|
selector: 'h1,h2,h3,h4,h5,h6',
|
|
443
470
|
},
|
|
471
|
+
'core/image': {
|
|
472
|
+
selector: '.wp-block-image',
|
|
473
|
+
featureSelectors: {
|
|
474
|
+
border: '.wp-block-image img, .wp-block-image .wp-crop-area',
|
|
475
|
+
},
|
|
476
|
+
},
|
|
444
477
|
};
|
|
445
478
|
|
|
446
479
|
expect( toStyles( tree, blockSelectors ) ).toEqual(
|
|
447
480
|
'body {margin: 0;}' +
|
|
448
481
|
'body{background-color: red;margin: 10px;padding: 10px;}h1{font-size: 42px;}a{color: blue;}a:hover{color: orange;}a:focus{color: orange;}.wp-block-group{margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}h1,h2,h3,h4,h5,h6{color: orange;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: hotpink;}h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{color: red;}h1 a:focus,h2 a:focus,h3 a:focus,h4 a:focus,h5 a:focus,h6 a:focus{color: red;}' +
|
|
449
|
-
'.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }' +
|
|
482
|
+
'.wp-block-image img, .wp-block-image .wp-crop-area{border-radius: 9999px }.wp-block-image{color: red;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }' +
|
|
450
483
|
'.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
|
|
451
484
|
);
|
|
452
485
|
} );
|
|
@@ -618,4 +651,34 @@ describe( 'global styles renderer', () => {
|
|
|
618
651
|
);
|
|
619
652
|
} );
|
|
620
653
|
} );
|
|
654
|
+
|
|
655
|
+
describe( 'getBlockSelectors', () => {
|
|
656
|
+
it( 'should return block selectors data', () => {
|
|
657
|
+
const imageSupports = {
|
|
658
|
+
__experimentalBorder: {
|
|
659
|
+
radius: true,
|
|
660
|
+
__experimentalSelector: 'img, .crop-area',
|
|
661
|
+
},
|
|
662
|
+
color: {
|
|
663
|
+
__experimentalDuotone: 'img',
|
|
664
|
+
},
|
|
665
|
+
__experimentalSelector: '.my-image',
|
|
666
|
+
};
|
|
667
|
+
const imageBlock = { name: 'core/image', supports: imageSupports };
|
|
668
|
+
const blockTypes = [ imageBlock ];
|
|
669
|
+
|
|
670
|
+
expect( getBlockSelectors( blockTypes ) ).toEqual( {
|
|
671
|
+
'core/image': {
|
|
672
|
+
name: imageBlock.name,
|
|
673
|
+
selector: imageSupports.__experimentalSelector,
|
|
674
|
+
duotoneSelector: imageSupports.color.__experimentalDuotone,
|
|
675
|
+
fallbackGapValue: undefined,
|
|
676
|
+
featureSelectors: {
|
|
677
|
+
border: '.my-image img, .my-image .crop-area',
|
|
678
|
+
},
|
|
679
|
+
hasLayoutSupport: false,
|
|
680
|
+
},
|
|
681
|
+
} );
|
|
682
|
+
} );
|
|
683
|
+
} );
|
|
621
684
|
} );
|
|
@@ -31,10 +31,19 @@ import {
|
|
|
31
31
|
/**
|
|
32
32
|
* Internal dependencies
|
|
33
33
|
*/
|
|
34
|
-
import { PRESET_METADATA, ROOT_BLOCK_SELECTOR } from './utils';
|
|
34
|
+
import { PRESET_METADATA, ROOT_BLOCK_SELECTOR, scopeSelector } from './utils';
|
|
35
35
|
import { GlobalStylesContext } from './context';
|
|
36
36
|
import { useSetting } from './hooks';
|
|
37
37
|
|
|
38
|
+
// List of block support features that can have their related styles
|
|
39
|
+
// generated under their own feature level selector rather than the block's.
|
|
40
|
+
const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = {
|
|
41
|
+
__experimentalBorder: 'border',
|
|
42
|
+
color: 'color',
|
|
43
|
+
spacing: 'spacing',
|
|
44
|
+
typography: 'typography',
|
|
45
|
+
};
|
|
46
|
+
|
|
38
47
|
function compileStyleValue( uncompiledValue ) {
|
|
39
48
|
const VARIABLE_REFERENCE_PREFIX = 'var:';
|
|
40
49
|
const VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE = '|';
|
|
@@ -172,14 +181,26 @@ function flattenTree( input = {}, prefix, token ) {
|
|
|
172
181
|
/**
|
|
173
182
|
* Transform given style tree into a set of style declarations.
|
|
174
183
|
*
|
|
175
|
-
* @param {Object}
|
|
184
|
+
* @param {Object} blockStyles Block styles.
|
|
185
|
+
*
|
|
186
|
+
* @param {string} selector The selector these declarations should attach to.
|
|
187
|
+
*
|
|
188
|
+
* @param {boolean} useRootPaddingAlign Whether to use CSS custom properties in root selector.
|
|
176
189
|
*
|
|
177
190
|
* @return {Array} An array of style declarations.
|
|
178
191
|
*/
|
|
179
|
-
function getStylesDeclarations(
|
|
192
|
+
function getStylesDeclarations(
|
|
193
|
+
blockStyles = {},
|
|
194
|
+
selector = '',
|
|
195
|
+
useRootPaddingAlign
|
|
196
|
+
) {
|
|
197
|
+
const isRoot = ROOT_BLOCK_SELECTOR === selector;
|
|
180
198
|
const output = reduce(
|
|
181
199
|
STYLE_PROPERTY,
|
|
182
|
-
( declarations, { value, properties, useEngine }, key ) => {
|
|
200
|
+
( declarations, { value, properties, useEngine, rootOnly }, key ) => {
|
|
201
|
+
if ( rootOnly && ! isRoot ) {
|
|
202
|
+
return declarations;
|
|
203
|
+
}
|
|
183
204
|
const pathToValue = value;
|
|
184
205
|
if ( first( pathToValue ) === 'elements' || useEngine ) {
|
|
185
206
|
return declarations;
|
|
@@ -197,13 +218,22 @@ function getStylesDeclarations( blockStyles = {} ) {
|
|
|
197
218
|
return;
|
|
198
219
|
}
|
|
199
220
|
|
|
200
|
-
const cssProperty =
|
|
221
|
+
const cssProperty = name.startsWith( '--' )
|
|
222
|
+
? name
|
|
223
|
+
: kebabCase( name );
|
|
201
224
|
declarations.push(
|
|
202
225
|
`${ cssProperty }: ${ compileStyleValue(
|
|
203
226
|
get( styleValue, [ prop ] )
|
|
204
227
|
) }`
|
|
205
228
|
);
|
|
206
229
|
} );
|
|
230
|
+
} else if (
|
|
231
|
+
key === '--wp--style--root--padding' &&
|
|
232
|
+
typeof styleValue === 'string'
|
|
233
|
+
) {
|
|
234
|
+
// Root-level padding styles don't currently support strings with CSS shorthand values.
|
|
235
|
+
// This may change: https://github.com/WordPress/gutenberg/issues/40132.
|
|
236
|
+
return declarations;
|
|
207
237
|
} else if ( get( blockStyles, pathToValue, false ) ) {
|
|
208
238
|
const cssProperty = key.startsWith( '--' )
|
|
209
239
|
? key
|
|
@@ -220,6 +250,10 @@ function getStylesDeclarations( blockStyles = {} ) {
|
|
|
220
250
|
[]
|
|
221
251
|
);
|
|
222
252
|
|
|
253
|
+
if ( isRoot && useRootPaddingAlign ) {
|
|
254
|
+
return output;
|
|
255
|
+
}
|
|
256
|
+
|
|
223
257
|
// The goal is to move everything to server side generated engine styles
|
|
224
258
|
// This is temporary as we absorb more and more styles into the engine.
|
|
225
259
|
const extraRules = getCSSRules( blockStyles );
|
|
@@ -403,6 +437,7 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
|
|
|
403
437
|
hasLayoutSupport: blockSelectors[ blockName ].hasLayoutSupport,
|
|
404
438
|
selector: blockSelectors[ blockName ].selector,
|
|
405
439
|
styles: blockStyles,
|
|
440
|
+
featureSelectors: blockSelectors[ blockName ].featureSelectors,
|
|
406
441
|
} );
|
|
407
442
|
}
|
|
408
443
|
|
|
@@ -505,6 +540,7 @@ export const toStyles = (
|
|
|
505
540
|
) => {
|
|
506
541
|
const nodesWithStyles = getNodesWithStyles( tree, blockSelectors );
|
|
507
542
|
const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
|
|
543
|
+
const useRootPaddingAlign = tree?.settings?.useRootPaddingAwareAlignments;
|
|
508
544
|
|
|
509
545
|
/*
|
|
510
546
|
* Reset default browser margin on the root body element.
|
|
@@ -515,6 +551,12 @@ export const toStyles = (
|
|
|
515
551
|
* @link https://github.com/WordPress/gutenberg/issues/36147.
|
|
516
552
|
*/
|
|
517
553
|
let ruleset = 'body {margin: 0;}';
|
|
554
|
+
|
|
555
|
+
if ( useRootPaddingAlign ) {
|
|
556
|
+
ruleset =
|
|
557
|
+
'body { margin: 0; padding-right: 0; padding-left: 0; padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom) } .has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); } .has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); } .has-global-padding > .alignfull > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }';
|
|
558
|
+
}
|
|
559
|
+
|
|
518
560
|
nodesWithStyles.forEach(
|
|
519
561
|
( {
|
|
520
562
|
selector,
|
|
@@ -522,7 +564,33 @@ export const toStyles = (
|
|
|
522
564
|
styles,
|
|
523
565
|
fallbackGapValue,
|
|
524
566
|
hasLayoutSupport,
|
|
567
|
+
featureSelectors,
|
|
525
568
|
} ) => {
|
|
569
|
+
// Process styles for block support features with custom feature level
|
|
570
|
+
// CSS selectors set.
|
|
571
|
+
if ( featureSelectors ) {
|
|
572
|
+
Object.entries( featureSelectors ).forEach(
|
|
573
|
+
( [ featureName, featureSelector ] ) => {
|
|
574
|
+
if ( styles?.[ featureName ] ) {
|
|
575
|
+
const featureStyles = {
|
|
576
|
+
[ featureName ]: styles[ featureName ],
|
|
577
|
+
};
|
|
578
|
+
const featureDeclarations =
|
|
579
|
+
getStylesDeclarations( featureStyles );
|
|
580
|
+
delete styles[ featureName ];
|
|
581
|
+
|
|
582
|
+
if ( !! featureDeclarations.length ) {
|
|
583
|
+
ruleset =
|
|
584
|
+
ruleset +
|
|
585
|
+
`${ featureSelector }{${ featureDeclarations.join(
|
|
586
|
+
';'
|
|
587
|
+
) } }`;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
|
|
526
594
|
const duotoneStyles = {};
|
|
527
595
|
if ( styles?.filter ) {
|
|
528
596
|
duotoneStyles.filter = styles.filter;
|
|
@@ -556,7 +624,11 @@ export const toStyles = (
|
|
|
556
624
|
}
|
|
557
625
|
|
|
558
626
|
// Process the remaining block styles (they use either normal block class or __experimentalSelector).
|
|
559
|
-
const declarations = getStylesDeclarations(
|
|
627
|
+
const declarations = getStylesDeclarations(
|
|
628
|
+
styles,
|
|
629
|
+
selector,
|
|
630
|
+
useRootPaddingAlign
|
|
631
|
+
);
|
|
560
632
|
if ( declarations?.length ) {
|
|
561
633
|
ruleset =
|
|
562
634
|
ruleset + `${ selector }{${ declarations.join( ';' ) };}`;
|
|
@@ -579,7 +651,7 @@ export const toStyles = (
|
|
|
579
651
|
|
|
580
652
|
// `selector` maybe provided in a form
|
|
581
653
|
// where block level selectors have sub element
|
|
582
|
-
// selectors appended to them as a comma
|
|
654
|
+
// selectors appended to them as a comma separated
|
|
583
655
|
// string.
|
|
584
656
|
// e.g. `h1 a,h2 a,h3 a,h4 a,h5 a,h6 a`;
|
|
585
657
|
// Split and append pseudo selector to create
|
|
@@ -645,7 +717,7 @@ export function toSvgFilters( tree, blockSelectors ) {
|
|
|
645
717
|
} );
|
|
646
718
|
}
|
|
647
719
|
|
|
648
|
-
const getBlockSelectors = ( blockTypes ) => {
|
|
720
|
+
export const getBlockSelectors = ( blockTypes ) => {
|
|
649
721
|
const result = {};
|
|
650
722
|
blockTypes.forEach( ( blockType ) => {
|
|
651
723
|
const name = blockType.name;
|
|
@@ -657,9 +729,29 @@ const getBlockSelectors = ( blockTypes ) => {
|
|
|
657
729
|
const hasLayoutSupport = !! blockType?.supports?.__experimentalLayout;
|
|
658
730
|
const fallbackGapValue =
|
|
659
731
|
blockType?.supports?.spacing?.blockGap?.__experimentalDefault;
|
|
732
|
+
|
|
733
|
+
// For each block support feature add any custom selectors.
|
|
734
|
+
const featureSelectors = {};
|
|
735
|
+
Object.entries( BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS ).forEach(
|
|
736
|
+
( [ featureKey, featureName ] ) => {
|
|
737
|
+
const featureSelector =
|
|
738
|
+
blockType?.supports?.[ featureKey ]?.__experimentalSelector;
|
|
739
|
+
|
|
740
|
+
if ( featureSelector ) {
|
|
741
|
+
featureSelectors[ featureName ] = scopeSelector(
|
|
742
|
+
selector,
|
|
743
|
+
featureSelector
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
);
|
|
748
|
+
|
|
660
749
|
result[ name ] = {
|
|
661
750
|
duotoneSelector,
|
|
662
751
|
fallbackGapValue,
|
|
752
|
+
featureSelectors: Object.keys( featureSelectors ).length
|
|
753
|
+
? featureSelectors
|
|
754
|
+
: undefined,
|
|
663
755
|
hasLayoutSupport,
|
|
664
756
|
name,
|
|
665
757
|
selector,
|
|
@@ -255,3 +255,34 @@ export function getValueFromVariable( features, blockName, variable ) {
|
|
|
255
255
|
}
|
|
256
256
|
return variable;
|
|
257
257
|
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Function that scopes a selector with another one. This works a bit like
|
|
261
|
+
* SCSS nesting except the `&` operator isn't supported.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```js
|
|
265
|
+
* const scope = '.a, .b .c';
|
|
266
|
+
* const selector = '> .x, .y';
|
|
267
|
+
* const merged = scopeSelector( scope, selector );
|
|
268
|
+
* // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y'
|
|
269
|
+
* ```
|
|
270
|
+
*
|
|
271
|
+
* @param {string} scope Selector to scope to.
|
|
272
|
+
* @param {string} selector Original selector.
|
|
273
|
+
*
|
|
274
|
+
* @return {string} Scoped selector.
|
|
275
|
+
*/
|
|
276
|
+
export function scopeSelector( scope, selector ) {
|
|
277
|
+
const scopes = scope.split( ',' );
|
|
278
|
+
const selectors = selector.split( ',' );
|
|
279
|
+
|
|
280
|
+
const selectorsScoped = [];
|
|
281
|
+
scopes.forEach( ( outer ) => {
|
|
282
|
+
selectors.forEach( ( inner ) => {
|
|
283
|
+
selectorsScoped.push( `${ outer.trim() } ${ inner.trim() }` );
|
|
284
|
+
} );
|
|
285
|
+
} );
|
|
286
|
+
|
|
287
|
+
return selectorsScoped.join( ', ' );
|
|
288
|
+
}
|
|
@@ -106,6 +106,13 @@ export default function Header( {
|
|
|
106
106
|
|
|
107
107
|
const isFocusMode = templateType === 'wp_template_part';
|
|
108
108
|
|
|
109
|
+
/* translators: button label text should, if possible, be under 16 characters. */
|
|
110
|
+
const longLabel = _x(
|
|
111
|
+
'Toggle block inserter',
|
|
112
|
+
'Generic label for block inserter button'
|
|
113
|
+
);
|
|
114
|
+
const shortLabel = ! isInserterOpen ? __( 'Add' ) : __( 'Close' );
|
|
115
|
+
|
|
109
116
|
return (
|
|
110
117
|
<div className="edit-site-header">
|
|
111
118
|
<NavigableToolbar
|
|
@@ -123,17 +130,9 @@ export default function Header( {
|
|
|
123
130
|
onClick={ openInserter }
|
|
124
131
|
disabled={ ! isVisualMode }
|
|
125
132
|
icon={ plus }
|
|
126
|
-
|
|
127
|
-
characters. */
|
|
128
|
-
label={ _x(
|
|
129
|
-
'Toggle block inserter',
|
|
130
|
-
'Generic label for block inserter button'
|
|
131
|
-
) }
|
|
133
|
+
label={ showIconLabels ? shortLabel : longLabel }
|
|
132
134
|
showTooltip={ ! showIconLabels }
|
|
133
|
-
|
|
134
|
-
{ showIconLabels &&
|
|
135
|
-
( ! isInserterOpen ? __( 'Add' ) : __( 'Close' ) ) }
|
|
136
|
-
</ToolbarItem>
|
|
135
|
+
/>
|
|
137
136
|
{ isLargeViewport && (
|
|
138
137
|
<>
|
|
139
138
|
<ToolbarItem
|