@wordpress/format-library 3.0.14 → 3.0.18-next.33ec3857e2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/default-formats.native.js +3 -1
- package/build/default-formats.native.js.map +1 -1
- package/build/text-color/index.js +6 -4
- package/build/text-color/index.js.map +1 -1
- package/build/text-color/index.native.js +190 -0
- package/build/text-color/index.native.js.map +1 -0
- package/build/text-color/inline.js +6 -6
- package/build/text-color/inline.js.map +1 -1
- package/build/text-color/inline.native.js +169 -0
- package/build/text-color/inline.native.js.map +1 -0
- package/build-module/default-formats.native.js +2 -1
- package/build-module/default-formats.native.js.map +1 -1
- package/build-module/text-color/index.js +4 -3
- package/build-module/text-color/index.js.map +1 -1
- package/build-module/text-color/index.native.js +171 -0
- package/build-module/text-color/index.native.js.map +1 -0
- package/build-module/text-color/inline.js +7 -9
- package/build-module/text-color/inline.js.map +1 -1
- package/build-module/text-color/inline.native.js +156 -0
- package/build-module/text-color/inline.native.js.map +1 -0
- package/package.json +15 -15
- package/src/default-formats.native.js +2 -1
- package/src/text-color/index.js +5 -3
- package/src/text-color/index.native.js +191 -0
- package/src/text-color/inline.js +9 -7
- package/src/text-color/inline.native.js +163 -0
- package/src/text-color/style.native.scss +23 -0
package/src/text-color/index.js
CHANGED
|
@@ -17,6 +17,8 @@ import { removeFormat } from '@wordpress/rich-text';
|
|
|
17
17
|
*/
|
|
18
18
|
import { default as InlineColorUI, getActiveColors } from './inline';
|
|
19
19
|
|
|
20
|
+
export const transparentValue = 'rgba(0, 0, 0, 0)';
|
|
21
|
+
|
|
20
22
|
const name = 'core/text-color';
|
|
21
23
|
const title = __( 'Highlight' );
|
|
22
24
|
|
|
@@ -30,7 +32,7 @@ function getComputedStyleProperty( element, property ) {
|
|
|
30
32
|
|
|
31
33
|
if (
|
|
32
34
|
property === 'background-color' &&
|
|
33
|
-
value ===
|
|
35
|
+
value === transparentValue &&
|
|
34
36
|
element.parentElement
|
|
35
37
|
) {
|
|
36
38
|
return getComputedStyleProperty( element.parentElement, property );
|
|
@@ -47,7 +49,7 @@ function fillComputedColors( element, { color, backgroundColor } ) {
|
|
|
47
49
|
return {
|
|
48
50
|
color: color || getComputedStyleProperty( element, 'color' ),
|
|
49
51
|
backgroundColor:
|
|
50
|
-
backgroundColor ===
|
|
52
|
+
backgroundColor === transparentValue
|
|
51
53
|
? getComputedStyleProperty( element, 'background-color' )
|
|
52
54
|
: backgroundColor,
|
|
53
55
|
};
|
|
@@ -139,7 +141,7 @@ export const textColor = {
|
|
|
139
141
|
if ( key !== 'style' ) return value;
|
|
140
142
|
// We should not add a background-color if it's already set
|
|
141
143
|
if ( value && value.includes( 'background-color' ) ) return value;
|
|
142
|
-
const addedCSS = [ 'background-color',
|
|
144
|
+
const addedCSS = [ 'background-color', transparentValue ].join( ':' );
|
|
143
145
|
// Prepend `addedCSS` to avoid a double `;;` as any the existing CSS
|
|
144
146
|
// rules will already include a `;`.
|
|
145
147
|
return value ? [ addedCSS, value ].join( ';' ) : addedCSS;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { isEmpty } from 'lodash';
|
|
5
|
+
import { View } from 'react-native';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WordPress dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { __ } from '@wordpress/i18n';
|
|
11
|
+
import { useCallback, useMemo, useState } from '@wordpress/element';
|
|
12
|
+
import { BlockControls, useSetting } from '@wordpress/block-editor';
|
|
13
|
+
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
|
|
14
|
+
import { Icon, textColor as textColorIcon } from '@wordpress/icons';
|
|
15
|
+
import { removeFormat } from '@wordpress/rich-text';
|
|
16
|
+
import { usePreferredColorSchemeStyle } from '@wordpress/compose';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Internal dependencies
|
|
20
|
+
*/
|
|
21
|
+
import { getActiveColors } from './inline.js';
|
|
22
|
+
import { transparentValue } from './index.js';
|
|
23
|
+
import { default as InlineColorUI } from './inline';
|
|
24
|
+
import styles from './style.scss';
|
|
25
|
+
|
|
26
|
+
const name = 'core/text-color';
|
|
27
|
+
const title = __( 'Text color' );
|
|
28
|
+
|
|
29
|
+
const EMPTY_ARRAY = [];
|
|
30
|
+
|
|
31
|
+
function getComputedStyleProperty( element, property ) {
|
|
32
|
+
const {
|
|
33
|
+
props: { style = {} },
|
|
34
|
+
} = element;
|
|
35
|
+
|
|
36
|
+
if ( property === 'background-color' ) {
|
|
37
|
+
const { backgroundColor, baseColors } = style;
|
|
38
|
+
|
|
39
|
+
if ( backgroundColor !== 'transparent' ) {
|
|
40
|
+
return backgroundColor;
|
|
41
|
+
} else if ( baseColors && baseColors?.color?.background ) {
|
|
42
|
+
return baseColors?.color?.background;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return 'transparent';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function fillComputedColors( element, { color, backgroundColor } ) {
|
|
50
|
+
if ( ! color && ! backgroundColor ) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
color: color || getComputedStyleProperty( element, 'color' ),
|
|
56
|
+
backgroundColor: getComputedStyleProperty(
|
|
57
|
+
element,
|
|
58
|
+
'background-color'
|
|
59
|
+
),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function TextColorEdit( {
|
|
64
|
+
value,
|
|
65
|
+
onChange,
|
|
66
|
+
isActive,
|
|
67
|
+
activeAttributes,
|
|
68
|
+
contentRef,
|
|
69
|
+
} ) {
|
|
70
|
+
const allowCustomControl = useSetting( 'color.custom' );
|
|
71
|
+
const colors = useSetting( 'color.palette' ) || EMPTY_ARRAY;
|
|
72
|
+
const [ isAddingColor, setIsAddingColor ] = useState( false );
|
|
73
|
+
const enableIsAddingColor = useCallback( () => setIsAddingColor( true ), [
|
|
74
|
+
setIsAddingColor,
|
|
75
|
+
] );
|
|
76
|
+
const disableIsAddingColor = useCallback( () => setIsAddingColor( false ), [
|
|
77
|
+
setIsAddingColor,
|
|
78
|
+
] );
|
|
79
|
+
const colorIndicatorStyle = useMemo(
|
|
80
|
+
() =>
|
|
81
|
+
fillComputedColors(
|
|
82
|
+
contentRef,
|
|
83
|
+
getActiveColors( value, name, colors )
|
|
84
|
+
),
|
|
85
|
+
[ value, colors ]
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const hasColorsToChoose = ! isEmpty( colors ) || ! allowCustomControl;
|
|
89
|
+
|
|
90
|
+
const onPressButton = useCallback( () => {
|
|
91
|
+
if ( hasColorsToChoose ) {
|
|
92
|
+
enableIsAddingColor();
|
|
93
|
+
} else {
|
|
94
|
+
onChange( removeFormat( value, name ) );
|
|
95
|
+
}
|
|
96
|
+
}, [ hasColorsToChoose, value ] );
|
|
97
|
+
|
|
98
|
+
const outlineStyle = usePreferredColorSchemeStyle(
|
|
99
|
+
styles[ 'components-inline-color__outline' ],
|
|
100
|
+
styles[ 'components-inline-color__outline--dark' ]
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
if ( ! hasColorsToChoose && ! isActive ) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const isActiveStyle = {
|
|
108
|
+
...colorIndicatorStyle,
|
|
109
|
+
...( ! colorIndicatorStyle?.backgroundColor
|
|
110
|
+
? { backgroundColor: 'transparent' }
|
|
111
|
+
: {} ),
|
|
112
|
+
...styles[ 'components-inline-color--is-active' ],
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const customContainerStyles =
|
|
116
|
+
styles[ 'components-inline-color__button-container' ];
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<>
|
|
120
|
+
<BlockControls>
|
|
121
|
+
<ToolbarGroup>
|
|
122
|
+
{ isActive && (
|
|
123
|
+
<View style={ outlineStyle } pointerEvents="none" />
|
|
124
|
+
) }
|
|
125
|
+
|
|
126
|
+
<ToolbarButton
|
|
127
|
+
name="text-color"
|
|
128
|
+
isActive={ isActive }
|
|
129
|
+
icon={
|
|
130
|
+
<Icon
|
|
131
|
+
icon={ textColorIcon }
|
|
132
|
+
style={
|
|
133
|
+
colorIndicatorStyle?.color && {
|
|
134
|
+
color: colorIndicatorStyle.color,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/>
|
|
138
|
+
}
|
|
139
|
+
title={ title }
|
|
140
|
+
extraProps={ {
|
|
141
|
+
isActiveStyle,
|
|
142
|
+
customContainerStyles,
|
|
143
|
+
} }
|
|
144
|
+
// If has no colors to choose but a color is active remove the color onClick
|
|
145
|
+
onClick={ onPressButton }
|
|
146
|
+
/>
|
|
147
|
+
</ToolbarGroup>
|
|
148
|
+
</BlockControls>
|
|
149
|
+
{ isAddingColor && (
|
|
150
|
+
<InlineColorUI
|
|
151
|
+
name={ name }
|
|
152
|
+
onClose={ disableIsAddingColor }
|
|
153
|
+
activeAttributes={ activeAttributes }
|
|
154
|
+
value={ value }
|
|
155
|
+
onChange={ onChange }
|
|
156
|
+
contentRef={ contentRef }
|
|
157
|
+
/>
|
|
158
|
+
) }
|
|
159
|
+
</>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const textColor = {
|
|
164
|
+
name,
|
|
165
|
+
title,
|
|
166
|
+
tagName: 'mark',
|
|
167
|
+
className: 'has-inline-color',
|
|
168
|
+
attributes: {
|
|
169
|
+
style: 'style',
|
|
170
|
+
class: 'class',
|
|
171
|
+
},
|
|
172
|
+
/*
|
|
173
|
+
* Since this format relies on the <mark> tag, it's important to
|
|
174
|
+
* prevent the default yellow background color applied by most
|
|
175
|
+
* browsers. The solution is to detect when this format is used with a
|
|
176
|
+
* text color but no background color, and in such cases to override
|
|
177
|
+
* the default styling with a transparent background.
|
|
178
|
+
*
|
|
179
|
+
* @see https://github.com/WordPress/gutenberg/pull/35516
|
|
180
|
+
*/
|
|
181
|
+
__unstableFilterAttributeValue( key, value ) {
|
|
182
|
+
if ( key !== 'style' ) return value;
|
|
183
|
+
// We should not add a background-color if it's already set
|
|
184
|
+
if ( value && value.includes( 'background-color' ) ) return value;
|
|
185
|
+
const addedCSS = [ 'background-color', transparentValue ].join( ':' );
|
|
186
|
+
// Prepend `addedCSS` to avoid a double `;;` as any the existing CSS
|
|
187
|
+
// rules will already include a `;`.
|
|
188
|
+
return value ? [ addedCSS, value ].join( ';' ) : addedCSS;
|
|
189
|
+
},
|
|
190
|
+
edit: TextColorEdit,
|
|
191
|
+
};
|
package/src/text-color/inline.js
CHANGED
|
@@ -28,25 +28,27 @@ import { __ } from '@wordpress/i18n';
|
|
|
28
28
|
/**
|
|
29
29
|
* Internal dependencies
|
|
30
30
|
*/
|
|
31
|
-
import { textColor as settings } from './index';
|
|
31
|
+
import { textColor as settings, transparentValue } from './index';
|
|
32
32
|
|
|
33
33
|
function parseCSS( css = '' ) {
|
|
34
34
|
return css.split( ';' ).reduce( ( accumulator, rule ) => {
|
|
35
35
|
if ( rule ) {
|
|
36
36
|
const [ property, value ] = rule.split( ':' );
|
|
37
37
|
if ( property === 'color' ) accumulator.color = value;
|
|
38
|
-
if ( property === 'background-color' )
|
|
38
|
+
if ( property === 'background-color' && value !== transparentValue )
|
|
39
39
|
accumulator.backgroundColor = value;
|
|
40
40
|
}
|
|
41
41
|
return accumulator;
|
|
42
42
|
}, {} );
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function parseClassName( className = '', colorSettings ) {
|
|
45
|
+
export function parseClassName( className = '', colorSettings ) {
|
|
46
46
|
return className.split( ' ' ).reduce( ( accumulator, name ) => {
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
const
|
|
47
|
+
// `colorSlug` could contain dashes, so simply match the start and end.
|
|
48
|
+
if ( name.startsWith( 'has-' ) && name.endsWith( '-color' ) ) {
|
|
49
|
+
const colorSlug = name
|
|
50
|
+
.replace( /^has-/, '' )
|
|
51
|
+
.replace( /-color$/, '' );
|
|
50
52
|
const colorObject = getColorObjectByAttributeValues(
|
|
51
53
|
colorSettings,
|
|
52
54
|
colorSlug
|
|
@@ -88,7 +90,7 @@ function setColors( value, name, colorSettings, colors ) {
|
|
|
88
90
|
styles.push( [ 'background-color', backgroundColor ].join( ':' ) );
|
|
89
91
|
} else {
|
|
90
92
|
// Override default browser color for mark element.
|
|
91
|
-
styles.push( [ 'background-color',
|
|
93
|
+
styles.push( [ 'background-color', transparentValue ].join( ':' ) );
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
if ( color ) {
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback, useMemo } from '@wordpress/element';
|
|
5
|
+
import {
|
|
6
|
+
applyFormat,
|
|
7
|
+
removeFormat,
|
|
8
|
+
getActiveFormat,
|
|
9
|
+
} from '@wordpress/rich-text';
|
|
10
|
+
import {
|
|
11
|
+
useSetting,
|
|
12
|
+
getColorClassName,
|
|
13
|
+
getColorObjectByColorValue,
|
|
14
|
+
} from '@wordpress/block-editor';
|
|
15
|
+
import { BottomSheet, ColorSettings } from '@wordpress/components';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Internal dependencies
|
|
19
|
+
*/
|
|
20
|
+
import { textColor as settings } from './index';
|
|
21
|
+
import { transparentValue } from './index.js';
|
|
22
|
+
import { parseClassName } from './inline.js';
|
|
23
|
+
|
|
24
|
+
function parseCSS( css = '' ) {
|
|
25
|
+
return css.split( ';' ).reduce( ( accumulator, rule ) => {
|
|
26
|
+
if ( rule ) {
|
|
27
|
+
const [ property, value ] = rule.replace( / /g, '' ).split( ':' );
|
|
28
|
+
if ( property === 'color' ) accumulator.color = value;
|
|
29
|
+
if ( property === 'background-color' && value !== transparentValue )
|
|
30
|
+
accumulator.backgroundColor = value;
|
|
31
|
+
}
|
|
32
|
+
return accumulator;
|
|
33
|
+
}, {} );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getActiveColors( value, name, colorSettings ) {
|
|
37
|
+
const activeColorFormat = getActiveFormat( value, name );
|
|
38
|
+
|
|
39
|
+
if ( ! activeColorFormat ) {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
...parseCSS( activeColorFormat.attributes.style ),
|
|
45
|
+
...parseClassName( activeColorFormat.attributes.class, colorSettings ),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function setColors( value, name, colorSettings, colors ) {
|
|
50
|
+
const { color, backgroundColor } = {
|
|
51
|
+
...getActiveColors( value, name, colorSettings ),
|
|
52
|
+
...colors,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
if ( ! color && ! backgroundColor ) {
|
|
56
|
+
return removeFormat( value, name );
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const styles = [];
|
|
60
|
+
const classNames = [];
|
|
61
|
+
const attributes = {};
|
|
62
|
+
|
|
63
|
+
if ( backgroundColor ) {
|
|
64
|
+
styles.push( [ 'background-color', backgroundColor ].join( ':' ) );
|
|
65
|
+
} else {
|
|
66
|
+
// Override default browser color for mark element.
|
|
67
|
+
styles.push( [ 'background-color', transparentValue ].join( ':' ) );
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if ( color ) {
|
|
71
|
+
const colorObject = getColorObjectByColorValue( colorSettings, color );
|
|
72
|
+
|
|
73
|
+
if ( colorObject ) {
|
|
74
|
+
classNames.push( getColorClassName( 'color', colorObject.slug ) );
|
|
75
|
+
styles.push( [ 'color', colorObject.color ].join( ':' ) );
|
|
76
|
+
} else {
|
|
77
|
+
styles.push( [ 'color', color ].join( ':' ) );
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if ( styles.length ) attributes.style = styles.join( ';' );
|
|
82
|
+
if ( classNames.length ) attributes.class = classNames.join( ' ' );
|
|
83
|
+
|
|
84
|
+
const format = { type: name, attributes };
|
|
85
|
+
|
|
86
|
+
// For cases when there is no text selected, formatting is forced
|
|
87
|
+
// for the first empty character
|
|
88
|
+
if (
|
|
89
|
+
value?.start === value?.end &&
|
|
90
|
+
( value?.text.length === 0 ||
|
|
91
|
+
value.text?.charAt( value.end - 1 ) === ' ' )
|
|
92
|
+
) {
|
|
93
|
+
return applyFormat( value, format, value?.start - 1, value?.end + 1 );
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return applyFormat( value, format );
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function ColorPicker( { name, value, onChange } ) {
|
|
100
|
+
const property = 'color';
|
|
101
|
+
const colors = useSetting( 'color.palette' ) || settings.colors;
|
|
102
|
+
const colorSettings = {
|
|
103
|
+
colors,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const onColorChange = useCallback(
|
|
107
|
+
( color ) => {
|
|
108
|
+
if ( color !== '' ) {
|
|
109
|
+
onChange(
|
|
110
|
+
setColors( value, name, colors, { [ property ]: color } )
|
|
111
|
+
);
|
|
112
|
+
// Remove formatting if the color was reset, there's no
|
|
113
|
+
// current selection and the previous character is a space
|
|
114
|
+
} else if (
|
|
115
|
+
value?.start === value?.end &&
|
|
116
|
+
value.text?.charAt( value?.end - 1 ) === ' '
|
|
117
|
+
) {
|
|
118
|
+
onChange(
|
|
119
|
+
removeFormat( value, name, value.end - 1, value.end )
|
|
120
|
+
);
|
|
121
|
+
} else {
|
|
122
|
+
onChange( removeFormat( value, name ) );
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
[ colors, onChange, property ]
|
|
126
|
+
);
|
|
127
|
+
const activeColors = useMemo(
|
|
128
|
+
() => getActiveColors( value, name, colors ),
|
|
129
|
+
[ name, value, colors ]
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<ColorSettings
|
|
134
|
+
colorValue={ activeColors[ property ] }
|
|
135
|
+
onColorChange={ onColorChange }
|
|
136
|
+
defaultSettings={ colorSettings }
|
|
137
|
+
hideNavigation
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export default function InlineColorUI( { name, value, onChange, onClose } ) {
|
|
143
|
+
return (
|
|
144
|
+
<BottomSheet
|
|
145
|
+
isVisible
|
|
146
|
+
onClose={ onClose }
|
|
147
|
+
hideHeader
|
|
148
|
+
contentStyle={ { paddingLeft: 0, paddingRight: 0 } }
|
|
149
|
+
hasNavigation
|
|
150
|
+
leftButton={ null }
|
|
151
|
+
>
|
|
152
|
+
<BottomSheet.NavigationContainer animate main>
|
|
153
|
+
<BottomSheet.NavigationScreen name="text-color">
|
|
154
|
+
<ColorPicker
|
|
155
|
+
name={ name }
|
|
156
|
+
value={ value }
|
|
157
|
+
onChange={ onChange }
|
|
158
|
+
/>
|
|
159
|
+
</BottomSheet.NavigationScreen>
|
|
160
|
+
</BottomSheet.NavigationContainer>
|
|
161
|
+
</BottomSheet>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.components-inline-color--is-active {
|
|
2
|
+
border-radius: 18px;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.components-inline-color__outline {
|
|
6
|
+
border-color: $light-dim;
|
|
7
|
+
top: 6px;
|
|
8
|
+
bottom: 6px;
|
|
9
|
+
left: 11px;
|
|
10
|
+
right: 11px;
|
|
11
|
+
border-radius: 24px;
|
|
12
|
+
border-width: $border-width;
|
|
13
|
+
position: absolute;
|
|
14
|
+
z-index: 2;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.components-inline-color__outline--dark {
|
|
18
|
+
border-color: $dark-ultra-dim;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.components-inline-color__button-container {
|
|
22
|
+
padding: 6px;
|
|
23
|
+
}
|