@wordpress/components 30.6.1-next.ff1cebbba.0 → 30.7.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/CHANGELOG.md +26 -1
- package/build/color-palette/styles.js +2 -12
- package/build/color-palette/styles.js.map +2 -2
- package/build/combobox-control/index.js +1 -2
- package/build/combobox-control/index.js.map +2 -2
- package/build/custom-select-control-v2/custom-select.js +2 -2
- package/build/custom-select-control-v2/custom-select.js.map +2 -2
- package/build/date-time/date/styles.js +9 -9
- package/build/date-time/date/styles.js.map +2 -2
- package/build/focal-point-picker/index.js +21 -10
- package/build/focal-point-picker/index.js.map +3 -3
- package/build/focal-point-picker/styles/focal-point-picker-style.js +20 -11
- package/build/focal-point-picker/styles/focal-point-picker-style.js.map +2 -2
- package/build/font-size-picker/font-size-picker-select.js +20 -19
- package/build/font-size-picker/font-size-picker-select.js.map +3 -3
- package/build/font-size-picker/font-size-picker-toggle-group.js +27 -3
- package/build/font-size-picker/font-size-picker-toggle-group.js.map +2 -2
- package/build/font-size-picker/index.js +23 -11
- package/build/font-size-picker/index.js.map +2 -2
- package/build/font-size-picker/styles.js +30 -13
- package/build/font-size-picker/styles.js.map +3 -3
- package/build/font-size-picker/utils.js +11 -0
- package/build/font-size-picker/utils.js.map +2 -2
- package/build/palette-edit/styles.js +9 -9
- package/build/palette-edit/styles.js.map +2 -2
- package/build/popover/index.js +13 -2
- package/build/popover/index.js.map +2 -2
- package/build/tabs/styles.js +5 -5
- package/build/tabs/styles.js.map +1 -1
- package/build/tools-panel/styles.js +14 -22
- package/build/tools-panel/styles.js.map +2 -2
- package/build/utils/base-label.js +12 -12
- package/build/utils/base-label.js.map +3 -3
- package/build/utils/config-values.js +2 -0
- package/build/utils/config-values.js.map +2 -2
- package/build-module/color-palette/styles.js +2 -12
- package/build-module/color-palette/styles.js.map +2 -2
- package/build-module/combobox-control/index.js +1 -2
- package/build-module/combobox-control/index.js.map +2 -2
- package/build-module/custom-select-control-v2/custom-select.js +1 -1
- package/build-module/custom-select-control-v2/custom-select.js.map +1 -1
- package/build-module/date-time/date/styles.js +9 -9
- package/build-module/date-time/date/styles.js.map +2 -2
- package/build-module/focal-point-picker/index.js +23 -12
- package/build-module/focal-point-picker/index.js.map +2 -2
- package/build-module/focal-point-picker/styles/focal-point-picker-style.js +20 -12
- package/build-module/focal-point-picker/styles/focal-point-picker-style.js.map +2 -2
- package/build-module/font-size-picker/font-size-picker-select.js +21 -10
- package/build-module/font-size-picker/font-size-picker-select.js.map +2 -2
- package/build-module/font-size-picker/font-size-picker-toggle-group.js +27 -3
- package/build-module/font-size-picker/font-size-picker-toggle-group.js.map +2 -2
- package/build-module/font-size-picker/index.js +23 -11
- package/build-module/font-size-picker/index.js.map +2 -2
- package/build-module/font-size-picker/styles.js +28 -12
- package/build-module/font-size-picker/styles.js.map +2 -2
- package/build-module/font-size-picker/utils.js +10 -0
- package/build-module/font-size-picker/utils.js.map +2 -2
- package/build-module/palette-edit/styles.js +9 -9
- package/build-module/palette-edit/styles.js.map +2 -2
- package/build-module/popover/index.js +13 -2
- package/build-module/popover/index.js.map +2 -2
- package/build-module/tabs/styles.js +5 -5
- package/build-module/tabs/styles.js.map +1 -1
- package/build-module/tools-panel/styles.js +14 -22
- package/build-module/tools-panel/styles.js.map +2 -2
- package/build-module/utils/base-label.js +2 -12
- package/build-module/utils/base-label.js.map +2 -2
- package/build-module/utils/config-values.js +2 -0
- package/build-module/utils/config-values.js.map +2 -2
- package/build-style/style-rtl.css +11 -5
- package/build-style/style.css +11 -5
- package/build-types/card/card-body/component.d.ts.map +1 -1
- package/build-types/card/card-body/hook.d.ts.map +1 -1
- package/build-types/card/card-footer/component.d.ts +1 -3
- package/build-types/card/card-footer/component.d.ts.map +1 -1
- package/build-types/card/card-footer/hook.d.ts +6 -0
- package/build-types/card/card-footer/hook.d.ts.map +1 -1
- package/build-types/card/card-header/component.d.ts +1 -1
- package/build-types/card/card-header/component.d.ts.map +1 -1
- package/build-types/card/card-header/hook.d.ts +7 -0
- package/build-types/card/card-header/hook.d.ts.map +1 -1
- package/build-types/card/card-media/hook.d.ts.map +1 -1
- package/build-types/card/types.d.ts +3 -8
- package/build-types/card/types.d.ts.map +1 -1
- package/build-types/color-palette/styles.d.ts.map +1 -1
- package/build-types/combobox-control/index.d.ts.map +1 -1
- package/build-types/combobox-control/stories/index.story.d.ts.map +1 -1
- package/build-types/date-time/date/styles.d.ts.map +1 -1
- package/build-types/focal-point-picker/index.d.ts +1 -1
- package/build-types/focal-point-picker/index.d.ts.map +1 -1
- package/build-types/focal-point-picker/styles/focal-point-picker-style.d.ts +253 -0
- package/build-types/focal-point-picker/styles/focal-point-picker-style.d.ts.map +1 -1
- package/build-types/font-size-picker/font-size-picker-select.d.ts +3 -0
- package/build-types/font-size-picker/font-size-picker-select.d.ts.map +1 -1
- package/build-types/font-size-picker/font-size-picker-toggle-group.d.ts.map +1 -1
- package/build-types/font-size-picker/index.d.ts.map +1 -1
- package/build-types/font-size-picker/styles.d.ts +3 -0
- package/build-types/font-size-picker/styles.d.ts.map +1 -1
- package/build-types/font-size-picker/test/font-size-picker-select.d.ts +2 -0
- package/build-types/font-size-picker/test/font-size-picker-select.d.ts.map +1 -0
- package/build-types/font-size-picker/test/font-size-picker-toggle-group.d.ts +2 -0
- package/build-types/font-size-picker/test/font-size-picker-toggle-group.d.ts.map +1 -0
- package/build-types/font-size-picker/types.d.ts +18 -4
- package/build-types/font-size-picker/types.d.ts.map +1 -1
- package/build-types/font-size-picker/utils.d.ts +10 -1
- package/build-types/font-size-picker/utils.d.ts.map +1 -1
- package/build-types/popover/index.d.ts.map +1 -1
- package/build-types/utils/base-label.d.ts.map +1 -1
- package/build-types/utils/config-values.d.ts +1 -0
- package/package.json +20 -20
- package/src/badge/styles.scss +1 -0
- package/src/button/style.scss +4 -1
- package/src/card/types.ts +3 -9
- package/src/color-palette/styles.ts +2 -1
- package/src/combobox-control/index.tsx +1 -4
- package/src/combobox-control/stories/index.story.tsx +0 -1
- package/src/combobox-control/test/index.tsx +20 -7
- package/src/custom-select-control-v2/custom-select.tsx +1 -1
- package/src/date-time/date/styles.ts +1 -0
- package/src/dimension-control/test/__snapshots__/index.test.js.snap +4 -4
- package/src/dropdown-menu/style.scss +1 -0
- package/src/focal-point-picker/index.tsx +26 -16
- package/src/focal-point-picker/styles/focal-point-picker-style.ts +11 -1
- package/src/font-size-picker/README.md +10 -0
- package/src/font-size-picker/font-size-picker-select.tsx +44 -11
- package/src/font-size-picker/font-size-picker-toggle-group.tsx +58 -4
- package/src/font-size-picker/index.tsx +44 -19
- package/src/font-size-picker/styles.ts +9 -0
- package/src/font-size-picker/test/font-size-picker-select.tsx +221 -0
- package/src/font-size-picker/test/font-size-picker-toggle-group.tsx +275 -0
- package/src/font-size-picker/test/index.tsx +460 -2
- package/src/font-size-picker/types.ts +24 -4
- package/src/font-size-picker/utils.ts +23 -1
- package/src/menu-group/style.scss +1 -1
- package/src/menu-item/style.scss +1 -0
- package/src/modal/style.scss +1 -1
- package/src/palette-edit/styles.ts +1 -1
- package/src/panel/style.scss +1 -1
- package/src/popover/index.tsx +23 -2
- package/src/tab-panel/style.scss +1 -1
- package/src/tabs/styles.ts +1 -1
- package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +4 -4
- package/src/tools-panel/styles.ts +2 -2
- package/src/utils/base-label.ts +6 -1
- package/src/utils/config-values.js +1 -0
- package/src/validated-form-controls/style.scss +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { __, sprintf } from '@wordpress/i18n';
|
|
5
|
+
import { useMemo } from '@wordpress/element';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
8
9
|
*/
|
|
9
|
-
import CustomSelectControl from '../custom-select-control';
|
|
10
10
|
import type {
|
|
11
11
|
FontSizePickerSelectProps,
|
|
12
12
|
FontSizePickerSelectOption,
|
|
13
13
|
} from './types';
|
|
14
|
-
import {
|
|
14
|
+
import { generateFontSizeHint } from './utils';
|
|
15
|
+
import { StyledCustomSelectControl } from './styles';
|
|
15
16
|
|
|
16
17
|
const DEFAULT_OPTION: FontSizePickerSelectOption = {
|
|
17
18
|
key: 'default',
|
|
@@ -20,15 +21,19 @@ const DEFAULT_OPTION: FontSizePickerSelectOption = {
|
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const FontSizePickerSelect = ( props: FontSizePickerSelectProps ) => {
|
|
23
|
-
const {
|
|
24
|
+
const {
|
|
25
|
+
__next40pxDefaultSize,
|
|
26
|
+
fontSizes,
|
|
27
|
+
value,
|
|
28
|
+
size,
|
|
29
|
+
valueMode = 'literal',
|
|
30
|
+
onChange,
|
|
31
|
+
} = props;
|
|
24
32
|
|
|
25
33
|
const options: FontSizePickerSelectOption[] = [
|
|
26
34
|
DEFAULT_OPTION,
|
|
27
35
|
...fontSizes.map( ( fontSize ) => {
|
|
28
|
-
|
|
29
|
-
if ( isSimpleCssValue( fontSize.size ) ) {
|
|
30
|
-
hint = String( fontSize.size );
|
|
31
|
-
}
|
|
36
|
+
const hint = generateFontSizeHint( fontSize );
|
|
32
37
|
return {
|
|
33
38
|
key: fontSize.slug,
|
|
34
39
|
name: fontSize.name || fontSize.slug,
|
|
@@ -38,11 +43,30 @@ const FontSizePickerSelect = ( props: FontSizePickerSelectProps ) => {
|
|
|
38
43
|
} ),
|
|
39
44
|
];
|
|
40
45
|
|
|
41
|
-
const selectedOption =
|
|
42
|
-
|
|
46
|
+
const selectedOption = useMemo( () => {
|
|
47
|
+
if ( value === undefined ) {
|
|
48
|
+
return DEFAULT_OPTION;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// If valueMode is 'slug', find by slug
|
|
52
|
+
if ( valueMode === 'slug' ) {
|
|
53
|
+
const optionBySlug = options.find(
|
|
54
|
+
( option ) => option.key === value
|
|
55
|
+
);
|
|
56
|
+
if ( optionBySlug ) {
|
|
57
|
+
return optionBySlug;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// If valueMode is 'literal', find by value (size)
|
|
62
|
+
return (
|
|
63
|
+
options.find( ( option ) => option.value === value ) ??
|
|
64
|
+
DEFAULT_OPTION
|
|
65
|
+
);
|
|
66
|
+
}, [ value, valueMode, options ] );
|
|
43
67
|
|
|
44
68
|
return (
|
|
45
|
-
<
|
|
69
|
+
<StyledCustomSelectControl
|
|
46
70
|
__next40pxDefaultSize={ __next40pxDefaultSize }
|
|
47
71
|
__shouldNotWarnDeprecated36pxSize
|
|
48
72
|
className="components-font-size-picker__select"
|
|
@@ -61,7 +85,16 @@ const FontSizePickerSelect = ( props: FontSizePickerSelectProps ) => {
|
|
|
61
85
|
}: {
|
|
62
86
|
selectedItem: FontSizePickerSelectOption;
|
|
63
87
|
} ) => {
|
|
64
|
-
|
|
88
|
+
// Find the corresponding FontSize object
|
|
89
|
+
const matchingFontSize =
|
|
90
|
+
selectedItem.key === 'default'
|
|
91
|
+
? undefined
|
|
92
|
+
: fontSizes.find(
|
|
93
|
+
( fontSize ) =>
|
|
94
|
+
fontSize.slug === selectedItem.key
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
onChange( selectedItem.value, matchingFontSize );
|
|
65
98
|
} }
|
|
66
99
|
size={ size }
|
|
67
100
|
/>
|
|
@@ -14,7 +14,46 @@ import { T_SHIRT_ABBREVIATIONS, T_SHIRT_NAMES } from './constants';
|
|
|
14
14
|
import type { FontSizePickerToggleGroupProps } from './types';
|
|
15
15
|
|
|
16
16
|
const FontSizePickerToggleGroup = ( props: FontSizePickerToggleGroupProps ) => {
|
|
17
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
fontSizes,
|
|
19
|
+
value,
|
|
20
|
+
valueMode = 'literal',
|
|
21
|
+
__next40pxDefaultSize,
|
|
22
|
+
size,
|
|
23
|
+
onChange,
|
|
24
|
+
} = props;
|
|
25
|
+
|
|
26
|
+
// Find the current value based on valueMode
|
|
27
|
+
const currentValue = ( () => {
|
|
28
|
+
if ( ! value ) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// If valueMode is 'slug', the value is already the slug
|
|
33
|
+
if ( valueMode === 'slug' ) {
|
|
34
|
+
return String( value );
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// If valueMode is 'literal', find the font size by size value
|
|
38
|
+
// If multiple font sizes have the same size value, we can't distinguish them
|
|
39
|
+
// without additional information, so we return undefined to avoid incorrect selection
|
|
40
|
+
const matchingFontSizes = fontSizes.filter(
|
|
41
|
+
( fontSize ) => fontSize.size === value
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// If there are multiple matches, return undefined to avoid selecting the wrong font size
|
|
45
|
+
if ( matchingFontSizes.length > 1 ) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Find the font size by size value
|
|
50
|
+
const fontSizeBySize = fontSizes.find(
|
|
51
|
+
( fontSize ) => fontSize.size === value
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return fontSizeBySize?.slug;
|
|
55
|
+
} )();
|
|
56
|
+
|
|
18
57
|
return (
|
|
19
58
|
<ToggleGroupControl
|
|
20
59
|
__nextHasNoMarginBottom
|
|
@@ -22,15 +61,30 @@ const FontSizePickerToggleGroup = ( props: FontSizePickerToggleGroupProps ) => {
|
|
|
22
61
|
__shouldNotWarnDeprecated36pxSize
|
|
23
62
|
label={ __( 'Font size' ) }
|
|
24
63
|
hideLabelFromVision
|
|
25
|
-
value={
|
|
26
|
-
onChange={
|
|
64
|
+
value={ currentValue }
|
|
65
|
+
onChange={ ( newSlug: string | number | undefined ) => {
|
|
66
|
+
if ( newSlug === undefined ) {
|
|
67
|
+
onChange( undefined );
|
|
68
|
+
} else {
|
|
69
|
+
// Find the font size by slug
|
|
70
|
+
const selectedFontSize = fontSizes.find(
|
|
71
|
+
( fontSize ) => fontSize.slug === String( newSlug )
|
|
72
|
+
);
|
|
73
|
+
if ( selectedFontSize ) {
|
|
74
|
+
onChange(
|
|
75
|
+
selectedFontSize.size as number | string,
|
|
76
|
+
selectedFontSize
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} }
|
|
27
81
|
isBlock
|
|
28
82
|
size={ size }
|
|
29
83
|
>
|
|
30
84
|
{ fontSizes.map( ( fontSize, index ) => (
|
|
31
85
|
<ToggleGroupControlOption
|
|
32
86
|
key={ fontSize.slug }
|
|
33
|
-
value={ fontSize.
|
|
87
|
+
value={ fontSize.slug }
|
|
34
88
|
label={ T_SHIRT_ABBREVIATIONS[ index ] }
|
|
35
89
|
aria-label={ fontSize.name || T_SHIRT_NAMES[ index ] }
|
|
36
90
|
showTooltip
|
|
@@ -46,6 +46,7 @@ const UnforwardedFontSizePicker = (
|
|
|
46
46
|
size = 'default',
|
|
47
47
|
units: unitsProp = DEFAULT_UNITS,
|
|
48
48
|
value,
|
|
49
|
+
valueMode = 'literal',
|
|
49
50
|
withSlider = false,
|
|
50
51
|
withReset = true,
|
|
51
52
|
} = props;
|
|
@@ -59,15 +60,32 @@ const UnforwardedFontSizePicker = (
|
|
|
59
60
|
availableUnits: unitsProp,
|
|
60
61
|
} );
|
|
61
62
|
|
|
62
|
-
const selectedFontSize =
|
|
63
|
-
(
|
|
64
|
-
|
|
63
|
+
const selectedFontSize = ( () => {
|
|
64
|
+
if ( ! value ) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If valueMode is 'slug', find by slug
|
|
69
|
+
if ( valueMode === 'slug' ) {
|
|
70
|
+
return fontSizes.find( ( fontSize ) => fontSize.slug === value );
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// If valueMode is 'literal', find by size value
|
|
74
|
+
return fontSizes.find( ( fontSize ) => fontSize.size === value );
|
|
75
|
+
} )();
|
|
65
76
|
const isCustomValue = !! value && ! selectedFontSize;
|
|
66
77
|
|
|
67
78
|
// Initially request a custom picker if the value is not from the predef list.
|
|
68
79
|
const [ userRequestedCustom, setUserRequestedCustom ] =
|
|
69
80
|
useState( isCustomValue );
|
|
70
81
|
|
|
82
|
+
// Resolve the literal value to use in custom controls when operating in slug mode.
|
|
83
|
+
// When `valueMode` is 'slug', the `value` prop contains the slug of the
|
|
84
|
+
// selected preset. In that case, the custom input should reflect the preset's
|
|
85
|
+
// actual size value so it pre-populates correctly after clicking "Set custom size".
|
|
86
|
+
const resolvedValueForControls =
|
|
87
|
+
valueMode === 'slug' ? selectedFontSize?.size : value;
|
|
88
|
+
|
|
71
89
|
let currentPickerType;
|
|
72
90
|
if ( ! disableCustomFontSizes && userRequestedCustom ) {
|
|
73
91
|
// While showing the custom value picker, switch back to predef only if
|
|
@@ -88,10 +106,11 @@ const UnforwardedFontSizePicker = (
|
|
|
88
106
|
// operates in a legacy "unitless" mode where UnitControl can only be used
|
|
89
107
|
// to select px values and onChange() is always called with number values.
|
|
90
108
|
const hasUnits =
|
|
91
|
-
typeof
|
|
109
|
+
typeof resolvedValueForControls === 'string' ||
|
|
110
|
+
typeof fontSizes[ 0 ]?.size === 'string';
|
|
92
111
|
|
|
93
112
|
const [ valueQuantity, valueUnit ] = parseQuantityAndUnitFromRawValue(
|
|
94
|
-
|
|
113
|
+
resolvedValueForControls,
|
|
95
114
|
units
|
|
96
115
|
);
|
|
97
116
|
const isValueUnitRelative =
|
|
@@ -139,18 +158,16 @@ const UnforwardedFontSizePicker = (
|
|
|
139
158
|
__next40pxDefaultSize={ __next40pxDefaultSize }
|
|
140
159
|
fontSizes={ fontSizes }
|
|
141
160
|
value={ value }
|
|
161
|
+
valueMode={ valueMode }
|
|
142
162
|
disableCustomFontSizes={ disableCustomFontSizes }
|
|
143
163
|
size={ size }
|
|
144
|
-
onChange={ ( newValue ) => {
|
|
164
|
+
onChange={ ( newValue, selectedItem ) => {
|
|
145
165
|
if ( newValue === undefined ) {
|
|
146
|
-
onChange?.( undefined );
|
|
166
|
+
onChange?.( undefined, selectedItem );
|
|
147
167
|
} else {
|
|
148
168
|
onChange?.(
|
|
149
169
|
hasUnits ? newValue : Number( newValue ),
|
|
150
|
-
|
|
151
|
-
( fontSize ) =>
|
|
152
|
-
fontSize.size === newValue
|
|
153
|
-
)
|
|
170
|
+
selectedItem
|
|
154
171
|
);
|
|
155
172
|
}
|
|
156
173
|
} }
|
|
@@ -161,18 +178,16 @@ const UnforwardedFontSizePicker = (
|
|
|
161
178
|
<FontSizePickerToggleGroup
|
|
162
179
|
fontSizes={ fontSizes }
|
|
163
180
|
value={ value }
|
|
181
|
+
valueMode={ valueMode }
|
|
164
182
|
__next40pxDefaultSize={ __next40pxDefaultSize }
|
|
165
183
|
size={ size }
|
|
166
|
-
onChange={ ( newValue ) => {
|
|
184
|
+
onChange={ ( newValue, selectedItem ) => {
|
|
167
185
|
if ( newValue === undefined ) {
|
|
168
|
-
onChange?.( undefined );
|
|
186
|
+
onChange?.( undefined, selectedItem );
|
|
169
187
|
} else {
|
|
170
188
|
onChange?.(
|
|
171
189
|
hasUnits ? newValue : Number( newValue ),
|
|
172
|
-
|
|
173
|
-
( fontSize ) =>
|
|
174
|
-
fontSize.size === newValue
|
|
175
|
-
)
|
|
190
|
+
selectedItem
|
|
176
191
|
);
|
|
177
192
|
}
|
|
178
193
|
} }
|
|
@@ -187,11 +202,21 @@ const UnforwardedFontSizePicker = (
|
|
|
187
202
|
label={ __( 'Font size' ) }
|
|
188
203
|
labelPosition="top"
|
|
189
204
|
hideLabelFromVision
|
|
190
|
-
value={
|
|
205
|
+
value={
|
|
206
|
+
hasUnits
|
|
207
|
+
? `${ valueQuantity ?? '' }${
|
|
208
|
+
valueUnit ?? ''
|
|
209
|
+
}`
|
|
210
|
+
: resolvedValueForControls
|
|
211
|
+
}
|
|
191
212
|
onChange={ ( newValue ) => {
|
|
192
213
|
setUserRequestedCustom( true );
|
|
193
214
|
|
|
194
|
-
|
|
215
|
+
// Treat clearing the input (empty string) as a reset
|
|
216
|
+
if (
|
|
217
|
+
newValue === undefined ||
|
|
218
|
+
newValue === ''
|
|
219
|
+
) {
|
|
195
220
|
onChange?.( undefined );
|
|
196
221
|
} else {
|
|
197
222
|
onChange?.(
|
|
@@ -8,6 +8,7 @@ import styled from '@emotion/styled';
|
|
|
8
8
|
*/
|
|
9
9
|
import BaseControl from '../base-control';
|
|
10
10
|
import Button from '../button';
|
|
11
|
+
import CustomSelectControl from '../custom-select-control';
|
|
11
12
|
import { HStack } from '../h-stack';
|
|
12
13
|
import { space } from '../utils/space';
|
|
13
14
|
|
|
@@ -32,3 +33,11 @@ export const HeaderLabel = styled( BaseControl.VisualLabel )`
|
|
|
32
33
|
justify-content: flex-start;
|
|
33
34
|
margin-bottom: 0;
|
|
34
35
|
`;
|
|
36
|
+
|
|
37
|
+
// Custom styled component to force line break between name and hint while keeping checkmark on the right
|
|
38
|
+
export const StyledCustomSelectControl = styled( CustomSelectControl )`
|
|
39
|
+
.components-custom-select-control__item
|
|
40
|
+
.components-custom-select-control__item-hint {
|
|
41
|
+
width: 100%;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { screen } from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
6
|
+
import { render } from '@ariakit/test/react';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import FontSizePickerSelect from '../font-size-picker-select';
|
|
12
|
+
import type { FontSize } from '../types';
|
|
13
|
+
|
|
14
|
+
describe( 'FontSizePickerSelect', () => {
|
|
15
|
+
const fontSizes: FontSize[] = [
|
|
16
|
+
{
|
|
17
|
+
slug: 'small',
|
|
18
|
+
name: 'Small',
|
|
19
|
+
size: '12px',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
slug: 'medium',
|
|
23
|
+
name: 'Medium',
|
|
24
|
+
size: '16px',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
slug: 'large',
|
|
28
|
+
name: 'Large',
|
|
29
|
+
size: '20px',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
describe( 'valueMode prop', () => {
|
|
34
|
+
it( 'should find font size by size value when valueMode is literal', async () => {
|
|
35
|
+
const onChange = jest.fn();
|
|
36
|
+
await render(
|
|
37
|
+
<FontSizePickerSelect
|
|
38
|
+
fontSizes={ fontSizes }
|
|
39
|
+
value="16px"
|
|
40
|
+
valueMode="literal"
|
|
41
|
+
onChange={ onChange }
|
|
42
|
+
onSelectCustom={ jest.fn() }
|
|
43
|
+
disableCustomFontSizes={ false }
|
|
44
|
+
__next40pxDefaultSize={ false }
|
|
45
|
+
size="default"
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
// Should select the medium option (16px)
|
|
49
|
+
expect(
|
|
50
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
51
|
+
).toHaveTextContent( 'Medium' );
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
it( 'should find font size by slug when valueMode is slug', async () => {
|
|
55
|
+
const onChange = jest.fn();
|
|
56
|
+
await render(
|
|
57
|
+
<FontSizePickerSelect
|
|
58
|
+
fontSizes={ fontSizes }
|
|
59
|
+
value="medium"
|
|
60
|
+
valueMode="slug"
|
|
61
|
+
onChange={ onChange }
|
|
62
|
+
onSelectCustom={ jest.fn() }
|
|
63
|
+
disableCustomFontSizes={ false }
|
|
64
|
+
__next40pxDefaultSize={ false }
|
|
65
|
+
size="default"
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
// Should select the medium option
|
|
69
|
+
expect(
|
|
70
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
71
|
+
).toHaveTextContent( 'Medium' );
|
|
72
|
+
} );
|
|
73
|
+
|
|
74
|
+
it( 'should handle undefined value', async () => {
|
|
75
|
+
const onChange = jest.fn();
|
|
76
|
+
await render(
|
|
77
|
+
<FontSizePickerSelect
|
|
78
|
+
fontSizes={ fontSizes }
|
|
79
|
+
value={ undefined }
|
|
80
|
+
valueMode="literal"
|
|
81
|
+
onChange={ onChange }
|
|
82
|
+
onSelectCustom={ jest.fn() }
|
|
83
|
+
disableCustomFontSizes={ false }
|
|
84
|
+
__next40pxDefaultSize={ false }
|
|
85
|
+
size="default"
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
// Should show default option
|
|
89
|
+
expect(
|
|
90
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
91
|
+
).toHaveTextContent( 'Default' );
|
|
92
|
+
} );
|
|
93
|
+
|
|
94
|
+
it( 'should handle empty string value', async () => {
|
|
95
|
+
const onChange = jest.fn();
|
|
96
|
+
await render(
|
|
97
|
+
<FontSizePickerSelect
|
|
98
|
+
fontSizes={ fontSizes }
|
|
99
|
+
value=""
|
|
100
|
+
valueMode="literal"
|
|
101
|
+
onChange={ onChange }
|
|
102
|
+
onSelectCustom={ jest.fn() }
|
|
103
|
+
disableCustomFontSizes={ false }
|
|
104
|
+
__next40pxDefaultSize={ false }
|
|
105
|
+
size="default"
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
// Should show default option
|
|
109
|
+
expect(
|
|
110
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
111
|
+
).toHaveTextContent( 'Default' );
|
|
112
|
+
} );
|
|
113
|
+
} );
|
|
114
|
+
|
|
115
|
+
describe( 'onChange callback', () => {
|
|
116
|
+
it( 'should call onChange with FontSize object as second parameter', async () => {
|
|
117
|
+
const user = userEvent.setup();
|
|
118
|
+
const onChange = jest.fn();
|
|
119
|
+
await render(
|
|
120
|
+
<FontSizePickerSelect
|
|
121
|
+
fontSizes={ fontSizes }
|
|
122
|
+
onChange={ onChange }
|
|
123
|
+
onSelectCustom={ jest.fn() }
|
|
124
|
+
disableCustomFontSizes={ false }
|
|
125
|
+
__next40pxDefaultSize={ false }
|
|
126
|
+
size="default"
|
|
127
|
+
/>
|
|
128
|
+
);
|
|
129
|
+
await user.click(
|
|
130
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
131
|
+
);
|
|
132
|
+
await user.click(
|
|
133
|
+
screen.getByRole( 'option', { name: 'Small 12px' } )
|
|
134
|
+
);
|
|
135
|
+
expect( onChange ).toHaveBeenCalledWith( '12px', fontSizes[ 0 ] );
|
|
136
|
+
} );
|
|
137
|
+
|
|
138
|
+
it( 'should call onChange with undefined as second parameter for default option', async () => {
|
|
139
|
+
const user = userEvent.setup();
|
|
140
|
+
const onChange = jest.fn();
|
|
141
|
+
await render(
|
|
142
|
+
<FontSizePickerSelect
|
|
143
|
+
fontSizes={ fontSizes }
|
|
144
|
+
value="16px" // Start with a selected value
|
|
145
|
+
onChange={ onChange }
|
|
146
|
+
onSelectCustom={ jest.fn() }
|
|
147
|
+
disableCustomFontSizes={ false }
|
|
148
|
+
__next40pxDefaultSize={ false }
|
|
149
|
+
size="default"
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
await user.click(
|
|
153
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
154
|
+
);
|
|
155
|
+
await user.click(
|
|
156
|
+
screen.getByRole( 'option', { name: 'Default' } )
|
|
157
|
+
);
|
|
158
|
+
expect( onChange ).toHaveBeenCalledWith( undefined, undefined );
|
|
159
|
+
} );
|
|
160
|
+
} );
|
|
161
|
+
|
|
162
|
+
describe( 'edge cases', () => {
|
|
163
|
+
const fontSizesWithDuplicates: FontSize[] = [
|
|
164
|
+
{
|
|
165
|
+
slug: 'small-1',
|
|
166
|
+
name: 'Small 1',
|
|
167
|
+
size: '12px',
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
slug: 'small-2',
|
|
171
|
+
name: 'Small 2',
|
|
172
|
+
size: '12px',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
slug: 'medium',
|
|
176
|
+
name: 'Medium',
|
|
177
|
+
size: '16px',
|
|
178
|
+
},
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
it( 'should handle multiple font sizes with same value in literal mode', async () => {
|
|
182
|
+
const onChange = jest.fn();
|
|
183
|
+
await render(
|
|
184
|
+
<FontSizePickerSelect
|
|
185
|
+
fontSizes={ fontSizesWithDuplicates }
|
|
186
|
+
value="12px"
|
|
187
|
+
valueMode="literal"
|
|
188
|
+
onChange={ onChange }
|
|
189
|
+
onSelectCustom={ jest.fn() }
|
|
190
|
+
disableCustomFontSizes={ false }
|
|
191
|
+
__next40pxDefaultSize={ false }
|
|
192
|
+
size="default"
|
|
193
|
+
/>
|
|
194
|
+
);
|
|
195
|
+
// Should show the first matching font size when there are multiple matches
|
|
196
|
+
expect(
|
|
197
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
198
|
+
).toHaveTextContent( 'Small 1' );
|
|
199
|
+
} );
|
|
200
|
+
|
|
201
|
+
it( 'should handle multiple font sizes with same value in slug mode', async () => {
|
|
202
|
+
const onChange = jest.fn();
|
|
203
|
+
await render(
|
|
204
|
+
<FontSizePickerSelect
|
|
205
|
+
fontSizes={ fontSizesWithDuplicates }
|
|
206
|
+
value="small-1"
|
|
207
|
+
valueMode="slug"
|
|
208
|
+
onChange={ onChange }
|
|
209
|
+
onSelectCustom={ jest.fn() }
|
|
210
|
+
disableCustomFontSizes={ false }
|
|
211
|
+
__next40pxDefaultSize={ false }
|
|
212
|
+
size="default"
|
|
213
|
+
/>
|
|
214
|
+
);
|
|
215
|
+
// Should select the specific font size by slug
|
|
216
|
+
expect(
|
|
217
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
218
|
+
).toHaveTextContent( 'Small 1' );
|
|
219
|
+
} );
|
|
220
|
+
} );
|
|
221
|
+
} );
|