@wordpress/edit-widgets 5.27.1 → 5.28.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/blocks/widget-area/edit/use-is-dragging-within.js +1 -2
  3. package/build/blocks/widget-area/edit/use-is-dragging-within.js.map +1 -1
  4. package/build/blocks/widget-area/index.js +2 -4
  5. package/build/blocks/widget-area/index.js.map +1 -1
  6. package/build/components/header/document-tools/index.js +1 -2
  7. package/build/components/header/document-tools/index.js.map +1 -1
  8. package/build/components/header/index.js +1 -2
  9. package/build/components/header/index.js.map +1 -1
  10. package/build/components/header/undo-redo/redo.js +1 -2
  11. package/build/components/header/undo-redo/redo.js.map +1 -1
  12. package/build/components/header/undo-redo/undo.js +1 -2
  13. package/build/components/header/undo-redo/undo.js.map +1 -1
  14. package/build/components/keyboard-shortcut-help-modal/config.js +1 -2
  15. package/build/components/keyboard-shortcut-help-modal/config.js.map +1 -1
  16. package/build/components/keyboard-shortcut-help-modal/dynamic-shortcut.js +1 -2
  17. package/build/components/keyboard-shortcut-help-modal/dynamic-shortcut.js.map +1 -1
  18. package/build/components/keyboard-shortcut-help-modal/index.js +0 -1
  19. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  20. package/build/components/keyboard-shortcut-help-modal/shortcut.js +1 -2
  21. package/build/components/keyboard-shortcut-help-modal/shortcut.js.map +1 -1
  22. package/build/components/keyboard-shortcuts/index.js +1 -2
  23. package/build/components/keyboard-shortcuts/index.js.map +1 -1
  24. package/build/components/layout/index.js +1 -2
  25. package/build/components/layout/index.js.map +1 -1
  26. package/build/components/layout/interface.js +1 -2
  27. package/build/components/layout/interface.js.map +1 -1
  28. package/build/components/more-menu/tools-more-menu-group.js +1 -2
  29. package/build/components/more-menu/tools-more-menu-group.js.map +1 -1
  30. package/build/components/notices/index.js +4 -3
  31. package/build/components/notices/index.js.map +1 -1
  32. package/build/components/save-button/index.js +4 -5
  33. package/build/components/save-button/index.js.map +1 -1
  34. package/build/components/sidebar/index.js +89 -58
  35. package/build/components/sidebar/index.js.map +1 -1
  36. package/build/constants.js +2 -4
  37. package/build/constants.js.map +1 -1
  38. package/build/hooks/use-last-selected-widget-area.js +1 -2
  39. package/build/hooks/use-last-selected-widget-area.js.map +1 -1
  40. package/build/hooks/use-widget-library-insertion-point.js +1 -2
  41. package/build/hooks/use-widget-library-insertion-point.js.map +1 -1
  42. package/build/index.js +3 -4
  43. package/build/index.js.map +1 -1
  44. package/build/store/constants.js +1 -2
  45. package/build/store/constants.js.map +1 -1
  46. package/build/store/index.js +3 -4
  47. package/build/store/index.js.map +1 -1
  48. package/build/store/reducer.js +1 -2
  49. package/build/store/reducer.js.map +1 -1
  50. package/build/store/selectors.js +9 -19
  51. package/build/store/selectors.js.map +1 -1
  52. package/build/store/utils.js +3 -6
  53. package/build/store/utils.js.map +1 -1
  54. package/build-module/components/keyboard-shortcut-help-modal/index.js +0 -1
  55. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  56. package/build-module/components/notices/index.js +4 -1
  57. package/build-module/components/notices/index.js.map +1 -1
  58. package/build-module/components/save-button/index.js +3 -3
  59. package/build-module/components/save-button/index.js.map +1 -1
  60. package/build-module/components/sidebar/index.js +92 -61
  61. package/build-module/components/sidebar/index.js.map +1 -1
  62. package/build-module/store/selectors.js +0 -1
  63. package/build-module/store/selectors.js.map +1 -1
  64. package/build-style/style-rtl.css +27 -86
  65. package/build-style/style.css +27 -86
  66. package/package.json +28 -28
  67. package/src/components/header/style.scss +39 -3
  68. package/src/components/notices/index.js +6 -3
  69. package/src/components/save-button/index.js +4 -3
  70. package/src/components/sidebar/index.js +138 -101
  71. package/src/components/sidebar/style.scss +0 -94
@@ -1,13 +1,13 @@
1
- /**
2
- * External dependencies
3
- */
4
- import classnames from 'classnames';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
- import { useEffect, Platform } from '@wordpress/element';
10
- import { isRTL, __, sprintf } from '@wordpress/i18n';
4
+ import {
5
+ useEffect,
6
+ Platform,
7
+ useContext,
8
+ useCallback,
9
+ } from '@wordpress/element';
10
+ import { isRTL, __ } from '@wordpress/i18n';
11
11
  import {
12
12
  ComplementaryArea,
13
13
  store as interfaceStore,
@@ -18,7 +18,7 @@ import {
18
18
  } from '@wordpress/block-editor';
19
19
 
20
20
  import { drawerLeft, drawerRight } from '@wordpress/icons';
21
- import { Button } from '@wordpress/components';
21
+ import { privateApis as componentsPrivateApis } from '@wordpress/components';
22
22
  import { useSelect, useDispatch } from '@wordpress/data';
23
23
 
24
24
  const SIDEBAR_ACTIVE_BY_DEFAULT = Platform.select( {
@@ -37,32 +37,112 @@ const WIDGET_AREAS_IDENTIFIER = 'edit-widgets/block-areas';
37
37
  */
38
38
  import WidgetAreas from './widget-areas';
39
39
  import { store as editWidgetsStore } from '../../store';
40
+ import { unlock } from '../../lock-unlock';
41
+
42
+ const { Tabs } = unlock( componentsPrivateApis );
40
43
 
41
- function ComplementaryAreaTab( { identifier, label, isActive } ) {
44
+ function SidebarHeader( { selectedWidgetAreaBlock } ) {
45
+ return (
46
+ <Tabs.TabList>
47
+ <Tabs.Tab tabId={ WIDGET_AREAS_IDENTIFIER }>
48
+ { selectedWidgetAreaBlock
49
+ ? selectedWidgetAreaBlock.attributes.name
50
+ : __( 'Widget Areas' ) }
51
+ </Tabs.Tab>
52
+ <Tabs.Tab tabId={ BLOCK_INSPECTOR_IDENTIFIER }>
53
+ { __( 'Block' ) }
54
+ </Tabs.Tab>
55
+ </Tabs.TabList>
56
+ );
57
+ }
58
+
59
+ function SidebarContent( {
60
+ hasSelectedNonAreaBlock,
61
+ currentArea,
62
+ isGeneralSidebarOpen,
63
+ selectedWidgetAreaBlock,
64
+ } ) {
42
65
  const { enableComplementaryArea } = useDispatch( interfaceStore );
66
+
67
+ useEffect( () => {
68
+ if (
69
+ hasSelectedNonAreaBlock &&
70
+ currentArea === WIDGET_AREAS_IDENTIFIER &&
71
+ isGeneralSidebarOpen
72
+ ) {
73
+ enableComplementaryArea(
74
+ 'core/edit-widgets',
75
+ BLOCK_INSPECTOR_IDENTIFIER
76
+ );
77
+ }
78
+ if (
79
+ ! hasSelectedNonAreaBlock &&
80
+ currentArea === BLOCK_INSPECTOR_IDENTIFIER &&
81
+ isGeneralSidebarOpen
82
+ ) {
83
+ enableComplementaryArea(
84
+ 'core/edit-widgets',
85
+ WIDGET_AREAS_IDENTIFIER
86
+ );
87
+ }
88
+ // We're intentionally leaving `currentArea` and `isGeneralSidebarOpen`
89
+ // out of the dep array because we want this effect to run based on
90
+ // block selection changes, not sidebar state changes.
91
+ // eslint-disable-next-line react-hooks/exhaustive-deps
92
+ }, [ hasSelectedNonAreaBlock, enableComplementaryArea ] );
93
+
94
+ const tabsContextValue = useContext( Tabs.Context );
95
+
43
96
  return (
44
- <Button
45
- onClick={ () =>
46
- enableComplementaryArea( editWidgetsStore.name, identifier )
47
- }
48
- className={ classnames( 'edit-widgets-sidebar__panel-tab', {
49
- 'is-active': isActive,
50
- } ) }
51
- aria-label={
52
- isActive
53
- ? // translators: %s: sidebar label e.g: "Widget Areas".
54
- sprintf( __( '%s (selected)' ), label )
55
- : label
97
+ <ComplementaryArea
98
+ className="edit-widgets-sidebar"
99
+ header={
100
+ <Tabs.Context.Provider value={ tabsContextValue }>
101
+ <SidebarHeader
102
+ selectedWidgetAreaBlock={ selectedWidgetAreaBlock }
103
+ />
104
+ </Tabs.Context.Provider>
56
105
  }
57
- data-label={ label }
106
+ headerClassName="edit-widgets-sidebar__panel-tabs"
107
+ /* translators: button label text should, if possible, be under 16 characters. */
108
+ title={ __( 'Settings' ) }
109
+ closeLabel={ __( 'Close Settings' ) }
110
+ scope="core/edit-widgets"
111
+ identifier={ currentArea }
112
+ icon={ isRTL() ? drawerLeft : drawerRight }
113
+ isActiveByDefault={ SIDEBAR_ACTIVE_BY_DEFAULT }
58
114
  >
59
- { label }
60
- </Button>
115
+ <Tabs.Context.Provider value={ tabsContextValue }>
116
+ <Tabs.TabPanel
117
+ tabId={ WIDGET_AREAS_IDENTIFIER }
118
+ focusable={ false }
119
+ >
120
+ <WidgetAreas
121
+ selectedWidgetAreaId={
122
+ selectedWidgetAreaBlock?.attributes.id
123
+ }
124
+ />
125
+ </Tabs.TabPanel>
126
+ <Tabs.TabPanel
127
+ tabId={ BLOCK_INSPECTOR_IDENTIFIER }
128
+ focusable={ false }
129
+ >
130
+ { hasSelectedNonAreaBlock ? (
131
+ <BlockInspector />
132
+ ) : (
133
+ // Pretend that Widget Areas are part of the UI by not
134
+ // showing the Block Inspector when one is selected.
135
+ <span className="block-editor-block-inspector__no-blocks">
136
+ { __( 'No block selected.' ) }
137
+ </span>
138
+ ) }
139
+ </Tabs.TabPanel>
140
+ </Tabs.Context.Provider>
141
+ </ComplementaryArea>
61
142
  );
62
143
  }
63
144
 
64
145
  export default function Sidebar() {
65
- const { enableComplementaryArea } = useDispatch( interfaceStore );
66
146
  const {
67
147
  currentArea,
68
148
  hasSelectedNonAreaBlock,
@@ -110,84 +190,41 @@ export default function Sidebar() {
110
190
  };
111
191
  }, [] );
112
192
 
113
- // currentArea, and isGeneralSidebarOpen are intentionally left out from the dependencies,
114
- // because we want to run the effect when a block is selected/unselected and not when the sidebar state changes.
115
- useEffect( () => {
116
- if (
117
- hasSelectedNonAreaBlock &&
118
- currentArea === WIDGET_AREAS_IDENTIFIER &&
119
- isGeneralSidebarOpen
120
- ) {
121
- enableComplementaryArea(
122
- 'core/edit-widgets',
123
- BLOCK_INSPECTOR_IDENTIFIER
124
- );
125
- }
126
- if (
127
- ! hasSelectedNonAreaBlock &&
128
- currentArea === BLOCK_INSPECTOR_IDENTIFIER &&
129
- isGeneralSidebarOpen
130
- ) {
131
- enableComplementaryArea(
132
- 'core/edit-widgets',
133
- WIDGET_AREAS_IDENTIFIER
134
- );
135
- }
136
- }, [ hasSelectedNonAreaBlock, enableComplementaryArea ] );
193
+ const { enableComplementaryArea } = useDispatch( interfaceStore );
137
194
 
138
- return (
139
- <ComplementaryArea
140
- className="edit-widgets-sidebar"
141
- header={
142
- <ul>
143
- <li>
144
- <ComplementaryAreaTab
145
- identifier={ WIDGET_AREAS_IDENTIFIER }
146
- label={
147
- selectedWidgetAreaBlock
148
- ? selectedWidgetAreaBlock.attributes.name
149
- : __( 'Widget Areas' )
150
- }
151
- isActive={ currentArea === WIDGET_AREAS_IDENTIFIER }
152
- />
153
- </li>
154
- <li>
155
- <ComplementaryAreaTab
156
- identifier={ BLOCK_INSPECTOR_IDENTIFIER }
157
- label={ __( 'Block' ) }
158
- isActive={
159
- currentArea === BLOCK_INSPECTOR_IDENTIFIER
160
- }
161
- />
162
- </li>
163
- </ul>
195
+ // `newSelectedTabId` could technically be falsey if no tab is selected (i.e.
196
+ // the initial render) or when we don't want a tab displayed (i.e. the
197
+ // sidebar is closed). These cases should both be covered by the `!!` check
198
+ // below, so we shouldn't need any additional falsey handling.
199
+ const onTabSelect = useCallback(
200
+ ( newSelectedTabId ) => {
201
+ if ( !! newSelectedTabId ) {
202
+ enableComplementaryArea(
203
+ editWidgetsStore.name,
204
+ newSelectedTabId
205
+ );
164
206
  }
165
- headerClassName="edit-widgets-sidebar__panel-tabs"
166
- /* translators: button label text should, if possible, be under 16 characters. */
167
- title={ __( 'Settings' ) }
168
- closeLabel={ __( 'Close Settings' ) }
169
- scope="core/edit-widgets"
170
- identifier={ currentArea }
171
- icon={ isRTL() ? drawerLeft : drawerRight }
172
- isActiveByDefault={ SIDEBAR_ACTIVE_BY_DEFAULT }
207
+ },
208
+ [ enableComplementaryArea ]
209
+ );
210
+
211
+ return (
212
+ <Tabs
213
+ // Due to how this component is controlled (via a value from the
214
+ // `interfaceStore`), when the sidebar closes the currently selected
215
+ // tab can't be found. This causes the component to continuously reset
216
+ // the selection to `null` in an infinite loop. Proactively setting
217
+ // the selected tab to `null` avoids that.
218
+ selectedTabId={ isGeneralSidebarOpen ? currentArea : null }
219
+ onSelect={ onTabSelect }
220
+ selectOnMove={ false }
173
221
  >
174
- { currentArea === WIDGET_AREAS_IDENTIFIER && (
175
- <WidgetAreas
176
- selectedWidgetAreaId={
177
- selectedWidgetAreaBlock?.attributes.id
178
- }
179
- />
180
- ) }
181
- { currentArea === BLOCK_INSPECTOR_IDENTIFIER &&
182
- ( hasSelectedNonAreaBlock ? (
183
- <BlockInspector />
184
- ) : (
185
- // Pretend that Widget Areas are part of the UI by not
186
- // showing the Block Inspector when one is selected.
187
- <span className="block-editor-block-inspector__no-blocks">
188
- { __( 'No block selected.' ) }
189
- </span>
190
- ) ) }
191
- </ComplementaryArea>
222
+ <SidebarContent
223
+ hasSelectedNonAreaBlock={ hasSelectedNonAreaBlock }
224
+ currentArea={ currentArea }
225
+ isGeneralSidebarOpen={ isGeneralSidebarOpen }
226
+ selectedWidgetAreaBlock={ selectedWidgetAreaBlock }
227
+ />
228
+ </Tabs>
192
229
  );
193
230
  }
@@ -1,99 +1,5 @@
1
1
  .components-panel__header.edit-widgets-sidebar__panel-tabs {
2
- justify-content: flex-start;
3
2
  padding-left: 0;
4
- padding-right: $grid-unit-05;
5
- border-top: 0;
6
- margin-top: 0;
7
-
8
- ul {
9
- display: flex;
10
- }
11
- li {
12
- margin: 0;
13
- }
14
- .components-button.has-icon {
15
- display: none;
16
- margin-left: auto;
17
-
18
- @include break-medium() {
19
- display: flex;
20
- }
21
- }
22
- }
23
-
24
- // This tab style CSS is duplicated verbatim in
25
- // /packages/components/src/tab-panel/style.scss
26
- .components-button.edit-widgets-sidebar__panel-tab {
27
- position: relative;
28
- border-radius: 0;
29
- height: $grid-unit-60;
30
- background: transparent;
31
- border: none;
32
- box-shadow: none;
33
- cursor: pointer;
34
- padding: 3px $grid-unit-20; // Use padding to offset the is-active border, this benefits Windows High Contrast mode
35
- margin-left: 0;
36
- font-weight: 500;
37
-
38
- &:focus:not(:disabled) {
39
- position: relative;
40
- box-shadow: none;
41
- outline: none;
42
- }
43
-
44
- // Tab indicator
45
- &::after {
46
- content: "";
47
- position: absolute;
48
- right: 0;
49
- bottom: 0;
50
- left: 0;
51
- pointer-events: none;
52
-
53
- // Draw the indicator.
54
- background: var(--wp-admin-theme-color);
55
- height: calc(0 * var(--wp-admin-border-width-focus));
56
- border-radius: 0;
57
-
58
- // Animation
59
- transition: all 0.1s linear;
60
- @include reduce-motion("transition");
61
- }
62
-
63
- // Active.
64
- &.is-active::after {
65
- height: calc(1 * var(--wp-admin-border-width-focus));
66
-
67
- // Windows high contrast mode.
68
- outline: 2px solid transparent;
69
- outline-offset: -1px;
70
- }
71
-
72
- // Focus.
73
- &::before {
74
- content: "";
75
- position: absolute;
76
- top: $grid-unit-15;
77
- right: $grid-unit-15;
78
- bottom: $grid-unit-15;
79
- left: $grid-unit-15;
80
- pointer-events: none;
81
-
82
- // Draw the indicator.
83
- box-shadow: 0 0 0 0 transparent;
84
- border-radius: $radius-block-ui;
85
-
86
- // Animation
87
- transition: all 0.1s linear;
88
- @include reduce-motion("transition");
89
- }
90
-
91
- &:focus-visible::before {
92
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
93
-
94
- // Windows high contrast mode.
95
- outline: 2px solid transparent;
96
- }
97
3
  }
98
4
 
99
5