1+ // @ts -ignore
12import { useBlockEditContext , store as blockEditorStore } from '@wordpress/block-editor' ;
23import { store as blocksStore } from '@wordpress/blocks' ;
34import { useSelect , dispatch } from '@wordpress/data' ;
@@ -25,14 +26,19 @@ import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
2526import { CSS } from '@dnd-kit/utilities' ;
2627import { DragHandle } from '../drag-handle' ;
2728
29+ /**
30+ * @typedef {object } IndexedItem
31+ * @property {string } id Identifier of the item
32+ */
33+
2834/**
2935 * The Sortable Item Component.
3036 *
3137 * @param {object } props React props
3238 * @param {Function } props.children Render prop to render the children.
3339 * @param {object } props.item The repeater item object.
34- * @param {Function } props.setItem A function to set state of a repeater item.
35- * @param {Function } props.removeItem A function to delete a repeater item.
40+ * @param {Function|null } props.setItem A function to set state of a repeater item.
41+ * @param {Function|null } props.removeItem A function to delete a repeater item.
3642 * @param {string } props.id A string identifier for a repeater item.
3743 * @returns {* } React JSX
3844 */
@@ -73,11 +79,11 @@ const SortableItem = ({ children, item = {}, setItem = null, removeItem = null,
7379 *
7480 * @param {object } props React props
7581 * @param {Function } props.children Render prop to render the children.
76- * @param {string } props.addButton render prop to customize the "Add item" button.
82+ * @param {Function|null } props.addButton render prop to customize the "Add item" button.
7783 * @param {boolean } props.allowReordering boolean to toggle reordering of Repeater items.
7884 * @param {Function } props.onChange callback function to update the block attribute.
79- * @param {Array } props.value array of Repeater items.
80- * @param {Array } props.defaultValue array of default Repeater items.
85+ * @param {Array<IndexedItem> } props.value array of Repeater items.
86+ * @param {Array<IndexedItem> } props.defaultValue array of default Repeater items.
8187 * @returns {* } React JSX
8288 */
8389export const AbstractRepeater = ( {
@@ -95,13 +101,24 @@ export const AbstractRepeater = ({
95101 } ) ,
96102 ) ;
97103
104+ /**
105+ * Handle drag event completion
106+ *
107+ * @param {import('@dnd-kit/core').DragEndEvent } event End of drag event
108+ */
98109 function handleDragEnd ( event ) {
99110 const { active, over } = event ;
100111
101- if ( active . id !== over . id ) {
112+ if ( active . id !== over ?. id ) {
113+ /**
114+ * Set of items to move.
115+ *
116+ * @param {Array<IndexedItem> } items Set of indexed items
117+ * @returns {Array<IndexedItem> } Changed set of items
118+ */
102119 const moveArray = ( items ) => {
103120 const oldIndex = items . findIndex ( ( item ) => item . id === active . id ) ;
104- const newIndex = items . findIndex ( ( item ) => item . id === over . id ) ;
121+ const newIndex = items . findIndex ( ( item ) => item . id === over ? .id ) ;
105122
106123 return arrayMove ( items , oldIndex , newIndex ) ;
107124 } ;
@@ -132,7 +149,7 @@ export const AbstractRepeater = ({
132149 /**
133150 * Updates the item currently being edited.
134151 *
135- * @param {string|number|boolean } newValue The value that should be used to updated the item.
152+ * @param {object| string|number|boolean } newValue The value that should be used to updated the item.
136153 * @param {number } index The index at which the item should be updated.
137154 */
138155 function setItem ( newValue , index ) {
@@ -158,6 +175,14 @@ export const AbstractRepeater = ({
158175 */
159176 function removeItem ( index ) {
160177 const valueCopy = JSON . parse ( JSON . stringify ( value ) ) . filter (
178+ /**
179+ * Filter out the item to remove.
180+ *
181+ * @param {IndexedItem } item Item to remove
182+ * @param {number } innerIndex Current index
183+ * @returns {boolean }
184+ */
185+ // @ts -ignore
161186 ( item , innerIndex ) => index !== innerIndex ,
162187 ) ;
163188 onChange ( valueCopy ) ;
@@ -179,19 +204,44 @@ export const AbstractRepeater = ({
179204 return (
180205 < SortableItem
181206 item = { item }
182- setItem = { ( val ) => setItem ( val , key ) }
207+ setItem = {
208+ /**
209+ * Add/update callback
210+ *
211+ * @param {object|string|number|boolean } val Value to set
212+ * @returns {void }
213+ */
214+ ( val ) => setItem ( val , key )
215+ }
183216 removeItem = { ( ) => removeItem ( key ) }
184217 key = { item . id }
185218 id = { item . id }
186219 >
187- { ( item , id , setItem , removeItem ) => {
188- return children (
189- item ,
190- id ,
191- ( val ) => setItem ( val , key ) ,
192- ( ) => removeItem ( key ) ,
193- ) ;
194- } }
220+ {
221+ /**
222+ * Mapped set of sortable items
223+ *
224+ * @param {IndexedItem } item Current Item
225+ * @param {string } id Current Item ID
226+ * @param {Function } setItem Callback to add/update an item
227+ * @param {Function } removeItem Callback to remove an item
228+ * @returns {* } React JSX
229+ */
230+ ( item , id , setItem , removeItem ) => {
231+ return children (
232+ item ,
233+ id ,
234+ /**
235+ * Add/update callback
236+ *
237+ * @param {object|string|number|boolean } val Value to set
238+ * @returns {void }
239+ */
240+ ( val ) => setItem ( val , key ) ,
241+ ( ) => removeItem ( key ) ,
242+ ) ;
243+ }
244+ }
195245 </ SortableItem >
196246 ) ;
197247 } ) }
@@ -202,6 +252,12 @@ export const AbstractRepeater = ({
202252 return children (
203253 item ,
204254 item . id ,
255+ /**
256+ * Add/update callback
257+ *
258+ * @param {object|string|number|boolean } val Value to set
259+ * @returns {void }
260+ */
205261 ( val ) => setItem ( val , key ) ,
206262 ( ) => removeItem ( key ) ,
207263 ) ;
@@ -218,6 +274,16 @@ export const AbstractRepeater = ({
218274 ) ;
219275} ;
220276
277+ /**
278+ * Attribute Repeater Component.
279+ *
280+ * @param {object } props React props
281+ * @param {Function } props.children Render prop to render the children.
282+ * @param {Function|null } props.addButton render prop to customize the "Add item" button.
283+ * @param {boolean } props.allowReordering boolean to toggle reordering of Repeater items.
284+ * @param {string|null } props.attribute Attribute name.
285+ * @returns {* } React JSX
286+ */
221287export const AttributeRepeater = ( {
222288 children,
223289 attribute = null ,
@@ -227,24 +293,39 @@ export const AttributeRepeater = ({
227293 const { clientId, name } = useBlockEditContext ( ) ;
228294 const { updateBlockAttributes } = dispatch ( blockEditorStore ) ;
229295
230- const attributeValue = useSelect ( ( select ) => {
231- const attributes = select ( blockEditorStore ) . getBlockAttributes ( clientId ) ;
232- return attributes [ attribute ] || [ ] ;
233- } ) ;
296+ const attributeValue = useSelect (
297+ ( select ) => {
298+ // @ts -ignore
299+ const attributes = select ( blockEditorStore ) . getBlockAttributes ( clientId ) ;
300+ return attributes [ attribute ] || [ ] ;
301+ } ,
302+ [ attribute , clientId ] ,
303+ ) ;
234304
235- const { defaultRepeaterData } = useSelect ( ( select ) => {
236- return {
237- defaultRepeaterData :
238- select ( blocksStore ) . getBlockType ( name ) . attributes [ attribute ] . default ,
239- } ;
240- } ) ;
305+ const { defaultRepeaterData } = useSelect (
306+ ( select ) => {
307+ return {
308+ defaultRepeaterData :
309+ // @ts -ignore
310+ select ( blocksStore ) . getBlockType ( name ) . attributes [ attribute ] . default ,
311+ } ;
312+ } ,
313+ [ attribute ] ,
314+ ) ;
241315
242316 if ( defaultRepeaterData . length ) {
243317 defaultRepeaterData [ 0 ] . id = uuid ( ) ;
244318 }
245319
320+ /**
321+ * Update a blocks attributes
322+ *
323+ * @param {string } value Attribute value
324+ */
246325 const handleOnChange = ( value ) => {
247- updateBlockAttributes ( clientId , { [ attribute ] : value } ) ;
326+ if ( attribute !== null ) {
327+ updateBlockAttributes ( clientId , { [ attribute ] : value } ) ;
328+ }
248329 } ;
249330
250331 return (
@@ -260,6 +341,19 @@ export const AttributeRepeater = ({
260341 ) ;
261342} ;
262343
344+ /**
345+ * Repeater Component.
346+ *
347+ * @param {object } props React props
348+ * @param {Function } props.children Render prop to render the children.
349+ * @param {Function|null } props.addButton render prop to customize the "Add item" button.
350+ * @param {boolean } props.allowReordering boolean to toggle reordering of Repeater items.
351+ * @param {Function } props.onChange callback function to update the block attribute.
352+ * @param {Array<IndexedItem> } props.value array of Repeater items.
353+ * @param {Array<IndexedItem> } props.defaultValue array of default Repeater items.
354+ * @param {string|null } props.attribute Attribute name.
355+ * @returns {* } React JSX
356+ */
263357export const Repeater = ( {
264358 children,
265359 addButton = null ,
0 commit comments