@wordpress/block-library 7.0.0 → 7.0.2

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 (230) hide show
  1. package/README.md +16 -0
  2. package/build/button/edit.native.js +2 -2
  3. package/build/button/edit.native.js.map +1 -1
  4. package/build/columns/index.js +12 -0
  5. package/build/columns/index.js.map +1 -1
  6. package/build/comment-author-avatar/edit.js +17 -4
  7. package/build/comment-author-avatar/edit.js.map +1 -1
  8. package/build/comment-template/edit.js +94 -36
  9. package/build/comment-template/edit.js.map +1 -1
  10. package/build/comment-template/hooks.js +175 -0
  11. package/build/comment-template/hooks.js.map +1 -0
  12. package/build/comment-template/index.js +1 -1
  13. package/build/comment-template/util.js.map +1 -1
  14. package/build/comments-pagination-next/index.js +1 -1
  15. package/build/comments-pagination-numbers/index.js +1 -1
  16. package/build/comments-query-loop/edit/comments-inspector-controls.js +20 -9
  17. package/build/comments-query-loop/edit/comments-inspector-controls.js.map +1 -1
  18. package/build/comments-query-loop/edit.js +1 -19
  19. package/build/comments-query-loop/edit.js.map +1 -1
  20. package/build/comments-query-loop/index.js +5 -0
  21. package/build/comments-query-loop/index.js.map +1 -1
  22. package/build/cover/edit.js +21 -22
  23. package/build/cover/edit.js.map +1 -1
  24. package/build/cover/edit.native.js +7 -5
  25. package/build/cover/edit.native.js.map +1 -1
  26. package/build/cover/overlay-color-settings.native.js +4 -3
  27. package/build/cover/overlay-color-settings.native.js.map +1 -1
  28. package/build/cover/transforms.js +4 -2
  29. package/build/cover/transforms.js.map +1 -1
  30. package/build/group/index.js +1 -0
  31. package/build/group/index.js.map +1 -1
  32. package/build/heading/edit.js +14 -2
  33. package/build/heading/edit.js.map +1 -1
  34. package/build/image/deprecated.js +89 -5
  35. package/build/image/deprecated.js.map +1 -1
  36. package/build/image/save.js +0 -7
  37. package/build/image/save.js.map +1 -1
  38. package/build/latest-posts/edit.js +1 -0
  39. package/build/latest-posts/edit.js.map +1 -1
  40. package/build/navigation/edit/index.js +17 -15
  41. package/build/navigation/edit/index.js.map +1 -1
  42. package/build/navigation/edit/navigation-menu-selector.js +44 -27
  43. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  44. package/build/navigation/edit/placeholder/index.js +8 -22
  45. package/build/navigation/edit/placeholder/index.js.map +1 -1
  46. package/build/navigation/use-navigation-menu.js +6 -6
  47. package/build/navigation/use-navigation-menu.js.map +1 -1
  48. package/build/navigation-submenu/edit.js +41 -9
  49. package/build/navigation-submenu/edit.js.map +1 -1
  50. package/build/page-list/edit.js +11 -17
  51. package/build/page-list/edit.js.map +1 -1
  52. package/build/social-links/deprecated.js +1 -62
  53. package/build/social-links/deprecated.js.map +1 -1
  54. package/build/template-part/edit/index.js +36 -64
  55. package/build/template-part/edit/index.js.map +1 -1
  56. package/build/template-part/edit/placeholder.js +64 -0
  57. package/build/template-part/edit/placeholder.js.map +1 -0
  58. package/build/template-part/edit/selection-modal.js +103 -0
  59. package/build/template-part/edit/selection-modal.js.map +1 -0
  60. package/build/template-part/edit/title-modal.js +54 -0
  61. package/build/template-part/edit/title-modal.js.map +1 -0
  62. package/build/template-part/edit/utils/hooks.js +156 -0
  63. package/build/template-part/edit/utils/hooks.js.map +1 -0
  64. package/build/template-part/index.js +3 -1
  65. package/build/template-part/index.js.map +1 -1
  66. package/build-module/button/edit.native.js +4 -4
  67. package/build-module/button/edit.native.js.map +1 -1
  68. package/build-module/columns/index.js +12 -0
  69. package/build-module/columns/index.js.map +1 -1
  70. package/build-module/comment-author-avatar/edit.js +18 -6
  71. package/build-module/comment-author-avatar/edit.js.map +1 -1
  72. package/build-module/comment-template/edit.js +95 -37
  73. package/build-module/comment-template/edit.js.map +1 -1
  74. package/build-module/comment-template/hooks.js +156 -0
  75. package/build-module/comment-template/hooks.js.map +1 -0
  76. package/build-module/comment-template/index.js +1 -1
  77. package/build-module/comment-template/util.js.map +1 -1
  78. package/build-module/comments-pagination-next/index.js +1 -1
  79. package/build-module/comments-pagination-numbers/index.js +1 -1
  80. package/build-module/comments-query-loop/edit/comments-inspector-controls.js +20 -9
  81. package/build-module/comments-query-loop/edit/comments-inspector-controls.js.map +1 -1
  82. package/build-module/comments-query-loop/edit.js +2 -19
  83. package/build-module/comments-query-loop/edit.js.map +1 -1
  84. package/build-module/comments-query-loop/index.js +5 -0
  85. package/build-module/comments-query-loop/index.js.map +1 -1
  86. package/build-module/cover/edit.js +23 -24
  87. package/build-module/cover/edit.js.map +1 -1
  88. package/build-module/cover/edit.native.js +10 -8
  89. package/build-module/cover/edit.native.js.map +1 -1
  90. package/build-module/cover/overlay-color-settings.native.js +4 -4
  91. package/build-module/cover/overlay-color-settings.native.js.map +1 -1
  92. package/build-module/cover/transforms.js +4 -2
  93. package/build-module/cover/transforms.js.map +1 -1
  94. package/build-module/group/index.js +1 -0
  95. package/build-module/group/index.js.map +1 -1
  96. package/build-module/heading/edit.js +15 -3
  97. package/build-module/heading/edit.js.map +1 -1
  98. package/build-module/image/deprecated.js +90 -7
  99. package/build-module/image/deprecated.js.map +1 -1
  100. package/build-module/image/save.js +0 -7
  101. package/build-module/image/save.js.map +1 -1
  102. package/build-module/latest-posts/edit.js +1 -0
  103. package/build-module/latest-posts/edit.js.map +1 -1
  104. package/build-module/navigation/edit/index.js +17 -15
  105. package/build-module/navigation/edit/index.js.map +1 -1
  106. package/build-module/navigation/edit/navigation-menu-selector.js +45 -27
  107. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  108. package/build-module/navigation/edit/placeholder/index.js +8 -21
  109. package/build-module/navigation/edit/placeholder/index.js.map +1 -1
  110. package/build-module/navigation/use-navigation-menu.js +6 -6
  111. package/build-module/navigation/use-navigation-menu.js.map +1 -1
  112. package/build-module/navigation-submenu/edit.js +41 -10
  113. package/build-module/navigation-submenu/edit.js.map +1 -1
  114. package/build-module/page-list/edit.js +12 -18
  115. package/build-module/page-list/edit.js.map +1 -1
  116. package/build-module/social-links/deprecated.js +1 -62
  117. package/build-module/social-links/deprecated.js.map +1 -1
  118. package/build-module/template-part/edit/index.js +37 -65
  119. package/build-module/template-part/edit/index.js.map +1 -1
  120. package/build-module/template-part/edit/placeholder.js +52 -0
  121. package/build-module/template-part/edit/placeholder.js.map +1 -0
  122. package/build-module/template-part/edit/selection-modal.js +89 -0
  123. package/build-module/template-part/edit/selection-modal.js.map +1 -0
  124. package/build-module/template-part/edit/title-modal.js +46 -0
  125. package/build-module/template-part/edit/title-modal.js.map +1 -0
  126. package/build-module/template-part/edit/utils/hooks.js +135 -0
  127. package/build-module/template-part/edit/utils/hooks.js.map +1 -0
  128. package/build-module/template-part/index.js +2 -1
  129. package/build-module/template-part/index.js.map +1 -1
  130. package/build-style/comment-author-avatar/editor-rtl.css +83 -0
  131. package/build-style/comment-author-avatar/editor.css +83 -0
  132. package/build-style/cover/style-rtl.css +4 -0
  133. package/build-style/cover/style.css +4 -0
  134. package/build-style/editor-rtl.css +27 -81
  135. package/build-style/editor.css +27 -81
  136. package/build-style/image/editor-rtl.css +0 -16
  137. package/build-style/image/editor.css +0 -16
  138. package/build-style/image/style-rtl.css +2 -0
  139. package/build-style/image/style.css +2 -0
  140. package/build-style/navigation/style-rtl.css +14 -3
  141. package/build-style/navigation/style.css +14 -3
  142. package/build-style/page-list/editor-rtl.css +0 -9
  143. package/build-style/page-list/editor.css +0 -9
  144. package/build-style/style-rtl.css +20 -3
  145. package/build-style/style.css +20 -3
  146. package/build-style/template-part/editor-rtl.css +19 -56
  147. package/build-style/template-part/editor.css +19 -56
  148. package/package.json +15 -15
  149. package/src/archives/index.php +1 -1
  150. package/src/button/edit.native.js +3 -3
  151. package/src/columns/block.json +12 -0
  152. package/src/comment-author-avatar/edit.js +13 -8
  153. package/src/comment-author-avatar/editor.scss +7 -0
  154. package/src/comment-template/block.json +7 -1
  155. package/src/comment-template/edit.js +102 -40
  156. package/src/comment-template/hooks.js +151 -0
  157. package/src/comment-template/index.php +8 -0
  158. package/src/comment-template/util.js +1 -0
  159. package/src/comments-pagination-next/block.json +8 -1
  160. package/src/comments-pagination-next/index.php +6 -8
  161. package/src/comments-pagination-numbers/block.json +7 -1
  162. package/src/comments-pagination-numbers/index.php +3 -10
  163. package/src/comments-query-loop/block.json +5 -0
  164. package/src/comments-query-loop/edit/comments-inspector-controls.js +22 -4
  165. package/src/comments-query-loop/edit.js +1 -16
  166. package/src/cover/edit.js +15 -28
  167. package/src/cover/edit.native.js +15 -7
  168. package/src/cover/overlay-color-settings.native.js +3 -4
  169. package/src/cover/style.scss +4 -0
  170. package/src/cover/transforms.js +2 -0
  171. package/src/editor.scss +1 -0
  172. package/src/gallery/index.php +1 -8
  173. package/src/group/block.json +1 -0
  174. package/src/heading/edit.js +18 -5
  175. package/src/home-link/index.php +1 -19
  176. package/src/image/deprecated.js +105 -1
  177. package/src/image/editor.scss +0 -18
  178. package/src/image/save.js +0 -8
  179. package/src/image/style.scss +3 -0
  180. package/src/image/test/edit.native.js +0 -10
  181. package/src/latest-posts/edit.js +1 -0
  182. package/src/latest-posts/index.php +1 -1
  183. package/src/navigation/edit/index.js +25 -26
  184. package/src/navigation/edit/navigation-menu-selector.js +73 -28
  185. package/src/navigation/edit/placeholder/index.js +8 -32
  186. package/src/navigation/index.php +4 -4
  187. package/src/navigation/style.scss +22 -3
  188. package/src/navigation/use-navigation-menu.js +6 -6
  189. package/src/navigation-link/index.php +3 -22
  190. package/src/navigation-submenu/edit.js +50 -12
  191. package/src/navigation-submenu/index.php +3 -21
  192. package/src/page-list/edit.js +21 -25
  193. package/src/page-list/editor.scss +0 -10
  194. package/src/page-list/index.php +4 -4
  195. package/src/post-navigation-link/index.php +3 -3
  196. package/src/search/index.php +6 -3
  197. package/src/site-logo/index.php +1 -1
  198. package/src/social-links/deprecated.js +0 -59
  199. package/src/template-part/edit/index.js +61 -71
  200. package/src/template-part/edit/placeholder.js +78 -0
  201. package/src/template-part/edit/selection-modal.js +115 -0
  202. package/src/template-part/edit/title-modal.js +59 -0
  203. package/src/template-part/edit/utils/hooks.js +158 -0
  204. package/src/template-part/editor.scss +16 -74
  205. package/src/template-part/index.js +4 -1
  206. package/build/navigation/edit/existing-menus-options.js +0 -62
  207. package/build/navigation/edit/existing-menus-options.js.map +0 -1
  208. package/build/template-part/edit/placeholder/index.js +0 -141
  209. package/build/template-part/edit/placeholder/index.js.map +0 -1
  210. package/build/template-part/edit/placeholder/patterns-setup.js +0 -100
  211. package/build/template-part/edit/placeholder/patterns-setup.js.map +0 -1
  212. package/build/template-part/edit/selection/index.js +0 -45
  213. package/build/template-part/edit/selection/index.js.map +0 -1
  214. package/build/template-part/edit/selection/template-part-previews.js +0 -317
  215. package/build/template-part/edit/selection/template-part-previews.js.map +0 -1
  216. package/build-module/navigation/edit/existing-menus-options.js +0 -53
  217. package/build-module/navigation/edit/existing-menus-options.js.map +0 -1
  218. package/build-module/template-part/edit/placeholder/index.js +0 -124
  219. package/build-module/template-part/edit/placeholder/index.js.map +0 -1
  220. package/build-module/template-part/edit/placeholder/patterns-setup.js +0 -91
  221. package/build-module/template-part/edit/placeholder/patterns-setup.js.map +0 -1
  222. package/build-module/template-part/edit/selection/index.js +0 -35
  223. package/build-module/template-part/edit/selection/index.js.map +0 -1
  224. package/build-module/template-part/edit/selection/template-part-previews.js +0 -298
  225. package/build-module/template-part/edit/selection/template-part-previews.js.map +0 -1
  226. package/src/navigation/edit/existing-menus-options.js +0 -70
  227. package/src/template-part/edit/placeholder/index.js +0 -172
  228. package/src/template-part/edit/placeholder/patterns-setup.js +0 -124
  229. package/src/template-part/edit/selection/index.js +0 -37
  230. package/src/template-part/edit/selection/template-part-previews.js +0 -372
@@ -1,172 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { find, kebabCase } from 'lodash';
5
-
6
- /**
7
- * WordPress dependencies
8
- */
9
- import { __, sprintf } from '@wordpress/i18n';
10
- import { useCallback, useState } from '@wordpress/element';
11
- import { useDispatch, useSelect } from '@wordpress/data';
12
- import { Placeholder, Dropdown, Button, Spinner } from '@wordpress/components';
13
- import { serialize } from '@wordpress/blocks';
14
- import { store as coreStore } from '@wordpress/core-data';
15
-
16
- /**
17
- * Internal dependencies
18
- */
19
- import TemplatePartSelection from '../selection';
20
- import PatternsSetup from './patterns-setup';
21
-
22
- const PLACEHOLDER_STEPS = {
23
- initial: 1,
24
- patterns: 2,
25
- };
26
-
27
- export default function TemplatePartPlaceholder( {
28
- area,
29
- clientId,
30
- setAttributes,
31
- enableSelection,
32
- hasResolvedReplacements,
33
- } ) {
34
- const { saveEntityRecord } = useDispatch( coreStore );
35
- const [ step, setStep ] = useState( PLACEHOLDER_STEPS.initial );
36
-
37
- const { areaIcon, areaLabel } = useSelect(
38
- ( select ) => {
39
- // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
40
- // Blocks can be loaded into a *non-post* block editor.
41
- // eslint-disable-next-line @wordpress/data-no-store-string-literals
42
- const definedAreas = select(
43
- 'core/editor'
44
- ).__experimentalGetDefaultTemplatePartAreas();
45
-
46
- const selectedArea = find( definedAreas, { area } );
47
- const defaultArea = find( definedAreas, { area: 'uncategorized' } );
48
-
49
- return {
50
- areaIcon: selectedArea?.icon || defaultArea?.icon,
51
- areaLabel: selectedArea?.label || __( 'Template Part' ),
52
- };
53
- },
54
- [ area ]
55
- );
56
-
57
- const onCreate = useCallback(
58
- async (
59
- startingBlocks = [],
60
- title = __( 'Untitled Template Part' )
61
- ) => {
62
- // If we have `area` set from block attributes, means an exposed
63
- // block variation was inserted. So add this prop to the template
64
- // part entity on creation. Afterwards remove `area` value from
65
- // block attributes.
66
- const record = {
67
- title,
68
- slug: kebabCase( title ),
69
- content: serialize( startingBlocks ),
70
- // `area` is filterable on the server and defaults to `UNCATEGORIZED`
71
- // if provided value is not allowed.
72
- area,
73
- };
74
- const templatePart = await saveEntityRecord(
75
- 'postType',
76
- 'wp_template_part',
77
- record
78
- );
79
- setAttributes( {
80
- slug: templatePart.slug,
81
- theme: templatePart.theme,
82
- area: undefined,
83
- } );
84
- },
85
- [ setAttributes, area ]
86
- );
87
-
88
- return (
89
- <>
90
- { step === PLACEHOLDER_STEPS.initial && (
91
- <Placeholder
92
- icon={ areaIcon }
93
- label={ areaLabel }
94
- instructions={
95
- enableSelection
96
- ? sprintf(
97
- // Translators: %s as template part area title ("Header", "Footer", etc.).
98
- __(
99
- 'Choose an existing %s or create a new one.'
100
- ),
101
- areaLabel.toLowerCase()
102
- )
103
- : sprintf(
104
- // Translators: %s as template part area title ("Header", "Footer", etc.).
105
- __( 'Create a new %s.' ),
106
- areaLabel.toLowerCase()
107
- )
108
- }
109
- >
110
- { ! hasResolvedReplacements ? (
111
- <Spinner />
112
- ) : (
113
- <Dropdown
114
- contentClassName="wp-block-template-part__placeholder-preview-dropdown-content"
115
- position="bottom right left"
116
- renderToggle={ ( { isOpen, onToggle } ) => (
117
- <>
118
- { enableSelection && (
119
- <Button
120
- variant="primary"
121
- onClick={ onToggle }
122
- aria-expanded={ isOpen }
123
- >
124
- { __( 'Choose existing' ) }
125
- </Button>
126
- ) }
127
- <Button
128
- variant={
129
- enableSelection
130
- ? 'tertiary'
131
- : 'primary'
132
- }
133
- onClick={ () =>
134
- setStep(
135
- PLACEHOLDER_STEPS.patterns
136
- )
137
- }
138
- >
139
- { sprintf(
140
- // Translators: %s as template part area title ("Header", "Footer", etc.).
141
- __( 'New %s' ),
142
- areaLabel.toLowerCase()
143
- ) }
144
- </Button>
145
- </>
146
- ) }
147
- renderContent={ ( { onClose } ) => (
148
- <TemplatePartSelection
149
- setAttributes={ setAttributes }
150
- onClose={ onClose }
151
- area={ area }
152
- />
153
- ) }
154
- />
155
- ) }
156
- </Placeholder>
157
- ) }
158
- { step === PLACEHOLDER_STEPS.patterns && (
159
- <PatternsSetup
160
- area={ area }
161
- areaLabel={ areaLabel }
162
- areaIcon={ areaIcon }
163
- onCreate={ onCreate }
164
- clientId={ clientId }
165
- resetPlaceholder={ () =>
166
- setStep( PLACEHOLDER_STEPS.initial )
167
- }
168
- />
169
- ) }
170
- </>
171
- );
172
- }
@@ -1,124 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { __experimentalBlockPatternSetup as BlockPatternSetup } from '@wordpress/block-editor';
5
- import { useEffect, useState } from '@wordpress/element';
6
- import { __, sprintf } from '@wordpress/i18n';
7
- import {
8
- TextControl,
9
- Flex,
10
- FlexItem,
11
- Button,
12
- Modal,
13
- Placeholder,
14
- } from '@wordpress/components';
15
-
16
- export default function PatternsSetup( {
17
- area,
18
- areaLabel,
19
- areaIcon,
20
- clientId,
21
- onCreate,
22
- resetPlaceholder,
23
- } ) {
24
- const blockNameWithArea = area
25
- ? `core/template-part/${ area }`
26
- : 'core/template-part';
27
-
28
- // Restructure onCreate to set the blocks on local state.
29
- // Add modal to confirm title and trigger onCreate.
30
- const [ title, setTitle ] = useState( __( 'Untitled Template Part' ) );
31
- const [ startingBlocks, setStartingBlocks ] = useState( [] );
32
- const [ isTitleStep, setIsTitleStep ] = useState( false );
33
-
34
- const selectPattern = ( selectedPattern ) => {
35
- setStartingBlocks( selectedPattern );
36
- setIsTitleStep( true );
37
- };
38
-
39
- const submitForCreation = ( event ) => {
40
- event.preventDefault();
41
- onCreate( startingBlocks, title );
42
- };
43
-
44
- return (
45
- <>
46
- <BlockPatternSetup
47
- clientId={ clientId }
48
- startBlankComponent={
49
- <StartBlankComponent
50
- setTitleStep={ setIsTitleStep }
51
- areaLabel={ areaLabel }
52
- areaIcon={ areaIcon }
53
- />
54
- }
55
- onBlockPatternSelect={ selectPattern }
56
- filterPatternsFn={ ( pattern ) =>
57
- pattern?.blockTypes?.some?.(
58
- ( blockType ) => blockType === blockNameWithArea
59
- )
60
- }
61
- />
62
- { isTitleStep && (
63
- <Modal
64
- title={ sprintf(
65
- // Translators: %s as template part area title ("Header", "Footer", etc.).
66
- __( 'Name and create your new %s' ),
67
- areaLabel.toLowerCase()
68
- ) }
69
- closeLabel={ __( 'Cancel' ) }
70
- onRequestClose={ resetPlaceholder }
71
- overlayClassName="wp-block-template-part__placeholder-create-new__title-form"
72
- >
73
- <form onSubmit={ submitForCreation }>
74
- <TextControl
75
- label={ __( 'Name' ) }
76
- value={ title }
77
- onChange={ setTitle }
78
- />
79
- <Flex
80
- className="wp-block-template-part__placeholder-create-new__title-form-actions"
81
- justify="flex-end"
82
- >
83
- <FlexItem>
84
- <Button
85
- variant="secondary"
86
- onClick={ resetPlaceholder }
87
- >
88
- { __( 'Cancel' ) }
89
- </Button>
90
- </FlexItem>
91
- <FlexItem>
92
- <Button
93
- variant="primary"
94
- type="submit"
95
- disabled={ ! title.length }
96
- aria-disabled={ ! title.length }
97
- >
98
- { __( 'Create' ) }
99
- </Button>
100
- </FlexItem>
101
- </Flex>
102
- </form>
103
- </Modal>
104
- ) }
105
- </>
106
- );
107
- }
108
-
109
- function StartBlankComponent( { setTitleStep, areaLabel, areaIcon } ) {
110
- useEffect( () => {
111
- setTitleStep( true );
112
- }, [] );
113
- return (
114
- <Placeholder
115
- label={ areaLabel }
116
- icon={ areaIcon }
117
- instructions={ sprintf(
118
- // Translators: %s as template part area title ("Header", "Footer", "Template Part", etc.).
119
- __( 'Creating your new %s…' ),
120
- areaLabel.toLowerCase()
121
- ) }
122
- />
123
- );
124
- }
@@ -1,37 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { SearchControl } from '@wordpress/components';
5
- import { useState } from '@wordpress/element';
6
-
7
- /**
8
- * Internal dependencies
9
- */
10
- import TemplatePartPreviews from './template-part-previews';
11
-
12
- export default function TemplatePartSelection( {
13
- setAttributes,
14
- onClose,
15
- area,
16
- templatePartId = null,
17
- } ) {
18
- const [ filterValue, setFilterValue ] = useState( '' );
19
- return (
20
- <div>
21
- <SearchControl
22
- value={ filterValue }
23
- onChange={ setFilterValue }
24
- className="wp-block-template-part__selection-preview-search-form"
25
- />
26
- <div className="wp-block-template-part__selection-preview-container">
27
- <TemplatePartPreviews
28
- setAttributes={ setAttributes }
29
- filterValue={ filterValue }
30
- onClose={ onClose }
31
- area={ area }
32
- templatePartId={ templatePartId }
33
- />
34
- </div>
35
- </div>
36
- );
37
- }
@@ -1,372 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { groupBy, deburr, flatten } from 'lodash';
5
-
6
- /**
7
- * WordPress dependencies
8
- */
9
- import { useSelect, useDispatch } from '@wordpress/data';
10
- import { parse } from '@wordpress/blocks';
11
- import { useMemo, useCallback } from '@wordpress/element';
12
- import { ENTER, SPACE } from '@wordpress/keycodes';
13
- import { __, sprintf } from '@wordpress/i18n';
14
- import { BlockPreview } from '@wordpress/block-editor';
15
- import {
16
- __unstableComposite as Composite,
17
- __unstableCompositeItem as CompositeItem,
18
- Icon,
19
- __unstableUseCompositeState as useCompositeState,
20
- } from '@wordpress/components';
21
- import { useAsyncList } from '@wordpress/compose';
22
- import { store as noticesStore } from '@wordpress/notices';
23
- import { store as coreStore } from '@wordpress/core-data';
24
-
25
- /**
26
- * Internal dependencies
27
- */
28
- import { createTemplatePartId } from '../utils/create-template-part-id';
29
-
30
- function getAreaGroupTitle( areaLabel ) {
31
- return sprintf(
32
- // Translators: %s for the area the template part is assigned to (Header, Footer, General, etc.)
33
- __( 'Area: %s' ),
34
- areaLabel
35
- );
36
- }
37
- function PreviewPlaceholder() {
38
- return (
39
- <div
40
- className="wp-block-template-part__selection-preview-item is-placeholder"
41
- tabIndex={ 0 }
42
- />
43
- );
44
- }
45
-
46
- function TemplatePartItem( {
47
- templatePart,
48
- setAttributes,
49
- onClose,
50
- composite,
51
- } ) {
52
- const {
53
- slug,
54
- theme,
55
- title: { rendered: title },
56
- } = templatePart;
57
- // The 'raw' property is not defined for a brief period in the save cycle.
58
- // The fallback prevents an error in the parse function while saving.
59
- const content = templatePart.content.raw || '';
60
- const blocks = useMemo( () => parse( content ), [ content ] );
61
- const { createSuccessNotice } = useDispatch( noticesStore );
62
-
63
- const onClick = useCallback( () => {
64
- setAttributes( { slug, theme, area: undefined } );
65
- createSuccessNotice(
66
- sprintf(
67
- /* translators: %s: template part title. */
68
- __( 'Template Part "%s" inserted.' ),
69
- title || slug
70
- ),
71
- {
72
- type: 'snackbar',
73
- }
74
- );
75
- onClose();
76
- }, [ slug, theme ] );
77
-
78
- return (
79
- <CompositeItem
80
- as="div"
81
- className="wp-block-template-part__selection-preview-item"
82
- role="option"
83
- onClick={ onClick }
84
- onKeyDown={ ( event ) => {
85
- if ( ENTER === event.keyCode || SPACE === event.keyCode ) {
86
- onClick();
87
- }
88
- } }
89
- tabIndex={ 0 }
90
- aria-label={ title || slug }
91
- { ...composite }
92
- >
93
- <BlockPreview blocks={ blocks } />
94
- <div className="wp-block-template-part__selection-preview-item-title">
95
- { title || slug }
96
- </div>
97
- </CompositeItem>
98
- );
99
- }
100
-
101
- function PanelGroup( { title, icon, children } ) {
102
- return (
103
- <>
104
- <div className="wp-block-template-part__selection-panel-group-header">
105
- <span className="wp-block-template-part__selection-panel-group-title">
106
- { title }
107
- </span>
108
- <Icon icon={ icon } />
109
- </div>
110
- <div className="wp-block-template-part__selection-panel-group-content">
111
- { children }
112
- </div>
113
- </>
114
- );
115
- }
116
-
117
- function TemplatePartsByArea( {
118
- templateParts,
119
- setAttributes,
120
- onClose,
121
- composite,
122
- area = 'uncategorized',
123
- labelsByArea,
124
- } ) {
125
- const { templatePartsByArea, templatePartsToShow } = useMemo( () => {
126
- const _templatePartsToShow =
127
- templateParts.filter(
128
- ( templatePart ) =>
129
- 'uncategorized' === area || templatePart.area === area
130
- ) || [];
131
- const _templatePartsByArea = Object.values(
132
- groupBy( _templatePartsToShow, 'area' )
133
- );
134
- const orderedTemplatePartsToShow = flatten( _templatePartsToShow );
135
- return {
136
- templatePartsByArea: _templatePartsByArea,
137
- templatePartsToShow: orderedTemplatePartsToShow,
138
- };
139
- }, [ templateParts, area ] );
140
-
141
- const currentShownTPs = useAsyncList( templatePartsToShow );
142
-
143
- if ( ! templatePartsToShow.length ) {
144
- return (
145
- <PanelGroup
146
- title={ getAreaGroupTitle(
147
- labelsByArea[ area ] || labelsByArea.uncategorized
148
- ) }
149
- >
150
- { sprintf(
151
- // Translators: %s for the template part variation ("Header", "Footer", "Template Part").
152
- __(
153
- 'There is no other %s available. If you are looking for another type of template part, try searching for it using the input above.'
154
- ),
155
- area && area !== 'uncategorized'
156
- ? labelsByArea[ area ] || area
157
- : __( 'Template Part' )
158
- ) }
159
- </PanelGroup>
160
- );
161
- }
162
-
163
- return templatePartsByArea.map( ( templatePartList ) => {
164
- return (
165
- <PanelGroup
166
- key={ templatePartList[ 0 ].area }
167
- title={ getAreaGroupTitle(
168
- labelsByArea[ templatePartList[ 0 ].area ] ||
169
- labelsByArea.uncategorized
170
- ) }
171
- >
172
- { templatePartList.map( ( templatePart ) => {
173
- return currentShownTPs.includes( templatePart ) ? (
174
- <TemplatePartItem
175
- key={ templatePart.id }
176
- templatePart={ templatePart }
177
- setAttributes={ setAttributes }
178
- onClose={ onClose }
179
- composite={ composite }
180
- />
181
- ) : (
182
- <PreviewPlaceholder key={ templatePart.id } />
183
- );
184
- } ) }
185
- </PanelGroup>
186
- );
187
- } );
188
- }
189
-
190
- function TemplatePartSearchResults( {
191
- templateParts,
192
- setAttributes,
193
- filterValue,
194
- onClose,
195
- composite,
196
- labelsByArea,
197
- } ) {
198
- const { filteredTPs, groupedResults } = useMemo( () => {
199
- // Filter based on value.
200
- // Remove diacritics and convert to lowercase to normalize.
201
- const normalizedFilterValue = deburr( filterValue ).toLowerCase();
202
- const searchResults = templateParts.filter(
203
- ( { title: { rendered: title }, area } ) =>
204
- deburr( title )
205
- .toLowerCase()
206
- .includes( normalizedFilterValue ) ||
207
- // Since diacritics can be used in theme names, remove them for the comparison.
208
- deburr( labelsByArea[ area ] )
209
- .toLowerCase()
210
- .includes( normalizedFilterValue )
211
- );
212
- // Order based on value location.
213
- searchResults.sort( ( a, b ) => {
214
- // First prioritize index found in title.
215
- // Deburr for diacritics.
216
- const indexInTitleA = deburr( a.title.rendered )
217
- .toLowerCase()
218
- .indexOf( normalizedFilterValue );
219
- const indexInTitleB = deburr( b.title.rendered )
220
- .toLowerCase()
221
- .indexOf( normalizedFilterValue );
222
- if ( indexInTitleA !== -1 && indexInTitleB !== -1 ) {
223
- return indexInTitleA - indexInTitleB;
224
- } else if ( indexInTitleA !== -1 ) {
225
- return -1;
226
- } else if ( indexInTitleB !== -1 ) {
227
- return 1;
228
- }
229
- // Second prioritize index found in area.
230
- return (
231
- deburr( labelsByArea[ a.area ] )
232
- .toLowerCase()
233
- .indexOf( normalizedFilterValue ) -
234
- deburr( labelsByArea[ b.area ] )
235
- .toLowerCase()
236
- .indexOf( normalizedFilterValue )
237
- );
238
- } );
239
- // Group filtered results together if their neighbors share the same area.
240
- // This helps not show redundant panel groups side by side in the results.
241
- const _groupedResults = [];
242
- for ( let i = 0; i < searchResults.length; i++ ) {
243
- if (
244
- i !== 0 &&
245
- searchResults[ i ].area === searchResults[ i - 1 ].area
246
- ) {
247
- _groupedResults[ _groupedResults.length - 1 ].push(
248
- searchResults[ i ]
249
- );
250
- } else {
251
- _groupedResults.push( [ searchResults[ i ] ] );
252
- }
253
- }
254
- return {
255
- filteredTPs: searchResults,
256
- groupedResults: _groupedResults,
257
- };
258
- }, [ filterValue, templateParts ] );
259
-
260
- const currentShownTPs = useAsyncList( filteredTPs );
261
-
262
- return groupedResults.map( ( group ) => (
263
- <PanelGroup
264
- key={ group[ 0 ].id }
265
- title={ getAreaGroupTitle(
266
- labelsByArea[ group[ 0 ].area ] || labelsByArea.uncategorized
267
- ) }
268
- >
269
- { group.map( ( templatePart ) =>
270
- currentShownTPs.includes( templatePart ) ? (
271
- <TemplatePartItem
272
- key={ templatePart.id }
273
- templatePart={ templatePart }
274
- setAttributes={ setAttributes }
275
- onClose={ onClose }
276
- composite={ composite }
277
- />
278
- ) : (
279
- <PreviewPlaceholder key={ templatePart.id } />
280
- )
281
- ) }
282
- </PanelGroup>
283
- ) );
284
- }
285
-
286
- export default function TemplatePartPreviews( {
287
- setAttributes,
288
- filterValue,
289
- onClose,
290
- area,
291
- templatePartId,
292
- } ) {
293
- const composite = useCompositeState();
294
-
295
- const { templateParts, labelsByArea } = useSelect( ( select ) => {
296
- const _templateParts = (
297
- select( coreStore ).getEntityRecords(
298
- 'postType',
299
- 'wp_template_part',
300
- {
301
- per_page: -1,
302
- }
303
- ) || []
304
- ).filter(
305
- ( templatePart ) =>
306
- createTemplatePartId(
307
- templatePart.theme,
308
- templatePart.slug
309
- ) !== templatePartId
310
- );
311
-
312
- // FIXME: @wordpress/block-library should not depend on @wordpress/editor.
313
- // Blocks can be loaded into a *non-post* block editor.
314
- // eslint-disable-next-line @wordpress/data-no-store-string-literals
315
- const definedAreas = select(
316
- 'core/editor'
317
- ).__experimentalGetDefaultTemplatePartAreas();
318
- const _labelsByArea = {};
319
- definedAreas.forEach( ( item ) => {
320
- _labelsByArea[ item.area ] = item.label;
321
- } );
322
-
323
- return {
324
- templateParts: _templateParts,
325
- labelsByArea: _labelsByArea,
326
- };
327
- }, [] );
328
-
329
- if ( ! templateParts || ! templateParts.length ) {
330
- return (
331
- <PanelGroup>
332
- { __( 'There are no existing template parts to select.' ) }
333
- </PanelGroup>
334
- );
335
- }
336
-
337
- if ( filterValue ) {
338
- return (
339
- <Composite
340
- { ...composite }
341
- role="listbox"
342
- aria-label={ __( 'List of template parts' ) }
343
- >
344
- <TemplatePartSearchResults
345
- templateParts={ templateParts }
346
- setAttributes={ setAttributes }
347
- filterValue={ filterValue }
348
- onClose={ onClose }
349
- composite={ composite }
350
- labelsByArea={ labelsByArea }
351
- />
352
- </Composite>
353
- );
354
- }
355
-
356
- return (
357
- <Composite
358
- { ...composite }
359
- role="listbox"
360
- aria-label={ __( 'List of template parts' ) }
361
- >
362
- <TemplatePartsByArea
363
- templateParts={ templateParts }
364
- setAttributes={ setAttributes }
365
- onClose={ onClose }
366
- composite={ composite }
367
- area={ area }
368
- labelsByArea={ labelsByArea }
369
- />
370
- </Composite>
371
- );
372
- }