@gechiui/block-editor
Version:
225 lines (206 loc) • 5.66 kB
JavaScript
/**
* GeChiUI dependencies
*/
import {
Button,
__experimentalUseCustomUnits as useCustomUnits,
__experimentalUnitControl as UnitControl,
} from '@gechiui/components';
import { __, sprintf } from '@gechiui/i18n';
import { Icon, positionCenter, stretchWide } from '@gechiui/icons';
/**
* Internal dependencies
*/
import useSetting from '../components/use-setting';
import { appendSelectors } from './utils';
export default {
name: 'default',
label: __( '流动' ),
inspectorControls: function DefaultLayoutInspectorControls( {
layout,
onChange,
} ) {
const { wideSize, contentSize } = layout;
const units = useCustomUnits( {
availableUnits: useSetting( 'spacing.units' ) || [
'%',
'px',
'em',
'rem',
'vw',
],
} );
return (
<>
<div className="block-editor-hooks__layout-controls">
<div className="block-editor-hooks__layout-controls-unit">
<UnitControl
label={ __( '内容' ) }
labelPosition="top"
__unstableInputWidth="80px"
value={ contentSize || wideSize || '' }
onChange={ ( nextWidth ) => {
nextWidth =
0 > parseFloat( nextWidth )
? '0'
: nextWidth;
onChange( {
...layout,
contentSize: nextWidth,
} );
} }
units={ units }
/>
<Icon icon={ positionCenter } />
</div>
<div className="block-editor-hooks__layout-controls-unit">
<UnitControl
label={ __( '宽' ) }
labelPosition="top"
__unstableInputWidth="80px"
value={ wideSize || contentSize || '' }
onChange={ ( nextWidth ) => {
nextWidth =
0 > parseFloat( nextWidth )
? '0'
: nextWidth;
onChange( {
...layout,
wideSize: nextWidth,
} );
} }
units={ units }
/>
<Icon icon={ stretchWide } />
</div>
</div>
<div className="block-editor-hooks__layout-controls-reset">
<Button
variant="secondary"
isSmall
disabled={ ! contentSize && ! wideSize }
onClick={ () =>
onChange( {
contentSize: undefined,
wideSize: undefined,
inherit: false,
} )
}
>
{ __( '重置' ) }
</Button>
</div>
<p className="block-editor-hooks__layout-controls-helptext">
{ __(
'自定义所有被分配到中间或宽列的元素的宽度。'
) }
</p>
</>
);
},
toolBarControls: function DefaultLayoutToolbarControls() {
return null;
},
save: function DefaultLayoutStyle( { selector, layout = {}, style } ) {
const { contentSize, wideSize } = layout;
const blockGapSupport = useSetting( 'spacing.blockGap' );
const hasBlockGapStylesSupport = blockGapSupport !== null;
const blockGapValue =
style?.spacing?.blockGap ?? 'var( --gc--style--block-gap )';
let output =
!! contentSize || !! wideSize
? `
${ appendSelectors( selector, '> *' ) } {
max-width: ${ contentSize ?? wideSize };
margin-left: auto !important;
margin-right: auto !important;
}
${ appendSelectors( selector, '> [data-align="wide"]' ) } {
max-width: ${ wideSize ?? contentSize };
}
${ appendSelectors( selector, '> [data-align="full"]' ) } {
max-width: none;
}
`
: '';
output += `
${ appendSelectors( selector, '> [data-align="left"]' ) } {
float: left;
margin-right: 2em;
}
${ appendSelectors( selector, '> [data-align="right"]' ) } {
float: right;
margin-left: 2em;
}
`;
if ( hasBlockGapStylesSupport ) {
output += `
${ appendSelectors( selector, '> *' ) } {
margin-top: 0;
margin-bottom: 0;
}
${ appendSelectors( selector, '> * + *' ) } {
margin-top: ${ blockGapValue };
}
`;
}
return <style>{ output }</style>;
},
getOrientation() {
return 'vertical';
},
getAlignments( layout ) {
const alignmentInfo = getAlignmentsInfo( layout );
if ( layout.alignments !== undefined ) {
if ( ! layout.alignments.includes( 'none' ) ) {
layout.alignments.unshift( 'none' );
}
return layout.alignments.map( ( alignment ) => ( {
name: alignment,
info: alignmentInfo[ alignment ],
} ) );
}
const { contentSize, wideSize } = layout;
const alignments = [
{ name: 'left' },
{ name: 'center' },
{ name: 'right' },
];
if ( contentSize ) {
alignments.unshift( { name: 'full' } );
}
if ( wideSize ) {
alignments.unshift( { name: 'wide', info: alignmentInfo.wide } );
}
alignments.unshift( { name: 'none', info: alignmentInfo.none } );
return alignments;
},
};
/**
* Helper method to assign contextual info to clarify
* alignment settings.
*
* Besides checking if `contentSize` and `wideSize` have a
* value, we now show this information only if their values
* are not a `css var`. This needs to change when parsing
* css variables land.
*
* @see https://github.com/GeChiUI/gutenberg/pull/34710#issuecomment-918000752
*
* @param {Object} layout The layout object.
* @return {Object} An object with contextual info per alignment.
*/
function getAlignmentsInfo( layout ) {
const { contentSize, wideSize } = layout;
const alignmentInfo = {};
const sizeRegex = /^(?!0)\d+(px|em|rem|vw|vh|%)?$/i;
if ( sizeRegex.test( contentSize ) ) {
// translators: %s: container size (i.e. 600px etc)
alignmentInfo.none = sprintf( __( '最大 %s 宽' ), contentSize );
}
if ( sizeRegex.test( wideSize ) ) {
// translators: %s: container size (i.e. 600px etc)
alignmentInfo.wide = sprintf( __( '最大 %s 宽' ), wideSize );
}
return alignmentInfo;
}