/** * Application shell — sidebar, canvas, save bar. * * The shell owns the full width of the admin content area (wp-admin's gutter * is cancelled in style.css). That single decision does more to shed the * "WordPress plugin" read than any amount of border radius: the plugin stops * being a document inside someone else's chrome and becomes the chrome. */ import { useEffect, useState } from '@wordpress/element'; import { boot } from '../lib/api'; import { fmt, num, t } from '../lib/i18n'; import { useSettings } from '../state/settings'; import { gradeFor, ScorePill } from '../ui/Score'; import Button from '../ui/Button'; import Logo from '../ui/Logo'; import { IconExternal, IconSparkle } from '../icons'; /** * Sidebar navigation. * * @param {Object} props * @param {Array} props.items `[{ slug, label, icon }]`. * @param {string} props.route Active slug. * @param {Function} props.navigate * @param {Function} props.hrefFor Real href per route, so links are * middle-clickable and copyable. * @return {Element} Navigation. */ function Nav( { items, route, navigate, hrefFor } ) { return ( ); } /** * Persistent save bar. It only exists while there is something to save, and * it says what changed rather than sitting there permanently as a button at * the bottom of a form. * * @return {JSX.Element|null} Save bar. */ function SaveBar() { const { dirty, saving, save, revert } = useSettings(); const [ mounted, setMounted ] = useState( false ); useEffect( () => { if ( dirty ) { setMounted( true ); } }, [ dirty ] ); if ( ! dirty ) { return null; } return (
{ t( 'unsavedChanges', 'You have unsaved changes' ) }
{ active.blurb }
) }