From bf9093e9af5a0cde8e0362402db4422ab3c1ffea Mon Sep 17 00:00:00 2001 From: sarthaknagoshe2002 Date: Mon, 9 Dec 2024 20:18:45 +0530 Subject: [PATCH 1/6] feat: Introduce Inline Time Format for Machine-Readable Dates and Time --- package-lock.json | 13 ++- packages/format-library/package.json | 3 +- .../format-library/src/default-formats.js | 2 + packages/format-library/src/time/index.js | 98 +++++++++++++++++++ 4 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 packages/format-library/src/time/index.js diff --git a/package-lock.json b/package-lock.json index 1fc9131a33c8c3..20dc65f7ed872c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34395,6 +34395,16 @@ "signal-exit": "^3.0.2" } }, + "node_modules/locutus": { + "version": "2.0.32", + "resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.32.tgz", + "integrity": "sha512-fr7OCpbE4xeefhHqfh6hM2/l9ZB3XvClHgtgFnQNImrM/nqL950o6FO98vmUH8GysfQRCcyBYtZ4C8GcY52Edw==", + "license": "MIT", + "engines": { + "node": ">= 10", + "yarn": ">= 1" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -54764,7 +54774,8 @@ "@wordpress/icons": "*", "@wordpress/private-apis": "*", "@wordpress/rich-text": "*", - "@wordpress/url": "*" + "@wordpress/url": "*", + "locutus": "2.0.32" }, "engines": { "node": ">=18.12.0", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index ee1dd8efd1fe95..d23987579b6081 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -39,7 +39,8 @@ "@wordpress/icons": "*", "@wordpress/private-apis": "*", "@wordpress/rich-text": "*", - "@wordpress/url": "*" + "@wordpress/url": "*", + "locutus": "2.0.32" }, "peerDependencies": { "react": "^18.0.0", diff --git a/packages/format-library/src/default-formats.js b/packages/format-library/src/default-formats.js index 3ccfc92cb40c18..0c9bfa4c9adece 100644 --- a/packages/format-library/src/default-formats.js +++ b/packages/format-library/src/default-formats.js @@ -9,6 +9,7 @@ import { link } from './link'; import { strikethrough } from './strikethrough'; import { underline } from './underline'; import { textColor } from './text-color'; +import { time } from './time'; import { subscript } from './subscript'; import { superscript } from './superscript'; import { keyboard } from './keyboard'; @@ -25,6 +26,7 @@ export default [ strikethrough, underline, textColor, + time, subscript, superscript, keyboard, diff --git a/packages/format-library/src/time/index.js b/packages/format-library/src/time/index.js new file mode 100644 index 00000000000000..8bf51d54ccf4a9 --- /dev/null +++ b/packages/format-library/src/time/index.js @@ -0,0 +1,98 @@ +/** + * External dependencies + */ +import { gmdate, strtotime } from 'locutus/php/datetime'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { toggleFormat } from '@wordpress/rich-text'; +import { + RichTextToolbarButton, + RichTextShortcut, +} from '@wordpress/block-editor'; +import { postDate as icon } from '@wordpress/icons'; + +const name = 'core/time'; +const title = __( 'Time' ); + +export const time = { + name, + title, + tagName: 'time', + className: null, + attributes: { + datetime: 'datetime', + }, + edit( { isActive, value, onChange, onFocus } ) { + function onClick() { + const dateDescription = value.text + .slice( value.start, value.end ) + .trim(); + + // Exit early if no selection or format is already active + if ( ! dateDescription || isActive ) { + onChange( + toggleFormat( value, { + type: name, + } ) + ); + return; + } + + // Clean up the date string + const dateCleaned = dateDescription + .replace( 'at ', '' ) // Remove "at" + .replace( 'UTC', 'GMT' ); // Replace "UTC" with "GMT" + + // Parse the date string using strtotime + const timestamp = strtotime( dateCleaned ); + + // If parsing fails, toggle format without enhancement + if ( ! timestamp ) { + onChange( + toggleFormat( value, { + type: name, + } ) + ); + return; + } + + // Format the datetime attributes using gmdate + const datetime = gmdate( 'c', timestamp ); // ISO 8601 format + const datetimeISO = gmdate( 'Ymd\\THi', timestamp ); // Compact ISO format + + // Apply the format with parsed datetime attributes + onChange( + toggleFormat( value, { + type: name, + attributes: { + datetime, + 'data-iso': datetimeISO, + style: 'text-decoration: underline; text-decoration-style: dotted', + }, + } ) + ); + + onFocus(); + } + + return ( + <> + + + + ); + }, +}; From 34d96a6e4e75cce9548920c0a820cdf41f42cbeb Mon Sep 17 00:00:00 2001 From: sarthaknagoshe2002 Date: Tue, 10 Dec 2024 15:06:20 +0530 Subject: [PATCH 2/6] Fix: remove attributes, styling & shortcuts which are not required --- packages/format-library/package.json | 1 - packages/format-library/src/time/index.js | 13 +------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/format-library/package.json b/packages/format-library/package.json index d23987579b6081..ef92d022cefd4e 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -39,7 +39,6 @@ "@wordpress/icons": "*", "@wordpress/private-apis": "*", "@wordpress/rich-text": "*", - "@wordpress/url": "*", "locutus": "2.0.32" }, "peerDependencies": { diff --git a/packages/format-library/src/time/index.js b/packages/format-library/src/time/index.js index 8bf51d54ccf4a9..ad4b788d0a339b 100644 --- a/packages/format-library/src/time/index.js +++ b/packages/format-library/src/time/index.js @@ -8,10 +8,7 @@ import { gmdate, strtotime } from 'locutus/php/datetime'; */ import { __ } from '@wordpress/i18n'; import { toggleFormat } from '@wordpress/rich-text'; -import { - RichTextToolbarButton, - RichTextShortcut, -} from '@wordpress/block-editor'; +import { RichTextToolbarButton } from '@wordpress/block-editor'; import { postDate as icon } from '@wordpress/icons'; const name = 'core/time'; @@ -61,7 +58,6 @@ export const time = { // Format the datetime attributes using gmdate const datetime = gmdate( 'c', timestamp ); // ISO 8601 format - const datetimeISO = gmdate( 'Ymd\\THi', timestamp ); // Compact ISO format // Apply the format with parsed datetime attributes onChange( @@ -69,8 +65,6 @@ export const time = { type: name, attributes: { datetime, - 'data-iso': datetimeISO, - style: 'text-decoration: underline; text-decoration-style: dotted', }, } ) ); @@ -80,11 +74,6 @@ export const time = { return ( <> - Date: Tue, 10 Dec 2024 23:34:35 +0530 Subject: [PATCH 3/6] Fix: re-add dependancy --- packages/format-library/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/format-library/package.json b/packages/format-library/package.json index ef92d022cefd4e..d23987579b6081 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -39,6 +39,7 @@ "@wordpress/icons": "*", "@wordpress/private-apis": "*", "@wordpress/rich-text": "*", + "@wordpress/url": "*", "locutus": "2.0.32" }, "peerDependencies": { From 7775dcf5f705b17a37cb39ca7b9b0519a21e9b34 Mon Sep 17 00:00:00 2001 From: sarthaknagoshe2002 Date: Fri, 13 Dec 2024 02:47:32 +0530 Subject: [PATCH 4/6] Feat: revamped with picker component --- packages/format-library/package.json | 4 +- packages/format-library/src/style.scss | 1 + packages/format-library/src/time/index.js | 155 ++++++++++++-------- packages/format-library/src/time/style.scss | 6 + 4 files changed, 101 insertions(+), 65 deletions(-) create mode 100644 packages/format-library/src/time/style.scss diff --git a/packages/format-library/package.json b/packages/format-library/package.json index d23987579b6081..7defd1631d625c 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -33,14 +33,14 @@ "@wordpress/components": "*", "@wordpress/compose": "*", "@wordpress/data": "*", + "@wordpress/date": "*", "@wordpress/element": "*", "@wordpress/html-entities": "*", "@wordpress/i18n": "*", "@wordpress/icons": "*", "@wordpress/private-apis": "*", "@wordpress/rich-text": "*", - "@wordpress/url": "*", - "locutus": "2.0.32" + "@wordpress/url": "*" }, "peerDependencies": { "react": "^18.0.0", diff --git a/packages/format-library/src/style.scss b/packages/format-library/src/style.scss index e388258b4d5a0e..67523480b5b59d 100644 --- a/packages/format-library/src/style.scss +++ b/packages/format-library/src/style.scss @@ -2,3 +2,4 @@ @import "./link/style.scss"; @import "./text-color/style.scss"; @import "./language/style.scss"; +@import "./time/style.scss"; diff --git a/packages/format-library/src/time/index.js b/packages/format-library/src/time/index.js index ad4b788d0a339b..f97c95cbbd2bbf 100644 --- a/packages/format-library/src/time/index.js +++ b/packages/format-library/src/time/index.js @@ -1,15 +1,18 @@ -/** - * External dependencies - */ -import { gmdate, strtotime } from 'locutus/php/datetime'; - /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { toggleFormat } from '@wordpress/rich-text'; +import { + DateTimePicker, + Popover, + Button, + __experimentalHStack as HStack, +} from '@wordpress/components'; import { RichTextToolbarButton } from '@wordpress/block-editor'; +import { useState } from '@wordpress/element'; +import { removeFormat, applyFormat, useAnchor } from '@wordpress/rich-text'; import { postDate as icon } from '@wordpress/icons'; +import { dateI18n, getSettings } from '@wordpress/date'; const name = 'core/time'; const title = __( 'Time' ); @@ -19,69 +22,95 @@ export const time = { title, tagName: 'time', className: null, + edit: Edit, attributes: { datetime: 'datetime', }, - edit( { isActive, value, onChange, onFocus } ) { - function onClick() { - const dateDescription = value.text - .slice( value.start, value.end ) - .trim(); - - // Exit early if no selection or format is already active - if ( ! dateDescription || isActive ) { - onChange( - toggleFormat( value, { - type: name, - } ) - ); - return; - } - - // Clean up the date string - const dateCleaned = dateDescription - .replace( 'at ', '' ) // Remove "at" - .replace( 'UTC', 'GMT' ); // Replace "UTC" with "GMT" - - // Parse the date string using strtotime - const timestamp = strtotime( dateCleaned ); +}; - // If parsing fails, toggle format without enhancement - if ( ! timestamp ) { - onChange( - toggleFormat( value, { - type: name, - } ) - ); - return; - } +function Edit( { isActive, value, onChange, contentRef } ) { + const [ date, setDate ] = useState( new Date() ); + const [ isPopoverVisible, setIsPopoverVisible ] = useState( false ); + const togglePopover = () => setIsPopoverVisible( ( state ) => ! state ); + const dateTimeSettings = getSettings(); - // Format the datetime attributes using gmdate - const datetime = gmdate( 'c', timestamp ); // ISO 8601 format + const applyDate = () => { + const formattedDate = dateI18n( 'c', date ); + const attributes = { + datetime: formattedDate, + }; + onChange( + applyFormat( value, { + type: name, + attributes, + } ) + ); + setIsPopoverVisible( false ); + }; - // Apply the format with parsed datetime attributes - onChange( - toggleFormat( value, { - type: name, - attributes: { - datetime, - }, - } ) - ); + return ( + <> + { + if ( isActive ) { + onChange( removeFormat( value, name ) ); + } else { + togglePopover(); + } + } } + isActive={ isActive } + role="menuitemcheckbox" + /> + { isPopoverVisible && ( + + ) } + + ); +} - onFocus(); - } +function InlineDateUI( { + contentRef, + onClose, + onApply, + date, + onChangeDate, + dateTimeSettings, +} ) { + const popoverAnchor = useAnchor( { + editableContentElement: contentRef.current, + settings: time, + } ); - return ( - <> - + + +