-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an API to add a plugin sidebar (new) (#4777)
* Make it possible for plugins to render a sidebar * Fix sidebar styling * Remove unused mobile middleware * Fix editor mode switching * Fix editorMode switch test * Fix documentation * Change `@returns` into `@return` * Add storeKey to make the plugins panel connect to the correct store * Rename 'plugins' to 'plugin' in selector * Set editor as default activeGeneralSidebar * Unexpose getSidebarSettings * Remove duplicate scss and remove renderSidebar function * Fix unittests * Fix header height, font and close button * Update index.js * Edit Post: Remove no longer used getPluginSidebar * Edit Post: Remove no longer used imports from PluginsPanel * Edit Post: Update Layout to handle missing plugin properly * Edit Post: Remove obsolete blank line
- Loading branch information
Showing
28 changed files
with
630 additions
and
345 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export { | ||
registerSidebar, | ||
activateSidebar, | ||
} from './sidebar'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* eslint no-console: [ 'error', { allow: [ 'error' ] } ] */ | ||
|
||
/* External dependencies */ | ||
import { isFunction } from 'lodash'; | ||
|
||
/* Internal dependencies */ | ||
import store from '../store'; | ||
import { setGeneralSidebarActivePanel, openGeneralSidebar } from '../store/actions'; | ||
import { applyFilters } from '@wordpress/hooks'; | ||
|
||
const sidebars = {}; | ||
|
||
/** | ||
* Registers a sidebar to the editor. | ||
* | ||
* A button will be shown in the settings menu to open the sidebar. The sidebar | ||
* can be manually opened by calling the `activateSidebar` function. | ||
* | ||
* @param {string} name The name of the sidebar. Should be in | ||
* `[plugin]/[sidebar]` format. | ||
* @param {Object} settings The settings for this sidebar. | ||
* @param {string} settings.title The name to show in the settings menu. | ||
* @param {Function} settings.render The function that renders the sidebar. | ||
* | ||
* @return {Object} The final sidebar settings object. | ||
*/ | ||
export function registerSidebar( name, settings ) { | ||
settings = { | ||
name, | ||
...settings, | ||
}; | ||
|
||
if ( typeof name !== 'string' ) { | ||
console.error( | ||
'Sidebar names must be strings.' | ||
); | ||
return null; | ||
} | ||
if ( ! /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test( name ) ) { | ||
console.error( | ||
'Sidebar names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-sidebar.' | ||
); | ||
return null; | ||
} | ||
if ( ! settings || ! isFunction( settings.render ) ) { | ||
console.error( | ||
'The "render" property must be specified and must be a valid function.' | ||
); | ||
return null; | ||
} | ||
if ( sidebars[ name ] ) { | ||
console.error( | ||
`Sidebar ${ name } is already registered.` | ||
); | ||
} | ||
|
||
if ( ! settings.title ) { | ||
console.error( | ||
`The sidebar ${ name } must have a title.` | ||
); | ||
return null; | ||
} | ||
if ( typeof settings.title !== 'string' ) { | ||
console.error( | ||
'Sidebar titles must be strings.' | ||
); | ||
return null; | ||
} | ||
|
||
settings = applyFilters( 'editor.registerSidebar', settings, name ); | ||
|
||
return sidebars[ name ] = settings; | ||
} | ||
|
||
/** | ||
* Retrieves the sidebar settings object. | ||
* | ||
* @param {string} name The name of the sidebar to retrieve the settings for. | ||
* | ||
* @return {Object} The settings object of the sidebar. Or null if the | ||
* sidebar doesn't exist. | ||
*/ | ||
export function getSidebarSettings( name ) { | ||
if ( ! sidebars.hasOwnProperty( name ) ) { | ||
return null; | ||
} | ||
return sidebars[ name ]; | ||
} | ||
/** | ||
* Activates the given sidebar. | ||
* | ||
* @param {string} name The name of the sidebar to activate. | ||
* @return {void} | ||
*/ | ||
export function activateSidebar( name ) { | ||
store.dispatch( openGeneralSidebar( 'plugin' ) ); | ||
store.dispatch( setGeneralSidebarActivePanel( 'plugin', name ) ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { connect } from 'react-redux'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { IconButton, withFocusReturn } from '@wordpress/components'; | ||
|
||
/** | ||
* Internal Dependencies | ||
*/ | ||
import './style.scss'; | ||
import { getSidebarSettings } from '../../api/sidebar'; | ||
import { getActivePlugin } from '../../store/selectors'; | ||
import { closeGeneralSidebar } from '../../store/actions'; | ||
|
||
function PluginsPanel( { onClose, plugin } ) { | ||
const pluginSidebar = getSidebarSettings( plugin ); | ||
|
||
if ( ! pluginSidebar ) { | ||
return null; | ||
} | ||
|
||
const { | ||
title, | ||
render, | ||
} = pluginSidebar; | ||
|
||
return ( | ||
<div | ||
className="edit-post-sidebar edit-post-plugins-panel" | ||
role="region" | ||
aria-label={ __( 'Editor plugins' ) } | ||
tabIndex="-1"> | ||
<div className="edit-post-plugins-panel__header"> | ||
<h3>{ title }</h3> | ||
<IconButton | ||
onClick={ onClose } | ||
icon="no-alt" | ||
label={ __( 'Close settings' ) } | ||
/> | ||
</div> | ||
<div className="edit-post-plugins-panel__content"> | ||
{ render() } | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default connect( | ||
( state ) => { | ||
return { | ||
plugin: getActivePlugin( state ), | ||
}; | ||
}, { | ||
onClose: closeGeneralSidebar, | ||
}, | ||
undefined, | ||
{ storeKey: 'edit-post' } | ||
)( withFocusReturn( PluginsPanel ) ); |
Oops, something went wrong.