Skip to content

Commit

Permalink
[v5] [datetime] break: promote datetime2 components (#6121)
Browse files Browse the repository at this point in the history
  • Loading branch information
adidahiya authored May 3, 2023
1 parent d8a63ed commit 46f2eb9
Show file tree
Hide file tree
Showing 98 changed files with 1,289 additions and 7,111 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ This repository contains multiple projects in the `packages/` directory that fal
These are the component libraries we publish to NPM.

- [![npm](https://img.shields.io/npm/v/@blueprintjs/core.svg?label=@blueprintjs/core)](https://www.npmjs.com/package/@blueprintjs/core) – Core styles & components.
- [![npm](https://img.shields.io/npm/v/@blueprintjs/datetime.svg?label=@blueprintjs/datetime)](https://www.npmjs.com/package/@blueprintjs/datetime) – Components for interacting with dates and times.
- [![npm](https://img.shields.io/npm/v/@blueprintjs/datetime2.svg?label=@blueprintjs/datetime2)](https://www.npmjs.com/package/@blueprintjs/datetime2) – Next-generation timezone-aware components for interacting with dates and times.
- [![npm](https://img.shields.io/npm/v/@blueprintjs/datetime.svg?label=@blueprintjs/datetime)](https://www.npmjs.com/package/@blueprintjs/datetime) – Timezone-aware components for interacting with dates and times.
- [![npm](https://img.shields.io/npm/v/@blueprintjs/icons.svg?label=@blueprintjs/icons)](https://www.npmjs.com/package/@blueprintjs/icons) – Components for generating and displaying icons.
- [![npm](https://img.shields.io/npm/v/@blueprintjs/select.svg?label=@blueprintjs/select)](https://www.npmjs.com/package/@blueprintjs/select) – Components for selecting items from a list.
- [![npm](https://img.shields.io/npm/v/@blueprintjs/table.svg?label=@blueprintjs/table)](https://www.npmjs.com/package/@blueprintjs/table) – Scalable interactive table component.
Expand Down Expand Up @@ -104,8 +103,6 @@ There are a few ways to run development scripts, here they are listed from simpl
- `yarn dev:core`
- `yarn dev:docs`
- `yarn dev:datetime`
- `yarn dev:datetime2`
- `yarn dev:popover2`
- `yarn dev:select`
- `yarn dev:table`
- Lastly, if you want to control exaclty which dev scripts are run and view the console output in the cleanest way, we recommend opening separate terminal windows or splits and running local package dev tasks in each one. This is the recommended workflow for frequent contributors and advanced developers. For example, to test changes in the core + icons packages, you would run the following in separate terminals:
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"dev:core": "lerna run dev --scope \"@blueprintjs/{core,icons,docs-app}\"",
"dev:docs": "lerna run dev --scope \"@blueprintjs/{core,docs-app,docs-theme}\"",
"dev:datetime": "lerna run dev --scope \"@blueprintjs/{datetime,timezone,docs-app}\"",
"dev:datetime2": "lerna run dev --scope \"@blueprintjs/{datetime2,docs-app}\"",
"dev:select": "lerna run dev --scope \"@blueprintjs/{select,docs-app}\"",
"dev:table": "lerna run dev --scope \"@blueprintjs/{table,table-dev-app}\"",
"dist": "run-s dist:libs dist:apps",
Expand Down
9 changes: 9 additions & 0 deletions packages/datetime/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ module.exports = async function (config) {
config.set(
createKarmaConfig({
dirname: __dirname,
coverageExcludes: [
// not worth coverage, fairly simple implementation
"src/common/timezoneDisplayFormat.ts",
],
coverageOverrides: {
"src/components/timezone-select/timezoneSelect.tsx": {
statements: 75,
},
},
}),
);
};
5 changes: 5 additions & 0 deletions packages/datetime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@
"dependencies": {
"@blueprintjs/core": "^4.18.0",
"@blueprintjs/icons": "^4.9.0",
"@blueprintjs/select": "^4.9.14",
"classnames": "^2.3.1",
"date-fns": "^2.28.0",
"date-fns-tz": "^1.3.7",
"lodash": "^4.17.21",
"react-day-picker": "7.4.9",
"tslib": "~2.5.0"
},
Expand All @@ -56,6 +60,7 @@
"@blueprintjs/karma-build-scripts": "^4.0.19",
"@blueprintjs/node-build-scripts": "^7.1.1",
"@blueprintjs/test-commons": "^1.1.16",
"@types/lodash": "~4.14.191",
"enzyme": "^3.11.0",
"karma": "^6.4.1",
"mocha": "^10.2.0",
Expand Down
28 changes: 0 additions & 28 deletions packages/datetime/src/_datetimepicker.scss

This file was deleted.

9 changes: 4 additions & 5 deletions packages/datetime/src/blueprint-datetime.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Copyright 2015 Palantir Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0.

@import "datepicker";
@import "daterangepicker";
@import "timepicker";
@import "datetimepicker";
@import "dateinput";
@import "components/date-input/dateinput";
@import "components/date-picker/datepicker";
@import "components/date-range-picker/daterangepicker";
@import "components/time-picker/timepicker";
11 changes: 8 additions & 3 deletions packages/datetime/src/common/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import { Classes } from "@blueprintjs/core";

const NS = Classes.getClassNamespace();

export const DATEINPUT = `${NS}-dateinput`;
export const DATEINPUT_POPOVER = `${DATEINPUT}-popover`;
export const DATE_INPUT = `${NS}-date-input`;
export const DATE_INPUT_POPOVER = `${NS}-date-input-popover`;
export const DATE_INPUT_TIMEZONE_SELECT = `${NS}-date-input-timezone-select`;

export const DATEPICKER = `${NS}-datepicker`;
export const DATEPICKER_CAPTION = `${DATEPICKER}-caption`;
Expand Down Expand Up @@ -49,7 +50,8 @@ export const DATERANGEPICKER_DAY_HOVERED_RANGE = `${DATEPICKER_DAY}--hovered-ran
export const DATERANGEPICKER_SHORTCUTS = `${DATERANGEPICKER}-shortcuts`;
export const DATERANGEPICKER_TIMEPICKERS = `${DATERANGEPICKER}-timepickers`;

export const DATETIMEPICKER = `${NS}-datetimepicker`;
export const DATE_RANGE_INPUT = `${NS}-date-range-input`;
export const DATE_RANGE_INPUT_POPOVER = `${NS}-date-range-input-popover`;

export const TIMEPICKER = `${NS}-timepicker`;
export const TIMEPICKER_ARROW_BUTTON = `${TIMEPICKER}-arrow-button`;
Expand All @@ -62,3 +64,6 @@ export const TIMEPICKER_MILLISECOND = `${TIMEPICKER}-millisecond`;
export const TIMEPICKER_MINUTE = `${TIMEPICKER}-minute`;
export const TIMEPICKER_SECOND = `${TIMEPICKER}-second`;
export const TIMEPICKER_AMPM_SELECT = `${TIMEPICKER}-ampm-select`;

export const TIMEZONE_SELECT = `${NS}-timezone-select`;
export const TIMEZONE_SELECT_POPOVER = `${TIMEZONE_SELECT}-popover`;
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/

import { isDateValid, isDayInRange } from "./common/dateUtils";
import { DatePickerBaseProps } from "./datePickerCore";
import type { DatePickerBaseProps } from "./datePickerBaseProps";
import { isDateValid, isDayInRange } from "./dateUtils";

export interface DateFormatProps {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

import { DayPickerProps, LocaleUtils } from "react-day-picker";

import { Months } from "./common/months";
import { TimePickerProps, TimePrecision } from "./timePicker";
import type { TimePickerProps, TimePrecision } from "./timePickerProps";

// DatePicker supports a simpler set of modifiers (for now).
// also we need an interface for the dictionary without `today` and `outside` injected by r-d-p.
Expand Down Expand Up @@ -124,46 +123,3 @@ export interface DatePickerBaseProps {
*/
timePickerProps?: TimePickerProps;
}

export const DISABLED_MODIFIER = "disabled";
export const HOVERED_RANGE_MODIFIER = "hovered-range";
export const OUTSIDE_MODIFIER = "outside";
export const SELECTED_MODIFIER = "selected";
export const SELECTED_RANGE_MODIFIER = "selected-range";
// modifiers the user can't set because they are used by Blueprint or react-day-picker
export const DISALLOWED_MODIFIERS = [
DISABLED_MODIFIER,
HOVERED_RANGE_MODIFIER,
OUTSIDE_MODIFIER,
SELECTED_MODIFIER,
SELECTED_RANGE_MODIFIER,
];

export function getDefaultMaxDate() {
const date = new Date();
date.setMonth(date.getMonth() + 6);
return date;
}

export function getDefaultMinDate() {
const date = new Date();
date.setFullYear(date.getFullYear() - 20);
date.setMonth(Months.JANUARY, 1);
return date;
}

export function combineModifiers(baseModifiers: DatePickerModifiers, userModifiers: DatePickerModifiers) {
let modifiers = baseModifiers;
if (userModifiers != null) {
modifiers = {};
for (const key of Object.keys(userModifiers)) {
if (DISALLOWED_MODIFIERS.indexOf(key) === -1) {
modifiers[key] = userModifiers[key];
}
}
for (const key of Object.keys(baseModifiers)) {
modifiers[key] = baseModifiers[key];
}
}
return modifiers;
}
6 changes: 6 additions & 0 deletions packages/datetime/src/common/dateRange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@
*/

export type DateRange = [Date | null, Date | null];
export type NonNullDateRange = [Date, Date];

/* istanbul ignore next */
export function isNonNullRange(range: DateRange): range is NonNullDateRange {
return range[0] != null && range[1] != null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

import { Boundary } from "@blueprintjs/core";

import { DateRange } from "./common/dateRange";
import { areSameDay } from "./common/dateUtils";
import { DateRange } from "./dateRange";
import { isSameDay } from "./dateUtils";

export interface DateRangeSelectionState {
/**
Expand Down Expand Up @@ -69,11 +69,11 @@ export class DateRangeSelectionStrategy {
nextBoundary = boundary;
nextDateRange = this.createRangeForBoundary(boundary, day, null);
} else if (boundaryDate != null && otherBoundaryDate == null) {
const nextBoundaryDate = areSameDay(boundaryDate, day) ? null : day;
const nextBoundaryDate = isSameDay(boundaryDate, day) ? null : day;
nextBoundary = boundary;
nextDateRange = this.createRangeForBoundary(boundary, nextBoundaryDate, null);
} else if (boundaryDate == null && otherBoundaryDate != null) {
if (areSameDay(day, otherBoundaryDate)) {
if (isSameDay(day, otherBoundaryDate)) {
let nextDate: Date;
if (allowSingleDayRange) {
nextBoundary = boundary;
Expand All @@ -92,12 +92,12 @@ export class DateRangeSelectionStrategy {
}
} else {
// both boundaryDate and otherBoundaryDate are already defined
if (areSameDay(boundaryDate, day)) {
const isSingleDayRangeSelected = areSameDay(boundaryDate, otherBoundaryDate);
if (isSameDay(boundaryDate, day)) {
const isSingleDayRangeSelected = isSameDay(boundaryDate, otherBoundaryDate);
const nextOtherBoundaryDate = isSingleDayRangeSelected ? null : otherBoundaryDate;
nextBoundary = boundary;
nextDateRange = this.createRangeForBoundary(boundary, null, nextOtherBoundaryDate);
} else if (areSameDay(day, otherBoundaryDate)) {
} else if (isSameDay(day, otherBoundaryDate)) {
const [nextBoundaryDate, nextOtherBoundaryDate] = allowSingleDayRange
? [otherBoundaryDate, otherBoundaryDate]
: [boundaryDate, null];
Expand Down Expand Up @@ -132,8 +132,8 @@ export class DateRangeSelectionStrategy {
} else if (start == null && end != null) {
nextDateRange = this.createRange(day, end, allowSingleDayRange);
} else {
const isStart = areSameDay(start, day);
const isEnd = areSameDay(end, day);
const isStart = isSameDay(start, day);
const isEnd = isSameDay(end, day);
if (isStart && isEnd) {
nextDateRange = [null, null];
} else if (isStart) {
Expand Down Expand Up @@ -168,7 +168,7 @@ export class DateRangeSelectionStrategy {

private static createRange(a: Date, b: Date, allowSingleDayRange: boolean): DateRange {
// clicking the same date again will clear it
if (!allowSingleDayRange && areSameDay(a, b)) {
if (!allowSingleDayRange && isSameDay(a, b)) {
return [null, null];
}
return a < b ? [a, b] : [b, a];
Expand Down
51 changes: 26 additions & 25 deletions packages/datetime/src/common/dateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,22 @@
* limitations under the License.
*/

import { DateRange } from "./dateRange";
import { isSameDay } from "date-fns";

import { DateRange, isNonNullRange } from "./dateRange";
import { Months } from "./months";

export { isSameDay };

export function clone(d: Date) {
return new Date(d.getTime());
}

export function isDateValid(date: Date | false | null): date is Date {
return date instanceof Date && !isNaN(date.valueOf());
}

export function areEqual(date1: Date, date2: Date) {
export function isEqual(date1: Date, date2: Date) {
if (date1 == null && date2 == null) {
return true;
} else if (date1 == null || date2 == null) {
Expand All @@ -39,17 +47,13 @@ export function areRangesEqual(dateRange1: DateRange, dateRange2: DateRange) {
} else {
const [start1, end1] = dateRange1;
const [start2, end2] = dateRange2;
const areStartsEqual = (start1 == null && start2 == null) || areSameDay(start1, start2);
const areEndsEqual = (end1 == null && end2 == null) || areSameDay(end1, end2);
const areStartsEqual = (start1 == null && start2 == null) || isSameDay(start1, start2);
const areEndsEqual = (end1 == null && end2 == null) || isSameDay(end1, end2);
return areStartsEqual && areEndsEqual;
}
}

export function areSameDay(date1: Date, date2: Date) {
return areSameMonth(date1, date2) && date1.getDate() === date2.getDate();
}

export function areSameMonth(date1: Date, date2: Date) {
export function isSameMonth(date1: Date, date2: Date) {
return (
date1 != null &&
date2 != null &&
Expand All @@ -58,23 +62,20 @@ export function areSameMonth(date1: Date, date2: Date) {
);
}

export function areSameTime(date1: Date, date2: Date) {
export function isSameTime(d1: Date | null, d2: Date | null) {
// N.B. do not use date-fns helper fns here, since we don't want to return false when the month/day/year is different
return (
date1 != null &&
date2 != null &&
date1.getHours() === date2.getHours() &&
date1.getMinutes() === date2.getMinutes() &&
date1.getSeconds() === date2.getSeconds() &&
date1.getMilliseconds() === date2.getMilliseconds()
d1 != null &&
d2 != null &&
d1.getHours() === d2.getHours() &&
d1.getMinutes() === d2.getMinutes() &&
d1.getSeconds() === d2.getSeconds() &&
d1.getMilliseconds() === d2.getMilliseconds()
);
}

export function clone(d: Date) {
return new Date(d.getTime());
}

export function isDayInRange(date: Date, dateRange: DateRange, exclusive = false) {
if (date == null) {
export function isDayInRange(date: Date | null, dateRange: DateRange, exclusive = false) {
if (date == null || !isNonNullRange(dateRange)) {
return false;
}

Expand All @@ -86,7 +87,7 @@ export function isDayInRange(date: Date, dateRange: DateRange, exclusive = false
start.setHours(0, 0, 0, 0);
end.setHours(0, 0, 0, 0);

return start <= day && day <= end && (!exclusive || (!areSameDay(start, day) && !areSameDay(day, end)));
return start <= day && day <= end && (!exclusive || (!isSameDay(start, day) && !isSameDay(day, end)));
}

export function isDayRangeInRange(innerRange: DateRange, outerRange: DateRange) {
Expand Down Expand Up @@ -134,7 +135,7 @@ export function isTimeInRange(date: Date, minDate: Date, maxDate: Date): boolean
}

export function getTimeInRange(time: Date, minTime: Date, maxTime: Date) {
if (areSameTime(minTime, maxTime)) {
if (isSameTime(minTime, maxTime)) {
return maxTime;
} else if (isTimeInRange(time, minTime, maxTime)) {
return time;
Expand Down Expand Up @@ -236,5 +237,5 @@ export function get24HourFrom12Hour(hour: number, isPm: boolean): number {
}

export function isToday(date: Date): boolean {
return areSameDay(date, new Date());
return isSameDay(date, new Date());
}
2 changes: 2 additions & 0 deletions packages/datetime/src/common/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ export const DATERANGEINPUT_NULL_VALUE =
ns +
` <DateRangeInput> value cannot be null. Pass undefined to clear the value and operate in` +
" uncontrolled mode, or pass [null, null] to clear the value and continue operating in controlled mode.";

export const DATEINPUT_INVALID_DEFAULT_TIMEZONE = `${ns} <DateInput> was provided an invalid defaultTimezone, defaulting to Etc/UTC instead`;
File renamed without changes.
Loading

1 comment on commit 46f2eb9

@adidahiya
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[v5] [datetime] break: promote datetime2 components (#6121)

Build artifact links for this commit: documentation | landing | table | demo

This is an automated comment from the deploy-preview CircleCI job.

Please sign in to comment.