Skip to content

Commit

Permalink
Cover: Customizing Alignment of inner content (#21091)
Browse files Browse the repository at this point in the history
* Add initial AlignmentControl

* Refactor AlignmentControl utils. Add basic tests for utils

* Move AlignmentControl styled components to dedicated file

* Add AlignControl icon. Refactor and share styles between main Control and Icon

* Update Docs Manifest

* Export AlignControl as __experimentalAlignControl

* Fix export for AlignmentControl (__experimentalAlignmentControl)

* Update packages/components/src/alignment-control/utils.js

Co-Authored-By: Zebulan Stanphill <[email protected]>

* Integrate AlignmentControl with Cover block

Renamed AlignmentControl to AlignmentMatrixControl.

* Update Docs manifest and Storyshot

* Improve AlignmentMatrix rendering in Edit and Save functions

Remove unused code from base AlignmentMatrix component

* Prevent rendering of position className if undefined

* Update Cover content position control label

* Add padding to Cover (rather than inner content)

* Adding a11y and RTL support to AlignmentMatrixControl

Also refactors isRTL / useRTL from the rtl utils.

* Add basic tests for keyboard movements

* Cover: Customizing Alignment with Reakit Composite (#21333)

* WIP: Attempt to use Composite from Reakit

* Fix issues and clean up composite code

* Refactor Composite integration and update tests

* Update snapshots

* Fix keyboard navigation for AlignmentMatrixControl in Toolbar

* Fix keyboard interaction to open Alignment position on keyboard down

Co-authored-by: Haz <[email protected]>

* Update comments in AlignmentMatrixControl

* Remove unnecessary fragment in Story

* Refactor styles. Add knobs to AlignmentMatrixControl story

* Adjust icon style

* Add Tooltip to AlignmentMatrixControl cell

* Remove onBlur handling and border styles

* Account for center position

* Adding code comment for width/height props in AlignmentMatrixControlIcon

* Add prefix support in useInstanceId

* Add code comment regarding icon export from AlignmentMatrixControl

* Remove export of AlignmentMatrixControl icon element

* Update stories + snapshot

* Simplify nested array flattening

* Remove padding from Cover editor.scss

* Adjust BlockAlignmentMatrixToolbar popover className

* Move padding styles to top of wp-block-cover selector

* Fix AlignmentMatrixControl tests for window.focus in JSDOM

* Replace Array.flat with lodash.flattenDeep

Due to lack of polyfill support (at the moment).

Co-authored-by: Zebulan Stanphill <[email protected]>
Co-authored-by: Haz <[email protected]>
  • Loading branch information
3 people authored May 13, 2020
1 parent 022eec5 commit 47389d5
Show file tree
Hide file tree
Showing 24 changed files with 801 additions and 19 deletions.
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,12 @@
"markdown_source": "../packages/components/README.md",
"parent": null
},
{
"title": "AlignmentMatrixControl",
"slug": "alignment-matrix-control",
"markdown_source": "../packages/components/src/alignment-matrix-control/README.md",
"parent": "components"
},
{
"title": "AnglePickerControl",
"slug": "angle-picker-control",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* External dependencies
*/
import { noop } from 'lodash';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { DOWN } from '@wordpress/keycodes';
import {
Button,
Dropdown,
ToolbarGroup,
__experimentalAlignmentMatrixControl as AlignmentMatrixControl,
} from '@wordpress/components';

export function BlockAlignmentMatrixToolbar( props ) {
const {
label = __( 'Change matrix alignment' ),
onChange = noop,
value = 'center',
} = props;

const icon = <AlignmentMatrixControl.Icon value={ value } />;
const className = 'block-editor-block-alignment-matrix-toolbar';
const popoverClassName = `${ className }__popover`;

return (
<Dropdown
position="bottom right"
className={ className }
popoverProps={ { className: popoverClassName } }
renderToggle={ ( { onToggle, isOpen } ) => {
const openOnArrowDown = ( event ) => {
if ( ! isOpen && event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
onToggle();
}
};

return (
<ToolbarGroup>
<Button
onClick={ onToggle }
aria-haspopup="true"
aria-expanded={ isOpen }
onKeyDown={ openOnArrowDown }
label={ label }
icon={ icon }
showTooltip
/>
</ToolbarGroup>
);
} }
renderContent={ () => (
<AlignmentMatrixControl
hasFocusBorder={ false }
onChange={ onChange }
value={ value }
/>
) }
/>
);
}

export default BlockAlignmentMatrixToolbar;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.block-editor-block-alignment-matrix-toolbar__popover {
.components-popover__content {
min-width: 0;
padding: $grid-unit;
width: auto;
}
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './font-sizes';
export { default as AlignmentToolbar } from './alignment-toolbar';
export { default as Autocomplete } from './autocomplete';
export { default as BlockAlignmentToolbar } from './block-alignment-toolbar';
export { default as __experimentalBlockAlignmentMatrixToolbar } from './block-alignment-matrix-toolbar';
export { default as BlockBreadcrumb } from './block-breadcrumb';
export { BlockContextProvider } from './block-context';
export { default as BlockControls } from './block-controls';
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Only add styles for components that are used inside the editing canvas here:

@import "./autocompleters/style.scss";
@import "./components/block-alignment-matrix-toolbar/style.scss";
@import "./components/block-icon/style.scss";
@import "./components/block-inspector/style.scss";
@import "./components/block-list/style.scss";
Expand Down
3 changes: 3 additions & 0 deletions packages/block-library/src/cover/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
},
"customGradient": {
"type": "string"
},
"contentPosition": {
"type": "string"
}
}
}
35 changes: 27 additions & 8 deletions packages/block-library/src/cover/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
__experimentalUseGradient,
__experimentalPanelColorGradientSettings as PanelColorGradientSettings,
__experimentalUnitControl as UnitControl,
__experimentalBlockAlignmentMatrixToolbar as BlockAlignmentMatrixToolbar,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import { withDispatch } from '@wordpress/data';
Expand All @@ -49,6 +50,8 @@ import {
CSS_UNITS,
backgroundImageStyles,
dimRatioToClass,
isContentPositionCenter,
getPositionClassName,
} from './shared';

/**
Expand Down Expand Up @@ -233,6 +236,7 @@ function CoverEdit( {
noticeOperations,
} ) {
const {
contentPosition,
id,
backgroundType,
dimRatio,
Expand Down Expand Up @@ -293,6 +297,13 @@ function CoverEdit( {
const controls = (
<>
<BlockControls>
<BlockAlignmentMatrixToolbar
label={ __( 'Change content position' ) }
value={ contentPosition }
onChange={ ( nextPosition ) =>
setAttributes( { contentPosition: nextPosition } )
}
/>
{ hasBackground && (
<MediaReplaceFlow
mediaId={ id }
Expand Down Expand Up @@ -439,14 +450,22 @@ function CoverEdit( {
);
}

const classes = classnames( className, dimRatioToClass( dimRatio ), {
'is-dark-theme': isDark,
'has-background-dim': dimRatio !== 0,
'has-parallax': hasParallax,
[ overlayColor.class ]: overlayColor.class,
'has-background-gradient': gradientValue,
[ gradientClass ]: ! url && gradientClass,
} );
const classes = classnames(
className,
dimRatioToClass( dimRatio ),
{
'is-dark-theme': isDark,
'has-background-dim': dimRatio !== 0,
'has-parallax': hasParallax,
[ overlayColor.class ]: overlayColor.class,
'has-background-gradient': gradientValue,
[ gradientClass ]: ! url && gradientClass,
'has-custom-content-position': ! isContentPositionCenter(
contentPosition
),
},
getPositionClassName( contentPosition )
);

return (
<>
Expand Down
9 changes: 8 additions & 1 deletion packages/block-library/src/cover/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ import {
VIDEO_BACKGROUND_TYPE,
backgroundImageStyles,
dimRatioToClass,
isContentPositionCenter,
getPositionClassName,
} from './shared';

export default function save( { attributes } ) {
const {
backgroundType,
gradient,
contentPosition,
customGradient,
customOverlayColor,
dimRatio,
Expand Down Expand Up @@ -70,7 +73,11 @@ export default function save( { attributes } ) {
'has-parallax': hasParallax,
'has-background-gradient': gradient || customGradient,
[ gradientClass ]: ! url && gradientClass,
}
'has-custom-content-position': ! isContentPositionCenter(
contentPosition
),
},
getPositionClassName( contentPosition )
);

return (
Expand Down
27 changes: 27 additions & 0 deletions packages/block-library/src/cover/shared.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
const POSITION_CLASSNAMES = {
'top left': 'is-position-top-left',
'top center': 'is-position-top-center',
'top right': 'is-position-top-right',
'center left': 'is-position-center-left',
'center center': 'is-position-center-center',
center: 'is-position-center-center',
'center right': 'is-position-center-right',
'bottom left': 'is-position-bottom-left',
'bottom center': 'is-position-bottom-center',
'bottom right': 'is-position-bottom-right',
};

export const IMAGE_BACKGROUND_TYPE = 'image';
export const VIDEO_BACKGROUND_TYPE = 'video';
export const COVER_MIN_HEIGHT = 50;
Expand Down Expand Up @@ -56,3 +69,17 @@ export function attributesFromMedia( setAttributes ) {
} );
};
}

export function getPositionClassName( contentPosition ) {
if ( contentPosition === undefined ) return '';

return POSITION_CLASSNAMES[ contentPosition ];
}

export function isContentPositionCenter( contentPosition ) {
return (
! contentPosition ||
contentPosition === 'center center' ||
contentPosition === 'center'
);
}
49 changes: 49 additions & 0 deletions packages/block-library/src/cover/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
justify-content: center;
align-items: center;
overflow: hidden;
padding: $grid-unit-20;

&.has-parallax {
background-attachment: fixed;

Expand Down Expand Up @@ -108,6 +110,53 @@
color: inherit;
}
}

// Position: Top
&.is-position-top-left {
align-items: flex-start;
justify-content: flex-start;
}
&.is-position-top-center {
align-items: flex-start;
justify-content: center;
}
&.is-position-top-right {
align-items: flex-start;
justify-content: flex-end;
}
// Position: Center
&.is-position-center-left {
align-items: center;
justify-content: flex-start;
}
&.is-position-center-center {
align-items: center;
justify-content: center;
}
&.is-position-center-right {
align-items: center;
justify-content: flex-end;
}
// Position: Bottom
&.is-position-bottom-left {
align-items: flex-end;
justify-content: flex-start;
}
&.is-position-bottom-center {
align-items: flex-end;
justify-content: center;
}
&.is-position-bottom-right {
align-items: flex-end;
justify-content: flex-end;
}

&.has-custom-content-position.has-custom-content-position {
.wp-block-cover__inner-container {
margin: 0;
width: auto;
}
}
}

.wp-block-cover__video-background {
Expand Down
18 changes: 18 additions & 0 deletions packages/components/src/alignment-matrix-control/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# AlignmentMatrixControl

AlignmentMatrixControl components let adjust horizontal and vertical alignments for UI.

## Usage

```jsx
import { AlignmentMatrixControl } from '@wordpress/components';
import { useState } from '@wordpress/elememt';

const Example = () => {
const [ alignment, setAlignment ] = useState( 'center center' );

return (
<AlignmentMatrixControl value={ alignment } onChange={ setAlignment } />
);
};
```
35 changes: 35 additions & 0 deletions packages/components/src/alignment-matrix-control/cell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* External dependencies
*/
import { unstable_CompositeItem as CompositeItem } from 'reakit/Composite';

/**
* Internal dependencies
*/
import Tooltip from '../tooltip';
import VisuallyHidden from '../visually-hidden';

/**
* Internal dependencies
*/
import { ALIGNMENT_LABEL } from './utils';
import {
Cell as CellView,
Point,
} from './styles/alignment-matrix-control-styles';

export default function Cell( { isActive = false, value, ...props } ) {
const tooltipText = ALIGNMENT_LABEL[ value ];

return (
<Tooltip text={ tooltipText }>
<CompositeItem as={ CellView } role="gridcell" { ...props }>
{ /* VoiceOver needs a text content to be rendered within grid cell,
otherwise it'll announce the content as "blank". So we use a visually
hidden element instead of aria-label. */ }
<VisuallyHidden>{ value }</VisuallyHidden>
<Point isActive={ isActive } role="presentation" />
</CompositeItem>
</Tooltip>
);
}
Loading

0 comments on commit 47389d5

Please sign in to comment.