@wordpress/block-editor 8.3.1 → 8.4.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/README.md +1 -0
- package/build/components/block-list/block-html.js +4 -1
- package/build/components/block-list/block-html.js.map +1 -1
- package/build/components/block-list/block.js +4 -1
- package/build/components/block-list/block.js.map +1 -1
- package/build/components/block-list/use-block-props/use-focus-first-element.js +19 -0
- package/build/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
- package/build/components/block-lock/index.js +32 -0
- package/build/components/block-lock/index.js.map +1 -0
- package/build/components/block-lock/menu-item.js +58 -0
- package/build/components/block-lock/menu-item.js.map +1 -0
- package/build/components/block-lock/modal.js +143 -0
- package/build/components/block-lock/modal.js.map +1 -0
- package/build/components/block-lock/toolbar.js +70 -0
- package/build/components/block-lock/toolbar.js.map +1 -0
- package/build/components/block-settings-menu/block-settings-dropdown.js +26 -6
- package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
- package/build/components/block-settings-menu-controls/index.js +19 -9
- package/build/components/block-settings-menu-controls/index.js.map +1 -1
- package/build/components/block-title/use-block-display-title.js +7 -5
- package/build/components/block-title/use-block-display-title.js.map +1 -1
- package/build/components/block-toolbar/index.js +4 -0
- package/build/components/block-toolbar/index.js.map +1 -1
- package/build/components/border-radius-control/index.js +0 -1
- package/build/components/border-radius-control/index.js.map +1 -1
- package/build/components/border-radius-control/utils.js +1 -1
- package/build/components/border-radius-control/utils.js.map +1 -1
- package/build/components/colors-gradients/control.js +3 -1
- package/build/components/colors-gradients/control.js.map +1 -1
- package/build/components/date-format-picker/index.js +132 -0
- package/build/components/date-format-picker/index.js.map +1 -0
- package/build/components/index.js +9 -0
- package/build/components/index.js.map +1 -1
- package/build/components/line-height-control/index.js +5 -3
- package/build/components/line-height-control/index.js.map +1 -1
- package/build/components/list-view/block-select-button.js +4 -22
- package/build/components/list-view/block-select-button.js.map +1 -1
- package/build/components/list-view/block.js +33 -12
- package/build/components/list-view/block.js.map +1 -1
- package/build/components/list-view/branch.js +16 -13
- package/build/components/list-view/branch.js.map +1 -1
- package/build/components/list-view/index.js +7 -1
- package/build/components/list-view/index.js.map +1 -1
- package/build/components/list-view/use-block-selection.js +9 -2
- package/build/components/list-view/use-block-selection.js.map +1 -1
- package/build/components/rich-text/index.js +2 -2
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/rich-text/index.native.js +13 -9
- package/build/components/rich-text/index.native.js.map +1 -1
- package/build/components/url-popover/image-url-input-ui.js +11 -27
- package/build/components/url-popover/image-url-input-ui.js.map +1 -1
- package/build/hooks/anchor.js +7 -6
- package/build/hooks/anchor.js.map +1 -1
- package/build/hooks/gap.js +70 -5
- package/build/hooks/gap.js.map +1 -1
- package/build/layouts/flex.js +8 -5
- package/build/layouts/flex.js.map +1 -1
- package/build/layouts/flow.js +16 -12
- package/build/layouts/flow.js.map +1 -1
- package/build/store/defaults.js +1 -0
- package/build/store/defaults.js.map +1 -1
- package/build/store/selectors.js +29 -3
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/block-list/block-html.js +5 -2
- package/build-module/components/block-list/block-html.js.map +1 -1
- package/build-module/components/block-list/block.js +5 -2
- package/build-module/components/block-list/block.js.map +1 -1
- package/build-module/components/block-list/use-block-props/use-focus-first-element.js +18 -0
- package/build-module/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
- package/build-module/components/block-lock/index.js +4 -0
- package/build-module/components/block-lock/index.js.map +1 -0
- package/build-module/components/block-lock/menu-item.js +44 -0
- package/build-module/components/block-lock/menu-item.js.map +1 -0
- package/build-module/components/block-lock/modal.js +128 -0
- package/build-module/components/block-lock/modal.js.map +1 -0
- package/build-module/components/block-lock/toolbar.js +55 -0
- package/build-module/components/block-lock/toolbar.js.map +1 -0
- package/build-module/components/block-settings-menu/block-settings-dropdown.js +26 -6
- package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
- package/build-module/components/block-settings-menu-controls/index.js +18 -9
- package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
- package/build-module/components/block-title/use-block-display-title.js +7 -5
- package/build-module/components/block-title/use-block-display-title.js.map +1 -1
- package/build-module/components/block-toolbar/index.js +3 -0
- package/build-module/components/block-toolbar/index.js.map +1 -1
- package/build-module/components/border-radius-control/index.js +0 -1
- package/build-module/components/border-radius-control/index.js.map +1 -1
- package/build-module/components/border-radius-control/utils.js +1 -1
- package/build-module/components/border-radius-control/utils.js.map +1 -1
- package/build-module/components/colors-gradients/control.js +3 -1
- package/build-module/components/colors-gradients/control.js.map +1 -1
- package/build-module/components/date-format-picker/index.js +122 -0
- package/build-module/components/date-format-picker/index.js.map +1 -0
- package/build-module/components/index.js +1 -0
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/line-height-control/index.js +5 -3
- package/build-module/components/line-height-control/index.js.map +1 -1
- package/build-module/components/list-view/block-select-button.js +5 -20
- package/build-module/components/list-view/block-select-button.js.map +1 -1
- package/build-module/components/list-view/block.js +31 -12
- package/build-module/components/list-view/block.js.map +1 -1
- package/build-module/components/list-view/branch.js +16 -13
- package/build-module/components/list-view/branch.js.map +1 -1
- package/build-module/components/list-view/index.js +7 -1
- package/build-module/components/list-view/index.js.map +1 -1
- package/build-module/components/list-view/use-block-selection.js +10 -3
- package/build-module/components/list-view/use-block-selection.js.map +1 -1
- package/build-module/components/rich-text/index.js +2 -2
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/rich-text/index.native.js +13 -9
- package/build-module/components/rich-text/index.native.js.map +1 -1
- package/build-module/components/url-popover/image-url-input-ui.js +12 -28
- package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
- package/build-module/hooks/anchor.js +7 -6
- package/build-module/hooks/anchor.js.map +1 -1
- package/build-module/hooks/gap.js +68 -7
- package/build-module/hooks/gap.js.map +1 -1
- package/build-module/layouts/flex.js +7 -5
- package/build-module/layouts/flex.js.map +1 -1
- package/build-module/layouts/flow.js +15 -12
- package/build-module/layouts/flow.js.map +1 -1
- package/build-module/store/defaults.js +1 -0
- package/build-module/store/defaults.js.map +1 -1
- package/build-module/store/selectors.js +24 -1
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +157 -0
- package/build-style/style.css +157 -0
- package/package.json +28 -27
- package/src/components/block-list/block-html.js +8 -4
- package/src/components/block-list/block.js +5 -1
- package/src/components/block-list/use-block-props/use-focus-first-element.js +28 -0
- package/src/components/block-lock/index.js +3 -0
- package/src/components/block-lock/menu-item.js +52 -0
- package/src/components/block-lock/modal.js +165 -0
- package/src/components/block-lock/style.scss +67 -0
- package/src/components/block-lock/toolbar.js +58 -0
- package/src/components/block-settings-menu/block-settings-dropdown.js +47 -5
- package/src/components/block-settings-menu-controls/index.js +33 -12
- package/src/components/block-title/README.md +6 -1
- package/src/components/block-title/test/index.js +43 -1
- package/src/components/block-title/use-block-display-title.js +9 -6
- package/src/components/block-toolbar/index.js +6 -0
- package/src/components/block-toolbar/style.scss +4 -0
- package/src/components/block-tools/style.scss +29 -0
- package/src/components/border-radius-control/index.js +0 -1
- package/src/components/border-radius-control/test/utils.js +4 -0
- package/src/components/border-radius-control/utils.js +2 -1
- package/src/components/color-palette/test/__snapshots__/control.js.snap +70 -4
- package/src/components/colors-gradients/control.js +1 -1
- package/src/components/colors-gradients/style.scss +6 -0
- package/src/components/date-format-picker/README.md +58 -0
- package/src/components/date-format-picker/index.js +161 -0
- package/src/components/date-format-picker/style.scss +31 -0
- package/src/components/index.js +1 -0
- package/src/components/line-height-control/index.js +3 -3
- package/src/components/link-control/README.md +1 -1
- package/src/components/list-view/block-select-button.js +2 -29
- package/src/components/list-view/block.js +47 -12
- package/src/components/list-view/branch.js +37 -15
- package/src/components/list-view/index.js +6 -0
- package/src/components/list-view/use-block-selection.js +15 -2
- package/src/components/rich-text/index.js +1 -1
- package/src/components/rich-text/index.native.js +24 -8
- package/src/components/url-popover/image-url-input-ui.js +16 -29
- package/src/hooks/anchor.js +8 -6
- package/src/hooks/gap.js +83 -12
- package/src/hooks/test/gap.js +42 -0
- package/src/layouts/flex.js +6 -3
- package/src/layouts/flow.js +16 -11
- package/src/store/defaults.js +1 -0
- package/src/store/selectors.js +26 -1
- package/src/store/test/selectors.js +63 -0
- package/src/style.scss +2 -0
|
@@ -23,39 +23,59 @@ import { isClientIdSelected } from './utils';
|
|
|
23
23
|
* When a block is collapsed, we do not count their children as part of that total. In the current drag
|
|
24
24
|
* implementation dragged blocks and their children are not counted.
|
|
25
25
|
*
|
|
26
|
-
* @param {Object}
|
|
27
|
-
* @param {Object}
|
|
28
|
-
* @param {Array}
|
|
26
|
+
* @param {Object} block block tree
|
|
27
|
+
* @param {Object} expandedState state that notes which branches are collapsed
|
|
28
|
+
* @param {Array} draggedClientIds a list of dragged client ids
|
|
29
|
+
* @param {boolean} isExpandedByDefault flag to determine the default fallback expanded state.
|
|
29
30
|
* @return {number} block count
|
|
30
31
|
*/
|
|
31
|
-
function countBlocks(
|
|
32
|
+
function countBlocks(
|
|
33
|
+
block,
|
|
34
|
+
expandedState,
|
|
35
|
+
draggedClientIds,
|
|
36
|
+
isExpandedByDefault
|
|
37
|
+
) {
|
|
32
38
|
const isDragged = draggedClientIds?.includes( block.clientId );
|
|
33
39
|
if ( isDragged ) {
|
|
34
40
|
return 0;
|
|
35
41
|
}
|
|
36
|
-
const isExpanded = expandedState[ block.clientId ] ??
|
|
42
|
+
const isExpanded = expandedState[ block.clientId ] ?? isExpandedByDefault;
|
|
43
|
+
|
|
37
44
|
if ( isExpanded ) {
|
|
38
45
|
return (
|
|
39
46
|
1 +
|
|
40
47
|
block.innerBlocks.reduce(
|
|
41
|
-
countReducer(
|
|
48
|
+
countReducer(
|
|
49
|
+
expandedState,
|
|
50
|
+
draggedClientIds,
|
|
51
|
+
isExpandedByDefault
|
|
52
|
+
),
|
|
42
53
|
0
|
|
43
54
|
)
|
|
44
55
|
);
|
|
45
56
|
}
|
|
46
57
|
return 1;
|
|
47
58
|
}
|
|
48
|
-
const countReducer = (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
const countReducer = (
|
|
60
|
+
expandedState,
|
|
61
|
+
draggedClientIds,
|
|
62
|
+
isExpandedByDefault
|
|
63
|
+
) => ( count, block ) => {
|
|
52
64
|
const isDragged = draggedClientIds?.includes( block.clientId );
|
|
53
65
|
if ( isDragged ) {
|
|
54
66
|
return count;
|
|
55
67
|
}
|
|
56
|
-
const isExpanded = expandedState[ block.clientId ] ??
|
|
68
|
+
const isExpanded = expandedState[ block.clientId ] ?? isExpandedByDefault;
|
|
57
69
|
if ( isExpanded && block.innerBlocks.length > 0 ) {
|
|
58
|
-
return
|
|
70
|
+
return (
|
|
71
|
+
count +
|
|
72
|
+
countBlocks(
|
|
73
|
+
block,
|
|
74
|
+
expandedState,
|
|
75
|
+
draggedClientIds,
|
|
76
|
+
isExpandedByDefault
|
|
77
|
+
)
|
|
78
|
+
);
|
|
59
79
|
}
|
|
60
80
|
return count + 1;
|
|
61
81
|
};
|
|
@@ -72,6 +92,7 @@ function ListViewBranch( props ) {
|
|
|
72
92
|
isBranchSelected = false,
|
|
73
93
|
listPosition = 0,
|
|
74
94
|
fixedListWindow,
|
|
95
|
+
expandNested = true,
|
|
75
96
|
} = props;
|
|
76
97
|
|
|
77
98
|
const {
|
|
@@ -93,14 +114,14 @@ function ListViewBranch( props ) {
|
|
|
93
114
|
nextPosition += countBlocks(
|
|
94
115
|
filteredBlocks[ index - 1 ],
|
|
95
116
|
expandedState,
|
|
96
|
-
draggedClientIds
|
|
117
|
+
draggedClientIds,
|
|
118
|
+
expandNested
|
|
97
119
|
);
|
|
98
120
|
}
|
|
99
121
|
|
|
100
122
|
const usesWindowing = __experimentalPersistentListViewFeatures;
|
|
101
123
|
|
|
102
124
|
const { itemInView } = fixedListWindow;
|
|
103
|
-
|
|
104
125
|
const blockInView =
|
|
105
126
|
! usesWindowing || itemInView( nextPosition );
|
|
106
127
|
|
|
@@ -113,7 +134,7 @@ function ListViewBranch( props ) {
|
|
|
113
134
|
showNestedBlocks && !! innerBlocks && !! innerBlocks.length;
|
|
114
135
|
|
|
115
136
|
const isExpanded = hasNestedBlocks
|
|
116
|
-
? expandedState[ clientId ] ??
|
|
137
|
+
? expandedState[ clientId ] ?? expandNested
|
|
117
138
|
: undefined;
|
|
118
139
|
|
|
119
140
|
const isDragged = !! draggedClientIds?.includes( clientId );
|
|
@@ -165,6 +186,7 @@ function ListViewBranch( props ) {
|
|
|
165
186
|
fixedListWindow={ fixedListWindow }
|
|
166
187
|
isBranchSelected={ isSelectedBranch }
|
|
167
188
|
selectedClientIds={ selectedClientIds }
|
|
189
|
+
expandNested={ expandNested }
|
|
168
190
|
/>
|
|
169
191
|
) }
|
|
170
192
|
</AsyncModeProvider>
|
|
@@ -59,6 +59,8 @@ export const BLOCK_LIST_ITEM_HEIGHT = 36;
|
|
|
59
59
|
* @param {boolean} props.__experimentalFeatures Flag to enable experimental features.
|
|
60
60
|
* @param {boolean} props.__experimentalPersistentListViewFeatures Flag to enable features for the Persistent List View experiment.
|
|
61
61
|
* @param {boolean} props.__experimentalHideContainerBlockActions Flag to hide actions of top level blocks (like core/widget-area)
|
|
62
|
+
* @param {string} props.id Unique identifier for the root list element (primarily for a11y purposes).
|
|
63
|
+
* @param {boolean} props.expandNested Flag to determine whether nested levels are expanded by default.
|
|
62
64
|
* @param {Object} ref Forwarded ref
|
|
63
65
|
*/
|
|
64
66
|
function ListView(
|
|
@@ -69,6 +71,8 @@ function ListView(
|
|
|
69
71
|
__experimentalHideContainerBlockActions,
|
|
70
72
|
showNestedBlocks,
|
|
71
73
|
showBlockMovers,
|
|
74
|
+
id,
|
|
75
|
+
expandNested = false,
|
|
72
76
|
...props
|
|
73
77
|
},
|
|
74
78
|
ref
|
|
@@ -205,6 +209,7 @@ function ListView(
|
|
|
205
209
|
blockDropTarget={ blockDropTarget }
|
|
206
210
|
/>
|
|
207
211
|
<TreeGrid
|
|
212
|
+
id={ id }
|
|
208
213
|
className="block-editor-list-view-tree"
|
|
209
214
|
aria-label={ __( 'Block navigation structure' ) }
|
|
210
215
|
ref={ treeGridRef }
|
|
@@ -220,6 +225,7 @@ function ListView(
|
|
|
220
225
|
showBlockMovers={ showBlockMovers }
|
|
221
226
|
fixedListWindow={ fixedListWindow }
|
|
222
227
|
selectedClientIds={ selectedClientIds }
|
|
228
|
+
expandNested={ expandNested }
|
|
223
229
|
{ ...props }
|
|
224
230
|
/>
|
|
225
231
|
</ListViewContext.Provider>
|
|
@@ -10,7 +10,7 @@ import { speak } from '@wordpress/a11y';
|
|
|
10
10
|
import { __, sprintf } from '@wordpress/i18n';
|
|
11
11
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
12
12
|
import { useCallback } from '@wordpress/element';
|
|
13
|
-
import { UP, DOWN } from '@wordpress/keycodes';
|
|
13
|
+
import { UP, DOWN, HOME, END } from '@wordpress/keycodes';
|
|
14
14
|
import { store as blocksStore } from '@wordpress/blocks';
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -49,7 +49,10 @@ export default function useBlockSelection() {
|
|
|
49
49
|
|
|
50
50
|
const isKeyPress =
|
|
51
51
|
event.type === 'keydown' &&
|
|
52
|
-
( event.keyCode === UP ||
|
|
52
|
+
( event.keyCode === UP ||
|
|
53
|
+
event.keyCode === DOWN ||
|
|
54
|
+
event.keyCode === HOME ||
|
|
55
|
+
event.keyCode === END );
|
|
53
56
|
|
|
54
57
|
// Handle clicking on a block when no blocks are selected, and return early.
|
|
55
58
|
if (
|
|
@@ -114,6 +117,16 @@ export default function useBlockSelection() {
|
|
|
114
117
|
// the total number of blocks deselected is greater than one.
|
|
115
118
|
const updatedSelectedBlocks = getSelectedBlockClientIds();
|
|
116
119
|
|
|
120
|
+
// If the selection is greater than 1 and the Home or End keys
|
|
121
|
+
// were used to generate the selection, then skip announcing the
|
|
122
|
+
// deselected blocks.
|
|
123
|
+
if (
|
|
124
|
+
( event.keyCode === HOME || event.keyCode === END ) &&
|
|
125
|
+
updatedSelectedBlocks.length > 1
|
|
126
|
+
) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
117
130
|
const selectionDiff = difference(
|
|
118
131
|
selectedBlocks,
|
|
119
132
|
updatedSelectedBlocks
|
|
@@ -330,6 +330,7 @@ function RichTextWrapper(
|
|
|
330
330
|
{ ...props }
|
|
331
331
|
{ ...autocompleteProps }
|
|
332
332
|
ref={ useMergeRefs( [
|
|
333
|
+
forwardedRef,
|
|
333
334
|
autocompleteProps.ref,
|
|
334
335
|
props.ref,
|
|
335
336
|
richTextRef,
|
|
@@ -371,7 +372,6 @@ function RichTextWrapper(
|
|
|
371
372
|
onSplitAtEnd,
|
|
372
373
|
} ),
|
|
373
374
|
anchorRef,
|
|
374
|
-
forwardedRef,
|
|
375
375
|
] ) }
|
|
376
376
|
contentEditable={ true }
|
|
377
377
|
suppressContentEditableWarning={ true }
|
|
@@ -66,6 +66,8 @@ function RichTextWrapper(
|
|
|
66
66
|
{
|
|
67
67
|
children,
|
|
68
68
|
tagName,
|
|
69
|
+
start,
|
|
70
|
+
reversed,
|
|
69
71
|
value: originalValue,
|
|
70
72
|
onChange: originalOnChange,
|
|
71
73
|
isSelected: originalIsSelected,
|
|
@@ -214,8 +216,13 @@ function RichTextWrapper(
|
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
const onSelectionChange = useCallback(
|
|
217
|
-
(
|
|
218
|
-
selectionChange(
|
|
219
|
+
( selectionChangeStart, selectionChangeEnd ) => {
|
|
220
|
+
selectionChange(
|
|
221
|
+
clientId,
|
|
222
|
+
identifier,
|
|
223
|
+
selectionChangeStart,
|
|
224
|
+
selectionChangeEnd
|
|
225
|
+
);
|
|
219
226
|
},
|
|
220
227
|
[ clientId, identifier ]
|
|
221
228
|
);
|
|
@@ -349,9 +356,11 @@ function RichTextWrapper(
|
|
|
349
356
|
onChange( insertLineSeparator( value ) );
|
|
350
357
|
}
|
|
351
358
|
} else {
|
|
352
|
-
const { text, start, end } = value;
|
|
359
|
+
const { text, start: splitStart, end: splitEnd } = value;
|
|
353
360
|
const canSplitAtEnd =
|
|
354
|
-
onSplitAtEnd &&
|
|
361
|
+
onSplitAtEnd &&
|
|
362
|
+
splitStart === splitEnd &&
|
|
363
|
+
splitEnd === text.length;
|
|
355
364
|
|
|
356
365
|
if ( shiftKey || ( ! canSplit && ! canSplitAtEnd ) ) {
|
|
357
366
|
if ( ! disableLineBreaks ) {
|
|
@@ -530,15 +539,18 @@ function RichTextWrapper(
|
|
|
530
539
|
return;
|
|
531
540
|
}
|
|
532
541
|
|
|
533
|
-
const { start, text } = value;
|
|
534
|
-
const characterBefore = text.slice(
|
|
542
|
+
const { start: startPosition, text } = value;
|
|
543
|
+
const characterBefore = text.slice(
|
|
544
|
+
startPosition - 1,
|
|
545
|
+
startPosition
|
|
546
|
+
);
|
|
535
547
|
|
|
536
548
|
// The character right before the caret must be a plain space.
|
|
537
549
|
if ( characterBefore !== ' ' ) {
|
|
538
550
|
return;
|
|
539
551
|
}
|
|
540
552
|
|
|
541
|
-
const trimmedTextBefore = text.slice( 0,
|
|
553
|
+
const trimmedTextBefore = text.slice( 0, startPosition ).trim();
|
|
542
554
|
const prefixTransforms = getBlockTransforms( 'from' ).filter(
|
|
543
555
|
( { type } ) => type === 'prefix'
|
|
544
556
|
);
|
|
@@ -553,7 +565,9 @@ function RichTextWrapper(
|
|
|
553
565
|
return;
|
|
554
566
|
}
|
|
555
567
|
|
|
556
|
-
const content = valueToFormat(
|
|
568
|
+
const content = valueToFormat(
|
|
569
|
+
slice( value, startPosition, text.length )
|
|
570
|
+
);
|
|
557
571
|
const block = transformation.transform( content );
|
|
558
572
|
|
|
559
573
|
onReplace( [ block ] );
|
|
@@ -575,6 +589,8 @@ function RichTextWrapper(
|
|
|
575
589
|
selectionEnd={ selectionEnd }
|
|
576
590
|
onSelectionChange={ onSelectionChange }
|
|
577
591
|
tagName={ tagName }
|
|
592
|
+
start={ start }
|
|
593
|
+
reversed={ reversed }
|
|
578
594
|
placeholder={ placeholder }
|
|
579
595
|
allowedFormats={ adjustedAllowedFormats }
|
|
580
596
|
withoutInteractiveFormatting={ withoutInteractiveFormatting }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { find,
|
|
4
|
+
import { find, map } from 'lodash';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
@@ -80,38 +80,25 @@ const ImageURLInputUI = ( {
|
|
|
80
80
|
setIsOpen( false );
|
|
81
81
|
} );
|
|
82
82
|
|
|
83
|
-
const removeNewTabRel = ( currentRel ) => {
|
|
84
|
-
let newRel = currentRel;
|
|
85
|
-
|
|
86
|
-
if ( currentRel !== undefined && ! isEmpty( newRel ) ) {
|
|
87
|
-
if ( ! isEmpty( newRel ) ) {
|
|
88
|
-
each( NEW_TAB_REL, ( relVal ) => {
|
|
89
|
-
const regExp = new RegExp( '\\b' + relVal + '\\b', 'gi' );
|
|
90
|
-
newRel = newRel.replace( regExp, '' );
|
|
91
|
-
} );
|
|
92
|
-
|
|
93
|
-
// Only trim if NEW_TAB_REL values was replaced.
|
|
94
|
-
if ( newRel !== currentRel ) {
|
|
95
|
-
newRel = newRel.trim();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if ( isEmpty( newRel ) ) {
|
|
99
|
-
newRel = undefined;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return newRel;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
83
|
const getUpdatedLinkTargetSettings = ( value ) => {
|
|
108
84
|
const newLinkTarget = value ? '_blank' : undefined;
|
|
109
85
|
|
|
110
86
|
let updatedRel;
|
|
111
|
-
if (
|
|
112
|
-
|
|
87
|
+
if ( newLinkTarget ) {
|
|
88
|
+
const rels = ( rel ?? '' ).split( ' ' );
|
|
89
|
+
NEW_TAB_REL.forEach( ( relVal ) => {
|
|
90
|
+
if ( ! rels.includes( relVal ) ) {
|
|
91
|
+
rels.push( relVal );
|
|
92
|
+
}
|
|
93
|
+
} );
|
|
94
|
+
updatedRel = rels.join( ' ' );
|
|
113
95
|
} else {
|
|
114
|
-
|
|
96
|
+
const rels = ( rel ?? '' )
|
|
97
|
+
.split( ' ' )
|
|
98
|
+
.filter(
|
|
99
|
+
( relVal ) => NEW_TAB_REL.includes( relVal ) === false
|
|
100
|
+
);
|
|
101
|
+
updatedRel = rels.length ? rels.join( ' ' ) : undefined;
|
|
115
102
|
}
|
|
116
103
|
|
|
117
104
|
return {
|
|
@@ -232,7 +219,7 @@ const ImageURLInputUI = ( {
|
|
|
232
219
|
/>
|
|
233
220
|
<TextControl
|
|
234
221
|
label={ __( 'Link Rel' ) }
|
|
235
|
-
value={
|
|
222
|
+
value={ rel ?? '' }
|
|
236
223
|
onChange={ onSetLinkRel }
|
|
237
224
|
/>
|
|
238
225
|
<TextControl
|
package/src/hooks/anchor.js
CHANGED
|
@@ -25,6 +25,13 @@ import { InspectorControls } from '../components';
|
|
|
25
25
|
*/
|
|
26
26
|
const ANCHOR_REGEX = /[\s#]/g;
|
|
27
27
|
|
|
28
|
+
const ANCHOR_SCHEMA = {
|
|
29
|
+
type: 'string',
|
|
30
|
+
source: 'attribute',
|
|
31
|
+
attribute: 'id',
|
|
32
|
+
selector: '*',
|
|
33
|
+
};
|
|
34
|
+
|
|
28
35
|
/**
|
|
29
36
|
* Filters registered block settings, extending attributes with anchor using ID
|
|
30
37
|
* of the first node.
|
|
@@ -42,12 +49,7 @@ export function addAttribute( settings ) {
|
|
|
42
49
|
// Gracefully handle if settings.attributes is undefined.
|
|
43
50
|
settings.attributes = {
|
|
44
51
|
...settings.attributes,
|
|
45
|
-
anchor:
|
|
46
|
-
type: 'string',
|
|
47
|
-
source: 'attribute',
|
|
48
|
-
attribute: 'id',
|
|
49
|
-
selector: '*',
|
|
50
|
-
},
|
|
52
|
+
anchor: ANCHOR_SCHEMA,
|
|
51
53
|
};
|
|
52
54
|
}
|
|
53
55
|
|
package/src/hooks/gap.js
CHANGED
|
@@ -6,6 +6,7 @@ import { Platform } from '@wordpress/element';
|
|
|
6
6
|
import { getBlockSupport } from '@wordpress/blocks';
|
|
7
7
|
import {
|
|
8
8
|
__experimentalUseCustomUnits as useCustomUnits,
|
|
9
|
+
__experimentalBoxControl as BoxControl,
|
|
9
10
|
__experimentalUnitControl as UnitControl,
|
|
10
11
|
} from '@wordpress/components';
|
|
11
12
|
|
|
@@ -14,14 +15,14 @@ import {
|
|
|
14
15
|
*/
|
|
15
16
|
import { __unstableUseBlockRef as useBlockRef } from '../components/block-list/use-block-props/use-block-refs';
|
|
16
17
|
import useSetting from '../components/use-setting';
|
|
17
|
-
import { SPACING_SUPPORT_KEY } from './dimensions';
|
|
18
|
+
import { AXIAL_SIDES, SPACING_SUPPORT_KEY, useCustomSides } from './dimensions';
|
|
18
19
|
import { cleanEmptyObject } from './utils';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Determines if there is gap support.
|
|
22
23
|
*
|
|
23
24
|
* @param {string|Object} blockType Block name or Block Type object.
|
|
24
|
-
* @return {boolean}
|
|
25
|
+
* @return {boolean} Whether there is support.
|
|
25
26
|
*/
|
|
26
27
|
export function hasGapSupport( blockType ) {
|
|
27
28
|
const support = getBlockSupport( blockType, SPACING_SUPPORT_KEY );
|
|
@@ -38,6 +39,45 @@ export function hasGapValue( props ) {
|
|
|
38
39
|
return props.attributes.style?.spacing?.blockGap !== undefined;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Returns a BoxControl object value from a given blockGap style.
|
|
44
|
+
* The string check is for backwards compatibility before Gutenberg supported
|
|
45
|
+
* split gap values (row and column) and the value was a string n + unit.
|
|
46
|
+
*
|
|
47
|
+
* @param {string? | Object?} rawBlockGapValue A style object.
|
|
48
|
+
* @return {Object?} A value to pass to the BoxControl component.
|
|
49
|
+
*/
|
|
50
|
+
export function getGapValueFromStyle( rawBlockGapValue ) {
|
|
51
|
+
if ( ! rawBlockGapValue ) {
|
|
52
|
+
return rawBlockGapValue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const isValueString = typeof rawBlockGapValue === 'string';
|
|
56
|
+
return {
|
|
57
|
+
top: isValueString ? rawBlockGapValue : rawBlockGapValue?.top,
|
|
58
|
+
left: isValueString ? rawBlockGapValue : rawBlockGapValue?.left,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns a CSS value for the `gap` property from a given blockGap style.
|
|
64
|
+
*
|
|
65
|
+
* @param {string? | Object?} blockGapValue A style object.
|
|
66
|
+
* @param {string?} defaultValue A default gap value.
|
|
67
|
+
* @return {string|null} The concatenated gap value (row and column).
|
|
68
|
+
*/
|
|
69
|
+
export function getGapCSSValue( blockGapValue, defaultValue = '0' ) {
|
|
70
|
+
const blockGapBoxControlValue = getGapValueFromStyle( blockGapValue );
|
|
71
|
+
if ( ! blockGapBoxControlValue ) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const row = blockGapBoxControlValue?.top || defaultValue;
|
|
76
|
+
const column = blockGapBoxControlValue?.left || defaultValue;
|
|
77
|
+
|
|
78
|
+
return row === column ? row : `${ row } ${ column }`;
|
|
79
|
+
}
|
|
80
|
+
|
|
41
81
|
/**
|
|
42
82
|
* Resets the gap block support attribute. This can be used when disabling
|
|
43
83
|
* the gap support controls for a block via a progressive discovery panel.
|
|
@@ -82,6 +122,7 @@ export function GapEdit( props ) {
|
|
|
82
122
|
const {
|
|
83
123
|
clientId,
|
|
84
124
|
attributes: { style },
|
|
125
|
+
name: blockName,
|
|
85
126
|
setAttributes,
|
|
86
127
|
} = props;
|
|
87
128
|
|
|
@@ -94,7 +135,7 @@ export function GapEdit( props ) {
|
|
|
94
135
|
'vw',
|
|
95
136
|
],
|
|
96
137
|
} );
|
|
97
|
-
|
|
138
|
+
const sides = useCustomSides( blockName, 'blockGap' );
|
|
98
139
|
const ref = useBlockRef( clientId );
|
|
99
140
|
|
|
100
141
|
if ( useIsGapDisabled( props ) ) {
|
|
@@ -106,7 +147,9 @@ export function GapEdit( props ) {
|
|
|
106
147
|
...style,
|
|
107
148
|
spacing: {
|
|
108
149
|
...style?.spacing,
|
|
109
|
-
blockGap:
|
|
150
|
+
blockGap: {
|
|
151
|
+
...getGapValueFromStyle( next ),
|
|
152
|
+
},
|
|
110
153
|
},
|
|
111
154
|
};
|
|
112
155
|
|
|
@@ -128,17 +171,45 @@ export function GapEdit( props ) {
|
|
|
128
171
|
}
|
|
129
172
|
};
|
|
130
173
|
|
|
174
|
+
const splitOnAxis =
|
|
175
|
+
sides && sides.some( ( side ) => AXIAL_SIDES.includes( side ) );
|
|
176
|
+
const gapValue = getGapValueFromStyle( style?.spacing?.blockGap );
|
|
177
|
+
|
|
178
|
+
// The BoxControl component expects a full complement of side values.
|
|
179
|
+
// Gap row and column values translate to top/bottom and left/right respectively.
|
|
180
|
+
const boxControlGapValue = splitOnAxis
|
|
181
|
+
? {
|
|
182
|
+
...gapValue,
|
|
183
|
+
right: gapValue?.left,
|
|
184
|
+
bottom: gapValue?.top,
|
|
185
|
+
}
|
|
186
|
+
: gapValue?.top;
|
|
187
|
+
|
|
131
188
|
return Platform.select( {
|
|
132
189
|
web: (
|
|
133
190
|
<>
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
191
|
+
{ splitOnAxis ? (
|
|
192
|
+
<BoxControl
|
|
193
|
+
label={ __( 'Block spacing' ) }
|
|
194
|
+
min={ 0 }
|
|
195
|
+
onChange={ onChange }
|
|
196
|
+
units={ units }
|
|
197
|
+
sides={ sides }
|
|
198
|
+
values={ boxControlGapValue }
|
|
199
|
+
allowReset={ false }
|
|
200
|
+
splitOnAxis={ splitOnAxis }
|
|
201
|
+
/>
|
|
202
|
+
) : (
|
|
203
|
+
<UnitControl
|
|
204
|
+
label={ __( 'Block spacing' ) }
|
|
205
|
+
__unstableInputWidth="80px"
|
|
206
|
+
min={ 0 }
|
|
207
|
+
onChange={ onChange }
|
|
208
|
+
units={ units }
|
|
209
|
+
// Default to `row` for combined values.
|
|
210
|
+
value={ boxControlGapValue }
|
|
211
|
+
/>
|
|
212
|
+
) }
|
|
142
213
|
</>
|
|
143
214
|
),
|
|
144
215
|
native: null,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { getGapCSSValue } from '../gap';
|
|
5
|
+
|
|
6
|
+
describe( 'gap', () => {
|
|
7
|
+
describe( 'getGapCSSValue()', () => {
|
|
8
|
+
it( 'should return `null` if argument is falsey', () => {
|
|
9
|
+
expect( getGapCSSValue( undefined ) ).toBeNull();
|
|
10
|
+
expect( getGapCSSValue( '' ) ).toBeNull();
|
|
11
|
+
} );
|
|
12
|
+
|
|
13
|
+
it( 'should return single value for gap if argument is valid string', () => {
|
|
14
|
+
expect( getGapCSSValue( '88rem' ) ).toEqual( '88rem' );
|
|
15
|
+
} );
|
|
16
|
+
|
|
17
|
+
it( 'should return single value for gap if row and column are the same', () => {
|
|
18
|
+
const blockGapValue = {
|
|
19
|
+
top: '88rem',
|
|
20
|
+
left: '88rem',
|
|
21
|
+
};
|
|
22
|
+
expect( getGapCSSValue( blockGapValue ) ).toEqual( '88rem' );
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
it( 'should return shorthand value for gap if row and column are different', () => {
|
|
26
|
+
const blockGapValue = {
|
|
27
|
+
top: '88px',
|
|
28
|
+
left: '88rem',
|
|
29
|
+
};
|
|
30
|
+
expect( getGapCSSValue( blockGapValue ) ).toEqual( '88px 88rem' );
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
it( 'should return default value if a top or left is missing', () => {
|
|
34
|
+
const blockGapValue = {
|
|
35
|
+
top: '88px',
|
|
36
|
+
};
|
|
37
|
+
expect( getGapCSSValue( blockGapValue, '1px' ) ).toEqual(
|
|
38
|
+
'88px 1px'
|
|
39
|
+
);
|
|
40
|
+
} );
|
|
41
|
+
} );
|
|
42
|
+
} );
|
package/src/layouts/flex.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Button, ToggleControl, Flex, FlexItem } from '@wordpress/components';
|
|
|
16
16
|
* Internal dependencies
|
|
17
17
|
*/
|
|
18
18
|
import { appendSelectors } from './utils';
|
|
19
|
+
import { getGapCSSValue } from '../hooks/gap';
|
|
19
20
|
import useSetting from '../components/use-setting';
|
|
20
21
|
import { BlockControls, JustifyContentControl } from '../components';
|
|
21
22
|
|
|
@@ -42,8 +43,9 @@ export default {
|
|
|
42
43
|
inspectorControls: function FlexLayoutInspectorControls( {
|
|
43
44
|
layout = {},
|
|
44
45
|
onChange,
|
|
46
|
+
layoutBlockSupport = {},
|
|
45
47
|
} ) {
|
|
46
|
-
const { allowOrientation = true } =
|
|
48
|
+
const { allowOrientation = true } = layoutBlockSupport;
|
|
47
49
|
return (
|
|
48
50
|
<>
|
|
49
51
|
<Flex>
|
|
@@ -89,7 +91,8 @@ export default {
|
|
|
89
91
|
const blockGapSupport = useSetting( 'spacing.blockGap' );
|
|
90
92
|
const hasBlockGapStylesSupport = blockGapSupport !== null;
|
|
91
93
|
const blockGapValue =
|
|
92
|
-
style?.spacing?.blockGap
|
|
94
|
+
getGapCSSValue( style?.spacing?.blockGap, '0.5em' ) ??
|
|
95
|
+
'var( --wp--style--block-gap, 0.5em )';
|
|
93
96
|
const justifyContent =
|
|
94
97
|
justifyContentMap[ layout.justifyContent ] ||
|
|
95
98
|
justifyContentMap.left;
|
|
@@ -112,8 +115,8 @@ export default {
|
|
|
112
115
|
<style>{ `
|
|
113
116
|
${ appendSelectors( selector ) } {
|
|
114
117
|
display: flex;
|
|
115
|
-
gap: ${ hasBlockGapStylesSupport ? blockGapValue : '0.5em' };
|
|
116
118
|
flex-wrap: ${ flexWrap };
|
|
119
|
+
gap: ${ hasBlockGapStylesSupport ? blockGapValue : '0.5em' };
|
|
117
120
|
${ orientation === 'horizontal' ? rowOrientation : columnOrientation }
|
|
118
121
|
}
|
|
119
122
|
|
package/src/layouts/flow.js
CHANGED
|
@@ -14,6 +14,7 @@ import { Icon, positionCenter, stretchWide } from '@wordpress/icons';
|
|
|
14
14
|
*/
|
|
15
15
|
import useSetting from '../components/use-setting';
|
|
16
16
|
import { appendSelectors } from './utils';
|
|
17
|
+
import { getGapValueFromStyle } from '../hooks/gap';
|
|
17
18
|
|
|
18
19
|
export default {
|
|
19
20
|
name: 'default',
|
|
@@ -109,8 +110,11 @@ export default {
|
|
|
109
110
|
const { contentSize, wideSize } = layout;
|
|
110
111
|
const blockGapSupport = useSetting( 'spacing.blockGap' );
|
|
111
112
|
const hasBlockGapStylesSupport = blockGapSupport !== null;
|
|
113
|
+
const blockGapStyleValue = getGapValueFromStyle(
|
|
114
|
+
style?.spacing?.blockGap
|
|
115
|
+
);
|
|
112
116
|
const blockGapValue =
|
|
113
|
-
|
|
117
|
+
blockGapStyleValue?.top ?? 'var( --wp--style--block-gap )';
|
|
114
118
|
|
|
115
119
|
let output =
|
|
116
120
|
!! contentSize || !! wideSize
|
|
@@ -123,11 +127,9 @@ export default {
|
|
|
123
127
|
margin-left: auto !important;
|
|
124
128
|
margin-right: auto !important;
|
|
125
129
|
}
|
|
126
|
-
|
|
127
130
|
${ appendSelectors( selector, '> .alignwide' ) } {
|
|
128
131
|
max-width: ${ wideSize ?? contentSize };
|
|
129
132
|
}
|
|
130
|
-
|
|
131
133
|
${ appendSelectors( selector, '> .alignfull' ) } {
|
|
132
134
|
max-width: none;
|
|
133
135
|
}
|
|
@@ -137,26 +139,29 @@ export default {
|
|
|
137
139
|
output += `
|
|
138
140
|
${ appendSelectors( selector, '> .alignleft' ) } {
|
|
139
141
|
float: left;
|
|
140
|
-
margin-
|
|
141
|
-
margin-
|
|
142
|
+
margin-inline-start: 0;
|
|
143
|
+
margin-inline-end: 2em;
|
|
142
144
|
}
|
|
143
|
-
|
|
144
145
|
${ appendSelectors( selector, '> .alignright' ) } {
|
|
145
146
|
float: right;
|
|
146
|
-
margin-
|
|
147
|
-
margin-
|
|
147
|
+
margin-inline-start: 2em;
|
|
148
|
+
margin-inline-end: 0;
|
|
148
149
|
}
|
|
149
150
|
|
|
151
|
+
${ appendSelectors( selector, '> .aligncenter' ) } {
|
|
152
|
+
margin-left: auto !important;
|
|
153
|
+
margin-right: auto !important;
|
|
154
|
+
}
|
|
150
155
|
`;
|
|
151
156
|
|
|
152
157
|
if ( hasBlockGapStylesSupport ) {
|
|
153
158
|
output += `
|
|
154
159
|
${ appendSelectors( selector, '> *' ) } {
|
|
155
|
-
margin-
|
|
156
|
-
margin-
|
|
160
|
+
margin-block-start: 0;
|
|
161
|
+
margin-block-end: 0;
|
|
157
162
|
}
|
|
158
163
|
${ appendSelectors( selector, '> * + *' ) } {
|
|
159
|
-
margin-
|
|
164
|
+
margin-block-start: ${ blockGapValue };
|
|
160
165
|
}
|
|
161
166
|
`;
|
|
162
167
|
}
|
package/src/store/defaults.js
CHANGED
|
@@ -28,6 +28,7 @@ export const PREFERENCES_DEFAULTS = {
|
|
|
28
28
|
* @property {boolean} __experimentalBlockDirectory Whether the user has enabled the Block Directory
|
|
29
29
|
* @property {Array} __experimentalBlockPatterns Array of objects representing the block patterns
|
|
30
30
|
* @property {Array} __experimentalBlockPatternCategories Array of objects representing the block pattern categories
|
|
31
|
+
* @property {boolean} __experimentalGenerateAnchors Enable/Disable auto anchor generation for Heading blocks
|
|
31
32
|
* @property {boolean} __unstableGalleryWithImageBlocks Whether the user has enabled the refactored gallery block which uses InnerBlocks
|
|
32
33
|
*/
|
|
33
34
|
export const SETTINGS_DEFAULTS = {
|