@wordpress/format-library
Version:
Format library for the WordPress editor.
173 lines (154 loc) • 3.92 kB
JavaScript
/**
* External dependencies
*/
import { StyleSheet, View } from 'react-native';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useMemo, useState } from '@wordpress/element';
import {
BlockControls,
useSettings,
useMobileGlobalStylesColors,
} from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import {
Icon,
color as colorIcon,
textColor as textColorIcon,
} from '@wordpress/icons';
import { removeFormat } from '@wordpress/rich-text';
import { usePreferredColorSchemeStyle } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { getActiveColors } from './inline.native.js';
import { default as InlineColorUI } from './inline';
import styles from './style.scss';
const name = 'core/text-color';
const title = __( 'Text color' );
function getComputedStyleProperty( element, property ) {
const style = element?.props?.style ?? {};
if ( property === 'background-color' ) {
const { backgroundColor, baseColors } = style;
if ( backgroundColor !== 'transparent' ) {
return backgroundColor;
} else if ( baseColors && baseColors?.color?.background ) {
return baseColors?.color?.background;
}
return 'transparent';
}
}
function fillComputedColors( element, { color, backgroundColor } ) {
if ( ! color && ! backgroundColor ) {
return;
}
return {
color: color || getComputedStyleProperty( element, 'color' ),
backgroundColor: getComputedStyleProperty(
element,
'background-color'
),
};
}
function TextColorEdit( {
value,
onChange,
isActive,
activeAttributes,
contentRef,
} ) {
const [ allowCustomControl ] = useSettings( 'color.custom' );
const colors = useMobileGlobalStylesColors();
const [ isAddingColor, setIsAddingColor ] = useState( false );
const colorIndicatorStyle = useMemo(
() =>
fillComputedColors(
contentRef,
getActiveColors( value, name, colors )
),
[ contentRef, value, colors ]
);
const hasColorsToChoose = colors.length || ! allowCustomControl;
const outlineStyle = [
usePreferredColorSchemeStyle(
styles[ 'components-inline-color__outline' ],
styles[ 'components-inline-color__outline--dark' ]
),
{ borderWidth: StyleSheet.hairlineWidth },
];
if ( ! hasColorsToChoose && ! isActive ) {
return null;
}
const isActiveStyle = {
...colorIndicatorStyle,
...( ! colorIndicatorStyle?.backgroundColor
? { backgroundColor: 'transparent' }
: {} ),
...styles[ 'components-inline-color--is-active' ],
};
const customContainerStyles =
styles[ 'components-inline-color__button-container' ];
return (
<>
<BlockControls>
<ToolbarGroup>
{ isActive && (
<View style={ outlineStyle } pointerEvents="none" />
) }
<ToolbarButton
name="text-color"
isActive={ isActive }
icon={
<Icon
icon={
Object.keys( activeAttributes ).length
? textColorIcon
: colorIcon
}
style={
colorIndicatorStyle?.color && {
color: colorIndicatorStyle.color,
}
}
/>
}
title={ title }
extraProps={ {
isActiveStyle,
customContainerStyles,
} }
// If has no colors to choose but a color is active remove the color onClick
onClick={
hasColorsToChoose
? () => setIsAddingColor( true )
: () => onChange( removeFormat( value, name ) )
}
/>
</ToolbarGroup>
</BlockControls>
{ isAddingColor && (
<InlineColorUI
name={ name }
onClose={ () => setIsAddingColor( false ) }
activeAttributes={ activeAttributes }
value={ value }
onChange={ onChange }
contentRef={ contentRef }
/>
) }
</>
);
}
export const textColor = {
name,
title,
tagName: 'mark',
className: 'has-inline-color',
attributes: {
style: 'style',
class: 'class',
},
edit: TextColorEdit,
};