@wordpress/fields 0.5.0 → 0.5.1-next.cd6172eb0.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/README.md +29 -0
- package/build/actions/duplicate-template-part.js +68 -0
- package/build/actions/duplicate-template-part.js.map +1 -0
- package/build/actions/index.js +7 -0
- package/build/actions/index.js.map +1 -1
- package/build/actions/permanently-delete-post.js +0 -1
- package/build/actions/permanently-delete-post.js.map +1 -1
- package/build/actions/rename-post.js +2 -2
- package/build/actions/rename-post.js.map +1 -1
- package/build/actions/reset-post.js +3 -3
- package/build/actions/reset-post.js.map +1 -1
- package/build/actions/restore-post.js +0 -1
- package/build/actions/restore-post.js.map +1 -1
- package/build/actions/trash-post.js +0 -1
- package/build/actions/trash-post.js.map +1 -1
- package/build/actions/utils.js +4 -12
- package/build/actions/utils.js.map +1 -1
- package/build/components/create-template-part-modal/index.js +213 -0
- package/build/components/create-template-part-modal/index.js.map +1 -0
- package/build/components/create-template-part-modal/utils.js +64 -0
- package/build/components/create-template-part-modal/utils.js.map +1 -0
- package/build/fields/index.js +7 -0
- package/build/fields/index.js.map +1 -1
- package/build/fields/slug/slug-view.js +1 -1
- package/build/fields/slug/slug-view.js.map +1 -1
- package/build/fields/slug/utils.js +3 -0
- package/build/fields/slug/utils.js.map +1 -1
- package/build/fields/template/index.js +28 -0
- package/build/fields/template/index.js.map +1 -0
- package/build/fields/template/template-edit.js +154 -0
- package/build/fields/template/template-edit.js.map +1 -0
- package/build/fields/title/title-view.js +1 -1
- package/build/fields/title/title-view.js.map +1 -1
- package/build/index.js +13 -0
- package/build/index.js.map +1 -1
- package/build/mutation/index.js +0 -1
- package/build/mutation/index.js.map +1 -1
- package/build/types.js.map +1 -1
- package/build-module/actions/duplicate-template-part.js +63 -0
- package/build-module/actions/duplicate-template-part.js.map +1 -0
- package/build-module/actions/index.js +1 -0
- package/build-module/actions/index.js.map +1 -1
- package/build-module/actions/permanently-delete-post.js +0 -1
- package/build-module/actions/permanently-delete-post.js.map +1 -1
- package/build-module/actions/rename-post.js +3 -3
- package/build-module/actions/rename-post.js.map +1 -1
- package/build-module/actions/reset-post.js +4 -4
- package/build-module/actions/reset-post.js.map +1 -1
- package/build-module/actions/restore-post.js +0 -1
- package/build-module/actions/restore-post.js.map +1 -1
- package/build-module/actions/trash-post.js +0 -1
- package/build-module/actions/trash-post.js.map +1 -1
- package/build-module/actions/utils.js +4 -11
- package/build-module/actions/utils.js.map +1 -1
- package/build-module/components/create-template-part-modal/index.js +204 -0
- package/build-module/components/create-template-part-modal/index.js.map +1 -0
- package/build-module/components/create-template-part-modal/utils.js +55 -0
- package/build-module/components/create-template-part-modal/utils.js.map +1 -0
- package/build-module/fields/index.js +1 -0
- package/build-module/fields/index.js.map +1 -1
- package/build-module/fields/slug/slug-view.js +1 -1
- package/build-module/fields/slug/slug-view.js.map +1 -1
- package/build-module/fields/slug/utils.js +3 -0
- package/build-module/fields/slug/utils.js.map +1 -1
- package/build-module/fields/template/index.js +21 -0
- package/build-module/fields/template/index.js.map +1 -0
- package/build-module/fields/template/template-edit.js +144 -0
- package/build-module/fields/template/template-edit.js.map +1 -0
- package/build-module/fields/title/title-view.js +1 -1
- package/build-module/fields/title/title-view.js.map +1 -1
- package/build-module/index.js +1 -0
- package/build-module/index.js.map +1 -1
- package/build-module/mutation/index.js +0 -1
- package/build-module/mutation/index.js.map +1 -1
- package/build-module/types.js.map +1 -1
- package/build-style/style-rtl.css +74 -0
- package/build-style/style.css +74 -0
- package/build-types/actions/duplicate-template-part.d.ts +11 -0
- package/build-types/actions/duplicate-template-part.d.ts.map +1 -0
- package/build-types/actions/index.d.ts +1 -0
- package/build-types/actions/index.d.ts.map +1 -1
- package/build-types/actions/rename-post.d.ts.map +1 -1
- package/build-types/actions/reset-post.d.ts.map +1 -1
- package/build-types/actions/utils.d.ts +7 -8
- package/build-types/actions/utils.d.ts.map +1 -1
- package/build-types/components/create-template-part-modal/index.d.ts +34 -0
- package/build-types/components/create-template-part-modal/index.d.ts.map +1 -0
- package/build-types/components/create-template-part-modal/utils.d.ts +4 -0
- package/build-types/components/create-template-part-modal/utils.d.ts.map +1 -0
- package/build-types/fields/index.d.ts +1 -0
- package/build-types/fields/index.d.ts.map +1 -1
- package/build-types/fields/slug/utils.d.ts.map +1 -1
- package/build-types/fields/template/index.d.ts +8 -0
- package/build-types/fields/template/index.d.ts.map +1 -0
- package/build-types/fields/template/template-edit.d.ts +4 -0
- package/build-types/fields/template/template-edit.d.ts.map +1 -0
- package/build-types/fields/title/title-view.d.ts.map +1 -1
- package/build-types/index.d.ts +2 -1
- package/build-types/index.d.ts.map +1 -1
- package/build-types/lock-unlock.d.ts +1 -1
- package/build-types/lock-unlock.d.ts.map +1 -1
- package/build-types/types.d.ts +3 -0
- package/build-types/types.d.ts.map +1 -1
- package/package.json +24 -23
- package/src/actions/duplicate-template-part.tsx +72 -0
- package/src/actions/index.ts +1 -0
- package/src/actions/rename-post.tsx +3 -6
- package/src/actions/reset-post.tsx +4 -9
- package/src/actions/utils.ts +7 -15
- package/src/components/create-template-part-modal/index.tsx +274 -0
- package/src/components/create-template-part-modal/style.scss +63 -0
- package/src/components/create-template-part-modal/test/utils.js +60 -0
- package/src/components/create-template-part-modal/utils.js +68 -0
- package/src/fields/index.ts +1 -0
- package/src/fields/slug/slug-view.tsx +1 -1
- package/src/fields/slug/utils.ts +4 -0
- package/src/fields/template/index.ts +22 -0
- package/src/fields/template/style.scss +23 -0
- package/src/fields/template/template-edit.tsx +210 -0
- package/src/fields/title/title-view.tsx +3 -4
- package/src/index.ts +2 -1
- package/src/style.scss +2 -0
- package/src/types.ts +3 -0
- package/tsconfig.json +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.fields-create-template-part-modal {
|
|
2
|
+
z-index: z-index(".fields-create-template-part-modal");
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.fields-create-template-part-modal__area-radio-group {
|
|
6
|
+
width: 100%;
|
|
7
|
+
border: $border-width solid $gray-700;
|
|
8
|
+
border-radius: $radius-small;
|
|
9
|
+
|
|
10
|
+
.components-button.fields-create-template-part-modal__area-radio {
|
|
11
|
+
display: block;
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
text-align: left;
|
|
15
|
+
padding: $grid-unit-15;
|
|
16
|
+
|
|
17
|
+
&,
|
|
18
|
+
&.is-secondary:hover,
|
|
19
|
+
&.is-primary:hover {
|
|
20
|
+
margin: 0;
|
|
21
|
+
background-color: inherit;
|
|
22
|
+
border-bottom: $border-width solid $gray-700;
|
|
23
|
+
border-radius: 0;
|
|
24
|
+
|
|
25
|
+
&:not(:focus) {
|
|
26
|
+
box-shadow: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&:focus {
|
|
30
|
+
border-bottom: $border-width solid $white;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&:last-of-type {
|
|
34
|
+
border-bottom: none;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:not(:hover),
|
|
39
|
+
&[aria-checked="true"] {
|
|
40
|
+
color: $gray-900;
|
|
41
|
+
cursor: auto;
|
|
42
|
+
|
|
43
|
+
.fields-create-template-part-modal__option-label div {
|
|
44
|
+
color: $gray-600;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.fields-create-template-part-modal__option-label {
|
|
49
|
+
padding-top: $grid-unit-05;
|
|
50
|
+
white-space: normal;
|
|
51
|
+
|
|
52
|
+
div {
|
|
53
|
+
padding-top: $grid-unit-05;
|
|
54
|
+
font-size: $helptext-font-size;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.fields-create-template-part-modal__checkbox {
|
|
59
|
+
margin-left: auto;
|
|
60
|
+
min-width: $grid-unit-30;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { getUniqueTemplatePartTitle, getCleanTemplatePartSlug } from '../utils';
|
|
5
|
+
|
|
6
|
+
describe( 'getUniqueTemplatePartTitle', () => {
|
|
7
|
+
it( 'should return the title if it is unique', () => {
|
|
8
|
+
const title = 'My Template Part';
|
|
9
|
+
const templateParts = [
|
|
10
|
+
{
|
|
11
|
+
title: {
|
|
12
|
+
rendered: 'Template Part With Another Title',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
expect( getUniqueTemplatePartTitle( title, templateParts ) ).toBe(
|
|
18
|
+
title
|
|
19
|
+
);
|
|
20
|
+
} );
|
|
21
|
+
|
|
22
|
+
it( 'should return the title with a suffix if it is not unique', () => {
|
|
23
|
+
const title = 'My Template Part';
|
|
24
|
+
const templateParts = [
|
|
25
|
+
{
|
|
26
|
+
title: {
|
|
27
|
+
rendered: 'My Template Part',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: {
|
|
32
|
+
rendered: 'My Template Part 2',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
expect( getUniqueTemplatePartTitle( title, templateParts ) ).toBe(
|
|
38
|
+
'My Template Part 3'
|
|
39
|
+
);
|
|
40
|
+
} );
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
describe( 'getCleanTemplatePartSlug', () => {
|
|
44
|
+
it( 'should return a slug with only latin chars', () => {
|
|
45
|
+
const title = 'Myɶ Template Partɮ';
|
|
46
|
+
expect( getCleanTemplatePartSlug( title ) ).toBe( 'my-template-part' );
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
it( 'should return a slug with only latin chars and numbers', () => {
|
|
50
|
+
const title = 'My Template Part 2';
|
|
51
|
+
expect( getCleanTemplatePartSlug( title ) ).toBe(
|
|
52
|
+
'my-template-part-2'
|
|
53
|
+
);
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
it( 'should default the slug to wp-custom-part', () => {
|
|
57
|
+
const title = '';
|
|
58
|
+
expect( getCleanTemplatePartSlug( title ) ).toBe( 'wp-custom-part' );
|
|
59
|
+
} );
|
|
60
|
+
} );
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { paramCase as kebabCase } from 'change-case';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const useExistingTemplateParts = () => {
|
|
17
|
+
return (
|
|
18
|
+
useSelect(
|
|
19
|
+
( select ) =>
|
|
20
|
+
select( coreStore ).getEntityRecords(
|
|
21
|
+
'postType',
|
|
22
|
+
'wp_template_part',
|
|
23
|
+
{
|
|
24
|
+
per_page: -1,
|
|
25
|
+
}
|
|
26
|
+
),
|
|
27
|
+
[]
|
|
28
|
+
) ?? []
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Return a unique template part title based on
|
|
34
|
+
* the given title and existing template parts.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} title The original template part title.
|
|
37
|
+
* @param {Object} templateParts The array of template part entities.
|
|
38
|
+
* @return {string} A unique template part title.
|
|
39
|
+
*/
|
|
40
|
+
export const getUniqueTemplatePartTitle = ( title, templateParts ) => {
|
|
41
|
+
const lowercaseTitle = title.toLowerCase();
|
|
42
|
+
const existingTitles = templateParts.map( ( templatePart ) =>
|
|
43
|
+
templatePart.title.rendered.toLowerCase()
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if ( ! existingTitles.includes( lowercaseTitle ) ) {
|
|
47
|
+
return title;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let suffix = 2;
|
|
51
|
+
while ( existingTitles.includes( `${ lowercaseTitle } ${ suffix }` ) ) {
|
|
52
|
+
suffix++;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return `${ title } ${ suffix }`;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get a valid slug for a template part.
|
|
60
|
+
* Currently template parts only allow latin chars.
|
|
61
|
+
* The fallback slug will receive suffix by default.
|
|
62
|
+
*
|
|
63
|
+
* @param {string} title The template part title.
|
|
64
|
+
* @return {string} A valid template part slug.
|
|
65
|
+
*/
|
|
66
|
+
export const getCleanTemplatePartSlug = ( title ) => {
|
|
67
|
+
return kebabCase( title ).replace( /[^\w-]+/g, '' ) || 'wp-custom-part';
|
|
68
|
+
};
|
package/src/fields/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { default as slugField } from './slug';
|
|
|
2
2
|
export { default as titleField } from './title';
|
|
3
3
|
export { default as orderField } from './order';
|
|
4
4
|
export { default as featuredImageField } from './featured-image';
|
|
5
|
+
export { default as templateField } from './template';
|
|
5
6
|
export { default as parentField } from './parent';
|
|
6
7
|
export { default as passwordField } from './password';
|
|
7
8
|
export { default as statusField } from './status';
|
|
@@ -10,7 +10,7 @@ import type { BasePost } from '../../types';
|
|
|
10
10
|
import { getSlug } from './utils';
|
|
11
11
|
|
|
12
12
|
const SlugView = ( { item }: { item: BasePost } ) => {
|
|
13
|
-
const slug =
|
|
13
|
+
const slug = getSlug( item );
|
|
14
14
|
const originalSlugRef = useRef( slug );
|
|
15
15
|
|
|
16
16
|
useEffect( () => {
|
package/src/fields/slug/utils.ts
CHANGED
|
@@ -9,6 +9,10 @@ import type { BasePost } from '../../types';
|
|
|
9
9
|
import { getItemTitle } from '../../actions/utils';
|
|
10
10
|
|
|
11
11
|
export const getSlug = ( item: BasePost ): string => {
|
|
12
|
+
if ( typeof item !== 'object' ) {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
return (
|
|
13
17
|
item.slug || cleanForSlug( getItemTitle( item ) ) || item.id.toString()
|
|
14
18
|
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { Field } from '@wordpress/dataviews';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
import type { BasePost } from '../../types';
|
|
11
|
+
import { TemplateEdit } from './template-edit';
|
|
12
|
+
|
|
13
|
+
const templateField: Field< BasePost > = {
|
|
14
|
+
id: 'template',
|
|
15
|
+
type: 'text',
|
|
16
|
+
label: __( 'Template' ),
|
|
17
|
+
getValue: ( { item } ) => item.template,
|
|
18
|
+
Edit: TemplateEdit,
|
|
19
|
+
enableSorting: false,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default templateField;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.fields-controls__template-modal {
|
|
2
|
+
z-index: z-index(".fields-controls__template-modal");
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.fields-controls__template-content .block-editor-block-patterns-list {
|
|
6
|
+
column-count: 2;
|
|
7
|
+
column-gap: $grid-unit-30;
|
|
8
|
+
|
|
9
|
+
// Small top padding required to avoid cutting off the visible outline when hovering items
|
|
10
|
+
padding-top: $border-width-focus-fallback;
|
|
11
|
+
|
|
12
|
+
@include break-medium() {
|
|
13
|
+
column-count: 3;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@include break-wide() {
|
|
17
|
+
column-count: 4;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.block-editor-block-patterns-list__list-item {
|
|
21
|
+
break-inside: avoid-column;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback, useMemo, useState } from '@wordpress/element';
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import { parse } from '@wordpress/blocks';
|
|
7
|
+
import type { WpTemplate } from '@wordpress/core-data';
|
|
8
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
9
|
+
import type { DataFormControlProps } from '@wordpress/dataviews';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
// @ts-expect-error block-editor is not typed correctly.
|
|
15
|
+
import { __experimentalBlockPatternsList as BlockPatternsList } from '@wordpress/block-editor';
|
|
16
|
+
import {
|
|
17
|
+
Button,
|
|
18
|
+
Dropdown,
|
|
19
|
+
MenuGroup,
|
|
20
|
+
MenuItem,
|
|
21
|
+
Modal,
|
|
22
|
+
} from '@wordpress/components';
|
|
23
|
+
import { useAsyncList } from '@wordpress/compose';
|
|
24
|
+
import { useSelect } from '@wordpress/data';
|
|
25
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
26
|
+
import { __ } from '@wordpress/i18n';
|
|
27
|
+
import { getItemTitle } from '../../actions/utils';
|
|
28
|
+
import type { BasePost } from '../../types';
|
|
29
|
+
import { unlock } from '../../lock-unlock';
|
|
30
|
+
|
|
31
|
+
export const TemplateEdit = ( {
|
|
32
|
+
data,
|
|
33
|
+
field,
|
|
34
|
+
onChange,
|
|
35
|
+
}: DataFormControlProps< BasePost > ) => {
|
|
36
|
+
const { id } = field;
|
|
37
|
+
const postType = data.type;
|
|
38
|
+
const postId =
|
|
39
|
+
typeof data.id === 'number' ? data.id : parseInt( data.id, 10 );
|
|
40
|
+
const slug = data.slug;
|
|
41
|
+
|
|
42
|
+
const { availableTemplates, templates } = useSelect(
|
|
43
|
+
( select ) => {
|
|
44
|
+
const allTemplates =
|
|
45
|
+
select( coreStore ).getEntityRecords< WpTemplate >(
|
|
46
|
+
'postType',
|
|
47
|
+
'wp_template',
|
|
48
|
+
{
|
|
49
|
+
per_page: -1,
|
|
50
|
+
post_type: postType,
|
|
51
|
+
}
|
|
52
|
+
) ?? [];
|
|
53
|
+
|
|
54
|
+
const { getHomePage, getPostsPageId } = unlock(
|
|
55
|
+
select( coreStore )
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const isPostsPage = getPostsPageId() === +postId;
|
|
59
|
+
const isFrontPage =
|
|
60
|
+
postType === 'page' && getHomePage()?.postId === +postId;
|
|
61
|
+
|
|
62
|
+
const allowSwitchingTemplate = ! isPostsPage && ! isFrontPage;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
templates: allTemplates,
|
|
66
|
+
availableTemplates: allowSwitchingTemplate
|
|
67
|
+
? allTemplates.filter(
|
|
68
|
+
( template ) =>
|
|
69
|
+
template.is_custom &&
|
|
70
|
+
template.slug !== data.template &&
|
|
71
|
+
!! template.content.raw // Skip empty templates.
|
|
72
|
+
)
|
|
73
|
+
: [],
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
[ data.template, postId, postType ]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const templatesAsPatterns = useMemo(
|
|
80
|
+
() =>
|
|
81
|
+
availableTemplates.map( ( template ) => ( {
|
|
82
|
+
name: template.slug,
|
|
83
|
+
blocks: parse( template.content.raw ),
|
|
84
|
+
title: decodeEntities( template.title.rendered ),
|
|
85
|
+
id: template.id,
|
|
86
|
+
} ) ),
|
|
87
|
+
[ availableTemplates ]
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const shownTemplates = useAsyncList( templatesAsPatterns );
|
|
91
|
+
|
|
92
|
+
const value = field.getValue( { item: data } );
|
|
93
|
+
|
|
94
|
+
const currentTemplate = useSelect(
|
|
95
|
+
( select ) => {
|
|
96
|
+
const foundTemplate = templates?.find(
|
|
97
|
+
( template ) => template.slug === value
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if ( foundTemplate ) {
|
|
101
|
+
return foundTemplate;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let slugToCheck;
|
|
105
|
+
// In `draft` status we might not have a slug available, so we use the `single`
|
|
106
|
+
// post type templates slug(ex page, single-post, single-product etc..).
|
|
107
|
+
// Pages do not need the `single` prefix in the slug to be prioritized
|
|
108
|
+
// through template hierarchy.
|
|
109
|
+
if ( slug ) {
|
|
110
|
+
slugToCheck =
|
|
111
|
+
postType === 'page'
|
|
112
|
+
? `${ postType }-${ slug }`
|
|
113
|
+
: `single-${ postType }-${ slug }`;
|
|
114
|
+
} else {
|
|
115
|
+
slugToCheck =
|
|
116
|
+
postType === 'page' ? 'page' : `single-${ postType }`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if ( postType ) {
|
|
120
|
+
const templateId = select( coreStore ).getDefaultTemplateId( {
|
|
121
|
+
slug: slugToCheck,
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
return select( coreStore ).getEntityRecord(
|
|
125
|
+
'postType',
|
|
126
|
+
'wp_template',
|
|
127
|
+
templateId
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
[ postType, slug, templates, value ]
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const [ showModal, setShowModal ] = useState( false );
|
|
135
|
+
|
|
136
|
+
const onChangeControl = useCallback(
|
|
137
|
+
( newValue: string ) =>
|
|
138
|
+
onChange( {
|
|
139
|
+
[ id ]: newValue,
|
|
140
|
+
} ),
|
|
141
|
+
[ id, onChange ]
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<fieldset className="fields-controls__template">
|
|
146
|
+
<Dropdown
|
|
147
|
+
popoverProps={ { placement: 'bottom-start' } }
|
|
148
|
+
renderToggle={ ( { onToggle } ) => (
|
|
149
|
+
<Button
|
|
150
|
+
__next40pxDefaultSize
|
|
151
|
+
variant="tertiary"
|
|
152
|
+
size="compact"
|
|
153
|
+
onClick={ onToggle }
|
|
154
|
+
>
|
|
155
|
+
{ currentTemplate
|
|
156
|
+
? getItemTitle( currentTemplate )
|
|
157
|
+
: '' }
|
|
158
|
+
</Button>
|
|
159
|
+
) }
|
|
160
|
+
renderContent={ ( { onToggle } ) => (
|
|
161
|
+
<MenuGroup>
|
|
162
|
+
<MenuItem
|
|
163
|
+
onClick={ () => {
|
|
164
|
+
setShowModal( true );
|
|
165
|
+
onToggle();
|
|
166
|
+
} }
|
|
167
|
+
>
|
|
168
|
+
{ __( 'Swap template' ) }
|
|
169
|
+
</MenuItem>
|
|
170
|
+
{
|
|
171
|
+
// The default template in a post is indicated by an empty string
|
|
172
|
+
value !== '' && (
|
|
173
|
+
<MenuItem
|
|
174
|
+
onClick={ () => {
|
|
175
|
+
onChangeControl( '' );
|
|
176
|
+
onToggle();
|
|
177
|
+
} }
|
|
178
|
+
>
|
|
179
|
+
{ __( 'Use default template' ) }
|
|
180
|
+
</MenuItem>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
</MenuGroup>
|
|
184
|
+
) }
|
|
185
|
+
/>
|
|
186
|
+
{ showModal && (
|
|
187
|
+
<Modal
|
|
188
|
+
title={ __( 'Choose a template' ) }
|
|
189
|
+
onRequestClose={ () => setShowModal( false ) }
|
|
190
|
+
overlayClassName="fields-controls__template-modal"
|
|
191
|
+
isFullScreen
|
|
192
|
+
>
|
|
193
|
+
<div className="fields-controls__template-content">
|
|
194
|
+
<BlockPatternsList
|
|
195
|
+
label={ __( 'Templates' ) }
|
|
196
|
+
blockPatterns={ templatesAsPatterns }
|
|
197
|
+
shownPatterns={ shownTemplates }
|
|
198
|
+
onClickPattern={ (
|
|
199
|
+
template: ( typeof templatesAsPatterns )[ 0 ]
|
|
200
|
+
) => {
|
|
201
|
+
onChangeControl( template.name );
|
|
202
|
+
setShowModal( false );
|
|
203
|
+
} }
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
</Modal>
|
|
207
|
+
) }
|
|
208
|
+
</fieldset>
|
|
209
|
+
);
|
|
210
|
+
};
|
|
@@ -17,11 +17,10 @@ import { getItemTitle } from '../../actions/utils';
|
|
|
17
17
|
const TitleView = ( { item }: { item: BasePost } ) => {
|
|
18
18
|
const { frontPageId, postsPageId } = useSelect( ( select ) => {
|
|
19
19
|
const { getEntityRecord } = select( coreStore );
|
|
20
|
-
const siteSettings
|
|
20
|
+
const siteSettings = getEntityRecord(
|
|
21
21
|
'root',
|
|
22
|
-
'site'
|
|
23
|
-
|
|
24
|
-
);
|
|
22
|
+
'site'
|
|
23
|
+
) as Partial< Settings >;
|
|
25
24
|
return {
|
|
26
25
|
frontPageId: siteSettings?.page_on_front,
|
|
27
26
|
postsPageId: siteSettings?.page_for_posts,
|
package/src/index.ts
CHANGED
package/src/style.scss
CHANGED
package/src/types.ts
CHANGED
package/tsconfig.json
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
{ "path": "../components" },
|
|
13
13
|
{ "path": "../compose" },
|
|
14
14
|
{ "path": "../core-data" },
|
|
15
|
+
{ "path": "../block-editor" },
|
|
15
16
|
{ "path": "../data" },
|
|
16
17
|
{ "path": "../dataviews" },
|
|
17
18
|
{ "path": "../date" },
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
{ "path": "../private-apis" },
|
|
27
28
|
{ "path": "../router" },
|
|
28
29
|
{ "path": "../url" },
|
|
30
|
+
{ "path": "../block-editor" },
|
|
29
31
|
{ "path": "../warning" }
|
|
30
32
|
],
|
|
31
33
|
"include": [ "src" ]
|