-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
use-navigate-to-entity-record.js
82 lines (76 loc) · 2.52 KB
/
use-navigate-to-entity-record.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
/**
* WordPress dependencies
*/
import { useCallback, useReducer } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
/**
* A hook that records the 'entity' history in the post editor as a user
* navigates between editing a post and editing the post template or patterns.
*
* Implemented as a stack, so a little similar to the browser history API.
*
* Used to control displaying UI elements like the back button.
*
* @param {number} initialPostId The post id of the post when the editor loaded.
* @param {string} initialPostType The post type of the post when the editor loaded.
* @param {string} defaultRenderingMode The rendering mode to switch to when navigating.
*
* @return {Object} An object containing the `currentPost` variable and
* `onNavigateToEntityRecord` and `onNavigateToPreviousEntityRecord` functions.
*/
export default function useNavigateToEntityRecord(
initialPostId,
initialPostType,
defaultRenderingMode
) {
const [ postHistory, dispatch ] = useReducer(
( historyState, { type, post, previousRenderingMode } ) => {
if ( type === 'push' ) {
return [ ...historyState, { post, previousRenderingMode } ];
}
if ( type === 'pop' ) {
// Try to leave one item in the history.
if ( historyState.length > 1 ) {
return historyState.slice( 0, -1 );
}
}
return historyState;
},
[
{
post: { postId: initialPostId, postType: initialPostType },
},
]
);
const { post, previousRenderingMode } =
postHistory[ postHistory.length - 1 ];
const { getRenderingMode } = useSelect( editorStore );
const { setRenderingMode } = useDispatch( editorStore );
const onNavigateToEntityRecord = useCallback(
( params ) => {
dispatch( {
type: 'push',
post: { postId: params.postId, postType: params.postType },
// Save the current rendering mode so we can restore it when navigating back.
previousRenderingMode: getRenderingMode(),
} );
setRenderingMode( defaultRenderingMode );
},
[ getRenderingMode, setRenderingMode, defaultRenderingMode ]
);
const onNavigateToPreviousEntityRecord = useCallback( () => {
dispatch( { type: 'pop' } );
if ( previousRenderingMode ) {
setRenderingMode( previousRenderingMode );
}
}, [ setRenderingMode, previousRenderingMode ] );
return {
currentPost: post,
onNavigateToEntityRecord,
onNavigateToPreviousEntityRecord:
postHistory.length > 1
? onNavigateToPreviousEntityRecord
: undefined,
};
}