@wordpress/block-editor 15.7.1-next.2f1c7c01b.0 → 15.8.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/block-card/index.js +76 -34
- package/build/components/block-card/index.js.map +2 -2
- package/build/components/block-inspector/edit-contents.js +72 -0
- package/build/components/block-inspector/edit-contents.js.map +7 -0
- package/build/components/block-inspector/index.js +32 -9
- package/build/components/block-inspector/index.js.map +3 -3
- package/build/components/block-list/index.js +9 -9
- package/build/components/block-list/index.js.map +2 -2
- package/build/components/block-switcher/index.js +24 -123
- package/build/components/block-switcher/index.js.map +3 -3
- package/build/components/block-toolbar/block-toolbar-icon.js +175 -0
- package/build/components/block-toolbar/block-toolbar-icon.js.map +7 -0
- package/build/components/block-toolbar/index.js +51 -53
- package/build/components/block-toolbar/index.js.map +3 -3
- package/build/components/block-toolbar/pattern-overrides-dropdown.js +93 -0
- package/build/components/block-toolbar/pattern-overrides-dropdown.js.map +7 -0
- package/build/components/block-tools/index.js +10 -3
- package/build/components/block-tools/index.js.map +2 -2
- package/build/components/border-radius-control/utils.js +7 -3
- package/build/components/border-radius-control/utils.js.map +2 -2
- package/build/components/content-lock/modify-content-lock-menu-item.js +3 -3
- package/build/components/content-lock/modify-content-lock-menu-item.js.map +2 -2
- package/build/components/global-styles/border-panel.js +11 -7
- package/build/components/global-styles/border-panel.js.map +2 -2
- package/build/components/global-styles/color-panel.js +35 -27
- package/build/components/global-styles/color-panel.js.map +2 -2
- package/build/components/global-styles/typography-panel.js +3 -2
- package/build/components/global-styles/typography-panel.js.map +2 -2
- package/build/components/inserter/media-tab/media-tab.js +2 -1
- package/build/components/inserter/media-tab/media-tab.js.map +2 -2
- package/build/components/inspector-controls-tabs/index.js +2 -1
- package/build/components/inspector-controls-tabs/index.js.map +2 -2
- package/build/components/inspector-controls-tabs/styles-tab.js +55 -1
- package/build/components/inspector-controls-tabs/styles-tab.js.map +3 -3
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
- package/build/components/keyboard-shortcuts/index.js +8 -0
- package/build/components/keyboard-shortcuts/index.js.map +2 -2
- package/build/components/rich-text/index.js +1 -0
- package/build/components/rich-text/index.js.map +2 -2
- package/build/hooks/border.js +10 -5
- package/build/hooks/border.js.map +3 -3
- package/build/hooks/color.js +31 -9
- package/build/hooks/color.js.map +3 -3
- package/build/hooks/content-lock-ui.js +4 -5
- package/build/hooks/content-lock-ui.js.map +2 -2
- package/build/hooks/dimensions.js +9 -4
- package/build/hooks/dimensions.js.map +2 -2
- package/build/hooks/fit-text.js +19 -75
- package/build/hooks/fit-text.js.map +3 -3
- package/build/hooks/font-size.js +5 -2
- package/build/hooks/font-size.js.map +2 -2
- package/build/hooks/layout.js +4 -1
- package/build/hooks/layout.js.map +2 -2
- package/build/hooks/spacing-visualizer.js +5 -0
- package/build/hooks/spacing-visualizer.js.map +2 -2
- package/build/hooks/typography.js +23 -14
- package/build/hooks/typography.js.map +3 -3
- package/build/store/private-selectors.js +21 -1
- package/build/store/private-selectors.js.map +2 -2
- package/build/store/reducer.js +4 -0
- package/build/store/reducer.js.map +2 -2
- package/build/store/selectors.js +9 -3
- package/build/store/selectors.js.map +2 -2
- package/build/utils/fit-text-frontend.js +1 -0
- package/build/utils/fit-text-frontend.js.map +2 -2
- package/build/utils/fit-text-utils.js +1 -1
- package/build/utils/fit-text-utils.js.map +1 -1
- package/build-module/components/block-card/index.js +82 -32
- package/build-module/components/block-card/index.js.map +2 -2
- package/build-module/components/block-inspector/edit-contents.js +51 -0
- package/build-module/components/block-inspector/edit-contents.js.map +7 -0
- package/build-module/components/block-inspector/index.js +32 -9
- package/build-module/components/block-inspector/index.js.map +2 -2
- package/build-module/components/block-list/index.js +11 -11
- package/build-module/components/block-list/index.js.map +2 -2
- package/build-module/components/block-switcher/index.js +24 -124
- package/build-module/components/block-switcher/index.js.map +2 -2
- package/build-module/components/block-toolbar/block-toolbar-icon.js +144 -0
- package/build-module/components/block-toolbar/block-toolbar-icon.js.map +7 -0
- package/build-module/components/block-toolbar/index.js +51 -53
- package/build-module/components/block-toolbar/index.js.map +2 -2
- package/build-module/components/block-toolbar/pattern-overrides-dropdown.js +76 -0
- package/build-module/components/block-toolbar/pattern-overrides-dropdown.js.map +7 -0
- package/build-module/components/block-tools/index.js +10 -3
- package/build-module/components/block-tools/index.js.map +2 -2
- package/build-module/components/border-radius-control/utils.js +7 -3
- package/build-module/components/border-radius-control/utils.js.map +2 -2
- package/build-module/components/content-lock/modify-content-lock-menu-item.js +3 -3
- package/build-module/components/content-lock/modify-content-lock-menu-item.js.map +2 -2
- package/build-module/components/global-styles/border-panel.js +11 -7
- package/build-module/components/global-styles/border-panel.js.map +2 -2
- package/build-module/components/global-styles/color-panel.js +34 -27
- package/build-module/components/global-styles/color-panel.js.map +2 -2
- package/build-module/components/global-styles/typography-panel.js +3 -2
- package/build-module/components/global-styles/typography-panel.js.map +2 -2
- package/build-module/components/inserter/media-tab/media-tab.js +2 -1
- package/build-module/components/inserter/media-tab/media-tab.js.map +2 -2
- package/build-module/components/inspector-controls-tabs/index.js +2 -1
- package/build-module/components/inspector-controls-tabs/index.js.map +2 -2
- package/build-module/components/inspector-controls-tabs/styles-tab.js +55 -1
- package/build-module/components/inspector-controls-tabs/styles-tab.js.map +2 -2
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
- package/build-module/components/keyboard-shortcuts/index.js +8 -0
- package/build-module/components/keyboard-shortcuts/index.js.map +2 -2
- package/build-module/components/rich-text/index.js +1 -0
- package/build-module/components/rich-text/index.js.map +2 -2
- package/build-module/hooks/border.js +10 -5
- package/build-module/hooks/border.js.map +3 -3
- package/build-module/hooks/color.js +31 -9
- package/build-module/hooks/color.js.map +3 -3
- package/build-module/hooks/content-lock-ui.js +4 -5
- package/build-module/hooks/content-lock-ui.js.map +2 -2
- package/build-module/hooks/dimensions.js +9 -4
- package/build-module/hooks/dimensions.js.map +2 -2
- package/build-module/hooks/fit-text.js +18 -66
- package/build-module/hooks/fit-text.js.map +2 -2
- package/build-module/hooks/font-size.js +5 -2
- package/build-module/hooks/font-size.js.map +2 -2
- package/build-module/hooks/layout.js +4 -1
- package/build-module/hooks/layout.js.map +2 -2
- package/build-module/hooks/spacing-visualizer.js +5 -0
- package/build-module/hooks/spacing-visualizer.js.map +2 -2
- package/build-module/hooks/typography.js +23 -14
- package/build-module/hooks/typography.js.map +3 -3
- package/build-module/store/private-selectors.js +20 -1
- package/build-module/store/private-selectors.js.map +2 -2
- package/build-module/store/reducer.js +4 -0
- package/build-module/store/reducer.js.map +2 -2
- package/build-module/store/selectors.js +9 -3
- package/build-module/store/selectors.js.map +2 -2
- package/build-module/utils/fit-text-frontend.js +1 -0
- package/build-module/utils/fit-text-frontend.js.map +2 -2
- package/build-module/utils/fit-text-utils.js +1 -1
- package/build-module/utils/fit-text-utils.js.map +1 -1
- package/build-style/style-rtl.css +31 -71
- package/build-style/style.css +31 -71
- package/package.json +37 -37
- package/src/components/block-card/index.js +95 -38
- package/src/components/block-card/style.scss +17 -1
- package/src/components/block-inspector/edit-contents.js +64 -0
- package/src/components/block-inspector/index.js +35 -13
- package/src/components/block-inspector/style.scss +6 -3
- package/src/components/block-list/index.js +11 -9
- package/src/components/block-switcher/index.js +51 -180
- package/src/components/block-switcher/style.scss +0 -70
- package/src/components/block-switcher/test/index.js +17 -18
- package/src/components/block-toolbar/block-toolbar-icon.js +173 -0
- package/src/components/block-toolbar/index.js +50 -52
- package/src/components/block-toolbar/pattern-overrides-dropdown.js +99 -0
- package/src/components/block-toolbar/style.scss +21 -21
- package/src/components/block-toolbar/test/block-toolbar-icon.js +182 -0
- package/src/components/block-tools/index.js +11 -1
- package/src/components/border-radius-control/test/utils.js +90 -0
- package/src/components/border-radius-control/utils.js +7 -3
- package/src/components/content-lock/modify-content-lock-menu-item.js +9 -3
- package/src/components/global-styles/border-panel.js +11 -7
- package/src/components/global-styles/color-panel.js +32 -26
- package/src/components/global-styles/typography-panel.js +2 -1
- package/src/components/inserter/media-tab/media-tab.js +7 -1
- package/src/components/inspector-controls-tabs/index.js +1 -0
- package/src/components/inspector-controls-tabs/styles-tab.js +58 -0
- package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +5 -1
- package/src/components/keyboard-shortcuts/index.js +9 -0
- package/src/components/rich-text/index.js +1 -0
- package/src/hooks/border.js +12 -6
- package/src/hooks/color.js +40 -13
- package/src/hooks/content-lock-ui.js +9 -6
- package/src/hooks/dimensions.js +25 -17
- package/src/hooks/fit-text.js +23 -84
- package/src/hooks/font-size.js +7 -2
- package/src/hooks/layout.js +11 -7
- package/src/hooks/spacing-visualizer.js +9 -1
- package/src/hooks/typography.js +24 -18
- package/src/store/private-selectors.js +26 -1
- package/src/store/reducer.js +6 -0
- package/src/store/selectors.js +17 -3
- package/src/utils/fit-text-frontend.js +1 -0
- package/src/utils/fit-text-utils.js +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/components/block-inspector/edit-contents-button.js +0 -61
- package/build/components/block-inspector/edit-contents-button.js.map +0 -7
- package/build-module/components/block-inspector/edit-contents-button.js +0 -40
- package/build-module/components/block-inspector/edit-contents-button.js.map +0 -7
- package/src/components/block-inspector/edit-contents-button.js +0 -46
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { paragraph } from '@wordpress/icons';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
import BlockToolbarIcon from '../block-toolbar-icon';
|
|
16
|
+
|
|
17
|
+
jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() );
|
|
18
|
+
jest.mock( '../../block-title/use-block-display-title', () =>
|
|
19
|
+
jest.fn().mockReturnValue( 'Block Name' )
|
|
20
|
+
);
|
|
21
|
+
jest.mock( '../../block-switcher', () =>
|
|
22
|
+
jest.fn( ( { children } ) => (
|
|
23
|
+
<div data-testid="block-switcher">{ children }</div>
|
|
24
|
+
) )
|
|
25
|
+
);
|
|
26
|
+
jest.mock( '../pattern-overrides-dropdown', () =>
|
|
27
|
+
jest.fn( ( { clientIds } ) => (
|
|
28
|
+
<div data-testid="pattern-overrides-dropdown">
|
|
29
|
+
{ clientIds.length === 1
|
|
30
|
+
? 'Block Name'
|
|
31
|
+
: 'Multiple blocks selected' }
|
|
32
|
+
</div>
|
|
33
|
+
) )
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
describe( 'BlockToolbarIcon', () => {
|
|
37
|
+
const defaultProps = {
|
|
38
|
+
clientIds: [ 'test-client-id' ],
|
|
39
|
+
isSynced: false,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
beforeEach( () => {
|
|
43
|
+
jest.clearAllMocks();
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
describe( 'when variant is "switcher"', () => {
|
|
47
|
+
it( 'should render BlockSwitcher with icon', () => {
|
|
48
|
+
useSelect.mockImplementation( () => ( {
|
|
49
|
+
icon: paragraph,
|
|
50
|
+
showIconLabels: false,
|
|
51
|
+
variant: 'switcher',
|
|
52
|
+
} ) );
|
|
53
|
+
|
|
54
|
+
render( <BlockToolbarIcon { ...defaultProps } /> );
|
|
55
|
+
|
|
56
|
+
expect(
|
|
57
|
+
screen.getByTestId( 'block-switcher' )
|
|
58
|
+
).toBeInTheDocument();
|
|
59
|
+
expect(
|
|
60
|
+
screen.queryByTestId( 'pattern-overrides-dropdown' )
|
|
61
|
+
).not.toBeInTheDocument();
|
|
62
|
+
} );
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
describe( 'when variant is "pattern-overrides"', () => {
|
|
66
|
+
it( 'should render PatternOverridesDropdown for single block', () => {
|
|
67
|
+
useSelect.mockImplementation( () => ( {
|
|
68
|
+
icon: paragraph,
|
|
69
|
+
showIconLabels: false,
|
|
70
|
+
variant: 'pattern-overrides',
|
|
71
|
+
} ) );
|
|
72
|
+
|
|
73
|
+
render( <BlockToolbarIcon { ...defaultProps } /> );
|
|
74
|
+
|
|
75
|
+
const dropdown = screen.getByTestId( 'pattern-overrides-dropdown' );
|
|
76
|
+
expect( dropdown ).toBeInTheDocument();
|
|
77
|
+
expect( dropdown ).toHaveTextContent( 'Block Name' );
|
|
78
|
+
expect(
|
|
79
|
+
screen.queryByTestId( 'block-switcher' )
|
|
80
|
+
).not.toBeInTheDocument();
|
|
81
|
+
} );
|
|
82
|
+
|
|
83
|
+
it( 'should render PatternOverridesDropdown for multiple blocks', () => {
|
|
84
|
+
useSelect.mockImplementation( () => ( {
|
|
85
|
+
icon: paragraph,
|
|
86
|
+
showIconLabels: false,
|
|
87
|
+
variant: 'pattern-overrides',
|
|
88
|
+
} ) );
|
|
89
|
+
|
|
90
|
+
render(
|
|
91
|
+
<BlockToolbarIcon
|
|
92
|
+
{ ...defaultProps }
|
|
93
|
+
clientIds={ [ 'test-1', 'test-2' ] }
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const dropdown = screen.getByTestId( 'pattern-overrides-dropdown' );
|
|
98
|
+
expect( dropdown ).toBeInTheDocument();
|
|
99
|
+
expect( dropdown ).toHaveTextContent( 'Multiple blocks selected' );
|
|
100
|
+
} );
|
|
101
|
+
} );
|
|
102
|
+
|
|
103
|
+
describe( 'when variant is "default"', () => {
|
|
104
|
+
it( 'should render disabled ToolbarButton for single block', () => {
|
|
105
|
+
useSelect.mockImplementation( () => ( {
|
|
106
|
+
icon: paragraph,
|
|
107
|
+
showIconLabels: false,
|
|
108
|
+
variant: 'default',
|
|
109
|
+
} ) );
|
|
110
|
+
|
|
111
|
+
render( <BlockToolbarIcon { ...defaultProps } /> );
|
|
112
|
+
|
|
113
|
+
const button = screen.getByRole( 'button' );
|
|
114
|
+
expect( button ).toHaveAttribute( 'aria-disabled', 'true' );
|
|
115
|
+
expect( button ).toHaveAttribute( 'aria-label', 'Block Name' );
|
|
116
|
+
expect(
|
|
117
|
+
screen.queryByTestId( 'block-switcher' )
|
|
118
|
+
).not.toBeInTheDocument();
|
|
119
|
+
expect(
|
|
120
|
+
screen.queryByTestId( 'pattern-overrides-dropdown' )
|
|
121
|
+
).not.toBeInTheDocument();
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
it( 'should render disabled ToolbarButton for multiple blocks', () => {
|
|
125
|
+
useSelect.mockImplementation( () => ( {
|
|
126
|
+
icon: paragraph,
|
|
127
|
+
showIconLabels: false,
|
|
128
|
+
variant: 'default',
|
|
129
|
+
} ) );
|
|
130
|
+
|
|
131
|
+
render(
|
|
132
|
+
<BlockToolbarIcon
|
|
133
|
+
{ ...defaultProps }
|
|
134
|
+
clientIds={ [ 'test-1', 'test-2', 'test-3' ] }
|
|
135
|
+
/>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const button = screen.getByRole( 'button' );
|
|
139
|
+
expect( button ).toHaveAttribute( 'aria-disabled', 'true' );
|
|
140
|
+
expect( button ).toHaveAttribute(
|
|
141
|
+
'aria-label',
|
|
142
|
+
'Multiple blocks selected'
|
|
143
|
+
);
|
|
144
|
+
} );
|
|
145
|
+
} );
|
|
146
|
+
|
|
147
|
+
describe( 'label calculation', () => {
|
|
148
|
+
it( 'should use block title for single block', () => {
|
|
149
|
+
useSelect.mockImplementation( () => ( {
|
|
150
|
+
icon: paragraph,
|
|
151
|
+
showIconLabels: false,
|
|
152
|
+
variant: 'default',
|
|
153
|
+
} ) );
|
|
154
|
+
|
|
155
|
+
render( <BlockToolbarIcon { ...defaultProps } /> );
|
|
156
|
+
|
|
157
|
+
const button = screen.getByRole( 'button' );
|
|
158
|
+
expect( button ).toHaveAttribute( 'aria-label', 'Block Name' );
|
|
159
|
+
} );
|
|
160
|
+
|
|
161
|
+
it( 'should use "Multiple blocks selected" for multiple blocks', () => {
|
|
162
|
+
useSelect.mockImplementation( () => ( {
|
|
163
|
+
icon: paragraph,
|
|
164
|
+
showIconLabels: false,
|
|
165
|
+
variant: 'default',
|
|
166
|
+
} ) );
|
|
167
|
+
|
|
168
|
+
render(
|
|
169
|
+
<BlockToolbarIcon
|
|
170
|
+
{ ...defaultProps }
|
|
171
|
+
clientIds={ [ 'test-1', 'test-2' ] }
|
|
172
|
+
/>
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const button = screen.getByRole( 'button' );
|
|
176
|
+
expect( button ).toHaveAttribute(
|
|
177
|
+
'aria-label',
|
|
178
|
+
'Multiple blocks selected'
|
|
179
|
+
);
|
|
180
|
+
} );
|
|
181
|
+
} );
|
|
182
|
+
} );
|
|
@@ -77,7 +77,8 @@ export default function BlockTools( {
|
|
|
77
77
|
getBlockRootClientId,
|
|
78
78
|
isGroupable,
|
|
79
79
|
getBlockName,
|
|
80
|
-
|
|
80
|
+
getEditedContentOnlySection,
|
|
81
|
+
} = unlock( useSelect( blockEditorStore ) );
|
|
81
82
|
const { getGroupingBlockName } = useSelect( blocksStore );
|
|
82
83
|
const { showEmptyBlockSideInserter, showBlockToolbarPopover } =
|
|
83
84
|
useShowBlockTools();
|
|
@@ -94,6 +95,7 @@ export default function BlockTools( {
|
|
|
94
95
|
moveBlocksDown,
|
|
95
96
|
expandBlock,
|
|
96
97
|
updateBlockAttributes,
|
|
98
|
+
stopEditingContentOnlySection,
|
|
97
99
|
} = unlock( useDispatch( blockEditorStore ) );
|
|
98
100
|
|
|
99
101
|
function onKeyDown( event ) {
|
|
@@ -246,6 +248,14 @@ export default function BlockTools( {
|
|
|
246
248
|
} );
|
|
247
249
|
}
|
|
248
250
|
}
|
|
251
|
+
|
|
252
|
+
// Has the same keyboard shortcut as 'unselect', so can't be within the
|
|
253
|
+
// if/else chain above.
|
|
254
|
+
if ( isMatch( 'core/block-editor/stop-editing-as-blocks', event ) ) {
|
|
255
|
+
if ( getEditedContentOnlySection() ) {
|
|
256
|
+
stopEditingContentOnlySection();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
249
259
|
}
|
|
250
260
|
const blockToolbarRef = usePopoverScroll( __unstableContentRef );
|
|
251
261
|
const blockToolbarAfterRef = usePopoverScroll( __unstableContentRef );
|
|
@@ -107,6 +107,96 @@ describe( 'getAllValue', () => {
|
|
|
107
107
|
expect( getAllValue( undefined ) ).toBe( undefined );
|
|
108
108
|
} );
|
|
109
109
|
} );
|
|
110
|
+
|
|
111
|
+
describe( 'when provided complex CSS values (clamp, min, max, calc)', () => {
|
|
112
|
+
it( 'should preserve clamp values when all corners have the same clamp value', () => {
|
|
113
|
+
const clampValue = 'clamp(1rem, 2vw, 3rem)';
|
|
114
|
+
const values = {
|
|
115
|
+
bottomLeft: clampValue,
|
|
116
|
+
bottomRight: clampValue,
|
|
117
|
+
topLeft: clampValue,
|
|
118
|
+
topRight: clampValue,
|
|
119
|
+
};
|
|
120
|
+
expect( getAllValue( values ) ).toBe( clampValue );
|
|
121
|
+
} );
|
|
122
|
+
|
|
123
|
+
it( 'should preserve min() values when all corners have the same min value', () => {
|
|
124
|
+
const minValue = 'min(10px, 5vw)';
|
|
125
|
+
const values = {
|
|
126
|
+
bottomLeft: minValue,
|
|
127
|
+
bottomRight: minValue,
|
|
128
|
+
topLeft: minValue,
|
|
129
|
+
topRight: minValue,
|
|
130
|
+
};
|
|
131
|
+
expect( getAllValue( values ) ).toBe( minValue );
|
|
132
|
+
} );
|
|
133
|
+
|
|
134
|
+
it( 'should preserve max() values when all corners have the same max value', () => {
|
|
135
|
+
const maxValue = 'max(20px, 10vw)';
|
|
136
|
+
const values = {
|
|
137
|
+
bottomLeft: maxValue,
|
|
138
|
+
bottomRight: maxValue,
|
|
139
|
+
topLeft: maxValue,
|
|
140
|
+
topRight: maxValue,
|
|
141
|
+
};
|
|
142
|
+
expect( getAllValue( values ) ).toBe( maxValue );
|
|
143
|
+
} );
|
|
144
|
+
|
|
145
|
+
it( 'should preserve calc() values when all corners have the same calc value', () => {
|
|
146
|
+
const calcValue = 'calc(100% - 20px)';
|
|
147
|
+
const values = {
|
|
148
|
+
bottomLeft: calcValue,
|
|
149
|
+
bottomRight: calcValue,
|
|
150
|
+
topLeft: calcValue,
|
|
151
|
+
topRight: calcValue,
|
|
152
|
+
};
|
|
153
|
+
expect( getAllValue( values ) ).toBe( calcValue );
|
|
154
|
+
} );
|
|
155
|
+
|
|
156
|
+
it( 'should return undefined when complex CSS values are mixed', () => {
|
|
157
|
+
const values = {
|
|
158
|
+
bottomLeft: 'clamp(1rem, 2vw, 3rem)',
|
|
159
|
+
bottomRight: 'clamp(1rem, 2vw, 3rem)',
|
|
160
|
+
topLeft: 'min(10px, 5vw)',
|
|
161
|
+
topRight: 'clamp(1rem, 2vw, 3rem)',
|
|
162
|
+
};
|
|
163
|
+
expect( getAllValue( values ) ).toBe( undefined );
|
|
164
|
+
} );
|
|
165
|
+
|
|
166
|
+
it( 'should return undefined when complex CSS values are mixed with simple values', () => {
|
|
167
|
+
const values = {
|
|
168
|
+
bottomLeft: 'clamp(1rem, 2vw, 3rem)',
|
|
169
|
+
bottomRight: 'clamp(1rem, 2vw, 3rem)',
|
|
170
|
+
topLeft: '2px',
|
|
171
|
+
topRight: 'clamp(1rem, 2vw, 3rem)',
|
|
172
|
+
};
|
|
173
|
+
expect( getAllValue( values ) ).toBe( undefined );
|
|
174
|
+
} );
|
|
175
|
+
|
|
176
|
+
it( 'should preserve string values that cannot be parsed at all (no numeric prefix)', () => {
|
|
177
|
+
// Values with no numeric prefix cannot be parsed, so they should be preserved
|
|
178
|
+
const unparseableValue = 'apples';
|
|
179
|
+
const values = {
|
|
180
|
+
bottomLeft: unparseableValue,
|
|
181
|
+
bottomRight: unparseableValue,
|
|
182
|
+
topLeft: unparseableValue,
|
|
183
|
+
topRight: unparseableValue,
|
|
184
|
+
};
|
|
185
|
+
expect( getAllValue( values ) ).toBe( unparseableValue );
|
|
186
|
+
} );
|
|
187
|
+
|
|
188
|
+
it( 'should parse numeric prefix from partially parseable values', () => {
|
|
189
|
+
// Values with numeric prefix get parsed, so "32apples" becomes "32"
|
|
190
|
+
const partiallyParseableValue = '32apples';
|
|
191
|
+
const values = {
|
|
192
|
+
bottomLeft: partiallyParseableValue,
|
|
193
|
+
bottomRight: partiallyParseableValue,
|
|
194
|
+
topLeft: partiallyParseableValue,
|
|
195
|
+
topRight: partiallyParseableValue,
|
|
196
|
+
};
|
|
197
|
+
expect( getAllValue( values ) ).toBe( '32' );
|
|
198
|
+
} );
|
|
199
|
+
} );
|
|
110
200
|
} );
|
|
111
201
|
|
|
112
202
|
describe( 'hasMixedValues', () => {
|
|
@@ -60,9 +60,13 @@ export function getAllValue( values = {} ) {
|
|
|
60
60
|
return values;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
const parsedQuantitiesAndUnits = Object.values( values ).map( ( value ) =>
|
|
64
|
-
parseQuantityAndUnitFromRawValue( value )
|
|
65
|
-
|
|
63
|
+
const parsedQuantitiesAndUnits = Object.values( values ).map( ( value ) => {
|
|
64
|
+
const newValue = parseQuantityAndUnitFromRawValue( value );
|
|
65
|
+
if ( typeof value === 'string' && newValue[ 0 ] === undefined ) {
|
|
66
|
+
return [ value, '' ];
|
|
67
|
+
}
|
|
68
|
+
return newValue;
|
|
69
|
+
} );
|
|
66
70
|
|
|
67
71
|
const allValues = parsedQuantitiesAndUnits.map(
|
|
68
72
|
( value ) => value[ 0 ] ?? ''
|
|
@@ -38,16 +38,22 @@ export function ModifyContentOnlySectionMenuItem( { clientId, onClose } ) {
|
|
|
38
38
|
const blockEditorActions = useDispatch( blockEditorStore );
|
|
39
39
|
const isContentLocked =
|
|
40
40
|
! isLockedByParent && templateLock === 'contentOnly';
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
// Hide the Modify button when the content only pattern insertion experiment is active.
|
|
43
|
+
// This is replaced by an alternative UI in the experiment.
|
|
44
|
+
if (
|
|
45
|
+
window?.__experimentalContentOnlyPatternInsertion ||
|
|
46
|
+
( ! isContentLocked && ! isEditingContentOnlySection )
|
|
47
|
+
) {
|
|
42
48
|
return null;
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
const { editContentOnlySection } = unlock( blockEditorActions );
|
|
46
|
-
const
|
|
52
|
+
const showContentOnlyModifyButton =
|
|
47
53
|
! isEditingContentOnlySection && isContentLocked;
|
|
48
54
|
|
|
49
55
|
return (
|
|
50
|
-
|
|
56
|
+
showContentOnlyModifyButton && (
|
|
51
57
|
<MenuItem
|
|
52
58
|
onClick={ () => {
|
|
53
59
|
editContentOnlySection( clientId );
|
|
@@ -147,17 +147,21 @@ export default function BorderPanel( {
|
|
|
147
147
|
// Border radius.
|
|
148
148
|
const showBorderRadius = useHasBorderRadiusControl( settings );
|
|
149
149
|
const borderRadiusValues = useMemo( () => {
|
|
150
|
-
if ( typeof border?.radius !== 'object' ) {
|
|
151
|
-
return border?.radius;
|
|
150
|
+
if ( typeof inheritedValue?.border?.radius !== 'object' ) {
|
|
151
|
+
return decodeValue( inheritedValue?.border?.radius );
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
return {
|
|
155
|
-
topLeft: border?.radius?.topLeft,
|
|
156
|
-
topRight: border?.radius?.topRight,
|
|
157
|
-
bottomLeft:
|
|
158
|
-
|
|
155
|
+
topLeft: decodeValue( inheritedValue?.border?.radius?.topLeft ),
|
|
156
|
+
topRight: decodeValue( inheritedValue?.border?.radius?.topRight ),
|
|
157
|
+
bottomLeft: decodeValue(
|
|
158
|
+
inheritedValue?.border?.radius?.bottomLeft
|
|
159
|
+
),
|
|
160
|
+
bottomRight: decodeValue(
|
|
161
|
+
inheritedValue?.border?.radius?.bottomRight
|
|
162
|
+
),
|
|
159
163
|
};
|
|
160
|
-
}, [ border?.radius ] );
|
|
164
|
+
}, [ inheritedValue?.border?.radius, decodeValue ] );
|
|
161
165
|
const setBorderRadius = ( newBorderRadius ) =>
|
|
162
166
|
setBorder( { ...border, radius: newBorderRadius } );
|
|
163
167
|
const hasBorderRadius = () => {
|
|
@@ -111,12 +111,13 @@ export function useHasBackgroundColorPanel( settings ) {
|
|
|
111
111
|
);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
function ColorToolsPanel( {
|
|
114
|
+
export function ColorToolsPanel( {
|
|
115
115
|
resetAllFilter,
|
|
116
116
|
onChange,
|
|
117
117
|
value,
|
|
118
118
|
panelId,
|
|
119
119
|
children,
|
|
120
|
+
label,
|
|
120
121
|
} ) {
|
|
121
122
|
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
|
|
122
123
|
const resetAll = () => {
|
|
@@ -126,7 +127,7 @@ function ColorToolsPanel( {
|
|
|
126
127
|
|
|
127
128
|
return (
|
|
128
129
|
<ToolsPanel
|
|
129
|
-
label={ __( 'Elements' ) }
|
|
130
|
+
label={ label || __( 'Elements' ) }
|
|
130
131
|
resetAll={ resetAll }
|
|
131
132
|
panelId={ panelId }
|
|
132
133
|
hasInnerWrapper
|
|
@@ -326,6 +327,7 @@ export default function ColorPanel( {
|
|
|
326
327
|
settings,
|
|
327
328
|
panelId,
|
|
328
329
|
defaultControls = DEFAULT_CONTROLS,
|
|
330
|
+
label,
|
|
329
331
|
children,
|
|
330
332
|
} ) {
|
|
331
333
|
const colors = useColorsPerOrigin( settings );
|
|
@@ -511,31 +513,34 @@ export default function ColorPanel( {
|
|
|
511
513
|
},
|
|
512
514
|
];
|
|
513
515
|
|
|
514
|
-
const resetAllFilter = useCallback(
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
':hover': {
|
|
516
|
+
const resetAllFilter = useCallback(
|
|
517
|
+
( previousValue ) => {
|
|
518
|
+
return {
|
|
519
|
+
...previousValue,
|
|
520
|
+
color: undefined,
|
|
521
|
+
elements: {
|
|
522
|
+
...previousValue?.elements,
|
|
523
|
+
link: {
|
|
524
|
+
...previousValue?.elements?.link,
|
|
524
525
|
color: undefined,
|
|
525
|
-
|
|
526
|
-
},
|
|
527
|
-
...elements.reduce( ( acc, element ) => {
|
|
528
|
-
return {
|
|
529
|
-
...acc,
|
|
530
|
-
[ element.name ]: {
|
|
531
|
-
...previousValue?.elements?.[ element.name ],
|
|
526
|
+
':hover': {
|
|
532
527
|
color: undefined,
|
|
533
528
|
},
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
529
|
+
},
|
|
530
|
+
...elements.reduce( ( acc, element ) => {
|
|
531
|
+
return {
|
|
532
|
+
...acc,
|
|
533
|
+
[ element.name ]: {
|
|
534
|
+
...previousValue?.elements?.[ element.name ],
|
|
535
|
+
color: undefined,
|
|
536
|
+
},
|
|
537
|
+
};
|
|
538
|
+
}, {} ),
|
|
539
|
+
},
|
|
540
|
+
};
|
|
541
|
+
},
|
|
542
|
+
[ elements ]
|
|
543
|
+
);
|
|
539
544
|
|
|
540
545
|
const items = [
|
|
541
546
|
showTextPanel && {
|
|
@@ -606,7 +611,7 @@ export default function ColorPanel( {
|
|
|
606
611
|
},
|
|
607
612
|
].filter( Boolean );
|
|
608
613
|
|
|
609
|
-
elements.forEach( ( { name, label, showPanel } ) => {
|
|
614
|
+
elements.forEach( ( { name, label: elementLabel, showPanel } ) => {
|
|
610
615
|
if ( ! showPanel ) {
|
|
611
616
|
return;
|
|
612
617
|
}
|
|
@@ -680,7 +685,7 @@ export default function ColorPanel( {
|
|
|
680
685
|
|
|
681
686
|
items.push( {
|
|
682
687
|
key: name,
|
|
683
|
-
label,
|
|
688
|
+
label: elementLabel,
|
|
684
689
|
hasValue: hasElement,
|
|
685
690
|
resetValue: resetElement,
|
|
686
691
|
isShownByDefault: defaultControls[ name ],
|
|
@@ -731,6 +736,7 @@ export default function ColorPanel( {
|
|
|
731
736
|
value={ value }
|
|
732
737
|
onChange={ onChange }
|
|
733
738
|
panelId={ panelId }
|
|
739
|
+
label={ label }
|
|
734
740
|
>
|
|
735
741
|
{ items.map( ( item ) => {
|
|
736
742
|
const { key, ...restItem } = item;
|
|
@@ -179,6 +179,7 @@ export default function TypographyPanel( {
|
|
|
179
179
|
settings,
|
|
180
180
|
panelId,
|
|
181
181
|
defaultControls = DEFAULT_CONTROLS,
|
|
182
|
+
fitText = false,
|
|
182
183
|
} ) {
|
|
183
184
|
const decodeValue = ( rawValue ) =>
|
|
184
185
|
getValueFromVariable( { settings }, '', rawValue );
|
|
@@ -448,7 +449,7 @@ export default function TypographyPanel( {
|
|
|
448
449
|
/>
|
|
449
450
|
</ToolsPanelItem>
|
|
450
451
|
) }
|
|
451
|
-
{ hasFontSizeEnabled && (
|
|
452
|
+
{ hasFontSizeEnabled && ! fitText && (
|
|
452
453
|
<ToolsPanelItem
|
|
453
454
|
label={ __( 'Size' ) }
|
|
454
455
|
hasValue={ hasFontSize }
|
|
@@ -77,7 +77,13 @@ function MediaTab( {
|
|
|
77
77
|
if ( ! media?.url ) {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
// When the experimental DataViews media modal is enabled,
|
|
81
|
+
// we need to extract the media type from mime_type (e.g., 'image/jpeg' -> 'image')
|
|
82
|
+
const mediaType =
|
|
83
|
+
window.__experimentalDataViewsMediaModal && media.mime_type
|
|
84
|
+
? media.mime_type.split( '/' )[ 0 ]
|
|
85
|
+
: media.type;
|
|
86
|
+
const [ block ] = getBlockAndPreviewFromMedia( media, mediaType );
|
|
81
87
|
onInsert( block );
|
|
82
88
|
},
|
|
83
89
|
[ onInsert ]
|
|
@@ -105,6 +105,7 @@ export default function InspectorControlsTabs( {
|
|
|
105
105
|
clientId={ clientId }
|
|
106
106
|
hasBlockStyles={ hasBlockStyles }
|
|
107
107
|
isSectionBlock={ isSectionBlock }
|
|
108
|
+
contentClientIds={ contentClientIds }
|
|
108
109
|
/>
|
|
109
110
|
</Tabs.TabPanel>
|
|
110
111
|
<Tabs.TabPanel tabId={ TAB_CONTENT.name } focusable={ false }>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { PanelBody } from '@wordpress/components';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Internal dependencies
|
|
@@ -10,12 +11,61 @@ import { __ } from '@wordpress/i18n';
|
|
|
10
11
|
import BlockStyles from '../block-styles';
|
|
11
12
|
import InspectorControls from '../inspector-controls';
|
|
12
13
|
import { useBorderPanelLabel } from '../../hooks/border';
|
|
14
|
+
import { useBlockSettings } from '../../hooks/utils';
|
|
15
|
+
import { store as blockEditorStore } from '../../store';
|
|
16
|
+
import { ColorEdit } from '../../hooks/color';
|
|
17
|
+
import { ColorToolsPanel } from '../global-styles/color-panel';
|
|
18
|
+
|
|
19
|
+
function SectionBlockColorControls( {
|
|
20
|
+
blockName,
|
|
21
|
+
clientId,
|
|
22
|
+
contentClientIds,
|
|
23
|
+
} ) {
|
|
24
|
+
const settings = useBlockSettings( blockName );
|
|
25
|
+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
26
|
+
|
|
27
|
+
const { hasButton, hasHeading } = useSelect(
|
|
28
|
+
( select ) => {
|
|
29
|
+
const blockNames =
|
|
30
|
+
select( blockEditorStore ).getBlockNamesByClientId(
|
|
31
|
+
contentClientIds
|
|
32
|
+
);
|
|
33
|
+
return {
|
|
34
|
+
hasButton: blockNames.includes( 'core/button' ),
|
|
35
|
+
hasHeading: blockNames.includes( 'core/heading' ),
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
[ contentClientIds ]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const setAttributes = ( newAttributes ) => {
|
|
42
|
+
updateBlockAttributes( clientId, newAttributes );
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<ColorEdit
|
|
47
|
+
clientId={ clientId }
|
|
48
|
+
name={ blockName }
|
|
49
|
+
settings={ settings }
|
|
50
|
+
setAttributes={ setAttributes }
|
|
51
|
+
asWrapper={ ColorToolsPanel }
|
|
52
|
+
label={ __( 'Color' ) }
|
|
53
|
+
defaultControls={ {
|
|
54
|
+
text: true,
|
|
55
|
+
background: true,
|
|
56
|
+
button: hasButton,
|
|
57
|
+
heading: hasHeading,
|
|
58
|
+
} }
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
13
62
|
|
|
14
63
|
const StylesTab = ( {
|
|
15
64
|
blockName,
|
|
16
65
|
clientId,
|
|
17
66
|
hasBlockStyles,
|
|
18
67
|
isSectionBlock,
|
|
68
|
+
contentClientIds,
|
|
19
69
|
} ) => {
|
|
20
70
|
const borderPanelLabel = useBorderPanelLabel( { blockName } );
|
|
21
71
|
|
|
@@ -28,6 +78,14 @@ const StylesTab = ( {
|
|
|
28
78
|
</PanelBody>
|
|
29
79
|
</div>
|
|
30
80
|
) }
|
|
81
|
+
{ isSectionBlock &&
|
|
82
|
+
window?.__experimentalContentOnlyPatternInsertion && (
|
|
83
|
+
<SectionBlockColorControls
|
|
84
|
+
blockName={ blockName }
|
|
85
|
+
clientId={ clientId }
|
|
86
|
+
contentClientIds={ contentClientIds }
|
|
87
|
+
/>
|
|
88
|
+
) }
|
|
31
89
|
{ ! isSectionBlock && (
|
|
32
90
|
<>
|
|
33
91
|
<InspectorControls.Slot
|
|
@@ -99,7 +99,11 @@ export default function useInspectorControlsTabs(
|
|
|
99
99
|
tabs.push( TAB_SETTINGS );
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
if (
|
|
102
|
+
if (
|
|
103
|
+
hasBlockStyles ||
|
|
104
|
+
hasStyleFills ||
|
|
105
|
+
window?.__experimentalContentOnlyPatternInsertion
|
|
106
|
+
) {
|
|
103
107
|
tabs.push( TAB_STYLES );
|
|
104
108
|
}
|
|
105
109
|
|
|
@@ -114,6 +114,15 @@ function KeyboardShortcutsRegister() {
|
|
|
114
114
|
],
|
|
115
115
|
} );
|
|
116
116
|
|
|
117
|
+
registerShortcut( {
|
|
118
|
+
name: 'core/block-editor/stop-editing-as-blocks',
|
|
119
|
+
category: 'block',
|
|
120
|
+
description: __( 'Finish editing a design.' ),
|
|
121
|
+
keyCombination: {
|
|
122
|
+
character: 'escape',
|
|
123
|
+
},
|
|
124
|
+
} );
|
|
125
|
+
|
|
117
126
|
registerShortcut( {
|
|
118
127
|
name: 'core/block-editor/select-all',
|
|
119
128
|
category: 'selection',
|
package/src/hooks/border.js
CHANGED
|
@@ -142,12 +142,18 @@ function BordersInspectorControl( { label, children, resetAllFilter } ) {
|
|
|
142
142
|
|
|
143
143
|
export function BorderPanel( { clientId, name, setAttributes, settings } ) {
|
|
144
144
|
const isEnabled = useHasBorderPanel( settings );
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
const { style, borderColor } = useSelect(
|
|
146
|
+
( select ) => {
|
|
147
|
+
// Early return to avoid subscription when disabled
|
|
148
|
+
if ( ! isEnabled ) {
|
|
149
|
+
return {};
|
|
150
|
+
}
|
|
151
|
+
const { style: _style, borderColor: _borderColor } =
|
|
152
|
+
select( blockEditorStore ).getBlockAttributes( clientId ) || {};
|
|
153
|
+
return { style: _style, borderColor: _borderColor };
|
|
154
|
+
},
|
|
155
|
+
[ clientId, isEnabled ]
|
|
156
|
+
);
|
|
151
157
|
const value = useMemo( () => {
|
|
152
158
|
return attributesToStyle( { style, borderColor } );
|
|
153
159
|
}, [ style, borderColor ] );
|