diff --git a/packages/components/src/components/date-picker/_date-picker.scss b/packages/components/src/components/date-picker/_date-picker.scss index df81cd7f8211..4df32e81fb5c 100644 --- a/packages/components/src/components/date-picker/_date-picker.scss +++ b/packages/components/src/components/date-picker/_date-picker.scss @@ -42,9 +42,19 @@ align-items: center; } - .#{$prefix}--date-picker.#{$prefix}--date-picker--simple { - .#{$prefix}--date-picker__input { - width: rem(120px); + .#{$prefix}--date-picker.#{$prefix}--date-picker--simple + .#{$prefix}--date-picker__input, + .#{$prefix}--date-picker.#{$prefix}--date-picker--simple .#{$prefix}--label { + width: rem(120px); + } + + .#{$prefix}--date-picker.#{$prefix}--date-picker--simple + .#{$prefix}--date-picker-input__wrapper--invalid, + .#{$prefix}--date-picker.#{$prefix}--date-picker--simple + .#{$prefix}--date-picker-input__wrapper--warn { + .#{$prefix}--date-picker__input, + ~ .#{$prefix}--form-requirement { + width: rem(152px); } } @@ -66,7 +76,6 @@ position: relative; display: block; - min-width: rem(144px); height: rem(40px); padding: 0 $carbon--spacing-05; color: $text-01; @@ -127,6 +136,24 @@ } } + .#{$prefix}--date-picker__icon--invalid, + .#{$prefix}--date-picker__icon--warn { + cursor: auto; + } + + .#{$prefix}--date-picker__icon--warn { + fill: $support-03; + } + + .#{$prefix}--date-picker__icon--warn path:first-of-type { + opacity: 1; + fill: $carbon__black-100; + } + + .#{$prefix}--date-picker__icon--invalid { + fill: $support-01; + } + .#{$prefix}--date-picker__icon ~ .#{$prefix}--date-picker__input { padding-right: $carbon--spacing-09; } diff --git a/packages/components/src/components/date-picker/_flatpickr.scss b/packages/components/src/components/date-picker/_flatpickr.scss index b03757a60242..8065036fa20f 100644 --- a/packages/components/src/components/date-picker/_flatpickr.scss +++ b/packages/components/src/components/date-picker/_flatpickr.scss @@ -117,7 +117,6 @@ height: rem(40px); display: flex; align-items: center; - margin-bottom: $carbon--spacing-02; background-color: transparent; color: $text-01; line-height: 1; @@ -271,6 +270,11 @@ border-bottom-color: $interactive-01; border-top-color: $interactive-01; } + + &:active::after { + border-bottom-color: $interactive-04; + border-top-color: $interactive-04; + } } .numInputWrapper .arrowUp { diff --git a/packages/components/src/components/form/_form.scss b/packages/components/src/components/form/_form.scss index 48238bc1c012..99af859e4546 100644 --- a/packages/components/src/components/form/_form.scss +++ b/packages/components/src/components/form/_form.scss @@ -79,7 +79,8 @@ input[data-invalid], .#{$prefix}--number[data-invalid] .#{$prefix}--number__input-wrapper, .#{$prefix}--number__input-wrapper--warning, - .#{$prefix}--date-picker-input__wrapper, + .#{$prefix}--date-picker-input__wrapper--warn, + .#{$prefix}--date-picker-input__wrapper--invalid, .#{$prefix}--time-picker--invalid, .#{$prefix}--text-input__field-wrapper[data-invalid], .#{$prefix}--text-input__field-wrapper--warning, @@ -99,7 +100,7 @@ input[data-invalid], .#{$prefix}--number[data-invalid] .#{$prefix}--number__input-wrapper, - .#{$prefix}--date-picker-input__wrapper, + .#{$prefix}--date-picker-input__wrapper--invalid, .#{$prefix}--time-picker--invalid, .#{$prefix}--text-input__field-wrapper[data-invalid], .#{$prefix}--text-area__wrapper[data-invalid], diff --git a/packages/components/src/components/number-input/_number-input.scss b/packages/components/src/components/number-input/_number-input.scss index d9d63364d31c..4d59ea68217b 100644 --- a/packages/components/src/components/number-input/_number-input.scss +++ b/packages/components/src/components/number-input/_number-input.scss @@ -164,7 +164,7 @@ fill: $support-03; } - .#{$prefix}--number__invalid--warning path[data-icon-path='inner-path'] { + .#{$prefix}--number__invalid--warning path:first-of-type { opacity: 1; fill: $carbon__black-100; } diff --git a/packages/components/src/components/text-input/_text-input.scss b/packages/components/src/components/text-input/_text-input.scss index c232b70b59c0..a6ce22c38261 100644 --- a/packages/components/src/components/text-input/_text-input.scss +++ b/packages/components/src/components/text-input/_text-input.scss @@ -86,7 +86,7 @@ .#{$prefix}--text-input__invalid-icon--warning { fill: $support-03; - path[data-icon-path='inner-path'] { + path:first-of-type { opacity: 1; fill: $carbon__black-100; } diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index af3cb6de95a5..6a31798544f2 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -2250,6 +2250,12 @@ Map { "type": Object { "type": "string", }, + "warn": Object { + "type": "bool", + }, + "warnText": Object { + "type": "string", + }, }, }, "Dropdown" => Object { diff --git a/packages/react/src/components/DatePicker/DatePicker-story.js b/packages/react/src/components/DatePicker/DatePicker-story.js index 0dd92d8654d1..0f4a14394e7c 100644 --- a/packages/react/src/components/DatePicker/DatePicker-story.js +++ b/packages/react/src/components/DatePicker/DatePicker-story.js @@ -23,11 +23,24 @@ const sizes = { 'Small size (sm)': 'sm', }; +const types = { + Simple: 'simple', + Single: 'single', + Range: 'range', +}; + const props = { datePicker: () => ({ dateFormat: text('The date format (dateFormat in )', 'm/d/Y'), id: 'date-picker', light: boolean('Light variant (light in )', false), + datePickerType: select( + 'Date Picker Type (datePickerType)', + types, + 'single' + ), + minDate: text('Disable dates before this date (minDate)', '11/15/2020'), + maxDate: text('Disabled dates after this date (maxDate)', '11/01/2040'), }), datePickerInput: () => ({ id: 'date-picker-input-id', @@ -53,7 +66,12 @@ const props = { ), invalidText: text( 'Form validation UI content (invalidText in )', - 'A valid value is required' + 'A valid date is required' + ), + warn: boolean('Show warning state (warn)', false), + warnText: text( + 'Warning state text (warnText)', + 'Selected dates may cause conflicts' ), iconDescription: text( 'Icon description (iconDescription in )', @@ -123,8 +141,11 @@ export const Range = () => { Range.storyName = 'range with calendar'; export const DatePickerPlayground = () => ( - + + {props.datePicker().datePickerType === 'range' && ( + + )} ); diff --git a/packages/react/src/components/DatePickerInput/DatePickerInput.js b/packages/react/src/components/DatePickerInput/DatePickerInput.js index c5e3c12d40ad..53287b8c06ba 100644 --- a/packages/react/src/components/DatePickerInput/DatePickerInput.js +++ b/packages/react/src/components/DatePickerInput/DatePickerInput.js @@ -9,6 +9,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import classNames from 'classnames'; import { settings } from 'carbon-components'; +import { WarningFilled16, WarningAltFilled16 } from '@carbon/icons-react'; import { Calendar16 } from '@carbon/icons-react'; const { prefix } = settings; @@ -106,6 +107,14 @@ export default class DatePickerInput extends Component { * Specify the type of the `` */ type: PropTypes.string, + /** + * Specify whether the control is currently in warning state + */ + warn: PropTypes.bool, + /** + * Provide the text that is displayed when the control is in warning state + */ + warnText: PropTypes.string, }; static defaultProps = { @@ -134,6 +143,8 @@ export default class DatePickerInput extends Component { iconDescription, openCalendar, size, + warn, + warnText, ...other } = this.props; @@ -154,6 +165,11 @@ export default class DatePickerInput extends Component { pattern, }; + const wrapperClasses = classNames(`${prefix}--date-picker-input__wrapper`, { + [`${prefix}--date-picker-input__wrapper--invalid`]: invalid, + [`${prefix}--date-picker-input__wrapper--warn`]: warn, + }); + const labelClasses = classNames(`${prefix}--label`, { [`${prefix}--visually-hidden`]: hideLabel, [`${prefix}--label--disabled`]: disabled, @@ -161,12 +177,30 @@ export default class DatePickerInput extends Component { const inputClasses = classNames(`${prefix}--date-picker__input`, { [`${prefix}--date-picker__input--${size}`]: size, + [`${prefix}--date-picker__input--invalid`]: invalid, }); const datePickerIcon = (() => { - if (datePickerType === 'simple') { + if (datePickerType === 'simple' && !invalid && !warn) { return; } + + if (invalid) { + return ( + + ); + } + + if (!invalid && warn) { + return ( + + ); + } + return ( ) : null; - const error = invalid ? ( -
{invalidText}
- ) : null; + let error = null; + if (invalid) { + error = ( +
{invalidText}
+ ); + } else if (warn) { + error =
{warnText}
; + } const containerClasses = classNames(`${prefix}--date-picker-container`, { [`${prefix}--date-picker--nolabel`]: !label, @@ -218,7 +257,7 @@ export default class DatePickerInput extends Component { return (
{label} -
+
{input} {datePickerIcon}