@wordpress/components 19.1.5 → 19.1.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 +8 -0
- package/build/font-size-picker/index.js +10 -9
- package/build/font-size-picker/index.js.map +1 -1
- package/build/font-size-picker/utils.js +19 -9
- package/build/font-size-picker/utils.js.map +1 -1
- package/build/palette-edit/index.js +31 -27
- package/build/palette-edit/index.js.map +1 -1
- package/build/palette-edit/styles.js +10 -10
- package/build/palette-edit/styles.js.map +1 -1
- package/build/tools-panel/tools-panel-item/hook.js +12 -6
- package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
- package/build-module/font-size-picker/index.js +10 -9
- package/build-module/font-size-picker/index.js.map +1 -1
- package/build-module/font-size-picker/utils.js +19 -9
- package/build-module/font-size-picker/utils.js.map +1 -1
- package/build-module/palette-edit/index.js +30 -27
- package/build-module/palette-edit/index.js.map +1 -1
- package/build-module/palette-edit/styles.js +10 -10
- package/build-module/palette-edit/styles.js.map +1 -1
- package/build-module/tools-panel/tools-panel-item/hook.js +12 -6
- package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
- package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/font-size-picker/index.js +27 -13
- package/src/font-size-picker/stories/index.js +62 -0
- package/src/font-size-picker/test/index.js +87 -0
- package/src/font-size-picker/utils.js +22 -9
- package/src/palette-edit/index.js +106 -73
- package/src/palette-edit/styles.js +0 -2
- package/src/tools-panel/test/index.js +353 -3
- package/src/tools-panel/tools-panel/README.md +3 -2
- package/src/tools-panel/tools-panel-item/hook.ts +18 -6
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
+
import { render, screen, fireEvent, within } from '@testing-library/react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
@@ -11,6 +11,7 @@ import { createSlotFill, Provider as SlotFillProvider } from '../../slot-fill';
|
|
|
11
11
|
|
|
12
12
|
const { Fill: ToolsPanelItems, Slot } = createSlotFill( 'ToolsPanelSlot' );
|
|
13
13
|
const resetAll = jest.fn();
|
|
14
|
+
const noop = () => undefined;
|
|
14
15
|
|
|
15
16
|
// Default props for the tools panel.
|
|
16
17
|
const defaultProps = {
|
|
@@ -86,6 +87,23 @@ const GroupedItems = ( {
|
|
|
86
87
|
);
|
|
87
88
|
};
|
|
88
89
|
|
|
90
|
+
// This context object is used to help simulate different scenarios in which
|
|
91
|
+
// `ToolsPanelItem` registration or deregistration requires testing.
|
|
92
|
+
const panelContext = {
|
|
93
|
+
panelId: '1234',
|
|
94
|
+
menuItems: {
|
|
95
|
+
default: {},
|
|
96
|
+
optional: { [ altControlProps.label ]: true },
|
|
97
|
+
},
|
|
98
|
+
hasMenuItems: false,
|
|
99
|
+
isResetting: false,
|
|
100
|
+
shouldRenderPlaceholderItems: false,
|
|
101
|
+
registerPanelItem: jest.fn(),
|
|
102
|
+
deregisterPanelItem: jest.fn(),
|
|
103
|
+
flagItemCustomization: noop,
|
|
104
|
+
areAllOptionalControlsHidden: true,
|
|
105
|
+
};
|
|
106
|
+
|
|
89
107
|
// Renders a tools panel including panel items that have been grouped within
|
|
90
108
|
// a custom component.
|
|
91
109
|
const renderGroupedItemsInPanel = () => {
|
|
@@ -348,6 +366,287 @@ describe( 'ToolsPanel', () => {
|
|
|
348
366
|
// there.
|
|
349
367
|
expect( optionalItem ).not.toBeInTheDocument();
|
|
350
368
|
} );
|
|
369
|
+
|
|
370
|
+
it( 'should render default controls with conditional isShownByDefault', async () => {
|
|
371
|
+
const linkedControlProps = {
|
|
372
|
+
attributes: { value: false },
|
|
373
|
+
hasValue: jest.fn().mockImplementation( () => {
|
|
374
|
+
return !! linkedControlProps.attributes.value;
|
|
375
|
+
} ),
|
|
376
|
+
label: 'Linked',
|
|
377
|
+
onDeselect: jest.fn(),
|
|
378
|
+
onSelect: jest.fn(),
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
const TestPanel = () => (
|
|
382
|
+
<ToolsPanel { ...defaultProps }>
|
|
383
|
+
<ToolsPanelItem
|
|
384
|
+
{ ...altControlProps }
|
|
385
|
+
isShownByDefault={ true }
|
|
386
|
+
>
|
|
387
|
+
<div>Default control</div>
|
|
388
|
+
</ToolsPanelItem>
|
|
389
|
+
<ToolsPanelItem
|
|
390
|
+
{ ...linkedControlProps }
|
|
391
|
+
isShownByDefault={ !! altControlProps.attributes.value }
|
|
392
|
+
>
|
|
393
|
+
<div>Linked control</div>
|
|
394
|
+
</ToolsPanelItem>
|
|
395
|
+
</ToolsPanel>
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
const { rerender } = render( <TestPanel /> );
|
|
399
|
+
|
|
400
|
+
// The linked control should start out as an optional control and is
|
|
401
|
+
// not rendered because it does not have a value.
|
|
402
|
+
let linkedItem = screen.queryByText( 'Linked control' );
|
|
403
|
+
expect( linkedItem ).not.toBeInTheDocument();
|
|
404
|
+
|
|
405
|
+
openDropdownMenu();
|
|
406
|
+
|
|
407
|
+
// The linked control should initially appear in the optional controls
|
|
408
|
+
// menu group. There should be three menu groups: default controls,
|
|
409
|
+
// optional controls, and the group to reset all options.
|
|
410
|
+
let menuGroups = screen.getAllByRole( 'group' );
|
|
411
|
+
expect( menuGroups.length ).toEqual( 3 );
|
|
412
|
+
|
|
413
|
+
// The linked control should be in the second group, of optional controls.
|
|
414
|
+
let optionalItem = within( menuGroups[ 1 ] ).getByText( 'Linked' );
|
|
415
|
+
expect( optionalItem ).toBeInTheDocument();
|
|
416
|
+
|
|
417
|
+
// Simulate the main control having a value set which should
|
|
418
|
+
// trigger the linked control becoming a default control via the
|
|
419
|
+
// conditional `isShownByDefault` prop.
|
|
420
|
+
altControlProps.attributes.value = true;
|
|
421
|
+
|
|
422
|
+
rerender( <TestPanel /> );
|
|
423
|
+
|
|
424
|
+
// The linked control should now be a default control and rendered
|
|
425
|
+
// despite not having a value.
|
|
426
|
+
linkedItem = screen.getByText( 'Linked control' );
|
|
427
|
+
expect( linkedItem ).toBeInTheDocument();
|
|
428
|
+
|
|
429
|
+
// The linked control should now appear in the default controls
|
|
430
|
+
// menu group and have been removed from the optional group.
|
|
431
|
+
menuGroups = screen.getAllByRole( 'group' );
|
|
432
|
+
|
|
433
|
+
// There should now only be two groups. The default controls and
|
|
434
|
+
// and the group for the reset all option.
|
|
435
|
+
expect( menuGroups.length ).toEqual( 2 );
|
|
436
|
+
|
|
437
|
+
// The new default control item for the Linked control should be
|
|
438
|
+
// within the first menu group.
|
|
439
|
+
const defaultItem = within( menuGroups[ 0 ] ).getByText( 'Linked' );
|
|
440
|
+
expect( defaultItem ).toBeInTheDocument();
|
|
441
|
+
|
|
442
|
+
// Optional controls have an additional aria-label. This can be used
|
|
443
|
+
// to confirm the conditional default control has been removed from
|
|
444
|
+
// the optional menu item group.
|
|
445
|
+
optionalItem = screen.queryByRole( 'menuitemcheckbox', {
|
|
446
|
+
name: 'Show Linked',
|
|
447
|
+
} );
|
|
448
|
+
expect( optionalItem ).not.toBeInTheDocument();
|
|
449
|
+
} );
|
|
450
|
+
|
|
451
|
+
it( 'should handle conditionally rendered default control', async () => {
|
|
452
|
+
const conditionalControlProps = {
|
|
453
|
+
attributes: { value: false },
|
|
454
|
+
hasValue: jest.fn().mockImplementation( () => {
|
|
455
|
+
return !! conditionalControlProps.attributes.value;
|
|
456
|
+
} ),
|
|
457
|
+
label: 'Conditional',
|
|
458
|
+
onDeselect: jest.fn(),
|
|
459
|
+
onSelect: jest.fn(),
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
const TestPanel = () => (
|
|
463
|
+
<ToolsPanel { ...defaultProps }>
|
|
464
|
+
<ToolsPanelItem
|
|
465
|
+
{ ...altControlProps }
|
|
466
|
+
isShownByDefault={ true }
|
|
467
|
+
>
|
|
468
|
+
<div>Default control</div>
|
|
469
|
+
</ToolsPanelItem>
|
|
470
|
+
{ !! altControlProps.attributes.value && (
|
|
471
|
+
<ToolsPanelItem
|
|
472
|
+
{ ...conditionalControlProps }
|
|
473
|
+
isShownByDefault={ true }
|
|
474
|
+
>
|
|
475
|
+
<div>Conditional control</div>
|
|
476
|
+
</ToolsPanelItem>
|
|
477
|
+
) }
|
|
478
|
+
</ToolsPanel>
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
const { rerender } = render( <TestPanel /> );
|
|
482
|
+
|
|
483
|
+
// The conditional control should not yet be rendered.
|
|
484
|
+
let conditionalItem = screen.queryByText( 'Conditional control' );
|
|
485
|
+
expect( conditionalItem ).not.toBeInTheDocument();
|
|
486
|
+
|
|
487
|
+
// The conditional control should not yet appear in the default controls
|
|
488
|
+
// menu group.
|
|
489
|
+
openDropdownMenu();
|
|
490
|
+
let menuGroups = screen.getAllByRole( 'group' );
|
|
491
|
+
let defaultItem = within( menuGroups[ 0 ] ).queryByText(
|
|
492
|
+
'Conditional'
|
|
493
|
+
);
|
|
494
|
+
expect( defaultItem ).not.toBeInTheDocument();
|
|
495
|
+
|
|
496
|
+
// Simulate the main control having a value set which will now
|
|
497
|
+
// render the new default control into the ToolsPanel.
|
|
498
|
+
altControlProps.attributes.value = true;
|
|
499
|
+
|
|
500
|
+
rerender( <TestPanel /> );
|
|
501
|
+
|
|
502
|
+
// The conditional control should now be rendered and included in
|
|
503
|
+
// the panel's menu.
|
|
504
|
+
conditionalItem = screen.getByText( 'Conditional control' );
|
|
505
|
+
expect( conditionalItem ).toBeInTheDocument();
|
|
506
|
+
|
|
507
|
+
// The conditional control should now appear in the default controls
|
|
508
|
+
// menu group.
|
|
509
|
+
menuGroups = screen.getAllByRole( 'group' );
|
|
510
|
+
|
|
511
|
+
// The new default control item for the Conditional control should
|
|
512
|
+
// be within the first menu group.
|
|
513
|
+
defaultItem = within( menuGroups[ 0 ] ).getByText( 'Conditional' );
|
|
514
|
+
expect( defaultItem ).toBeInTheDocument();
|
|
515
|
+
} );
|
|
516
|
+
} );
|
|
517
|
+
|
|
518
|
+
describe( 'registration of panel items', () => {
|
|
519
|
+
beforeEach( () => {
|
|
520
|
+
jest.clearAllMocks();
|
|
521
|
+
} );
|
|
522
|
+
|
|
523
|
+
it( 'should register and deregister items when panelId changes', () => {
|
|
524
|
+
// This test simulates switching block selection, which causes the
|
|
525
|
+
// `ToolsPanel` to rerender with a new panelId, necessitating the
|
|
526
|
+
// registration and deregistration of appropriate `ToolsPanelItem`
|
|
527
|
+
// children.
|
|
528
|
+
//
|
|
529
|
+
// When the `panelId` changes, only items matching the new ID register
|
|
530
|
+
// themselves, while those for the old panelId deregister.
|
|
531
|
+
//
|
|
532
|
+
// See: https://github.com/WordPress/gutenberg/pull/36588
|
|
533
|
+
const context = { ...panelContext };
|
|
534
|
+
const TestPanel = () => (
|
|
535
|
+
<ToolsPanelContext.Provider value={ context }>
|
|
536
|
+
<ToolsPanelItem { ...altControlProps } panelId="1234">
|
|
537
|
+
<div>Item</div>
|
|
538
|
+
</ToolsPanelItem>
|
|
539
|
+
</ToolsPanelContext.Provider>
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
// On the initial render of the panel, the ToolsPanelItem should
|
|
543
|
+
// be registered.
|
|
544
|
+
const { rerender } = render( <TestPanel /> );
|
|
545
|
+
|
|
546
|
+
expect( context.registerPanelItem ).toHaveBeenCalledWith(
|
|
547
|
+
expect.objectContaining( {
|
|
548
|
+
label: altControlProps.label,
|
|
549
|
+
panelId: '1234',
|
|
550
|
+
} )
|
|
551
|
+
);
|
|
552
|
+
expect( context.deregisterPanelItem ).not.toHaveBeenCalled();
|
|
553
|
+
|
|
554
|
+
// Simulate a change in panel, e.g. a switch of block selection.
|
|
555
|
+
context.panelId = '4321';
|
|
556
|
+
context.menuItems.optional[ altControlProps.label ] = false;
|
|
557
|
+
|
|
558
|
+
// Rerender the panel item. Because we have a new panelId, this
|
|
559
|
+
// panelItem should NOT be registered, but it SHOULD be
|
|
560
|
+
// deregistered.
|
|
561
|
+
rerender( <TestPanel /> );
|
|
562
|
+
|
|
563
|
+
// registerPanelItem has still only been called once.
|
|
564
|
+
expect( context.registerPanelItem ).toHaveBeenCalledTimes( 1 );
|
|
565
|
+
// deregisterPanelItem is called, given that we have switched panels.
|
|
566
|
+
expect( context.deregisterPanelItem ).toBeCalledWith(
|
|
567
|
+
altControlProps.label
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
// Simulate switching back to the original panelId, e.g. by selecting
|
|
571
|
+
// the original block again.
|
|
572
|
+
context.panelId = '1234';
|
|
573
|
+
context.menuItems.optional[ altControlProps.label ] = true;
|
|
574
|
+
|
|
575
|
+
// Rerender the panel and ensure that the panelItem is registered
|
|
576
|
+
// again, and it is not de-registered.
|
|
577
|
+
rerender( <TestPanel /> );
|
|
578
|
+
|
|
579
|
+
expect( context.registerPanelItem ).toHaveBeenCalledWith(
|
|
580
|
+
expect.objectContaining( {
|
|
581
|
+
label: altControlProps.label,
|
|
582
|
+
panelId: '1234',
|
|
583
|
+
} )
|
|
584
|
+
);
|
|
585
|
+
expect( context.registerPanelItem ).toHaveBeenCalledTimes( 2 );
|
|
586
|
+
// deregisterPanelItem has still only been called once.
|
|
587
|
+
expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 1 );
|
|
588
|
+
} );
|
|
589
|
+
|
|
590
|
+
it( 'should register items when ToolsPanel panelId is null', () => {
|
|
591
|
+
// This test simulates when a panel spans multiple block selections.
|
|
592
|
+
// Multi-selection means a panel can't have a single id to match
|
|
593
|
+
// against the item's. Instead the panel gets an id of `null` and
|
|
594
|
+
// individual items should still render themselves in this case.
|
|
595
|
+
//
|
|
596
|
+
// See: https://github.com/WordPress/gutenberg/pull/37216
|
|
597
|
+
const context = { ...panelContext, panelId: null };
|
|
598
|
+
const TestPanel = () => (
|
|
599
|
+
<ToolsPanelContext.Provider value={ context }>
|
|
600
|
+
<ToolsPanelItem { ...altControlProps } panelId="1234">
|
|
601
|
+
<div>Item</div>
|
|
602
|
+
</ToolsPanelItem>
|
|
603
|
+
</ToolsPanelContext.Provider>
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
// On the initial render of the panel, the ToolsPanelItem should
|
|
607
|
+
// be registered.
|
|
608
|
+
const { rerender, unmount } = render( <TestPanel /> );
|
|
609
|
+
|
|
610
|
+
expect( context.registerPanelItem ).toHaveBeenCalledWith(
|
|
611
|
+
expect.objectContaining( {
|
|
612
|
+
label: altControlProps.label,
|
|
613
|
+
panelId: '1234',
|
|
614
|
+
} )
|
|
615
|
+
);
|
|
616
|
+
expect( context.deregisterPanelItem ).not.toHaveBeenCalled();
|
|
617
|
+
|
|
618
|
+
// Simulate a further block selection being added to the
|
|
619
|
+
// multi-selection. The panelId will remain `null` in this case.
|
|
620
|
+
rerender( <TestPanel /> );
|
|
621
|
+
expect( context.registerPanelItem ).toHaveBeenCalledTimes( 1 );
|
|
622
|
+
expect( context.deregisterPanelItem ).not.toHaveBeenCalled();
|
|
623
|
+
|
|
624
|
+
// Simulate a change in panel back to single block selection for
|
|
625
|
+
// which the item matches panelId.
|
|
626
|
+
context.panelId = '1234';
|
|
627
|
+
rerender( <TestPanel /> );
|
|
628
|
+
expect( context.registerPanelItem ).toHaveBeenCalledTimes( 1 );
|
|
629
|
+
expect( context.deregisterPanelItem ).not.toHaveBeenCalled();
|
|
630
|
+
|
|
631
|
+
// Simulate another multi-selection where the panelId is `null`.
|
|
632
|
+
// Item should re-register itself after it deregistered as the
|
|
633
|
+
// multi-selection occurred.
|
|
634
|
+
context.panelId = null;
|
|
635
|
+
rerender( <TestPanel /> );
|
|
636
|
+
expect( context.registerPanelItem ).toHaveBeenCalledTimes( 2 );
|
|
637
|
+
expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 1 );
|
|
638
|
+
|
|
639
|
+
// Simulate a change in panel e.g. back to a single block selection
|
|
640
|
+
// Where the item's panelId is not a match.
|
|
641
|
+
context.panelId = '4321';
|
|
642
|
+
rerender( <TestPanel /> );
|
|
643
|
+
|
|
644
|
+
// As the item no longer matches the panelId it should not have
|
|
645
|
+
// registered again but instead deregistered.
|
|
646
|
+
unmount();
|
|
647
|
+
expect( context.registerPanelItem ).toHaveBeenCalledTimes( 2 );
|
|
648
|
+
expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 2 );
|
|
649
|
+
} );
|
|
351
650
|
} );
|
|
352
651
|
|
|
353
652
|
describe( 'callbacks on menu item selection', () => {
|
|
@@ -542,8 +841,6 @@ describe( 'ToolsPanel', () => {
|
|
|
542
841
|
// This test simulates this issue by rendering an item within a
|
|
543
842
|
// contrived `ToolsPanelContext` to reflect the changes the panel
|
|
544
843
|
// item needs to protect against.
|
|
545
|
-
|
|
546
|
-
const noop = () => undefined;
|
|
547
844
|
const context = {
|
|
548
845
|
panelId: '1234',
|
|
549
846
|
menuItems: {
|
|
@@ -588,6 +885,59 @@ describe( 'ToolsPanel', () => {
|
|
|
588
885
|
|
|
589
886
|
expect( altControlProps.onDeselect ).not.toHaveBeenCalled();
|
|
590
887
|
} );
|
|
888
|
+
|
|
889
|
+
it( 'should not contain orphaned menu items when panelId changes', async () => {
|
|
890
|
+
// As fills and the panel can update independently this aims to
|
|
891
|
+
// test that no orphaned items appear registered in the panel menu.
|
|
892
|
+
//
|
|
893
|
+
// See: https://github.com/WordPress/gutenberg/pull/34085
|
|
894
|
+
const TestSlotFillPanel = ( { panelId } ) => (
|
|
895
|
+
<SlotFillProvider>
|
|
896
|
+
<ToolsPanelItems>
|
|
897
|
+
<ToolsPanelItem { ...altControlProps } panelId="1234">
|
|
898
|
+
<div>Item 1</div>
|
|
899
|
+
</ToolsPanelItem>
|
|
900
|
+
</ToolsPanelItems>
|
|
901
|
+
<ToolsPanelItems>
|
|
902
|
+
<ToolsPanelItem { ...controlProps } panelId="9999">
|
|
903
|
+
<div>Item 2</div>
|
|
904
|
+
</ToolsPanelItem>
|
|
905
|
+
</ToolsPanelItems>
|
|
906
|
+
<ToolsPanel { ...defaultProps } panelId={ panelId }>
|
|
907
|
+
<Slot />
|
|
908
|
+
</ToolsPanel>
|
|
909
|
+
</SlotFillProvider>
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
const { rerender } = render( <TestSlotFillPanel panelId="1234" /> );
|
|
913
|
+
await openDropdownMenu();
|
|
914
|
+
|
|
915
|
+
// Only the item matching the panelId should have been registered
|
|
916
|
+
// and appear in the panel menu.
|
|
917
|
+
let altMenuItem = screen.getByRole( 'menuitemcheckbox', {
|
|
918
|
+
name: 'Show Alt',
|
|
919
|
+
} );
|
|
920
|
+
let exampleMenuItem = screen.queryByRole( 'menuitemcheckbox', {
|
|
921
|
+
name: 'Hide and reset Example',
|
|
922
|
+
} );
|
|
923
|
+
|
|
924
|
+
expect( altMenuItem ).toBeInTheDocument();
|
|
925
|
+
expect( exampleMenuItem ).not.toBeInTheDocument();
|
|
926
|
+
|
|
927
|
+
// Re-render the panel with different panelID simulating a block
|
|
928
|
+
// selection change.
|
|
929
|
+
rerender( <TestSlotFillPanel panelId="9999" /> );
|
|
930
|
+
|
|
931
|
+
altMenuItem = screen.queryByRole( 'menuitemcheckbox', {
|
|
932
|
+
name: 'Show Alt',
|
|
933
|
+
} );
|
|
934
|
+
exampleMenuItem = screen.getByRole( 'menuitemcheckbox', {
|
|
935
|
+
name: 'Hide and reset Example',
|
|
936
|
+
} );
|
|
937
|
+
|
|
938
|
+
expect( altMenuItem ).not.toBeInTheDocument();
|
|
939
|
+
expect( exampleMenuItem ).toBeInTheDocument();
|
|
940
|
+
} );
|
|
591
941
|
} );
|
|
592
942
|
|
|
593
943
|
describe( 'panel header icon toggle', () => {
|
|
@@ -84,8 +84,9 @@ panel's dropdown menu.
|
|
|
84
84
|
### `panelId`: `string`
|
|
85
85
|
|
|
86
86
|
If a `panelId` is set, it is passed through the `ToolsPanelContext` and used
|
|
87
|
-
to restrict panel items.
|
|
88
|
-
|
|
87
|
+
to restrict panel items. When a `panelId` is set, items can only register
|
|
88
|
+
themselves if the `panelId` is explicitly `null` or the item's `panelId` matches
|
|
89
|
+
exactly.
|
|
89
90
|
|
|
90
91
|
- Required: No
|
|
91
92
|
|
|
@@ -40,11 +40,15 @@ export function useToolsPanelItem(
|
|
|
40
40
|
|
|
41
41
|
const hasValueCallback = useCallback( hasValue, [ panelId ] );
|
|
42
42
|
const resetAllFilterCallback = useCallback( resetAllFilter, [ panelId ] );
|
|
43
|
+
const previousPanelId = usePrevious( currentPanelId );
|
|
44
|
+
|
|
45
|
+
const hasMatchingPanel =
|
|
46
|
+
currentPanelId === panelId || currentPanelId === null;
|
|
43
47
|
|
|
44
48
|
// Registering the panel item allows the panel to include it in its
|
|
45
49
|
// automatically generated menu and determine its initial checked status.
|
|
46
50
|
useEffect( () => {
|
|
47
|
-
if (
|
|
51
|
+
if ( hasMatchingPanel && previousPanelId !== null ) {
|
|
48
52
|
registerPanelItem( {
|
|
49
53
|
hasValue: hasValueCallback,
|
|
50
54
|
isShownByDefault,
|
|
@@ -54,13 +58,22 @@ export function useToolsPanelItem(
|
|
|
54
58
|
} );
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
return () =>
|
|
61
|
+
return () => {
|
|
62
|
+
if (
|
|
63
|
+
( previousPanelId === null && !! currentPanelId ) ||
|
|
64
|
+
currentPanelId === panelId
|
|
65
|
+
) {
|
|
66
|
+
deregisterPanelItem( label );
|
|
67
|
+
}
|
|
68
|
+
};
|
|
58
69
|
}, [
|
|
59
70
|
currentPanelId,
|
|
60
|
-
|
|
71
|
+
hasMatchingPanel,
|
|
61
72
|
isShownByDefault,
|
|
62
73
|
label,
|
|
63
74
|
hasValueCallback,
|
|
75
|
+
panelId,
|
|
76
|
+
previousPanelId,
|
|
64
77
|
resetAllFilterCallback,
|
|
65
78
|
] );
|
|
66
79
|
|
|
@@ -84,7 +97,7 @@ export function useToolsPanelItem(
|
|
|
84
97
|
// Determine if the panel item's corresponding menu is being toggled and
|
|
85
98
|
// trigger appropriate callback if it is.
|
|
86
99
|
useEffect( () => {
|
|
87
|
-
if ( isResetting ||
|
|
100
|
+
if ( isResetting || ! hasMatchingPanel ) {
|
|
88
101
|
return;
|
|
89
102
|
}
|
|
90
103
|
|
|
@@ -96,11 +109,10 @@ export function useToolsPanelItem(
|
|
|
96
109
|
onDeselect?.();
|
|
97
110
|
}
|
|
98
111
|
}, [
|
|
99
|
-
|
|
112
|
+
hasMatchingPanel,
|
|
100
113
|
isMenuItemChecked,
|
|
101
114
|
isResetting,
|
|
102
115
|
isValueSet,
|
|
103
|
-
panelId,
|
|
104
116
|
wasMenuItemChecked,
|
|
105
117
|
] );
|
|
106
118
|
|