diff --git a/components/date-time/README.md b/components/date-time/README.md new file mode 100644 index 00000000000000..c140a5fb4a654e --- /dev/null +++ b/components/date-time/README.md @@ -0,0 +1,66 @@ +DateTimePicker +======= + +DateTimePicker is a React component to render a calendar and clock for selecting a date and time. The calendar and clock components can be accessed individually using the `DatePicker` and `TimePicker` components respectively. + +## Usage + +Render a DateTimePicker. + +```jsx +import { DateTimePicker } from '@wordpress/components'; +import { settings } from '@wordpress/date'; + +function selectTime( date, onUpdateDate ) { + // To know if the current timezone is a 12 hour time with look for "a" in the time format. + // We also make sure this a is not escaped by a "/". + const is12HourTime = /a(?!\\)/i.test( + settings.formats.time + .toLowerCase() // Test only the lower case a + .replace( /\\\\/g, '' ) // Replace "//" with empty strings + .split( '' ).reverse().join( '' ) // Reverse the string and test for "a" not followed by a slash + ); + + return ( + + ); +} +``` + +## Props + +The component accepts the following props: + +### currentDate + +The current date and time at initialization. + +- Type: `string` +- Required: Yes + +### onChange + +The function called when a new date or time has been selected. It is passed the `currentDate` as an argument. + +- Type: `Function` +- Required: No +- Default: `noop` + +### locale + +The localization for the display of the date and time. + +- Type: `string` +- Required: No + +### is12Hour + +Whether the current timezone is a 12 hour time. + +- Type: `bool` +- Required: No diff --git a/components/date-time/date.js b/components/date-time/date.js new file mode 100644 index 00000000000000..3e32c0b938d571 --- /dev/null +++ b/components/date-time/date.js @@ -0,0 +1,16 @@ +/** + * External dependencies + */ +import ReactDatePicker from 'react-datepicker'; +import moment from 'moment'; + +export function DatePicker( { currentDate, onChange, ...args } ) { + const momentDate = currentDate ? moment( currentDate ) : moment(); + + return ; +} diff --git a/components/date-time/index.js b/components/date-time/index.js new file mode 100644 index 00000000000000..955120cd0e025c --- /dev/null +++ b/components/date-time/index.js @@ -0,0 +1,25 @@ +/** + * Internal dependencies + */ +import './style.scss'; +import { DatePicker } from './date'; +import { TimePicker } from './time'; + +export { DatePicker, TimePicker }; + +export function DateTimePicker( { currentDate, onChange, is12Hour, ...args } ) { + return [ + , + , + ]; +} diff --git a/components/date-time/style.scss b/components/date-time/style.scss new file mode 100644 index 00000000000000..a38470f9a5690d --- /dev/null +++ b/components/date-time/style.scss @@ -0,0 +1,35 @@ +@import '~react-datepicker/dist/react-datepicker'; + +.components-time-picker { + display: flex; + align-items: center; + justify-content: center; + margin-top: 10px; + + .components-time-picker__input { + width: 40px; + } + + .components-time-picker__separator { + padding: 0 4px; + } + + .components-time-picker__am-button { + margin-left: 8px; + margin-right: -1px; + border-radius: 3px 0 0 3px; + } + + .components-time-picker__pm-button { + margin-left: -1px; + border-radius: 0 3px 3px 0; + } + + .components-time-picker__am-button.is-toggled, + .components-time-picker__pm-button.is-toggled { + background: $light-gray-300; + border-color: $dark-gray-100; + box-shadow: inset 0 2px 5px -3px $dark-gray-500; + transform: translateY(1px); + } +} diff --git a/editor/components/post-schedule/clock.js b/components/date-time/time.js similarity index 77% rename from editor/components/post-schedule/clock.js rename to components/date-time/time.js index 060472fcbf9caa..99f2145dc3614a 100644 --- a/editor/components/post-schedule/clock.js +++ b/components/date-time/time.js @@ -2,14 +2,17 @@ * External dependencies */ import { isInteger } from 'lodash'; +import moment from 'moment'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Button } from '@wordpress/components'; +import Button from '../button'; + +export function TimePicker( { currentTime, onChange, is12Hour } ) { + const selected = currentTime ? moment( currentTime ) : moment(); -function PostScheduleClock( { is12Hour, selected, onChange } ) { const minutes = selected.format( 'mm' ); const am = selected.format( 'A' ); const hours = selected.format( is12Hour ? 'hh' : 'HH' ); @@ -56,30 +59,30 @@ function PostScheduleClock( { is12Hour, selected, onChange } ) { }; return ( -
+
- : + : { is12Hour &&
); } - -export default PostScheduleClock; diff --git a/components/index.js b/components/index.js index dc63a3eabae280..96ecef165b8add 100644 --- a/components/index.js +++ b/components/index.js @@ -4,6 +4,7 @@ export { default as Autocomplete } from './autocomplete'; export { default as Button } from './button'; export { default as ClipboardButton } from './clipboard-button'; export { default as Dashicon } from './dashicon'; +export { DateTimePicker, DatePicker, TimePicker } from './date-time'; export { default as DropZone } from './drop-zone'; export { default as DropZoneProvider } from './drop-zone/provider'; export { default as Dropdown } from './dropdown'; diff --git a/editor/components/post-schedule/index.js b/editor/components/post-schedule/index.js index 04f1e4826b0615..82d43b41c99bd7 100644 --- a/editor/components/post-schedule/index.js +++ b/editor/components/post-schedule/index.js @@ -2,8 +2,6 @@ * External dependencies */ import { connect } from 'react-redux'; -import DatePicker from 'react-datepicker'; -import moment from 'moment'; /** * WordPress dependencies @@ -13,19 +11,17 @@ import { settings } from '@wordpress/date'; /** * Internal dependencies */ -import './style.scss'; -import PostScheduleClock from './clock'; +import { DateTimePicker } from '@wordpress/components'; import { getEditedPostAttribute } from '../../store/selectors'; import { editPost } from '../../store/actions'; export function PostSchedule( { date, onUpdateDate } ) { - const momentDate = date ? moment( date ) : moment(); const handleChange = ( newDate ) => { onUpdateDate( newDate.format( 'YYYY-MM-DDTHH:mm:ss' ) ); }; - // To know if the current timezone is a 12 hour time with look for "a" in the time format - // We also make sure this a is not escaped by a "/" + // To know if the current timezone is a 12 hour time with look for "a" in the time format + // We also make sure this a is not escaped by a "/" const is12HourTime = /a(?!\\)/i.test( settings.formats.time .toLowerCase() // Test only the lower case a @@ -33,21 +29,15 @@ export function PostSchedule( { date, onUpdateDate } ) { .split( '' ).reverse().join( '' ) // Reverse the string and test for "a" not followed by a slash ); - return [ - , - , - ]; + /> + ); } export default connect( diff --git a/editor/components/post-schedule/style.scss b/editor/components/post-schedule/style.scss deleted file mode 100644 index 725265c6471e52..00000000000000 --- a/editor/components/post-schedule/style.scss +++ /dev/null @@ -1,35 +0,0 @@ -@import '~react-datepicker/dist/react-datepicker'; - -.editor-post-schedule__clock { - display: flex; - align-items: center; - justify-content: center; - margin-top: 10px; -} - -.editor-post-schedule__clock-input { - width: 40px; -} - -.editor-post-schedule__clock-separator { - padding: 0 4px; -} - -.wp-core-ui .editor-post-schedule__clock-am-button { - margin-left: 8px; - margin-right: -1px; - border-radius: 3px 0 0 3px; -} - -.wp-core-ui .editor-post-schedule__clock-pm-button { - margin-left: -1px; - border-radius: 0 3px 3px 0; -} - -.wp-core-ui .editor-post-schedule__clock-am-button.is-toggled, -.wp-core-ui .editor-post-schedule__clock-pm-button.is-toggled { - background: $light-gray-300; - border-color: $dark-gray-100; - box-shadow: inset 0 2px 5px -3px $dark-gray-500; - transform: translateY(1px); -} diff --git a/lib/client-assets.php b/lib/client-assets.php index 590b7355092005..026d416877fe26 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -141,7 +141,7 @@ function gutenberg_register_scripts_and_styles() { wp_register_script( 'wp-components', gutenberg_url( 'components/build/index.js' ), - array( 'wp-element', 'wp-i18n', 'wp-utils', 'wp-hooks', 'wp-api-request' ), + array( 'wp-element', 'wp-i18n', 'wp-utils', 'wp-hooks', 'wp-api-request', 'moment' ), filemtime( gutenberg_dir_path() . 'components/build/index.js' ) ); wp_register_script(