diff --git a/package-lock.json b/package-lock.json
index 0bb48c55c5326c..27f01fd681824f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -54685,6 +54685,7 @@
"@wordpress/core-data": "*",
"@wordpress/data": "*",
"@wordpress/dataviews": "*",
+ "@wordpress/date": "*",
"@wordpress/element": "*",
"@wordpress/hooks": "*",
"@wordpress/html-entities": "*",
diff --git a/packages/date/README.md b/packages/date/README.md
index 8edd4e94a8538f..ed2dfdd4790324 100644
--- a/packages/date/README.md
+++ b/packages/date/README.md
@@ -50,7 +50,7 @@ _Parameters_
- _dateFormat_ `string`: PHP-style formatting string. See php.net/date.
- _dateValue_ `Moment | Date | string | undefined`: Date object or string, parsable by moment.js.
-- _timezone_ `string | number | boolean | undefined`: Timezone to output result in or a UTC offset. Defaults to timezone from site. Notice: `boolean` is effectively deprecated, but still supported for backward compatibility reasons.
+- _timezone_ `string | number | boolean | undefined=`: Timezone to output result in or a UTC offset. Defaults to timezone from site. Notice: `boolean` is effectively deprecated, but still supported for backward compatibility reasons.
_Returns_
diff --git a/packages/date/src/index.js b/packages/date/src/index.js
index 90f65f62628dc8..b632de3a7431f6 100644
--- a/packages/date/src/index.js
+++ b/packages/date/src/index.js
@@ -525,15 +525,15 @@ export function gmdate( dateFormat, dateValue = new Date() ) {
* Backward Compatibility Notice: if `timezone` is set to `true`, the function
* behaves like `gmdateI18n`.
*
- * @param {string} dateFormat PHP-style formatting string.
- * See php.net/date.
- * @param {Moment | Date | string | undefined} dateValue Date object or string, parsable by
- * moment.js.
- * @param {string | number | boolean | undefined} timezone Timezone to output result in or a
- * UTC offset. Defaults to timezone from
- * site. Notice: `boolean` is effectively
- * deprecated, but still supported for
- * backward compatibility reasons.
+ * @param {string} dateFormat PHP-style formatting string.
+ * See php.net/date.
+ * @param {Moment | Date | string | undefined} dateValue Date object or string, parsable by
+ * moment.js.
+ * @param {string | number | boolean | undefined=} timezone Timezone to output result in or a
+ * UTC offset. Defaults to timezone from
+ * site. Notice: `boolean` is effectively
+ * deprecated, but still supported for
+ * backward compatibility reasons.
*
* @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
* @see https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC
diff --git a/packages/edit-site/src/components/post-fields/index.js b/packages/edit-site/src/components/post-fields/index.js
index 097459ea110039..e151c5a048c011 100644
--- a/packages/edit-site/src/components/post-fields/index.js
+++ b/packages/edit-site/src/components/post-fields/index.js
@@ -6,7 +6,7 @@ import clsx from 'clsx';
/**
* WordPress dependencies
*/
-import { __, sprintf } from '@wordpress/i18n';
+import { __ } from '@wordpress/i18n';
import {
featuredImageField,
slugField,
@@ -15,24 +15,14 @@ import {
statusField,
commentStatusField,
titleField,
+ dateField,
} from '@wordpress/fields';
-import {
- createInterpolateElement,
- useMemo,
- useState,
-} from '@wordpress/element';
-import { dateI18n, getDate, getSettings } from '@wordpress/date';
+import { useMemo, useState } from '@wordpress/element';
import { commentAuthorAvatar as authorIcon } from '@wordpress/icons';
import { __experimentalHStack as HStack, Icon } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
-const getFormattedDate = ( dateToDisplay ) =>
- dateI18n(
- getSettings().formats.datetimeAbbreviated,
- getDate( dateToDisplay )
- );
-
function PostAuthorField( { item } ) {
const { text, imageUrl } = useSelect(
( select ) => {
@@ -99,83 +89,7 @@ function usePostFields() {
},
},
statusField,
- {
- label: __( 'Date' ),
- id: 'date',
- type: 'datetime',
- render: ( { item } ) => {
- const isDraftOrPrivate = [ 'draft', 'private' ].includes(
- item.status
- );
- if ( isDraftOrPrivate ) {
- return createInterpolateElement(
- sprintf(
- /* translators: %s: page creation or modification date. */
- __( 'Modified: ' ),
- getFormattedDate( item.date )
- ),
- {
- span: ,
- time: ,
- }
- );
- }
-
- const isScheduled = item.status === 'future';
- if ( isScheduled ) {
- return createInterpolateElement(
- sprintf(
- /* translators: %s: page creation date */
- __( 'Scheduled: ' ),
- getFormattedDate( item.date )
- ),
- {
- span: ,
- time: ,
- }
- );
- }
-
- const isPublished = item.status === 'publish';
- if ( isPublished ) {
- return createInterpolateElement(
- sprintf(
- /* translators: %s: page creation time */
- __( 'Published: ' ),
- getFormattedDate( item.date )
- ),
- {
- span: ,
- time: ,
- }
- );
- }
-
- // Pending posts show the modified date if it's newer.
- const dateToDisplay =
- getDate( item.modified ) > getDate( item.date )
- ? item.modified
- : item.date;
-
- const isPending = item.status === 'pending';
- if ( isPending ) {
- return createInterpolateElement(
- sprintf(
- /* translators: %s: page creation or modification date. */
- __( 'Modified: ' ),
- getFormattedDate( dateToDisplay )
- ),
- {
- span: ,
- time: ,
- }
- );
- }
-
- // Unknow status.
- return ;
- },
- },
+ dateField,
slugField,
parentField,
commentStatusField,
diff --git a/packages/fields/README.md b/packages/fields/README.md
index 1d673c4d46c7b1..bfcc63be4da472 100644
--- a/packages/fields/README.md
+++ b/packages/fields/README.md
@@ -18,6 +18,10 @@ npm install @wordpress/fields --save
Comment status field for BasePost.
+### dateField
+
+Date field for BasePost.
+
### deletePost
Undocumented declaration.
diff --git a/packages/fields/package.json b/packages/fields/package.json
index 34ef8992f93adf..f32c779c2e989e 100644
--- a/packages/fields/package.json
+++ b/packages/fields/package.json
@@ -41,6 +41,7 @@
"@wordpress/core-data": "*",
"@wordpress/data": "*",
"@wordpress/dataviews": "*",
+ "@wordpress/date": "*",
"@wordpress/element": "*",
"@wordpress/hooks": "*",
"@wordpress/html-entities": "*",
diff --git a/packages/fields/src/fields/date/date-view.tsx b/packages/fields/src/fields/date/date-view.tsx
new file mode 100644
index 00000000000000..1cc2ab2d04e047
--- /dev/null
+++ b/packages/fields/src/fields/date/date-view.tsx
@@ -0,0 +1,92 @@
+/**
+ * WordPress dependencies
+ */
+import { __, sprintf } from '@wordpress/i18n';
+import { createInterpolateElement } from '@wordpress/element';
+import { dateI18n, getDate, getSettings } from '@wordpress/date';
+
+/**
+ * Internal dependencies
+ */
+import type { BasePost } from '../../types';
+
+const getFormattedDate = ( dateToDisplay: string | null ) =>
+ dateI18n(
+ getSettings().formats.datetimeAbbreviated,
+ getDate( dateToDisplay )
+ );
+
+const DateView = ( { item }: { item: BasePost } ) => {
+ const isDraftOrPrivate = [ 'draft', 'private' ].includes(
+ item.status ?? ''
+ );
+ if ( isDraftOrPrivate ) {
+ return createInterpolateElement(
+ sprintf(
+ /* translators: %s: page creation or modification date. */
+ __( 'Modified: ' ),
+ getFormattedDate( item.date ?? null )
+ ),
+ {
+ span: ,
+ time: ,
+ }
+ );
+ }
+
+ const isScheduled = item.status === 'future';
+ if ( isScheduled ) {
+ return createInterpolateElement(
+ sprintf(
+ /* translators: %s: page creation date */
+ __( 'Scheduled: ' ),
+ getFormattedDate( item.date ?? null )
+ ),
+ {
+ span: ,
+ time: ,
+ }
+ );
+ }
+
+ const isPublished = item.status === 'publish';
+ if ( isPublished ) {
+ return createInterpolateElement(
+ sprintf(
+ /* translators: %s: page creation time */
+ __( 'Published: ' ),
+ getFormattedDate( item.date ?? null )
+ ),
+ {
+ span: ,
+ time: ,
+ }
+ );
+ }
+
+ // Pending posts show the modified date if it's newer.
+ const dateToDisplay =
+ getDate( item.modified ?? null ) > getDate( item.date ?? null )
+ ? item.modified
+ : item.date;
+
+ const isPending = item.status === 'pending';
+ if ( isPending ) {
+ return createInterpolateElement(
+ sprintf(
+ /* translators: %s: page creation or modification date. */
+ __( 'Modified: ' ),
+ getFormattedDate( dateToDisplay ?? null )
+ ),
+ {
+ span: ,
+ time: ,
+ }
+ );
+ }
+
+ // Unknow status.
+ return ;
+};
+
+export default DateView;
diff --git a/packages/fields/src/fields/date/index.tsx b/packages/fields/src/fields/date/index.tsx
new file mode 100644
index 00000000000000..49bd0807de6691
--- /dev/null
+++ b/packages/fields/src/fields/date/index.tsx
@@ -0,0 +1,23 @@
+/**
+ * WordPress dependencies
+ */
+import type { Field } from '@wordpress/dataviews';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import type { BasePost } from '../../types';
+import DateView from './date-view';
+
+const dateField: Field< BasePost > = {
+ id: 'date',
+ type: 'datetime',
+ label: __( 'Date' ),
+ render: DateView,
+};
+
+/**
+ * Date field for BasePost.
+ */
+export default dateField;
diff --git a/packages/fields/src/fields/index.ts b/packages/fields/src/fields/index.ts
index fba34eb2388a39..36e064006232bb 100644
--- a/packages/fields/src/fields/index.ts
+++ b/packages/fields/src/fields/index.ts
@@ -6,3 +6,4 @@ export { default as parentField } from './parent';
export { default as passwordField } from './password';
export { default as statusField } from './status';
export { default as commentStatusField } from './comment-status';
+export { default as dateField } from './date';
diff --git a/packages/fields/src/types.ts b/packages/fields/src/types.ts
index d895195cb40af7..71831b6aab180c 100644
--- a/packages/fields/src/types.ts
+++ b/packages/fields/src/types.ts
@@ -1,5 +1,5 @@
type PostStatus =
- | 'published'
+ | 'publish'
| 'draft'
| 'pending'
| 'private'
@@ -37,6 +37,8 @@ export interface BasePost extends CommonPost {
link?: string;
slug?: string;
permalink_template?: string;
+ date?: string;
+ modified?: string;
}
export interface Template extends CommonPost {
diff --git a/packages/fields/tsconfig.json b/packages/fields/tsconfig.json
index c553ee023993d0..5c4b91e88f895a 100644
--- a/packages/fields/tsconfig.json
+++ b/packages/fields/tsconfig.json
@@ -8,24 +8,25 @@
},
"references": [
{ "path": "../api-fetch" },
+ { "path": "../blob" },
{ "path": "../components" },
{ "path": "../compose" },
+ { "path": "../core-data" },
{ "path": "../data" },
+ { "path": "../dataviews" },
+ { "path": "../date" },
{ "path": "../element" },
+ { "path": "../hooks" },
+ { "path": "../html-entities" },
{ "path": "../i18n" },
{ "path": "../icons" },
+ { "path": "../media-utils" },
+ { "path": "../notices" },
{ "path": "../primitives" },
{ "path": "../private-apis" },
- { "path": "../warning" },
+ { "path": "../router" },
{ "path": "../url" },
- { "path": "../notices" },
- { "path": "../dataviews" },
- { "path": "../blob" },
- { "path": "../core-data" },
- { "path": "../hooks" },
- { "path": "../html-entities" },
- { "path": "../media-utils" },
- { "path": "../router" }
+ { "path": "../warning" }
],
"include": [ "src" ]
}