@wordpress/edit-site 4.17.0 → 4.19.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 (141) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/add-new-template/add-custom-template-modal.js +3 -1
  3. package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
  4. package/build/components/app/index.js +8 -3
  5. package/build/components/app/index.js.map +1 -1
  6. package/build/components/block-editor/resizable-editor.js +9 -47
  7. package/build/components/block-editor/resizable-editor.js.map +1 -1
  8. package/build/components/editor/index.js +9 -13
  9. package/build/components/editor/index.js.map +1 -1
  10. package/build/components/global-styles/border-panel.js +2 -1
  11. package/build/components/global-styles/border-panel.js.map +1 -1
  12. package/build/components/global-styles/dimensions-panel.js +46 -2
  13. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  14. package/build/components/global-styles/global-styles-provider.js +6 -5
  15. package/build/components/global-styles/global-styles-provider.js.map +1 -1
  16. package/build/components/global-styles/hooks.js +32 -0
  17. package/build/components/global-styles/hooks.js.map +1 -1
  18. package/build/components/global-styles/palette.js +8 -1
  19. package/build/components/global-styles/palette.js.map +1 -1
  20. package/build/components/global-styles/typography-panel.js +53 -16
  21. package/build/components/global-styles/typography-panel.js.map +1 -1
  22. package/build/components/global-styles/use-global-styles-output.js +43 -8
  23. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  24. package/build/components/header-edit-mode/document-actions/index.js +3 -1
  25. package/build/components/header-edit-mode/document-actions/index.js.map +1 -1
  26. package/build/components/header-edit-mode/index.js +15 -13
  27. package/build/components/header-edit-mode/index.js.map +1 -1
  28. package/build/components/keyboard-shortcut-help-modal/shortcut.js +1 -7
  29. package/build/components/keyboard-shortcut-help-modal/shortcut.js.map +1 -1
  30. package/build/components/keyboard-shortcuts/index.js +8 -5
  31. package/build/components/keyboard-shortcuts/index.js.map +1 -1
  32. package/build/components/list/table.js +1 -1
  33. package/build/components/list/table.js.map +1 -1
  34. package/build/components/list/use-register-shortcuts.js +3 -0
  35. package/build/components/list/use-register-shortcuts.js.map +1 -1
  36. package/build/components/navigation-sidebar/navigation-panel/index.js +9 -8
  37. package/build/components/navigation-sidebar/navigation-panel/index.js.map +1 -1
  38. package/build/components/save-button/index.js +36 -14
  39. package/build/components/save-button/index.js.map +1 -1
  40. package/build/components/sidebar-edit-mode/template-card/index.js +4 -2
  41. package/build/components/sidebar-edit-mode/template-card/index.js.map +1 -1
  42. package/build/components/template-details/index.js +4 -2
  43. package/build/components/template-details/index.js.map +1 -1
  44. package/build/index.js +5 -10
  45. package/build/index.js.map +1 -1
  46. package/build/store/actions.js +15 -0
  47. package/build/store/actions.js.map +1 -1
  48. package/build/store/reducer.js +28 -1
  49. package/build/store/reducer.js.map +1 -1
  50. package/build/store/selectors.js +13 -0
  51. package/build/store/selectors.js.map +1 -1
  52. package/build-module/components/add-new-template/add-custom-template-modal.js +2 -1
  53. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
  54. package/build-module/components/app/index.js +8 -3
  55. package/build-module/components/app/index.js.map +1 -1
  56. package/build-module/components/block-editor/resizable-editor.js +11 -49
  57. package/build-module/components/block-editor/resizable-editor.js.map +1 -1
  58. package/build-module/components/editor/index.js +10 -14
  59. package/build-module/components/editor/index.js.map +1 -1
  60. package/build-module/components/global-styles/border-panel.js +2 -1
  61. package/build-module/components/global-styles/border-panel.js.map +1 -1
  62. package/build-module/components/global-styles/dimensions-panel.js +46 -2
  63. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  64. package/build-module/components/global-styles/global-styles-provider.js +7 -6
  65. package/build-module/components/global-styles/global-styles-provider.js.map +1 -1
  66. package/build-module/components/global-styles/hooks.js +27 -1
  67. package/build-module/components/global-styles/hooks.js.map +1 -1
  68. package/build-module/components/global-styles/palette.js +9 -3
  69. package/build-module/components/global-styles/palette.js.map +1 -1
  70. package/build-module/components/global-styles/typography-panel.js +54 -16
  71. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  72. package/build-module/components/global-styles/use-global-styles-output.js +44 -9
  73. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  74. package/build-module/components/header-edit-mode/document-actions/index.js +2 -1
  75. package/build-module/components/header-edit-mode/document-actions/index.js.map +1 -1
  76. package/build-module/components/header-edit-mode/index.js +14 -13
  77. package/build-module/components/header-edit-mode/index.js.map +1 -1
  78. package/build-module/components/keyboard-shortcut-help-modal/shortcut.js +1 -6
  79. package/build-module/components/keyboard-shortcut-help-modal/shortcut.js.map +1 -1
  80. package/build-module/components/keyboard-shortcuts/index.js +8 -5
  81. package/build-module/components/keyboard-shortcuts/index.js.map +1 -1
  82. package/build-module/components/list/table.js +1 -1
  83. package/build-module/components/list/table.js.map +1 -1
  84. package/build-module/components/list/use-register-shortcuts.js +3 -0
  85. package/build-module/components/list/use-register-shortcuts.js.map +1 -1
  86. package/build-module/components/navigation-sidebar/navigation-panel/index.js +9 -7
  87. package/build-module/components/navigation-sidebar/navigation-panel/index.js.map +1 -1
  88. package/build-module/components/save-button/index.js +39 -16
  89. package/build-module/components/save-button/index.js.map +1 -1
  90. package/build-module/components/sidebar-edit-mode/template-card/index.js +3 -2
  91. package/build-module/components/sidebar-edit-mode/template-card/index.js.map +1 -1
  92. package/build-module/components/template-details/index.js +3 -2
  93. package/build-module/components/template-details/index.js.map +1 -1
  94. package/build-module/index.js +5 -3
  95. package/build-module/index.js.map +1 -1
  96. package/build-module/store/actions.js +13 -0
  97. package/build-module/store/actions.js.map +1 -1
  98. package/build-module/store/reducer.js +26 -1
  99. package/build-module/store/reducer.js.map +1 -1
  100. package/build-module/store/selectors.js +11 -0
  101. package/build-module/store/selectors.js.map +1 -1
  102. package/build-style/style-rtl.css +17 -15
  103. package/build-style/style.css +17 -15
  104. package/package.json +30 -29
  105. package/src/components/add-new-template/add-custom-template-modal.js +5 -1
  106. package/src/components/app/index.js +11 -2
  107. package/src/components/block-editor/resizable-editor.js +10 -55
  108. package/src/components/block-editor/style.scss +1 -0
  109. package/src/components/editor/index.js +16 -25
  110. package/src/components/editor/style.scss +1 -7
  111. package/src/components/global-styles/border-panel.js +1 -0
  112. package/src/components/global-styles/dimensions-panel.js +59 -1
  113. package/src/components/global-styles/global-styles-provider.js +5 -6
  114. package/src/components/global-styles/hooks.js +36 -0
  115. package/src/components/global-styles/palette.js +15 -1
  116. package/src/components/global-styles/style.scss +1 -0
  117. package/src/components/global-styles/test/typography-utils.js +82 -98
  118. package/src/components/global-styles/test/use-global-styles-output.js +6 -6
  119. package/src/components/global-styles/typography-panel.js +58 -15
  120. package/src/components/global-styles/use-global-styles-output.js +47 -10
  121. package/src/components/header-edit-mode/document-actions/index.js +2 -1
  122. package/src/components/header-edit-mode/index.js +10 -13
  123. package/src/components/keyboard-shortcut-help-modal/shortcut.js +15 -18
  124. package/src/components/keyboard-shortcuts/index.js +7 -2
  125. package/src/components/list/table.js +1 -1
  126. package/src/components/list/use-register-shortcuts.js +4 -0
  127. package/src/components/navigation-sidebar/navigation-panel/index.js +30 -24
  128. package/src/components/navigation-sidebar/navigation-panel/style.scss +0 -7
  129. package/src/components/navigation-sidebar/navigation-toggle/test/index.js +24 -30
  130. package/src/components/save-button/index.js +31 -15
  131. package/src/components/sidebar-edit-mode/template-card/index.js +3 -2
  132. package/src/components/template-details/index.js +3 -2
  133. package/src/index.js +10 -3
  134. package/src/store/actions.js +13 -0
  135. package/src/store/reducer.js +19 -0
  136. package/src/store/selectors.js +11 -0
  137. package/build/components/main-dashboard-button/index.js +0 -41
  138. package/build/components/main-dashboard-button/index.js.map +0 -1
  139. package/build-module/components/main-dashboard-button/index.js +0 -32
  140. package/build-module/components/main-dashboard-button/index.js.map +0 -1
  141. package/src/components/main-dashboard-button/index.js +0 -28
@@ -8,6 +8,7 @@ import classnames from 'classnames';
8
8
  */
9
9
  import { useCallback, useRef } from '@wordpress/element';
10
10
  import { useViewportMatch } from '@wordpress/compose';
11
+ import { store as coreStore } from '@wordpress/core-data';
11
12
  import {
12
13
  ToolSelector,
13
14
  __experimentalPreviewOptions as PreviewOptions,
@@ -41,11 +42,7 @@ const preventDefault = ( event ) => {
41
42
  event.preventDefault();
42
43
  };
43
44
 
44
- export default function Header( {
45
- openEntitiesSavedStates,
46
- isEntitiesSavedStatesOpen,
47
- showIconLabels,
48
- } ) {
45
+ export default function Header( { showIconLabels } ) {
49
46
  const inserterButton = useRef();
50
47
  const {
51
48
  deviceType,
@@ -54,8 +51,8 @@ export default function Header( {
54
51
  isListViewOpen,
55
52
  listViewShortcut,
56
53
  isVisualMode,
57
- settings,
58
54
  blockEditorMode,
55
+ homeUrl,
59
56
  } = useSelect( ( select ) => {
60
57
  const {
61
58
  __experimentalGetPreviewDeviceType,
@@ -63,13 +60,16 @@ export default function Header( {
63
60
  isInserterOpened,
64
61
  isListViewOpened,
65
62
  getEditorMode,
66
- getSettings,
67
63
  } = select( editSiteStore );
68
64
  const { getShortcutRepresentation } = select( keyboardShortcutsStore );
69
65
  const { __unstableGetEditorMode } = select( blockEditorStore );
70
66
 
71
67
  const postType = getEditedPostType();
72
68
 
69
+ const {
70
+ getUnstableBase, // Site index.
71
+ } = select( coreStore );
72
+
73
73
  return {
74
74
  deviceType: __experimentalGetPreviewDeviceType(),
75
75
  templateType: postType,
@@ -79,8 +79,8 @@ export default function Header( {
79
79
  'core/edit-site/toggle-list-view'
80
80
  ),
81
81
  isVisualMode: getEditorMode() === 'visual',
82
- settings: getSettings(),
83
82
  blockEditorMode: __unstableGetEditorMode(),
83
+ homeUrl: getUnstableBase()?.home,
84
84
  };
85
85
  }, [] );
86
86
 
@@ -222,7 +222,7 @@ export default function Header( {
222
222
  >
223
223
  <MenuGroup>
224
224
  <MenuItem
225
- href={ settings?.siteUrl }
225
+ href={ homeUrl }
226
226
  target="_blank"
227
227
  icon={ external }
228
228
  >
@@ -238,10 +238,7 @@ export default function Header( {
238
238
  </PreviewOptions>
239
239
  </div>
240
240
  ) }
241
- <SaveButton
242
- openEntitiesSavedStates={ openEntitiesSavedStates }
243
- isEntitiesSavedStatesOpen={ isEntitiesSavedStatesOpen }
244
- />
241
+ <SaveButton />
245
242
  <PinnedItems.Slot scope="core/edit-site" />
246
243
  <MoreMenu showIconLabels={ showIconLabels } />
247
244
  </div>
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { castArray } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -26,20 +21,22 @@ function KeyCombination( { keyCombination, forceAriaLabel } ) {
26
21
  className="edit-site-keyboard-shortcut-help-modal__shortcut-key-combination"
27
22
  aria-label={ forceAriaLabel || ariaLabel }
28
23
  >
29
- { castArray( shortcut ).map( ( character, index ) => {
30
- if ( character === '+' ) {
31
- return <Fragment key={ index }>{ character }</Fragment>;
32
- }
24
+ { ( Array.isArray( shortcut ) ? shortcut : [ shortcut ] ).map(
25
+ ( character, index ) => {
26
+ if ( character === '+' ) {
27
+ return <Fragment key={ index }>{ character }</Fragment>;
28
+ }
33
29
 
34
- return (
35
- <kbd
36
- key={ index }
37
- className="edit-site-keyboard-shortcut-help-modal__shortcut-key"
38
- >
39
- { character }
40
- </kbd>
41
- );
42
- } ) }
30
+ return (
31
+ <kbd
32
+ key={ index }
33
+ className="edit-site-keyboard-shortcut-help-modal__shortcut-key"
34
+ >
35
+ { character }
36
+ </kbd>
37
+ );
38
+ }
39
+ ) }
43
40
  </kbd>
44
41
  );
45
42
  }
@@ -18,7 +18,7 @@ import { store as editSiteStore } from '../../store';
18
18
  import { SIDEBAR_BLOCK } from '../sidebar-edit-mode/constants';
19
19
  import { STORE_NAME } from '../../store/constants';
20
20
 
21
- function KeyboardShortcuts( { openEntitiesSavedStates } ) {
21
+ function KeyboardShortcuts() {
22
22
  const { __experimentalGetDirtyEntityRecords, isSavingEntityRecord } =
23
23
  useSelect( coreStore );
24
24
  const { getEditorMode } = useSelect( editSiteStore );
@@ -38,6 +38,7 @@ function KeyboardShortcuts( { openEntitiesSavedStates } ) {
38
38
  useDispatch( editSiteStore );
39
39
  const { enableComplementaryArea, disableComplementaryArea } =
40
40
  useDispatch( interfaceStore );
41
+ const { setIsSaveViewOpened } = useDispatch( editSiteStore );
41
42
 
42
43
  useShortcut( 'core/edit-site/save', ( event ) => {
43
44
  event.preventDefault();
@@ -49,7 +50,7 @@ function KeyboardShortcuts( { openEntitiesSavedStates } ) {
49
50
  );
50
51
 
51
52
  if ( ! isSaving && isDirty ) {
52
- openEntitiesSavedStates();
53
+ setIsSaveViewOpened( true );
53
54
  }
54
55
  } );
55
56
 
@@ -179,6 +180,10 @@ function KeyboardShortcutsRegister() {
179
180
  modifier: 'access',
180
181
  character: 'p',
181
182
  },
183
+ {
184
+ modifier: 'ctrlShift',
185
+ character: '~',
186
+ },
182
187
  ],
183
188
  } );
184
189
  registerShortcut( {
@@ -94,7 +94,7 @@ export default function Table( { templateType } ) {
94
94
  ) }
95
95
  </Link>
96
96
  </Heading>
97
- { template.description }
97
+ { decodeEntities( template.description ) }
98
98
  </td>
99
99
 
100
100
  <td className="edit-site-list-table-column" role="cell">
@@ -39,6 +39,10 @@ export default function useRegisterShortcuts() {
39
39
  modifier: 'access',
40
40
  character: 'p',
41
41
  },
42
+ {
43
+ modifier: 'ctrlShift',
44
+ character: '~',
45
+ },
42
46
  ],
43
47
  } );
44
48
  }, [] );
@@ -28,7 +28,6 @@ import {
28
28
  * Internal dependencies
29
29
  */
30
30
  import { useLink } from '../../routes/link';
31
- import MainDashboardButton from '../../main-dashboard-button';
32
31
  import { store as editSiteStore } from '../../../store';
33
32
 
34
33
  const SITE_EDITOR_KEY = 'site-editor';
@@ -39,24 +38,33 @@ function NavLink( { params, replace, ...props } ) {
39
38
  return <NavigationItem { ...linkProps } { ...props } />;
40
39
  }
41
40
 
42
- const NavigationPanel = ( { activeItem = SITE_EDITOR_KEY } ) => {
43
- const { homeTemplate, isNavigationOpen, isTemplatePartsMode, siteTitle } =
44
- useSelect( ( select ) => {
45
- const { getEntityRecord } = select( coreDataStore );
46
- const { getSettings, isNavigationOpened } = select( editSiteStore );
41
+ const NavigationPanel = ( { activeItem } ) => {
42
+ const {
43
+ homeTemplate,
44
+ isNavigationOpen,
45
+ isTemplatePartsMode,
46
+ siteTitle,
47
+ dashboardLink,
48
+ } = useSelect( ( select ) => {
49
+ const { getEntityRecord } = select( coreDataStore );
50
+ const { getSettings, isNavigationOpened } = select( editSiteStore );
47
51
 
48
- const siteData =
49
- getEntityRecord( 'root', '__unstableBase', undefined ) || {};
50
- const { supportsTemplatePartsMode, __unstableHomeTemplate } =
51
- getSettings();
52
+ const siteData =
53
+ getEntityRecord( 'root', '__unstableBase', undefined ) || {};
54
+ const {
55
+ supportsTemplatePartsMode,
56
+ __unstableHomeTemplate,
57
+ __experimentalDashboardLink,
58
+ } = getSettings();
52
59
 
53
- return {
54
- siteTitle: siteData.name,
55
- homeTemplate: __unstableHomeTemplate,
56
- isNavigationOpen: isNavigationOpened(),
57
- isTemplatePartsMode: !! supportsTemplatePartsMode,
58
- };
59
- }, [] );
60
+ return {
61
+ siteTitle: siteData.name,
62
+ homeTemplate: __unstableHomeTemplate,
63
+ dashboardLink: __experimentalDashboardLink,
64
+ isNavigationOpen: isNavigationOpened(),
65
+ isTemplatePartsMode: !! supportsTemplatePartsMode,
66
+ };
67
+ }, [] );
60
68
  const { setIsNavigationPanelOpened } = useDispatch( editSiteStore );
61
69
 
62
70
  const closeOnEscape = ( event ) => {
@@ -82,13 +90,11 @@ const NavigationPanel = ( { activeItem = SITE_EDITOR_KEY } ) => {
82
90
  </div>
83
91
  <div className="edit-site-navigation-panel__scroll-container">
84
92
  <Navigation activeItem={ activeItem }>
85
- <MainDashboardButton.Slot>
86
- <NavigationBackButton
87
- backButtonLabel={ __( 'Dashboard' ) }
88
- className="edit-site-navigation-panel__back-to-dashboard"
89
- href="index.php"
90
- />
91
- </MainDashboardButton.Slot>
93
+ <NavigationBackButton
94
+ backButtonLabel={ __( 'Dashboard' ) }
95
+ className="edit-site-navigation-panel__back-to-dashboard"
96
+ href={ dashboardLink ?? 'index.php' }
97
+ />
92
98
 
93
99
  <NavigationMenu>
94
100
  <NavigationGroup title={ __( 'Editor' ) }>
@@ -7,13 +7,6 @@
7
7
  color: $white;
8
8
  transition: width 100ms linear;
9
9
  @include reduce-motion("transition");
10
-
11
- // Footer is visible from medium so we subtract footer's height
12
- .interface-interface-skeleton.has-footer & {
13
- @include break-medium() {
14
- height: calc(100% - #{$button-size-small + $border-width});
15
- }
16
- }
17
10
  }
18
11
 
19
12
  .edit-site-navigation-panel__inner {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { render } from '@testing-library/react';
4
+ import { render, screen } from '@testing-library/react';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -15,57 +15,51 @@ import NavigationToggle from '..';
15
15
 
16
16
  jest.mock( '@wordpress/data/src/components/use-select', () => {
17
17
  // This allows us to tweak the returned value on each test.
18
- const mock = jest.fn();
19
- return mock;
18
+ return jest.fn();
20
19
  } );
21
- jest.mock( '@wordpress/data/src/components/use-dispatch', () => ( {
22
- useDispatch: () => ( { setNavigationPanelActiveMenu: jest.fn() } ),
23
- } ) );
24
-
25
- jest.mock( '@wordpress/core-data' );
26
20
 
27
21
  describe( 'NavigationToggle', () => {
28
22
  describe( 'when in full screen mode', () => {
29
23
  it( 'should display a user uploaded site icon if it exists', () => {
30
- useSelect.mockImplementation( ( cb ) => {
31
- return cb( () => ( {
32
- getCurrentTemplateNavigationPanelSubMenu: () => 'root',
24
+ useSelect.mockImplementation( ( cb ) =>
25
+ cb( () => ( {
33
26
  getEntityRecord: () => ( {
34
27
  site_icon_url: 'https://fakeUrl.com',
35
28
  } ),
36
29
  isResolving: () => false,
37
30
  isNavigationOpened: () => false,
38
- } ) );
39
- } );
40
-
41
- const { container } = render( <NavigationToggle /> );
42
- const siteIcon = container.querySelector(
43
- '.edit-site-navigation-toggle__site-icon'
31
+ } ) )
44
32
  );
45
33
 
46
- expect( siteIcon ).toBeTruthy();
34
+ const { unmount } = render( <NavigationToggle /> );
35
+
36
+ const siteIcon = screen.getByAltText( 'Site Icon' );
37
+ expect( siteIcon ).toBeVisible();
38
+
39
+ // Unmount the UI synchronously so that any async effects, like the on-mount focus
40
+ // that shows and positions a tooltip, are cancelled right away and never run.
41
+ unmount();
47
42
  } );
48
43
 
49
44
  it( 'should display a default site icon if no user uploaded site icon exists', () => {
50
- useSelect.mockImplementation( ( cb ) => {
51
- return cb( () => ( {
52
- getCurrentTemplateNavigationPanelSubMenu: () => 'root',
45
+ useSelect.mockImplementation( ( cb ) =>
46
+ cb( () => ( {
53
47
  getEntityRecord: () => ( {
54
48
  site_icon_url: '',
55
49
  } ),
56
50
  isResolving: () => false,
57
51
  isNavigationOpened: () => false,
58
- } ) );
59
- } );
60
-
61
- const { container } = render( <NavigationToggle /> );
62
- const siteIcon = container.querySelector(
63
- '.edit-site-navigation-toggle__site-icon'
52
+ } ) )
64
53
  );
65
- const defaultIcon = container.querySelector( 'svg' );
66
54
 
67
- expect( siteIcon ).toBeFalsy();
68
- expect( defaultIcon ).toBeTruthy();
55
+ const { unmount } = render( <NavigationToggle /> );
56
+
57
+ const siteIcon = screen.queryByAltText( 'Site Icon' );
58
+ expect( siteIcon ).not.toBeInTheDocument();
59
+
60
+ // Unmount the UI synchronously so that any async effects, like the on-mount focus
61
+ // that shows and positions a tooltip, are cancelled right away and never run.
62
+ unmount();
69
63
  } );
70
64
  } );
71
65
  } );
@@ -1,44 +1,60 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { some } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
- import { useSelect } from '@wordpress/data';
4
+ import { useSelect, useDispatch } from '@wordpress/data';
10
5
  import { Button } from '@wordpress/components';
11
6
  import { __ } from '@wordpress/i18n';
12
7
  import { store as coreStore } from '@wordpress/core-data';
8
+ import { displayShortcut } from '@wordpress/keycodes';
13
9
 
14
- export default function SaveButton( {
15
- openEntitiesSavedStates,
16
- isEntitiesSavedStatesOpen,
17
- } ) {
18
- const { isDirty, isSaving } = useSelect( ( select ) => {
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { store as editSiteStore } from '../../store';
14
+
15
+ export default function SaveButton() {
16
+ const { isDirty, isSaving, isSaveViewOpen } = useSelect( ( select ) => {
19
17
  const { __experimentalGetDirtyEntityRecords, isSavingEntityRecord } =
20
18
  select( coreStore );
21
19
  const dirtyEntityRecords = __experimentalGetDirtyEntityRecords();
20
+ const { isSaveViewOpened } = select( editSiteStore );
22
21
  return {
23
22
  isDirty: dirtyEntityRecords.length > 0,
24
- isSaving: some( dirtyEntityRecords, ( record ) =>
23
+ isSaving: dirtyEntityRecords.some( ( record ) =>
25
24
  isSavingEntityRecord( record.kind, record.name, record.key )
26
25
  ),
26
+ isSaveViewOpen: isSaveViewOpened(),
27
27
  };
28
28
  }, [] );
29
+ const { setIsSaveViewOpened } = useDispatch( editSiteStore );
29
30
 
30
31
  const disabled = ! isDirty || isSaving;
31
32
 
33
+ const label = __( 'Save' );
34
+
32
35
  return (
33
36
  <Button
34
37
  variant="primary"
35
38
  className="edit-site-save-button__button"
36
39
  aria-disabled={ disabled }
37
- aria-expanded={ isEntitiesSavedStatesOpen }
40
+ aria-expanded={ isSaveViewOpen }
38
41
  isBusy={ isSaving }
39
- onClick={ disabled ? undefined : openEntitiesSavedStates }
42
+ onClick={ disabled ? undefined : () => setIsSaveViewOpened( true ) }
43
+ label={ label }
44
+ /*
45
+ * We want the tooltip to show the keyboard shortcut only when the
46
+ * button does something, i.e. when it's not disabled.
47
+ */
48
+ shortcut={ disabled ? undefined : displayShortcut.primary( 's' ) }
49
+ /*
50
+ * Displaying the keyboard shortcut conditionally makes the tooltip
51
+ * itself show conditionally. This would trigger a full-rerendering
52
+ * of the button that we want to avoid. By setting `showTooltip`,
53
+ & the tooltip is always rendered even when there's no keyboard shortcut.
54
+ */
55
+ showTooltip
40
56
  >
41
- { __( 'Save' ) }
57
+ { label }
42
58
  </Button>
43
59
  );
44
60
  }
@@ -5,6 +5,7 @@ import { useSelect } from '@wordpress/data';
5
5
  import { Icon } from '@wordpress/components';
6
6
  import { store as editorStore } from '@wordpress/editor';
7
7
  import { store as coreStore } from '@wordpress/core-data';
8
+ import { decodeEntities } from '@wordpress/html-entities';
8
9
 
9
10
  /**
10
11
  * Internal dependencies
@@ -42,12 +43,12 @@ export default function TemplateCard() {
42
43
  <div className="edit-site-template-card__content">
43
44
  <div className="edit-site-template-card__header">
44
45
  <h2 className="edit-site-template-card__title">
45
- { title }
46
+ { decodeEntities( title ) }
46
47
  </h2>
47
48
  <TemplateActions template={ template } />
48
49
  </div>
49
50
  <div className="edit-site-template-card__description">
50
- { description }
51
+ { decodeEntities( description ) }
51
52
  </div>
52
53
  <TemplateAreas />
53
54
  </div>
@@ -11,6 +11,7 @@ import {
11
11
  } from '@wordpress/components';
12
12
  import { useDispatch, useSelect } from '@wordpress/data';
13
13
  import { store as editorStore } from '@wordpress/editor';
14
+ import { decodeEntities } from '@wordpress/html-entities';
14
15
 
15
16
  /**
16
17
  * Internal dependencies
@@ -65,7 +66,7 @@ export default function TemplateDetails( { template, onClose } ) {
65
66
  className="edit-site-template-details__title"
66
67
  as="p"
67
68
  >
68
- { title }
69
+ { decodeEntities( title ) }
69
70
  </Text>
70
71
  ) }
71
72
 
@@ -75,7 +76,7 @@ export default function TemplateDetails( { template, onClose } ) {
75
76
  className="edit-site-template-details__description"
76
77
  as="p"
77
78
  >
78
- { description }
79
+ { decodeEntities( description ) }
79
80
  </Text>
80
81
  ) }
81
82
  </VStack>
package/src/index.js CHANGED
@@ -45,7 +45,9 @@ export function reinitializeEditor( target, settings ) {
45
45
  message={ __(
46
46
  'The editor is unable to find a block template for the homepage.'
47
47
  ) }
48
- dashboardLink="index.php"
48
+ dashboardLink={
49
+ settings.__experimentalDashboardLink ?? 'index.php'
50
+ }
49
51
  />,
50
52
  target
51
53
  );
@@ -132,7 +134,13 @@ export function reinitializeEditor( target, settings ) {
132
134
  window.addEventListener( 'dragover', ( e ) => e.preventDefault(), false );
133
135
  window.addEventListener( 'drop', ( e ) => e.preventDefault(), false );
134
136
 
135
- render( <EditSiteApp reboot={ reboot } />, target );
137
+ render(
138
+ <EditSiteApp
139
+ reboot={ reboot }
140
+ homeTemplate={ settings.__unstableHomeTemplate }
141
+ />,
142
+ target
143
+ );
136
144
  }
137
145
 
138
146
  /**
@@ -159,7 +167,6 @@ export function initializeEditor( id, settings ) {
159
167
  reinitializeEditor( target, settings );
160
168
  }
161
169
 
162
- export { default as __experimentalMainDashboardButton } from './components/main-dashboard-button';
163
170
  export { default as __experimentalNavigationToggle } from './components/navigation-sidebar/navigation-toggle';
164
171
  export { default as PluginSidebar } from './components/sidebar-edit-mode/plugin-sidebar';
165
172
  export { default as PluginSidebarMoreMenuItem } from './components/header-edit-mode/plugin-sidebar-more-menu-item';
@@ -320,6 +320,19 @@ export function setIsListViewOpened( isOpen ) {
320
320
  };
321
321
  }
322
322
 
323
+ /**
324
+ * Sets whether the save view panel should be open.
325
+ *
326
+ * @param {boolean} isOpen If true, opens the save view. If false, closes it.
327
+ * It does not toggle the state, but sets it directly.
328
+ */
329
+ export function setIsSaveViewOpened( isOpen ) {
330
+ return {
331
+ type: 'SET_IS_SAVE_VIEW_OPENED',
332
+ isOpen,
333
+ };
334
+ }
335
+
323
336
  /**
324
337
  * Reverts a template to its original theme-provided file.
325
338
  *
@@ -183,6 +183,24 @@ export function listViewPanel( state = false, action ) {
183
183
  return state;
184
184
  }
185
185
 
186
+ /**
187
+ * Reducer to set the save view panel open or closed.
188
+ *
189
+ * @param {Object} state Current state.
190
+ * @param {Object} action Dispatched action.
191
+ */
192
+ export function saveViewPanel( state = false, action ) {
193
+ switch ( action.type ) {
194
+ case 'OPEN_NAVIGATION_PANEL_TO_MENU':
195
+ return false;
196
+ case 'SET_IS_NAVIGATION_PANEL_OPENED':
197
+ return action.isOpen ? false : state;
198
+ case 'SET_IS_SAVE_VIEW_OPENED':
199
+ return action.isOpen;
200
+ }
201
+ return state;
202
+ }
203
+
186
204
  export default combineReducers( {
187
205
  deviceType,
188
206
  settings,
@@ -191,4 +209,5 @@ export default combineReducers( {
191
209
  navigationPanel,
192
210
  blockInserterPanel,
193
211
  listViewPanel,
212
+ saveViewPanel,
194
213
  } );
@@ -320,6 +320,17 @@ export function isListViewOpened( state ) {
320
320
  return state.listViewPanel;
321
321
  }
322
322
 
323
+ /**
324
+ * Returns the current opened/closed state of the save panel.
325
+ *
326
+ * @param {Object} state Global application state.
327
+ *
328
+ * @return {boolean} True if the save panel should be open; false if closed.
329
+ */
330
+ export function isSaveViewOpened( state ) {
331
+ return state.saveViewPanel;
332
+ }
333
+
323
334
  /**
324
335
  * Returns the template parts and their blocks for the current edited template.
325
336
  *
@@ -1,41 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _element = require("@wordpress/element");
9
-
10
- var _components = require("@wordpress/components");
11
-
12
- /**
13
- * WordPress dependencies
14
- */
15
- const slotName = '__experimentalMainDashboardButton';
16
- const {
17
- Fill,
18
- Slot: MainDashboardButtonSlot
19
- } = (0, _components.createSlotFill)(slotName);
20
- const MainDashboardButton = Fill;
21
-
22
- const Slot = _ref => {
23
- let {
24
- children
25
- } = _ref;
26
- const fills = (0, _components.__experimentalUseSlotFills)(slotName);
27
- const hasFills = Boolean(fills && fills.length);
28
-
29
- if (!hasFills) {
30
- return children;
31
- }
32
-
33
- return (0, _element.createElement)(MainDashboardButtonSlot, {
34
- bubblesVirtually: true
35
- });
36
- };
37
-
38
- MainDashboardButton.Slot = Slot;
39
- var _default = MainDashboardButton;
40
- exports.default = _default;
41
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/edit-site/src/components/main-dashboard-button/index.js"],"names":["slotName","Fill","Slot","MainDashboardButtonSlot","MainDashboardButton","children","fills","hasFills","Boolean","length"],"mappings":";;;;;;;;;AAGA;;AAHA;AACA;AACA;AAMA,MAAMA,QAAQ,GAAG,mCAAjB;AAEA,MAAM;AAAEC,EAAAA,IAAF;AAAQC,EAAAA,IAAI,EAAEC;AAAd,IAA0C,gCAAgBH,QAAhB,CAAhD;AAEA,MAAMI,mBAAmB,GAAGH,IAA5B;;AAEA,MAAMC,IAAI,GAAG,QAAoB;AAAA,MAAlB;AAAEG,IAAAA;AAAF,GAAkB;AAChC,QAAMC,KAAK,GAAG,4CAAcN,QAAd,CAAd;AACA,QAAMO,QAAQ,GAAGC,OAAO,CAAEF,KAAK,IAAIA,KAAK,CAACG,MAAjB,CAAxB;;AAEA,MAAK,CAAEF,QAAP,EAAkB;AACjB,WAAOF,QAAP;AACA;;AAED,SAAO,4BAAC,uBAAD;AAAyB,IAAA,gBAAgB;AAAzC,IAAP;AACA,CATD;;AAWAD,mBAAmB,CAACF,IAApB,GAA2BA,IAA3B;eAEeE,mB","sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\t__experimentalUseSlotFills as useSlotFills,\n\tcreateSlotFill,\n} from '@wordpress/components';\n\nconst slotName = '__experimentalMainDashboardButton';\n\nconst { Fill, Slot: MainDashboardButtonSlot } = createSlotFill( slotName );\n\nconst MainDashboardButton = Fill;\n\nconst Slot = ( { children } ) => {\n\tconst fills = useSlotFills( slotName );\n\tconst hasFills = Boolean( fills && fills.length );\n\n\tif ( ! hasFills ) {\n\t\treturn children;\n\t}\n\n\treturn <MainDashboardButtonSlot bubblesVirtually />;\n};\n\nMainDashboardButton.Slot = Slot;\n\nexport default MainDashboardButton;\n"]}
@@ -1,32 +0,0 @@
1
- import { createElement } from "@wordpress/element";
2
-
3
- /**
4
- * WordPress dependencies
5
- */
6
- import { __experimentalUseSlotFills as useSlotFills, createSlotFill } from '@wordpress/components';
7
- const slotName = '__experimentalMainDashboardButton';
8
- const {
9
- Fill,
10
- Slot: MainDashboardButtonSlot
11
- } = createSlotFill(slotName);
12
- const MainDashboardButton = Fill;
13
-
14
- const Slot = _ref => {
15
- let {
16
- children
17
- } = _ref;
18
- const fills = useSlotFills(slotName);
19
- const hasFills = Boolean(fills && fills.length);
20
-
21
- if (!hasFills) {
22
- return children;
23
- }
24
-
25
- return createElement(MainDashboardButtonSlot, {
26
- bubblesVirtually: true
27
- });
28
- };
29
-
30
- MainDashboardButton.Slot = Slot;
31
- export default MainDashboardButton;
32
- //# sourceMappingURL=index.js.map