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

ToolsPanel: Use Grid component to handle layout #35621

Merged
merged 11 commits into from
Oct 29, 2021
4 changes: 4 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Experimental

- Updated the `ToolsPanel` to use `Grid` internally to manage panel layout ([35621](https://github.com/WordPress/gutenberg/pull/35621)).

## 19.0.0 (2021-10-22)

### New Features
Expand Down
40 changes: 21 additions & 19 deletions packages/components/src/tools-panel/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ export const _default = () => {
label="Tools Panel (default example)"
resetAll={ resetAll }
>
<ToolsPanelItem
className="single-column"
<SingleColumnItem
hasValue={ () => !! width }
label="Width"
onDeselect={ () => setWidth( undefined ) }
Expand All @@ -51,9 +50,8 @@ export const _default = () => {
value={ width }
onChange={ ( next ) => setWidth( next ) }
/>
</ToolsPanelItem>
<ToolsPanelItem
className="single-column"
</SingleColumnItem>
<SingleColumnItem
hasValue={ () => !! height }
label="Height"
onDeselect={ () => setHeight( undefined ) }
Expand All @@ -64,7 +62,7 @@ export const _default = () => {
value={ height }
onChange={ ( next ) => setHeight( next ) }
/>
</ToolsPanelItem>
</SingleColumnItem>
<ToolsPanelItem
hasValue={ () => !! minHeight }
label="Minimum height"
Expand Down Expand Up @@ -99,8 +97,7 @@ export const WithOptionalItemsPlusIcon = () => {
label="Tools Panel (optional items only)"
resetAll={ resetAll }
>
<ToolsPanelItem
className="single-column"
<SingleColumnItem
hasValue={ () => !! width }
label="Width"
onDeselect={ () => setWidth( undefined ) }
Expand All @@ -111,9 +108,8 @@ export const WithOptionalItemsPlusIcon = () => {
value={ width }
onChange={ ( next ) => setWidth( next ) }
/>
</ToolsPanelItem>
<ToolsPanelItem
className="single-column"
</SingleColumnItem>
<SingleColumnItem
hasValue={ () => !! height }
label="Height"
onDeselect={ () => setHeight( undefined ) }
Expand All @@ -124,7 +120,7 @@ export const WithOptionalItemsPlusIcon = () => {
value={ height }
onChange={ ( next ) => setHeight( next ) }
/>
</ToolsPanelItem>
</SingleColumnItem>
</ToolsPanel>
</Panel>
</PanelWrapperView>
Expand Down Expand Up @@ -161,8 +157,7 @@ export const WithSlotFillItems = () => {
return (
<SlotFillProvider>
<ToolsPanelItems>
<ToolsPanelItem
className="single-column"
<SingleColumnItem
hasValue={ () => !! width }
label="Injected Width"
onDeselect={ () => updateAttribute( 'width', undefined ) }
Expand All @@ -176,9 +171,8 @@ export const WithSlotFillItems = () => {
updateAttribute( 'width', next )
}
/>
</ToolsPanelItem>
<ToolsPanelItem
className="single-column"
</SingleColumnItem>
<SingleColumnItem
hasValue={ () => !! height }
label="Injected Height"
onDeselect={ () => updateAttribute( 'height', undefined ) }
Expand All @@ -192,7 +186,7 @@ export const WithSlotFillItems = () => {
updateAttribute( 'height', next )
}
/>
</ToolsPanelItem>
</SingleColumnItem>
<ToolsPanelItem
hasValue={ () => true }
label="Item for alternate panel"
Expand Down Expand Up @@ -224,6 +218,14 @@ export const WithSlotFillItems = () => {
export { TypographyPanel } from './typography-panel';

const PanelWrapperView = styled.div`
max-width: 270px;
max-width: 280px;
font-size: 13px;

.components-dropdown-menu__menu {
max-width: 220px;
}
`;

const SingleColumnItem = styled( ToolsPanelItem )`
grid-column: span 1;
`;
32 changes: 14 additions & 18 deletions packages/components/src/tools-panel/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,19 @@ import { COLORS, CONFIG } from '../utils';
import { space } from '../ui/utils/space';

const toolsPanelGrid = {
container: css`
spacing: css`
column-gap: ${ space( 4 ) };
display: grid;
grid-template-columns: 1fr 1fr;
row-gap: ${ space( 6 ) };
`,
item: {
halfWidth: css`
grid-column: span 1;
`,
fullWidth: css`
grid-column: span 2;
grid-column: 1 / -1;
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
`,
},
};

export const ToolsPanel = css`
${ toolsPanelGrid.container };
${ toolsPanelGrid.spacing };
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved

border-top: ${ CONFIG.borderWidth } solid ${ COLORS.gray[ 200 ] };
margin-top: -1px;
Expand All @@ -43,12 +38,17 @@ export const ToolsPanel = css`
* an inner dom element to be injected. The following rule allows for the
* CSS grid display to be re-established.
*/
export const ToolsPanelWithInnerWrapper = css`
> div:not( :first-of-type ) {
${ toolsPanelGrid.container }
${ toolsPanelGrid.item.fullWidth }
}
`;

export const ToolsPanelWithInnerWrapper = ( columns: number ) => {
return css`
> div:not( :first-of-type ) {
display: grid;
grid-template-columns: ${ `repeat( ${ columns }, 1fr )` };
${ toolsPanelGrid.spacing }
${ toolsPanelGrid.item.fullWidth }
}
`;
};

export const ToolsPanelHiddenInnerWrapper = css`
> div:not( :first-of-type ) {
Expand Down Expand Up @@ -94,10 +94,6 @@ export const ToolsPanelHeading = css`
export const ToolsPanelItem = css`
${ toolsPanelGrid.item.fullWidth }

&.single-column {
${ toolsPanelGrid.item.halfWidth }
}

/* Clear spacing in and around controls added as panel items. */
/* Remove when they can be addressed via context system. */
& > div,
Expand Down
11 changes: 7 additions & 4 deletions packages/components/src/tools-panel/tools-panel/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Ref } from 'react';
import ToolsPanelHeader from '../tools-panel-header';
import { ToolsPanelContext } from '../context';
import { useToolsPanel } from './hook';
import { View } from '../../view';
import { Grid } from '../../grid';
import { contextConnect, WordPressComponentProps } from '../../ui/context';
import type { ToolsPanelProps } from '../types';

Expand All @@ -24,11 +24,14 @@ const ToolsPanel = (
panelContext,
resetAllItems,
toggleItem,
...toolsPanelProps
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
className,
} = useToolsPanel( props );

// Props are not directly passed through to avoid exposing Grid props
// until agreement has been reached on how ToolsPanel layout should be
// handled.
return (
<View { ...toolsPanelProps } ref={ forwardedRef }>
<Grid columns={ 2 } className={ className } ref={ forwardedRef }>
<ToolsPanelContext.Provider value={ panelContext }>
<ToolsPanelHeader
label={ label }
Expand All @@ -37,7 +40,7 @@ const ToolsPanel = (
/>
{ children }
</ToolsPanelContext.Provider>
</View>
</Grid>
);
};

Expand Down
5 changes: 4 additions & 1 deletion packages/components/src/tools-panel/tools-panel/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import type {
ToolsPanelProps,
} from '../types';

const DEFAULT_COLUMNS = 2;

const generateMenuItems = ( {
panelItems,
shouldReset,
Expand Down Expand Up @@ -133,7 +135,8 @@ export function useToolsPanel(
const hasDefaultMenuItems =
menuItems?.default && !! Object.keys( menuItems?.default ).length;
const wrapperStyle =
hasInnerWrapper && styles.ToolsPanelWithInnerWrapper;
hasInnerWrapper &&
styles.ToolsPanelWithInnerWrapper( DEFAULT_COLUMNS );
const emptyStyle =
! hasDefaultMenuItems &&
areAllOptionalControlsHidden &&
Expand Down