@wordpress/patterns 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/build/components/category-selector.js +16 -31
- package/build/components/category-selector.js.map +1 -1
- package/build/components/create-pattern-modal.js +59 -14
- package/build/components/create-pattern-modal.js.map +1 -1
- package/build/components/duplicate-pattern-modal.js +81 -0
- package/build/components/duplicate-pattern-modal.js.map +1 -0
- package/build/components/rename-pattern-category-modal.js +106 -0
- package/build/components/rename-pattern-category-modal.js.map +1 -0
- package/build/components/rename-pattern-modal.js +97 -0
- package/build/components/rename-pattern-modal.js.map +1 -0
- package/build/lock-unlock.js +1 -1
- package/build/lock-unlock.js.map +1 -1
- package/build/private-apis.js +6 -0
- package/build/private-apis.js.map +1 -1
- package/build-module/components/category-selector.js +17 -32
- package/build-module/components/category-selector.js.map +1 -1
- package/build-module/components/create-pattern-modal.js +61 -16
- package/build-module/components/create-pattern-modal.js.map +1 -1
- package/build-module/components/duplicate-pattern-modal.js +73 -0
- package/build-module/components/duplicate-pattern-modal.js.map +1 -0
- package/build-module/components/rename-pattern-category-modal.js +99 -0
- package/build-module/components/rename-pattern-category-modal.js.map +1 -0
- package/build-module/components/rename-pattern-modal.js +90 -0
- package/build-module/components/rename-pattern-modal.js.map +1 -0
- package/build-module/lock-unlock.js +1 -1
- package/build-module/lock-unlock.js.map +1 -1
- package/build-module/private-apis.js +6 -0
- package/build-module/private-apis.js.map +1 -1
- package/build-style/style-rtl.css +22 -2
- package/build-style/style.css +22 -2
- package/package.json +16 -17
- package/src/components/category-selector.js +28 -42
- package/src/components/create-pattern-modal.js +63 -14
- package/src/components/duplicate-pattern-modal.js +93 -0
- package/src/components/rename-pattern-category-modal.js +121 -0
- package/src/components/rename-pattern-modal.js +115 -0
- package/src/components/style.scss +28 -2
- package/src/lock-unlock.js +1 -1
- package/src/private-apis.js +6 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createElement } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* WordPress dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { Button, Modal, TextControl, __experimentalHStack as HStack, __experimentalVStack as VStack } from '@wordpress/components';
|
|
6
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
7
|
+
import { useDispatch } from '@wordpress/data';
|
|
8
|
+
import { useState } from '@wordpress/element';
|
|
9
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
10
|
+
import { __ } from '@wordpress/i18n';
|
|
11
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
12
|
+
export default function RenamePatternModal({
|
|
13
|
+
onClose,
|
|
14
|
+
onError,
|
|
15
|
+
onSuccess,
|
|
16
|
+
pattern,
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
const originalName = decodeEntities(pattern.title);
|
|
20
|
+
const [name, setName] = useState(originalName);
|
|
21
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
22
|
+
const {
|
|
23
|
+
editEntityRecord,
|
|
24
|
+
__experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits
|
|
25
|
+
} = useDispatch(coreStore);
|
|
26
|
+
const {
|
|
27
|
+
createSuccessNotice,
|
|
28
|
+
createErrorNotice
|
|
29
|
+
} = useDispatch(noticesStore);
|
|
30
|
+
const onRename = async event => {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
if (!name || name === pattern.title || isSaving) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
await editEntityRecord('postType', pattern.type, pattern.id, {
|
|
37
|
+
title: name
|
|
38
|
+
});
|
|
39
|
+
setIsSaving(true);
|
|
40
|
+
setName('');
|
|
41
|
+
onClose?.();
|
|
42
|
+
const savedRecord = await saveSpecifiedEntityEdits('postType', pattern.type, pattern.id, ['title'], {
|
|
43
|
+
throwOnError: true
|
|
44
|
+
});
|
|
45
|
+
onSuccess?.(savedRecord);
|
|
46
|
+
createSuccessNotice(__('Pattern renamed'), {
|
|
47
|
+
type: 'snackbar',
|
|
48
|
+
id: 'pattern-update'
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
onError?.();
|
|
52
|
+
const errorMessage = error.message && error.code !== 'unknown_error' ? error.message : __('An error occurred while renaming the pattern.');
|
|
53
|
+
createErrorNotice(errorMessage, {
|
|
54
|
+
type: 'snackbar',
|
|
55
|
+
id: 'pattern-update'
|
|
56
|
+
});
|
|
57
|
+
} finally {
|
|
58
|
+
setIsSaving(false);
|
|
59
|
+
setName('');
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const onRequestClose = () => {
|
|
63
|
+
onClose?.();
|
|
64
|
+
setName('');
|
|
65
|
+
};
|
|
66
|
+
return createElement(Modal, {
|
|
67
|
+
title: __('Rename'),
|
|
68
|
+
...props,
|
|
69
|
+
onRequestClose: onClose
|
|
70
|
+
}, createElement("form", {
|
|
71
|
+
onSubmit: onRename
|
|
72
|
+
}, createElement(VStack, {
|
|
73
|
+
spacing: "5"
|
|
74
|
+
}, createElement(TextControl, {
|
|
75
|
+
__nextHasNoMarginBottom: true,
|
|
76
|
+
label: __('Name'),
|
|
77
|
+
value: name,
|
|
78
|
+
onChange: setName,
|
|
79
|
+
required: true
|
|
80
|
+
}), createElement(HStack, {
|
|
81
|
+
justify: "right"
|
|
82
|
+
}, createElement(Button, {
|
|
83
|
+
variant: "tertiary",
|
|
84
|
+
onClick: onRequestClose
|
|
85
|
+
}, __('Cancel')), createElement(Button, {
|
|
86
|
+
variant: "primary",
|
|
87
|
+
type: "submit"
|
|
88
|
+
}, __('Save'))))));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=rename-pattern-modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Button","Modal","TextControl","__experimentalHStack","HStack","__experimentalVStack","VStack","store","coreStore","useDispatch","useState","decodeEntities","__","noticesStore","RenamePatternModal","onClose","onError","onSuccess","pattern","props","originalName","title","name","setName","isSaving","setIsSaving","editEntityRecord","__experimentalSaveSpecifiedEntityEdits","saveSpecifiedEntityEdits","createSuccessNotice","createErrorNotice","onRename","event","preventDefault","type","id","savedRecord","throwOnError","error","errorMessage","message","code","onRequestClose","createElement","onSubmit","spacing","__nextHasNoMarginBottom","label","value","onChange","required","justify","variant","onClick"],"sources":["@wordpress/patterns/src/components/rename-pattern-modal.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tModal,\n\tTextControl,\n\t__experimentalHStack as HStack,\n\t__experimentalVStack as VStack,\n} from '@wordpress/components';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { useDispatch } from '@wordpress/data';\nimport { useState } from '@wordpress/element';\nimport { decodeEntities } from '@wordpress/html-entities';\nimport { __ } from '@wordpress/i18n';\nimport { store as noticesStore } from '@wordpress/notices';\n\nexport default function RenamePatternModal( {\n\tonClose,\n\tonError,\n\tonSuccess,\n\tpattern,\n\t...props\n} ) {\n\tconst originalName = decodeEntities( pattern.title );\n\tconst [ name, setName ] = useState( originalName );\n\tconst [ isSaving, setIsSaving ] = useState( false );\n\n\tconst {\n\t\teditEntityRecord,\n\t\t__experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits,\n\t} = useDispatch( coreStore );\n\n\tconst { createSuccessNotice, createErrorNotice } =\n\t\tuseDispatch( noticesStore );\n\n\tconst onRename = async ( event ) => {\n\t\tevent.preventDefault();\n\n\t\tif ( ! name || name === pattern.title || isSaving ) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait editEntityRecord( 'postType', pattern.type, pattern.id, {\n\t\t\t\ttitle: name,\n\t\t\t} );\n\n\t\t\tsetIsSaving( true );\n\t\t\tsetName( '' );\n\t\t\tonClose?.();\n\n\t\t\tconst savedRecord = await saveSpecifiedEntityEdits(\n\t\t\t\t'postType',\n\t\t\t\tpattern.type,\n\t\t\t\tpattern.id,\n\t\t\t\t[ 'title' ],\n\t\t\t\t{ throwOnError: true }\n\t\t\t);\n\n\t\t\tonSuccess?.( savedRecord );\n\n\t\t\tcreateSuccessNotice( __( 'Pattern renamed' ), {\n\t\t\t\ttype: 'snackbar',\n\t\t\t\tid: 'pattern-update',\n\t\t\t} );\n\t\t} catch ( error ) {\n\t\t\tonError?.();\n\n\t\t\tconst errorMessage =\n\t\t\t\terror.message && error.code !== 'unknown_error'\n\t\t\t\t\t? error.message\n\t\t\t\t\t: __( 'An error occurred while renaming the pattern.' );\n\n\t\t\tcreateErrorNotice( errorMessage, {\n\t\t\t\ttype: 'snackbar',\n\t\t\t\tid: 'pattern-update',\n\t\t\t} );\n\t\t} finally {\n\t\t\tsetIsSaving( false );\n\t\t\tsetName( '' );\n\t\t}\n\t};\n\n\tconst onRequestClose = () => {\n\t\tonClose?.();\n\t\tsetName( '' );\n\t};\n\n\treturn (\n\t\t<Modal title={ __( 'Rename' ) } { ...props } onRequestClose={ onClose }>\n\t\t\t<form onSubmit={ onRename }>\n\t\t\t\t<VStack spacing=\"5\">\n\t\t\t\t\t<TextControl\n\t\t\t\t\t\t__nextHasNoMarginBottom\n\t\t\t\t\t\tlabel={ __( 'Name' ) }\n\t\t\t\t\t\tvalue={ name }\n\t\t\t\t\t\tonChange={ setName }\n\t\t\t\t\t\trequired\n\t\t\t\t\t/>\n\n\t\t\t\t\t<HStack justify=\"right\">\n\t\t\t\t\t\t<Button variant=\"tertiary\" onClick={ onRequestClose }>\n\t\t\t\t\t\t\t{ __( 'Cancel' ) }\n\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t<Button variant=\"primary\" type=\"submit\">\n\t\t\t\t\t\t\t{ __( 'Save' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t</VStack>\n\t\t\t</form>\n\t\t</Modal>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -5,5 +5,5 @@ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/pri
|
|
|
5
5
|
export const {
|
|
6
6
|
lock,
|
|
7
7
|
unlock
|
|
8
|
-
} = __dangerousOptInToUnstableAPIsOnlyForCoreModules('I know using unstable features means my
|
|
8
|
+
} = __dangerousOptInToUnstableAPIsOnlyForCoreModules('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/patterns');
|
|
9
9
|
//# sourceMappingURL=lock-unlock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["__dangerousOptInToUnstableAPIsOnlyForCoreModules","lock","unlock"],"sources":["@wordpress/patterns/src/lock-unlock.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';\nexport const { lock, unlock } =\n\t__dangerousOptInToUnstableAPIsOnlyForCoreModules(\n\t\t'I know using unstable features means my
|
|
1
|
+
{"version":3,"names":["__dangerousOptInToUnstableAPIsOnlyForCoreModules","lock","unlock"],"sources":["@wordpress/patterns/src/lock-unlock.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';\nexport const { lock, unlock } =\n\t__dangerousOptInToUnstableAPIsOnlyForCoreModules(\n\t\t'I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.',\n\t\t'@wordpress/patterns'\n\t);\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,gDAAgD,QAAQ,yBAAyB;AAC1F,OAAO,MAAM;EAAEC,IAAI;EAAEC;AAAO,CAAC,GAC5BF,gDAAgD,CAC/C,iHAAiH,EACjH,qBACD,CAAC"}
|
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { lock } from './lock-unlock';
|
|
5
5
|
import CreatePatternModal from './components/create-pattern-modal';
|
|
6
|
+
import DuplicatePatternModal from './components/duplicate-pattern-modal';
|
|
7
|
+
import RenamePatternModal from './components/rename-pattern-modal';
|
|
6
8
|
import PatternsMenuItems from './components';
|
|
9
|
+
import RenamePatternCategoryModal from './components/rename-pattern-category-modal';
|
|
7
10
|
import { PATTERN_TYPES, PATTERN_DEFAULT_CATEGORY, PATTERN_USER_CATEGORY, PATTERN_CORE_SOURCES, PATTERN_SYNC_TYPES } from './constants';
|
|
8
11
|
export const privateApis = {};
|
|
9
12
|
lock(privateApis, {
|
|
10
13
|
CreatePatternModal,
|
|
14
|
+
DuplicatePatternModal,
|
|
15
|
+
RenamePatternModal,
|
|
11
16
|
PatternsMenuItems,
|
|
17
|
+
RenamePatternCategoryModal,
|
|
12
18
|
PATTERN_TYPES,
|
|
13
19
|
PATTERN_DEFAULT_CATEGORY,
|
|
14
20
|
PATTERN_USER_CATEGORY,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["lock","CreatePatternModal","PatternsMenuItems","PATTERN_TYPES","PATTERN_DEFAULT_CATEGORY","PATTERN_USER_CATEGORY","PATTERN_CORE_SOURCES","PATTERN_SYNC_TYPES","privateApis"],"sources":["@wordpress/patterns/src/private-apis.js"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport { lock } from './lock-unlock';\nimport CreatePatternModal from './components/create-pattern-modal';\nimport PatternsMenuItems from './components';\nimport {\n\tPATTERN_TYPES,\n\tPATTERN_DEFAULT_CATEGORY,\n\tPATTERN_USER_CATEGORY,\n\tPATTERN_CORE_SOURCES,\n\tPATTERN_SYNC_TYPES,\n} from './constants';\n\nexport const privateApis = {};\nlock( privateApis, {\n\tCreatePatternModal,\n\tPatternsMenuItems,\n\tPATTERN_TYPES,\n\tPATTERN_DEFAULT_CATEGORY,\n\tPATTERN_USER_CATEGORY,\n\tPATTERN_CORE_SOURCES,\n\tPATTERN_SYNC_TYPES,\n} );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,IAAI,QAAQ,eAAe;AACpC,OAAOC,kBAAkB,MAAM,mCAAmC;AAClE,OAAOC,iBAAiB,MAAM,cAAc;AAC5C,SACCC,aAAa,EACbC,wBAAwB,EACxBC,qBAAqB,EACrBC,oBAAoB,EACpBC,kBAAkB,QACZ,aAAa;AAEpB,OAAO,MAAMC,WAAW,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["lock","CreatePatternModal","DuplicatePatternModal","RenamePatternModal","PatternsMenuItems","RenamePatternCategoryModal","PATTERN_TYPES","PATTERN_DEFAULT_CATEGORY","PATTERN_USER_CATEGORY","PATTERN_CORE_SOURCES","PATTERN_SYNC_TYPES","privateApis"],"sources":["@wordpress/patterns/src/private-apis.js"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport { lock } from './lock-unlock';\nimport CreatePatternModal from './components/create-pattern-modal';\nimport DuplicatePatternModal from './components/duplicate-pattern-modal';\nimport RenamePatternModal from './components/rename-pattern-modal';\nimport PatternsMenuItems from './components';\nimport RenamePatternCategoryModal from './components/rename-pattern-category-modal';\nimport {\n\tPATTERN_TYPES,\n\tPATTERN_DEFAULT_CATEGORY,\n\tPATTERN_USER_CATEGORY,\n\tPATTERN_CORE_SOURCES,\n\tPATTERN_SYNC_TYPES,\n} from './constants';\n\nexport const privateApis = {};\nlock( privateApis, {\n\tCreatePatternModal,\n\tDuplicatePatternModal,\n\tRenamePatternModal,\n\tPatternsMenuItems,\n\tRenamePatternCategoryModal,\n\tPATTERN_TYPES,\n\tPATTERN_DEFAULT_CATEGORY,\n\tPATTERN_USER_CATEGORY,\n\tPATTERN_CORE_SOURCES,\n\tPATTERN_SYNC_TYPES,\n} );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,IAAI,QAAQ,eAAe;AACpC,OAAOC,kBAAkB,MAAM,mCAAmC;AAClE,OAAOC,qBAAqB,MAAM,sCAAsC;AACxE,OAAOC,kBAAkB,MAAM,mCAAmC;AAClE,OAAOC,iBAAiB,MAAM,cAAc;AAC5C,OAAOC,0BAA0B,MAAM,4CAA4C;AACnF,SACCC,aAAa,EACbC,wBAAwB,EACxBC,qBAAqB,EACrBC,oBAAoB,EACpBC,kBAAkB,QACZ,aAAa;AAEpB,OAAO,MAAMC,WAAW,GAAG,CAAC,CAAC;AAC7BX,IAAI,CAAEW,WAAW,EAAE;EAClBV,kBAAkB;EAClBC,qBAAqB;EACrBC,kBAAkB;EAClBC,iBAAiB;EACjBC,0BAA0B;EAC1BC,aAAa;EACbC,wBAAwB;EACxBC,qBAAqB;EACrBC,oBAAoB;EACpBC;AACD,CAAE,CAAC"}
|
|
@@ -106,10 +106,30 @@
|
|
|
106
106
|
.patterns-menu-items__convert-modal {
|
|
107
107
|
z-index: 1000001;
|
|
108
108
|
}
|
|
109
|
+
.patterns-menu-items__convert-modal [role=dialog] > [role=document] {
|
|
110
|
+
width: 350px;
|
|
111
|
+
}
|
|
109
112
|
.patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories {
|
|
110
|
-
|
|
113
|
+
width: 100%;
|
|
114
|
+
position: relative;
|
|
115
|
+
min-height: 40px;
|
|
116
|
+
}
|
|
117
|
+
.patterns-menu-items__convert-modal .components-form-token-field__suggestions-list {
|
|
118
|
+
position: absolute;
|
|
119
|
+
box-sizing: border-box;
|
|
120
|
+
z-index: 1;
|
|
121
|
+
background-color: #fff;
|
|
122
|
+
width: calc(100% + 2px);
|
|
123
|
+
right: -1px;
|
|
124
|
+
min-width: initial;
|
|
125
|
+
border: 1px solid var(--wp-admin-theme-color);
|
|
126
|
+
border-top: none;
|
|
127
|
+
box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color);
|
|
128
|
+
border-bottom-right-radius: 2px;
|
|
129
|
+
border-bottom-left-radius: 2px;
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
.patterns-create-modal__name-input input[type=text] {
|
|
114
|
-
min-height:
|
|
133
|
+
min-height: 40px;
|
|
134
|
+
margin: 0;
|
|
115
135
|
}
|
package/build-style/style.css
CHANGED
|
@@ -106,10 +106,30 @@
|
|
|
106
106
|
.patterns-menu-items__convert-modal {
|
|
107
107
|
z-index: 1000001;
|
|
108
108
|
}
|
|
109
|
+
.patterns-menu-items__convert-modal [role=dialog] > [role=document] {
|
|
110
|
+
width: 350px;
|
|
111
|
+
}
|
|
109
112
|
.patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories {
|
|
110
|
-
|
|
113
|
+
width: 100%;
|
|
114
|
+
position: relative;
|
|
115
|
+
min-height: 40px;
|
|
116
|
+
}
|
|
117
|
+
.patterns-menu-items__convert-modal .components-form-token-field__suggestions-list {
|
|
118
|
+
position: absolute;
|
|
119
|
+
box-sizing: border-box;
|
|
120
|
+
z-index: 1;
|
|
121
|
+
background-color: #fff;
|
|
122
|
+
width: calc(100% + 2px);
|
|
123
|
+
left: -1px;
|
|
124
|
+
min-width: initial;
|
|
125
|
+
border: 1px solid var(--wp-admin-theme-color);
|
|
126
|
+
border-top: none;
|
|
127
|
+
box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color);
|
|
128
|
+
border-bottom-left-radius: 2px;
|
|
129
|
+
border-bottom-right-radius: 2px;
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
.patterns-create-modal__name-input input[type=text] {
|
|
114
|
-
min-height:
|
|
133
|
+
min-height: 40px;
|
|
134
|
+
margin: 0;
|
|
115
135
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/patterns",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Management of user pattern editing.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"url": "https://github.com/WordPress/gutenberg/issues"
|
|
20
20
|
},
|
|
21
21
|
"engines": {
|
|
22
|
-
"node": ">=16.0.0"
|
|
23
|
-
"npm": ">=8 <9"
|
|
22
|
+
"node": ">=16.0.0"
|
|
24
23
|
},
|
|
25
24
|
"main": "build/index.js",
|
|
26
25
|
"module": "build-module/index.js",
|
|
@@ -32,19 +31,19 @@
|
|
|
32
31
|
],
|
|
33
32
|
"dependencies": {
|
|
34
33
|
"@babel/runtime": "^7.16.0",
|
|
35
|
-
"@wordpress/block-editor": "^12.
|
|
36
|
-
"@wordpress/blocks": "^12.
|
|
37
|
-
"@wordpress/components": "^25.
|
|
38
|
-
"@wordpress/compose": "^6.
|
|
39
|
-
"@wordpress/core-data": "^6.
|
|
40
|
-
"@wordpress/data": "^9.
|
|
41
|
-
"@wordpress/element": "^5.
|
|
42
|
-
"@wordpress/html-entities": "^3.
|
|
43
|
-
"@wordpress/i18n": "^4.
|
|
44
|
-
"@wordpress/icons": "^9.
|
|
45
|
-
"@wordpress/notices": "^4.
|
|
46
|
-
"@wordpress/private-apis": "^0.
|
|
47
|
-
"@wordpress/url": "^3.
|
|
34
|
+
"@wordpress/block-editor": "^12.12.0",
|
|
35
|
+
"@wordpress/blocks": "^12.21.0",
|
|
36
|
+
"@wordpress/components": "^25.10.0",
|
|
37
|
+
"@wordpress/compose": "^6.21.0",
|
|
38
|
+
"@wordpress/core-data": "^6.21.0",
|
|
39
|
+
"@wordpress/data": "^9.14.0",
|
|
40
|
+
"@wordpress/element": "^5.21.0",
|
|
41
|
+
"@wordpress/html-entities": "^3.44.0",
|
|
42
|
+
"@wordpress/i18n": "^4.44.0",
|
|
43
|
+
"@wordpress/icons": "^9.35.0",
|
|
44
|
+
"@wordpress/notices": "^4.12.0",
|
|
45
|
+
"@wordpress/private-apis": "^0.26.0",
|
|
46
|
+
"@wordpress/url": "^3.45.0"
|
|
48
47
|
},
|
|
49
48
|
"peerDependencies": {
|
|
50
49
|
"react": "^18.0.0",
|
|
@@ -53,5 +52,5 @@
|
|
|
53
52
|
"publishConfig": {
|
|
54
53
|
"access": "public"
|
|
55
54
|
},
|
|
56
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "f83bb1a71e8fa416131b81a9f282a72a1dc6c694"
|
|
57
56
|
}
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
import { useMemo, useState } from '@wordpress/element';
|
|
6
6
|
import { FormTokenField } from '@wordpress/components';
|
|
7
|
-
import { useSelect } from '@wordpress/data';
|
|
8
|
-
import { store as coreStore } from '@wordpress/core-data';
|
|
9
7
|
import { useDebounce } from '@wordpress/compose';
|
|
10
8
|
import { decodeEntities } from '@wordpress/html-entities';
|
|
11
9
|
|
|
@@ -13,40 +11,29 @@ const unescapeString = ( arg ) => {
|
|
|
13
11
|
return decodeEntities( arg );
|
|
14
12
|
};
|
|
15
13
|
|
|
16
|
-
const EMPTY_ARRAY = [];
|
|
17
|
-
const MAX_TERMS_SUGGESTIONS = 20;
|
|
18
|
-
const DEFAULT_QUERY = {
|
|
19
|
-
per_page: MAX_TERMS_SUGGESTIONS,
|
|
20
|
-
_fields: 'id,name',
|
|
21
|
-
context: 'view',
|
|
22
|
-
};
|
|
23
14
|
export const CATEGORY_SLUG = 'wp_pattern_category';
|
|
24
15
|
|
|
25
|
-
export default function CategorySelector( {
|
|
16
|
+
export default function CategorySelector( {
|
|
17
|
+
categoryTerms,
|
|
18
|
+
onChange,
|
|
19
|
+
categoryMap,
|
|
20
|
+
} ) {
|
|
26
21
|
const [ search, setSearch ] = useState( '' );
|
|
27
22
|
const debouncedSearch = useDebounce( setSearch, 500 );
|
|
28
23
|
|
|
29
|
-
const { searchResults } = useSelect(
|
|
30
|
-
( select ) => {
|
|
31
|
-
const { getEntityRecords } = select( coreStore );
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
searchResults: !! search
|
|
35
|
-
? getEntityRecords( 'taxonomy', CATEGORY_SLUG, {
|
|
36
|
-
...DEFAULT_QUERY,
|
|
37
|
-
search,
|
|
38
|
-
} )
|
|
39
|
-
: EMPTY_ARRAY,
|
|
40
|
-
};
|
|
41
|
-
},
|
|
42
|
-
[ search ]
|
|
43
|
-
);
|
|
44
|
-
|
|
45
24
|
const suggestions = useMemo( () => {
|
|
46
|
-
return (
|
|
47
|
-
unescapeString(
|
|
48
|
-
|
|
49
|
-
|
|
25
|
+
return Array.from( categoryMap.values() )
|
|
26
|
+
.map( ( category ) => unescapeString( category.label ) )
|
|
27
|
+
.filter( ( category ) => {
|
|
28
|
+
if ( search !== '' ) {
|
|
29
|
+
return category
|
|
30
|
+
.toLowerCase()
|
|
31
|
+
.includes( search.toLowerCase() );
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
} )
|
|
35
|
+
.sort( ( a, b ) => a.localeCompare( b ) );
|
|
36
|
+
}, [ search, categoryMap ] );
|
|
50
37
|
|
|
51
38
|
function handleChange( termNames ) {
|
|
52
39
|
const uniqueTerms = termNames.reduce( ( terms, newTerm ) => {
|
|
@@ -64,17 +51,16 @@ export default function CategorySelector( { values, onChange } ) {
|
|
|
64
51
|
}
|
|
65
52
|
|
|
66
53
|
return (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
</>
|
|
54
|
+
<FormTokenField
|
|
55
|
+
className="patterns-menu-items__convert-modal-categories"
|
|
56
|
+
value={ categoryTerms }
|
|
57
|
+
suggestions={ suggestions }
|
|
58
|
+
onChange={ handleChange }
|
|
59
|
+
onInputChange={ debouncedSearch }
|
|
60
|
+
label={ __( 'Categories' ) }
|
|
61
|
+
tokenizeOnBlur
|
|
62
|
+
__experimentalExpandOnFocus
|
|
63
|
+
__next40pxDefaultSize
|
|
64
|
+
/>
|
|
79
65
|
);
|
|
80
66
|
}
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
ToggleControl,
|
|
11
11
|
} from '@wordpress/components';
|
|
12
12
|
import { __ } from '@wordpress/i18n';
|
|
13
|
-
import { useState } from '@wordpress/element';
|
|
14
|
-
import { useDispatch } from '@wordpress/data';
|
|
13
|
+
import { useState, useMemo } from '@wordpress/element';
|
|
14
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
15
15
|
import { store as noticesStore } from '@wordpress/notices';
|
|
16
16
|
import { store as coreStore } from '@wordpress/core-data';
|
|
17
17
|
|
|
@@ -28,20 +28,62 @@ import CategorySelector, { CATEGORY_SLUG } from './category-selector';
|
|
|
28
28
|
import { unlock } from '../lock-unlock';
|
|
29
29
|
|
|
30
30
|
export default function CreatePatternModal( {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
confirmLabel = __( 'Create' ),
|
|
32
|
+
defaultCategories = [],
|
|
33
|
+
className = 'patterns-menu-items__convert-modal',
|
|
33
34
|
content,
|
|
35
|
+
modalTitle = __( 'Create pattern' ),
|
|
34
36
|
onClose,
|
|
35
|
-
|
|
37
|
+
onError,
|
|
38
|
+
onSuccess,
|
|
39
|
+
defaultSyncType = PATTERN_SYNC_TYPES.full,
|
|
40
|
+
defaultTitle = '',
|
|
36
41
|
} ) {
|
|
37
|
-
const [ syncType, setSyncType ] = useState(
|
|
38
|
-
const [ categoryTerms, setCategoryTerms ] = useState(
|
|
39
|
-
const [ title, setTitle ] = useState(
|
|
42
|
+
const [ syncType, setSyncType ] = useState( defaultSyncType );
|
|
43
|
+
const [ categoryTerms, setCategoryTerms ] = useState( defaultCategories );
|
|
44
|
+
const [ title, setTitle ] = useState( defaultTitle );
|
|
45
|
+
|
|
40
46
|
const [ isSaving, setIsSaving ] = useState( false );
|
|
41
47
|
const { createPattern } = unlock( useDispatch( patternsStore ) );
|
|
42
48
|
const { saveEntityRecord, invalidateResolution } = useDispatch( coreStore );
|
|
43
49
|
const { createErrorNotice } = useDispatch( noticesStore );
|
|
44
50
|
|
|
51
|
+
const { corePatternCategories, userPatternCategories } = useSelect(
|
|
52
|
+
( select ) => {
|
|
53
|
+
const { getUserPatternCategories, getBlockPatternCategories } =
|
|
54
|
+
select( coreStore );
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
corePatternCategories: getBlockPatternCategories(),
|
|
58
|
+
userPatternCategories: getUserPatternCategories(),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const categoryMap = useMemo( () => {
|
|
64
|
+
// Merge the user and core pattern categories and remove any duplicates.
|
|
65
|
+
const uniqueCategories = new Map();
|
|
66
|
+
[ ...userPatternCategories, ...corePatternCategories ].forEach(
|
|
67
|
+
( category ) => {
|
|
68
|
+
if (
|
|
69
|
+
! uniqueCategories.has( category.label ) &&
|
|
70
|
+
// There are two core categories with `Post` label so explicitly remove the one with
|
|
71
|
+
// the `query` slug to avoid any confusion.
|
|
72
|
+
category.name !== 'query'
|
|
73
|
+
) {
|
|
74
|
+
// We need to store the name separately as this is used as the slug in the
|
|
75
|
+
// taxonomy and may vary from the label.
|
|
76
|
+
uniqueCategories.set( category.label, {
|
|
77
|
+
label: category.label,
|
|
78
|
+
value: category.label,
|
|
79
|
+
name: category.name,
|
|
80
|
+
} );
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
return uniqueCategories;
|
|
85
|
+
}, [ userPatternCategories, corePatternCategories ] );
|
|
86
|
+
|
|
45
87
|
async function onCreate( patternTitle, sync ) {
|
|
46
88
|
if ( ! title || isSaving ) {
|
|
47
89
|
return;
|
|
@@ -68,9 +110,9 @@ export default function CreatePatternModal( {
|
|
|
68
110
|
} catch ( error ) {
|
|
69
111
|
createErrorNotice( error.message, {
|
|
70
112
|
type: 'snackbar',
|
|
71
|
-
id: '
|
|
113
|
+
id: 'pattern-create',
|
|
72
114
|
} );
|
|
73
|
-
onError();
|
|
115
|
+
onError?.();
|
|
74
116
|
} finally {
|
|
75
117
|
setIsSaving( false );
|
|
76
118
|
setCategoryTerms( [] );
|
|
@@ -84,10 +126,16 @@ export default function CreatePatternModal( {
|
|
|
84
126
|
*/
|
|
85
127
|
async function findOrCreateTerm( term ) {
|
|
86
128
|
try {
|
|
129
|
+
// We need to match any existing term to the correct slug to prevent duplicates, eg.
|
|
130
|
+
// the core `Headers` category uses the singular `header` as the slug.
|
|
131
|
+
const existingTerm = categoryMap.get( term );
|
|
132
|
+
const termData = existingTerm
|
|
133
|
+
? { name: existingTerm.label, slug: existingTerm.name }
|
|
134
|
+
: { name: term };
|
|
87
135
|
const newTerm = await saveEntityRecord(
|
|
88
136
|
'taxonomy',
|
|
89
137
|
CATEGORY_SLUG,
|
|
90
|
-
|
|
138
|
+
termData,
|
|
91
139
|
{ throwOnError: true }
|
|
92
140
|
);
|
|
93
141
|
invalidateResolution( 'getUserPatternCategories' );
|
|
@@ -103,7 +151,7 @@ export default function CreatePatternModal( {
|
|
|
103
151
|
|
|
104
152
|
return (
|
|
105
153
|
<Modal
|
|
106
|
-
title={
|
|
154
|
+
title={ modalTitle }
|
|
107
155
|
onRequestClose={ () => {
|
|
108
156
|
onClose();
|
|
109
157
|
setTitle( '' );
|
|
@@ -126,8 +174,9 @@ export default function CreatePatternModal( {
|
|
|
126
174
|
className="patterns-create-modal__name-input"
|
|
127
175
|
/>
|
|
128
176
|
<CategorySelector
|
|
129
|
-
|
|
177
|
+
categoryTerms={ categoryTerms }
|
|
130
178
|
onChange={ setCategoryTerms }
|
|
179
|
+
categoryMap={ categoryMap }
|
|
131
180
|
/>
|
|
132
181
|
<ToggleControl
|
|
133
182
|
label={ __( 'Synced' ) }
|
|
@@ -160,7 +209,7 @@ export default function CreatePatternModal( {
|
|
|
160
209
|
aria-disabled={ ! title || isSaving }
|
|
161
210
|
isBusy={ isSaving }
|
|
162
211
|
>
|
|
163
|
-
{
|
|
212
|
+
{ confirmLabel }
|
|
164
213
|
</Button>
|
|
165
214
|
</HStack>
|
|
166
215
|
</VStack>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
5
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
6
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
7
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies
|
|
11
|
+
*/
|
|
12
|
+
import CreatePatternModal from './create-pattern-modal';
|
|
13
|
+
import { PATTERN_SYNC_TYPES } from '../constants';
|
|
14
|
+
|
|
15
|
+
function getTermLabels( pattern, categories ) {
|
|
16
|
+
// Theme patterns don't have an id and rely on core pattern categories.
|
|
17
|
+
if ( ! pattern.id ) {
|
|
18
|
+
return categories.core
|
|
19
|
+
?.filter( ( category ) =>
|
|
20
|
+
pattern.categories.includes( category.name )
|
|
21
|
+
)
|
|
22
|
+
.map( ( category ) => category.label );
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return categories.user
|
|
26
|
+
?.filter( ( category ) =>
|
|
27
|
+
pattern.wp_pattern_category.includes( category.id )
|
|
28
|
+
)
|
|
29
|
+
.map( ( category ) => category.label );
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default function DuplicatePatternModal( {
|
|
33
|
+
pattern,
|
|
34
|
+
onClose,
|
|
35
|
+
onSuccess,
|
|
36
|
+
} ) {
|
|
37
|
+
const { createSuccessNotice } = useDispatch( noticesStore );
|
|
38
|
+
const categories = useSelect( ( select ) => {
|
|
39
|
+
const { getUserPatternCategories, getBlockPatternCategories } =
|
|
40
|
+
select( coreStore );
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
core: getBlockPatternCategories(),
|
|
44
|
+
user: getUserPatternCategories(),
|
|
45
|
+
};
|
|
46
|
+
} );
|
|
47
|
+
|
|
48
|
+
if ( ! pattern ) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const duplicatedProps = {
|
|
53
|
+
content: pattern.content,
|
|
54
|
+
defaultCategories: getTermLabels( pattern, categories ),
|
|
55
|
+
defaultSyncType: ! pattern.id // Theme patterns don't have an ID.
|
|
56
|
+
? PATTERN_SYNC_TYPES.unsynced
|
|
57
|
+
: pattern.wp_pattern_sync_status || PATTERN_SYNC_TYPES.full,
|
|
58
|
+
defaultTitle: sprintf(
|
|
59
|
+
/* translators: %s: Existing pattern title */
|
|
60
|
+
__( '%s (Copy)' ),
|
|
61
|
+
typeof pattern.title === 'string'
|
|
62
|
+
? pattern.title
|
|
63
|
+
: pattern.title.raw
|
|
64
|
+
),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function handleOnSuccess( { pattern: newPattern } ) {
|
|
68
|
+
createSuccessNotice(
|
|
69
|
+
sprintf(
|
|
70
|
+
// translators: %s: The new pattern's title e.g. 'Call to action (copy)'.
|
|
71
|
+
__( '"%s" duplicated.' ),
|
|
72
|
+
newPattern.title.raw
|
|
73
|
+
),
|
|
74
|
+
{
|
|
75
|
+
type: 'snackbar',
|
|
76
|
+
id: 'patterns-create',
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
onSuccess?.( { pattern: newPattern } );
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<CreatePatternModal
|
|
85
|
+
modalTitle={ __( 'Duplicate pattern' ) }
|
|
86
|
+
confirmLabel={ __( 'Duplicate' ) }
|
|
87
|
+
onClose={ onClose }
|
|
88
|
+
onError={ onClose }
|
|
89
|
+
onSuccess={ handleOnSuccess }
|
|
90
|
+
{ ...duplicatedProps }
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|