+ data-wp-interactive
+ data-wp-context='{ "{{namespace}}": { "isOpen": false } }'
+ data-wp-effect="effects.{{namespace}}.logIsOpen"
+>
+
+
+
+
+
+
+{{/isBasicVariant}}
\ No newline at end of file
diff --git a/packages/create-block-interactive-template/block-templates/style.scss.mustache b/packages/create-block-interactive-template/block-templates/style.scss.mustache
new file mode 100644
index 0000000000000..1c73fa1c38ff9
--- /dev/null
+++ b/packages/create-block-interactive-template/block-templates/style.scss.mustache
@@ -0,0 +1,12 @@
+/**
+ * The following styles get applied both on the front of your site
+ * and in the editor.
+ *
+ * Replace them with your own styles or remove the file completely.
+ */
+
+.wp-block-{{namespace}}-{{slug}} {
+ font-size: 1em;
+ background: #ffff001a;
+ padding: 1em;
+}
diff --git a/packages/create-block-interactive-template/block-templates/view.js.mustache b/packages/create-block-interactive-template/block-templates/view.js.mustache
new file mode 100644
index 0000000000000..85d74fec190ba
--- /dev/null
+++ b/packages/create-block-interactive-template/block-templates/view.js.mustache
@@ -0,0 +1,26 @@
+{{#isBasicVariant}}
+
+/**
+ * WordPress dependencies
+ */
+import { store } from "@wordpress/interactivity";
+
+store( {
+ actions: {
+ '{{namespace}}': {
+ toggle: ( { context } ) => {
+ context[ '{{namespace}}' ].isOpen = !context[ '{{namespace}}' ].isOpen;
+ },
+ },
+ },
+ effects: {
+ '{{namespace}}': {
+ logIsOpen: ( { context } ) => {
+ // Log the value of `isOpen` each time it changes.
+ console.log( `Is open: ${ context[ '{{namespace}}' ].isOpen }` );
+ },
+ },
+ },
+} );
+
+{{/isBasicVariant}}
\ No newline at end of file
diff --git a/packages/create-block-interactive-template/index.js b/packages/create-block-interactive-template/index.js
new file mode 100644
index 0000000000000..a52475ed7a79e
--- /dev/null
+++ b/packages/create-block-interactive-template/index.js
@@ -0,0 +1,24 @@
+/**
+ * External dependencies
+ */
+const { join } = require( 'path' );
+
+module.exports = {
+ defaultValues: {
+ slug: 'example-interactive',
+ title: 'Example Interactive',
+ description: 'An interactive block with the Interactivity API',
+ dashicon: 'media-interactive',
+ npmDependencies: [ '@wordpress/interactivity' ],
+ supports: {
+ interactivity: true,
+ },
+ render: 'file:./render.php',
+ viewScript: 'file:./view.js',
+ },
+ variants: {
+ basic: {},
+ },
+ pluginTemplatesPath: join( __dirname, 'plugin-templates' ),
+ blockTemplatesPath: join( __dirname, 'block-templates' ),
+};
diff --git a/packages/create-block-interactive-template/package.json b/packages/create-block-interactive-template/package.json
new file mode 100644
index 0000000000000..1638b33e64847
--- /dev/null
+++ b/packages/create-block-interactive-template/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "@wordpress/create-block-interactive-template",
+ "version": "1.0.0",
+ "description": "Template for @wordpress/create-block to create interactive blocks with the Interactivity API.",
+ "author": "The WordPress Contributors",
+ "license": "GPL-2.0-or-later",
+ "keywords": [
+ "wordpress",
+ "create block",
+ "block template",
+ "Interactivity API"
+ ],
+ "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/docs/getting-started/create-block",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/WordPress/gutenberg.git",
+ "directory": "packages/create-block-interactive-template"
+ },
+ "bugs": {
+ "url": "https://github.com/WordPress/gutenberg/issues"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/packages/create-block-interactive-template/plugin-templates/$slug.php.mustache b/packages/create-block-interactive-template/plugin-templates/$slug.php.mustache
new file mode 100644
index 0000000000000..2322881ab0d71
--- /dev/null
+++ b/packages/create-block-interactive-template/plugin-templates/$slug.php.mustache
@@ -0,0 +1,43 @@
+ !! value )
),
diff --git a/packages/create-block/lib/scaffold.js b/packages/create-block/lib/scaffold.js
index cdeaf85a97bb4..a8d9c3859e20d 100644
--- a/packages/create-block/lib/scaffold.js
+++ b/packages/create-block/lib/scaffold.js
@@ -44,6 +44,7 @@ module.exports = async (
editorStyle,
style,
render,
+ viewScript,
variantVars,
customPackageJSON,
customBlockJSON,
@@ -103,6 +104,7 @@ module.exports = async (
editorStyle,
style,
render,
+ viewScript,
customPackageJSON,
customBlockJSON,
...variantVars,
diff --git a/packages/create-block/lib/templates.js b/packages/create-block/lib/templates.js
index 018385c9fde82..4ce898617adde 100644
--- a/packages/create-block/lib/templates.js
+++ b/packages/create-block/lib/templates.js
@@ -33,6 +33,7 @@ const predefinedPluginTemplates = {
editorScript: null,
editorStyle: null,
style: null,
+ viewScript: 'file:./view.js',
},
templatesPath: join( __dirname, 'templates', 'es5' ),
variants: {
@@ -53,6 +54,7 @@ const predefinedPluginTemplates = {
supports: {
html: false,
},
+ viewScript: 'file:./view.js',
},
variants: {
static: {},
diff --git a/packages/create-block/lib/templates/block/view.js.mustache b/packages/create-block/lib/templates/block/view.js.mustache
new file mode 100644
index 0000000000000..baff12a165cd9
--- /dev/null
+++ b/packages/create-block/lib/templates/block/view.js.mustache
@@ -0,0 +1,3 @@
+/* eslint-disable no-console */
+console.log("Hello World! (from {{namespace}}-{{slug}} block)");
+/* eslint-enable no-console */
diff --git a/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap b/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap
index faeb6f9e434cb..0e4ff9e63a10a 100644
--- a/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap
+++ b/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap
@@ -50,7 +50,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`dynamic-import\` should pro
`;
exports[`DependencyExtractionWebpackPlugin Webpack \`function-output-filename\` should produce expected output: Asset file 'chunk--main--main.asset.php' should match snapshot 1`] = `
-" array('lodash', 'wp-blob'), 'version' => '9b7ebe61044661fdabda');
+" array('lodash', 'wp-blob'), 'version' => 'fc2d750fc9e08c5749db');
"
`;
@@ -96,7 +96,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`has-extension-suffix\` shou
`;
exports[`DependencyExtractionWebpackPlugin Webpack \`no-default\` should produce expected output: Asset file 'main.asset.php' should match snapshot 1`] = `
-" array(), 'version' => 'f7e2cb527e601f74f8bd');
+" array(), 'version' => '43880e6c42e7c39fcdf1');
"
`;
@@ -110,7 +110,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`no-deps\` should produce ex
exports[`DependencyExtractionWebpackPlugin Webpack \`no-deps\` should produce expected output: External modules should match snapshot 1`] = `[]`;
exports[`DependencyExtractionWebpackPlugin Webpack \`option-function-output-filename\` should produce expected output: Asset file 'chunk--main--main.asset.php' should match snapshot 1`] = `
-" array('lodash', 'wp-blob'), 'version' => '9b7ebe61044661fdabda');
+" array('lodash', 'wp-blob'), 'version' => 'fc2d750fc9e08c5749db');
"
`;
@@ -133,7 +133,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`option-function-output-file
`;
exports[`DependencyExtractionWebpackPlugin Webpack \`option-output-filename\` should produce expected output: Asset file 'main-foo.asset.php' should match snapshot 1`] = `
-" array('lodash', 'wp-blob'), 'version' => '9b7ebe61044661fdabda');
+" array('lodash', 'wp-blob'), 'version' => 'fc2d750fc9e08c5749db');
"
`;
@@ -155,7 +155,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`option-output-filename\` sh
]
`;
-exports[`DependencyExtractionWebpackPlugin Webpack \`output-format-json\` should produce expected output: Asset file 'main.asset.json' should match snapshot 1`] = `"{"dependencies":["lodash"],"version":"4c42b9646049ad2e9438"}"`;
+exports[`DependencyExtractionWebpackPlugin Webpack \`output-format-json\` should produce expected output: Asset file 'main.asset.json' should match snapshot 1`] = `"{"dependencies":["lodash"],"version":"7bd48470d799a795bf9a"}"`;
exports[`DependencyExtractionWebpackPlugin Webpack \`output-format-json\` should produce expected output: External modules should match snapshot 1`] = `
[
@@ -240,7 +240,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`runtime-chunk-single\` shou
`;
exports[`DependencyExtractionWebpackPlugin Webpack \`style-imports\` should produce expected output: Asset file 'main.asset.php' should match snapshot 1`] = `
-" array('lodash', 'wp-blob'), 'version' => 'd8c0ee89d933a3809c0e');
+" array('lodash', 'wp-blob'), 'version' => '4c661914a4e4d80b8a0b');
"
`;
@@ -263,7 +263,7 @@ exports[`DependencyExtractionWebpackPlugin Webpack \`style-imports\` should prod
`;
exports[`DependencyExtractionWebpackPlugin Webpack \`wordpress\` should produce expected output: Asset file 'main.asset.php' should match snapshot 1`] = `
-" array('lodash', 'wp-blob'), 'version' => '9b7ebe61044661fdabda');
+" array('lodash', 'wp-blob'), 'version' => 'fc2d750fc9e08c5749db');
"
`;
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/function-output-filename/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/function-output-filename/index.js
index 917b4cd7e204b..4545bcd0c19bc 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/function-output-filename/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/function-output-filename/index.js
@@ -6,6 +6,7 @@ import { isBlobURL } from '@wordpress/blob';
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.isEmpty( isBlobURL( '' ) );
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/no-default/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/no-default/index.js
index 612e420c2a6c4..f9eb6f42f0a2d 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/no-default/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/no-default/index.js
@@ -1,6 +1,7 @@
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.map( [], _.identity );
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/option-function-output-filename/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/option-function-output-filename/index.js
index 917b4cd7e204b..4545bcd0c19bc 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/option-function-output-filename/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/option-function-output-filename/index.js
@@ -6,6 +6,7 @@ import { isBlobURL } from '@wordpress/blob';
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.isEmpty( isBlobURL( '' ) );
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/option-output-filename/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/option-output-filename/index.js
index 917b4cd7e204b..4545bcd0c19bc 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/option-output-filename/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/option-output-filename/index.js
@@ -6,6 +6,7 @@ import { isBlobURL } from '@wordpress/blob';
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.isEmpty( isBlobURL( '' ) );
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/output-format-json/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/output-format-json/index.js
index 612e420c2a6c4..f9eb6f42f0a2d 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/output-format-json/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/output-format-json/index.js
@@ -1,6 +1,7 @@
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.map( [], _.identity );
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/runtime-chunk-single/b.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/runtime-chunk-single/b.js
index 917b4cd7e204b..4545bcd0c19bc 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/runtime-chunk-single/b.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/runtime-chunk-single/b.js
@@ -6,6 +6,7 @@ import { isBlobURL } from '@wordpress/blob';
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.isEmpty( isBlobURL( '' ) );
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/style-imports/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/style-imports/index.js
index df02e0b35e6f8..b4e8cb76d1fa5 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/style-imports/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/style-imports/index.js
@@ -6,6 +6,7 @@ import { isBlobURL } from '@wordpress/blob';
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
/**
diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/wordpress/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/wordpress/index.js
index 917b4cd7e204b..4545bcd0c19bc 100644
--- a/packages/dependency-extraction-webpack-plugin/test/fixtures/wordpress/index.js
+++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/wordpress/index.js
@@ -6,6 +6,7 @@ import { isBlobURL } from '@wordpress/blob';
/**
* External dependencies
*/
+// eslint-disable-next-line no-restricted-imports
import _ from 'lodash';
_.isEmpty( isBlobURL( '' ) );
diff --git a/packages/e2e-test-utils-playwright/src/test.ts b/packages/e2e-test-utils-playwright/src/test.ts
index 894abf93dcd02..eec8e4e279c0f 100644
--- a/packages/e2e-test-utils-playwright/src/test.ts
+++ b/packages/e2e-test-utils-playwright/src/test.ts
@@ -136,18 +136,6 @@ const test = base.extend<
storageStatePath: STORAGE_STATE_PATH,
} );
- await Promise.all( [
- requestUtils.activateTheme( 'twentytwentyone' ),
- // Disable this test plugin as it's conflicting with some of the tests.
- // We already have reduced motion enabled and Playwright will wait for most of the animations anyway.
- requestUtils.deactivatePlugin(
- 'gutenberg-test-plugin-disables-the-css-animations'
- ),
- requestUtils.deleteAllPosts(),
- requestUtils.deleteAllBlocks(),
- requestUtils.resetPreferences(),
- ] );
-
await use( requestUtils );
},
{ scope: 'worker', auto: true },
diff --git a/packages/e2e-test-utils/src/create-reusable-block.js b/packages/e2e-test-utils/src/create-reusable-block.js
index 9714638154403..860b5ac5660eb 100644
--- a/packages/e2e-test-utils/src/create-reusable-block.js
+++ b/packages/e2e-test-utils/src/create-reusable-block.js
@@ -15,8 +15,6 @@ import { canvas } from './canvas';
export const createReusableBlock = async ( content, title ) => {
const reusableBlockNameInputSelector =
'.reusable-blocks-menu-items__convert-modal .components-text-control__input';
- const syncToggleSelector =
- '.reusable-blocks-menu-items__convert-modal .components-form-toggle__input';
const syncToggleSelectorChecked =
'.reusable-blocks-menu-items__convert-modal .components-form-toggle.is-checked';
// Insert a paragraph block
@@ -31,8 +29,6 @@ export const createReusableBlock = async ( content, title ) => {
await nameInput.click();
await page.keyboard.type( title );
- const syncToggle = await page.waitForSelector( syncToggleSelector );
- syncToggle.click();
await page.waitForSelector( syncToggleSelectorChecked );
await page.keyboard.press( 'Enter' );
diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
index 2f237822b1ccc..1fc9217b4a77c 100644
--- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
+++ b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
@@ -23,8 +23,6 @@ const reusableBlockNameInputSelector =
'.reusable-blocks-menu-items__convert-modal .components-text-control__input';
const reusableBlockInspectorNameInputSelector =
'.block-editor-block-inspector .components-text-control__input';
-const syncToggleSelector =
- '.reusable-blocks-menu-items__convert-modal .components-form-toggle__input';
const syncToggleSelectorChecked =
'.reusable-blocks-menu-items__convert-modal .components-form-toggle.is-checked';
@@ -205,8 +203,6 @@ describe( 'Reusable blocks', () => {
);
await nameInput.click();
await page.keyboard.type( 'Multi-selection reusable block' );
- const syncToggle = await page.waitForSelector( syncToggleSelector );
- syncToggle.click();
await page.waitForSelector( syncToggleSelectorChecked );
await page.keyboard.press( 'Enter' );
@@ -389,8 +385,6 @@ describe( 'Reusable blocks', () => {
);
await nameInput.click();
await page.keyboard.type( 'Block with styles' );
- const syncToggle = await page.waitForSelector( syncToggleSelector );
- syncToggle.click();
await page.waitForSelector( syncToggleSelectorChecked );
await page.keyboard.press( 'Enter' );
const reusableBlock = await canvas().waitForSelector(
diff --git a/packages/edit-post/src/components/header/header-toolbar/index.native.js b/packages/edit-post/src/components/header/header-toolbar/index.native.js
index 55854ffc995f6..692136b2c3c20 100644
--- a/packages/edit-post/src/components/header/header-toolbar/index.native.js
+++ b/packages/edit-post/src/components/header/header-toolbar/index.native.js
@@ -1,13 +1,13 @@
/**
* External dependencies
*/
-import { Platform, ScrollView, View } from 'react-native';
+import { ScrollView, StyleSheet, View } from 'react-native';
/**
* WordPress dependencies
*/
-import { useCallback, useRef, useEffect } from '@wordpress/element';
-import { compose, withPreferredColorScheme } from '@wordpress/compose';
+import { useCallback, useRef, useEffect, Platform } from '@wordpress/element';
+import { compose, usePreferredColorSchemeStyle } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { withViewportMatch } from '@wordpress/viewport';
import { __ } from '@wordpress/i18n';
@@ -39,6 +39,13 @@ import {
import styles from './style.scss';
import { store as editPostStore } from '../../../store';
+const shadowStyle = {
+ shadowOffset: { width: 2, height: 2 },
+ shadowOpacity: 1,
+ shadowRadius: 6,
+ elevation: 18,
+};
+
function HeaderToolbar( {
hasRedo,
hasUndo,
@@ -46,18 +53,20 @@ function HeaderToolbar( {
undo,
showInserter,
showKeyboardHideButton,
- getStylesFromColorScheme,
insertBlock,
onHideKeyboard,
- onOpenBlockSettings,
isRTL,
noContentSelected,
} ) {
const anchorNodeRef = useRef();
- const containerStyle = getStylesFromColorScheme(
- styles[ 'header-toolbar__container' ],
- styles[ 'header-toolbar__container--dark' ]
- );
+
+ const containerStyle = [
+ usePreferredColorSchemeStyle(
+ styles[ 'header-toolbar__container' ],
+ styles[ 'header-toolbar__container--dark' ]
+ ),
+ { borderTopWidth: StyleSheet.hairlineWidth },
+ ];
useEffect( () => {
const onUndoSubscription = subscribeOnUndoPressed( undo );
@@ -80,8 +89,7 @@ function HeaderToolbar( {
const scrollViewRef = useRef( null );
const scrollToStart = () => {
// scrollview doesn't seem to automatically adjust to RTL on Android so, scroll to end when Android
- const isAndroid = Platform.OS === 'android';
- if ( isAndroid && isRTL ) {
+ if ( Platform.isAndroid && isRTL ) {
scrollViewRef.current.scrollToEnd();
} else {
scrollViewRef.current.scrollTo( { x: 0 } );
@@ -145,6 +153,23 @@ function HeaderToolbar( {
/* translators: accessibility text for the editor toolbar */
const toolbarAriaLabel = __( 'Document tools' );
+ const shadowColor = usePreferredColorSchemeStyle(
+ styles[ 'header-toolbar__keyboard-hide-shadow--light' ],
+ styles[ 'header-toolbar__keyboard-hide-shadow--dark' ]
+ );
+ const showKeyboardButtonStyles = [
+ usePreferredColorSchemeStyle(
+ styles[ 'header-toolbar__keyboard-hide-container' ],
+ styles[ 'header-toolbar__keyboard-hide-container--dark' ]
+ ),
+ shadowStyle,
+ {
+ shadowColor: Platform.isAndroid
+ ? styles[ 'header-toolbar__keyboard-hide-shadow--solid' ].color
+ : shadowColor.color,
+ },
+ ];
+
return (