-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
use-navigation-blocks.js
98 lines (79 loc) · 2.25 KB
/
use-navigation-blocks.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
* External dependencies
*/
import { isEqual, difference } from 'lodash';
/**
* WordPress dependencies
*/
import { createBlock } from '@wordpress/blocks';
import { useSelect, useDispatch } from '@wordpress/data';
import { useState, useRef, useEffect } from '@wordpress/element';
function createBlockFromMenuItem( menuItem ) {
return createBlock( 'core/navigation-link', {
label: menuItem.title.raw,
url: menuItem.url,
} );
}
function createMenuItemAttributesFromBlock( block ) {
return {
title: block.attributes.label,
url: block.attributes.url,
};
}
export default function useNavigationBlocks( menuId ) {
const menuItems = useSelect(
( select ) => select( 'core' ).getMenuItems( { menus: menuId } ),
[ menuId ]
);
const { saveMenuItem } = useDispatch( 'core' );
const [ blocks, setBlocks ] = useState( [] );
const menuItemsRef = useRef( {} );
useEffect( () => {
if ( ! menuItems ) {
return;
}
menuItemsRef.current = {};
const innerBlocks = [];
for ( const menuItem of menuItems ) {
const block = createBlockFromMenuItem( menuItem );
menuItemsRef.current[ block.clientId ] = menuItem;
innerBlocks.push( block );
}
setBlocks( [ createBlock( 'core/navigation', {}, innerBlocks ) ] );
}, [ menuItems ] );
const saveBlocks = () => {
const { innerBlocks } = blocks[ 0 ];
for ( const block of innerBlocks ) {
const menuItem = menuItemsRef.current[ block.clientId ];
if ( ! menuItem ) {
saveMenuItem( {
...createMenuItemAttributesFromBlock( block ),
menus: menuId,
} );
continue;
}
if (
! isEqual(
block.attributes,
createBlockFromMenuItem( menuItem ).attributes
)
) {
saveMenuItem( {
...menuItem,
...createMenuItemAttributesFromBlock( block ),
menus: menuId, // Gotta do this because REST API doesn't like receiving an array here. Maybe a bug in the REST API?
} );
}
}
const deletedClientIds = difference(
Object.keys( menuItemsRef.current ),
innerBlocks.map( ( block ) => block.clientId )
);
// Disable reason, this code will eventually be implemented.
// eslint-disable-next-line no-unused-vars
for ( const clientId of deletedClientIds ) {
// TODO - delete menu items.
}
};
return [ blocks, setBlocks, saveBlocks ];
}