@wordpress/block-editor
Version:
156 lines (141 loc) • 4.61 kB
JavaScript
/**
* WordPress dependencies
*/
import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
import { useMemo, useCallback } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import InspectorControls from '../components/inspector-controls';
import {
default as StylesTypographyPanel,
useHasTypographyPanel,
} from '../components/global-styles/typography-panel';
import { LINE_HEIGHT_SUPPORT_KEY } from './line-height';
import { FONT_FAMILY_SUPPORT_KEY } from './font-family';
import { FONT_SIZE_SUPPORT_KEY } from './font-size';
import { TEXT_ALIGN_SUPPORT_KEY } from './text-align';
import { cleanEmptyObject } from './utils';
import { store as blockEditorStore } from '../store';
function omit( object, keys ) {
return Object.fromEntries(
Object.entries( object ).filter( ( [ key ] ) => ! keys.includes( key ) )
);
}
const LETTER_SPACING_SUPPORT_KEY = 'typography.__experimentalLetterSpacing';
const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform';
const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle';
const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight';
const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode';
export const TYPOGRAPHY_SUPPORT_KEY = 'typography';
export const TYPOGRAPHY_SUPPORT_KEYS = [
LINE_HEIGHT_SUPPORT_KEY,
FONT_SIZE_SUPPORT_KEY,
FONT_STYLE_SUPPORT_KEY,
FONT_WEIGHT_SUPPORT_KEY,
FONT_FAMILY_SUPPORT_KEY,
TEXT_ALIGN_SUPPORT_KEY,
TEXT_COLUMNS_SUPPORT_KEY,
TEXT_DECORATION_SUPPORT_KEY,
WRITING_MODE_SUPPORT_KEY,
TEXT_TRANSFORM_SUPPORT_KEY,
LETTER_SPACING_SUPPORT_KEY,
];
function styleToAttributes( style ) {
const updatedStyle = { ...omit( style, [ 'fontFamily' ] ) };
const fontSizeValue = style?.typography?.fontSize;
const fontFamilyValue = style?.typography?.fontFamily;
const fontSizeSlug = fontSizeValue?.startsWith( 'var:preset|font-size|' )
? fontSizeValue.substring( 'var:preset|font-size|'.length )
: undefined;
const fontFamilySlug = fontFamilyValue?.startsWith(
'var:preset|font-family|'
)
? fontFamilyValue.substring( 'var:preset|font-family|'.length )
: undefined;
updatedStyle.typography = {
...omit( updatedStyle.typography, [ 'fontFamily' ] ),
fontSize: fontSizeSlug ? undefined : fontSizeValue,
};
return {
style: cleanEmptyObject( updatedStyle ),
fontFamily: fontFamilySlug,
fontSize: fontSizeSlug,
};
}
function attributesToStyle( attributes ) {
return {
...attributes.style,
typography: {
...attributes.style?.typography,
fontFamily: attributes.fontFamily
? 'var:preset|font-family|' + attributes.fontFamily
: undefined,
fontSize: attributes.fontSize
? 'var:preset|font-size|' + attributes.fontSize
: attributes.style?.typography?.fontSize,
},
};
}
function TypographyInspectorControl( { children, resetAllFilter } ) {
const attributesResetAllFilter = useCallback(
( attributes ) => {
const existingStyle = attributesToStyle( attributes );
const updatedStyle = resetAllFilter( existingStyle );
return {
...attributes,
...styleToAttributes( updatedStyle ),
};
},
[ resetAllFilter ]
);
return (
<InspectorControls
group="typography"
resetAllFilter={ attributesResetAllFilter }
>
{ children }
</InspectorControls>
);
}
export function TypographyPanel( { clientId, name, setAttributes, settings } ) {
function selector( select ) {
const { style, fontFamily, fontSize } =
select( blockEditorStore ).getBlockAttributes( clientId ) || {};
return { style, fontFamily, fontSize };
}
const { style, fontFamily, fontSize } = useSelect( selector, [ clientId ] );
const isEnabled = useHasTypographyPanel( settings );
const value = useMemo(
() => attributesToStyle( { style, fontFamily, fontSize } ),
[ style, fontSize, fontFamily ]
);
const onChange = ( newStyle ) => {
setAttributes( styleToAttributes( newStyle ) );
};
if ( ! isEnabled ) {
return null;
}
const defaultControls = getBlockSupport( name, [
TYPOGRAPHY_SUPPORT_KEY,
'__experimentalDefaultControls',
] );
return (
<StylesTypographyPanel
as={ TypographyInspectorControl }
panelId={ clientId }
settings={ settings }
value={ value }
onChange={ onChange }
defaultControls={ defaultControls }
/>
);
}
export const hasTypographySupport = ( blockName ) => {
return TYPOGRAPHY_SUPPORT_KEYS.some( ( key ) =>
hasBlockSupport( blockName, key )
);
};