@wordpress/components 30.6.1-next.b8c8708f3.0 → 30.6.1
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 +6 -1
- 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/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-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/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-style/style-rtl.css +1 -0
- package/build-style/style.css +1 -0
- 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/package.json +20 -20
- package/src/badge/styles.scss +1 -0
- package/src/custom-select-control-v2/custom-select.tsx +1 -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/tsconfig.tsbuildinfo +1 -1
|
@@ -145,7 +145,7 @@ describe( 'FontSizePicker', () => {
|
|
|
145
145
|
{
|
|
146
146
|
option: 'Default',
|
|
147
147
|
value: '8px',
|
|
148
|
-
expectedArguments: [ undefined ],
|
|
148
|
+
expectedArguments: [ undefined, undefined ],
|
|
149
149
|
},
|
|
150
150
|
{
|
|
151
151
|
option: 'Tiny 8px',
|
|
@@ -249,7 +249,7 @@ describe( 'FontSizePicker', () => {
|
|
|
249
249
|
{
|
|
250
250
|
option: 'Default',
|
|
251
251
|
value: '8px',
|
|
252
|
-
expectedArguments: [ undefined ],
|
|
252
|
+
expectedArguments: [ undefined, undefined ],
|
|
253
253
|
},
|
|
254
254
|
{
|
|
255
255
|
option: 'Tiny 8px',
|
|
@@ -358,6 +358,98 @@ describe( 'FontSizePicker', () => {
|
|
|
358
358
|
|
|
359
359
|
commonToggleGroupTests( fontSizes );
|
|
360
360
|
commonTests( fontSizes );
|
|
361
|
+
|
|
362
|
+
describe( 'valueMode prop for toggle group', () => {
|
|
363
|
+
it( 'should find font size by size value when valueMode is literal', async () => {
|
|
364
|
+
await render(
|
|
365
|
+
<FontSizePicker
|
|
366
|
+
fontSizes={ fontSizes }
|
|
367
|
+
value="16px"
|
|
368
|
+
valueMode="literal"
|
|
369
|
+
/>
|
|
370
|
+
);
|
|
371
|
+
// Should select the medium option (16px)
|
|
372
|
+
expect(
|
|
373
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
374
|
+
).toHaveAccessibleName( 'Medium' );
|
|
375
|
+
} );
|
|
376
|
+
|
|
377
|
+
it( 'should find font size by slug when valueMode is slug', async () => {
|
|
378
|
+
await render(
|
|
379
|
+
<FontSizePicker
|
|
380
|
+
fontSizes={ fontSizes }
|
|
381
|
+
value="medium"
|
|
382
|
+
valueMode="slug"
|
|
383
|
+
/>
|
|
384
|
+
);
|
|
385
|
+
// Should select the medium option
|
|
386
|
+
expect(
|
|
387
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
388
|
+
).toHaveAccessibleName( 'Medium' );
|
|
389
|
+
} );
|
|
390
|
+
|
|
391
|
+
it( 'should handle multiple font sizes with same value in literal mode', async () => {
|
|
392
|
+
const fontSizesWithDuplicates = [
|
|
393
|
+
{
|
|
394
|
+
slug: 'small-1',
|
|
395
|
+
name: 'Small 1',
|
|
396
|
+
size: '12px',
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
slug: 'small-2',
|
|
400
|
+
name: 'Small 2',
|
|
401
|
+
size: '12px',
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
slug: 'medium',
|
|
405
|
+
name: 'Medium',
|
|
406
|
+
size: '16px',
|
|
407
|
+
},
|
|
408
|
+
];
|
|
409
|
+
await render(
|
|
410
|
+
<FontSizePicker
|
|
411
|
+
fontSizes={ fontSizesWithDuplicates }
|
|
412
|
+
value="12px"
|
|
413
|
+
valueMode="literal"
|
|
414
|
+
/>
|
|
415
|
+
);
|
|
416
|
+
// Should have no selection when there are multiple matches
|
|
417
|
+
expect(
|
|
418
|
+
screen.queryByRole( 'radio', { checked: true } )
|
|
419
|
+
).not.toBeInTheDocument();
|
|
420
|
+
} );
|
|
421
|
+
|
|
422
|
+
it( 'should handle multiple font sizes with same value in slug mode', async () => {
|
|
423
|
+
const fontSizesWithDuplicates = [
|
|
424
|
+
{
|
|
425
|
+
slug: 'small-1',
|
|
426
|
+
name: 'Small 1',
|
|
427
|
+
size: '12px',
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
slug: 'small-2',
|
|
431
|
+
name: 'Small 2',
|
|
432
|
+
size: '12px',
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
slug: 'medium',
|
|
436
|
+
name: 'Medium',
|
|
437
|
+
size: '16px',
|
|
438
|
+
},
|
|
439
|
+
];
|
|
440
|
+
await render(
|
|
441
|
+
<FontSizePicker
|
|
442
|
+
fontSizes={ fontSizesWithDuplicates }
|
|
443
|
+
value="small-1"
|
|
444
|
+
valueMode="slug"
|
|
445
|
+
/>
|
|
446
|
+
);
|
|
447
|
+
// Should select the specific font size by slug
|
|
448
|
+
expect(
|
|
449
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
450
|
+
).toHaveAccessibleName( 'Small 1' );
|
|
451
|
+
} );
|
|
452
|
+
} );
|
|
361
453
|
} );
|
|
362
454
|
|
|
363
455
|
describe( 'with ≤ 5 heterogeneous font sizes', () => {
|
|
@@ -430,6 +522,64 @@ describe( 'FontSizePicker', () => {
|
|
|
430
522
|
|
|
431
523
|
commonToggleGroupTests( fontSizes );
|
|
432
524
|
commonTests( fontSizes );
|
|
525
|
+
|
|
526
|
+
describe( 'valueMode prop for heterogeneous toggle group', () => {
|
|
527
|
+
it( 'should find font size by size value when valueMode is literal', async () => {
|
|
528
|
+
await render(
|
|
529
|
+
<FontSizePicker
|
|
530
|
+
fontSizes={ fontSizes }
|
|
531
|
+
value="1em"
|
|
532
|
+
valueMode="literal"
|
|
533
|
+
/>
|
|
534
|
+
);
|
|
535
|
+
// Should select the medium option (1em)
|
|
536
|
+
expect(
|
|
537
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
538
|
+
).toHaveAccessibleName( 'Medium' );
|
|
539
|
+
} );
|
|
540
|
+
|
|
541
|
+
it( 'should find font size by slug when valueMode is slug', async () => {
|
|
542
|
+
await render(
|
|
543
|
+
<FontSizePicker
|
|
544
|
+
fontSizes={ fontSizes }
|
|
545
|
+
value="medium"
|
|
546
|
+
valueMode="slug"
|
|
547
|
+
/>
|
|
548
|
+
);
|
|
549
|
+
// Should select the medium option
|
|
550
|
+
expect(
|
|
551
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
552
|
+
).toHaveAccessibleName( 'Medium' );
|
|
553
|
+
} );
|
|
554
|
+
|
|
555
|
+
it( 'should handle complex font size values in literal mode', async () => {
|
|
556
|
+
await render(
|
|
557
|
+
<FontSizePicker
|
|
558
|
+
fontSizes={ fontSizes }
|
|
559
|
+
value="clamp(1.75rem, 3vw, 2.25rem)"
|
|
560
|
+
valueMode="literal"
|
|
561
|
+
/>
|
|
562
|
+
);
|
|
563
|
+
// Should select the extra large option
|
|
564
|
+
expect(
|
|
565
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
566
|
+
).toHaveAccessibleName( 'Extra Large' );
|
|
567
|
+
} );
|
|
568
|
+
|
|
569
|
+
it( 'should handle complex font size values in slug mode', async () => {
|
|
570
|
+
await render(
|
|
571
|
+
<FontSizePicker
|
|
572
|
+
fontSizes={ fontSizes }
|
|
573
|
+
value="x-large"
|
|
574
|
+
valueMode="slug"
|
|
575
|
+
/>
|
|
576
|
+
);
|
|
577
|
+
// Should select the extra large option
|
|
578
|
+
expect(
|
|
579
|
+
screen.getByRole( 'radio', { checked: true } )
|
|
580
|
+
).toHaveAccessibleName( 'Extra Large' );
|
|
581
|
+
} );
|
|
582
|
+
} );
|
|
433
583
|
} );
|
|
434
584
|
|
|
435
585
|
function commonToggleGroupTests( fontSizes: FontSize[] ) {
|
|
@@ -653,4 +803,312 @@ describe( 'FontSizePicker', () => {
|
|
|
653
803
|
expect( units[ 2 ] ).toHaveAccessibleName( 'ex' );
|
|
654
804
|
} );
|
|
655
805
|
}
|
|
806
|
+
|
|
807
|
+
describe( 'valueMode prop', () => {
|
|
808
|
+
// Use 6 font sizes to trigger select control (> 5)
|
|
809
|
+
const fontSizes = [
|
|
810
|
+
{
|
|
811
|
+
slug: 'small',
|
|
812
|
+
name: 'Small',
|
|
813
|
+
size: '12px',
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
slug: 'medium',
|
|
817
|
+
name: 'Medium',
|
|
818
|
+
size: '16px',
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
slug: 'large',
|
|
822
|
+
name: 'Large',
|
|
823
|
+
size: '20px',
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
slug: 'x-large',
|
|
827
|
+
name: 'Extra Large',
|
|
828
|
+
size: '24px',
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
slug: 'xx-large',
|
|
832
|
+
name: 'XX Large',
|
|
833
|
+
size: '28px',
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
slug: 'huge',
|
|
837
|
+
name: 'Huge',
|
|
838
|
+
size: '32px',
|
|
839
|
+
},
|
|
840
|
+
];
|
|
841
|
+
|
|
842
|
+
describe( 'valueMode="literal" (default)', () => {
|
|
843
|
+
it( 'should find font size by size value when valueMode is literal', async () => {
|
|
844
|
+
await render(
|
|
845
|
+
<FontSizePicker
|
|
846
|
+
fontSizes={ fontSizes }
|
|
847
|
+
value="16px"
|
|
848
|
+
valueMode="literal"
|
|
849
|
+
/>
|
|
850
|
+
);
|
|
851
|
+
// Should select the medium option (16px)
|
|
852
|
+
expect(
|
|
853
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
854
|
+
).toHaveTextContent( 'Medium' );
|
|
855
|
+
} );
|
|
856
|
+
|
|
857
|
+
it( 'should call onChange with size value and FontSize object when valueMode is literal', async () => {
|
|
858
|
+
const user = userEvent.setup();
|
|
859
|
+
const onChange = jest.fn();
|
|
860
|
+
await render(
|
|
861
|
+
<FontSizePicker
|
|
862
|
+
fontSizes={ fontSizes }
|
|
863
|
+
onChange={ onChange }
|
|
864
|
+
valueMode="literal"
|
|
865
|
+
/>
|
|
866
|
+
);
|
|
867
|
+
await user.click(
|
|
868
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
869
|
+
);
|
|
870
|
+
await user.click(
|
|
871
|
+
screen.getByRole( 'option', { name: 'Medium 16px' } )
|
|
872
|
+
);
|
|
873
|
+
expect( onChange ).toHaveBeenCalledWith(
|
|
874
|
+
'16px',
|
|
875
|
+
fontSizes[ 1 ]
|
|
876
|
+
);
|
|
877
|
+
} );
|
|
878
|
+
} );
|
|
879
|
+
|
|
880
|
+
describe( 'valueMode="slug"', () => {
|
|
881
|
+
it( 'should find font size by slug when valueMode is slug', async () => {
|
|
882
|
+
await render(
|
|
883
|
+
<FontSizePicker
|
|
884
|
+
fontSizes={ fontSizes }
|
|
885
|
+
value="medium"
|
|
886
|
+
valueMode="slug"
|
|
887
|
+
/>
|
|
888
|
+
);
|
|
889
|
+
// Should select the medium option
|
|
890
|
+
expect(
|
|
891
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
892
|
+
).toHaveTextContent( 'Medium' );
|
|
893
|
+
} );
|
|
894
|
+
|
|
895
|
+
it( 'should call onChange with size value and FontSize object when valueMode is slug', async () => {
|
|
896
|
+
const user = userEvent.setup();
|
|
897
|
+
const onChange = jest.fn();
|
|
898
|
+
await render(
|
|
899
|
+
<FontSizePicker
|
|
900
|
+
fontSizes={ fontSizes }
|
|
901
|
+
onChange={ onChange }
|
|
902
|
+
valueMode="slug"
|
|
903
|
+
/>
|
|
904
|
+
);
|
|
905
|
+
await user.click(
|
|
906
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
907
|
+
);
|
|
908
|
+
await user.click(
|
|
909
|
+
screen.getByRole( 'option', { name: 'Large 20px' } )
|
|
910
|
+
);
|
|
911
|
+
expect( onChange ).toHaveBeenCalledWith(
|
|
912
|
+
'20px',
|
|
913
|
+
fontSizes[ 2 ]
|
|
914
|
+
);
|
|
915
|
+
} );
|
|
916
|
+
|
|
917
|
+
it( 'should handle undefined value when valueMode is slug', async () => {
|
|
918
|
+
await render(
|
|
919
|
+
<FontSizePicker
|
|
920
|
+
fontSizes={ fontSizes }
|
|
921
|
+
value={ undefined }
|
|
922
|
+
valueMode="slug"
|
|
923
|
+
/>
|
|
924
|
+
);
|
|
925
|
+
// Should show default option
|
|
926
|
+
expect(
|
|
927
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
928
|
+
).toHaveTextContent( 'Default' );
|
|
929
|
+
} );
|
|
930
|
+
|
|
931
|
+
it( 'should handle empty string value when valueMode is slug', async () => {
|
|
932
|
+
await render(
|
|
933
|
+
<FontSizePicker
|
|
934
|
+
fontSizes={ fontSizes }
|
|
935
|
+
value=""
|
|
936
|
+
valueMode="slug"
|
|
937
|
+
/>
|
|
938
|
+
);
|
|
939
|
+
// Should show default option
|
|
940
|
+
expect(
|
|
941
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
942
|
+
).toHaveTextContent( 'Default' );
|
|
943
|
+
} );
|
|
944
|
+
} );
|
|
945
|
+
|
|
946
|
+
describe( 'edge cases with valueMode', () => {
|
|
947
|
+
// Use 6 font sizes to trigger select control (> 5)
|
|
948
|
+
const fontSizesWithDuplicates = [
|
|
949
|
+
{
|
|
950
|
+
slug: 'small-1',
|
|
951
|
+
name: 'Small 1',
|
|
952
|
+
size: '12px',
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
slug: 'small-2',
|
|
956
|
+
name: 'Small 2',
|
|
957
|
+
size: '12px',
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
slug: 'medium',
|
|
961
|
+
name: 'Medium',
|
|
962
|
+
size: '16px',
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
slug: 'large',
|
|
966
|
+
name: 'Large',
|
|
967
|
+
size: '20px',
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
slug: 'x-large',
|
|
971
|
+
name: 'Extra Large',
|
|
972
|
+
size: '24px',
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
slug: 'huge',
|
|
976
|
+
name: 'Huge',
|
|
977
|
+
size: '28px',
|
|
978
|
+
},
|
|
979
|
+
];
|
|
980
|
+
|
|
981
|
+
it( 'should handle multiple font sizes with same value in literal mode', async () => {
|
|
982
|
+
await render(
|
|
983
|
+
<FontSizePicker
|
|
984
|
+
fontSizes={ fontSizesWithDuplicates }
|
|
985
|
+
value="12px"
|
|
986
|
+
valueMode="literal"
|
|
987
|
+
/>
|
|
988
|
+
);
|
|
989
|
+
// Should show the first matching font size when there are multiple matches
|
|
990
|
+
expect(
|
|
991
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
992
|
+
).toHaveTextContent( 'Small 1' );
|
|
993
|
+
} );
|
|
994
|
+
|
|
995
|
+
it( 'should handle multiple font sizes with same value in slug mode', async () => {
|
|
996
|
+
await render(
|
|
997
|
+
<FontSizePicker
|
|
998
|
+
fontSizes={ fontSizesWithDuplicates }
|
|
999
|
+
value="small-1"
|
|
1000
|
+
valueMode="slug"
|
|
1001
|
+
/>
|
|
1002
|
+
);
|
|
1003
|
+
// Should select the specific font size by slug
|
|
1004
|
+
expect(
|
|
1005
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
1006
|
+
).toHaveTextContent( 'Small 1' );
|
|
1007
|
+
} );
|
|
1008
|
+
} );
|
|
1009
|
+
} );
|
|
1010
|
+
|
|
1011
|
+
describe( 'onChange callback signature', () => {
|
|
1012
|
+
// Use 6 font sizes to trigger select control (> 5)
|
|
1013
|
+
const fontSizes = [
|
|
1014
|
+
{
|
|
1015
|
+
slug: 'small',
|
|
1016
|
+
name: 'Small',
|
|
1017
|
+
size: '12px',
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
slug: 'medium',
|
|
1021
|
+
name: 'Medium',
|
|
1022
|
+
size: '16px',
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
slug: 'large',
|
|
1026
|
+
name: 'Large',
|
|
1027
|
+
size: '20px',
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
slug: 'x-large',
|
|
1031
|
+
name: 'Extra Large',
|
|
1032
|
+
size: '24px',
|
|
1033
|
+
},
|
|
1034
|
+
{
|
|
1035
|
+
slug: 'xx-large',
|
|
1036
|
+
name: 'XX Large',
|
|
1037
|
+
size: '28px',
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
slug: 'huge',
|
|
1041
|
+
name: 'Huge',
|
|
1042
|
+
size: '32px',
|
|
1043
|
+
},
|
|
1044
|
+
];
|
|
1045
|
+
|
|
1046
|
+
it( 'should call onChange with FontSize object as second parameter for select control', async () => {
|
|
1047
|
+
const user = userEvent.setup();
|
|
1048
|
+
const onChange = jest.fn();
|
|
1049
|
+
await render(
|
|
1050
|
+
<FontSizePicker fontSizes={ fontSizes } onChange={ onChange } />
|
|
1051
|
+
);
|
|
1052
|
+
await user.click(
|
|
1053
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
1054
|
+
);
|
|
1055
|
+
await user.click(
|
|
1056
|
+
screen.getByRole( 'option', { name: 'Small 12px' } )
|
|
1057
|
+
);
|
|
1058
|
+
expect( onChange ).toHaveBeenCalledWith( '12px', fontSizes[ 0 ] );
|
|
1059
|
+
} );
|
|
1060
|
+
|
|
1061
|
+
it( 'should call onChange with undefined as second parameter for default option', async () => {
|
|
1062
|
+
const user = userEvent.setup();
|
|
1063
|
+
const onChange = jest.fn();
|
|
1064
|
+
await render(
|
|
1065
|
+
<FontSizePicker
|
|
1066
|
+
fontSizes={ fontSizes }
|
|
1067
|
+
value="16px" // Start with a selected value
|
|
1068
|
+
onChange={ onChange }
|
|
1069
|
+
/>
|
|
1070
|
+
);
|
|
1071
|
+
await user.click(
|
|
1072
|
+
screen.getByRole( 'combobox', { name: 'Font size' } )
|
|
1073
|
+
);
|
|
1074
|
+
await user.click(
|
|
1075
|
+
screen.getByRole( 'option', { name: 'Default' } )
|
|
1076
|
+
);
|
|
1077
|
+
expect( onChange ).toHaveBeenCalledWith( undefined, undefined );
|
|
1078
|
+
} );
|
|
1079
|
+
|
|
1080
|
+
it( 'should call onChange with FontSize object as second parameter for toggle group control', async () => {
|
|
1081
|
+
const user = userEvent.setup();
|
|
1082
|
+
const onChange = jest.fn();
|
|
1083
|
+
// Use fewer font sizes to trigger toggle group (≤ 5)
|
|
1084
|
+
const toggleGroupFontSizes = [
|
|
1085
|
+
{
|
|
1086
|
+
slug: 'small',
|
|
1087
|
+
name: 'Small',
|
|
1088
|
+
size: '12px',
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
slug: 'medium',
|
|
1092
|
+
name: 'Medium',
|
|
1093
|
+
size: '16px',
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
slug: 'large',
|
|
1097
|
+
name: 'Large',
|
|
1098
|
+
size: '20px',
|
|
1099
|
+
},
|
|
1100
|
+
];
|
|
1101
|
+
await render(
|
|
1102
|
+
<FontSizePicker
|
|
1103
|
+
fontSizes={ toggleGroupFontSizes }
|
|
1104
|
+
onChange={ onChange }
|
|
1105
|
+
/>
|
|
1106
|
+
);
|
|
1107
|
+
await user.click( screen.getByRole( 'radio', { name: 'Small' } ) );
|
|
1108
|
+
expect( onChange ).toHaveBeenCalledWith(
|
|
1109
|
+
'12px',
|
|
1110
|
+
toggleGroupFontSizes[ 0 ]
|
|
1111
|
+
);
|
|
1112
|
+
} );
|
|
1113
|
+
} );
|
|
656
1114
|
} );
|
|
@@ -40,6 +40,14 @@ export type FontSizePickerProps = {
|
|
|
40
40
|
* as a number, the component operates in "unitless mode" where the `units` property has no effect.
|
|
41
41
|
*/
|
|
42
42
|
value?: number | string;
|
|
43
|
+
/**
|
|
44
|
+
* Determines how the `value` prop should be interpreted.
|
|
45
|
+
* - `'literal'`: The `value` prop contains the actual font size value (number or string)
|
|
46
|
+
* - `'slug'`: The `value` prop contains the slug of the selected font size
|
|
47
|
+
*
|
|
48
|
+
* @default 'literal'
|
|
49
|
+
*/
|
|
50
|
+
valueMode?: 'literal' | 'slug';
|
|
43
51
|
/**
|
|
44
52
|
* If `true`, a slider will be displayed alongside the input field when a
|
|
45
53
|
* custom font size is active. Has no effect when `disableCustomFontSizes`
|
|
@@ -96,17 +104,26 @@ export type FontSize = {
|
|
|
96
104
|
* size. Used for the class generation process.
|
|
97
105
|
*/
|
|
98
106
|
slug: string;
|
|
107
|
+
/**
|
|
108
|
+
* The `hint` property is an optional string that provides additional information
|
|
109
|
+
* about the font size, such as fluid typography ranges or custom descriptions.
|
|
110
|
+
* Consumers can use this to provide their own preferred hints.
|
|
111
|
+
*/
|
|
112
|
+
hint?: string;
|
|
99
113
|
};
|
|
100
114
|
|
|
101
115
|
export type FontSizePickerSelectProps = Pick<
|
|
102
116
|
FontSizePickerProps,
|
|
103
|
-
'value' | 'size'
|
|
117
|
+
'value' | 'size' | 'valueMode'
|
|
104
118
|
> & {
|
|
105
119
|
fontSizes: NonNullable< FontSizePickerProps[ 'fontSizes' ] >;
|
|
106
120
|
disableCustomFontSizes: NonNullable<
|
|
107
121
|
FontSizePickerProps[ 'disableCustomFontSizes' ]
|
|
108
122
|
>;
|
|
109
|
-
onChange:
|
|
123
|
+
onChange: (
|
|
124
|
+
value: number | string | undefined,
|
|
125
|
+
selectedItem?: FontSize
|
|
126
|
+
) => void;
|
|
110
127
|
onSelectCustom: () => void;
|
|
111
128
|
__next40pxDefaultSize: boolean;
|
|
112
129
|
};
|
|
@@ -120,8 +137,11 @@ export type FontSizePickerSelectOption = {
|
|
|
120
137
|
|
|
121
138
|
export type FontSizePickerToggleGroupProps = Pick<
|
|
122
139
|
FontSizePickerProps,
|
|
123
|
-
'value' | 'size' | '__next40pxDefaultSize'
|
|
140
|
+
'value' | 'size' | '__next40pxDefaultSize' | 'valueMode'
|
|
124
141
|
> & {
|
|
125
142
|
fontSizes: NonNullable< FontSizePickerProps[ 'fontSizes' ] >;
|
|
126
|
-
onChange:
|
|
143
|
+
onChange: (
|
|
144
|
+
value: number | string | undefined,
|
|
145
|
+
selectedItem?: FontSize
|
|
146
|
+
) => void;
|
|
127
147
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { FontSizePickerProps } from './types';
|
|
4
|
+
import type { FontSizePickerProps, FontSize } from './types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Some themes use css vars for their font sizes, so until we
|
|
@@ -17,3 +17,25 @@ export function isSimpleCssValue(
|
|
|
17
17
|
/^[\d\.]+(px|em|rem|vw|vh|%|svw|lvw|dvw|svh|lvh|dvh|vi|svi|lvi|dvi|vb|svb|lvb|dvb|vmin|svmin|lvmin|dvmin|vmax|svmax|lvmax|dvmax)?$/i;
|
|
18
18
|
return sizeRegex.test( String( value ) );
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Generates hint text for a font size.
|
|
23
|
+
* This function returns the hint provided by the consumer, if any.
|
|
24
|
+
* If no hint is provided, it falls back to showing the size value for simple CSS values.
|
|
25
|
+
*
|
|
26
|
+
* @param fontSize The font size object to generate hint text for.
|
|
27
|
+
* @return The hint text provided by the consumer, or the size value for simple CSS values, or undefined.
|
|
28
|
+
*/
|
|
29
|
+
export function generateFontSizeHint( fontSize: FontSize ): string | undefined {
|
|
30
|
+
// If the font size already has a hint, use it
|
|
31
|
+
if ( fontSize.hint ) {
|
|
32
|
+
return fontSize.hint;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Fallback to showing the size value if it's a simple CSS value
|
|
36
|
+
if ( isSimpleCssValue( fontSize.size ) ) {
|
|
37
|
+
return String( fontSize.size );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|