-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathquery-content.js
134 lines (130 loc) · 4.06 KB
/
query-content.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { useInstanceId } from '@wordpress/compose';
import { useEffect } from '@wordpress/element';
import {
BlockControls,
InspectorControls,
useBlockProps,
store as blockEditorStore,
useInnerBlocksProps,
} from '@wordpress/block-editor';
import { SelectControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import QueryToolbar from './query-toolbar';
import QueryInspectorControls from './inspector-controls';
const DEFAULTS_POSTS_PER_PAGE = 3;
const TEMPLATE = [ [ 'core/post-template' ] ];
export default function QueryContent( {
attributes,
setAttributes,
openPatternSelectionModal,
name,
clientId,
} ) {
const {
queryId,
query,
displayLayout,
tagName: TagName = 'div',
} = attributes;
const { __unstableMarkNextChangeAsNotPersistent } =
useDispatch( blockEditorStore );
const instanceId = useInstanceId( QueryContent );
const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps( blockProps, {
template: TEMPLATE,
} );
const { postsPerPage } = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
return {
postsPerPage:
+getSettings().postsPerPage || DEFAULTS_POSTS_PER_PAGE,
};
}, [] );
// There are some effects running where some initialization logic is
// happening and setting some values to some attributes (ex. queryId).
// These updates can cause an `undo trap` where undoing will result in
// resetting again, so we need to mark these changes as not persistent
// with `__unstableMarkNextChangeAsNotPersistent`.
// Changes in query property (which is an object) need to be in the same callback,
// because updates are batched after the render and changes in different query properties
// would cause to override previous wanted changes.
useEffect( () => {
const newQuery = {};
if ( ! query.perPage && postsPerPage ) {
newQuery.perPage = postsPerPage;
}
if ( !! Object.keys( newQuery ).length ) {
__unstableMarkNextChangeAsNotPersistent();
updateQuery( newQuery );
}
}, [ query.perPage ] );
// We need this for multi-query block pagination.
// Query parameters for each block are scoped to their ID.
useEffect( () => {
if ( ! Number.isFinite( queryId ) ) {
__unstableMarkNextChangeAsNotPersistent();
setAttributes( { queryId: instanceId } );
}
}, [ queryId, instanceId ] );
const updateQuery = ( newQuery ) =>
setAttributes( { query: { ...query, ...newQuery } } );
const updateDisplayLayout = ( newDisplayLayout ) =>
setAttributes( {
displayLayout: { ...displayLayout, ...newDisplayLayout },
} );
const htmlElementMessages = {
main: __(
'The <main> element should be used for the primary content of your document only. '
),
section: __(
"The <section> element should represent a standalone portion of the document that can't be better represented by another element."
),
aside: __(
"The <aside> element should represent a portion of a document whose content is only indirectly related to the document's main content."
),
};
return (
<>
<QueryInspectorControls
attributes={ attributes }
setQuery={ updateQuery }
setDisplayLayout={ updateDisplayLayout }
/>
<BlockControls>
<QueryToolbar
name={ name }
clientId={ clientId }
attributes={ attributes }
setQuery={ updateQuery }
setDisplayLayout={ updateDisplayLayout }
openPatternSelectionModal={ openPatternSelectionModal }
/>
</BlockControls>
<InspectorControls group="advanced">
<SelectControl
__nextHasNoMarginBottom
label={ __( 'HTML element' ) }
options={ [
{ label: __( 'Default (<div>)' ), value: 'div' },
{ label: '<main>', value: 'main' },
{ label: '<section>', value: 'section' },
{ label: '<aside>', value: 'aside' },
] }
value={ TagName }
onChange={ ( value ) =>
setAttributes( { tagName: value } )
}
help={ htmlElementMessages[ TagName ] }
/>
</InspectorControls>
<TagName { ...innerBlocksProps } />
</>
);
}