Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preferences modal to site editor #39485

Merged
merged 4 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/edit-site/src/components/header/more-menu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { PreferenceToggleMenuItem } from '@wordpress/preferences';
* Internal dependencies
*/
import KeyboardShortcutHelpModal from '../../keyboard-shortcut-help-modal';
import EditSitePreferencesModal from '../../preferences-modal';
import ToolsMoreMenuGroup from '../tools-more-menu-group';
import SiteExport from './site-export';
import WelcomeGuideMenuItem from './welcome-guide-menu-item';
Expand All @@ -26,6 +27,11 @@ export default function MoreMenu() {
false
);

const [ isPreferencesModalActive, togglePreferencesModal ] = useReducer(
( isActive ) => ! isActive,
false
);

useShortcut( 'core/edit-site/keyboard-shortcuts', toggleModal );

return (
Expand Down Expand Up @@ -99,13 +105,22 @@ export default function MoreMenu() {
fillProps={ { onClose } }
/>
</MenuGroup>
<MenuGroup>
<MenuItem onClick={ togglePreferencesModal }>
{ __( 'Preferences' ) }
</MenuItem>
</MenuGroup>
</>
) }
</MoreMenuDropdown>
<KeyboardShortcutHelpModal
isModalActive={ isModalActive }
toggleModal={ toggleModal }
/>
<EditSitePreferencesModal
isModalActive={ isPreferencesModalActive }
toggleModal={ togglePreferencesModal }
/>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface';
import { store as preferencesStore } from '@wordpress/preferences';

export default function EnableFeature( props ) {
const { featureName, ...remainingProps } = props;
const isChecked = useSelect( ( select ) =>
select( preferencesStore ).get( 'core/edit-site', featureName )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd maybe just coerce this into a bool to be on the safe side 😄

Suggested change
select( preferencesStore ).get( 'core/edit-site', featureName )
!! select( preferencesStore ).get( 'core/edit-site', featureName )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
select( preferencesStore ).get( 'core/edit-site', featureName )
( select ) =>
select( preferencesStore ).get( 'core/edit-site', featureName ),
[ featureName ]

Missing dependency.

);
const { toggle } = useDispatch( preferencesStore );
const onChange = () => toggle( 'core/edit-site', featureName );
return (
<BaseOption
onChange={ onChange }
isChecked={ isChecked }
{ ...remainingProps }
/>
);
}
71 changes: 71 additions & 0 deletions packages/edit-site/src/components/preferences-modal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* WordPress dependencies
*/
import {
PreferencesModal,
PreferencesModalTabs,
PreferencesModalSection,
} from '@wordpress/interface';
import { useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import EnableFeature from './enable-feature';

export default function EditSitePreferencesModal( {
isModalActive,
toggleModal,
} ) {
const sections = useMemo( () => [
{
name: 'general',
tabLabel: __( 'General' ),
content: (
<PreferencesModalSection
title={ __( 'Appearance' ) }
description={ __(
'Customize options related to the block editor interface and editing flow.'
) }
>
<EnableFeature
featureName="focusMode"
help={ __(
'Highlights the current block and fades other content.'
) }
label={ __( 'Spotlight mode' ) }
/>
</PreferencesModalSection>
),
},
{
name: 'blocks',
tabLabel: __( 'Blocks' ),
content: (
<PreferencesModalSection
title={ __( 'Block interactions' ) }
description={ __(
'Customize how you interact with blocks in the block library and editing canvas.'
) }
>
<EnableFeature
featureName="keepCaretInsideBlock"
help={ __(
'Aids screen readers by stopping text caret from leaving blocks.'
) }
label={ __( 'Contain text cursor inside block' ) }
/>
</PreferencesModalSection>
),
},
] );
if ( ! isModalActive ) {
return null;
}
return (
<PreferencesModal closeModal={ toggleModal }>
<PreferencesModalTabs sections={ sections } />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does still feel a bit empty with one setting per tab. I wonder if right now an option could be to not add the tabs until there are more settings later on, and instead render the two PreferenceModalSections directly in the modal.

I don't know if the styles will work out of the box, but it might be possible to make some quick fixes there.

Could be good to get some design feedback on it though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think tabs will fill up faster now that we've modal.

Copy link
Contributor

@talldan talldan Mar 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be pretty easy to get the block manager in there as well now.

I think the component needs to be moved out of edit-post, but the rest of the implementation shouldn't be too difficult.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I added the second tab mainly thinking about the block manager which takes up a huge chunk of space 😄

Plus with #38317 there'll be at least one more item under Appearance soon.

</PreferencesModal>
);
}
1 change: 1 addition & 0 deletions packages/edit-site/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export function reinitializeEditor( target, settings ) {
editorMode: 'visual',
fixedToolbar: false,
focusMode: false,
keepCaretInsideBlock: false,
welcomeGuide: true,
welcomeGuideStyles: true,
} );
Expand Down
5 changes: 5 additions & 0 deletions packages/edit-site/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ export const getSettings = createSelector(
state,
'fixedToolbar'
),
keepCaretInsideBlock: !! __unstableGetPreference(
state,
'keepCaretInsideBlock'
),
__experimentalSetIsInserterOpened: setIsInserterOpen,
__experimentalReusableBlocks: getReusableBlocks( state ),
__experimentalPreferPatternsOnRoot:
Expand All @@ -145,6 +149,7 @@ export const getSettings = createSelector(
state.settings,
__unstableGetPreference( state, 'focusMode' ),
__unstableGetPreference( state, 'fixedToolbar' ),
__unstableGetPreference( state, 'keepCaretInsideBlock' ),
getReusableBlocks( state ),
getEditedPostType( state ),
]
Expand Down
2 changes: 2 additions & 0 deletions packages/edit-site/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ describe( 'selectors', () => {
outlineMode: true,
focusMode: false,
hasFixedToolbar: false,
keepCaretInsideBlock: false,
__experimentalSetIsInserterOpened: setInserterOpened,
__experimentalReusableBlocks: [],
__experimentalPreferPatternsOnRoot: true,
Expand All @@ -102,6 +103,7 @@ describe( 'selectors', () => {
key: 'value',
focusMode: true,
hasFixedToolbar: true,
keepCaretInsideBlock: false,
__experimentalSetIsInserterOpened: setInserterOpened,
__experimentalReusableBlocks: [],
mediaUpload: expect.any( Function ),
Expand Down