diff --git a/bin/build-plugin-zip.sh b/bin/build-plugin-zip.sh
index ad627e05f0c69..c823ca6a8017f 100755
--- a/bin/build-plugin-zip.sh
+++ b/bin/build-plugin-zip.sh
@@ -78,26 +78,15 @@ npm run build
php bin/generate-gutenberg-php.php > gutenberg.tmp.php
mv gutenberg.tmp.php gutenberg.php
-build_files=$(
- ls build/*/*.{js,js.map,css,asset.php} \
- build/block-library/blocks/*.php \
- build/block-library/blocks/*/block.json \
- build/block-library/blocks/*/*.{js,js.map,css,asset.php} \
- build/edit-widgets/blocks/*/block.json \
- build/widgets/blocks/*.php \
- build/widgets/blocks/*/block.json \
- build/style-engine/*.php \
-)
-
-
# Generate the plugin zip file.
status "Creating archive... 🎁"
-zip -r gutenberg.zip \
+zip --recurse-paths --no-dir-entries \
+ gutenberg.zip \
gutenberg.php \
lib \
packages/block-serialization-default-parser/*.php \
post-content.php \
- $build_files \
+ build \
build-module \
readme.txt \
changelog.txt \
diff --git a/docs/manifest.json b/docs/manifest.json
index d7f74d47995b6..e4eba19d99fa2 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -1697,12 +1697,6 @@
"markdown_source": "../packages/eslint-plugin/README.md",
"parent": "packages"
},
- {
- "title": "@wordpress/fields",
- "slug": "packages-fields",
- "markdown_source": "../packages/fields/README.md",
- "parent": "packages"
- },
{
"title": "@wordpress/format-library",
"slug": "packages-format-library",
diff --git a/lib/experimental/script-modules.php b/lib/experimental/script-modules.php
index 5a14e1418ed6d..a113df02b9d75 100644
--- a/lib/experimental/script-modules.php
+++ b/lib/experimental/script-modules.php
@@ -200,3 +200,30 @@ function gutenberg_dequeue_module( $module_identifier ) {
_deprecated_function( __FUNCTION__, 'Gutenberg 17.6.0', 'wp_dequeue_script_module' );
wp_script_modules()->dequeue( $module_identifier );
}
+
+/**
+ * Registers Gutenberg Script Modules.
+ *
+ * @since 19.3
+ */
+function gutenberg_register_script_modules() {
+ // When in production, use the plugin's version as the default asset version;
+ // else (for development or test) default to use the current time.
+ $default_version = defined( 'GUTENBERG_VERSION' ) && ! SCRIPT_DEBUG ? GUTENBERG_VERSION : time();
+
+ wp_deregister_script_module( '@wordpress/a11y' );
+ wp_register_script_module(
+ '@wordpress/a11y',
+ gutenberg_url( 'build-module/a11y/index.min.js' ),
+ array(),
+ $default_version
+ );
+ add_filter(
+ 'script_module_data_@wordpress/a11y',
+ function ( $data ) {
+ $data['i18n'] = array( 'Notifications' => __( 'Notifications', 'default' ) );
+ return $data;
+ }
+ );
+}
+add_action( 'init', 'gutenberg_register_script_modules' );
diff --git a/packages/a11y/README.md b/packages/a11y/README.md
index 0f40d9edd010e..755396d2bb8f0 100644
--- a/packages/a11y/README.md
+++ b/packages/a11y/README.md
@@ -39,7 +39,7 @@ speak( 'The message you want to send to the ARIA live region', 'assertive' );
_Parameters_
- _message_ `string`: The message to be announced by assistive technologies.
-- _ariaLive_ `[string]`: The politeness level for aria-live; default: 'polite'.
+- _ariaLive_ `['polite'|'assertive']`: The politeness level for aria-live; default: 'polite'.
diff --git a/packages/a11y/package.json b/packages/a11y/package.json
index 88123b3c6c712..327d6b9ff0716 100644
--- a/packages/a11y/package.json
+++ b/packages/a11y/package.json
@@ -28,6 +28,7 @@
"module": "build-module/index.js",
"react-native": "src/index",
"types": "build-types",
+ "wpScriptModuleExports": "./build-module/module/index.js",
"dependencies": {
"@babel/runtime": "^7.16.0",
"@wordpress/dom-ready": "file:../dom-ready",
diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js
index 957c76500c434..59e93da780bd8 100644
--- a/packages/a11y/src/index.js
+++ b/packages/a11y/src/index.js
@@ -2,87 +2,20 @@
* WordPress dependencies
*/
import domReady from '@wordpress/dom-ready';
+import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
-import addIntroText from './add-intro-text';
-import addContainer from './add-container';
-import clear from './clear';
-import filterMessage from './filter-message';
+import { makeSetupFunction } from './shared/index';
+export { speak } from './shared/index';
/**
* Create the live regions.
*/
-export function setup() {
- const introText = document.getElementById( 'a11y-speak-intro-text' );
- const containerAssertive = document.getElementById(
- 'a11y-speak-assertive'
- );
- const containerPolite = document.getElementById( 'a11y-speak-polite' );
-
- if ( introText === null ) {
- addIntroText();
- }
-
- if ( containerAssertive === null ) {
- addContainer( 'assertive' );
- }
-
- if ( containerPolite === null ) {
- addContainer( 'polite' );
- }
-}
+export const setup = makeSetupFunction( __( 'Notifications' ) );
/**
* Run setup on domReady.
*/
domReady( setup );
-
-/**
- * Allows you to easily announce dynamic interface updates to screen readers using ARIA live regions.
- * This module is inspired by the `speak` function in `wp-a11y.js`.
- *
- * @param {string} message The message to be announced by assistive technologies.
- * @param {string} [ariaLive] The politeness level for aria-live; default: 'polite'.
- *
- * @example
- * ```js
- * import { speak } from '@wordpress/a11y';
- *
- * // For polite messages that shouldn't interrupt what screen readers are currently announcing.
- * speak( 'The message you want to send to the ARIA live region' );
- *
- * // For assertive messages that should interrupt what screen readers are currently announcing.
- * speak( 'The message you want to send to the ARIA live region', 'assertive' );
- * ```
- */
-export function speak( message, ariaLive ) {
- /*
- * Clear previous messages to allow repeated strings being read out and hide
- * the explanatory text from assistive technologies.
- */
- clear();
-
- message = filterMessage( message );
-
- const introText = document.getElementById( 'a11y-speak-intro-text' );
- const containerAssertive = document.getElementById(
- 'a11y-speak-assertive'
- );
- const containerPolite = document.getElementById( 'a11y-speak-polite' );
-
- if ( containerAssertive && ariaLive === 'assertive' ) {
- containerAssertive.textContent = message;
- } else if ( containerPolite ) {
- containerPolite.textContent = message;
- }
-
- /*
- * Make the explanatory text available to assistive technologies by removing
- * the 'hidden' HTML attribute.
- */
- if ( introText ) {
- introText.removeAttribute( 'hidden' );
- }
-}
diff --git a/packages/a11y/src/index.native.js b/packages/a11y/src/index.native.js
index f6f53b6343adb..e17597a8b2747 100644
--- a/packages/a11y/src/index.native.js
+++ b/packages/a11y/src/index.native.js
@@ -1,7 +1,7 @@
/**
* Internal dependencies
*/
-import filterMessage from './filter-message';
+import filterMessage from './shared/filter-message';
/**
* Update the ARIA live notification area text node.
diff --git a/packages/a11y/src/module/index.ts b/packages/a11y/src/module/index.ts
new file mode 100644
index 0000000000000..a2c87f397f487
--- /dev/null
+++ b/packages/a11y/src/module/index.ts
@@ -0,0 +1,25 @@
+/**
+ * Internal dependencies
+ */
+import { makeSetupFunction } from '../shared/index';
+export { speak } from '../shared/index';
+
+// Without an i18n Script Module, "Notifications" (the only localized text used in this module)
+// will be translated on the server and provided as script-module data.
+let notificationsText = 'Notifications';
+try {
+ const textContent = document.getElementById(
+ 'wp-script-module-data-@wordpress/a11y'
+ )?.textContent;
+ if ( textContent ) {
+ const parsed = JSON.parse( textContent );
+ notificationsText = parsed?.i18n?.Notifications ?? notificationsText;
+ }
+} catch {}
+
+/**
+ * Create the live regions.
+ */
+export const setup = makeSetupFunction( notificationsText );
+
+setup();
diff --git a/packages/a11y/src/add-container.js b/packages/a11y/src/shared/add-container.js
similarity index 100%
rename from packages/a11y/src/add-container.js
rename to packages/a11y/src/shared/add-container.js
diff --git a/packages/a11y/src/add-intro-text.js b/packages/a11y/src/shared/add-intro-text.ts
similarity index 83%
rename from packages/a11y/src/add-intro-text.js
rename to packages/a11y/src/shared/add-intro-text.ts
index 2bcf453ec44c8..6bd97c887664d 100644
--- a/packages/a11y/src/add-intro-text.js
+++ b/packages/a11y/src/shared/add-intro-text.ts
@@ -1,22 +1,18 @@
-/**
- * WordPress dependencies
- */
-import { __ } from '@wordpress/i18n';
-
/**
* Build the explanatory text to be placed before the aria live regions.
*
* This text is initially hidden from assistive technologies by using a `hidden`
* HTML attribute which is then removed once a message fills the aria-live regions.
*
+ * @param {string} introTextContent The translated intro text content.
* @return {HTMLParagraphElement} The explanatory text HTML element.
*/
-export default function addIntroText() {
+export default function addIntroText( introTextContent: string ) {
const introText = document.createElement( 'p' );
introText.id = 'a11y-speak-intro-text';
introText.className = 'a11y-speak-intro-text';
- introText.textContent = __( 'Notifications' );
+ introText.textContent = introTextContent;
introText.setAttribute(
'style',
diff --git a/packages/a11y/src/clear.js b/packages/a11y/src/shared/clear.js
similarity index 100%
rename from packages/a11y/src/clear.js
rename to packages/a11y/src/shared/clear.js
diff --git a/packages/a11y/src/filter-message.js b/packages/a11y/src/shared/filter-message.js
similarity index 100%
rename from packages/a11y/src/filter-message.js
rename to packages/a11y/src/shared/filter-message.js
diff --git a/packages/a11y/src/shared/index.js b/packages/a11y/src/shared/index.js
new file mode 100644
index 0000000000000..a05f891f42856
--- /dev/null
+++ b/packages/a11y/src/shared/index.js
@@ -0,0 +1,81 @@
+/**
+ * Internal dependencies
+ */
+import addContainer from './add-container';
+import addIntroText from './add-intro-text';
+import clear from './clear';
+import filterMessage from './filter-message';
+
+/**
+ * Create the live regions.
+ * @param {string} introTextContent The intro text content.
+ */
+export function makeSetupFunction( introTextContent ) {
+ return function setup() {
+ const introText = document.getElementById( 'a11y-speak-intro-text' );
+ const containerAssertive = document.getElementById(
+ 'a11y-speak-assertive'
+ );
+ const containerPolite = document.getElementById( 'a11y-speak-polite' );
+
+ if ( introText === null ) {
+ addIntroText( introTextContent );
+ }
+
+ if ( containerAssertive === null ) {
+ addContainer( 'assertive' );
+ }
+
+ if ( containerPolite === null ) {
+ addContainer( 'polite' );
+ }
+ };
+}
+
+/**
+ * Allows you to easily announce dynamic interface updates to screen readers using ARIA live regions.
+ * This module is inspired by the `speak` function in `wp-a11y.js`.
+ *
+ * @param {string} message The message to be announced by assistive technologies.
+ * @param {'polite'|'assertive'} [ariaLive] The politeness level for aria-live; default: 'polite'.
+ *
+ * @example
+ * ```js
+ * import { speak } from '@wordpress/a11y';
+ *
+ * // For polite messages that shouldn't interrupt what screen readers are currently announcing.
+ * speak( 'The message you want to send to the ARIA live region' );
+ *
+ * // For assertive messages that should interrupt what screen readers are currently announcing.
+ * speak( 'The message you want to send to the ARIA live region', 'assertive' );
+ * ```
+ */
+export function speak( message, ariaLive ) {
+ /*
+ * Clear previous messages to allow repeated strings being read out and hide
+ * the explanatory text from assistive technologies.
+ */
+ clear();
+
+ message = filterMessage( message );
+
+ const introText = document.getElementById( 'a11y-speak-intro-text' );
+ const containerAssertive = document.getElementById(
+ 'a11y-speak-assertive'
+ );
+ const containerPolite = document.getElementById( 'a11y-speak-polite' );
+
+ if ( containerAssertive && ariaLive === 'assertive' ) {
+ containerAssertive.textContent = message;
+ } else if ( containerPolite ) {
+ containerPolite.textContent = message;
+ }
+
+ /*
+ * Make the explanatory text available to assistive technologies by removing
+ * the 'hidden' HTML attribute.
+ */
+ if ( introText ) {
+ introText.removeAttribute( 'hidden' );
+ }
+}
diff --git a/packages/a11y/src/test/add-container.test.js b/packages/a11y/src/shared/test/add-container.test.js
similarity index 100%
rename from packages/a11y/src/test/add-container.test.js
rename to packages/a11y/src/shared/test/add-container.test.js
diff --git a/packages/a11y/src/test/clear.test.js b/packages/a11y/src/shared/test/clear.test.js
similarity index 100%
rename from packages/a11y/src/test/clear.test.js
rename to packages/a11y/src/shared/test/clear.test.js
diff --git a/packages/a11y/src/test/filter-message.test.js b/packages/a11y/src/shared/test/filter-message.test.js
similarity index 100%
rename from packages/a11y/src/test/filter-message.test.js
rename to packages/a11y/src/shared/test/filter-message.test.js
diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js
index 4815baa220504..0f6b9d0bd572e 100644
--- a/packages/a11y/src/test/index.test.js
+++ b/packages/a11y/src/test/index.test.js
@@ -7,10 +7,10 @@ import domReady from '@wordpress/dom-ready';
* Internal dependencies
*/
import { setup, speak } from '../';
-import clear from '../clear';
-import filterMessage from '../filter-message';
+import clear from '../shared/clear';
+import filterMessage from '../shared/filter-message';
-jest.mock( '../clear', () => {
+jest.mock( '../shared/clear', () => {
return jest.fn();
} );
jest.mock( '@wordpress/dom-ready', () => {
@@ -18,7 +18,7 @@ jest.mock( '@wordpress/dom-ready', () => {
callback();
} );
} );
-jest.mock( '../filter-message', () => {
+jest.mock( '../shared/filter-message', () => {
return jest.fn( ( message ) => {
return message;
} );
diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js b/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js
index bb6edd066f06f..1944cfde96c7f 100644
--- a/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js
+++ b/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { useDispatch } from '@wordpress/data';
+import { useSelect, useDispatch } from '@wordpress/data';
import { useRefEffect } from '@wordpress/compose';
/**
@@ -16,6 +16,10 @@ import { unlock } from '../../../lock-unlock';
* @param {string} clientId Block client ID.
*/
export function useZoomOutModeExit( { editorMode } ) {
+ const getSettings = useSelect(
+ ( select ) => select( blockEditorStore ).getSettings
+ );
+
const { __unstableSetEditorMode } = unlock(
useDispatch( blockEditorStore )
);
@@ -29,6 +33,14 @@ export function useZoomOutModeExit( { editorMode } ) {
function onDoubleClick( event ) {
if ( ! event.defaultPrevented ) {
event.preventDefault();
+
+ const { __experimentalSetIsInserterOpened } = getSettings();
+
+ if (
+ typeof __experimentalSetIsInserterOpened === 'function'
+ ) {
+ __experimentalSetIsInserterOpened( false );
+ }
__unstableSetEditorMode( 'edit' );
}
}
diff --git a/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js b/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js
index 0d3df9e20dfc5..a3c46c4b4c970 100644
--- a/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js
+++ b/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js
@@ -31,7 +31,12 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) {
getPreviousBlockClientId,
canRemoveBlock,
canMoveBlock,
+ getSettings,
} = select( blockEditorStore );
+
+ const { __experimentalSetIsInserterOpened: setIsInserterOpened } =
+ getSettings();
+
const { getBlockType } = select( blocksStore );
const { name } = getBlock( clientId );
const blockType = getBlockType( name );
@@ -63,6 +68,7 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) {
isPrevBlockTemplatePart,
canRemove: canRemoveBlock( clientId ),
canMove: canMoveBlock( clientId ),
+ setIsInserterOpened,
};
},
[ clientId ]
@@ -75,6 +81,7 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) {
isPrevBlockTemplatePart,
canRemove,
canMove,
+ setIsInserterOpened,
} = selected;
const { removeBlock, __unstableSetEditorMode } =
@@ -132,6 +139,10 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) {
icon={ edit }
label={ __( 'Edit' ) }
onClick={ () => {
+ // Setting may be undefined.
+ if ( typeof setIsInserterOpened === 'function' ) {
+ setIsInserterOpened( false );
+ }
__unstableSetEditorMode( 'edit' );
__unstableContentRef.current?.focus();
} }
diff --git a/packages/block-editor/src/components/list-view/index.js b/packages/block-editor/src/components/list-view/index.js
index 1493fa655a5aa..87599ea870913 100644
--- a/packages/block-editor/src/components/list-view/index.js
+++ b/packages/block-editor/src/components/list-view/index.js
@@ -119,20 +119,16 @@ function ListViewComponent(
const blockIndexes = useListViewBlockIndexes( clientIdsTree );
const { getBlock } = useSelect( blockEditorStore );
- const { visibleBlockCount, shouldShowInnerBlocks } = useSelect(
+ const { visibleBlockCount } = useSelect(
( select ) => {
- const {
- getGlobalBlockCount,
- getClientIdsOfDescendants,
- __unstableGetEditorMode,
- } = select( blockEditorStore );
+ const { getGlobalBlockCount, getClientIdsOfDescendants } =
+ select( blockEditorStore );
const draggedBlockCount =
draggedClientIds?.length > 0
? getClientIdsOfDescendants( draggedClientIds ).length + 1
: 0;
return {
visibleBlockCount: getGlobalBlockCount() - draggedBlockCount,
- shouldShowInnerBlocks: __unstableGetEditorMode() !== 'zoom-out',
};
},
[ draggedClientIds ]
@@ -397,7 +393,6 @@ function ListViewComponent(
fixedListWindow={ fixedListWindow }
selectedClientIds={ selectedClientIds }
isExpanded={ isExpanded }
- shouldShowInnerBlocks={ shouldShowInnerBlocks }
showAppender={ showAppender }
/>
diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js
index b72ebd1818337..d76f90bc94ffe 100644
--- a/packages/block-editor/src/store/private-selectors.js
+++ b/packages/block-editor/src/store/private-selectors.js
@@ -114,6 +114,7 @@ export const getEnabledClientIdsTree = createSelector(
state.blockEditingModes,
state.settings.templateLock,
state.blockListSettings,
+ state.editorMode,
]
);
diff --git a/packages/block-library/src/form-input/deprecated.js b/packages/block-library/src/form-input/deprecated.js
index 9cd49d5b0011b..451cc704a42d5 100644
--- a/packages/block-library/src/form-input/deprecated.js
+++ b/packages/block-library/src/form-input/deprecated.js
@@ -9,6 +9,7 @@ import removeAccents from 'remove-accents';
*/
import {
RichText,
+ useBlockProps,
__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
} from '@wordpress/block-editor';
@@ -26,6 +27,118 @@ const getNameFromLabelV1 = ( content ) => {
);
};
+const v2 = {
+ attributes: {
+ type: {
+ type: 'string',
+ default: 'text',
+ },
+ name: {
+ type: 'string',
+ },
+ label: {
+ type: 'string',
+ default: 'Label',
+ selector: '.wp-block-form-input__label-content',
+ source: 'html',
+ __experimentalRole: 'content',
+ },
+ inlineLabel: {
+ type: 'boolean',
+ default: false,
+ },
+ required: {
+ type: 'boolean',
+ default: false,
+ selector: '.wp-block-form-input__input',
+ source: 'attribute',
+ attribute: 'required',
+ },
+ placeholder: {
+ type: 'string',
+ selector: '.wp-block-form-input__input',
+ source: 'attribute',
+ attribute: 'placeholder',
+ __experimentalRole: 'content',
+ },
+ value: {
+ type: 'string',
+ default: '',
+ selector: 'input',
+ source: 'attribute',
+ attribute: 'value',
+ },
+ visibilityPermissions: {
+ type: 'string',
+ default: 'all',
+ },
+ },
+ supports: {
+ anchor: true,
+ reusable: false,
+ spacing: {
+ margin: [ 'top', 'bottom' ],
+ },
+ __experimentalBorder: {
+ radius: true,
+ __experimentalSkipSerialization: true,
+ __experimentalDefaultControls: {
+ radius: true,
+ },
+ },
+ },
+ save( { attributes } ) {
+ const { type, name, label, inlineLabel, required, placeholder, value } =
+ attributes;
+
+ const borderProps = getBorderClassesAndStyles( attributes );
+ const colorProps = getColorClassesAndStyles( attributes );
+
+ const inputStyle = {
+ ...borderProps.style,
+ ...colorProps.style,
+ };
+
+ const inputClasses = clsx(
+ 'wp-block-form-input__input',
+ colorProps.className,
+ borderProps.className
+ );
+ const TagName = type === 'textarea' ? 'textarea' : 'input';
+
+ const blockProps = useBlockProps.save();
+
+ if ( 'hidden' === type ) {
+ return ;
+ }
+
+ return (
+
+ { /* eslint-disable jsx-a11y/label-has-associated-control */ }
+
+ { /* eslint-enable jsx-a11y/label-has-associated-control */ }
+
+ );
+ },
+};
+
// Version without wrapper div in saved markup
// See: https://github.com/WordPress/gutenberg/pull/56507
const v1 = {
@@ -137,6 +250,6 @@ const v1 = {
},
};
-const deprecated = [ v1 ];
+const deprecated = [ v2, v1 ];
export default deprecated;
diff --git a/packages/block-library/src/form-input/edit.js b/packages/block-library/src/form-input/edit.js
index 6939443011ee5..5f3713e83975f 100644
--- a/packages/block-library/src/form-input/edit.js
+++ b/packages/block-library/src/form-input/edit.js
@@ -31,6 +31,9 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
ref.current.focus();
}
+ // Note: radio inputs aren't implemented yet.
+ const isCheckboxOrRadio = type === 'checkbox' || type === 'radio';
+
const controls = (
<>
{ 'hidden' !== type && (
@@ -81,6 +84,18 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
>
);
+ const content = (
+ setAttributes( { label: newLabel } ) }
+ aria-label={ label ? __( 'Label' ) : __( 'Empty label' ) }
+ data-empty={ ! label }
+ placeholder={ __( 'Type the label for this input' ) }
+ />
+ );
+
if ( 'hidden' === type ) {
return (
<>
@@ -111,17 +126,7 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
'is-label-inline': inlineLabel || 'checkbox' === type,
} ) }
>
-
- setAttributes( { label: newLabel } )
- }
- aria-label={ label ? __( 'Label' ) : __( 'Empty label' ) }
- data-empty={ label ? false : true }
- placeholder={ __( 'Type the label for this input' ) }
- />
+ { ! isCheckboxOrRadio && content }
+ { isCheckboxOrRadio && content }
);
diff --git a/packages/block-library/src/form-input/save.js b/packages/block-library/src/form-input/save.js
index c408e06923ca9..941c23dc2014d 100644
--- a/packages/block-library/src/form-input/save.js
+++ b/packages/block-library/src/form-input/save.js
@@ -55,6 +55,9 @@ export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
+ // Note: radio inputs aren't implemented yet.
+ const isCheckboxOrRadio = type === 'checkbox' || type === 'radio';
+
if ( 'hidden' === type ) {
return ;
}
@@ -67,9 +70,11 @@ export default function save( { attributes } ) {
'is-label-inline': inlineLabel,
} ) }
>
-
-
-
+ { ! isCheckboxOrRadio && (
+
+
+
+ ) }
+ { isCheckboxOrRadio && (
+
+
+
+ ) }
{ /* eslint-enable jsx-a11y/label-has-associated-control */ }
diff --git a/packages/block-library/src/form-input/style.scss b/packages/block-library/src/form-input/style.scss
index f9e1753cf0a7b..7b1ac53cc89c0 100644
--- a/packages/block-library/src/form-input/style.scss
+++ b/packages/block-library/src/form-input/style.scss
@@ -15,16 +15,17 @@
}
}
- /*
- Small tweak to left-align the checkbox.
- Even though `:has` is not currently supported in Firefox, this is a small tweak
- and does not affect the functionality of the block or the user's experience.
- There will be a minor inconsistency between browsers. However, it's more important to provide
- a better experience for 80+% of users, until Firefox catches up and supports `:has`.
- */
&:has(input[type="checkbox"]) {
+ flex-direction: row;
width: fit-content;
- /* stylelint-disable-next-line declaration-property-value-allowed-list -- This should be refactored to not use the row-reverse value. */
+
+ .wp-block-form-input__label-content {
+ margin: 0;
+ }
+ }
+
+ &:has(.wp-block-form-input__label-content + input[type="checkbox"]) {
+ /* stylelint-disable-next-line declaration-property-value-allowed-list -- This style is required for old markup. */
flex-direction: row-reverse;
}
}
diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js
index fcc6e5a0ed173..cc99986024476 100644
--- a/packages/dependency-extraction-webpack-plugin/lib/util.js
+++ b/packages/dependency-extraction-webpack-plugin/lib/util.js
@@ -90,9 +90,10 @@ function defaultRequestToExternalModule( request ) {
return `module ${ request }`;
}
- if ( request === '@wordpress/interactivity-router' ) {
- // Assumes this is usually going to be used as a dynamic import.
- return `import ${ request }`;
+ switch ( request ) {
+ case '@wordpress/interactivity-router':
+ case '@wordpress/a11y':
+ return `import ${ request }`;
}
const isWordPressScript = Boolean( defaultRequestToExternal( request ) );
diff --git a/packages/editor/src/components/start-template-options/index.js b/packages/editor/src/components/start-template-options/index.js
index e86531272b54f..3651c5c029a2c 100644
--- a/packages/editor/src/components/start-template-options/index.js
+++ b/packages/editor/src/components/start-template-options/index.js
@@ -156,8 +156,7 @@ function StartModal( { slug, isCustom, onClose, postType } ) {
>