This repository was archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 221
/
Copy pathuse-view-switcher.tsx
116 lines (102 loc) · 2.83 KB
/
use-view-switcher.tsx
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import { useDispatch, select } from '@wordpress/data';
import { ToolbarGroup, ToolbarDropdownMenu } from '@wordpress/components';
import { eye } from '@woocommerce/icons';
import { Icon } from '@wordpress/icons';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { useEditorContext } from '@woocommerce/base-context';
interface View {
view: string;
label: string;
icon: string | JSX.Element;
}
function getView( viewName: string, views: View[] ) {
return views.find( ( view ) => view.view === viewName );
}
export const useViewSwitcher = (
clientId: string,
views: View[],
onViewChange: ( view: View ) => void
): {
currentView: string;
component: JSX.Element;
} => {
const initialView = views[ 0 ];
const { currentView, setCurrentView } = useEditorContext();
const { selectBlock } = useDispatch( 'core/block-editor' );
const { getBlock, getSelectedBlockClientId, getBlockParentsByBlockName } =
select( blockEditorStore );
const selectedBlockClientId = getSelectedBlockClientId();
if ( ! currentView ) {
setCurrentView( initialView );
}
useEffect( () => {
const selectedBlock = getBlock( selectedBlockClientId );
if ( ! selectedBlock ) {
return;
}
if ( currentView.view === selectedBlock.name ) {
return;
}
const viewNames = views.map( ( { view } ) => view );
if ( viewNames.includes( selectedBlock.name ) ) {
const newView = getView( selectedBlock.name, views );
if ( newView ) {
return setCurrentView( newView );
}
}
const parentBlockIds = getBlockParentsByBlockName(
selectedBlockClientId,
viewNames
);
if ( parentBlockIds.length !== 1 ) {
return;
}
const parentBlock = getBlock( parentBlockIds[ 0 ] );
if ( currentView.view === parentBlock.name ) {
return;
}
const newView = getView( parentBlock.name, views );
if ( newView ) {
setCurrentView( newView );
}
}, [
getBlockParentsByBlockName,
selectedBlockClientId,
getBlock,
currentView.view,
views,
setCurrentView,
] );
const ViewSwitcherComponent = (
<ToolbarGroup>
<ToolbarDropdownMenu
label={ __( 'Switch view', 'woo-gutenberg-products-block' ) }
text={ currentView.label }
icon={ <Icon icon={ eye } style={ { marginRight: '8px' } } /> }
controls={ views.map( ( view ) => ( {
...view,
title: <span>{ view.label }</span>,
isActive: view.view === currentView.view,
onClick: () => {
setCurrentView( view );
selectBlock(
getBlock( clientId ).innerBlocks.find(
( block: { name: string } ) =>
block.name === view.view
)?.clientId || clientId
);
},
} ) ) }
/>
</ToolbarGroup>
);
return {
currentView: currentView.view,
component: ViewSwitcherComponent,
};
};