diff --git a/package-lock.json b/package-lock.json
index 3cd1b0d9e3856a..321b5145fd445b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7906,6 +7906,7 @@
"@wordpress/components": "file:packages/components",
"@wordpress/core-data": "file:packages/core-data",
"@wordpress/data": "file:packages/data",
+ "@wordpress/editor": "file:packages/editor",
"@wordpress/element": "file:packages/element",
"@wordpress/hooks": "file:packages/hooks",
"@wordpress/i18n": "file:packages/i18n",
diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json
index 6bc88e9ec33271..587a13296c1530 100644
--- a/packages/edit-site/package.json
+++ b/packages/edit-site/package.json
@@ -28,6 +28,7 @@
"@wordpress/components": "file:../components",
"@wordpress/core-data": "file:../core-data",
"@wordpress/data": "file:../data",
+ "@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
"@wordpress/hooks": "file:../hooks",
"@wordpress/i18n": "file:../i18n",
diff --git a/packages/edit-site/src/components/header/index.js b/packages/edit-site/src/components/header/index.js
index 2b89acdafa8fbc..196b80834eadd6 100644
--- a/packages/edit-site/src/components/header/index.js
+++ b/packages/edit-site/src/components/header/index.js
@@ -3,6 +3,11 @@
*/
import { __ } from '@wordpress/i18n';
+/**
+ * Internal dependencies
+ */
+import SaveButton from '../save-button';
+
export default function Header() {
return (
{ __( 'Site Editor' ) } { __( '(beta)' ) }
+
+
+
);
}
diff --git a/packages/edit-site/src/components/header/style.scss b/packages/edit-site/src/components/header/style.scss
index f280aa258020d4..84fa28b4cd5918 100644
--- a/packages/edit-site/src/components/header/style.scss
+++ b/packages/edit-site/src/components/header/style.scss
@@ -31,3 +31,7 @@
font-size: 16px;
padding: 0 20px;
}
+
+.edit-site-header__actions {
+ padding: 0 20px;
+}
diff --git a/packages/edit-site/src/components/save-button/index.js b/packages/edit-site/src/components/save-button/index.js
new file mode 100644
index 00000000000000..ad1ab25b832258
--- /dev/null
+++ b/packages/edit-site/src/components/save-button/index.js
@@ -0,0 +1,56 @@
+/**
+ * WordPress dependencies
+ */
+import { useEntityProp } from '@wordpress/core-data';
+import { useEffect, useState, useCallback } from '@wordpress/element';
+import { useSelect } from '@wordpress/data';
+import { Button } from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+import { EntitiesSavedStates } from '@wordpress/editor';
+
+export default function SaveButton() {
+ const [ , setStatus ] = useEntityProp( 'postType', 'wp_template', 'status' );
+ // Publish template if not done yet.
+ useEffect( () => setStatus( 'publish' ), [] );
+
+ const { isDirty, isSaving } = useSelect( ( select ) => {
+ const { getEntityRecordChangesByRecord, isSavingEntityRecord } = select(
+ 'core'
+ );
+ const entityRecordChangesByRecord = getEntityRecordChangesByRecord();
+ const changedKinds = Object.keys( entityRecordChangesByRecord );
+ return {
+ isDirty: changedKinds.length > 0,
+ isSaving: changedKinds.some( ( changedKind ) =>
+ Object.keys(
+ entityRecordChangesByRecord[ changedKind ]
+ ).some( ( changedName ) =>
+ Object.keys(
+ entityRecordChangesByRecord[ changedKind ][ changedName ]
+ ).some( ( changedKey ) =>
+ isSavingEntityRecord( changedKind, changedName, changedKey )
+ )
+ )
+ ),
+ };
+ } );
+ const disabled = ! isDirty || isSaving;
+
+ const [ isOpen, setIsOpen ] = useState( false );
+ const open = useCallback( setIsOpen.bind( null, true ), [] );
+ const close = useCallback( setIsOpen.bind( null, false ), [] );
+ return (
+ <>
+
+
+ >
+ );
+}