diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index a7bf34a80888c9..9c5fb95fb89e78 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -323,6 +323,15 @@ Create a bulleted or numbered list. ([Source](https://github.com/WordPress/guten
- **Supports:** __unstablePasteTextInline, anchor, color (background, gradients, link, text), typography (fontSize, lineHeight), ~~className~~
- **Attributes:** ordered, placeholder, reversed, start, type, values
+## List item
+
+Create a list item. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/list-item))
+
+- **Name:** core/list-item
+- **Category:** text
+- **Supports:** ~~className~~
+- **Attributes:** content, placeholder
+
## Login/out
Show login & logout links. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/loginout))
diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js
index 52a2b4f3f50b09..a01fc96bd6e158 100644
--- a/packages/block-library/src/index.js
+++ b/packages/block-library/src/index.js
@@ -46,6 +46,7 @@ import * as image from './image';
import * as latestComments from './latest-comments';
import * as latestPosts from './latest-posts';
import * as list from './list';
+import * as listItem from './list-item';
import * as logInOut from './loginout';
import * as mediaText from './media-text';
import * as missing from './missing';
@@ -135,6 +136,7 @@ export const __experimentalGetCoreBlocks = () => [
heading,
gallery,
list,
+ listItem,
quote,
// Register all remaining core blocks.
diff --git a/packages/block-library/src/list-item/block.json b/packages/block-library/src/list-item/block.json
new file mode 100644
index 00000000000000..ae8009feec8f82
--- /dev/null
+++ b/packages/block-library/src/list-item/block.json
@@ -0,0 +1,26 @@
+{
+ "$schema": "https://schemas.wp.org/trunk/block.json",
+ "apiVersion": 2,
+ "name": "core/list-item",
+ "title": "List item",
+ "category": "text",
+ "parent": [ "core/list" ],
+ "description": "Create a list item.",
+ "textdomain": "default",
+ "attributes": {
+ "placeholder": {
+ "type": "string"
+ },
+ "content": {
+ "type": "string",
+ "source": "html",
+ "selector": "li",
+ "default": "",
+ "__experimentalRole": "content"
+ }
+ },
+ "supports": {
+ "className": false,
+ "__experimentalSelector": "li"
+ }
+}
diff --git a/packages/block-library/src/list-item/edit.js b/packages/block-library/src/list-item/edit.js
new file mode 100644
index 00000000000000..c78f6671b5635a
--- /dev/null
+++ b/packages/block-library/src/list-item/edit.js
@@ -0,0 +1,32 @@
+/**
+ * WordPress dependencies
+ */
+import {
+ RichText,
+ useBlockProps,
+ useInnerBlocksProps,
+} from '@wordpress/block-editor';
+import { __ } from '@wordpress/i18n';
+
+export default function ListItemEdit( { attributes, setAttributes } ) {
+ const blockProps = useBlockProps();
+ const innerBlocksProps = useInnerBlocksProps( blockProps, {
+ allowedBlocks: [ 'core/list' ],
+ } );
+
+ return (
+
+
+ setAttributes( { content: nextContent } )
+ }
+ value={ attributes.content }
+ aria-label={ __( 'List text' ) }
+ placeholder={ attributes.placeholder || __( 'List' ) }
+ />
+ { innerBlocksProps.children }
+
+ );
+}
diff --git a/packages/block-library/src/list-item/index.js b/packages/block-library/src/list-item/index.js
new file mode 100644
index 00000000000000..87858117665379
--- /dev/null
+++ b/packages/block-library/src/list-item/index.js
@@ -0,0 +1,21 @@
+/**
+ * WordPress dependencies
+ */
+import { list as icon } from '@wordpress/icons';
+
+/**
+ * Internal dependencies
+ */
+import metadata from './block.json';
+import edit from './edit';
+import save from './save';
+
+const { name } = metadata;
+
+export { metadata, name };
+
+export const settings = {
+ icon,
+ edit,
+ save,
+};
diff --git a/packages/block-library/src/list-item/save.js b/packages/block-library/src/list-item/save.js
new file mode 100644
index 00000000000000..1362061ec0d911
--- /dev/null
+++ b/packages/block-library/src/list-item/save.js
@@ -0,0 +1,13 @@
+/**
+ * WordPress dependencies
+ */
+import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';
+
+export default function save( { attributes } ) {
+ return (
+
+
+
+
+ );
+}
diff --git a/packages/block-library/src/list/v2/edit.js b/packages/block-library/src/list/v2/edit.js
index db14ebaa0427f3..a8641aa338a9fd 100644
--- a/packages/block-library/src/list/v2/edit.js
+++ b/packages/block-library/src/list/v2/edit.js
@@ -1,5 +1,18 @@
+/**
+ * WordPress dependencies
+ */
+import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
+
+const TEMPLATE = [ [ 'core/list-item' ] ];
+
function Edit() {
- return List block v2
;
+ const blockProps = useBlockProps();
+ const innerBlocksProps = useInnerBlocksProps( blockProps, {
+ allowedBlocks: [ 'core/list-item' ],
+ template: TEMPLATE,
+ } );
+
+ return ;
}
export default Edit;
diff --git a/packages/block-library/src/list/v2/save.js b/packages/block-library/src/list/v2/save.js
index 8970ff165f7255..23126d88d6d8c8 100644
--- a/packages/block-library/src/list/v2/save.js
+++ b/packages/block-library/src/list/v2/save.js
@@ -1,5 +1,12 @@
-function Save() {
- return List block v2
;
-}
+/**
+ * WordPress dependencies
+ */
+import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
-export default Save;
+export default function save() {
+ return (
+
+ );
+}
diff --git a/test/integration/fixtures/blocks/core__list-item.html b/test/integration/fixtures/blocks/core__list-item.html
new file mode 100644
index 00000000000000..f6df40887ffa3d
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__list-item.html
@@ -0,0 +1 @@
+
diff --git a/test/integration/fixtures/blocks/core__list-item.json b/test/integration/fixtures/blocks/core__list-item.json
new file mode 100644
index 00000000000000..0535b301da1230
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__list-item.json
@@ -0,0 +1,10 @@
+[
+ {
+ "name": "core/list-item",
+ "isValid": true,
+ "attributes": {
+ "content": ""
+ },
+ "innerBlocks": []
+ }
+]
diff --git a/test/integration/fixtures/blocks/core__list-item.parsed.json b/test/integration/fixtures/blocks/core__list-item.parsed.json
new file mode 100644
index 00000000000000..e20f173481eba5
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__list-item.parsed.json
@@ -0,0 +1,9 @@
+[
+ {
+ "blockName": "core/list-item",
+ "attrs": {},
+ "innerBlocks": [],
+ "innerHTML": "",
+ "innerContent": [ "" ]
+ }
+]
diff --git a/test/integration/fixtures/blocks/core__list-item.serialized.html b/test/integration/fixtures/blocks/core__list-item.serialized.html
new file mode 100644
index 00000000000000..58cc62e69b8646
--- /dev/null
+++ b/test/integration/fixtures/blocks/core__list-item.serialized.html
@@ -0,0 +1,3 @@
+
+
+