@wordpress/editor 14.35.2-next.dc3f6d3c1.0 → 14.36.1-next.6deb34194.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 +1 -1
- package/README.md +2 -2
- package/build/bindings/post-data.js +15 -15
- package/build/bindings/post-data.js.map +2 -2
- package/build/bindings/term-data.js +97 -95
- package/build/bindings/term-data.js.map +2 -2
- package/build/components/autocompleters/user.js.map +2 -2
- package/build/components/collab-sidebar/comments.js.map +2 -2
- package/build/components/collab-sidebar/hooks.js +7 -11
- package/build/components/collab-sidebar/hooks.js.map +2 -2
- package/build/components/document-bar/index.js +19 -8
- package/build/components/document-bar/index.js.map +3 -3
- package/build/components/document-bar/useEditedSectionDetails.js +95 -0
- package/build/components/document-bar/useEditedSectionDetails.js.map +7 -0
- package/build/components/global-styles/index.js +1 -1
- package/build/components/global-styles/index.js.map +1 -1
- package/build/components/page-attributes/parent.js +1 -0
- package/build/components/page-attributes/parent.js.map +2 -2
- package/build/components/post-card-panel/index.js +1 -1
- package/build/components/post-card-panel/index.js.map +2 -2
- package/build/components/post-schedule/panel.js +1 -7
- package/build/components/post-schedule/panel.js.map +2 -2
- package/build/components/post-status/index.js +1 -7
- package/build/components/post-status/index.js.map +2 -2
- package/build/components/post-template/block-theme.js +1 -1
- package/build/components/post-template/block-theme.js.map +2 -2
- package/build/components/post-template/hooks.js +1 -1
- package/build/components/post-template/hooks.js.map +2 -2
- package/build/components/provider/index.js +3 -1
- package/build/components/provider/index.js.map +2 -2
- package/build/components/visual-editor/index.js +1 -7
- package/build/components/visual-editor/index.js.map +2 -2
- package/build/components/visual-editor/use-edit-content-only-section-exit.js +5 -6
- package/build/components/visual-editor/use-edit-content-only-section-exit.js.map +2 -2
- package/build/dataviews/store/private-actions.js +14 -2
- package/build/dataviews/store/private-actions.js.map +2 -2
- package/build/hooks/template-part-navigation-edit-button.js +8 -11
- package/build/hooks/template-part-navigation-edit-button.js.map +3 -3
- package/build/store/actions.js +1 -1
- package/build/store/actions.js.map +2 -2
- package/build/store/constants.js +8 -0
- package/build/store/constants.js.map +2 -2
- package/build/utils/get-template-part-icon.js +9 -4
- package/build/utils/get-template-part-icon.js.map +3 -3
- package/build-module/bindings/post-data.js +15 -15
- package/build-module/bindings/post-data.js.map +2 -2
- package/build-module/bindings/term-data.js +93 -95
- package/build-module/bindings/term-data.js.map +2 -2
- package/build-module/components/autocompleters/user.js.map +2 -2
- package/build-module/components/collab-sidebar/comments.js.map +2 -2
- package/build-module/components/collab-sidebar/hooks.js +7 -12
- package/build-module/components/collab-sidebar/hooks.js.map +2 -2
- package/build-module/components/document-bar/index.js +20 -9
- package/build-module/components/document-bar/index.js.map +2 -2
- package/build-module/components/document-bar/useEditedSectionDetails.js +74 -0
- package/build-module/components/document-bar/useEditedSectionDetails.js.map +7 -0
- package/build-module/components/global-styles/index.js +1 -1
- package/build-module/components/global-styles/index.js.map +1 -1
- package/build-module/components/page-attributes/parent.js +1 -0
- package/build-module/components/page-attributes/parent.js.map +2 -2
- package/build-module/components/post-card-panel/index.js +1 -1
- package/build-module/components/post-card-panel/index.js.map +2 -2
- package/build-module/components/post-schedule/panel.js +1 -12
- package/build-module/components/post-schedule/panel.js.map +2 -2
- package/build-module/components/post-status/index.js +1 -12
- package/build-module/components/post-status/index.js.map +2 -2
- package/build-module/components/post-template/block-theme.js +1 -1
- package/build-module/components/post-template/block-theme.js.map +2 -2
- package/build-module/components/post-template/hooks.js +1 -1
- package/build-module/components/post-template/hooks.js.map +2 -2
- package/build-module/components/provider/index.js +3 -1
- package/build-module/components/provider/index.js.map +2 -2
- package/build-module/components/visual-editor/index.js +2 -7
- package/build-module/components/visual-editor/index.js.map +2 -2
- package/build-module/components/visual-editor/use-edit-content-only-section-exit.js +5 -6
- package/build-module/components/visual-editor/use-edit-content-only-section-exit.js.map +2 -2
- package/build-module/dataviews/store/private-actions.js +16 -3
- package/build-module/dataviews/store/private-actions.js.map +2 -2
- package/build-module/hooks/template-part-navigation-edit-button.js +10 -17
- package/build-module/hooks/template-part-navigation-edit-button.js.map +2 -2
- package/build-module/store/actions.js +1 -1
- package/build-module/store/actions.js.map +2 -2
- package/build-module/store/constants.js +7 -0
- package/build-module/store/constants.js.map +2 -2
- package/build-module/utils/get-template-part-icon.js +10 -4
- package/build-module/utils/get-template-part-icon.js.map +2 -2
- package/build-style/style-rtl.css +296 -142
- package/build-style/style.css +296 -142
- package/build-types/bindings/post-data.d.ts +2 -1
- package/build-types/bindings/term-data.d.ts +86 -8
- package/build-types/bindings/term-data.d.ts.map +1 -1
- package/build-types/components/autocompleters/user.d.ts +8 -2
- package/build-types/components/autocompleters/user.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comments.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/hooks.d.ts +0 -1
- package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/document-bar/index.d.ts.map +1 -1
- package/build-types/components/document-bar/useEditedSectionDetails.d.ts +8 -0
- package/build-types/components/document-bar/useEditedSectionDetails.d.ts.map +1 -0
- package/build-types/components/page-attributes/parent.d.ts.map +1 -1
- package/build-types/components/post-schedule/panel.d.ts.map +1 -1
- package/build-types/components/post-status/index.d.ts.map +1 -1
- package/build-types/components/post-template/block-theme.d.ts.map +1 -1
- package/build-types/components/post-template/hooks.d.ts +1 -1
- package/build-types/components/post-template/hooks.d.ts.map +1 -1
- package/build-types/components/provider/index.d.ts.map +1 -1
- package/build-types/components/visual-editor/index.d.ts.map +1 -1
- package/build-types/components/visual-editor/use-edit-content-only-section-exit.d.ts.map +1 -1
- package/build-types/dataviews/store/private-actions.d.ts +5 -0
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/store/actions.d.ts.map +1 -1
- package/build-types/store/constants.d.ts +1 -0
- package/build-types/store/constants.d.ts.map +1 -1
- package/build-types/store/index.d.ts +1 -1
- package/build-types/store/index.d.ts.map +1 -1
- package/build-types/utils/get-template-part-icon.d.ts +3 -3
- package/build-types/utils/get-template-part-icon.d.ts.map +1 -1
- package/package.json +40 -40
- package/src/bindings/post-data.js +21 -20
- package/src/bindings/term-data.js +124 -151
- package/src/bindings/test/post-data.js +31 -20
- package/src/bindings/test/term-data.js +406 -0
- package/src/components/autocompleters/user.js +6 -0
- package/src/components/collab-sidebar/comments.js +1 -0
- package/src/components/collab-sidebar/hooks.js +7 -13
- package/src/components/document-bar/index.js +41 -9
- package/src/components/document-bar/useEditedSectionDetails.js +103 -0
- package/src/components/global-styles/index.js +1 -1
- package/src/components/global-styles-sidebar/style.scss +2 -2
- package/src/components/page-attributes/parent.js +2 -1
- package/src/components/post-card-panel/index.js +1 -1
- package/src/components/post-schedule/panel.js +1 -13
- package/src/components/post-status/index.js +1 -13
- package/src/components/post-template/block-theme.js +4 -1
- package/src/components/post-template/hooks.js +1 -1
- package/src/components/provider/index.js +7 -2
- package/src/components/visual-editor/index.js +1 -6
- package/src/components/visual-editor/use-edit-content-only-section-exit.js +9 -10
- package/src/dataviews/store/private-actions.ts +33 -1
- package/src/hooks/template-part-navigation-edit-button.js +4 -15
- package/src/store/actions.js +2 -0
- package/src/store/constants.ts +6 -0
- package/src/utils/get-template-part-icon.js +19 -6
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
5
|
+
import { store as coreDataStore } from '@wordpress/core-data';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { default as termDataBindings, termDataFields } from '../term-data';
|
|
11
|
+
|
|
12
|
+
describe( 'term-data bindings', () => {
|
|
13
|
+
const bindings = {
|
|
14
|
+
id: {
|
|
15
|
+
source: 'core/term-data',
|
|
16
|
+
args: { field: 'id' },
|
|
17
|
+
},
|
|
18
|
+
name: {
|
|
19
|
+
source: 'core/term-data',
|
|
20
|
+
args: { field: 'name' },
|
|
21
|
+
},
|
|
22
|
+
slug: {
|
|
23
|
+
source: 'core/term-data',
|
|
24
|
+
args: { field: 'slug' },
|
|
25
|
+
},
|
|
26
|
+
link: {
|
|
27
|
+
source: 'core/term-data',
|
|
28
|
+
args: { field: 'link' },
|
|
29
|
+
},
|
|
30
|
+
description: {
|
|
31
|
+
source: 'core/term-data',
|
|
32
|
+
args: { field: 'description' },
|
|
33
|
+
},
|
|
34
|
+
parent: {
|
|
35
|
+
source: 'core/term-data',
|
|
36
|
+
args: { field: 'parent' },
|
|
37
|
+
},
|
|
38
|
+
count: {
|
|
39
|
+
source: 'core/term-data',
|
|
40
|
+
args: { field: 'count' },
|
|
41
|
+
},
|
|
42
|
+
content: {
|
|
43
|
+
source: 'core/term-data',
|
|
44
|
+
args: { field: 'unknown' },
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const getEntityRecordMock = ( kind, taxonomy, termId ) => {
|
|
49
|
+
if (
|
|
50
|
+
kind === 'taxonomy' &&
|
|
51
|
+
taxonomy === 'category' &&
|
|
52
|
+
termId === 123
|
|
53
|
+
) {
|
|
54
|
+
return {
|
|
55
|
+
id: 123,
|
|
56
|
+
name: 'Technology',
|
|
57
|
+
slug: 'technology',
|
|
58
|
+
link: 'https://example.com/category/technology',
|
|
59
|
+
parent: 0,
|
|
60
|
+
count: 42,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
describe( 'getValues', () => {
|
|
67
|
+
describe( 'for regular blocks using block context', () => {
|
|
68
|
+
describe( 'when termId and taxonomy are provided in context', () => {
|
|
69
|
+
const select = ( store ) => {
|
|
70
|
+
if ( store === blockEditorStore ) {
|
|
71
|
+
return {
|
|
72
|
+
getBlockName: ( clientId ) =>
|
|
73
|
+
clientId === '123abc456'
|
|
74
|
+
? 'core/paragraph'
|
|
75
|
+
: undefined,
|
|
76
|
+
getBlockAttributes: () => ( {} ),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if ( store === coreDataStore ) {
|
|
80
|
+
return {
|
|
81
|
+
getEntityRecord: getEntityRecordMock,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
it( 'should return entity field values when they exist, fall back to field label, and to field name for unknown fields', () => {
|
|
87
|
+
const values = termDataBindings.getValues( {
|
|
88
|
+
select,
|
|
89
|
+
context: {
|
|
90
|
+
taxonomy: 'category',
|
|
91
|
+
termId: 123,
|
|
92
|
+
},
|
|
93
|
+
bindings,
|
|
94
|
+
clientId: '123abc456',
|
|
95
|
+
} );
|
|
96
|
+
|
|
97
|
+
expect( values ).toStrictEqual( {
|
|
98
|
+
id: 123,
|
|
99
|
+
name: 'Technology',
|
|
100
|
+
slug: 'technology',
|
|
101
|
+
link: 'https://example.com/category/technology',
|
|
102
|
+
description: 'Description',
|
|
103
|
+
parent: 0,
|
|
104
|
+
count: '(42)',
|
|
105
|
+
content: 'unknown',
|
|
106
|
+
} );
|
|
107
|
+
} );
|
|
108
|
+
|
|
109
|
+
it( 'should fall back to field label when entity does not exist, and to field name for unknown fields', () => {
|
|
110
|
+
const values = termDataBindings.getValues( {
|
|
111
|
+
select,
|
|
112
|
+
context: {
|
|
113
|
+
taxonomy: 'category',
|
|
114
|
+
termId: 456,
|
|
115
|
+
},
|
|
116
|
+
bindings,
|
|
117
|
+
clientId: '123abc456',
|
|
118
|
+
} );
|
|
119
|
+
|
|
120
|
+
expect( values ).toStrictEqual( {
|
|
121
|
+
id: 'Term ID',
|
|
122
|
+
name: 'Name',
|
|
123
|
+
slug: 'Slug',
|
|
124
|
+
link: 'Link',
|
|
125
|
+
description: 'Description',
|
|
126
|
+
parent: 'Parent ID',
|
|
127
|
+
count: 'Count',
|
|
128
|
+
content: 'unknown',
|
|
129
|
+
} );
|
|
130
|
+
} );
|
|
131
|
+
} );
|
|
132
|
+
|
|
133
|
+
describe( 'when termData is provided in context', () => {
|
|
134
|
+
const select = ( store ) => {
|
|
135
|
+
if ( store === blockEditorStore ) {
|
|
136
|
+
return {
|
|
137
|
+
getBlockName: () => 'core/paragraph',
|
|
138
|
+
getBlockAttributes: () => ( {} ),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if ( store === coreDataStore ) {
|
|
142
|
+
return {
|
|
143
|
+
getEntityRecord: () => null,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const termData = {
|
|
149
|
+
id: 456,
|
|
150
|
+
name: 'Design',
|
|
151
|
+
link: 'https://example.com/category/design',
|
|
152
|
+
description: 'Design resources',
|
|
153
|
+
parent: 0,
|
|
154
|
+
count: 15,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
it( 'should use termData from context when entity record is not available', () => {
|
|
158
|
+
const values = termDataBindings.getValues( {
|
|
159
|
+
select,
|
|
160
|
+
context: {
|
|
161
|
+
taxonomy: 'category',
|
|
162
|
+
termId: 456,
|
|
163
|
+
termData,
|
|
164
|
+
},
|
|
165
|
+
bindings,
|
|
166
|
+
clientId: '123abc456',
|
|
167
|
+
} );
|
|
168
|
+
|
|
169
|
+
expect( values ).toStrictEqual( {
|
|
170
|
+
id: 456,
|
|
171
|
+
name: 'Design',
|
|
172
|
+
slug: 'Slug',
|
|
173
|
+
link: 'https://example.com/category/design',
|
|
174
|
+
description: 'Design resources',
|
|
175
|
+
parent: 0,
|
|
176
|
+
count: '(15)',
|
|
177
|
+
content: 'unknown',
|
|
178
|
+
} );
|
|
179
|
+
} );
|
|
180
|
+
|
|
181
|
+
it( 'should use termData when taxonomy and termId are not provided', () => {
|
|
182
|
+
const values = termDataBindings.getValues( {
|
|
183
|
+
select,
|
|
184
|
+
context: {
|
|
185
|
+
termData,
|
|
186
|
+
},
|
|
187
|
+
bindings,
|
|
188
|
+
clientId: '123abc456',
|
|
189
|
+
} );
|
|
190
|
+
|
|
191
|
+
expect( values ).toStrictEqual( {
|
|
192
|
+
id: 456,
|
|
193
|
+
name: 'Design',
|
|
194
|
+
slug: 'Slug',
|
|
195
|
+
link: 'https://example.com/category/design',
|
|
196
|
+
description: 'Design resources',
|
|
197
|
+
parent: 0,
|
|
198
|
+
count: '(15)',
|
|
199
|
+
content: 'unknown',
|
|
200
|
+
} );
|
|
201
|
+
} );
|
|
202
|
+
} );
|
|
203
|
+
} );
|
|
204
|
+
|
|
205
|
+
describe( 'for navigation blocks using block attributes', () => {
|
|
206
|
+
it( 'should use block attributes instead of context', () => {
|
|
207
|
+
const select = ( store ) => {
|
|
208
|
+
if ( store === blockEditorStore ) {
|
|
209
|
+
return {
|
|
210
|
+
getBlockName: () => 'core/navigation-link',
|
|
211
|
+
getBlockAttributes: () => ( {
|
|
212
|
+
id: 789,
|
|
213
|
+
type: 'category',
|
|
214
|
+
} ),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
if ( store === coreDataStore ) {
|
|
218
|
+
return {
|
|
219
|
+
getEntityRecord: ( kind, taxonomy, termId ) => {
|
|
220
|
+
if (
|
|
221
|
+
kind === 'taxonomy' &&
|
|
222
|
+
taxonomy === 'category' &&
|
|
223
|
+
termId === 789
|
|
224
|
+
) {
|
|
225
|
+
return {
|
|
226
|
+
id: 789,
|
|
227
|
+
name: 'Programming',
|
|
228
|
+
slug: 'programming',
|
|
229
|
+
link: 'https://example.com/category/programming',
|
|
230
|
+
description: 'Programming resources',
|
|
231
|
+
parent: 0,
|
|
232
|
+
count: 10,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const values = termDataBindings.getValues( {
|
|
242
|
+
select,
|
|
243
|
+
context: {},
|
|
244
|
+
bindings,
|
|
245
|
+
clientId: '123abc456',
|
|
246
|
+
} );
|
|
247
|
+
|
|
248
|
+
expect( values ).toStrictEqual( {
|
|
249
|
+
id: 789,
|
|
250
|
+
name: 'Programming',
|
|
251
|
+
slug: 'programming',
|
|
252
|
+
link: 'https://example.com/category/programming',
|
|
253
|
+
description: 'Programming resources',
|
|
254
|
+
parent: 0,
|
|
255
|
+
count: '(10)',
|
|
256
|
+
content: 'unknown',
|
|
257
|
+
} );
|
|
258
|
+
} );
|
|
259
|
+
|
|
260
|
+
it( 'should convert "tag" type to "post_tag" taxonomy', () => {
|
|
261
|
+
const select = ( store ) => {
|
|
262
|
+
if ( store === blockEditorStore ) {
|
|
263
|
+
return {
|
|
264
|
+
getBlockName: () => 'core/navigation-link',
|
|
265
|
+
getBlockAttributes: () => ( {
|
|
266
|
+
id: 321,
|
|
267
|
+
type: 'tag',
|
|
268
|
+
} ),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if ( store === coreDataStore ) {
|
|
272
|
+
return {
|
|
273
|
+
getEntityRecord: ( kind, taxonomy, termId ) => {
|
|
274
|
+
if (
|
|
275
|
+
kind === 'taxonomy' &&
|
|
276
|
+
taxonomy === 'post_tag' &&
|
|
277
|
+
termId === 321
|
|
278
|
+
) {
|
|
279
|
+
return {
|
|
280
|
+
name: 'JavaScript',
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const values = termDataBindings.getValues( {
|
|
290
|
+
select,
|
|
291
|
+
context: {},
|
|
292
|
+
bindings: {
|
|
293
|
+
content: {
|
|
294
|
+
source: 'core/term-data',
|
|
295
|
+
args: { field: 'name' },
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
clientId: '123abc456',
|
|
299
|
+
} );
|
|
300
|
+
|
|
301
|
+
expect( values.content ).toBe( 'JavaScript' );
|
|
302
|
+
} );
|
|
303
|
+
} );
|
|
304
|
+
} );
|
|
305
|
+
|
|
306
|
+
describe( 'getFieldsList', () => {
|
|
307
|
+
describe( 'when a Navigation block is selected', () => {
|
|
308
|
+
it( 'should return the list of available term data fields if id and type attributes are present', () => {
|
|
309
|
+
const select = ( store ) => {
|
|
310
|
+
if ( store === blockEditorStore ) {
|
|
311
|
+
return {
|
|
312
|
+
getSelectedBlockClientId: () => '123abc456',
|
|
313
|
+
getBlockName: () => 'core/navigation-link',
|
|
314
|
+
getBlockAttributes: () => ( {
|
|
315
|
+
id: 123,
|
|
316
|
+
type: 'category',
|
|
317
|
+
} ),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if ( store === coreDataStore ) {
|
|
321
|
+
return {
|
|
322
|
+
getEntityRecord: getEntityRecordMock,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
const fields = termDataBindings.getFieldsList( { select } );
|
|
327
|
+
|
|
328
|
+
expect( fields ).toEqual( termDataFields );
|
|
329
|
+
} );
|
|
330
|
+
|
|
331
|
+
it( 'should return an empty array if id or type attributes are missing', () => {
|
|
332
|
+
const select = ( store ) => {
|
|
333
|
+
if ( store === blockEditorStore ) {
|
|
334
|
+
return {
|
|
335
|
+
getSelectedBlockClientId: () => '123abc456',
|
|
336
|
+
getBlockName: () => 'core/navigation-link',
|
|
337
|
+
getBlockAttributes: () => ( { type: 'category' } ),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
if ( store === coreDataStore ) {
|
|
341
|
+
return {
|
|
342
|
+
getEntityRecord: getEntityRecordMock,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const fields = termDataBindings.getFieldsList( { select } );
|
|
347
|
+
|
|
348
|
+
expect( fields ).toEqual( [] );
|
|
349
|
+
} );
|
|
350
|
+
} );
|
|
351
|
+
|
|
352
|
+
describe( 'when a non-Navigation block is selected', () => {
|
|
353
|
+
const select = ( store ) => {
|
|
354
|
+
if ( store === blockEditorStore ) {
|
|
355
|
+
return {
|
|
356
|
+
getSelectedBlockClientId: () => '123abc456',
|
|
357
|
+
getBlockName: () => 'core/paragraph',
|
|
358
|
+
getBlockAttributes: () => ( {} ),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
if ( store === coreDataStore ) {
|
|
362
|
+
return {
|
|
363
|
+
getEntityRecord: getEntityRecordMock,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
it( 'should return the list of available term data fields when taxonomy and termId are provided by context', () => {
|
|
369
|
+
const fields = termDataBindings.getFieldsList( {
|
|
370
|
+
select,
|
|
371
|
+
context: { taxonomy: 'category', termId: 123 },
|
|
372
|
+
} );
|
|
373
|
+
|
|
374
|
+
expect( fields ).toEqual( termDataFields );
|
|
375
|
+
} );
|
|
376
|
+
|
|
377
|
+
it( 'should return empty array when neither termId nor termData is provided from context', () => {
|
|
378
|
+
const fields = termDataBindings.getFieldsList( {
|
|
379
|
+
select,
|
|
380
|
+
context: { taxonomy: 'category' },
|
|
381
|
+
} );
|
|
382
|
+
|
|
383
|
+
expect( fields ).toEqual( [] );
|
|
384
|
+
} );
|
|
385
|
+
|
|
386
|
+
it( 'should return fields when using termData from context', () => {
|
|
387
|
+
const fields = termDataBindings.getFieldsList( {
|
|
388
|
+
select,
|
|
389
|
+
context: {
|
|
390
|
+
termData: {
|
|
391
|
+
id: 456,
|
|
392
|
+
name: 'Design',
|
|
393
|
+
slug: 'design',
|
|
394
|
+
link: 'https://example.com/category/design',
|
|
395
|
+
description: 'Design resources',
|
|
396
|
+
parent: 0,
|
|
397
|
+
count: 15,
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
} );
|
|
401
|
+
|
|
402
|
+
expect( fields ).toEqual( termDataFields );
|
|
403
|
+
} );
|
|
404
|
+
} );
|
|
405
|
+
} );
|
|
406
|
+
} );
|
|
@@ -5,6 +5,12 @@ import { useMemo } from '@wordpress/element';
|
|
|
5
5
|
import { useSelect } from '@wordpress/data';
|
|
6
6
|
import { store as coreStore } from '@wordpress/core-data';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Renders a user label for the autocompleter.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} user User object.
|
|
12
|
+
* @return {JSX.Element} User label component.
|
|
13
|
+
*/
|
|
8
14
|
export function getUserLabel( user ) {
|
|
9
15
|
const avatar =
|
|
10
16
|
user.avatar_urls && user.avatar_urls[ 24 ] ? (
|
|
@@ -14,7 +14,6 @@ import { __ } from '@wordpress/i18n';
|
|
|
14
14
|
import {
|
|
15
15
|
useEffect,
|
|
16
16
|
useMemo,
|
|
17
|
-
useRef,
|
|
18
17
|
useCallback,
|
|
19
18
|
useReducer,
|
|
20
19
|
} from '@wordpress/element';
|
|
@@ -36,9 +35,7 @@ import { collabSidebarName } from './constants';
|
|
|
36
35
|
import { unlock } from '../../lock-unlock';
|
|
37
36
|
import { noop } from './utils';
|
|
38
37
|
|
|
39
|
-
const {
|
|
40
|
-
blockEditorPrivateApis
|
|
41
|
-
);
|
|
38
|
+
const { useBlockElement, cleanEmptyObject } = unlock( blockEditorPrivateApis );
|
|
42
39
|
|
|
43
40
|
export function useBlockComments( postId ) {
|
|
44
41
|
const [ commentLastUpdated, reflowComments ] = useReducer(
|
|
@@ -369,9 +366,7 @@ export function useFloatingThread( {
|
|
|
369
366
|
setBlockRef,
|
|
370
367
|
commentLastUpdated,
|
|
371
368
|
} ) {
|
|
372
|
-
const
|
|
373
|
-
useBlockElementRef( thread.blockClientId, blockRef );
|
|
374
|
-
|
|
369
|
+
const blockElement = useBlockElement( thread.blockClientId );
|
|
375
370
|
const updateHeight = useCallback(
|
|
376
371
|
( id, newHeight ) => {
|
|
377
372
|
setHeights( ( prev ) => {
|
|
@@ -397,17 +392,17 @@ export function useFloatingThread( {
|
|
|
397
392
|
|
|
398
393
|
// Store the block reference for each thread.
|
|
399
394
|
useEffect( () => {
|
|
400
|
-
if (
|
|
401
|
-
refs.setReference(
|
|
395
|
+
if ( blockElement ) {
|
|
396
|
+
refs.setReference( blockElement );
|
|
402
397
|
}
|
|
403
|
-
}, [
|
|
398
|
+
}, [ blockElement, refs, commentLastUpdated ] );
|
|
404
399
|
|
|
405
400
|
// Track thread heights.
|
|
406
401
|
useEffect( () => {
|
|
407
402
|
if ( refs.floating?.current ) {
|
|
408
|
-
setBlockRef( thread.id,
|
|
403
|
+
setBlockRef( thread.id, blockElement );
|
|
409
404
|
}
|
|
410
|
-
}, [ thread.id, refs.floating, setBlockRef ] );
|
|
405
|
+
}, [ blockElement, thread.id, refs.floating, setBlockRef ] );
|
|
411
406
|
|
|
412
407
|
// When the selected thread changes, update heights, triggering offset recalculation.
|
|
413
408
|
useEffect( () => {
|
|
@@ -424,7 +419,6 @@ export function useFloatingThread( {
|
|
|
424
419
|
] );
|
|
425
420
|
|
|
426
421
|
return {
|
|
427
|
-
blockRef,
|
|
428
422
|
y,
|
|
429
423
|
refs,
|
|
430
424
|
};
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
__unstableMotion as motion,
|
|
15
15
|
__unstableAnimatePresence as AnimatePresence,
|
|
16
16
|
} from '@wordpress/components';
|
|
17
|
-
import { BlockIcon } from '@wordpress/block-editor';
|
|
17
|
+
import { BlockIcon, store as blockEditorStore } from '@wordpress/block-editor';
|
|
18
18
|
import { chevronLeftSmall, chevronRightSmall, layout } from '@wordpress/icons';
|
|
19
19
|
import { displayShortcut } from '@wordpress/keycodes';
|
|
20
20
|
import { store as coreStore } from '@wordpress/core-data';
|
|
@@ -33,6 +33,7 @@ import usePageTypeBadge from '../../utils/pageTypeBadge';
|
|
|
33
33
|
import { getTemplateInfo } from '../../utils/get-template-info';
|
|
34
34
|
import { getStylesCanvasTitle } from '../styles-canvas';
|
|
35
35
|
import { unlock } from '../../lock-unlock';
|
|
36
|
+
import useEditedSectionDetails from './useEditedSectionDetails';
|
|
36
37
|
|
|
37
38
|
/** @typedef {import("@wordpress/components").IconType} IconType */
|
|
38
39
|
|
|
@@ -56,6 +57,14 @@ const MotionButton = motion.create( Button );
|
|
|
56
57
|
* @return {React.ReactNode} The rendered DocumentBar component.
|
|
57
58
|
*/
|
|
58
59
|
export default function DocumentBar( props ) {
|
|
60
|
+
// Get action to lock the pattern design
|
|
61
|
+
const { stopEditingContentOnlySection } = unlock(
|
|
62
|
+
useDispatch( blockEditorStore )
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Get details about the currently edited content-only section
|
|
66
|
+
const unlockedPatternInfo = useEditedSectionDetails();
|
|
67
|
+
|
|
59
68
|
const {
|
|
60
69
|
postId,
|
|
61
70
|
postType,
|
|
@@ -133,11 +142,28 @@ export default function DocumentBar( props ) {
|
|
|
133
142
|
const isReducedMotion = useReducedMotion();
|
|
134
143
|
|
|
135
144
|
const isTemplate = TEMPLATE_POST_TYPES.includes( postType );
|
|
136
|
-
const hasBackButton =
|
|
145
|
+
const hasBackButton =
|
|
146
|
+
!! onNavigateToPreviousEntityRecord || !! unlockedPatternInfo;
|
|
137
147
|
const entityTitle = isTemplate ? templateTitle : documentTitle;
|
|
138
|
-
|
|
148
|
+
|
|
149
|
+
// Use pattern info if a pattern block is unlocked, otherwise use document/entity info
|
|
150
|
+
const title =
|
|
151
|
+
unlockedPatternInfo?.patternTitle ||
|
|
152
|
+
props.title ||
|
|
153
|
+
stylesCanvasTitle ||
|
|
154
|
+
entityTitle;
|
|
139
155
|
const icon = props.icon;
|
|
140
156
|
|
|
157
|
+
// Determine the back button action
|
|
158
|
+
const handleBackClick = ( event ) => {
|
|
159
|
+
event.stopPropagation();
|
|
160
|
+
if ( unlockedPatternInfo ) {
|
|
161
|
+
stopEditingContentOnlySection();
|
|
162
|
+
} else if ( onNavigateToPreviousEntityRecord ) {
|
|
163
|
+
onNavigateToPreviousEntityRecord();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
141
167
|
const pageTypeBadge = usePageTypeBadge( postId );
|
|
142
168
|
|
|
143
169
|
const mountedRef = useRef( false );
|
|
@@ -156,10 +182,7 @@ export default function DocumentBar( props ) {
|
|
|
156
182
|
<MotionButton
|
|
157
183
|
className="editor-document-bar__back"
|
|
158
184
|
icon={ isRTL() ? chevronRightSmall : chevronLeftSmall }
|
|
159
|
-
onClick={
|
|
160
|
-
event.stopPropagation();
|
|
161
|
-
onNavigateToPreviousEntityRecord();
|
|
162
|
-
} }
|
|
185
|
+
onClick={ handleBackClick }
|
|
163
186
|
size="compact"
|
|
164
187
|
initial={
|
|
165
188
|
mountedRef.current
|
|
@@ -219,12 +242,21 @@ export default function DocumentBar( props ) {
|
|
|
219
242
|
? stripHTML( title )
|
|
220
243
|
: __( 'No title' ) }
|
|
221
244
|
</span>
|
|
222
|
-
{
|
|
245
|
+
{ unlockedPatternInfo && (
|
|
246
|
+
<span className="editor-document-bar__post-type-label">
|
|
247
|
+
{ unlockedPatternInfo.type ===
|
|
248
|
+
'template-part'
|
|
249
|
+
? `· ${ __( 'Template Part' ) }`
|
|
250
|
+
: `· ${ __( 'Pattern' ) }` }
|
|
251
|
+
</span>
|
|
252
|
+
) }
|
|
253
|
+
{ ! unlockedPatternInfo && pageTypeBadge && (
|
|
223
254
|
<span className="editor-document-bar__post-type-label">
|
|
224
255
|
{ `· ${ pageTypeBadge }` }
|
|
225
256
|
</span>
|
|
226
257
|
) }
|
|
227
|
-
{
|
|
258
|
+
{ ! unlockedPatternInfo &&
|
|
259
|
+
postTypeLabel &&
|
|
228
260
|
! props.title &&
|
|
229
261
|
! pageTypeBadge && (
|
|
230
262
|
<span className="editor-document-bar__post-type-label">
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useSelect } from '@wordpress/data';
|
|
5
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
6
|
+
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
7
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies
|
|
11
|
+
*/
|
|
12
|
+
import { unlock } from '../../lock-unlock';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hook to get details about the currently edited content-only section.
|
|
16
|
+
* Only returns information when the content only pattern insertion experiment is enabled.
|
|
17
|
+
*
|
|
18
|
+
* @return {Object|null} Object with patternName, patternTitle, and type, or null if no section is being edited or experiment is disabled.
|
|
19
|
+
*/
|
|
20
|
+
export default function useEditedSectionDetails() {
|
|
21
|
+
return useSelect( ( select ) => {
|
|
22
|
+
// Only run when the content only pattern insertion experiment is enabled
|
|
23
|
+
if ( ! window?.__experimentalContentOnlyPatternInsertion ) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
getBlockAttributes,
|
|
29
|
+
getBlockName,
|
|
30
|
+
__experimentalGetParsedPattern,
|
|
31
|
+
} = select( blockEditorStore );
|
|
32
|
+
const { getEditedEntityRecord, getCurrentTheme } = select( coreStore );
|
|
33
|
+
const { getEditedContentOnlySection } = unlock(
|
|
34
|
+
select( blockEditorStore )
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Get the clientId of the unlocked pattern/section
|
|
38
|
+
const editedSectionId = getEditedContentOnlySection();
|
|
39
|
+
if ( ! editedSectionId ) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const attributes = getBlockAttributes( editedSectionId );
|
|
44
|
+
|
|
45
|
+
// Handle unsynced patterns (contentOnly patterns with patternName)
|
|
46
|
+
const patternName = attributes?.metadata?.patternName;
|
|
47
|
+
if ( patternName ) {
|
|
48
|
+
// Get pattern details if available
|
|
49
|
+
const pattern =
|
|
50
|
+
typeof __experimentalGetParsedPattern === 'function'
|
|
51
|
+
? __experimentalGetParsedPattern( patternName )
|
|
52
|
+
: null;
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
patternName,
|
|
56
|
+
patternTitle: pattern?.title || attributes?.metadata?.name,
|
|
57
|
+
type: 'pattern',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const blockName = getBlockName( editedSectionId );
|
|
62
|
+
|
|
63
|
+
// Handle synced patterns (core/block)
|
|
64
|
+
if ( blockName === 'core/block' && !! attributes?.ref ) {
|
|
65
|
+
const entity = getEditedEntityRecord(
|
|
66
|
+
'postType',
|
|
67
|
+
'wp_block',
|
|
68
|
+
attributes.ref
|
|
69
|
+
);
|
|
70
|
+
if ( entity?.title ) {
|
|
71
|
+
return {
|
|
72
|
+
patternName: attributes.ref,
|
|
73
|
+
patternTitle: decodeEntities( entity.title ),
|
|
74
|
+
type: 'synced-pattern',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Handle template parts (core/template-part)
|
|
80
|
+
if ( blockName === 'core/template-part' && !! attributes?.slug ) {
|
|
81
|
+
const theme = attributes.theme || getCurrentTheme()?.stylesheet;
|
|
82
|
+
const templatePartId = theme
|
|
83
|
+
? `${ theme }//${ attributes.slug }`
|
|
84
|
+
: null;
|
|
85
|
+
if ( templatePartId ) {
|
|
86
|
+
const entity = getEditedEntityRecord(
|
|
87
|
+
'postType',
|
|
88
|
+
'wp_template_part',
|
|
89
|
+
templatePartId
|
|
90
|
+
);
|
|
91
|
+
if ( entity?.title ) {
|
|
92
|
+
return {
|
|
93
|
+
patternName: attributes.slug,
|
|
94
|
+
patternTitle: decodeEntities( entity.title ),
|
|
95
|
+
type: 'template-part',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return null;
|
|
102
|
+
}, [] );
|
|
103
|
+
}
|