From f0ef528bfc4637bb9d94f675a9f30fdb45e9a1b4 Mon Sep 17 00:00:00 2001 From: Adam Beret Manczuk Date: Tue, 9 Nov 2021 20:58:30 +0000 Subject: [PATCH 1/4] Added nullable property to `Calendar`, `DatePicker`, `DateRangePicker`, and `WeekPicker` that allow set value to null. Property nullable is as a default set to false. --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/Calendar.js | 44 +++++++++++++++++++++++----------- src/DatePicker.js | 5 +++- src/DateRangePicker.js | 19 +++++++++++---- src/WeekPicker.js | 21 +++++++++++----- src/daycy.css | 10 ++++++++ src/translate.js | 3 +++ stories/index.stories.js | 52 ++++++++++++++++++++++++++++++++++++++++ yarn.lock | 6 ++--- 10 files changed, 137 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5326d0..c20706b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.6.0] - 2021-11-03 +### Added +- Added nullable property to `Calendar`, `DatePicker`, `DateRangePicker`, and `WeekPicker` that allow set value to null. Property nullable is as a default set to false. + ## [0.5.1] - 2021-11-03 ### Fixed - Fixed `MonthPicker` to correctly forward the value to `MonthInput`. diff --git a/package.json b/package.json index 32e9aee..a8d8613 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "daycy", - "version": "0.5.1", + "version": "0.6.0", "description": "Simple date (range) picker for React based on Semantic-UI.", "main": "./dist/index.js", "scripts": { diff --git a/src/Calendar.js b/src/Calendar.js index c05bc3e..6e41895 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -27,14 +27,16 @@ export default class Calendar extends Component { includeWeeks: PropTypes.bool, onWeekSelect: PropTypes.func, translate: PropTypes.func, + nullable: PropTypes.bool, }; static defaultProps = { includeWeeks: false, onClose: () => {}, + nullable: false, }; - state = { month: null, weeks: null, hoverWeek: null, hoverDate: null }; + state = { month: null, weeks: null, hoverWeek: null, hoverDate: null, hoverClear: false }; constructor(...args) { super(...args); @@ -54,7 +56,7 @@ export default class Calendar extends Component { { month, weeks, hoverDate }, ) { const updates = {}; - + if (value) { updates.value = value.startOf('day'); } else { @@ -74,7 +76,7 @@ export default class Calendar extends Component { const date = ( value || highlightStart || - highlightEnd || + highlightEnd || DateTime.local() ); month = date.startOf('month'); @@ -122,7 +124,7 @@ export default class Calendar extends Component { onChange(date) { const { value, onChange } = this.props - if (value) { + if (value && date !== null) { date = date.set({ hour: value.hour, minute: value.minute, @@ -195,7 +197,7 @@ export default class Calendar extends Component { ( hover === 'start' && highlightEnd && - date >= hoverDate && + date >= hoverDate && date <= highlightEnd ) || ( @@ -204,9 +206,7 @@ export default class Calendar extends Component { date >= highlightStart && date <= hoverDate ) - ) : ( - false - )) { + ) : false) { classes.push('hover'); } if (date.year !== month.year || date.month !== month.month) { @@ -226,17 +226,20 @@ export default class Calendar extends Component { ); } + + render() { - const { includeWeeks, open, trigger, onClose } = this.props; - const { month, weeks } = this.state; + const { includeWeeks, open, trigger, onClose, nullable } = this.props; + const { month, weeks, hoverClear } = this.state; + const onChange = this.onChange; return ( - e.preventDefault()} > @@ -259,6 +262,19 @@ export default class Calendar extends Component { {DAYS.map(this.renderDay)} {weeks && weeks.map(this.renderWeek)} +
+ {nullable && ( +
this.onChange(null)} + onMouseEnter={() => this.setState({hoverClear: true})} + onMouseLeave={() => this.setState({hoverClear: false})} + > + {this.translate('clear.label')} +
+ )} +
); diff --git a/src/DatePicker.js b/src/DatePicker.js index a14ad51..d7f09e1 100644 --- a/src/DatePicker.js +++ b/src/DatePicker.js @@ -15,12 +15,14 @@ export default class DatePicker extends Component { includeWeeks: PropTypes.bool, onWeekSelect: PropTypes.func, noPopup: PropTypes.bool, + nullable: PropTypes.bool, }; static defaultProps = { format: 'dd-LL-yyyy', fluid: false, noPopup: false, + nullable: false, }; state = { open: false }; @@ -60,7 +62,7 @@ export default class DatePicker extends Component { } render() { - const { value, translate, includeWeeks, onWeekSelect, noPopup, ...props } = this.props; + const { value, translate, includeWeeks, onWeekSelect, nullable, noPopup, ...props } = this.props; const { open } = this.state; delete props.onChange; @@ -71,6 +73,7 @@ export default class DatePicker extends Component { open={!noPopup && open} value={value} onChange={this.onChange} + nullable={nullable} trigger={ this.input = ref} diff --git a/src/DateRangePicker.js b/src/DateRangePicker.js index 2c0de25..b73857d 100644 --- a/src/DateRangePicker.js +++ b/src/DateRangePicker.js @@ -27,6 +27,7 @@ export default class DateRangePicker extends Component { includeWeeks: PropTypes.bool, disabled: PropTypes.bool, noPopup: PropTypes.bool, + nullable: PropTypes.bool, }; static defaultProps = { @@ -39,6 +40,7 @@ export default class DateRangePicker extends Component { fluid: false, disabled: false, noPopup: false, + nullable: false, }; state = { open: null, override: null }; @@ -58,11 +60,18 @@ export default class DateRangePicker extends Component { onChange(date, close = true) { let { value, onChange } = this.props; const { open, override } = this.state; + console.log(value, open, override) value = override || value || EMPTY; let other = OTHER[open]; - - if ( + if (date === null){ + // this.setState({ + // open: null, + // override: null, + // }); + onChange(null); + } + else if ( value[other] === null || (open === 'start' && date > value.end) || (open === 'end' && date < value.start) @@ -79,7 +88,8 @@ export default class DateRangePicker extends Component { month: date.startOf('month'), weeks: null, }); - } else { + } + else { value = { [open]: date, [other]: value[other] }; onChange(Interval.fromDateTimes(value.start, value.end)); if (close) { @@ -123,7 +133,7 @@ export default class DateRangePicker extends Component { let { value, format, icon, translate, startProps, endProps, startPlaceholder, endPlaceholder, fluid, includeWeeks, disabled, - noPopup, + noPopup, nullable, ...props } = this.props; const { open, override } = this.state; @@ -156,6 +166,7 @@ export default class DateRangePicker extends Component { value={value[open]} onChange={this.onChange} hover={open} + nullable={nullable} highlightStart={value.start || value.end} highlightEnd={value.end || value.start} trigger={ diff --git a/src/WeekPicker.js b/src/WeekPicker.js index 3b9e968..ff5c911 100644 --- a/src/WeekPicker.js +++ b/src/WeekPicker.js @@ -26,8 +26,8 @@ export function isoWeekEnd({ year, week }) { export default class WeekPicker extends Component { static propTypes = { value: PropTypes.shape({ - year: PropTypes.number.isRequired, - week: PropTypes.number.isRequired, + year: PropTypes.number.isRequired, + week: PropTypes.number.isRequired, }), onChange: PropTypes.func.isRequired, translate: PropTypes.func, @@ -35,6 +35,7 @@ export default class WeekPicker extends Component { format: PropTypes.string, includeDates: PropTypes.bool, noPopup: PropTypes.bool, + nullable: PropTypes.bool, }; static defaultProps = { @@ -42,6 +43,7 @@ export default class WeekPicker extends Component { format: 'dd-LL-yyyy', includeDates: false, noPopup: false, + nullable: false, }; state = { open: false }; @@ -55,10 +57,12 @@ export default class WeekPicker extends Component { onChange(value) { const { onChange } = this.props; - if (value instanceof Interval) { - value = value.start; + if(value !== null) { + if (value instanceof Interval) { + value = value.start; + } + value = {year: value.weekYear, week: value.weekNumber}; } - value = { year: value.weekYear, week: value.weekNumber }; onChange(value); this.onClose(); } @@ -77,7 +81,11 @@ export default class WeekPicker extends Component { } render() { - const { value, includeDates, format, translate, className, fluid, style, noPopup, ...props } = this.props; + const { value, includeDates, format, + translate, className, fluid, + style, noPopup, nullable, + ...props + } = this.props; const { open } = this.state; delete props.onChange; @@ -102,6 +110,7 @@ export default class WeekPicker extends Component { highlightStart={value && isoWeekStart(value)} highlightEnd={value && isoWeekEnd(value)} hover="week" + nullable={nullable} trigger={
.clear { + display: flex; + justify-content: space-between; + font-size: 120%; + font-weight: bold; + border-bottom: 1px solid rgba(34, 36, 38, 0.15); + padding: 0.883rem 1rem; + color: rgb(34, 36, 38); +} + .daycy.calendar > .title > .icon, .daycy.month-calendar > .title > .icon { cursor: pointer; diff --git a/src/translate.js b/src/translate.js index 034f68a..6c909f6 100644 --- a/src/translate.js +++ b/src/translate.js @@ -60,4 +60,7 @@ configureTranslation({ am: 'AM', pm: 'PM', }, + clear: { + label: "Clear", + } }); diff --git a/stories/index.stories.js b/stories/index.stories.js index a7c9d54..55acaf6 100644 --- a/stories/index.stories.js +++ b/stories/index.stories.js @@ -47,6 +47,23 @@ storiesOf('DatePicker', module) style={{ margin: '1rem', width: '19.5rem' }} includeWeeks /> + )) + .add('nullable basic', () => ( + + )) + .add('nullable with weeks', () => ( + )); storiesOf('DateRangePicker', module) @@ -66,6 +83,25 @@ storiesOf('DateRangePicker', module) style={{ margin: '1rem' }} includeWeeks /> + )) + .add('nullable empty', () => ( + + )) + .add('nullable with weeks', () => ( + )); storiesOf('TimePicker', module) @@ -101,6 +137,22 @@ storiesOf('WeekPicker', module) placeholder="Week" style={{ margin: '1rem', width: '19.5rem' }} /> + )) + .add('nullable empty', () => ( + + )) + .add('nullable with dates', () => ( + )); storiesOf('MonthPicker', module) diff --git a/yarn.lock b/yarn.lock index 03e3107..f52779a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2761,9 +2761,9 @@ can-use-dom@^0.1.0: integrity sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo= caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001097: - version "1.0.30001099" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001099.tgz#540118fcc6842d1fde62f4ee5521d1ec6afdb40e" - integrity sha512-sdS9A+sQTk7wKoeuZBN/YMAHVztUfVnjDi4/UV3sDE8xoh7YR12hKW+pIdB3oqKGwr9XaFL2ovfzt9w8eUI5CA== + version "1.0.30001279" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001279.tgz" + integrity sha512-VfEHpzHEXj6/CxggTwSFoZBBYGQfQv9Cf42KPlO79sWXCD1QNKWKsKzFeWL7QpZHJQYAvocqV6Rty1yJMkqWLQ== case-sensitive-paths-webpack-plugin@^2.2.0: version "2.3.0" From 86fa1adc9fea453f68a636372dea231bcf5d3da2 Mon Sep 17 00:00:00 2001 From: Adam Beret Manczuk Date: Tue, 9 Nov 2021 21:02:15 +0000 Subject: [PATCH 2/4] Remove non important changes --- src/Calendar.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Calendar.js b/src/Calendar.js index 6e41895..7242a0a 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -206,7 +206,9 @@ export default class Calendar extends Component { date >= highlightStart && date <= hoverDate ) - ) : false) { + ) : ( + false + )) { classes.push('hover'); } if (date.year !== month.year || date.month !== month.month) { @@ -229,9 +231,8 @@ export default class Calendar extends Component { render() { - const { includeWeeks, open, trigger, onClose, nullable } = this.props; - const { month, weeks, hoverClear } = this.state; - const onChange = this.onChange; + const { includeWeeks, open, trigger, onClose } = this.props; + const { month, weeks } = this.state; return ( Date: Tue, 9 Nov 2021 21:27:02 +0000 Subject: [PATCH 3/4] Some change was important! Cleanup Calendar and css styles. --- src/Calendar.js | 7 +++---- src/daycy.css | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Calendar.js b/src/Calendar.js index 7242a0a..4606c4b 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -231,8 +231,8 @@ export default class Calendar extends Component { render() { - const { includeWeeks, open, trigger, onClose } = this.props; - const { month, weeks } = this.state; + const { includeWeeks, open, trigger, onClose, nullable } = this.props; + const { month, weeks, hoverClear } = this.state; return ( {weeks && weeks.map(this.renderWeek)} -
+
{nullable && (
this.onChange(null)} onMouseEnter={() => this.setState({hoverClear: true})} onMouseLeave={() => this.setState({hoverClear: false})} diff --git a/src/daycy.css b/src/daycy.css index 9ba861a..b83a11b 100644 --- a/src/daycy.css +++ b/src/daycy.css @@ -87,16 +87,6 @@ color: rgb(34, 36, 38); } -.daycy.calendar > .clear { - display: flex; - justify-content: space-between; - font-size: 120%; - font-weight: bold; - border-bottom: 1px solid rgba(34, 36, 38, 0.15); - padding: 0.883rem 1rem; - color: rgb(34, 36, 38); -} - .daycy.calendar > .title > .icon, .daycy.month-calendar > .title > .icon { cursor: pointer; @@ -107,6 +97,20 @@ color: rgba(34, 36, 38, 0.5); } +.daycy.calendar > .grid > .row.clear { + display: flex; + justify-content: space-around; + flex-flow: row nowrap; + font-weight: bold; + border-bottom: 1px solid rgba(34, 36, 38, 0.15); + padding: 1rem 1rem; + color: rgb(34, 36, 38); +} + +.daycy.calendar > .grid > .row.clear > .cell { + flex: 1 100%; +} + .daycy.calendar > .grid > .row > .cell { display: inline-block; width: 2.3rem; From 6b5254502f4803b2a89c6f0922c5ee1d6830c21f Mon Sep 17 00:00:00 2001 From: Adam Beret Manczuk Date: Tue, 9 Nov 2021 21:47:06 +0000 Subject: [PATCH 4/4] Remove non-important changes again. Clean up code. --- src/Calendar.js | 2 -- src/DateRangePicker.js | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Calendar.js b/src/Calendar.js index 4606c4b..93b0035 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -228,8 +228,6 @@ export default class Calendar extends Component { ); } - - render() { const { includeWeeks, open, trigger, onClose, nullable } = this.props; const { month, weeks, hoverClear } = this.state; diff --git a/src/DateRangePicker.js b/src/DateRangePicker.js index b73857d..1a9e140 100644 --- a/src/DateRangePicker.js +++ b/src/DateRangePicker.js @@ -65,10 +65,6 @@ export default class DateRangePicker extends Component { value = override || value || EMPTY; let other = OTHER[open]; if (date === null){ - // this.setState({ - // open: null, - // override: null, - // }); onChange(null); } else if ( @@ -88,8 +84,7 @@ export default class DateRangePicker extends Component { month: date.startOf('month'), weeks: null, }); - } - else { + } else { value = { [open]: date, [other]: value[other] }; onChange(Interval.fromDateTimes(value.start, value.end)); if (close) {