@wordpress/block-editor 10.0.4 → 10.0.6
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/CHANGELOG.md +9 -0
- package/README.md +40 -0
- package/build/components/block-inspector/index.js +3 -4
- package/build/components/block-inspector/index.js.map +1 -1
- package/build/components/block-list/block.js +72 -14
- package/build/components/block-list/block.js.map +1 -1
- package/build/components/font-sizes/fluid-utils.js +208 -0
- package/build/components/font-sizes/fluid-utils.js.map +1 -0
- package/build/components/font-sizes/index.js +8 -0
- package/build/components/font-sizes/index.js.map +1 -1
- package/build/components/inserter/search-items.js +2 -17
- package/build/components/inserter/search-items.js.map +1 -1
- package/build/hooks/font-size.js +60 -0
- package/build/hooks/font-size.js.map +1 -1
- package/build/hooks/margin.js +4 -4
- package/build/hooks/margin.js.map +1 -1
- package/build/hooks/use-typography-props.js +17 -3
- package/build/hooks/use-typography-props.js.map +1 -1
- package/build-module/components/block-inspector/index.js +3 -4
- package/build-module/components/block-inspector/index.js.map +1 -1
- package/build-module/components/block-list/block.js +72 -14
- package/build-module/components/block-list/block.js.map +1 -1
- package/build-module/components/font-sizes/fluid-utils.js +197 -0
- package/build-module/components/font-sizes/fluid-utils.js.map +1 -0
- package/build-module/components/font-sizes/index.js +1 -0
- package/build-module/components/font-sizes/index.js.map +1 -1
- package/build-module/components/inserter/search-items.js +3 -17
- package/build-module/components/inserter/search-items.js.map +1 -1
- package/build-module/hooks/font-size.js +59 -1
- package/build-module/hooks/font-size.js.map +1 -1
- package/build-module/hooks/margin.js +4 -4
- package/build-module/hooks/margin.js.map +1 -1
- package/build-module/hooks/use-typography-props.js +17 -4
- package/build-module/hooks/use-typography-props.js.map +1 -1
- package/build-style/style-rtl.css +61 -106
- package/build-style/style.css +61 -106
- package/package.json +3 -4
- package/src/components/block-inspector/index.js +4 -7
- package/src/components/block-list/block.js +111 -7
- package/src/components/block-list/style.scss +85 -133
- package/src/components/button-block-appender/style.scss +3 -1
- package/src/components/font-sizes/fluid-utils.js +221 -0
- package/src/components/font-sizes/index.js +1 -0
- package/src/components/font-sizes/test/fluid-utils.js +168 -0
- package/src/components/inserter/search-items.js +3 -15
- package/src/components/inserter/test/search-items.js +4 -0
- package/src/hooks/font-size.js +75 -0
- package/src/hooks/margin.js +4 -4
- package/src/hooks/test/use-typography-props.js +22 -0
- package/src/hooks/use-typography-props.js +18 -3
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fluid utilities must match the backend equivalent.
|
|
3
|
+
* See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php
|
|
4
|
+
* ---------------------------------------------------------------
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Defaults.
|
|
8
|
+
const DEFAULT_MAXIMUM_VIEWPORT_WIDTH = '1600px';
|
|
9
|
+
const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '768px';
|
|
10
|
+
const DEFAULT_SCALE_FACTOR = 1;
|
|
11
|
+
const DEFAULT_MINIMUM_FONT_SIZE_FACTOR = 0.75;
|
|
12
|
+
const DEFAULT_MAXIMUM_FONT_SIZE_FACTOR = 1.5;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Computes a fluid font-size value that uses clamp(). A minimum and maxinmum
|
|
16
|
+
* font size OR a single font size can be specified.
|
|
17
|
+
*
|
|
18
|
+
* If a single font size is specified, it is scaled up and down by
|
|
19
|
+
* minimumFontSizeFactor and maximumFontSizeFactor to arrive at the minimum and
|
|
20
|
+
* maximum sizes.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```js
|
|
24
|
+
* // Calculate fluid font-size value from a minimum and maximum value.
|
|
25
|
+
* const fontSize = getComputedFluidTypographyValue( {
|
|
26
|
+
* minimumFontSize: '20px',
|
|
27
|
+
* maximumFontSize: '45px'
|
|
28
|
+
* } );
|
|
29
|
+
* // Calculate fluid font-size value from a single font size.
|
|
30
|
+
* const fontSize = getComputedFluidTypographyValue( {
|
|
31
|
+
* fontSize: '30px',
|
|
32
|
+
* } );
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @param {Object} args
|
|
36
|
+
* @param {?string} args.minimumViewPortWidth Minimum viewport size from which type will have fluidity. Optional if fontSize is specified.
|
|
37
|
+
* @param {?string} args.maximumViewPortWidth Maximum size up to which type will have fluidity. Optional if fontSize is specified.
|
|
38
|
+
* @param {string|number} [args.fontSize] Size to derive maximumFontSize and minimumFontSize from, if necessary. Optional if minimumFontSize and maximumFontSize are specified.
|
|
39
|
+
* @param {?string} args.maximumFontSize Maximum font size for any clamp() calculation. Optional.
|
|
40
|
+
* @param {?string} args.minimumFontSize Minimum font size for any clamp() calculation. Optional.
|
|
41
|
+
* @param {?number} args.scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional.
|
|
42
|
+
* @param {?number} args.minimumFontSizeFactor How much to scale defaultFontSize by to derive minimumFontSize. Optional.
|
|
43
|
+
* @param {?number} args.maximumFontSizeFactor How much to scale defaultFontSize by to derive maximumFontSize. Optional.
|
|
44
|
+
*
|
|
45
|
+
* @return {string|null} A font-size value using clamp().
|
|
46
|
+
*/
|
|
47
|
+
export function getComputedFluidTypographyValue( {
|
|
48
|
+
minimumFontSize,
|
|
49
|
+
maximumFontSize,
|
|
50
|
+
fontSize,
|
|
51
|
+
minimumViewPortWidth = DEFAULT_MINIMUM_VIEWPORT_WIDTH,
|
|
52
|
+
maximumViewPortWidth = DEFAULT_MAXIMUM_VIEWPORT_WIDTH,
|
|
53
|
+
scaleFactor = DEFAULT_SCALE_FACTOR,
|
|
54
|
+
minimumFontSizeFactor = DEFAULT_MINIMUM_FONT_SIZE_FACTOR,
|
|
55
|
+
maximumFontSizeFactor = DEFAULT_MAXIMUM_FONT_SIZE_FACTOR,
|
|
56
|
+
} ) {
|
|
57
|
+
// Calculate missing minimumFontSize and maximumFontSize from
|
|
58
|
+
// defaultFontSize if provided.
|
|
59
|
+
if ( fontSize && ( ! minimumFontSize || ! maximumFontSize ) ) {
|
|
60
|
+
// Parse default font size.
|
|
61
|
+
const fontSizeParsed = getTypographyValueAndUnit( fontSize );
|
|
62
|
+
|
|
63
|
+
// Protect against invalid units.
|
|
64
|
+
if ( ! fontSizeParsed?.unit ) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If no minimumFontSize is provided, derive using min scale factor.
|
|
69
|
+
if ( ! minimumFontSize ) {
|
|
70
|
+
minimumFontSize =
|
|
71
|
+
fontSizeParsed.value * minimumFontSizeFactor +
|
|
72
|
+
fontSizeParsed.unit;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// If no maximumFontSize is provided, derive using max scale factor.
|
|
76
|
+
if ( ! maximumFontSize ) {
|
|
77
|
+
maximumFontSize =
|
|
78
|
+
fontSizeParsed.value * maximumFontSizeFactor +
|
|
79
|
+
fontSizeParsed.unit;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Return early if one of the provided inputs is not provided.
|
|
84
|
+
if ( ! minimumFontSize || ! maximumFontSize ) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Grab the minimum font size and normalize it in order to use the value for calculations.
|
|
89
|
+
const minimumFontSizeParsed = getTypographyValueAndUnit( minimumFontSize );
|
|
90
|
+
|
|
91
|
+
// We get a 'preferred' unit to keep units consistent when calculating,
|
|
92
|
+
// otherwise the result will not be accurate.
|
|
93
|
+
const fontSizeUnit = minimumFontSizeParsed?.unit || 'rem';
|
|
94
|
+
|
|
95
|
+
// Grab the maximum font size and normalize it in order to use the value for calculations.
|
|
96
|
+
const maximumFontSizeParsed = getTypographyValueAndUnit( maximumFontSize, {
|
|
97
|
+
coerceTo: fontSizeUnit,
|
|
98
|
+
} );
|
|
99
|
+
|
|
100
|
+
// Protect against unsupported units.
|
|
101
|
+
if ( ! minimumFontSizeParsed || ! maximumFontSizeParsed ) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Use rem for accessible fluid target font scaling.
|
|
106
|
+
const minimumFontSizeRem = getTypographyValueAndUnit( minimumFontSize, {
|
|
107
|
+
coerceTo: 'rem',
|
|
108
|
+
} );
|
|
109
|
+
|
|
110
|
+
// Viewport widths defined for fluid typography. Normalize units
|
|
111
|
+
const maximumViewPortWidthParsed = getTypographyValueAndUnit(
|
|
112
|
+
maximumViewPortWidth,
|
|
113
|
+
{ coerceTo: fontSizeUnit }
|
|
114
|
+
);
|
|
115
|
+
const minumumViewPortWidthParsed = getTypographyValueAndUnit(
|
|
116
|
+
minimumViewPortWidth,
|
|
117
|
+
{ coerceTo: fontSizeUnit }
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Protect against unsupported units.
|
|
121
|
+
if (
|
|
122
|
+
! maximumViewPortWidthParsed ||
|
|
123
|
+
! minumumViewPortWidthParsed ||
|
|
124
|
+
! minimumFontSizeRem
|
|
125
|
+
) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Build CSS rule.
|
|
130
|
+
// Borrowed from https://websemantics.uk/tools/responsive-font-calculator/.
|
|
131
|
+
const minViewPortWidthOffsetValue = roundToPrecision(
|
|
132
|
+
minumumViewPortWidthParsed.value / 100,
|
|
133
|
+
3
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const viewPortWidthOffset = minViewPortWidthOffsetValue + fontSizeUnit;
|
|
137
|
+
let linearFactor =
|
|
138
|
+
100 *
|
|
139
|
+
( ( maximumFontSizeParsed.value - minimumFontSizeParsed.value ) /
|
|
140
|
+
( maximumViewPortWidthParsed.value -
|
|
141
|
+
minumumViewPortWidthParsed.value ) );
|
|
142
|
+
linearFactor = roundToPrecision( linearFactor, 3 ) || 1;
|
|
143
|
+
const linearFactorScaled = linearFactor * scaleFactor;
|
|
144
|
+
const fluidTargetFontSize = `${ minimumFontSizeRem.value }${ minimumFontSizeRem.unit } + ((1vw - ${ viewPortWidthOffset }) * ${ linearFactorScaled })`;
|
|
145
|
+
|
|
146
|
+
return `clamp(${ minimumFontSize }, ${ fluidTargetFontSize }, ${ maximumFontSize })`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Internal method that checks a string for a unit and value and returns an array consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ].
|
|
151
|
+
* A raw font size of `value + unit` is expected. If the value is an integer, it will convert to `value + 'px'`.
|
|
152
|
+
*
|
|
153
|
+
* @param {string|number} rawValue Raw size value from theme.json.
|
|
154
|
+
* @param {Object|undefined} options Calculation options.
|
|
155
|
+
*
|
|
156
|
+
* @return {{ unit: string, value: number }|null} An object consisting of `'value'` and `'unit'` properties.
|
|
157
|
+
*/
|
|
158
|
+
export function getTypographyValueAndUnit( rawValue, options = {} ) {
|
|
159
|
+
if ( typeof rawValue !== 'string' && typeof rawValue !== 'number' ) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Converts numeric values to pixel values by default.
|
|
164
|
+
if ( isFinite( rawValue ) ) {
|
|
165
|
+
rawValue = `${ rawValue }px`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const { coerceTo, rootSizeValue, acceptableUnits } = {
|
|
169
|
+
coerceTo: '',
|
|
170
|
+
// Default browser font size. Later we could inject some JS to compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`.
|
|
171
|
+
rootSizeValue: 16,
|
|
172
|
+
acceptableUnits: [ 'rem', 'px', 'em' ],
|
|
173
|
+
...options,
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const acceptableUnitsGroup = acceptableUnits?.join( '|' );
|
|
177
|
+
const regexUnits = new RegExp(
|
|
178
|
+
`^(\\d*\\.?\\d+)(${ acceptableUnitsGroup }){1,1}$`
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const matches = rawValue.match( regexUnits );
|
|
182
|
+
|
|
183
|
+
// We need a number value and a unit.
|
|
184
|
+
if ( ! matches || matches.length < 3 ) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let [ , value, unit ] = matches;
|
|
189
|
+
|
|
190
|
+
let returnValue = parseFloat( value );
|
|
191
|
+
|
|
192
|
+
if ( 'px' === coerceTo && ( 'em' === unit || 'rem' === unit ) ) {
|
|
193
|
+
returnValue = returnValue * rootSizeValue;
|
|
194
|
+
unit = coerceTo;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if ( 'px' === unit && ( 'em' === coerceTo || 'rem' === coerceTo ) ) {
|
|
198
|
+
returnValue = returnValue / rootSizeValue;
|
|
199
|
+
unit = coerceTo;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
value: returnValue,
|
|
204
|
+
unit,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Returns a value rounded to defined precision.
|
|
210
|
+
* Returns `undefined` if the value is not a valid finite number.
|
|
211
|
+
*
|
|
212
|
+
* @param {number} value Raw value.
|
|
213
|
+
* @param {number} digits The number of digits to appear after the decimal point
|
|
214
|
+
*
|
|
215
|
+
* @return {number|undefined} Value rounded to standard precision.
|
|
216
|
+
*/
|
|
217
|
+
export function roundToPrecision( value, digits = 3 ) {
|
|
218
|
+
return Number.isFinite( value )
|
|
219
|
+
? parseFloat( value.toFixed( digits ) )
|
|
220
|
+
: undefined;
|
|
221
|
+
}
|
|
@@ -3,5 +3,6 @@ export {
|
|
|
3
3
|
getFontSizeClass,
|
|
4
4
|
getFontSizeObjectByValue,
|
|
5
5
|
} from './utils';
|
|
6
|
+
export { getComputedFluidTypographyValue } from './fluid-utils';
|
|
6
7
|
export { default as FontSizePicker } from './font-size-picker';
|
|
7
8
|
export { default as withFontSizes } from './with-font-sizes';
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { logged } from '@wordpress/deprecated';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
getComputedFluidTypographyValue,
|
|
11
|
+
getTypographyValueAndUnit,
|
|
12
|
+
} from '../fluid-utils';
|
|
13
|
+
|
|
14
|
+
describe( 'getComputedFluidTypographyValue()', () => {
|
|
15
|
+
afterEach( () => {
|
|
16
|
+
for ( const key in logged ) {
|
|
17
|
+
delete logged[ key ];
|
|
18
|
+
}
|
|
19
|
+
} );
|
|
20
|
+
|
|
21
|
+
it( 'should return a fluid font size when given a min and max font size', () => {
|
|
22
|
+
const fluidTypographyValues = getComputedFluidTypographyValue( {
|
|
23
|
+
minimumFontSize: '20px',
|
|
24
|
+
maximumFontSize: '45px',
|
|
25
|
+
} );
|
|
26
|
+
expect( fluidTypographyValues ).toBe(
|
|
27
|
+
'clamp(20px, 1.25rem + ((1vw - 7.68px) * 3.005), 45px)'
|
|
28
|
+
);
|
|
29
|
+
} );
|
|
30
|
+
|
|
31
|
+
it( 'should return a fluid font size when given a font size', () => {
|
|
32
|
+
const fluidTypographyValues = getComputedFluidTypographyValue( {
|
|
33
|
+
fontSize: '30px',
|
|
34
|
+
} );
|
|
35
|
+
expect( fluidTypographyValues ).toBe(
|
|
36
|
+
'clamp(22.5px, 1.40625rem + ((1vw - 7.68px) * 2.704), 45px)'
|
|
37
|
+
);
|
|
38
|
+
} );
|
|
39
|
+
|
|
40
|
+
it( 'should return a fluid font size based on px when given a numerical font size', () => {
|
|
41
|
+
const fluidTypographyValues = getComputedFluidTypographyValue( {
|
|
42
|
+
fontSize: '30px',
|
|
43
|
+
} );
|
|
44
|
+
expect( fluidTypographyValues ).toBe(
|
|
45
|
+
'clamp(22.5px, 1.40625rem + ((1vw - 7.68px) * 2.704), 45px)'
|
|
46
|
+
);
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
it( 'should return a fluid font size when given a min and max viewport width', () => {
|
|
50
|
+
const fluidTypographyValues = getComputedFluidTypographyValue( {
|
|
51
|
+
fontSize: '30px',
|
|
52
|
+
minimumViewPortWidth: '500px',
|
|
53
|
+
maximumViewPortWidth: '1000px',
|
|
54
|
+
} );
|
|
55
|
+
expect( fluidTypographyValues ).toBe(
|
|
56
|
+
'clamp(22.5px, 1.40625rem + ((1vw - 5px) * 4.5), 45px)'
|
|
57
|
+
);
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
it( 'should return a fluid font size when given a scale factor', () => {
|
|
61
|
+
const fluidTypographyValues = getComputedFluidTypographyValue( {
|
|
62
|
+
fontSize: '30px',
|
|
63
|
+
scaleFactor: '2',
|
|
64
|
+
} );
|
|
65
|
+
expect( fluidTypographyValues ).toBe(
|
|
66
|
+
'clamp(22.5px, 1.40625rem + ((1vw - 7.68px) * 5.408), 45px)'
|
|
67
|
+
);
|
|
68
|
+
} );
|
|
69
|
+
|
|
70
|
+
it( 'should return a fluid font size when given a min and max font size factor', () => {
|
|
71
|
+
const fluidTypographyValues = getComputedFluidTypographyValue( {
|
|
72
|
+
fontSize: '30px',
|
|
73
|
+
minimumFontSizeFactor: '0.5',
|
|
74
|
+
maximumFontSizeFactor: '2',
|
|
75
|
+
} );
|
|
76
|
+
expect( fluidTypographyValues ).toBe(
|
|
77
|
+
'clamp(15px, 0.9375rem + ((1vw - 7.68px) * 5.409), 60px)'
|
|
78
|
+
);
|
|
79
|
+
} );
|
|
80
|
+
|
|
81
|
+
describe( 'getTypographyValueAndUnit', () => {
|
|
82
|
+
it( 'should return the expected return values', () => {
|
|
83
|
+
[
|
|
84
|
+
{
|
|
85
|
+
value: null,
|
|
86
|
+
expected: null,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
value: false,
|
|
90
|
+
expected: null,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
value: true,
|
|
94
|
+
expected: null,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
value: [ '10' ],
|
|
98
|
+
expected: null,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
value: '10vh',
|
|
102
|
+
expected: null,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
value: 'calc(2 * 10px)',
|
|
106
|
+
expected: null,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
value: 'clamp(15px, 0.9375rem + ((1vw - 7.68px) * 5.409), 60px)',
|
|
110
|
+
expected: null,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
value: '10',
|
|
114
|
+
expected: {
|
|
115
|
+
value: 10,
|
|
116
|
+
unit: 'px',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
value: 11,
|
|
121
|
+
expected: {
|
|
122
|
+
value: 11,
|
|
123
|
+
unit: 'px',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
value: 11.234,
|
|
128
|
+
expected: {
|
|
129
|
+
value: 11.234,
|
|
130
|
+
unit: 'px',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
value: '12rem',
|
|
135
|
+
expected: {
|
|
136
|
+
value: 12,
|
|
137
|
+
unit: 'rem',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
value: '12px',
|
|
142
|
+
expected: {
|
|
143
|
+
value: 12,
|
|
144
|
+
unit: 'px',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
value: '12em',
|
|
149
|
+
expected: {
|
|
150
|
+
value: 12,
|
|
151
|
+
unit: 'em',
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
value: '12.74em',
|
|
156
|
+
expected: {
|
|
157
|
+
value: 12.74,
|
|
158
|
+
unit: 'em',
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
].forEach( ( { value, expected } ) => {
|
|
162
|
+
expect( getTypographyValueAndUnit( value ) ).toEqual(
|
|
163
|
+
expected
|
|
164
|
+
);
|
|
165
|
+
} );
|
|
166
|
+
} );
|
|
167
|
+
} );
|
|
168
|
+
} );
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { noCase } from 'change-case';
|
|
5
4
|
import removeAccents from 'remove-accents';
|
|
6
|
-
import { find } from 'lodash';
|
|
5
|
+
import { find, words } from 'lodash';
|
|
7
6
|
|
|
8
7
|
// Default search helpers.
|
|
9
8
|
const defaultGetName = ( item ) => item.name || '';
|
|
@@ -36,17 +35,6 @@ function normalizeSearchInput( input = '' ) {
|
|
|
36
35
|
return input;
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
/**
|
|
40
|
-
* Extracts words from an input string.
|
|
41
|
-
*
|
|
42
|
-
* @param {string} input The input string.
|
|
43
|
-
*
|
|
44
|
-
* @return {Array} Words, extracted from the input string.
|
|
45
|
-
*/
|
|
46
|
-
function extractWords( input = '' ) {
|
|
47
|
-
return noCase( input ).split( ' ' ).filter( Boolean );
|
|
48
|
-
}
|
|
49
|
-
|
|
50
38
|
/**
|
|
51
39
|
* Converts the search term into a list of normalized terms.
|
|
52
40
|
*
|
|
@@ -55,7 +43,7 @@ function extractWords( input = '' ) {
|
|
|
55
43
|
* @return {string[]} The normalized list of search terms.
|
|
56
44
|
*/
|
|
57
45
|
export const getNormalizedSearchTerms = ( input = '' ) => {
|
|
58
|
-
return
|
|
46
|
+
return words( normalizeSearchInput( input ) );
|
|
59
47
|
};
|
|
60
48
|
|
|
61
49
|
const removeMatchingTerms = ( unmatchedTerms, unprocessedTerms ) => {
|
|
@@ -162,7 +150,7 @@ export function getItemSearchRank( item, searchTerm, config = {} ) {
|
|
|
162
150
|
category,
|
|
163
151
|
collection,
|
|
164
152
|
].join( ' ' );
|
|
165
|
-
const normalizedSearchTerms =
|
|
153
|
+
const normalizedSearchTerms = words( normalizedSearchInput );
|
|
166
154
|
const unmatchedTerms = removeMatchingTerms(
|
|
167
155
|
normalizedSearchTerms,
|
|
168
156
|
terms
|
|
@@ -42,6 +42,10 @@ describe( 'getNormalizedSearchTerms', () => {
|
|
|
42
42
|
getNormalizedSearchTerms( ' Média & Text Tag-Cloud > 123' )
|
|
43
43
|
).toEqual( [ 'media', 'text', 'tag', 'cloud', '123' ] );
|
|
44
44
|
} );
|
|
45
|
+
|
|
46
|
+
it( 'should support non-latin letters', () => {
|
|
47
|
+
expect( getNormalizedSearchTerms( 'მედია' ) ).toEqual( [ 'მედია' ] );
|
|
48
|
+
} );
|
|
45
49
|
} );
|
|
46
50
|
|
|
47
51
|
describe( 'getItemSearchRank', () => {
|
package/src/hooks/font-size.js
CHANGED
|
@@ -5,6 +5,7 @@ import { addFilter } from '@wordpress/hooks';
|
|
|
5
5
|
import { hasBlockSupport } from '@wordpress/blocks';
|
|
6
6
|
import TokenList from '@wordpress/token-list';
|
|
7
7
|
import { createHigherOrderComponent } from '@wordpress/compose';
|
|
8
|
+
import { select } from '@wordpress/data';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Internal dependencies
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
getFontSizeClass,
|
|
15
16
|
getFontSizeObjectByValue,
|
|
16
17
|
FontSizePicker,
|
|
18
|
+
getComputedFluidTypographyValue,
|
|
17
19
|
} from '../components/font-sizes';
|
|
18
20
|
import { TYPOGRAPHY_SUPPORT_KEY } from './typography';
|
|
19
21
|
import {
|
|
@@ -22,6 +24,7 @@ import {
|
|
|
22
24
|
shouldSkipSerialization,
|
|
23
25
|
} from './utils';
|
|
24
26
|
import useSetting from '../components/use-setting';
|
|
27
|
+
import { store as blockEditorStore } from '../store';
|
|
25
28
|
|
|
26
29
|
export const FONT_SIZE_SUPPORT_KEY = 'typography.fontSize';
|
|
27
30
|
|
|
@@ -282,6 +285,69 @@ export function addTransforms( result, source, index, results ) {
|
|
|
282
285
|
);
|
|
283
286
|
}
|
|
284
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Allow custom font sizes to appear fluid when fluid typography is enabled at
|
|
290
|
+
* the theme level.
|
|
291
|
+
*
|
|
292
|
+
* Adds a custom getEditWrapperProps() callback to all block types that support
|
|
293
|
+
* font sizes. Then, if fluid typography is enabled, this callback will swap any
|
|
294
|
+
* custom font size in style.fontSize with a fluid font size (i.e. one that uses
|
|
295
|
+
* clamp()).
|
|
296
|
+
*
|
|
297
|
+
* It's important that this hook runs after 'core/style/addEditProps' sets
|
|
298
|
+
* style.fontSize as otherwise fontSize will be overwritten.
|
|
299
|
+
*
|
|
300
|
+
* @param {Object} blockType Block settings object.
|
|
301
|
+
*/
|
|
302
|
+
function addEditPropsForFluidCustomFontSizes( blockType ) {
|
|
303
|
+
if (
|
|
304
|
+
! hasBlockSupport( blockType, FONT_SIZE_SUPPORT_KEY ) ||
|
|
305
|
+
shouldSkipSerialization( blockType, TYPOGRAPHY_SUPPORT_KEY, 'fontSize' )
|
|
306
|
+
) {
|
|
307
|
+
return blockType;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const existingGetEditWrapperProps = blockType.getEditWrapperProps;
|
|
311
|
+
|
|
312
|
+
blockType.getEditWrapperProps = ( attributes ) => {
|
|
313
|
+
const wrapperProps = existingGetEditWrapperProps
|
|
314
|
+
? existingGetEditWrapperProps( attributes )
|
|
315
|
+
: {};
|
|
316
|
+
|
|
317
|
+
const fontSize = wrapperProps?.style?.fontSize;
|
|
318
|
+
|
|
319
|
+
// TODO: This sucks! We should be using useSetting( 'typography.fluid' )
|
|
320
|
+
// or even useSelect( blockEditorStore ). We can't do either here
|
|
321
|
+
// because getEditWrapperProps is a plain JavaScript function called by
|
|
322
|
+
// BlockListBlock and not a React component rendered within
|
|
323
|
+
// BlockListContext.Provider. If we set fontSize using editor.
|
|
324
|
+
// BlockListBlock instead of using getEditWrapperProps then the value is
|
|
325
|
+
// clobbered when the core/style/addEditProps filter runs.
|
|
326
|
+
const isFluidTypographyEnabled =
|
|
327
|
+
!! select( blockEditorStore ).getSettings().__experimentalFeatures
|
|
328
|
+
?.typography?.fluid;
|
|
329
|
+
|
|
330
|
+
const newFontSize =
|
|
331
|
+
fontSize && isFluidTypographyEnabled
|
|
332
|
+
? getComputedFluidTypographyValue( { fontSize } )
|
|
333
|
+
: null;
|
|
334
|
+
|
|
335
|
+
if ( newFontSize === null ) {
|
|
336
|
+
return wrapperProps;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
...wrapperProps,
|
|
341
|
+
style: {
|
|
342
|
+
...wrapperProps?.style,
|
|
343
|
+
fontSize: newFontSize,
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
return blockType;
|
|
349
|
+
}
|
|
350
|
+
|
|
285
351
|
addFilter(
|
|
286
352
|
'blocks.registerBlockType',
|
|
287
353
|
'core/font/addAttribute',
|
|
@@ -307,3 +373,12 @@ addFilter(
|
|
|
307
373
|
'core/font-size/addTransforms',
|
|
308
374
|
addTransforms
|
|
309
375
|
);
|
|
376
|
+
|
|
377
|
+
addFilter(
|
|
378
|
+
'blocks.registerBlockType',
|
|
379
|
+
'core/font-size/addEditPropsForFluidCustomFontSizes',
|
|
380
|
+
addEditPropsForFluidCustomFontSizes,
|
|
381
|
+
// Run after 'core/style/addEditProps' so that the style object has already
|
|
382
|
+
// been translated into inline CSS.
|
|
383
|
+
11
|
|
384
|
+
);
|
package/src/hooks/margin.js
CHANGED
|
@@ -190,10 +190,10 @@ export function MarginVisualizer( { clientId, attributes } ) {
|
|
|
190
190
|
borderRightWidth: marginRight,
|
|
191
191
|
borderBottomWidth: marginBottom,
|
|
192
192
|
borderLeftWidth: marginLeft,
|
|
193
|
-
top: marginTop !== 0 ?
|
|
194
|
-
right: marginRight !== 0 ?
|
|
195
|
-
bottom: marginBottom !== 0 ?
|
|
196
|
-
left: marginLeft !== 0 ?
|
|
193
|
+
top: marginTop !== 0 ? `calc(${ marginTop } * -1)` : 0,
|
|
194
|
+
right: marginRight !== 0 ? `calc(${ marginRight } * -1)` : 0,
|
|
195
|
+
bottom: marginBottom !== 0 ? `calc(${ marginBottom } * -1)` : 0,
|
|
196
|
+
left: marginLeft !== 0 ? `calc(${ marginLeft } * -1)` : 0,
|
|
197
197
|
};
|
|
198
198
|
}, [ margin ] );
|
|
199
199
|
|
|
@@ -25,4 +25,26 @@ describe( 'getTypographyClassesAndStyles', () => {
|
|
|
25
25
|
},
|
|
26
26
|
} );
|
|
27
27
|
} );
|
|
28
|
+
|
|
29
|
+
it( 'should return fluid font size styles', () => {
|
|
30
|
+
const attributes = {
|
|
31
|
+
fontFamily: 'tofu',
|
|
32
|
+
style: {
|
|
33
|
+
typography: {
|
|
34
|
+
letterSpacing: '22px',
|
|
35
|
+
fontSize: '2rem',
|
|
36
|
+
textTransform: 'uppercase',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
expect( getTypographyClassesAndStyles( attributes, true ) ).toEqual( {
|
|
41
|
+
className: 'has-tofu-font-family',
|
|
42
|
+
style: {
|
|
43
|
+
letterSpacing: '22px',
|
|
44
|
+
fontSize:
|
|
45
|
+
'clamp(1.5rem, 1.5rem + ((1vw - 0.48rem) * 2.885), 3rem)',
|
|
46
|
+
textTransform: 'uppercase',
|
|
47
|
+
},
|
|
48
|
+
} );
|
|
49
|
+
} );
|
|
28
50
|
} );
|
|
@@ -9,6 +9,7 @@ import classnames from 'classnames';
|
|
|
9
9
|
*/
|
|
10
10
|
import { getInlineStyles } from './style';
|
|
11
11
|
import { getFontSizeClass } from '../components/font-sizes';
|
|
12
|
+
import { getComputedFluidTypographyValue } from '../components/font-sizes/fluid-utils';
|
|
12
13
|
|
|
13
14
|
// This utility is intended to assist where the serialization of the typography
|
|
14
15
|
// block support is being skipped for a block but the typography related CSS
|
|
@@ -18,12 +19,26 @@ import { getFontSizeClass } from '../components/font-sizes';
|
|
|
18
19
|
* Provides the CSS class names and inline styles for a block's typography support
|
|
19
20
|
* attributes.
|
|
20
21
|
*
|
|
21
|
-
* @param {Object}
|
|
22
|
+
* @param {Object} attributes Block attributes.
|
|
23
|
+
* @param {boolean} isFluidFontSizeActive Whether the function should try to convert font sizes to fluid values.
|
|
22
24
|
*
|
|
23
25
|
* @return {Object} Typography block support derived CSS classes & styles.
|
|
24
26
|
*/
|
|
25
|
-
export function getTypographyClassesAndStyles(
|
|
26
|
-
|
|
27
|
+
export function getTypographyClassesAndStyles(
|
|
28
|
+
attributes,
|
|
29
|
+
isFluidFontSizeActive
|
|
30
|
+
) {
|
|
31
|
+
let typographyStyles = attributes?.style?.typography || {};
|
|
32
|
+
|
|
33
|
+
if ( isFluidFontSizeActive ) {
|
|
34
|
+
typographyStyles = {
|
|
35
|
+
...typographyStyles,
|
|
36
|
+
fontSize: getComputedFluidTypographyValue( {
|
|
37
|
+
fontSize: attributes?.style?.typography?.fontSize,
|
|
38
|
+
} ),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
const style = getInlineStyles( { typography: typographyStyles } );
|
|
28
43
|
const fontFamilyClassName = !! attributes?.fontFamily
|
|
29
44
|
? `has-${ kebabCase( attributes.fontFamily ) }-font-family`
|