diff --git a/src/components/DateTimePicker/CustomInput.js b/src/components/DateTimePicker/CustomInput.js index f6f4d6018b..84ecbf31be 100644 --- a/src/components/DateTimePicker/CustomInput.js +++ b/src/components/DateTimePicker/CustomInput.js @@ -1,28 +1,54 @@ import React, { PureComponent } from 'react' -import { func } from 'prop-types' +import { func, oneOf } from 'prop-types' import { COMPONENT_TYPE, SIZES_TYPE } from '../../utils' import { IconWrapper } from '../Field/styles' +import { Icon } from '../Icon' import * as S from './styles' // eslint-disable-next-line react/prefer-stateless-function export class CustomInput extends PureComponent { render() { - const { handleBlur, handleFocus, icon, inputRef, size, ...rest } = this.props + const { + focused, + handleBlur, + handleFocus, + icon, + iconPlacement, + inputRef, + size, + ...rest + } = this.props return ( - - {icon && {icon}} + + {icon && ( + + {icon} + + )} + + + ) } } CustomInput.propTypes = { + focused: oneOf('date', 'time', null), handleBlur: func, handleFocus: func, icon: COMPONENT_TYPE, + iconPlacement: oneOf('right', 'left'), inputRef: func, size: SIZES_TYPE } diff --git a/src/components/DateTimePicker/doc.mdx b/src/components/DateTimePicker/doc.mdx index 751a7e1c0f..c95f438da4 100644 --- a/src/components/DateTimePicker/doc.mdx +++ b/src/components/DateTimePicker/doc.mdx @@ -46,6 +46,7 @@ _Note_: Pass a value of `null` if you don't want the default value of `Date.now( } + timeIconPlacement="right" value={Date.now()} onChange={date => console.log('date: ', date)} /> diff --git a/src/components/DateTimePicker/index.js b/src/components/DateTimePicker/index.js index 4bdad4e6b6..ab219d59de 100644 --- a/src/components/DateTimePicker/index.js +++ b/src/components/DateTimePicker/index.js @@ -1,6 +1,6 @@ import React, { forwardRef, useEffect, useState } from 'react' import { createPortal } from 'react-dom' -import { bool, func, number, object, oneOfType, string } from 'prop-types' +import { bool, func, number, object, oneOf, oneOfType, string } from 'prop-types' import { COMPONENT_TYPE, SIZES_TYPE } from '../../utils' @@ -22,11 +22,13 @@ export const DateTimePicker = forwardRef( { value = new Date(), dateIcon, + dateIconPlacement = 'left', datePickerOnly, datePickerProps = {}, onChange, size = 'lg', timeIcon, + timeIconPlacement = 'left', timePickerOnly, timePickerProps = {}, ...rest @@ -38,6 +40,9 @@ export const DateTimePicker = forwardRef( const timePickerDateFormat = timePickerProps.dateFormat || DEFAULT_TIME_FORMAT const timeIntervals = timePickerProps.timeIntervals || DEFAULT_INTERVAL + const [focused, setFocused] = useState( + (datePickerProps.autoFocus && 'date') || (timePickerProps.autoFocus && 'time') || null + ) const [date, setDate] = useState(null) const formatDate = date => getDate(date, timeIntervals) @@ -61,6 +66,7 @@ export const DateTimePicker = forwardRef( const handleFocus = (kind, e) => { let onDatePickerFocus = datePickerProps.onFocus let onTimePickerFocus = timePickerProps.onFocus + setFocused(kind) kind === 'date' && onDatePickerFocus && onDatePickerFocus(e) kind === 'time' && onTimePickerFocus && onTimePickerFocus(e) } @@ -68,6 +74,7 @@ export const DateTimePicker = forwardRef( const handleBlur = (kind, e) => { let onDatePickerBlur = datePickerProps.onBlur let onTimePickerBlur = timePickerProps.onBlur + setFocused(null) kind === 'date' && onDatePickerBlur && onDatePickerBlur(e) kind === 'time' && onTimePickerBlur && onTimePickerBlur(e) } @@ -99,9 +106,11 @@ export const DateTimePicker = forwardRef( className="date-picker" customInput={ handleBlur('date', e)} handleFocus={e => handleFocus('date', e)} icon={dateIcon} + iconPlacement={dateIconPlacement} inputRef={timePickerOnly ? null : ref} ref={ref} size={size} @@ -122,9 +131,11 @@ export const DateTimePicker = forwardRef( className="time-picker" customInput={ handleBlur('date', e)} handleFocus={e => handleFocus('date', e)} icon={timeIcon} + iconPlacement={timeIconPlacement} inputRef={timePickerOnly ? ref : null} size={size} /> @@ -150,11 +161,13 @@ DateTimePicker.displayName = 'DateTimePicker' DateTimePicker.propTypes = { dateIcon: COMPONENT_TYPE, + dateIconPlacement: oneOf('right', 'left'), datePickerOnly: bool, datePickerProps: object, onChange: func, size: SIZES_TYPE, timeIcon: COMPONENT_TYPE, + timeIconPlacement: oneOf('right', 'left'), timePickerOnly: bool, timePickerProps: object, value: oneOfType([number, object, string]).isRequired diff --git a/src/components/DateTimePicker/styles.js b/src/components/DateTimePicker/styles.js index c8be41bc36..d99190d5e5 100644 --- a/src/components/DateTimePicker/styles.js +++ b/src/components/DateTimePicker/styles.js @@ -4,6 +4,8 @@ import ReactDatePicker from 'react-datepicker' import { componentSystem, wrapperSystem } from '../../utils/' import { fieldStyles } from '../../common/styles/form' +import { IconWrapper } from '../Field/styles' +import { Icon } from '../Icon/styles' // Only require CSS on client if (typeof window !== 'undefined') { @@ -20,6 +22,10 @@ const focusStyles = css` &:focus { position: relative; z-index: 1; + + ~ ${IconWrapper}:last-child ${Icon} { + transform: rotate3d(0, 0, 1, 180deg); + } } ` @@ -65,11 +71,41 @@ export const DateTimePicker = styled.div( ` ) -export const CustomInput = styled.div(({ icon, size, ...rest }) => { +const iconPlacementStyles = (placement, size, rest) => { + if (placement === 'right') { + return css` + ${IconWrapper}:not(:last-child) { + right: ${th(`fields.sizes.${size}.height`)(rest)}; + width: ${`calc(0.5 * ${th(`fields.sizes.${size}.height`)(rest)})`}; + justify-content: flex-end; + } + + ${DatePicker}, ${TimePicker} { + padding-right: ${`calc(1.5 * ${th(`fields.sizes.${size}.height`)(rest)})`}; + } + ` + } + if (placement === 'left') { + return css` + ${DatePicker}, ${TimePicker} { + padding-left: ${th(`fields.sizes.${size}.height`)(rest)}; + } + ` + } +} + +export const CustomInput = styled.div(({ focused, icon, iconPlacement, size, ...rest }) => { return css` position: relative; + ${icon && iconPlacementStyles(iconPlacement, size, rest)}; + ${DatePicker}, ${TimePicker} { - padding-left: ${icon ? th(`fields.sizes.${size}.height`)(rest) : null}; + padding-right: ${th(`fields.sizes.${size}.height`)(rest)}; + } + + ${Icon} { + transition: medium; + z-index: ${focused ? 2 : null}; } ` }) @@ -90,6 +126,14 @@ export const Popper = styled.div` font-weight: medium; } + .react-datepicker__year-read-view--down-arrow, + .react-datepicker__month-read-view--down-arrow, + .react-datepicker__month-year-read-view--down-arrow { + top: 3px; + padding: sm 0; + transform: scale(0.5); + } + .react-datepicker__time-container { width: 100px; .react-datepicker__time .react-datepicker__time-box {