From b87608bc87ebc2f824a3457866c38cd48136d943 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 25 May 2022 16:24:05 +1000 Subject: [PATCH] Update design of DateTimePicker and convert to Emotion - Updates the design of DateTimePicker, DatePicker and TimePicker. - Converts CSS in DateTimePicker, DatePicker and TimePicker to Emotion where it makes sense to do so. - Allows removal of Reset button and Help functionality from DateTimePicker. - Adds PublishDateTimePicker to block-editor. This exposes a specialised DateTimePicker that is good for choosing a post publish date. --- packages/block-editor/src/components/index.js | 1 + .../publish-date-time-picker/README.md | 54 +++ .../publish-date-time-picker/index.js | 50 +++ .../publish-date-time-picker/style.scss | 20 + packages/block-editor/src/style.scss | 1 + packages/block-library/src/post-date/edit.js | 7 +- packages/components/src/date-time/README.md | 16 + .../src/date-time/date-time/index.tsx | 213 ++++----- .../src/date-time/date-time/styles.ts | 8 + .../src/date-time/{ => date}/datepicker.scss | 0 .../components/src/date-time/date/index.tsx | 41 +- .../components/src/date-time/date/style.scss | 75 ++++ .../components/src/date-time/date/styles.ts | 55 +++ .../stories/{index.tsx => date-time.tsx} | 2 +- packages/components/src/date-time/style.scss | 263 +----------- .../components/src/date-time/time/index.tsx | 406 ++++++++++-------- .../components/src/date-time/time/styles.ts | 119 +++++ .../src/date-time/time/test/index.tsx | 8 +- .../src/date-time/time/timezone.tsx | 5 +- packages/components/src/date-time/types.ts | 34 +- .../components/sidebar/post-schedule/index.js | 4 +- .../sidebar/post-schedule/style.scss | 4 +- .../src/components/post-schedule/index.js | 19 +- 23 files changed, 800 insertions(+), 605 deletions(-) create mode 100644 packages/block-editor/src/components/publish-date-time-picker/README.md create mode 100644 packages/block-editor/src/components/publish-date-time-picker/index.js create mode 100644 packages/block-editor/src/components/publish-date-time-picker/style.scss create mode 100644 packages/components/src/date-time/date-time/styles.ts rename packages/components/src/date-time/{ => date}/datepicker.scss (100%) create mode 100644 packages/components/src/date-time/date/style.scss create mode 100644 packages/components/src/date-time/date/styles.ts rename packages/components/src/date-time/stories/{index.tsx => date-time.tsx} (97%) create mode 100644 packages/components/src/date-time/time/styles.ts diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 43448fdae43b7d..2330a35e338cc6 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -147,6 +147,7 @@ export { default as useBlockDisplayInformation } from './use-block-display-infor export { default as __unstableIframe } from './iframe'; export { default as __experimentalUseNoRecursiveRenders } from './use-no-recursive-renders'; export { default as __experimentalBlockPatternsList } from './block-patterns-list'; +export { default as __experimentalPublishDateTimePicker } from './publish-date-time-picker'; /* * State Related Components diff --git a/packages/block-editor/src/components/publish-date-time-picker/README.md b/packages/block-editor/src/components/publish-date-time-picker/README.md new file mode 100644 index 00000000000000..7c1ba8ceada87b --- /dev/null +++ b/packages/block-editor/src/components/publish-date-time-picker/README.md @@ -0,0 +1,54 @@ +# `PublishDateTimePicker` + +`` is a component used to select the date and time that +a post will be published. It wraps the `` component found in +`@wordpress/components` and adds additional post-specific controls. + +See [the documentation for +DateTimePicker](https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/date-time) +for more information. + +## Usage + +```jsx +import { Dropdown, Button } from '@wordpress/components'; +import { __experimentalPublishDateTimePicker as PublishDateTimePicker } from '@wordpress/block-editor'; +import { useState } from '@wordpress/element'; + +const MyDateTimePicker = () => { + const [ date, setDate ] = useState( new Date() ); + + return ( + ( + + ) } + renderContent={ ( { onClose } ) => ( + setDate( newDate ) } + onClose={ onClose } + /> + ) } + /> + ); +}; +``` + +## Props + +`PublishDateTimePicker` supports all of the props that +[`DateTimePicker`](https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/date-time#Props) +supports, plus: + +### onClose + +Called when the user presses the close button. + +- Type: `Function` +- Required: Yes diff --git a/packages/block-editor/src/components/publish-date-time-picker/index.js b/packages/block-editor/src/components/publish-date-time-picker/index.js new file mode 100644 index 00000000000000..7244ed3a5c35f4 --- /dev/null +++ b/packages/block-editor/src/components/publish-date-time-picker/index.js @@ -0,0 +1,50 @@ +/** + * WordPress dependencies + */ +import { + DateTimePicker, + __experimentalHStack as HStack, + __experimentalSpacer as Spacer, + Button, +} from '@wordpress/components'; +import { closeSmall } from '@wordpress/icons'; +import { __ } from '@wordpress/i18n'; +import { forwardRef } from '@wordpress/element'; + +function PublishDateTimePicker( + { onClose, onChange, ...additionalProps }, + ref +) { + return ( +
+ { /* TODO: This header is essentially the same as the one in . DRY it up. */ } + +

+ { __( 'Publish' ) } +

+ + +
+ ); +} + +export default forwardRef( PublishDateTimePicker ); diff --git a/packages/block-editor/src/components/publish-date-time-picker/style.scss b/packages/block-editor/src/components/publish-date-time-picker/style.scss new file mode 100644 index 00000000000000..517700e2ca5c25 --- /dev/null +++ b/packages/block-editor/src/components/publish-date-time-picker/style.scss @@ -0,0 +1,20 @@ +.block-editor-publish-date-time-picker__header { + margin-bottom: 1em; +} + +.block-editor-publish-date-time-picker__heading { + font-size: $default-font-size; + margin: 0; +} + +.block-editor-publish-date-time-picker__reset { + height: $icon-size; + margin: 0; + text-decoration: underline; +} + +[class].block-editor-publish-date-time-picker__close { + height: $icon-size; + min-width: $icon-size; + padding: 0; +} diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 5f036b4d9b264d..56ae7fb6c24d17 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -42,6 +42,7 @@ @import "./components/media-placeholder/style.scss"; @import "./components/multi-selection-inspector/style.scss"; @import "./components/plain-text/style.scss"; +@import "./components/publish-date-time-picker/style.scss"; @import "./components/responsive-block-control/style.scss"; @import "./components/rich-text/style.scss"; @import "./components/skip-to-selected-block/style.scss"; diff --git a/packages/block-library/src/post-date/edit.js b/packages/block-library/src/post-date/edit.js index da33f65418116c..dd7bd46852f7ec 100644 --- a/packages/block-library/src/post-date/edit.js +++ b/packages/block-library/src/post-date/edit.js @@ -18,13 +18,13 @@ import { InspectorControls, useBlockProps, __experimentalDateFormatPicker as DateFormatPicker, + __experimentalPublishDateTimePicker as PublishDateTimePicker, } from '@wordpress/block-editor'; import { Dropdown, ToolbarGroup, ToolbarButton, ToggleControl, - DateTimePicker, PanelBody, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; @@ -101,13 +101,14 @@ export default function PostDateEdit( { ( - ( + ) } renderToggle={ ( { isOpen, onToggle } ) => { diff --git a/packages/components/src/date-time/README.md b/packages/components/src/date-time/README.md index 6c2cddd62841ad..6784af6c15ceb0 100644 --- a/packages/components/src/date-time/README.md +++ b/packages/components/src/date-time/README.md @@ -26,6 +26,8 @@ const MyDateTimePicker = () => { currentDate={ date } onChange={ ( newDate ) => setDate( newDate ) } is12Hour={ true } + __nextRemoveHelpButton + __nextRemoveResetButton /> ); }; @@ -74,3 +76,17 @@ List of events to show in the date picker. Each event will appear as a dot on th - Type: `Array` - Required: No + +### `__nextRemoveHelpButton`: `boolean` + +Start opting in to not displaying a Help button which will become the default in a future version. + +- Required: No +- Default: `false` + +### `__nextRemoveResetButton`: `boolean` + +Start opting in to not displaying a Reset button which will become the default in a future version. + +- Required: No +- Default: `false` diff --git a/packages/components/src/date-time/date-time/index.tsx b/packages/components/src/date-time/date-time/index.tsx index 724ce81c395b76..c7e0820c7cd1fe 100644 --- a/packages/components/src/date-time/date-time/index.tsx +++ b/packages/components/src/date-time/date-time/index.tsx @@ -1,9 +1,6 @@ /** * External dependencies */ -// Needed to initialise the default datepicker styles. -// See: https://github.com/airbnb/react-dates#initialize -import 'react-dates/initialize'; import { noop } from 'lodash'; import type { ForwardedRef } from 'react'; @@ -20,6 +17,10 @@ import Button from '../../button'; import { default as DatePicker } from '../date'; import { default as TimePicker } from '../time'; import type { DateTimePickerProps } from '../types'; +import { CalendarHelp } from './styles'; +import { HStack } from '../../h-stack'; +import { Heading } from '../../heading'; +import { Spacer } from '../../spacer'; export { DatePicker, TimePicker }; @@ -31,6 +32,8 @@ function UnforwardedDateTimePicker( onMonthPreviewed = noop, onChange, events, + __nextRemoveHelpButton = false, + __nextRemoveResetButton = false, }: DateTimePickerProps, ref: ForwardedRef< any > ) { @@ -61,110 +64,110 @@ function UnforwardedDateTimePicker( ) } { calendarHelpIsVisible && ( - <> -
-

{ __( 'Click to Select' ) }

-
    -
  • - { __( - 'Click the right or left arrows to select other months in the past or the future.' - ) } -
  • -
  • - { __( 'Click the desired day to select it.' ) } -
  • -
-

{ __( 'Navigating with a keyboard' ) }

-
    -
  • - - ↵ - - { - ' ' /* JSX removes whitespace, but a space is required for screen readers. */ - } - - { __( 'Select the date in focus.' ) } - -
  • -
  • - - ←/→ - - { - ' ' /* JSX removes whitespace, but a space is required for screen readers. */ - } - { __( - 'Move backward (left) or forward (right) by one day.' - ) } -
  • -
  • - - ↑/↓ - - { - ' ' /* JSX removes whitespace, but a space is required for screen readers. */ - } - { __( - 'Move backward (up) or forward (down) by one week.' - ) } -
  • -
  • - - { __( 'PgUp/PgDn' ) } - - { - ' ' /* JSX removes whitespace, but a space is required for screen readers. */ - } - { __( - 'Move backward (PgUp) or forward (PgDn) by one month.' - ) } -
  • -
  • - - { /* Translators: Home/End reffer to the 'Home' and 'End' buttons on the keyboard.*/ } - { __( 'Home/End' ) } - - { - ' ' /* JSX removes whitespace, but a space is required for screen readers. */ - } - { __( - 'Go to the first (Home) or last (End) day of a week.' - ) } -
  • -
-
- + + { __( 'Click to Select' ) } +
    +
  • + { __( + 'Click the right or left arrows to select other months in the past or the future.' + ) } +
  • +
  • { __( 'Click the desired day to select it.' ) }
  • +
+ + { __( 'Navigating with a keyboard' ) } + +
    +
  • + + ↵ + + { + ' ' /* JSX removes whitespace, but a space is required for screen readers. */ + } + { __( 'Select the date in focus.' ) } +
  • +
  • + + ←/→ + + { + ' ' /* JSX removes whitespace, but a space is required for screen readers. */ + } + { __( + 'Move backward (left) or forward (right) by one day.' + ) } +
  • +
  • + + ↑/↓ + + { + ' ' /* JSX removes whitespace, but a space is required for screen readers. */ + } + { __( + 'Move backward (up) or forward (down) by one week.' + ) } +
  • +
  • + + { __( 'PgUp/PgDn' ) } + + { + ' ' /* JSX removes whitespace, but a space is required for screen readers. */ + } + { __( + 'Move backward (PgUp) or forward (PgDn) by one month.' + ) } +
  • +
  • + + { /* Translators: Home/End reffer to the 'Home' and 'End' buttons on the keyboard.*/ } + { __( 'Home/End' ) } + + { + ' ' /* JSX removes whitespace, but a space is required for screen readers. */ + } + { __( + 'Go to the first (Home) or last (End) day of a week.' + ) } +
  • +
+
) } -
- { ! calendarHelpIsVisible && currentDate && ( - - ) } - -
+ { ! __nextRemoveResetButton && + ! calendarHelpIsVisible && + currentDate && ( + + ) } + + { ! __nextRemoveHelpButton && ( + + ) } + + ) } ); } diff --git a/packages/components/src/date-time/date-time/styles.ts b/packages/components/src/date-time/date-time/styles.ts new file mode 100644 index 00000000000000..8c5693213eabbe --- /dev/null +++ b/packages/components/src/date-time/date-time/styles.ts @@ -0,0 +1,8 @@ +/** + * External dependencies + */ +import styled from '@emotion/styled'; + +export const CalendarHelp = styled.div` + min-width: 260px; +`; diff --git a/packages/components/src/date-time/datepicker.scss b/packages/components/src/date-time/date/datepicker.scss similarity index 100% rename from packages/components/src/date-time/datepicker.scss rename to packages/components/src/date-time/date/datepicker.scss diff --git a/packages/components/src/date-time/date/index.tsx b/packages/components/src/date-time/date/index.tsx index df5441f634fa5b..0e583c6c5e150a 100644 --- a/packages/components/src/date-time/date/index.tsx +++ b/packages/components/src/date-time/date/index.tsx @@ -2,10 +2,11 @@ * External dependencies */ import moment from 'moment'; -import classnames from 'classnames'; import type { Moment } from 'moment'; import { noop } from 'lodash'; - +// Needed to initialise the default datepicker styles. +// See: https://github.com/airbnb/react-dates#initialize +import 'react-dates/initialize'; // `react-dates` doesn't tree-shake correctly, so we import from the individual // component here. import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerSingleDateController'; @@ -15,12 +16,14 @@ import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerS */ import { useEffect, useRef } from '@wordpress/element'; import { isRTL, _n, sprintf } from '@wordpress/i18n'; +import { arrowLeft, arrowRight } from '@wordpress/icons'; /** * Internal dependencies */ import { getMomentDate } from './utils'; import type { DatePickerDayProps, DatePickerProps } from '../types'; +import { Day, NavPrevButton, NavNextButton } from './styles'; const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss'; const ARIAL_LABEL_TIME_FORMAT = 'dddd, LL'; @@ -64,14 +67,14 @@ function DatePickerDay( { day, events = [] }: DatePickerDayProps ) { }, [ events.length ] ); return ( -
{ day.format( 'D' ) } -
+ ); } @@ -102,6 +105,7 @@ export function DatePicker( { onMonthPreviewed, }: DatePickerProps ) { const nodeRef = useRef< HTMLDivElement >( null ); + const onMonthPreviewedHandler = ( newMonthDate: Moment ) => { onMonthPreviewed?.( newMonthDate.toISOString() ); keepFocusInside(); @@ -175,6 +179,7 @@ export function DatePicker( { date={ momentDate } initialVisibleMonth={ null } daySize={ 30 } + horizontalMonthPadding={ 0 } focused hideKeyboardShortcutsPanel // This is a hack to force the calendar to update on month or year change @@ -200,6 +205,28 @@ export function DatePicker( { events={ getEventsPerDay( day ) } /> ) } + renderMonthElement={ ( { month } ) => ( + <> + { month.format( 'MMMM' ) }{ ' ' } + { month.format( 'YYYY' ) } + + ) } + renderNavPrevButton={ ( { ariaLabel, ...props } ) => ( + + ) } + renderNavNextButton={ ( { ariaLabel, ...props } ) => ( + + ) } onFocusChange={ noop } /> diff --git a/packages/components/src/date-time/date/style.scss b/packages/components/src/date-time/date/style.scss new file mode 100644 index 00000000000000..26b41d089a86a1 --- /dev/null +++ b/packages/components/src/date-time/date/style.scss @@ -0,0 +1,75 @@ +@import "./datepicker.scss"; + +// Styles that overrides the calendar styling provided by react-dates go here. +// Everything else goes in styles.ts. + +.components-datetime__date { + // + // Margin overrides + // + + // Remove the left and right margin from the calendar by setting all the + // containers' widths to 100%. This means that the slide left / slide right + // animation won't work but we don't want that, anyway. + + .CalendarMonthGrid__horizontal, + .DayPicker_weekHeader_li { + transform: none !important; // Override inline style. + width: 100% !important; // Override inline style. + } + + .CalendarMonthGrid_month__horizontal, + .CalendarMonth_table, + .DayPicker_weekHeader { + width: 100%; + } + + .DayPicker_weekHeaders__horizontal { + margin: 0; + } + + .DayPicker_weekHeader_ul { + display: flex; + } + + // + // Theming + // + + .DayPicker_weekHeader { + top: 50px; + } + + .CalendarMonth_caption { + font-size: $default-font-size; + } + + .CalendarMonth_table { + border-collapse: separate; + border-spacing: 2px; + } + + .CalendarDay { + border: none; + font-size: $default-font-size; + border-radius: $radius-round; + + &:focus { + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 #{ $border-width-focus + $border-width } $white; + outline: 2px solid transparent; // Shown in Windows 10 high contrast mode. + } + } + + .CalendarDay__selected { + background: var(--wp-admin-theme-color); + border: 2px solid transparent; // This indicates selection in Windows 10 high contrast mode. + + &:hover { + background: var(--wp-admin-theme-color-darker-20); + } + + &:focus { + box-shadow: inset 0 0 0 $border-width $white; + } + } +} diff --git a/packages/components/src/date-time/date/styles.ts b/packages/components/src/date-time/date/styles.ts new file mode 100644 index 00000000000000..e80229a3050b4c --- /dev/null +++ b/packages/components/src/date-time/date/styles.ts @@ -0,0 +1,55 @@ +/** + * External dependencies + */ +import styled from '@emotion/styled'; +import { css } from '@emotion/react'; + +/** + * Internal dependencies + */ +import Button from '../../button'; +import { COLORS } from '../../utils'; +import { VStack } from '../../v-stack'; + +// Styles that overrides the calendar styling provided by react-dates go in +// style.scss. Everything else goes here. + +export const Day = styled( VStack )< { hasEvents: boolean } >` + height: 100%; + position: relative; + + ${ ( props ) => + props.hasEvents && + ` + ::before { + background: var(--wp-admin-theme-color); + border-radius: 2px; + bottom: 0; + content: " "; + height: 4px; + left: 50%; + margin-left: -2px; + position: absolute; + width: 4px; + + .CalendarDay__selected & { + background: ${ COLORS.white }; + } + } + ` } +`; + +const baseNavButton = css` + position: absolute; + top: 15px; +`; + +export const NavPrevButton = styled( Button )` + ${ baseNavButton } + left: 0; +`; + +export const NavNextButton = styled( Button )` + ${ baseNavButton } + right: 0; +`; diff --git a/packages/components/src/date-time/stories/index.tsx b/packages/components/src/date-time/stories/date-time.tsx similarity index 97% rename from packages/components/src/date-time/stories/index.tsx rename to packages/components/src/date-time/stories/date-time.tsx index fb126edb81f4e4..bea4028e7fb567 100644 --- a/packages/components/src/date-time/stories/index.tsx +++ b/packages/components/src/date-time/stories/date-time.tsx @@ -11,7 +11,7 @@ import { useState, useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import DateTimePicker from '..'; +import DateTimePicker from '../date-time'; import { daysFromNow, isWeekend } from './utils'; const meta: ComponentMeta< typeof DateTimePicker > = { diff --git a/packages/components/src/date-time/style.scss b/packages/components/src/date-time/style.scss index 636f7851218798..9e059d0d5be6d3 100644 --- a/packages/components/src/date-time/style.scss +++ b/packages/components/src/date-time/style.scss @@ -1,262 +1 @@ -@import "./datepicker"; - -.components-datetime { - // This padding is leveraged when the component is used alone, - // usually inside popovers. - padding: $grid-unit-20; - - // This rule removes the padding when used inside a panel. - .components-panel__body & { - padding: 0; - } - - .components-datetime__calendar-help { - padding: $grid-unit-20; - min-width: 260px; - - h4 { - margin: 0; - } - } - - .components-datetime__buttons { - display: flex; - justify-content: space-between; - } - - .components-datetime__date-help-toggle { - display: block; - margin-left: auto; - } - - fieldset { - border: 0; - padding: 0; - margin: 0; - } - - select, - input { - @include input-style__neutral(); - } - - // Override inherited conflicting styles to be consistent. - select, - input[type="number"], - .components-button { - height: 30px; - margin-top: 0; - margin-bottom: 0; - } - - .components-button:focus { - z-index: z-index(".components-button {:focus or .is-primary}"); - } -} - -.components-datetime__date { - min-height: 236px; - border-top: 1px solid $gray-300; - - // Override external DatePicker styles. - .DayPickerNavigation_leftButton__horizontalDefault { - /*!rtl:begin:ignore*/ - left: 13px; - /*!rtl:end:ignore*/ - } - - .CalendarMonth_caption { - font-size: $default-font-size; - } - - // Seperate borders so that border respect border radius - .CalendarMonth_table { - border-collapse: separate; - border-spacing: 2px; - } - - .CalendarDay { - font-size: $default-font-size; - border: none; - border-radius: $radius-round; - text-align: center; - - &:focus { - box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 #{ $border-width-focus + $border-width } $white; - outline: 2px solid transparent; // Shown in Windows 10 high contrast mode. - } - } - - .CalendarDay__selected { - background: var(--wp-admin-theme-color); - border: 2px solid transparent; // This indicates selection in Windows 10 high contrast mode. - - &:hover { - background: var(--wp-admin-theme-color-darker-20); - } - - &:focus { - box-shadow: inset 0 0 0 $border-width $white; - } - } - - .DayPickerNavigation_button__horizontalDefault { - padding: 2px 8px; - top: 20px; - - &:focus { - @include input-style__focus(); - } - } - - .DayPicker_weekHeader { - top: 50px; - .DayPicker_weekHeader_ul { - margin: 1px; - padding-left: 0; - padding-right: 0; - } - } - - &.is-description-visible .DayPicker { - visibility: hidden; - } -} - -.components-datetime__date .CalendarDay .components-datetime__date__day { - height: 100%; - display: flex; - justify-content: center; - align-content: center; - flex-direction: column; - position: relative; - - &.has-events::before { - content: " "; - width: 4px; - height: 4px; - border-radius: 2px; - position: absolute; - left: 50%; - margin-left: -2px; - bottom: 0; - background-color: $white; - } -} - -.components-datetime__date .CalendarDay:not(.CalendarDay__selected) .components-datetime__date__day.has-events::before { - background: var(--wp-admin-theme-color); -} - -.components-datetime__time { - padding-bottom: $grid-unit-20; - - fieldset { - position: relative; - margin-bottom: 0.5em; - } - - fieldset + fieldset { - margin-bottom: 0; - } - - .components-datetime__time-field-am-pm fieldset { - margin-top: 0; - } - - .components-datetime__time-wrapper { - display: flex; - - .components-datetime__time-separator { - display: inline-block; - padding: 0 3px 0 0; - } - - .components-datetime__time-field { - - &-time { - /*rtl:ignore*/ - direction: ltr; - } - - select { - margin-right: $grid-unit-05; - - &:focus { - position: relative; - z-index: 1; - } - } - - input[type="number"] { - padding: 2px; - margin-right: $grid-unit-05; - text-align: center; - -moz-appearance: textfield; - - &:focus { - position: relative; - z-index: 1; - } - - &::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; - } - } - } - } - - // Makes the month appear before the day if time format uses AM/PM - // We are assuming MM-DD-YYY correlates with AM/PM - &.is-12-hour { - .components-datetime__time-field-day input { - margin: 0 -$grid-unit-05 0 0 !important; - border-radius: $radius-block-ui 0 0 $radius-block-ui !important; - } - .components-datetime__time-field-year input { - border-radius: 0 $radius-block-ui $radius-block-ui 0 !important; - } - } -} - -.components-datetime__timezone { - line-height: 30px; - margin-left: $grid-unit-05; - text-decoration: underline dotted; -} - -.components-datetime__time-legend { - font-weight: 600; - margin-top: 0.5em; - - &.invisible { - position: absolute; - top: -999em; - left: -999em; - } -} - -.components-datetime__time-field-integer-field { - font-family: inherit; -} - -.components-datetime__time-field-hours-input, -.components-datetime__time-field-minutes-input, -.components-datetime__time-field-day-input { - width: 35px; -} - -.components-datetime__time-field-year-input { - width: 55px; -} - -.components-datetime__time-field-month-select { - max-width: 145px; -} - -// Hack to center the datepicker component within the popover. -// It sets its own styles so centering is tricky. -.components-popover .components-datetime__date { - padding-left: $grid-unit-05; -} +@import "./date/style.scss"; diff --git a/packages/components/src/date-time/time/index.tsx b/packages/components/src/date-time/time/index.tsx index 4a7b703192321b..9c7bdb9f08ce33 100644 --- a/packages/components/src/date-time/time/index.tsx +++ b/packages/components/src/date-time/time/index.tsx @@ -1,21 +1,12 @@ /** * External dependencies */ -import classnames from 'classnames'; -import { isInteger } from 'lodash'; import moment from 'moment'; -import type { FocusEvent } from 'react'; -import type { Moment } from 'moment'; /** * WordPress dependencies */ -import { - createElement, - useState, - useMemo, - useEffect, -} from '@wordpress/element'; +import { useState, useMemo, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** @@ -24,11 +15,30 @@ import { __ } from '@wordpress/i18n'; import Button from '../../button'; import ButtonGroup from '../../button-group'; import TimeZone from './timezone'; -import type { WordPressComponentProps } from '../../ui/context'; -import type { - UpdateOnBlurAsIntegerFieldProps, - TimePickerProps, -} from '../types'; +import type { TimePickerProps } from '../types'; +import { + Wrapper, + Fieldset, + Legend, + HoursInput, + TimeSeparator, + MinutesInput, + MonthSelectWrapper, + MonthSelect, + DayInput, + YearInput, + TimeWrapper, +} from './styles'; +import { HStack } from '../../h-stack'; +import { Spacer } from '../../spacer'; +import type { InputChangeCallback } from '../../input-control/types'; +import type { InputState } from '../../input-control/reducer/state'; +import { + COMMIT, + InputAction, + PRESS_DOWN, + PRESS_UP, +} from '../../input-control/reducer/actions'; const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss'; @@ -37,50 +47,28 @@ function from12hTo24h( hours: number, isPm: boolean ) { } /** - * A shared component to parse, validate, and handle remounting of the - * underlying form field element like and