@wordpress/patterns 1.2.1-next.5a1d1283.0 → 1.3.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/category-selector.js +105 -0
  3. package/build/components/category-selector.js.map +1 -0
  4. package/build/components/create-pattern-modal.js +26 -19
  5. package/build/components/create-pattern-modal.js.map +1 -1
  6. package/build/components/pattern-convert-button.js +20 -1
  7. package/build/components/pattern-convert-button.js.map +1 -1
  8. package/build/components/patterns-manage-button.js +7 -3
  9. package/build/components/patterns-manage-button.js.map +1 -1
  10. package/build/constants.js +21 -0
  11. package/build/constants.js.map +1 -0
  12. package/build/index.js +11 -1
  13. package/build/index.js.map +1 -1
  14. package/build/private-apis.js +6 -1
  15. package/build/private-apis.js.map +1 -1
  16. package/build/store/actions.js +45 -23
  17. package/build/store/actions.js.map +1 -1
  18. package/build/store/index.js +4 -3
  19. package/build/store/index.js.map +1 -1
  20. package/build/store/selectors.js +2 -2
  21. package/build/store/selectors.js.map +1 -1
  22. package/build-module/components/category-selector.js +99 -0
  23. package/build-module/components/category-selector.js.map +1 -0
  24. package/build-module/components/create-pattern-modal.js +27 -18
  25. package/build-module/components/create-pattern-modal.js.map +1 -1
  26. package/build-module/components/pattern-convert-button.js +22 -3
  27. package/build-module/components/pattern-convert-button.js.map +1 -1
  28. package/build-module/components/patterns-manage-button.js +8 -4
  29. package/build-module/components/patterns-manage-button.js.map +1 -1
  30. package/build-module/constants.js +11 -0
  31. package/build-module/constants.js.map +1 -0
  32. package/build-module/index.js +1 -1
  33. package/build-module/index.js.map +1 -1
  34. package/build-module/private-apis.js +6 -1
  35. package/build-module/private-apis.js.map +1 -1
  36. package/build-module/store/actions.js +41 -20
  37. package/build-module/store/actions.js.map +1 -1
  38. package/build-module/store/index.js +4 -3
  39. package/build-module/store/index.js.map +1 -1
  40. package/build-module/store/selectors.js +1 -1
  41. package/build-module/store/selectors.js.map +1 -1
  42. package/build-style/style-rtl.css +7 -0
  43. package/build-style/style.css +7 -0
  44. package/package.json +16 -14
  45. package/src/components/category-selector.js +118 -0
  46. package/src/components/create-pattern-modal.js +45 -38
  47. package/src/components/pattern-convert-button.js +26 -3
  48. package/src/components/patterns-manage-button.js +10 -4
  49. package/src/components/style.scss +7 -0
  50. package/src/constants.js +16 -0
  51. package/src/index.js +1 -2
  52. package/src/private-apis.js +10 -0
  53. package/src/store/actions.js +55 -27
  54. package/src/store/index.js +3 -2
  55. package/src/store/selectors.js +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":["MenuItem","__","isReusableBlock","useSelect","useDispatch","store","blockEditorStore","addQueryArgs","coreStore","editorStore","PatternsManageButton","clientId","canRemove","isVisible","innerBlockCount","managePatternsUrl","select","getBlock","canRemoveBlock","getBlockCount","getSettings","canUser","reusableBlock","isBlockTheme","__unstableIsBlockBasedTheme","attributes","ref","path","post_type","__experimentalConvertSyncedPatternToStatic","convertBlockToStatic","createElement","Fragment","href","onClick"],"sources":["@wordpress/patterns/src/components/patterns-manage-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { MenuItem } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { isReusableBlock } from '@wordpress/blocks';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport { store as coreStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { store as editorStore } from '../store';\n\nfunction PatternsManageButton( { clientId } ) {\n\tconst { canRemove, isVisible, innerBlockCount, managePatternsUrl } =\n\t\tuseSelect(\n\t\t\t( select ) => {\n\t\t\t\tconst { getBlock, canRemoveBlock, getBlockCount, getSettings } =\n\t\t\t\t\tselect( blockEditorStore );\n\t\t\t\tconst { canUser } = select( coreStore );\n\t\t\t\tconst reusableBlock = getBlock( clientId );\n\t\t\t\tconst isBlockTheme = getSettings().__unstableIsBlockBasedTheme;\n\n\t\t\t\treturn {\n\t\t\t\t\tcanRemove: canRemoveBlock( clientId ),\n\t\t\t\t\tisVisible:\n\t\t\t\t\t\t!! reusableBlock &&\n\t\t\t\t\t\tisReusableBlock( reusableBlock ) &&\n\t\t\t\t\t\t!! canUser(\n\t\t\t\t\t\t\t'update',\n\t\t\t\t\t\t\t'blocks',\n\t\t\t\t\t\t\treusableBlock.attributes.ref\n\t\t\t\t\t\t),\n\t\t\t\t\tinnerBlockCount: getBlockCount( clientId ),\n\t\t\t\t\t// The site editor and templates both check whether the user\n\t\t\t\t\t// has edit_theme_options capabilities. We can leverage that here\n\t\t\t\t\t// and omit the manage patterns link if the user can't access it.\n\t\t\t\t\tmanagePatternsUrl:\n\t\t\t\t\t\tisBlockTheme && canUser( 'read', 'templates' )\n\t\t\t\t\t\t\t? addQueryArgs( 'site-editor.php', {\n\t\t\t\t\t\t\t\t\tpath: '/patterns',\n\t\t\t\t\t\t\t } )\n\t\t\t\t\t\t\t: addQueryArgs( 'edit.php', {\n\t\t\t\t\t\t\t\t\tpost_type: 'wp_block',\n\t\t\t\t\t\t\t } ),\n\t\t\t\t};\n\t\t\t},\n\t\t\t[ clientId ]\n\t\t);\n\n\tconst { __experimentalConvertSyncedPatternToStatic: convertBlockToStatic } =\n\t\tuseDispatch( editorStore );\n\n\tif ( ! isVisible ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<MenuItem href={ managePatternsUrl }>\n\t\t\t\t{ __( 'Manage patterns' ) }\n\t\t\t</MenuItem>\n\t\t\t{ canRemove && (\n\t\t\t\t<MenuItem onClick={ () => convertBlockToStatic( clientId ) }>\n\t\t\t\t\t{ innerBlockCount > 1\n\t\t\t\t\t\t? __( 'Detach patterns' )\n\t\t\t\t\t\t: __( 'Detach pattern' ) }\n\t\t\t\t</MenuItem>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\nexport default PatternsManageButton;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,QAAQ,QAAQ,uBAAuB;AAChD,SAASC,EAAE,QAAQ,iBAAiB;AACpC,SAASC,eAAe,QAAQ,mBAAmB;AACnD,SAASC,SAAS,EAAEC,WAAW,QAAQ,iBAAiB;AACxD,SAASC,KAAK,IAAIC,gBAAgB,QAAQ,yBAAyB;AACnE,SAASC,YAAY,QAAQ,gBAAgB;AAC7C,SAASF,KAAK,IAAIG,SAAS,QAAQ,sBAAsB;;AAEzD;AACA;AACA;AACA,SAASH,KAAK,IAAII,WAAW,QAAQ,UAAU;AAE/C,SAASC,oBAAoBA,CAAE;EAAEC;AAAS,CAAC,EAAG;EAC7C,MAAM;IAAEC,SAAS;IAAEC,SAAS;IAAEC,eAAe;IAAEC;EAAkB,CAAC,GACjEZ,SAAS,CACNa,MAAM,IAAM;IACb,MAAM;MAAEC,QAAQ;MAAEC,cAAc;MAAEC,aAAa;MAAEC;IAAY,CAAC,GAC7DJ,MAAM,CAAEV,gBAAiB,CAAC;IAC3B,MAAM;MAAEe;IAAQ,CAAC,GAAGL,MAAM,CAAER,SAAU,CAAC;IACvC,MAAMc,aAAa,GAAGL,QAAQ,CAAEN,QAAS,CAAC;IAC1C,MAAMY,YAAY,GAAGH,WAAW,CAAC,CAAC,CAACI,2BAA2B;IAE9D,OAAO;MACNZ,SAAS,EAAEM,cAAc,CAAEP,QAAS,CAAC;MACrCE,SAAS,EACR,CAAC,CAAES,aAAa,IAChBpB,eAAe,CAAEoB,aAAc,CAAC,IAChC,CAAC,CAAED,OAAO,CACT,QAAQ,EACR,QAAQ,EACRC,aAAa,CAACG,UAAU,CAACC,GAC1B,CAAC;MACFZ,eAAe,EAAEK,aAAa,CAAER,QAAS,CAAC;MAC1C;MACA;MACA;MACAI,iBAAiB,EAChBQ,YAAY,IAAIF,OAAO,CAAE,MAAM,EAAE,WAAY,CAAC,GAC3Cd,YAAY,CAAE,iBAAiB,EAAE;QACjCoB,IAAI,EAAE;MACN,CAAE,CAAC,GACHpB,YAAY,CAAE,UAAU,EAAE;QAC1BqB,SAAS,EAAE;MACX,CAAE;IACP,CAAC;EACF,CAAC,EACD,CAAEjB,QAAQ,CACX,CAAC;EAEF,MAAM;IAAEkB,0CAA0C,EAAEC;EAAqB,CAAC,GACzE1B,WAAW,CAAEK,WAAY,CAAC;EAE3B,IAAK,CAAEI,SAAS,EAAG;IAClB,OAAO,IAAI;EACZ;EAEA,OACCkB,aAAA,CAAAC,QAAA,QACCD,aAAA,CAAC/B,QAAQ;IAACiC,IAAI,EAAGlB;EAAmB,GACjCd,EAAE,CAAE,iBAAkB,CACf,CAAC,EACTW,SAAS,IACVmB,aAAA,CAAC/B,QAAQ;IAACkC,OAAO,EAAGA,CAAA,KAAMJ,oBAAoB,CAAEnB,QAAS;EAAG,GACzDG,eAAe,GAAG,CAAC,GAClBb,EAAE,CAAE,iBAAkB,CAAC,GACvBA,EAAE,CAAE,gBAAiB,CACf,CAEV,CAAC;AAEL;AAEA,eAAeS,oBAAoB"}
1
+ {"version":3,"names":["MenuItem","__","isReusableBlock","useSelect","useDispatch","store","blockEditorStore","addQueryArgs","coreStore","patternsStore","unlock","PatternsManageButton","clientId","canRemove","isVisible","innerBlockCount","managePatternsUrl","select","getBlock","canRemoveBlock","getBlockCount","getSettings","canUser","reusableBlock","isBlockTheme","__unstableIsBlockBasedTheme","attributes","ref","path","post_type","convertSyncedPatternToStatic","createElement","Fragment","href","onClick"],"sources":["@wordpress/patterns/src/components/patterns-manage-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { MenuItem } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { isReusableBlock } from '@wordpress/blocks';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport { store as coreStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport { unlock } from '../lock-unlock';\n\nfunction PatternsManageButton( { clientId } ) {\n\tconst { canRemove, isVisible, innerBlockCount, managePatternsUrl } =\n\t\tuseSelect(\n\t\t\t( select ) => {\n\t\t\t\tconst { getBlock, canRemoveBlock, getBlockCount, getSettings } =\n\t\t\t\t\tselect( blockEditorStore );\n\t\t\t\tconst { canUser } = select( coreStore );\n\t\t\t\tconst reusableBlock = getBlock( clientId );\n\t\t\t\tconst isBlockTheme = getSettings().__unstableIsBlockBasedTheme;\n\n\t\t\t\treturn {\n\t\t\t\t\tcanRemove: canRemoveBlock( clientId ),\n\t\t\t\t\tisVisible:\n\t\t\t\t\t\t!! reusableBlock &&\n\t\t\t\t\t\tisReusableBlock( reusableBlock ) &&\n\t\t\t\t\t\t!! canUser(\n\t\t\t\t\t\t\t'update',\n\t\t\t\t\t\t\t'blocks',\n\t\t\t\t\t\t\treusableBlock.attributes.ref\n\t\t\t\t\t\t),\n\t\t\t\t\tinnerBlockCount: getBlockCount( clientId ),\n\t\t\t\t\t// The site editor and templates both check whether the user\n\t\t\t\t\t// has edit_theme_options capabilities. We can leverage that here\n\t\t\t\t\t// and omit the manage patterns link if the user can't access it.\n\t\t\t\t\tmanagePatternsUrl:\n\t\t\t\t\t\tisBlockTheme && canUser( 'read', 'templates' )\n\t\t\t\t\t\t\t? addQueryArgs( 'site-editor.php', {\n\t\t\t\t\t\t\t\t\tpath: '/patterns',\n\t\t\t\t\t\t\t } )\n\t\t\t\t\t\t\t: addQueryArgs( 'edit.php', {\n\t\t\t\t\t\t\t\t\tpost_type: 'wp_block',\n\t\t\t\t\t\t\t } ),\n\t\t\t\t};\n\t\t\t},\n\t\t\t[ clientId ]\n\t\t);\n\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { convertSyncedPatternToStatic } = unlock(\n\t\tuseDispatch( patternsStore )\n\t);\n\n\tif ( ! isVisible ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<MenuItem href={ managePatternsUrl }>\n\t\t\t\t{ __( 'Manage patterns' ) }\n\t\t\t</MenuItem>\n\t\t\t{ canRemove && (\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => convertSyncedPatternToStatic( clientId ) }\n\t\t\t\t>\n\t\t\t\t\t{ innerBlockCount > 1\n\t\t\t\t\t\t? __( 'Detach patterns' )\n\t\t\t\t\t\t: __( 'Detach pattern' ) }\n\t\t\t\t</MenuItem>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\nexport default PatternsManageButton;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,QAAQ,QAAQ,uBAAuB;AAChD,SAASC,EAAE,QAAQ,iBAAiB;AACpC,SAASC,eAAe,QAAQ,mBAAmB;AACnD,SAASC,SAAS,EAAEC,WAAW,QAAQ,iBAAiB;AACxD,SAASC,KAAK,IAAIC,gBAAgB,QAAQ,yBAAyB;AACnE,SAASC,YAAY,QAAQ,gBAAgB;AAC7C,SAASF,KAAK,IAAIG,SAAS,QAAQ,sBAAsB;;AAEzD;AACA;AACA;AACA,SAASH,KAAK,IAAII,aAAa,QAAQ,UAAU;AACjD,SAASC,MAAM,QAAQ,gBAAgB;AAEvC,SAASC,oBAAoBA,CAAE;EAAEC;AAAS,CAAC,EAAG;EAC7C,MAAM;IAAEC,SAAS;IAAEC,SAAS;IAAEC,eAAe;IAAEC;EAAkB,CAAC,GACjEb,SAAS,CACNc,MAAM,IAAM;IACb,MAAM;MAAEC,QAAQ;MAAEC,cAAc;MAAEC,aAAa;MAAEC;IAAY,CAAC,GAC7DJ,MAAM,CAAEX,gBAAiB,CAAC;IAC3B,MAAM;MAAEgB;IAAQ,CAAC,GAAGL,MAAM,CAAET,SAAU,CAAC;IACvC,MAAMe,aAAa,GAAGL,QAAQ,CAAEN,QAAS,CAAC;IAC1C,MAAMY,YAAY,GAAGH,WAAW,CAAC,CAAC,CAACI,2BAA2B;IAE9D,OAAO;MACNZ,SAAS,EAAEM,cAAc,CAAEP,QAAS,CAAC;MACrCE,SAAS,EACR,CAAC,CAAES,aAAa,IAChBrB,eAAe,CAAEqB,aAAc,CAAC,IAChC,CAAC,CAAED,OAAO,CACT,QAAQ,EACR,QAAQ,EACRC,aAAa,CAACG,UAAU,CAACC,GAC1B,CAAC;MACFZ,eAAe,EAAEK,aAAa,CAAER,QAAS,CAAC;MAC1C;MACA;MACA;MACAI,iBAAiB,EAChBQ,YAAY,IAAIF,OAAO,CAAE,MAAM,EAAE,WAAY,CAAC,GAC3Cf,YAAY,CAAE,iBAAiB,EAAE;QACjCqB,IAAI,EAAE;MACN,CAAE,CAAC,GACHrB,YAAY,CAAE,UAAU,EAAE;QAC1BsB,SAAS,EAAE;MACX,CAAE;IACP,CAAC;EACF,CAAC,EACD,CAAEjB,QAAQ,CACX,CAAC;;EAEF;EACA;EACA,MAAM;IAAEkB;EAA6B,CAAC,GAAGpB,MAAM,CAC9CN,WAAW,CAAEK,aAAc,CAC5B,CAAC;EAED,IAAK,CAAEK,SAAS,EAAG;IAClB,OAAO,IAAI;EACZ;EAEA,OACCiB,aAAA,CAAAC,QAAA,QACCD,aAAA,CAAC/B,QAAQ;IAACiC,IAAI,EAAGjB;EAAmB,GACjCf,EAAE,CAAE,iBAAkB,CACf,CAAC,EACTY,SAAS,IACVkB,aAAA,CAAC/B,QAAQ;IACRkC,OAAO,EAAGA,CAAA,KAAMJ,4BAA4B,CAAElB,QAAS;EAAG,GAExDG,eAAe,GAAG,CAAC,GAClBd,EAAE,CAAE,iBAAkB,CAAC,GACvBA,EAAE,CAAE,gBAAiB,CACf,CAEV,CAAC;AAEL;AAEA,eAAeU,oBAAoB"}
@@ -0,0 +1,11 @@
1
+ export const PATTERN_TYPES = {
2
+ theme: 'pattern',
3
+ user: 'wp_block'
4
+ };
5
+ export const PATTERN_DEFAULT_CATEGORY = 'all-patterns';
6
+ export const PATTERN_CORE_SOURCES = ['core', 'pattern-directory/core', 'pattern-directory/featured', 'pattern-directory/theme'];
7
+ export const PATTERN_SYNC_TYPES = {
8
+ full: 'fully',
9
+ unsynced: 'unsynced'
10
+ };
11
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["PATTERN_TYPES","theme","user","PATTERN_DEFAULT_CATEGORY","PATTERN_CORE_SOURCES","PATTERN_SYNC_TYPES","full","unsynced"],"sources":["@wordpress/patterns/src/constants.js"],"sourcesContent":["export const PATTERN_TYPES = {\n\ttheme: 'pattern',\n\tuser: 'wp_block',\n};\n\nexport const PATTERN_DEFAULT_CATEGORY = 'all-patterns';\nexport const PATTERN_CORE_SOURCES = [\n\t'core',\n\t'pattern-directory/core',\n\t'pattern-directory/featured',\n\t'pattern-directory/theme',\n];\nexport const PATTERN_SYNC_TYPES = {\n\tfull: 'fully',\n\tunsynced: 'unsynced',\n};\n"],"mappings":"AAAA,OAAO,MAAMA,aAAa,GAAG;EAC5BC,KAAK,EAAE,SAAS;EAChBC,IAAI,EAAE;AACP,CAAC;AAED,OAAO,MAAMC,wBAAwB,GAAG,cAAc;AACtD,OAAO,MAAMC,oBAAoB,GAAG,CACnC,MAAM,EACN,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,CACzB;AACD,OAAO,MAAMC,kBAAkB,GAAG;EACjCC,IAAI,EAAE,OAAO;EACbC,QAAQ,EAAE;AACX,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Internal dependencies
3
3
  */
4
- import './store';
4
+ export { store } from './store';
5
5
  export * from './private-apis';
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["@wordpress/patterns/src/index.js"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport './store';\n\nexport * from './private-apis';\n"],"mappings":"AAAA;AACA;AACA;AACA,OAAO,SAAS;AAEhB,cAAc,gBAAgB"}
1
+ {"version":3,"names":["store"],"sources":["@wordpress/patterns/src/index.js"],"sourcesContent":["/**\n * Internal dependencies\n */\nexport { store } from './store';\nexport * from './private-apis';\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,KAAK,QAAQ,SAAS;AAC/B,cAAc,gBAAgB"}
@@ -4,9 +4,14 @@
4
4
  import { lock } from './lock-unlock';
5
5
  import CreatePatternModal from './components/create-pattern-modal';
6
6
  import PatternsMenuItems from './components';
7
+ import { PATTERN_TYPES, PATTERN_DEFAULT_CATEGORY, PATTERN_CORE_SOURCES, PATTERN_SYNC_TYPES } from './constants';
7
8
  export const privateApis = {};
8
9
  lock(privateApis, {
9
10
  CreatePatternModal,
10
- PatternsMenuItems
11
+ PatternsMenuItems,
12
+ PATTERN_TYPES,
13
+ PATTERN_DEFAULT_CATEGORY,
14
+ PATTERN_CORE_SOURCES,
15
+ PATTERN_SYNC_TYPES
11
16
  });
12
17
  //# sourceMappingURL=private-apis.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["lock","CreatePatternModal","PatternsMenuItems","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';\n\nexport const privateApis = {};\nlock( privateApis, {\n\tCreatePatternModal,\n\tPatternsMenuItems,\n} );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,IAAI,QAAQ,eAAe;AACpC,OAAOC,kBAAkB,MAAM,mCAAmC;AAClE,OAAOC,iBAAiB,MAAM,cAAc;AAE5C,OAAO,MAAMC,WAAW,GAAG,CAAC,CAAC;AAC7BH,IAAI,CAAEG,WAAW,EAAE;EAClBF,kBAAkB;EAClBC;AACD,CAAE,CAAC"}
1
+ {"version":3,"names":["lock","CreatePatternModal","PatternsMenuItems","PATTERN_TYPES","PATTERN_DEFAULT_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_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_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,oBAAoB,EACpBC,kBAAkB,QACZ,aAAa;AAEpB,OAAO,MAAMC,WAAW,GAAG,CAAC,CAAC;AAC7BP,IAAI,CAAEO,WAAW,EAAE;EAClBN,kBAAkB;EAClBC,iBAAiB;EACjBC,aAAa;EACbC,wBAAwB;EACxBC,oBAAoB;EACpBC;AACD,CAAE,CAAC"}
@@ -2,48 +2,69 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
 
5
- import { parse, serialize, createBlock } from '@wordpress/blocks';
5
+ import { parse } from '@wordpress/blocks';
6
6
  import { store as coreStore } from '@wordpress/core-data';
7
7
  import { store as blockEditorStore } from '@wordpress/block-editor';
8
8
 
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { PATTERN_SYNC_TYPES } from '../constants';
13
+
9
14
  /**
10
15
  * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.
11
16
  *
12
- * @param {string} title Pattern title.
13
- * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.
14
- * @param {string[]|undefined} clientIds Optional client IDs of blocks to convert to pattern.
17
+ * @param {string} title Pattern title.
18
+ * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.
19
+ * @param {string|undefined} [content] Optional serialized content of blocks to convert to pattern.
20
+ * @param {number[]|undefined} [categories] Ids of any selected categories.
15
21
  */
16
- export const __experimentalCreatePattern = (title, syncType, clientIds) => async ({
17
- registry,
18
- dispatch
22
+ export const createPattern = (title, syncType, content, categories) => async ({
23
+ registry
19
24
  }) => {
20
- const meta = syncType === 'unsynced' ? {
25
+ const meta = syncType === PATTERN_SYNC_TYPES.unsynced ? {
21
26
  wp_pattern_sync_status: syncType
22
27
  } : undefined;
23
28
  const reusableBlock = {
24
29
  title,
25
- content: clientIds ? serialize(registry.select(blockEditorStore).getBlocksByClientId(clientIds)) : undefined,
30
+ content,
26
31
  status: 'publish',
27
- meta
32
+ meta,
33
+ wp_pattern_category: categories
28
34
  };
29
35
  const updatedRecord = await registry.dispatch(coreStore).saveEntityRecord('postType', 'wp_block', reusableBlock);
30
- if (syncType === 'unsynced' || !clientIds) {
31
- return updatedRecord;
32
- }
33
- const newBlock = createBlock('core/block', {
34
- ref: updatedRecord.id
35
- });
36
- registry.dispatch(blockEditorStore).replaceBlocks(clientIds, newBlock);
37
- dispatch.__experimentalSetEditingPattern(newBlock.clientId, true);
38
36
  return updatedRecord;
39
37
  };
40
38
 
39
+ /**
40
+ * Create a pattern from a JSON file.
41
+ * @param {File} file The JSON file instance of the pattern.
42
+ * @param {number[]|undefined} [categories] Ids of any selected categories.
43
+ */
44
+ export const createPatternFromFile = (file, categories) => async ({
45
+ dispatch
46
+ }) => {
47
+ const fileContent = await file.text();
48
+ /** @type {import('./types').PatternJSON} */
49
+ let parsedContent;
50
+ try {
51
+ parsedContent = JSON.parse(fileContent);
52
+ } catch (e) {
53
+ throw new Error('Invalid JSON file');
54
+ }
55
+ if (parsedContent.__file !== 'wp_block' || !parsedContent.title || !parsedContent.content || typeof parsedContent.title !== 'string' || typeof parsedContent.content !== 'string' || parsedContent.syncStatus && typeof parsedContent.syncStatus !== 'string') {
56
+ throw new Error('Invalid Pattern JSON file');
57
+ }
58
+ const pattern = await dispatch.createPattern(parsedContent.title, parsedContent.syncStatus, parsedContent.content, categories);
59
+ return pattern;
60
+ };
61
+
41
62
  /**
42
63
  * Returns a generator converting a synced pattern block into a static block.
43
64
  *
44
65
  * @param {string} clientId The client ID of the block to attach.
45
66
  */
46
- export const __experimentalConvertSyncedPatternToStatic = clientId => ({
67
+ export const convertSyncedPatternToStatic = clientId => ({
47
68
  registry
48
69
  }) => {
49
70
  const oldBlock = registry.select(blockEditorStore).getBlock(clientId);
@@ -59,7 +80,7 @@ export const __experimentalConvertSyncedPatternToStatic = clientId => ({
59
80
  * @param {boolean} isEditing Whether the block should be in editing state.
60
81
  * @return {Object} Action descriptor.
61
82
  */
62
- export function __experimentalSetEditingPattern(clientId, isEditing) {
83
+ export function setEditingPattern(clientId, isEditing) {
63
84
  return {
64
85
  type: 'SET_EDITING_PATTERN',
65
86
  clientId,
@@ -1 +1 @@
1
- {"version":3,"names":["parse","serialize","createBlock","store","coreStore","blockEditorStore","__experimentalCreatePattern","title","syncType","clientIds","registry","dispatch","meta","wp_pattern_sync_status","undefined","reusableBlock","content","select","getBlocksByClientId","status","updatedRecord","saveEntityRecord","newBlock","ref","id","replaceBlocks","__experimentalSetEditingPattern","clientId","__experimentalConvertSyncedPatternToStatic","oldBlock","getBlock","pattern","getEditedEntityRecord","attributes","newBlocks","isEditing","type"],"sources":["@wordpress/patterns/src/store/actions.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\n\nimport { parse, serialize, createBlock } from '@wordpress/blocks';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.\n *\n * @param {string} title Pattern title.\n * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.\n * @param {string[]|undefined} clientIds Optional client IDs of blocks to convert to pattern.\n */\nexport const __experimentalCreatePattern =\n\t( title, syncType, clientIds ) =>\n\tasync ( { registry, dispatch } ) => {\n\t\tconst meta =\n\t\t\tsyncType === 'unsynced'\n\t\t\t\t? {\n\t\t\t\t\t\twp_pattern_sync_status: syncType,\n\t\t\t\t }\n\t\t\t\t: undefined;\n\n\t\tconst reusableBlock = {\n\t\t\ttitle,\n\t\t\tcontent: clientIds\n\t\t\t\t? serialize(\n\t\t\t\t\t\tregistry\n\t\t\t\t\t\t\t.select( blockEditorStore )\n\t\t\t\t\t\t\t.getBlocksByClientId( clientIds )\n\t\t\t\t )\n\t\t\t\t: undefined,\n\t\t\tstatus: 'publish',\n\t\t\tmeta,\n\t\t};\n\n\t\tconst updatedRecord = await registry\n\t\t\t.dispatch( coreStore )\n\t\t\t.saveEntityRecord( 'postType', 'wp_block', reusableBlock );\n\n\t\tif ( syncType === 'unsynced' || ! clientIds ) {\n\t\t\treturn updatedRecord;\n\t\t}\n\n\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\tref: updatedRecord.id,\n\t\t} );\n\t\tregistry\n\t\t\t.dispatch( blockEditorStore )\n\t\t\t.replaceBlocks( clientIds, newBlock );\n\t\tdispatch.__experimentalSetEditingPattern( newBlock.clientId, true );\n\t\treturn updatedRecord;\n\t};\n\n/**\n * Returns a generator converting a synced pattern block into a static block.\n *\n * @param {string} clientId The client ID of the block to attach.\n */\nexport const __experimentalConvertSyncedPatternToStatic =\n\t( clientId ) =>\n\t( { registry } ) => {\n\t\tconst oldBlock = registry\n\t\t\t.select( blockEditorStore )\n\t\t\t.getBlock( clientId );\n\t\tconst pattern = registry\n\t\t\t.select( 'core' )\n\t\t\t.getEditedEntityRecord(\n\t\t\t\t'postType',\n\t\t\t\t'wp_block',\n\t\t\t\toldBlock.attributes.ref\n\t\t\t);\n\n\t\tconst newBlocks = parse(\n\t\t\ttypeof pattern.content === 'function'\n\t\t\t\t? pattern.content( pattern )\n\t\t\t\t: pattern.content\n\t\t);\n\t\tregistry\n\t\t\t.dispatch( blockEditorStore )\n\t\t\t.replaceBlocks( oldBlock.clientId, newBlocks );\n\t};\n\n/**\n * Returns an action descriptor for SET_EDITING_PATTERN action.\n *\n * @param {string} clientId The clientID of the pattern to target.\n * @param {boolean} isEditing Whether the block should be in editing state.\n * @return {Object} Action descriptor.\n */\nexport function __experimentalSetEditingPattern( clientId, isEditing ) {\n\treturn {\n\t\ttype: 'SET_EDITING_PATTERN',\n\t\tclientId,\n\t\tisEditing,\n\t};\n}\n"],"mappings":"AAAA;AACA;AACA;;AAEA,SAASA,KAAK,EAAEC,SAAS,EAAEC,WAAW,QAAQ,mBAAmB;AACjE,SAASC,KAAK,IAAIC,SAAS,QAAQ,sBAAsB;AACzD,SAASD,KAAK,IAAIE,gBAAgB,QAAQ,yBAAyB;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,2BAA2B,GACvCA,CAAEC,KAAK,EAAEC,QAAQ,EAAEC,SAAS,KAC5B,OAAQ;EAAEC,QAAQ;EAAEC;AAAS,CAAC,KAAM;EACnC,MAAMC,IAAI,GACTJ,QAAQ,KAAK,UAAU,GACpB;IACAK,sBAAsB,EAAEL;EACxB,CAAC,GACDM,SAAS;EAEb,MAAMC,aAAa,GAAG;IACrBR,KAAK;IACLS,OAAO,EAAEP,SAAS,GACfR,SAAS,CACTS,QAAQ,CACNO,MAAM,CAAEZ,gBAAiB,CAAC,CAC1Ba,mBAAmB,CAAET,SAAU,CACjC,CAAC,GACDK,SAAS;IACZK,MAAM,EAAE,SAAS;IACjBP;EACD,CAAC;EAED,MAAMQ,aAAa,GAAG,MAAMV,QAAQ,CAClCC,QAAQ,CAAEP,SAAU,CAAC,CACrBiB,gBAAgB,CAAE,UAAU,EAAE,UAAU,EAAEN,aAAc,CAAC;EAE3D,IAAKP,QAAQ,KAAK,UAAU,IAAI,CAAEC,SAAS,EAAG;IAC7C,OAAOW,aAAa;EACrB;EAEA,MAAME,QAAQ,GAAGpB,WAAW,CAAE,YAAY,EAAE;IAC3CqB,GAAG,EAAEH,aAAa,CAACI;EACpB,CAAE,CAAC;EACHd,QAAQ,CACNC,QAAQ,CAAEN,gBAAiB,CAAC,CAC5BoB,aAAa,CAAEhB,SAAS,EAAEa,QAAS,CAAC;EACtCX,QAAQ,CAACe,+BAA+B,CAAEJ,QAAQ,CAACK,QAAQ,EAAE,IAAK,CAAC;EACnE,OAAOP,aAAa;AACrB,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMQ,0CAA0C,GACpDD,QAAQ,IACV,CAAE;EAAEjB;AAAS,CAAC,KAAM;EACnB,MAAMmB,QAAQ,GAAGnB,QAAQ,CACvBO,MAAM,CAAEZ,gBAAiB,CAAC,CAC1ByB,QAAQ,CAAEH,QAAS,CAAC;EACtB,MAAMI,OAAO,GAAGrB,QAAQ,CACtBO,MAAM,CAAE,MAAO,CAAC,CAChBe,qBAAqB,CACrB,UAAU,EACV,UAAU,EACVH,QAAQ,CAACI,UAAU,CAACV,GACrB,CAAC;EAEF,MAAMW,SAAS,GAAGlC,KAAK,CACtB,OAAO+B,OAAO,CAACf,OAAO,KAAK,UAAU,GAClCe,OAAO,CAACf,OAAO,CAAEe,OAAQ,CAAC,GAC1BA,OAAO,CAACf,OACZ,CAAC;EACDN,QAAQ,CACNC,QAAQ,CAAEN,gBAAiB,CAAC,CAC5BoB,aAAa,CAAEI,QAAQ,CAACF,QAAQ,EAAEO,SAAU,CAAC;AAChD,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASR,+BAA+BA,CAAEC,QAAQ,EAAEQ,SAAS,EAAG;EACtE,OAAO;IACNC,IAAI,EAAE,qBAAqB;IAC3BT,QAAQ;IACRQ;EACD,CAAC;AACF"}
1
+ {"version":3,"names":["parse","store","coreStore","blockEditorStore","PATTERN_SYNC_TYPES","createPattern","title","syncType","content","categories","registry","meta","unsynced","wp_pattern_sync_status","undefined","reusableBlock","status","wp_pattern_category","updatedRecord","dispatch","saveEntityRecord","createPatternFromFile","file","fileContent","text","parsedContent","JSON","e","Error","__file","syncStatus","pattern","convertSyncedPatternToStatic","clientId","oldBlock","select","getBlock","getEditedEntityRecord","attributes","ref","newBlocks","replaceBlocks","setEditingPattern","isEditing","type"],"sources":["@wordpress/patterns/src/store/actions.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\n\nimport { parse } from '@wordpress/blocks';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.\n *\n * @param {string} title Pattern title.\n * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.\n * @param {string|undefined} [content] Optional serialized content of blocks to convert to pattern.\n * @param {number[]|undefined} [categories] Ids of any selected categories.\n */\nexport const createPattern =\n\t( title, syncType, content, categories ) =>\n\tasync ( { registry } ) => {\n\t\tconst meta =\n\t\t\tsyncType === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? {\n\t\t\t\t\t\twp_pattern_sync_status: syncType,\n\t\t\t\t }\n\t\t\t\t: undefined;\n\n\t\tconst reusableBlock = {\n\t\t\ttitle,\n\t\t\tcontent,\n\t\t\tstatus: 'publish',\n\t\t\tmeta,\n\t\t\twp_pattern_category: categories,\n\t\t};\n\n\t\tconst updatedRecord = await registry\n\t\t\t.dispatch( coreStore )\n\t\t\t.saveEntityRecord( 'postType', 'wp_block', reusableBlock );\n\n\t\treturn updatedRecord;\n\t};\n\n/**\n * Create a pattern from a JSON file.\n * @param {File} file The JSON file instance of the pattern.\n * @param {number[]|undefined} [categories] Ids of any selected categories.\n */\nexport const createPatternFromFile =\n\t( file, categories ) =>\n\tasync ( { dispatch } ) => {\n\t\tconst fileContent = await file.text();\n\t\t/** @type {import('./types').PatternJSON} */\n\t\tlet parsedContent;\n\t\ttry {\n\t\t\tparsedContent = JSON.parse( fileContent );\n\t\t} catch ( e ) {\n\t\t\tthrow new Error( 'Invalid JSON file' );\n\t\t}\n\t\tif (\n\t\t\tparsedContent.__file !== 'wp_block' ||\n\t\t\t! parsedContent.title ||\n\t\t\t! parsedContent.content ||\n\t\t\ttypeof parsedContent.title !== 'string' ||\n\t\t\ttypeof parsedContent.content !== 'string' ||\n\t\t\t( parsedContent.syncStatus &&\n\t\t\t\ttypeof parsedContent.syncStatus !== 'string' )\n\t\t) {\n\t\t\tthrow new Error( 'Invalid Pattern JSON file' );\n\t\t}\n\n\t\tconst pattern = await dispatch.createPattern(\n\t\t\tparsedContent.title,\n\t\t\tparsedContent.syncStatus,\n\t\t\tparsedContent.content,\n\t\t\tcategories\n\t\t);\n\n\t\treturn pattern;\n\t};\n\n/**\n * Returns a generator converting a synced pattern block into a static block.\n *\n * @param {string} clientId The client ID of the block to attach.\n */\nexport const convertSyncedPatternToStatic =\n\t( clientId ) =>\n\t( { registry } ) => {\n\t\tconst oldBlock = registry\n\t\t\t.select( blockEditorStore )\n\t\t\t.getBlock( clientId );\n\t\tconst pattern = registry\n\t\t\t.select( 'core' )\n\t\t\t.getEditedEntityRecord(\n\t\t\t\t'postType',\n\t\t\t\t'wp_block',\n\t\t\t\toldBlock.attributes.ref\n\t\t\t);\n\n\t\tconst newBlocks = parse(\n\t\t\ttypeof pattern.content === 'function'\n\t\t\t\t? pattern.content( pattern )\n\t\t\t\t: pattern.content\n\t\t);\n\t\tregistry\n\t\t\t.dispatch( blockEditorStore )\n\t\t\t.replaceBlocks( oldBlock.clientId, newBlocks );\n\t};\n\n/**\n * Returns an action descriptor for SET_EDITING_PATTERN action.\n *\n * @param {string} clientId The clientID of the pattern to target.\n * @param {boolean} isEditing Whether the block should be in editing state.\n * @return {Object} Action descriptor.\n */\nexport function setEditingPattern( clientId, isEditing ) {\n\treturn {\n\t\ttype: 'SET_EDITING_PATTERN',\n\t\tclientId,\n\t\tisEditing,\n\t};\n}\n"],"mappings":"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"}
@@ -10,6 +10,7 @@ import reducer from './reducer';
10
10
  import * as actions from './actions';
11
11
  import { STORE_NAME } from './constants';
12
12
  import * as selectors from './selectors';
13
+ import { unlock } from '../lock-unlock';
13
14
 
14
15
  /**
15
16
  * Post editor data store configuration.
@@ -19,9 +20,7 @@ import * as selectors from './selectors';
19
20
  * @type {Object}
20
21
  */
21
22
  export const storeConfig = {
22
- reducer,
23
- selectors,
24
- actions
23
+ reducer
25
24
  };
26
25
 
27
26
  /**
@@ -35,4 +34,6 @@ export const store = createReduxStore(STORE_NAME, {
35
34
  ...storeConfig
36
35
  });
37
36
  register(store);
37
+ unlock(store).registerPrivateActions(actions);
38
+ unlock(store).registerPrivateSelectors(selectors);
38
39
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["createReduxStore","register","reducer","actions","STORE_NAME","selectors","storeConfig","store"],"sources":["@wordpress/patterns/src/store/index.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createReduxStore, register } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport reducer from './reducer';\nimport * as actions from './actions';\nimport { STORE_NAME } from './constants';\nimport * as selectors from './selectors';\n\n/**\n * Post editor data store configuration.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore\n *\n * @type {Object}\n */\nexport const storeConfig = {\n\treducer,\n\tselectors,\n\tactions,\n};\n\n/**\n * Store definition for the editor namespace.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore\n *\n * @type {Object}\n */\nexport const store = createReduxStore( STORE_NAME, {\n\t...storeConfig,\n} );\n\nregister( store );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,gBAAgB,EAAEC,QAAQ,QAAQ,iBAAiB;;AAE5D;AACA;AACA;AACA,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAO,KAAKC,OAAO,MAAM,WAAW;AACpC,SAASC,UAAU,QAAQ,aAAa;AACxC,OAAO,KAAKC,SAAS,MAAM,aAAa;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAG;EAC1BJ,OAAO;EACPG,SAAS;EACTF;AACD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMI,KAAK,GAAGP,gBAAgB,CAAEI,UAAU,EAAE;EAClD,GAAGE;AACJ,CAAE,CAAC;AAEHL,QAAQ,CAAEM,KAAM,CAAC"}
1
+ {"version":3,"names":["createReduxStore","register","reducer","actions","STORE_NAME","selectors","unlock","storeConfig","store","registerPrivateActions","registerPrivateSelectors"],"sources":["@wordpress/patterns/src/store/index.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createReduxStore, register } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport reducer from './reducer';\nimport * as actions from './actions';\nimport { STORE_NAME } from './constants';\nimport * as selectors from './selectors';\nimport { unlock } from '../lock-unlock';\n\n/**\n * Post editor data store configuration.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore\n *\n * @type {Object}\n */\nexport const storeConfig = {\n\treducer,\n};\n\n/**\n * Store definition for the editor namespace.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore\n *\n * @type {Object}\n */\nexport const store = createReduxStore( STORE_NAME, {\n\t...storeConfig,\n} );\n\nregister( store );\nunlock( store ).registerPrivateActions( actions );\nunlock( store ).registerPrivateSelectors( selectors );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,gBAAgB,EAAEC,QAAQ,QAAQ,iBAAiB;;AAE5D;AACA;AACA;AACA,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAO,KAAKC,OAAO,MAAM,WAAW;AACpC,SAASC,UAAU,QAAQ,aAAa;AACxC,OAAO,KAAKC,SAAS,MAAM,aAAa;AACxC,SAASC,MAAM,QAAQ,gBAAgB;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAG;EAC1BL;AACD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMM,KAAK,GAAGR,gBAAgB,CAAEI,UAAU,EAAE;EAClD,GAAGG;AACJ,CAAE,CAAC;AAEHN,QAAQ,CAAEO,KAAM,CAAC;AACjBF,MAAM,CAAEE,KAAM,CAAC,CAACC,sBAAsB,CAAEN,OAAQ,CAAC;AACjDG,MAAM,CAAEE,KAAM,CAAC,CAACE,wBAAwB,CAAEL,SAAU,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * @param {number} clientId the clientID of the block.
6
6
  * @return {boolean} Whether the pattern is in the editing state.
7
7
  */
8
- export function __experimentalIsEditingPattern(state, clientId) {
8
+ export function isEditingPattern(state, clientId) {
9
9
  return state.isEditingPattern[clientId];
10
10
  }
11
11
  //# sourceMappingURL=selectors.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["__experimentalIsEditingPattern","state","clientId","isEditingPattern"],"sources":["@wordpress/patterns/src/store/selectors.js"],"sourcesContent":["/**\n * Returns true if pattern is in the editing state.\n *\n * @param {Object} state Global application state.\n * @param {number} clientId the clientID of the block.\n * @return {boolean} Whether the pattern is in the editing state.\n */\nexport function __experimentalIsEditingPattern( state, clientId ) {\n\treturn state.isEditingPattern[ clientId ];\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,8BAA8BA,CAAEC,KAAK,EAAEC,QAAQ,EAAG;EACjE,OAAOD,KAAK,CAACE,gBAAgB,CAAED,QAAQ,CAAE;AAC1C"}
1
+ {"version":3,"names":["isEditingPattern","state","clientId"],"sources":["@wordpress/patterns/src/store/selectors.js"],"sourcesContent":["/**\n * Returns true if pattern is in the editing state.\n *\n * @param {Object} state Global application state.\n * @param {number} clientId the clientID of the block.\n * @return {boolean} Whether the pattern is in the editing state.\n */\nexport function isEditingPattern( state, clientId ) {\n\treturn state.isEditingPattern[ clientId ];\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,gBAAgBA,CAAEC,KAAK,EAAEC,QAAQ,EAAG;EACnD,OAAOD,KAAK,CAACD,gBAAgB,CAAEE,QAAQ,CAAE;AAC1C"}
@@ -105,4 +105,11 @@
105
105
 
106
106
  .patterns-menu-items__convert-modal {
107
107
  z-index: 1000001;
108
+ }
109
+ .patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories {
110
+ max-width: 300px;
111
+ }
112
+
113
+ .patterns-create-modal__name-input input[type=text] {
114
+ min-height: 34px;
108
115
  }
@@ -105,4 +105,11 @@
105
105
 
106
106
  .patterns-menu-items__convert-modal {
107
107
  z-index: 1000001;
108
+ }
109
+ .patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories {
110
+ max-width: 300px;
111
+ }
112
+
113
+ .patterns-create-modal__name-input input[type=text] {
114
+ min-height: 34px;
108
115
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/patterns",
3
- "version": "1.2.1-next.5a1d1283.0",
3
+ "version": "1.3.0",
4
4
  "description": "Management of user pattern editing.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -31,18 +31,20 @@
31
31
  "{src,build,build-module}/{index.js,store/index.js,hooks/**}"
32
32
  ],
33
33
  "dependencies": {
34
- "@wordpress/block-editor": "^12.9.1-next.5a1d1283.0",
35
- "@wordpress/blocks": "^12.18.1-next.5a1d1283.0",
36
- "@wordpress/components": "^26.0.1-next.5a1d1283.0",
37
- "@wordpress/compose": "^6.18.1-next.5a1d1283.0",
38
- "@wordpress/core-data": "^6.18.1-next.5a1d1283.0",
39
- "@wordpress/data": "^9.11.1-next.5a1d1283.0",
40
- "@wordpress/element": "^5.18.1-next.5a1d1283.0",
41
- "@wordpress/i18n": "^4.41.1-next.5a1d1283.0",
42
- "@wordpress/icons": "^9.32.1-next.5a1d1283.0",
43
- "@wordpress/notices": "^4.9.1-next.5a1d1283.0",
44
- "@wordpress/private-apis": "^0.23.1-next.5a1d1283.0",
45
- "@wordpress/url": "^3.42.1-next.5a1d1283.0"
34
+ "@babel/runtime": "^7.16.0",
35
+ "@wordpress/block-editor": "^12.10.0",
36
+ "@wordpress/blocks": "^12.19.0",
37
+ "@wordpress/components": "^25.8.0",
38
+ "@wordpress/compose": "^6.19.0",
39
+ "@wordpress/core-data": "^6.19.0",
40
+ "@wordpress/data": "^9.12.0",
41
+ "@wordpress/element": "^5.19.0",
42
+ "@wordpress/html-entities": "^3.42.0",
43
+ "@wordpress/i18n": "^4.42.0",
44
+ "@wordpress/icons": "^9.33.0",
45
+ "@wordpress/notices": "^4.10.0",
46
+ "@wordpress/private-apis": "^0.24.0",
47
+ "@wordpress/url": "^3.43.0"
46
48
  },
47
49
  "peerDependencies": {
48
50
  "react": "^18.0.0",
@@ -51,5 +53,5 @@
51
53
  "publishConfig": {
52
54
  "access": "public"
53
55
  },
54
- "gitHead": "fa0b66987dab5a15f38663e06036d09bccffaa4b"
56
+ "gitHead": "cc35f517ed017ab7131319af3e87c359e8de175d"
55
57
  }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { useMemo, useState } from '@wordpress/element';
6
+ import { FormTokenField } from '@wordpress/components';
7
+ import { useSelect, useDispatch } from '@wordpress/data';
8
+ import { store as coreStore } from '@wordpress/core-data';
9
+ import { useDebounce } from '@wordpress/compose';
10
+ import { decodeEntities } from '@wordpress/html-entities';
11
+
12
+ const unescapeString = ( arg ) => {
13
+ return decodeEntities( arg );
14
+ };
15
+
16
+ const unescapeTerm = ( term ) => {
17
+ return {
18
+ ...term,
19
+ name: unescapeString( term.name ),
20
+ };
21
+ };
22
+
23
+ const EMPTY_ARRAY = [];
24
+ const MAX_TERMS_SUGGESTIONS = 20;
25
+ const DEFAULT_QUERY = {
26
+ per_page: MAX_TERMS_SUGGESTIONS,
27
+ _fields: 'id,name',
28
+ context: 'view',
29
+ };
30
+ const slug = 'wp_pattern_category';
31
+
32
+ export default function CategorySelector( { onCategorySelection } ) {
33
+ const [ values, setValues ] = useState( [] );
34
+ const [ search, setSearch ] = useState( '' );
35
+ const debouncedSearch = useDebounce( setSearch, 500 );
36
+ const { invalidateResolution } = useDispatch( coreStore );
37
+
38
+ const { searchResults } = useSelect(
39
+ ( select ) => {
40
+ const { getEntityRecords } = select( coreStore );
41
+
42
+ return {
43
+ searchResults: !! search
44
+ ? getEntityRecords( 'taxonomy', slug, {
45
+ ...DEFAULT_QUERY,
46
+ search,
47
+ } )
48
+ : EMPTY_ARRAY,
49
+ };
50
+ },
51
+ [ search ]
52
+ );
53
+
54
+ const suggestions = useMemo( () => {
55
+ return ( searchResults ?? [] ).map( ( term ) =>
56
+ unescapeString( term.name )
57
+ );
58
+ }, [ searchResults ] );
59
+
60
+ const { saveEntityRecord } = useDispatch( coreStore );
61
+
62
+ async function findOrCreateTerm( term ) {
63
+ try {
64
+ const newTerm = await saveEntityRecord( 'taxonomy', slug, term, {
65
+ throwOnError: true,
66
+ } );
67
+ invalidateResolution( 'getUserPatternCategories' );
68
+ return unescapeTerm( newTerm );
69
+ } catch ( error ) {
70
+ if ( error.code !== 'term_exists' ) {
71
+ throw error;
72
+ }
73
+
74
+ return {
75
+ id: error.data.term_id,
76
+ name: term.name,
77
+ };
78
+ }
79
+ }
80
+
81
+ function onChange( termNames ) {
82
+ const uniqueTerms = termNames.reduce( ( terms, newTerm ) => {
83
+ if (
84
+ ! terms.some(
85
+ ( term ) => term.toLowerCase() === newTerm.toLowerCase()
86
+ )
87
+ ) {
88
+ terms.push( newTerm );
89
+ }
90
+ return terms;
91
+ }, [] );
92
+
93
+ setValues( uniqueTerms );
94
+
95
+ Promise.all(
96
+ uniqueTerms.map( ( termName ) =>
97
+ findOrCreateTerm( { name: termName } )
98
+ )
99
+ ).then( ( newTerms ) => {
100
+ onCategorySelection( newTerms );
101
+ } );
102
+ }
103
+
104
+ return (
105
+ <>
106
+ <FormTokenField
107
+ className="patterns-menu-items__convert-modal-categories"
108
+ value={ values }
109
+ suggestions={ suggestions }
110
+ onChange={ onChange }
111
+ onInputChange={ debouncedSearch }
112
+ maxSuggestions={ MAX_TERMS_SUGGESTIONS }
113
+ label={ __( 'Categories' ) }
114
+ tokenizeOnBlur={ true }
115
+ />
116
+ </>
117
+ );
118
+ }
@@ -10,56 +10,60 @@ import {
10
10
  ToggleControl,
11
11
  } from '@wordpress/components';
12
12
  import { __ } from '@wordpress/i18n';
13
- import { useState, useCallback } from '@wordpress/element';
13
+ import { useState } from '@wordpress/element';
14
14
  import { useDispatch } from '@wordpress/data';
15
15
  import { store as noticesStore } from '@wordpress/notices';
16
16
 
17
- export const USER_PATTERN_CATEGORY = 'my-patterns';
18
-
19
- export const SYNC_TYPES = {
20
- full: undefined,
21
- unsynced: 'unsynced',
22
- };
17
+ /**
18
+ * Internal dependencies
19
+ */
20
+ import { PATTERN_DEFAULT_CATEGORY, PATTERN_SYNC_TYPES } from '../constants';
23
21
 
24
22
  /**
25
23
  * Internal dependencies
26
24
  */
27
- import { store } from '../store';
25
+ import { store as patternsStore } from '../store';
26
+ import CategorySelector from './category-selector';
27
+ import { unlock } from '../lock-unlock';
28
28
 
29
29
  export default function CreatePatternModal( {
30
30
  onSuccess,
31
31
  onError,
32
- clientIds,
32
+ content,
33
33
  onClose,
34
34
  className = 'patterns-menu-items__convert-modal',
35
35
  } ) {
36
- const [ syncType, setSyncType ] = useState( SYNC_TYPES.full );
36
+ const [ syncType, setSyncType ] = useState( PATTERN_SYNC_TYPES.full );
37
+ const [ categories, setCategories ] = useState( [] );
37
38
  const [ title, setTitle ] = useState( '' );
38
- const { __experimentalCreatePattern: createPattern } = useDispatch( store );
39
+ const { createPattern } = unlock( useDispatch( patternsStore ) );
39
40
 
40
41
  const { createErrorNotice } = useDispatch( noticesStore );
41
- const onCreate = useCallback(
42
- async function ( patternTitle, sync ) {
43
- try {
44
- const newPattern = await createPattern(
45
- patternTitle,
46
- sync,
47
- clientIds
48
- );
49
- onSuccess( {
50
- pattern: newPattern,
51
- categoryId: USER_PATTERN_CATEGORY,
52
- } );
53
- } catch ( error ) {
54
- createErrorNotice( error.message, {
55
- type: 'snackbar',
56
- id: 'convert-to-pattern-error',
57
- } );
58
- onError();
59
- }
60
- },
61
- [ createPattern, clientIds, onSuccess, createErrorNotice, onError ]
62
- );
42
+ async function onCreate( patternTitle, sync ) {
43
+ try {
44
+ const newPattern = await createPattern(
45
+ patternTitle,
46
+ sync,
47
+ typeof content === 'function' ? content() : content,
48
+ categories
49
+ );
50
+ onSuccess( {
51
+ pattern: newPattern,
52
+ categoryId: PATTERN_DEFAULT_CATEGORY,
53
+ } );
54
+ } catch ( error ) {
55
+ createErrorNotice( error.message, {
56
+ type: 'snackbar',
57
+ id: 'convert-to-pattern-error',
58
+ } );
59
+ onError();
60
+ }
61
+ }
62
+
63
+ const handleCategorySelection = ( selectedCategories ) => {
64
+ setCategories( selectedCategories.map( ( cat ) => cat.id ) );
65
+ };
66
+
63
67
  return (
64
68
  <Modal
65
69
  title={ __( 'Create pattern' ) }
@@ -83,19 +87,22 @@ export default function CreatePatternModal( {
83
87
  value={ title }
84
88
  onChange={ setTitle }
85
89
  placeholder={ __( 'My pattern' ) }
90
+ className="patterns-create-modal__name-input"
91
+ />
92
+ <CategorySelector
93
+ onCategorySelection={ handleCategorySelection }
86
94
  />
87
-
88
95
  <ToggleControl
89
96
  label={ __( 'Synced' ) }
90
97
  help={ __(
91
98
  'Editing the pattern will update it anywhere it is used.'
92
99
  ) }
93
- checked={ ! syncType }
100
+ checked={ syncType === PATTERN_SYNC_TYPES.full }
94
101
  onChange={ () => {
95
102
  setSyncType(
96
- syncType === SYNC_TYPES.full
97
- ? SYNC_TYPES.unsynced
98
- : SYNC_TYPES.full
103
+ syncType === PATTERN_SYNC_TYPES.full
104
+ ? PATTERN_SYNC_TYPES.unsynced
105
+ : PATTERN_SYNC_TYPES.full
99
106
  );
100
107
  } }
101
108
  />