@gechiui/block-editor
Version:
256 lines (243 loc) • 5.77 kB
JavaScript
/**
* GeChiUI dependencies
*/
import { __ } from '@gechiui/i18n';
import {
justifyLeft,
justifyCenter,
justifyRight,
justifySpaceBetween,
arrowRight,
arrowDown,
} from '@gechiui/icons';
import { Button, ToggleControl, Flex, FlexItem } from '@gechiui/components';
/**
* Internal dependencies
*/
import { appendSelectors } from './utils';
import useSetting from '../components/use-setting';
import { BlockControls, JustifyContentControl } from '../components';
// Used with the default, horizontal flex orientation.
const justifyContentMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
'space-between': 'space-between',
};
// Used with the vertical (column) flex orientation.
const alignItemsMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
};
const flexWrapOptions = [ 'wrap', 'nowrap' ];
export default {
name: 'flex',
label: __( '灵活' ),
inspectorControls: function FlexLayoutInspectorControls( {
layout = {},
onChange,
} ) {
const { allowOrientation = true } = layout;
return (
<>
<Flex>
<FlexItem>
<FlexLayoutJustifyContentControl
layout={ layout }
onChange={ onChange }
/>
</FlexItem>
<FlexItem>
{ allowOrientation && (
<OrientationControl
layout={ layout }
onChange={ onChange }
/>
) }
</FlexItem>
</Flex>
<FlexWrapControl layout={ layout } onChange={ onChange } />
</>
);
},
toolBarControls: function FlexLayoutToolbarControls( {
layout = {},
onChange,
layoutBlockSupport,
} ) {
if ( layoutBlockSupport?.allowSwitching ) {
return null;
}
return (
<BlockControls group="block" __experimentalShareWithChildBlocks>
<FlexLayoutJustifyContentControl
layout={ layout }
onChange={ onChange }
isToolbar
/>
</BlockControls>
);
},
save: function FlexLayoutStyle( { selector, layout, style } ) {
const { orientation = 'horizontal' } = layout;
const blockGapSupport = useSetting( 'spacing.blockGap' );
const hasBlockGapStylesSupport = blockGapSupport !== null;
const blockGapValue =
style?.spacing?.blockGap ?? 'var( --gc--style--block-gap, 0.5em )';
const justifyContent =
justifyContentMap[ layout.justifyContent ] ||
justifyContentMap.left;
const flexWrap = flexWrapOptions.includes( layout.flexWrap )
? layout.flexWrap
: 'wrap';
const rowOrientation = `
flex-direction: row;
align-items: center;
justify-content: ${ justifyContent };
`;
const alignItems =
alignItemsMap[ layout.justifyContent ] || alignItemsMap.left;
const columnOrientation = `
flex-direction: column;
align-items: ${ alignItems };
`;
return (
<style>{ `
${ appendSelectors( selector ) } {
display: flex;
gap: ${ hasBlockGapStylesSupport ? blockGapValue : '0.5em' };
flex-wrap: ${ flexWrap };
${ orientation === 'horizontal' ? rowOrientation : columnOrientation }
}
${ appendSelectors( selector, '> *' ) } {
margin: 0;
}
` }</style>
);
},
getOrientation( layout ) {
const { orientation = 'horizontal' } = layout;
return orientation;
},
getAlignments() {
return [];
},
};
function FlexLayoutJustifyContentControl( {
layout,
onChange,
isToolbar = false,
} ) {
const { justifyContent = 'left', orientation = 'horizontal' } = layout;
const onJustificationChange = ( value ) => {
onChange( {
...layout,
justifyContent: value,
} );
};
const allowedControls = [ 'left', 'center', 'right' ];
if ( orientation === 'horizontal' ) {
allowedControls.push( 'space-between' );
}
if ( isToolbar ) {
return (
<JustifyContentControl
allowedControls={ allowedControls }
value={ justifyContent }
onChange={ onJustificationChange }
popoverProps={ {
position: 'bottom right',
isAlternate: true,
} }
/>
);
}
const justificationOptions = [
{
value: 'left',
icon: justifyLeft,
label: __( '左对齐项' ),
},
{
value: 'center',
icon: justifyCenter,
label: __( '居中对齐项' ),
},
{
value: 'right',
icon: justifyRight,
label: __( '右对齐项' ),
},
];
if ( orientation === 'horizontal' ) {
justificationOptions.push( {
value: 'space-between',
icon: justifySpaceBetween,
label: __( '项目间距' ),
} );
}
return (
<fieldset className="block-editor-hooks__flex-layout-justification-controls">
<legend>{ __( '理由' ) }</legend>
<div>
{ justificationOptions.map( ( { value, icon, label } ) => {
return (
<Button
key={ value }
label={ label }
icon={ icon }
isPressed={ justifyContent === value }
onClick={ () => onJustificationChange( value ) }
/>
);
} ) }
</div>
</fieldset>
);
}
function FlexWrapControl( { layout, onChange } ) {
const { flexWrap = 'wrap' } = layout;
return (
<ToggleControl
label={ __( '允许换行到多行' ) }
onChange={ ( value ) => {
onChange( {
...layout,
flexWrap: value ? 'wrap' : 'nowrap',
} );
} }
checked={ flexWrap === 'wrap' }
/>
);
}
function OrientationControl( { layout, onChange } ) {
const { orientation = 'horizontal' } = layout;
return (
<fieldset className="block-editor-hooks__flex-layout-orientation-controls">
<legend>{ __( '方向' ) }</legend>
<Button
label={ 'horizontal' }
icon={ arrowRight }
isPressed={ orientation === 'horizontal' }
onClick={ () =>
onChange( {
...layout,
orientation: 'horizontal',
} )
}
/>
<Button
label={ 'vertical' }
icon={ arrowDown }
isPressed={ orientation === 'vertical' }
onClick={ () =>
onChange( {
...layout,
orientation: 'vertical',
} )
}
/>
</fieldset>
);
}