Implement two-tabbed sidebar content and its state

[MAILPOET-4287]
This commit is contained in:
Jan Jakes
2022-05-13 11:53:29 +02:00
committed by Veljko V
parent be29ee04a6
commit ae8ae8a4fc
11 changed files with 130 additions and 6 deletions

View File

@@ -1,8 +1,9 @@
import { Button, Icon, NavigableMenu } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { wordpress } from '@wordpress/icons';
import { PinnedItems } from '@wordpress/interface';
import { MoreMenu } from './more_menu';
import { store } from '../../store';
import { store, storeName } from '../../store';
// See:
// https://github.com/WordPress/gutenberg/blob/9601a33e30ba41bac98579c8d822af63dd961488/packages/edit-post/src/components/header/index.js
@@ -42,6 +43,7 @@ export function Header(): JSX.Element {
<Button isPrimary className="editor-post-publish-button">
Publish
</Button>
<PinnedItems.Slot scope={storeName} />
<MoreMenu />
</div>
</div>

View File

@@ -0,0 +1,50 @@
import { Button } from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { stepSidebarKey, store, workflowSidebarKey } from '../../store';
// See: https://github.com/WordPress/gutenberg/blob/9601a33e30ba41bac98579c8d822af63dd961488/packages/edit-post/src/components/sidebar/settings-header/index.js
type Props = {
sidebarKey: string;
};
export function Header({ sidebarKey }: Props): JSX.Element {
const { openSidebar } = useDispatch(store);
const openWorkflowSettings = () => openSidebar(workflowSidebarKey);
const openStepSettings = () => openSidebar(stepSidebarKey);
const [workflowAriaLabel, workflowActiveClass] =
sidebarKey === workflowSidebarKey
? ['Workflow (selected)', 'is-active']
: ['Workflow', ''];
const [stepAriaLabel, stepActiveClass] =
sidebarKey === stepSidebarKey
? ['Step (selected)', 'is-active']
: ['Step', ''];
return (
<ul>
<li>
<Button
onClick={openWorkflowSettings}
className={`edit-post-sidebar__panel-tab ${workflowActiveClass}`}
aria-label={workflowAriaLabel}
data-label="Workflow"
>
Workflow
</Button>
</li>
<li>
<Button
onClick={openStepSettings}
className={`edit-post-sidebar__panel-tab ${stepActiveClass}`}
aria-label={stepAriaLabel}
data-label="Workflow"
>
Step
</Button>
</li>
</ul>
);
}

View File

@@ -1,9 +1,21 @@
import { ComponentProps } from 'react';
import { useSelect } from '@wordpress/data';
import { Platform } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { cog } from '@wordpress/icons';
import { ComplementaryArea } from '@wordpress/interface';
import { storeName } from '../../store';
import {
ComplementaryArea,
store as interfaceStore,
} from '@wordpress/interface';
import { Header } from './header';
import { StepSidebar } from './step';
import { WorkflowSidebar } from './workflow';
import {
stepSidebarKey,
store,
storeName,
workflowSidebarKey,
} from '../../store';
// See:
// https://github.com/WordPress/gutenberg/blob/5caeae34b3fb303761e3b9432311b26f4e5ea3a6/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js
@@ -17,10 +29,20 @@ const sidebarActiveByDefault = Platform.select({
type Props = ComponentProps<typeof ComplementaryArea>;
export function Sidebar(props: Props): JSX.Element {
const { sidebarName } = useSelect(
(select) => ({
sidebarName:
select(interfaceStore).getActiveComplementaryArea(storeName) ??
workflowSidebarKey,
}),
[],
);
const workflowName = 'Testing workflow';
return (
<ComplementaryArea
identifier="mailpoet/automation-editor/workflow"
identifier={sidebarName}
header={<Header sidebarName={sidebarName} />}
closeLabel={__('Close settings')}
headerClassName="edit-post-sidebar__panel-tabs"
title={__('Settings')}
@@ -32,7 +54,8 @@ export function Sidebar(props: Props): JSX.Element {
isActiveByDefault={sidebarActiveByDefault}
{...props}
>
Sidebar
{sidebarName === workflowSidebarKey && <WorkflowSidebar />}
{sidebarName === stepSidebarKey && <StepSidebar />}
</ComplementaryArea>
);
}

View File

@@ -0,0 +1,5 @@
import { PanelBody } from '@wordpress/components';
export function StepSidebar(): JSX.Element {
return <PanelBody>Step settings</PanelBody>;
}

View File

@@ -0,0 +1,5 @@
import { PanelBody } from '@wordpress/components';
export function WorkflowSidebar(): JSX.Element {
return <PanelBody>Workflow settings</PanelBody>;
}

View File

@@ -14,9 +14,13 @@ import { store, storeName } from './store';
// See: https://github.com/WordPress/gutenberg/blob/9601a33e30ba41bac98579c8d822af63dd961488/packages/edit-post/src/components/layout/index.js
function Editor(): JSX.Element {
const { isFullscreenActive } = useSelect(
const {
isFullscreenActive,
isSidebarOpened,
} = useSelect(
(select) => ({
isFullscreenActive: select(store).isFeatureActive('fullscreenMode'),
isSidebarOpened: select(store).isSidebarOpened(),
}),
[],
);
@@ -24,6 +28,9 @@ function Editor(): JSX.Element {
const className = classnames(
'edit-post-layout',
'interface-interface-skeleton',
{
'is-sidebar-opened': isSidebarOpened,
},
);
return (

View File

@@ -1,7 +1,18 @@
import { store as interfaceStore } from '@wordpress/interface';
import { store as preferencesStore } from '@wordpress/preferences';
import { storeName } from './constants';
import { Feature } from './types';
export const openSidebar =
(key) =>
({ registry }) =>
registry.dispatch(interfaceStore).enableComplementaryArea(storeName, key);
export const closeSidebar =
() =>
({ registry }) =>
registry.dispatch(interfaceStore).disableComplementaryArea(storeName);
export const toggleFeature =
(feature: Feature) =>
({ registry }) =>

View File

@@ -1 +1,4 @@
export const storeName = 'mailpoet/automation-editor';
export const workflowSidebarKey = 'mailpoet/automation-editor/workflow';
export const stepSidebarKey = 'mailpoet/automation-editor/step';

View File

@@ -1,4 +1,5 @@
import { createRegistrySelector } from '@wordpress/data';
import { store as interfaceStore } from '@wordpress/interface';
import { store as preferencesStore } from '@wordpress/preferences';
import { storeName } from './constants';
import { Feature } from './types';
@@ -8,3 +9,8 @@ export const isFeatureActive = createRegistrySelector(
(_, feature: Feature): boolean =>
select(preferencesStore).get(storeName, feature),
);
export const isSidebarOpened = createRegistrySelector(
(select) => (): boolean =>
!!select(interfaceStore).getActiveComplementaryArea(storeName),
);

View File

@@ -1,4 +1,5 @@
import { ColorPalette, FontSizePicker } from '@wordpress/components';
import { store as interfaceStore } from '@wordpress/interface';
import { store as preferencesStore } from '@wordpress/preferences';
import './wordpress_modules';
@@ -42,8 +43,14 @@ declare module '@wordpress/block-editor' {
}
declare module '@wordpress/data' {
type InterfaceStore = 'core/interface' | typeof interfaceStore;
type PreferencesStore = 'core/preferences' | typeof preferencesStore;
// there are no @types/wordpress__interface yet
function select(key: InterfaceStore): {
getActiveComplementaryArea: (scope: string) => string | undefined | null;
};
// there are no @types/wordpress__preferences yet
function select(key: PreferencesStore): {
get: <T>(scope: string, name: string) => T;

View File

@@ -1,11 +1,16 @@
/* eslint-disable @typescript-eslint/no-explicit-any -- some general types in this file need to use "any" */
/* eslint-disable import/no-duplicates -- importing within multiple "declare module" blocks is OK */
// there are no @types/wordpress__interface yet
declare module '@wordpress/interface' {
import { StoreDescriptor } from '@wordpress/data';
export const store: { name: 'core/interface' } & StoreDescriptor;
export const ComplementaryArea: any;
export const FullscreenMode: any;
export const MoreMenuDropdown: any;
export const InterfaceSkeleton: any;
export const PinnedItems: any;
}
// there are no @types/wordpress__preferences yet