From b5d8eff2549556df93a7b7b38e316828a6d4e8a8 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 11 Dec 2023 18:17:29 -0600 Subject: [PATCH 001/155] feat(month-picker): adds month-picker component --- .../month-picker-item/month-picker-item.scss | 19 +++++ .../month-picker-item/month-picker-item.tsx | 37 +++++++++ .../components/month-picker/month-picker.scss | 7 ++ .../components/month-picker/month-picker.tsx | 80 +++++++++++++++++++ .../src/demos/month-picker.html | 14 ++++ packages/calcite-components/src/index.html | 7 ++ packages/calcite-components/stencil.config.ts | 1 + 7 files changed, 165 insertions(+) create mode 100644 packages/calcite-components/src/components/month-picker-item/month-picker-item.scss create mode 100644 packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx create mode 100644 packages/calcite-components/src/components/month-picker/month-picker.scss create mode 100644 packages/calcite-components/src/components/month-picker/month-picker.tsx create mode 100644 packages/calcite-components/src/demos/month-picker.html diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss b/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss new file mode 100644 index 00000000000..9233b40bb62 --- /dev/null +++ b/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss @@ -0,0 +1,19 @@ +:host { + display: flex; + block-size: 36px; +} + +.month-item { + display: flex; + inline-size: 100%; + @apply text-color-1; + padding-block: 8px; + padding-inline: 12px 8px; + &:hover { + background-color: var(--calcite-color-foreground-2); + } +} + +.month-item--active { + border-inline-start: 2px solid var(--calcite-color-brand); +} diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx new file mode 100644 index 00000000000..0e8fc9b75b3 --- /dev/null +++ b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx @@ -0,0 +1,37 @@ +import { Component, Host, VNode, h, Element, Prop, EventEmitter, Event } from "@stencil/core"; + +@Component({ + tag: "calcite-month-picker-item", + styleUrl: "month-picker-item.scss", + shadow: true, +}) +export class MonthPickerItem { + @Element() el: HTMLCalciteMonthPickerItemElement; + + @Prop() value: string; + + @Prop() isActive: boolean; + + /** + * Emits whenever the component is selected. + * + */ + @Event() calciteInternalMonthPickerItemSelect: EventEmitter; + + private handleClick = (): void => { + this.calciteInternalMonthPickerItemSelect.emit(); + }; + + render(): VNode { + return ( + +
+ {this.value} +
+
+ ); + } +} diff --git a/packages/calcite-components/src/components/month-picker/month-picker.scss b/packages/calcite-components/src/components/month-picker/month-picker.scss new file mode 100644 index 00000000000..cfc23394f8c --- /dev/null +++ b/packages/calcite-components/src/components/month-picker/month-picker.scss @@ -0,0 +1,7 @@ +:host { + display: block; + block-size: 344px; + background-color: var(--calcite-color-foreground-1); + font-size: var(--calcite-font-size--1); + overflow: auto; +} diff --git a/packages/calcite-components/src/components/month-picker/month-picker.tsx b/packages/calcite-components/src/components/month-picker/month-picker.tsx new file mode 100644 index 00000000000..c1d955bab84 --- /dev/null +++ b/packages/calcite-components/src/components/month-picker/month-picker.tsx @@ -0,0 +1,80 @@ +import { + Component, + Host, + VNode, + h, + Element, + Prop, + State, + Watch, + Build, + Listen, + Event, + EventEmitter, +} from "@stencil/core"; +import { LocalizedComponent, connectLocalized, disconnectLocalized } from "../../utils/locale"; +import { DateLocaleData, getLocaleData } from "../date-picker/utils"; + +@Component({ + tag: "calcite-month-picker", + styleUrl: "month-picker.scss", + shadow: true, +}) +export class MonthPicker implements LocalizedComponent { + @Prop({ mutable: true }) activeMonthIndex: number; + + /** + * Emits whenever the component is selected. + * + */ + @Event() calciteMonthPickerChange: EventEmitter; + + connectedCallback() { + connectLocalized(this); + } + + async componentWillLoad(): Promise { + await this.loadLocaleData(); + } + + disconnectedCallback() { + disconnectLocalized(this); + } + + @Element() el: HTMLCalciteMonthPickerElement; + + @State() effectiveLocale = ""; + + @State() localeData: DateLocaleData; + + @Watch("effectiveLocale") + private async loadLocaleData(): Promise { + if (!Build.isBrowser) { + return; + } + + this.localeData = await getLocaleData(this.effectiveLocale); + } + + @Listen("calciteInternalMonthPickerItemSelect") + handleCalciteMonthPickerItemChange(event: CustomEvent): void { + const target = event.target as HTMLCalciteMonthPickerItemElement; + this.activeMonthIndex = this.localeData?.months.wide.indexOf(target.value); + this.calciteMonthPickerChange.emit(); + } + + render(): VNode { + console.log("render", this.localeData?.months); + return ( + + {this.localeData?.months.wide.map((month, index) => ( + + ))} + + ); + } +} diff --git a/packages/calcite-components/src/demos/month-picker.html b/packages/calcite-components/src/demos/month-picker.html new file mode 100644 index 00000000000..c7dde155b00 --- /dev/null +++ b/packages/calcite-components/src/demos/month-picker.html @@ -0,0 +1,14 @@ + + + + + + + Month Picker + + + + + + + diff --git a/packages/calcite-components/src/index.html b/packages/calcite-components/src/index.html index e2bed63436e..f3477f8eb27 100644 --- a/packages/calcite-components/src/index.html +++ b/packages/calcite-components/src/index.html @@ -284,6 +284,13 @@

Calcite demo

+ +
diff --git a/packages/calcite-components/stencil.config.ts b/packages/calcite-components/stencil.config.ts index 13a50b00eb7..873cff3d42f 100644 --- a/packages/calcite-components/stencil.config.ts +++ b/packages/calcite-components/stencil.config.ts @@ -52,6 +52,7 @@ export const create: () => Config = () => ({ { components: ["calcite-list", "calcite-list-item", "calcite-list-item-group"] }, { components: ["calcite-loader"] }, { components: ["calcite-meter"] }, + { components: ["calcite-month-picker", "calcite-month-picker-item"] }, { components: ["calcite-modal"] }, { components: ["calcite-navigation", "calcite-navigation-user", "calcite-navigation-logo"] }, { components: ["calcite-menu", "calcite-menu-item"] }, From 78c58ebad598e0a2e3ed661249b06080ffc50c5c Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 12 Dec 2023 17:40:59 -0600 Subject: [PATCH 002/155] emit change event when month is selected --- .../src/components/month-picker-item/month-picker-item.tsx | 4 ++-- .../src/components/month-picker/month-picker.scss | 3 ++- .../src/components/month-picker/month-picker.tsx | 5 ++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx index 0e8fc9b75b3..269703aa911 100644 --- a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx +++ b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx @@ -16,10 +16,10 @@ export class MonthPickerItem { * Emits whenever the component is selected. * */ - @Event() calciteInternalMonthPickerItemSelect: EventEmitter; + @Event() calciteInternalMonthPickerItemSelect: EventEmitter; private handleClick = (): void => { - this.calciteInternalMonthPickerItemSelect.emit(); + this.calciteInternalMonthPickerItemSelect.emit(this.value); }; render(): VNode { diff --git a/packages/calcite-components/src/components/month-picker/month-picker.scss b/packages/calcite-components/src/components/month-picker/month-picker.scss index cfc23394f8c..90fc14b8b51 100644 --- a/packages/calcite-components/src/components/month-picker/month-picker.scss +++ b/packages/calcite-components/src/components/month-picker/month-picker.scss @@ -1,5 +1,6 @@ :host { - display: block; + display: flex; + flex-direction: column; block-size: 344px; background-color: var(--calcite-color-foreground-1); font-size: var(--calcite-font-size--1); diff --git a/packages/calcite-components/src/components/month-picker/month-picker.tsx b/packages/calcite-components/src/components/month-picker/month-picker.tsx index c1d955bab84..67c42270cc7 100644 --- a/packages/calcite-components/src/components/month-picker/month-picker.tsx +++ b/packages/calcite-components/src/components/month-picker/month-picker.tsx @@ -57,9 +57,8 @@ export class MonthPicker implements LocalizedComponent { } @Listen("calciteInternalMonthPickerItemSelect") - handleCalciteMonthPickerItemChange(event: CustomEvent): void { - const target = event.target as HTMLCalciteMonthPickerItemElement; - this.activeMonthIndex = this.localeData?.months.wide.indexOf(target.value); + handleCalciteMonthPickerItemChange(event: CustomEvent): void { + this.activeMonthIndex = this.localeData?.months.wide.indexOf(event.detail); this.calciteMonthPickerChange.emit(); } From 963868b3e8dffab9b883097b82fbbda4ec1a4958 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 18 Dec 2023 17:58:01 -0600 Subject: [PATCH 003/155] redesign month-picker and adds year-picker --- .../month-picker-item/month-picker-item.scss | 11 +-- .../month-picker-item/month-picker-item.tsx | 2 +- .../components/month-picker/month-picker.scss | 33 ++++++- .../components/month-picker/month-picker.tsx | 11 ++- .../components/year-picker/year-picker.scss | 0 .../components/year-picker/year-picker.tsx | 93 +++++++++++++++++++ packages/calcite-components/stencil.config.ts | 2 +- 7 files changed, 136 insertions(+), 16 deletions(-) create mode 100644 packages/calcite-components/src/components/year-picker/year-picker.scss create mode 100644 packages/calcite-components/src/components/year-picker/year-picker.tsx diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss b/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss index 9233b40bb62..8d2f832a313 100644 --- a/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss +++ b/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss @@ -1,19 +1,16 @@ :host { display: flex; - block-size: 36px; } .month-item { display: flex; inline-size: 100%; @apply text-color-1; - padding-block: 8px; - padding-inline: 12px 8px; - &:hover { - background-color: var(--calcite-color-foreground-2); - } + justify-content: center; + align-items: center; } .month-item--active { - border-inline-start: 2px solid var(--calcite-color-brand); + background-color: var(--calcite-color-brand); + color: #ffffff; } diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx index 269703aa911..0edcd90614b 100644 --- a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx +++ b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx @@ -24,7 +24,7 @@ export class MonthPickerItem { render(): VNode { return ( - +
): void { - this.activeMonthIndex = this.localeData?.months.wide.indexOf(event.detail); + this.activeMonthIndex = this.localeData?.months.abbreviated.indexOf(event.detail); this.calciteMonthPickerChange.emit(); } render(): VNode { - console.log("render", this.localeData?.months); return ( - {this.localeData?.months.wide.map((month, index) => ( +
+
Year picker
+ + +
+ {this.localeData?.months.abbreviated.map((month, index) => ( ; + + connectedCallback() { + connectLocalized(this); + this.getYearList(); + } + + disconnectedCallback() { + disconnectLocalized(this); + } + + @Element() el: HTMLCalciteYearPickerElement; + + @State() effectiveLocale = ""; + + @State() localeData: DateLocaleData; + + private yearList: string[] = []; + + @Watch("effectiveLocale") + @Watch("numberingSystem") + getYearList(): void { + numberStringFormatter.numberFormatOptions = { + locale: this.effectiveLocale, + numberingSystem: this.numberingSystem, + useGrouping: false, + }; + this.yearList = []; + for (let i = this.min; i < this.max; i++) { + this.yearList.push(numberStringFormatter?.numberFormatter.format(i)); + } + } + + render(): VNode { + return ( + + {this.yearList?.map((year: string) => { + return ( + + {year} + + ); + })} + + ); + } +} diff --git a/packages/calcite-components/stencil.config.ts b/packages/calcite-components/stencil.config.ts index 873cff3d42f..e58c012d2ee 100644 --- a/packages/calcite-components/stencil.config.ts +++ b/packages/calcite-components/stencil.config.ts @@ -52,7 +52,7 @@ export const create: () => Config = () => ({ { components: ["calcite-list", "calcite-list-item", "calcite-list-item-group"] }, { components: ["calcite-loader"] }, { components: ["calcite-meter"] }, - { components: ["calcite-month-picker", "calcite-month-picker-item"] }, + { components: ["calcite-month-picker", "calcite-month-picker-item", "calcite-year-picker"] }, { components: ["calcite-modal"] }, { components: ["calcite-navigation", "calcite-navigation-user", "calcite-navigation-logo"] }, { components: ["calcite-menu", "calcite-menu-item"] }, From 47449cf3af95b76381582121b8cb6a3cc6d600ec Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 19 Dec 2023 17:47:38 -0600 Subject: [PATCH 004/155] add range and emit change event in year-picker --- .../components/year-picker/year-picker.scss | 10 ++ .../components/year-picker/year-picker.tsx | 101 ++++++++++++++---- 2 files changed, 93 insertions(+), 18 deletions(-) diff --git a/packages/calcite-components/src/components/year-picker/year-picker.scss b/packages/calcite-components/src/components/year-picker/year-picker.scss index e69de29bb2d..0429266d7eb 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.scss +++ b/packages/calcite-components/src/components/year-picker/year-picker.scss @@ -0,0 +1,10 @@ +:host { + display: flex; + flex-direction: row; + inline-size: 100%; +} + +.start-year, +.end-year { + inline-size: 50%; +} diff --git a/packages/calcite-components/src/components/year-picker/year-picker.tsx b/packages/calcite-components/src/components/year-picker/year-picker.tsx index e6501c05628..ee94b4e7102 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.tsx +++ b/packages/calcite-components/src/components/year-picker/year-picker.tsx @@ -1,6 +1,5 @@ import { Component, - // Host, VNode, h, Element, @@ -9,6 +8,7 @@ import { Watch, Event, EventEmitter, + Host, } from "@stencil/core"; import { LocalizedComponent, @@ -16,7 +16,6 @@ import { connectLocalized, disconnectLocalized, numberStringFormatter, - // numberingSystems, } from "../../utils/locale"; import { DateLocaleData } from "../date-picker/utils"; @@ -26,12 +25,18 @@ import { DateLocaleData } from "../date-picker/utils"; shadow: true, }) export class YearPicker implements LocalizedComponent { - @Prop() selectedYear: number; + @Prop({ mutable: true }) value: string; + + @Prop({ mutable: true }) maxValue: string; + + @Prop({ mutable: true }) minValue: string; @Prop() min = 1900; @Prop() max = 2100; + @Prop() range: boolean; + /** * Specifies the Unicode numeral system used by the component for localization. */ @@ -58,36 +63,96 @@ export class YearPicker implements LocalizedComponent { @State() localeData: DateLocaleData; - private yearList: string[] = []; + private yearList: number[] = []; + + selectEl: HTMLCalciteSelectElement; + + maxValueSelectEl: HTMLCalciteSelectElement; @Watch("effectiveLocale") @Watch("numberingSystem") - getYearList(): void { + updateNumberStringFormatter(): void { numberStringFormatter.numberFormatOptions = { locale: this.effectiveLocale, numberingSystem: this.numberingSystem, useGrouping: false, }; + } + + getYearList(): void { this.yearList = []; for (let i = this.min; i < this.max; i++) { - this.yearList.push(numberStringFormatter?.numberFormatter.format(i)); + this.yearList.push(i); } } + handleSelectChange = (event: CustomEvent): void => { + event.stopPropagation(); + const target = event.target as HTMLCalciteSelectElement; + const newValue = target.value; + if (this.range) { + this.minValue = newValue; + } else { + this.value = newValue; + } + + this.calciteYearPickerChange.emit(); + }; + + handleMaxValueSelectChange = (event: CustomEvent): void => { + event.stopPropagation(); + const target = event.target as HTMLCalciteSelectElement; + this.maxValue = target.value; + this.calciteYearPickerChange.emit(); + }; + + setSelectEl = (el: HTMLCalciteSelectElement): void => { + this.selectEl = el; + }; + + setMaxValueSelectEl = (el: HTMLCalciteSelectElement): void => { + this.maxValueSelectEl = el; + }; + render(): VNode { return ( - - {this.yearList?.map((year: string) => { - return ( - - {year} - - ); - })} - + + + {this.yearList?.map((year: number) => { + const yearString = year.toString(); + return ( + + {numberStringFormatter?.localize(yearString)} + + ); + })} + + {this.range && ( + + {this.yearList?.map((year: number) => { + const yearString = year.toString(); + return ( + + {numberStringFormatter?.localize(yearString)} + + ); + })} + + )} + ); } } From 2d67c2b282d4a0adc709e318ca88f41aa718597c Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 20 Dec 2023 16:59:33 -0600 Subject: [PATCH 005/155] disable years based on start and end year selected --- .../components/year-picker/year-picker.tsx | 141 ++++++++++++++---- 1 file changed, 110 insertions(+), 31 deletions(-) diff --git a/packages/calcite-components/src/components/year-picker/year-picker.tsx b/packages/calcite-components/src/components/year-picker/year-picker.tsx index ee94b4e7102..a4aa59a966e 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.tsx +++ b/packages/calcite-components/src/components/year-picker/year-picker.tsx @@ -17,7 +17,7 @@ import { disconnectLocalized, numberStringFormatter, } from "../../utils/locale"; -import { DateLocaleData } from "../date-picker/utils"; +// import { DateLocaleData } from "../date-picker/utils"; @Component({ tag: "calcite-year-picker", @@ -25,31 +25,81 @@ import { DateLocaleData } from "../date-picker/utils"; shadow: true, }) export class YearPicker implements LocalizedComponent { - @Prop({ mutable: true }) value: string; + //-------------------------------------------------------------------------- + // + // Public Properties + // + //-------------------------------------------------------------------------- - @Prop({ mutable: true }) maxValue: string; + /** When `true`, disables the component */ + @Prop({ reflect: true }) disabled: boolean; - @Prop({ mutable: true }) minValue: string; - - @Prop() min = 1900; + /** When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. */ + @Prop() disableYearsOutOfRange = false; + /** Specifies the latest allowed year (`"yyyy"`). */ @Prop() max = 2100; - @Prop() range: boolean; + /** Specifies the earliest allowed year (`"yyyy"`). */ + @Prop() min = 1900; + + @Watch("min") + @Watch("max") + handleMinChange(): void { + this.getYearList(); + } /** * Specifies the Unicode numeral system used by the component for localization. */ @Prop({ reflect: true }) numberingSystem: NumberingSystem; + /** When `true`, activates the component's range mode to allow a start and end year. */ + @Prop() range: boolean; + + /** + * Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). + */ + @Prop({ mutable: true }) value: number | number[]; + + @Watch("value") + handleValueChange(value: number | number[]): void { + if (Array.isArray(value)) { + this.startYear = value[0]; + this.endYear = value[1]; + } else if (value) { + this.startYear = value; + } + } + + //-------------------------------------------------------------------------- + // + // Events + // + //-------------------------------------------------------------------------- + /** * Emits whenever the component is selected. * */ @Event() calciteYearPickerChange: EventEmitter; + // -------------------------------------------------------------------------- + // + // Lifecycle + // + // -------------------------------------------------------------------------- + connectedCallback() { connectLocalized(this); + if (Array.isArray(this.value)) { + if (this.range) { + this.startYear = this.value[0]; + this.endYear = this.value[1]; + } + } else { + this.startYear = this.value; + } this.getYearList(); } @@ -57,18 +107,16 @@ export class YearPicker implements LocalizedComponent { disconnectLocalized(this); } + //-------------------------------------------------------------------------- + // + // Private State/Props + // + //-------------------------------------------------------------------------- + @Element() el: HTMLCalciteYearPickerElement; @State() effectiveLocale = ""; - @State() localeData: DateLocaleData; - - private yearList: number[] = []; - - selectEl: HTMLCalciteSelectElement; - - maxValueSelectEl: HTMLCalciteSelectElement; - @Watch("effectiveLocale") @Watch("numberingSystem") updateNumberStringFormatter(): void { @@ -79,6 +127,22 @@ export class YearPicker implements LocalizedComponent { }; } + @State() yearList: number[] = []; + + private endYear: number; + + private startYear: number; + + // maxValueSelectEl: HTMLCalciteSelectElement; + + // selectEl: HTMLCalciteSelectElement; + + //-------------------------------------------------------------------------- + // + // Private Methods + // + //-------------------------------------------------------------------------- + getYearList(): void { this.yearList = []; for (let i = this.min; i < this.max; i++) { @@ -89,9 +153,11 @@ export class YearPicker implements LocalizedComponent { handleSelectChange = (event: CustomEvent): void => { event.stopPropagation(); const target = event.target as HTMLCalciteSelectElement; - const newValue = target.value; - if (this.range) { - this.minValue = newValue; + const newValue = Number(target.value); + + if (this.range && Array.isArray(this.value)) { + this.value = [newValue, this.value[1]]; + this.startYear = newValue; } else { this.value = newValue; } @@ -99,35 +165,43 @@ export class YearPicker implements LocalizedComponent { this.calciteYearPickerChange.emit(); }; - handleMaxValueSelectChange = (event: CustomEvent): void => { + handleEndYearSelectChange = (event: CustomEvent): void => { event.stopPropagation(); const target = event.target as HTMLCalciteSelectElement; - this.maxValue = target.value; + const newValue = Number(target.value); + + if (Array.isArray(this.value)) { + this.value = [this.value[0], newValue]; + this.endYear = newValue; + } + this.calciteYearPickerChange.emit(); }; - setSelectEl = (el: HTMLCalciteSelectElement): void => { - this.selectEl = el; - }; + // setSelectEl = (el: HTMLCalciteSelectElement): void => { + // this.selectEl = el; + // }; - setMaxValueSelectEl = (el: HTMLCalciteSelectElement): void => { - this.maxValueSelectEl = el; - }; + // setMaxValueSelectEl = (el: HTMLCalciteSelectElement): void => { + // this.maxValueSelectEl = el; + // }; render(): VNode { return ( {this.yearList?.map((year: number) => { const yearString = year.toString(); return ( this.endYear && this.disableYearsOutOfRange} + selected={year === this.startYear} value={yearString} > {numberStringFormatter?.localize(yearString)} @@ -138,14 +212,19 @@ export class YearPicker implements LocalizedComponent { {this.range && ( {this.yearList?.map((year: number) => { const yearString = year.toString(); return ( - + {numberStringFormatter?.localize(yearString)} ); From 2657e2cf21c1cd08ed92416574b3dd5b10532b5f Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 22 Dec 2023 18:39:24 -0600 Subject: [PATCH 006/155] add year picker and month picker in date-picker-header --- .../calcite-components/src/components.d.ts | 202 ++++++++++++++++++ .../date-picker-month-header.tsx | 91 +++++--- .../components/month-picker/month-picker.scss | 11 +- .../components/month-picker/month-picker.tsx | 75 ++++++- .../src/components/select/select.scss | 5 +- .../components/year-picker/year-picker.tsx | 33 +++ packages/calcite-components/src/utils/date.ts | 16 ++ 7 files changed, 392 insertions(+), 41 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index ce68881ce6c..0c8aefe77c1 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -3105,6 +3105,29 @@ export namespace Components { */ "widthScale": Scale; } + interface CalciteMonthPicker { + /** + * Focused date with indicator (will become selected date if user proceeds) + */ + "activeDate": Date; + "activeMonthIndex": number; + /** + * Specifies the latest allowed date (`"yyyy-mm-dd"`). + */ + "max": Date; + /** + * Specifies the earliest allowed date (`"yyyy-mm-dd"`). + */ + "min": Date; + /** + * Already selected date. + */ + "selectedMonthYear": Date; + } + interface CalciteMonthPickerItem { + "isActive": boolean; + "value": string; + } interface CalciteNavigation { /** * When `navigationAction` is `true`, specifies the label of the `calcite-action`. @@ -5233,6 +5256,38 @@ export namespace Components { */ "value": any; } + interface CalciteYearPicker { + /** + * When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. + */ + "disableYearsOutOfRange": boolean; + /** + * When `true`, disables the component + */ + "disabled": boolean; + /** + * Specifies the latest allowed year (`"yyyy"`). + */ + "max": number; + /** + * Specifies the earliest allowed year (`"yyyy"`). + */ + "min": number; + "nextYear": () => Promise; + /** + * Specifies the Unicode numeral system used by the component for localization. + */ + "numberingSystem": NumberingSystem; + "prevYear": () => Promise; + /** + * When `true`, activates the component's range mode to allow a start and end year. + */ + "range": boolean; + /** + * Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). + */ + "value": number | number[]; + } } export interface CalciteAccordionCustomEvent extends CustomEvent { detail: T; @@ -5390,6 +5445,14 @@ export interface CalciteModalCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteModalElement; } +export interface CalciteMonthPickerCustomEvent extends CustomEvent { + detail: T; + target: HTMLCalciteMonthPickerElement; +} +export interface CalciteMonthPickerItemCustomEvent extends CustomEvent { + detail: T; + target: HTMLCalciteMonthPickerItemElement; +} export interface CalciteNavigationCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteNavigationElement; @@ -5542,6 +5605,10 @@ export interface CalciteValueListItemCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteValueListItemElement; } +export interface CalciteYearPickerCustomEvent extends CustomEvent { + detail: T; + target: HTMLCalciteYearPickerElement; +} declare global { interface HTMLCalciteAccordionElementEventMap { "calciteInternalAccordionChange": RequestedItem; @@ -6260,6 +6327,8 @@ declare global { }; interface HTMLCalciteListElementEventMap { "calciteListChange": void; + "calciteListDragEnd": ListDragDetail; + "calciteListDragStart": ListDragDetail; "calciteListFilter": void; "calciteListOrderChange": ListDragDetail; "calciteInternalListDefaultSlotChange": void; @@ -6379,6 +6448,40 @@ declare global { prototype: HTMLCalciteModalElement; new (): HTMLCalciteModalElement; }; + interface HTMLCalciteMonthPickerElementEventMap { + "calciteMonthPickerChange": void; + } + interface HTMLCalciteMonthPickerElement extends Components.CalciteMonthPicker, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLCalciteMonthPickerElement, ev: CalciteMonthPickerCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLCalciteMonthPickerElement, ev: CalciteMonthPickerCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + } + var HTMLCalciteMonthPickerElement: { + prototype: HTMLCalciteMonthPickerElement; + new (): HTMLCalciteMonthPickerElement; + }; + interface HTMLCalciteMonthPickerItemElementEventMap { + "calciteInternalMonthPickerItemSelect": string; + } + interface HTMLCalciteMonthPickerItemElement extends Components.CalciteMonthPickerItem, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLCalciteMonthPickerItemElement, ev: CalciteMonthPickerItemCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLCalciteMonthPickerItemElement, ev: CalciteMonthPickerItemCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + } + var HTMLCalciteMonthPickerItemElement: { + prototype: HTMLCalciteMonthPickerItemElement; + new (): HTMLCalciteMonthPickerItemElement; + }; interface HTMLCalciteNavigationElementEventMap { "calciteNavigationActionSelect": void; } @@ -7185,6 +7288,23 @@ declare global { prototype: HTMLCalciteValueListItemElement; new (): HTMLCalciteValueListItemElement; }; + interface HTMLCalciteYearPickerElementEventMap { + "calciteYearPickerChange": void; + } + interface HTMLCalciteYearPickerElement extends Components.CalciteYearPicker, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLCalciteYearPickerElement, ev: CalciteYearPickerCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLCalciteYearPickerElement, ev: CalciteYearPickerCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + } + var HTMLCalciteYearPickerElement: { + prototype: HTMLCalciteYearPickerElement; + new (): HTMLCalciteYearPickerElement; + }; interface HTMLElementTagNameMap { "calcite-accordion": HTMLCalciteAccordionElement; "calcite-accordion-item": HTMLCalciteAccordionItemElement; @@ -7240,6 +7360,8 @@ declare global { "calcite-menu-item": HTMLCalciteMenuItemElement; "calcite-meter": HTMLCalciteMeterElement; "calcite-modal": HTMLCalciteModalElement; + "calcite-month-picker": HTMLCalciteMonthPickerElement; + "calcite-month-picker-item": HTMLCalciteMonthPickerItemElement; "calcite-navigation": HTMLCalciteNavigationElement; "calcite-navigation-logo": HTMLCalciteNavigationLogoElement; "calcite-navigation-user": HTMLCalciteNavigationUserElement; @@ -7292,6 +7414,7 @@ declare global { "calcite-tree-item": HTMLCalciteTreeItemElement; "calcite-value-list": HTMLCalciteValueListElement; "calcite-value-list-item": HTMLCalciteValueListItemElement; + "calcite-year-picker": HTMLCalciteYearPickerElement; } } declare namespace LocalJSX { @@ -9984,6 +10107,14 @@ declare namespace LocalJSX { * Emits when any of the list item selections have changed. */ "onCalciteListChange"?: (event: CalciteListCustomEvent) => void; + /** + * Emits when the component's dragging has ended. + */ + "onCalciteListDragEnd"?: (event: CalciteListCustomEvent) => void; + /** + * Emits when the component's dragging has started. + */ + "onCalciteListDragStart"?: (event: CalciteListCustomEvent) => void; /** * Emits when the component's filter has changed. */ @@ -10383,6 +10514,37 @@ declare namespace LocalJSX { */ "widthScale"?: Scale; } + interface CalciteMonthPicker { + /** + * Focused date with indicator (will become selected date if user proceeds) + */ + "activeDate"?: Date; + "activeMonthIndex"?: number; + /** + * Specifies the latest allowed date (`"yyyy-mm-dd"`). + */ + "max"?: Date; + /** + * Specifies the earliest allowed date (`"yyyy-mm-dd"`). + */ + "min"?: Date; + /** + * Emits whenever the component is selected. + */ + "onCalciteMonthPickerChange"?: (event: CalciteMonthPickerCustomEvent) => void; + /** + * Already selected date. + */ + "selectedMonthYear"?: Date; + } + interface CalciteMonthPickerItem { + "isActive"?: boolean; + /** + * Emits whenever the component is selected. + */ + "onCalciteInternalMonthPickerItemSelect"?: (event: CalciteMonthPickerItemCustomEvent) => void; + "value"?: string; + } interface CalciteNavigation { /** * When `navigationAction` is `true`, specifies the label of the `calcite-action`. @@ -12591,6 +12753,40 @@ declare namespace LocalJSX { */ "value": any; } + interface CalciteYearPicker { + /** + * When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. + */ + "disableYearsOutOfRange"?: boolean; + /** + * When `true`, disables the component + */ + "disabled"?: boolean; + /** + * Specifies the latest allowed year (`"yyyy"`). + */ + "max"?: number; + /** + * Specifies the earliest allowed year (`"yyyy"`). + */ + "min"?: number; + /** + * Specifies the Unicode numeral system used by the component for localization. + */ + "numberingSystem"?: NumberingSystem; + /** + * Emits whenever the component is selected. + */ + "onCalciteYearPickerChange"?: (event: CalciteYearPickerCustomEvent) => void; + /** + * When `true`, activates the component's range mode to allow a start and end year. + */ + "range"?: boolean; + /** + * Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). + */ + "value"?: number | number[]; + } interface IntrinsicElements { "calcite-accordion": CalciteAccordion; "calcite-accordion-item": CalciteAccordionItem; @@ -12646,6 +12842,8 @@ declare namespace LocalJSX { "calcite-menu-item": CalciteMenuItem; "calcite-meter": CalciteMeter; "calcite-modal": CalciteModal; + "calcite-month-picker": CalciteMonthPicker; + "calcite-month-picker-item": CalciteMonthPickerItem; "calcite-navigation": CalciteNavigation; "calcite-navigation-logo": CalciteNavigationLogo; "calcite-navigation-user": CalciteNavigationUser; @@ -12698,6 +12896,7 @@ declare namespace LocalJSX { "calcite-tree-item": CalciteTreeItem; "calcite-value-list": CalciteValueList; "calcite-value-list-item": CalciteValueListItem; + "calcite-year-picker": CalciteYearPicker; } } export { LocalJSX as JSX }; @@ -12761,6 +12960,8 @@ declare module "@stencil/core" { "calcite-menu-item": LocalJSX.CalciteMenuItem & JSXBase.HTMLAttributes; "calcite-meter": LocalJSX.CalciteMeter & JSXBase.HTMLAttributes; "calcite-modal": LocalJSX.CalciteModal & JSXBase.HTMLAttributes; + "calcite-month-picker": LocalJSX.CalciteMonthPicker & JSXBase.HTMLAttributes; + "calcite-month-picker-item": LocalJSX.CalciteMonthPickerItem & JSXBase.HTMLAttributes; "calcite-navigation": LocalJSX.CalciteNavigation & JSXBase.HTMLAttributes; "calcite-navigation-logo": LocalJSX.CalciteNavigationLogo & JSXBase.HTMLAttributes; "calcite-navigation-user": LocalJSX.CalciteNavigationUser & JSXBase.HTMLAttributes; @@ -12828,6 +13029,7 @@ declare module "@stencil/core" { * @deprecated Use the `list` component instead. */ "calcite-value-list-item": LocalJSX.CalciteValueListItem & JSXBase.HTMLAttributes; + "calcite-year-picker": LocalJSX.CalciteYearPicker & JSXBase.HTMLAttributes; } } } diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 5f24f136f1e..9134cc0e6e7 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -5,6 +5,7 @@ import { EventEmitter, Fragment, h, + // Listen, Prop, State, VNode, @@ -17,6 +18,7 @@ import { nextMonth, prevMonth, formatCalendarYear, + requestedMonth, } from "../../utils/date"; import { closestElementCrossShadowBoundary } from "../../utils/dom"; @@ -24,7 +26,7 @@ import { isActivationKey } from "../../utils/key"; import { numberStringFormatter } from "../../utils/locale"; import { DatePickerMessages } from "../date-picker/assets/date-picker/t9n"; import { DateLocaleData } from "../date-picker/utils"; -import { Heading, HeadingLevel } from "../functional/Heading"; +import { HeadingLevel } from "../functional/Heading"; import { Scale } from "../interfaces"; import { CSS, ICON } from "./resources"; import { getIconScale } from "../../utils/component"; @@ -125,13 +127,41 @@ export class DatePickerMonthHeader { const activeMonth = activeDate.getMonth(); const { months, unitOrder } = localeData; - const localizedMonth = (months.wide || months.narrow || months.abbreviated)[activeMonth]; - const localizedYear = this.formatCalendarYear(activeDate.getFullYear()); + //const localizedMonth = (months.wide || months.narrow || months.abbreviated)[activeMonth]; + //const localizedYear = this.formatCalendarYear(activeDate.getFullYear()); const order = getOrder(unitOrder); const reverse = order.indexOf("y") < order.indexOf("m"); - const suffix = localeData.year?.suffix; + //const suffix = localeData.year?.suffix; + + //console.log("active month", activeMonth); return ( +
+ + {months.abbreviated?.map((month: string, index: number) => { + return ( + this.endYear && this.disableYearsOutOfRange} + selected={index === activeMonth} + value={month} + > + {month} + + ); + })} + + + +
-
- - {localizedMonth} - - - (this.yearInput = el)} - /> - {suffix && {suffix}} - -
{ - this.setYear({ - localizedYear: this.parseCalendarYear((event.target as HTMLInputElement).value), - }); + const target = event.target as HTMLCalciteYearPickerElement; + if (!Array.isArray(target.value)) { + this.setYear({ + localizedYear: numberStringFormatter.localize( + `${parseCalendarYear(target.value, this.localeData)}` + ), + }); + } }; private onYearInput = (event: Event): void => { @@ -289,6 +300,13 @@ export class DatePickerMonthHeader { this.calciteInternalDatePickerSelect.emit(date); }; + handleMonthChange = (event: CustomEvent): void => { + const target = event.target as HTMLCalciteOptionElement; + const monthIndex = this.localeData.months.abbreviated.indexOf(target.value); + const newDate = requestedMonth(this.activeDate, monthIndex); + this.calciteInternalDatePickerSelect.emit(newDate); + }; + private getInRangeDate({ localizedYear, offset = 0, @@ -340,4 +358,11 @@ export class DatePickerMonthHeader { yearInput.value = this.formatCalendarYear((inRangeDate || activeDate).getFullYear()); } } + + private getYearList(min: number, max: number): void { + this.yearList = []; + for (let i = min; i < max; i++) { + this.yearList.push(i); + } + } } diff --git a/packages/calcite-components/src/components/month-picker/month-picker.scss b/packages/calcite-components/src/components/month-picker/month-picker.scss index 3c075690c7b..1a77360ae71 100644 --- a/packages/calcite-components/src/components/month-picker/month-picker.scss +++ b/packages/calcite-components/src/components/month-picker/month-picker.scss @@ -18,16 +18,21 @@ grid-area: header; display: flex; justify-content: space-between; + align-items: center; } .year-picker { inline-size: 278px; } -.next { +.next, +.previous { inline-size: 40px; + block-size: 100%; } -.previous { - inline-size: 40px; +calcite-year-picker { + // width: 100px; + --calcite-select-internal-border-width: 0px; + --calcite-select-internal-icon-border-inline-end-width: 0px; } diff --git a/packages/calcite-components/src/components/month-picker/month-picker.tsx b/packages/calcite-components/src/components/month-picker/month-picker.tsx index a5ed9817e55..91a97f75ff6 100644 --- a/packages/calcite-components/src/components/month-picker/month-picker.tsx +++ b/packages/calcite-components/src/components/month-picker/month-picker.tsx @@ -21,14 +21,44 @@ import { DateLocaleData, getLocaleData } from "../date-picker/utils"; shadow: true, }) export class MonthPicker implements LocalizedComponent { + //-------------------------------------------------------------------------- + // + // Public Properties + // + //-------------------------------------------------------------------------- + @Prop({ mutable: true }) activeMonthIndex: number; + /** Already selected date. */ + @Prop() selectedMonthYear: Date; + + /** Focused date with indicator (will become selected date if user proceeds) */ + @Prop() activeDate: Date; + + /** Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ + @Prop() min: Date; + + /** Specifies the latest allowed date (`"yyyy-mm-dd"`). */ + @Prop() max: Date; + + //-------------------------------------------------------------------------- + // + // Events + // + //-------------------------------------------------------------------------- + /** * Emits whenever the component is selected. * */ @Event() calciteMonthPickerChange: EventEmitter; + // -------------------------------------------------------------------------- + // + // Lifecycle + // + // -------------------------------------------------------------------------- + connectedCallback() { connectLocalized(this); } @@ -41,6 +71,12 @@ export class MonthPicker implements LocalizedComponent { disconnectLocalized(this); } + //-------------------------------------------------------------------------- + // + // Private State/Props + // + //-------------------------------------------------------------------------- + @Element() el: HTMLCalciteMonthPickerElement; @State() effectiveLocale = ""; @@ -56,19 +92,52 @@ export class MonthPicker implements LocalizedComponent { this.localeData = await getLocaleData(this.effectiveLocale); } + yearPickerEl: HTMLCalciteYearPickerElement; + + //-------------------------------------------------------------------------- + // + // Private Methods + // + //-------------------------------------------------------------------------- + @Listen("calciteInternalMonthPickerItemSelect") handleCalciteMonthPickerItemChange(event: CustomEvent): void { this.activeMonthIndex = this.localeData?.months.abbreviated.indexOf(event.detail); this.calciteMonthPickerChange.emit(); } + handlePreviousYear = (): void => { + this.yearPickerEl.prevYear(); + }; + + handleNextYear = (): void => { + console.log("next year"); + this.yearPickerEl.nextYear(); + }; + + setYearPickerEl = (el: HTMLCalciteYearPickerElement): void => { + this.yearPickerEl = el; + }; + render(): VNode { return (
-
Year picker
- - + + +
{this.localeData?.months.abbreviated.map((month, index) => ( { + if (Array.isArray(this.value)) { + this.value = + this.activeRange === "start" + ? [this.value[0] - 1, this.value[1]] + : [this.value[0], this.value[1] - 1]; + } else { + this.value = this.value - 1; + } + } + + @Method() + async nextYear(): Promise { + console.log("next year", this.value); + if (Array.isArray(this.value)) { + this.value = + this.activeRange === "start" + ? [this.value[0] + 1, this.value[1]] + : [this.value[0], this.value[1] + 1]; + } else { + this.value = this.value + 1; + } + } //-------------------------------------------------------------------------- // // Private State/Props @@ -133,6 +161,8 @@ export class YearPicker implements LocalizedComponent { private startYear: number; + private activeRange: "start" | "end" = "start"; + // maxValueSelectEl: HTMLCalciteSelectElement; // selectEl: HTMLCalciteSelectElement; @@ -152,6 +182,8 @@ export class YearPicker implements LocalizedComponent { handleSelectChange = (event: CustomEvent): void => { event.stopPropagation(); + + this.activeRange = "start"; const target = event.target as HTMLCalciteSelectElement; const newValue = Number(target.value); @@ -169,6 +201,7 @@ export class YearPicker implements LocalizedComponent { event.stopPropagation(); const target = event.target as HTMLCalciteSelectElement; const newValue = Number(target.value); + this.activeRange = "end"; if (Array.isArray(this.value)) { this.value = [this.value[0], newValue]; diff --git a/packages/calcite-components/src/utils/date.ts b/packages/calcite-components/src/utils/date.ts index cbb9ee1b3fa..8a9590411e6 100644 --- a/packages/calcite-components/src/utils/date.ts +++ b/packages/calcite-components/src/utils/date.ts @@ -199,6 +199,22 @@ export function prevMonth(date: Date): Date { return nextDate; } +/** + * Get a date for the specified Month + * + * @param date + * @param month + */ +export function requestedMonth(date: Date, month: number): Date { + const nextDate = new Date(date); + nextDate.setMonth(month); + // date doesn't exist in new month, use last day + if (month !== date.getMonth()) { + return new Date(date.getFullYear(), month + 1, 0); + } + return nextDate; +} + /** * Get a date one month in the future * From cfad87b9db9a79b0b81e4368d99ce1643ec97a66 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 27 Dec 2023 17:21:31 -0600 Subject: [PATCH 007/155] add second date-picker in input-date-picker when range is enabled --- .../date-picker-month-header.scss | 18 ++--- .../date-picker-month-header.tsx | 72 ++++++++++--------- .../date-picker-month/date-picker-month.scss | 1 - .../input-date-picker/input-date-picker.tsx | 25 ++++++- .../components/year-picker/year-picker.scss | 4 ++ .../components/year-picker/year-picker.tsx | 11 ++- 6 files changed, 81 insertions(+), 50 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss index 4a2868b70d0..c70da7b48ad 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss @@ -11,34 +11,30 @@ .text { @apply text-n1h my-2; } - .chevron { - @apply h-9; - } } :host([scale="m"]) { .text { @apply text-0h my-3; } - .chevron { - @apply h-12; - } } :host([scale="l"]) { .text { @apply text-1h my-4; } - .chevron { - block-size: 3.5rem; - } +} + +.chevron-container { + display: flex; + inline-size: 80px; } .chevron { @apply text-color-3 bg-foreground-1 focus-base - -mx-1 + mx-1 box-content flex flex-grow-0 @@ -49,7 +45,7 @@ px-1 outline-none transition-default; - inline-size: calc(100% / 7); + inline-size: 40px; &:focus { @apply focus-inset; diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 9134cc0e6e7..3951b06f4d4 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -141,6 +141,7 @@ export class DatePickerMonthHeader { class="start-year" label={"start year"} onCalciteSelectChange={this.handleMonthChange} + width="full" > {months.abbreviated?.map((month: string, index: number) => { return ( @@ -158,34 +159,39 @@ export class DatePickerMonthHeader { (this.yearPickerEl = el)} />
- - - - - - + ); } @@ -198,10 +204,10 @@ export class DatePickerMonthHeader { @Element() el: HTMLCalciteDatePickerMonthHeaderElement; - private yearInput: HTMLInputElement; - private parentDatePickerEl: HTMLCalciteDatePickerElement; + private yearPickerEl: HTMLCalciteYearPickerElement; + @State() nextMonthDate: Date; @State() prevMonthDate: Date; @@ -265,13 +271,6 @@ export class DatePickerMonthHeader { } }; - private onYearInput = (event: Event): void => { - this.setYear({ - localizedYear: this.parseCalendarYear((event.target as HTMLInputElement).value), - commit: false, - }); - }; - private prevMonthClick = (event: KeyboardEvent | MouseEvent): void => { this.handleArrowClick(event, this.prevMonthDate); }; @@ -346,7 +345,7 @@ export class DatePickerMonthHeader { commit?: boolean; offset?: number; }): void { - const { yearInput, activeDate } = this; + const { activeDate } = this; const inRangeDate = this.getInRangeDate({ localizedYear, offset }); // if you've supplied a year and it's in range, update active date @@ -355,7 +354,10 @@ export class DatePickerMonthHeader { } if (commit) { - yearInput.value = this.formatCalendarYear((inRangeDate || activeDate).getFullYear()); + this.yearPickerEl.value = formatCalendarYear( + (inRangeDate || activeDate).getFullYear(), + this.localeData + ); } } diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss index 60c1e853b2a..4c0aea2a03a 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss @@ -8,7 +8,6 @@ @apply border-color-3 flex border-0 - border-t border-solid py-0 px-1; diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 360d9cbc606..e4a953f862b 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -580,7 +580,7 @@ export class InputDatePicker > + + {this.range && ( + + )}
diff --git a/packages/calcite-components/src/components/year-picker/year-picker.scss b/packages/calcite-components/src/components/year-picker/year-picker.scss index 0429266d7eb..d65952fa956 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.scss +++ b/packages/calcite-components/src/components/year-picker/year-picker.scss @@ -8,3 +8,7 @@ .end-year { inline-size: 50%; } + +.year { + inline-size: 100%; +} diff --git a/packages/calcite-components/src/components/year-picker/year-picker.tsx b/packages/calcite-components/src/components/year-picker/year-picker.tsx index 174577e5af5..be47e134e1b 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.tsx +++ b/packages/calcite-components/src/components/year-picker/year-picker.tsx @@ -18,6 +18,7 @@ import { disconnectLocalized, numberStringFormatter, } from "../../utils/locale"; +import { DateLocaleData, getLocaleData } from "../date-picker/utils"; // import { DateLocaleData } from "../date-picker/utils"; @Component({ @@ -147,12 +148,14 @@ export class YearPicker implements LocalizedComponent { @Watch("effectiveLocale") @Watch("numberingSystem") - updateNumberStringFormatter(): void { + async updateNumberStringFormatter(): Promise { numberStringFormatter.numberFormatOptions = { locale: this.effectiveLocale, numberingSystem: this.numberingSystem, useGrouping: false, }; + + this.localeData = await getLocaleData(this.effectiveLocale); } @State() yearList: number[] = []; @@ -163,6 +166,8 @@ export class YearPicker implements LocalizedComponent { private activeRange: "start" | "end" = "start"; + @State() localeData: DateLocaleData; + // maxValueSelectEl: HTMLCalciteSelectElement; // selectEl: HTMLCalciteSelectElement; @@ -220,10 +225,11 @@ export class YearPicker implements LocalizedComponent { // }; render(): VNode { + const suffix = this.localeData?.year?.suffix; return ( {numberStringFormatter?.localize(yearString)} + {suffix} ); })} From bf7179bb2b969fc9076997c9527176c19bc93673 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 29 Dec 2023 17:46:42 -0600 Subject: [PATCH 008/155] revert input-date-picker changes and update date-picker for range --- .../date-picker-month-header.tsx | 66 +++++------ .../components/date-picker/date-picker.scss | 27 +++++ .../components/date-picker/date-picker.tsx | 106 +++++++++++++++--- .../input-date-picker/input-date-picker.tsx | 25 +---- 4 files changed, 149 insertions(+), 75 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 3951b06f4d4..28fa77b21e0 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -76,6 +76,9 @@ export class DatePickerMonthHeader { // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module @Prop({ mutable: true }) messages: DatePickerMessages; + /** @internal */ + @Prop() position: "start" | "end"; + //-------------------------------------------------------------------------- // // Events @@ -127,13 +130,9 @@ export class DatePickerMonthHeader { const activeMonth = activeDate.getMonth(); const { months, unitOrder } = localeData; - //const localizedMonth = (months.wide || months.narrow || months.abbreviated)[activeMonth]; - //const localizedYear = this.formatCalendarYear(activeDate.getFullYear()); const order = getOrder(unitOrder); const reverse = order.indexOf("y") < order.indexOf("m"); - //const suffix = localeData.year?.suffix; - //console.log("active month", activeMonth); return (
@@ -167,30 +166,34 @@ export class DatePickerMonthHeader { />
- - - - - - + {this.position !== "end" && ( + + + + )} + {this.position !== "start" && ( + + + + )}
); @@ -360,11 +363,4 @@ export class DatePickerMonthHeader { ); } } - - private getYearList(min: number, max: number): void { - this.yearList = []; - for (let i = min; i < max; i++) { - this.yearList.push(i); - } - } } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.scss b/packages/calcite-components/src/components/date-picker/date-picker.scss index c94b0112c41..bd8f497b819 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.scss +++ b/packages/calcite-components/src/components/date-picker/date-picker.scss @@ -16,16 +16,43 @@ max-inline-size: 380px; } +:host([scale="s"][range]) { + inline-size: 480px; + min-inline-size: 432px; + max-inline-size: 772px; +} + :host([scale="m"]) { inline-size: 304px; min-inline-size: 272px; max-inline-size: 480px; } +:host([scale="m"][range]) { + inline-size: 620px; + min-inline-size: 544px; + max-inline-size: 972px; +} + :host([scale="l"]) { inline-size: 370px; min-inline-size: 320px; max-inline-size: 600px; } +:host([scale="l"][range]) { + inline-size: 752px; + min-inline-size: 640px; + max-inline-size: 1212px; +} + +.container { + display: flex; + flex-direction: row; +} + +:host([range]) .start { + margin-inline-end: 12px; +} + @include base-component(); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index f12e7f28f3e..b652506797c 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -18,6 +18,8 @@ import { dateToISO, getDaysDiff, HoverRange, + nextMonth, + prevMonth, setEndOfDay, } from "../../utils/date"; import { @@ -208,7 +210,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom connectedCallback(): void { connectLocalized(this); connectMessages(this); - if (Array.isArray(this.value)) { this.valueAsDate = getValueAsDateRange(this.value); } else if (this.value) { @@ -252,14 +253,16 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.range && Array.isArray(this.valueAsDate) ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) : null; - const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); - if ( - (this.activeRange === "end" || - (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && - activeEndDate - ) { - activeDate = activeEndDate; - } + //const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); + + // if ( + // (this.activeRange === "end" || + // (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && + // activeEndDate + // ) { + // activeDate = activeEndDate; + // } + if (this.range && this.mostRecentRangeValue) { activeDate = this.mostRecentRangeValue; } @@ -277,9 +280,39 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom ? endDate || this.maxAsDate : this.maxAsDate : this.maxAsDate; + return ( - {this.renderCalendar(activeDate, maxDate, minDate, date, endDate)} +
+
+ {this.renderCalendar( + this.activeStartDate || this.getDisplayedDate("start"), + maxDate, + minDate, + date, + endDate, + this.range ? "start" : null + )} +
+
+ {this.range && + this.renderCalendar( + // sameDate(activeDate, activeEndDate) ? nextMonth(activeEndDate) : this.activeEndDate, + // this.activeEndDate || nextMonth(activeDate), + this.activeStartDate + ? nextMonth(this.activeStartDate) + : activeDate + ? nextMonth(activeDate) + : nextMonth(new Date()), + + maxDate, + minDate, + date, + endDate, + "end" + )} +
+
); } @@ -367,16 +400,26 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom monthHeaderSelectChange = (event: CustomEvent): void => { const date = new Date(event.detail); + const target = event.target as HTMLCalciteDatePickerMonthHeaderElement; + if (!this.range) { this.activeDate = date; } else { - if (this.activeRange === "end") { + if (target.position === "end") { this.activeEndDate = date; + this.activeStartDate = this.activeStartDate + ? nextMonth(this.activeStartDate) + : nextMonth(new Date()); + this.activeDate = this.activeStartDate; } else { this.activeStartDate = date; + this.activeDate = date; + this.activeEndDate = this.activeEndDate + ? prevMonth(this.activeEndDate) + : prevMonth(new Date()); } - this.mostRecentRangeValue = date; } + this.mostRecentRangeValue = date; }; monthActiveDateChange = (event: CustomEvent): void => { @@ -473,14 +516,17 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom * @param minDate * @param date * @param endDate + * @param position */ private renderCalendar( activeDate: Date, maxDate: Date, minDate: Date, date: Date, - endDate: Date + endDate: Date, + position?: "start" | "end" ) { + // debugger; return ( this.localeData && [ , @@ -507,7 +554,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom onCalciteInternalDatePickerMouseOut={this.monthMouseOutChange} onCalciteInternalDatePickerSelect={this.monthDateChange} scale={this.scale} - selectedDate={this.activeRange === "end" ? endDate : date} + selectedDate={position === "end" ? endDate : date} startDate={this.range ? date : undefined} />, ] @@ -566,7 +613,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private monthDateChange = (event: CustomEvent): void => { const date = new Date(event.detail); const isoDate = dateToISO(date); - + // debugger; if (!this.range && isoDate === dateToISO(this.valueAsDate as Date)) { return; } @@ -634,7 +681,34 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private getActiveEndDate(value: Date | null, min: Date | null, max: Date | null): Date { return ( - dateFromRange(this.activeEndDate, min, max) || value || dateFromRange(new Date(), min, max) + dateFromRange(this.activeEndDate, min, max) || + value || + dateFromRange(nextMonth(new Date()), min, max) ); } + + private getDisplayedDate(position: "start" | "end"): Date { + if (position === "start") { + const date = dateFromRange( + this.range && Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, + this.minAsDate, + this.maxAsDate + ); + let activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); + + if (this.range && this.mostRecentRangeValue) { + activeDate = this.mostRecentRangeValue; + } + + return activeDate; + } + + const endDate = + this.range && Array.isArray(this.valueAsDate) + ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) + : null; + const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); + + return activeEndDate; + } } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index e4a953f862b..360d9cbc606 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -580,7 +580,7 @@ export class InputDatePicker > - - {this.range && ( - - )} From d1a0da2e1e75b2502428c0f866b258cccc51dcb9 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 3 Jan 2024 13:02:08 -0600 Subject: [PATCH 009/155] simplify calendar render logic --- .../date-picker-month-header.tsx | 45 ++++--- .../components/date-picker/date-picker.tsx | 120 +++++++++--------- .../components/year-picker/year-picker.tsx | 24 +++- 3 files changed, 102 insertions(+), 87 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 28fa77b21e0..2fd3aba9fe1 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -5,7 +5,6 @@ import { EventEmitter, Fragment, h, - // Listen, Prop, State, VNode, @@ -136,25 +135,7 @@ export class DatePickerMonthHeader { return (
- - {months.abbreviated?.map((month: string, index: number) => { - return ( - this.endYear && this.disableYearsOutOfRange} - selected={index === activeMonth} - value={month} - > - {month} - - ); - })} - - + {this.renderMonthPicker(months, activeMonth)} + {months.abbreviated?.map((month: string, index: number) => { + return ( + this.endYear && this.disableYearsOutOfRange} + selected={index === activeMonth} + value={month} + > + {month} + + ); + })} + + ); + } + //-------------------------------------------------------------------------- // // Private State/Props @@ -265,6 +269,7 @@ export class DatePickerMonthHeader { private onYearChange = (event: Event): void => { const target = event.target as HTMLCalciteYearPickerElement; + console.log("year change"); if (!Array.isArray(target.value)) { this.setYear({ localizedYear: numberStringFormatter.localize( diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index b652506797c..4c0d3171154 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -253,42 +253,52 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.range && Array.isArray(this.valueAsDate) ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) : null; - //const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); + const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); - // if ( - // (this.activeRange === "end" || - // (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && - // activeEndDate - // ) { - // activeDate = activeEndDate; - // } + if ( + (this.activeRange === "end" || + (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && + activeEndDate + ) { + activeDate = activeEndDate; + } if (this.range && this.mostRecentRangeValue) { activeDate = this.mostRecentRangeValue; } - const minDate = - this.range && this.activeRange - ? this.activeRange === "start" - ? this.minAsDate - : date || this.minAsDate - : this.minAsDate; - - const maxDate = - this.range && this.activeRange - ? this.activeRange === "start" - ? endDate || this.maxAsDate - : this.maxAsDate - : this.maxAsDate; + const minStartDate = this.activeRange + ? this.activeRange === "start" + ? this.minAsDate + : date + : this.minAsDate; + + const maxStartDate = this.activeRange + ? this.activeRange === "start" + ? endDate + : this.maxAsDate + : this.maxAsDate; + + const minEndDate = this.activeRange + ? this.activeRange === "start" + ? this.minAsDate + : date + : this.minAsDate; + + const maxEndDate = this.activeRange + ? this.activeRange === "start" + ? endDate + : this.maxAsDate + : this.maxAsDate; return (
{this.renderCalendar( - this.activeStartDate || this.getDisplayedDate("start"), - maxDate, - minDate, + this.getStartCalendarActiveDate(activeDate), + maxStartDate, + minStartDate, date, endDate, this.range ? "start" : null @@ -297,16 +307,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.range && this.renderCalendar( - // sameDate(activeDate, activeEndDate) ? nextMonth(activeEndDate) : this.activeEndDate, - // this.activeEndDate || nextMonth(activeDate), - this.activeStartDate - ? nextMonth(this.activeStartDate) - : activeDate - ? nextMonth(activeDate) - : nextMonth(new Date()), - - maxDate, - minDate, + this.getEndCalendarActiveDate(activeDate), + maxEndDate, + minEndDate, date, endDate, "end" @@ -409,17 +412,13 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeEndDate = date; this.activeStartDate = this.activeStartDate ? nextMonth(this.activeStartDate) - : nextMonth(new Date()); - this.activeDate = this.activeStartDate; + : prevMonth(date); } else { this.activeStartDate = date; - this.activeDate = date; - this.activeEndDate = this.activeEndDate - ? prevMonth(this.activeEndDate) - : prevMonth(new Date()); + this.activeEndDate = this.activeEndDate ? prevMonth(this.activeEndDate) : nextMonth(date); } + this.mostRecentRangeValue = date; } - this.mostRecentRangeValue = date; }; monthActiveDateChange = (event: CustomEvent): void => { @@ -526,7 +525,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom endDate: Date, position?: "start" | "end" ) { - // debugger; return ( this.localeData && [ ): void => { const date = new Date(event.detail); const isoDate = dateToISO(date); - // debugger; if (!this.range && isoDate === dateToISO(this.valueAsDate as Date)) { return; } @@ -687,28 +684,25 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom ); } - private getDisplayedDate(position: "start" | "end"): Date { - if (position === "start") { - const date = dateFromRange( - this.range && Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, - this.minAsDate, - this.maxAsDate - ); - let activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); - - if (this.range && this.mostRecentRangeValue) { - activeDate = this.mostRecentRangeValue; + private getStartCalendarActiveDate(activeDate: Date): Date { + if (this.range) { + if (this.activeStartDate) { + return this.activeStartDate; + } else { + return this.activeRange === "start" ? activeDate : prevMonth(activeDate); } - - return activeDate; } + return activeDate; + } - const endDate = - this.range && Array.isArray(this.valueAsDate) - ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) - : null; - const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); - - return activeEndDate; + private getEndCalendarActiveDate(activeDate: Date): Date { + if (this.range) { + if (this.activeEndDate) { + return this.activeEndDate; + } else { + return this.activeRange === "end" ? activeDate : nextMonth(activeDate); + } + } + return activeDate; } } diff --git a/packages/calcite-components/src/components/year-picker/year-picker.tsx b/packages/calcite-components/src/components/year-picker/year-picker.tsx index be47e134e1b..91d198db6ee 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.tsx +++ b/packages/calcite-components/src/components/year-picker/year-picker.tsx @@ -46,8 +46,20 @@ export class YearPicker implements LocalizedComponent { @Prop() min = 1900; @Watch("min") + handleMinChange(value: number): void { + if (!value) { + this.min = 1900; + return; + } + this.getYearList(); + } + @Watch("max") - handleMinChange(): void { + handleMaxChange(value: number): void { + if (!value) { + this.max = 2100; + return; + } this.getYearList(); } @@ -126,7 +138,7 @@ export class YearPicker implements LocalizedComponent { @Method() async nextYear(): Promise { - console.log("next year", this.value); + // console.log("next year", this.value); if (Array.isArray(this.value)) { this.value = this.activeRange === "start" @@ -180,7 +192,7 @@ export class YearPicker implements LocalizedComponent { getYearList(): void { this.yearList = []; - for (let i = this.min; i < this.max; i++) { + for (let i = this.min; i <= this.max; i++) { this.yearList.push(i); } } @@ -216,6 +228,10 @@ export class YearPicker implements LocalizedComponent { this.calciteYearPickerChange.emit(); }; + private isYearSelected(year: number): boolean { + return !Array.isArray(this.value) ? year === this.value : false; + } + // setSelectEl = (el: HTMLCalciteSelectElement): void => { // this.selectEl = el; // }; @@ -240,7 +256,7 @@ export class YearPicker implements LocalizedComponent { return ( this.endYear && this.disableYearsOutOfRange} - selected={year === this.startYear} + selected={(this.range && year === this.startYear) || this.isYearSelected(year)} value={yearString} > {numberStringFormatter?.localize(yearString)} From 11f48d81e70f60b92db61504fc95fb5387455a10 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 3 Jan 2024 18:07:48 -0600 Subject: [PATCH 010/155] allows editing date values and navigating using action buttons --- .../components/date-picker/date-picker.tsx | 76 +++++++++++-------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 4c0d3171154..ce980d8d79e 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -248,24 +248,30 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.minAsDate, this.maxAsDate ); - let activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); + const activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); const endDate = this.range && Array.isArray(this.valueAsDate) ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) : null; const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); - if ( - (this.activeRange === "end" || - (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && - activeEndDate - ) { - activeDate = activeEndDate; - } + // if ( + // (this.activeRange === "end" || + // (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && + // activeEndDate + // ) { + // activeDate = activeEndDate; + // } - if (this.range && this.mostRecentRangeValue) { - activeDate = this.mostRecentRangeValue; - } + // if (this.range && this.mostRecentRangeValue) { + // activeDate = this.mostRecentRangeValue; + // } + + console.log(activeDate, activeEndDate); + console.log(`%c ${this.activeStartDate}, ${this.activeEndDate}`, "color:red"); + console.log(`%c ${this.activeDate}`, "color:green"); + + console.log("value as date", this.valueAsDate); const minStartDate = this.activeRange ? this.activeRange === "start" @@ -296,7 +302,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.renderCalendar( - this.getStartCalendarActiveDate(activeDate), + this.getStartCalendarActiveDate( + this.activeRange === "start" ? activeDate : activeEndDate + ), maxStartDate, minStartDate, date, @@ -307,7 +315,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.range && this.renderCalendar( - this.getEndCalendarActiveDate(activeDate), + this.getEndCalendarActiveDate( + this.activeRange === "end" ? activeEndDate : activeDate + ), maxEndDate, minEndDate, date, @@ -413,9 +423,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeStartDate = this.activeStartDate ? nextMonth(this.activeStartDate) : prevMonth(date); + // this.activeDate = this.activeStartDate; } else { this.activeStartDate = date; this.activeEndDate = this.activeEndDate ? prevMonth(this.activeEndDate) : nextMonth(date); + // this.activeDate = date; } this.mostRecentRangeValue = date; } @@ -673,7 +685,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom * @param max */ private getActiveDate(value: Date | null, min: Date | null, max: Date | null): Date { - return dateFromRange(this.activeDate, min, max) || value || dateFromRange(new Date(), min, max); + return ( + dateFromRange(this.activeStartDate || this.activeDate, min, max) || + value || + dateFromRange(new Date(), min, max) + ); } private getActiveEndDate(value: Date | null, min: Date | null, max: Date | null): Date { @@ -685,24 +701,24 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } private getStartCalendarActiveDate(activeDate: Date): Date { - if (this.range) { - if (this.activeStartDate) { - return this.activeStartDate; - } else { - return this.activeRange === "start" ? activeDate : prevMonth(activeDate); - } - } - return activeDate; + // if (this.range) { + // if (this.activeStartDate) { + // return this.activeStartDate; + // } else { + return this.activeRange === "start" ? activeDate : prevMonth(activeDate); + // } + // } + // return activeDate; } private getEndCalendarActiveDate(activeDate: Date): Date { - if (this.range) { - if (this.activeEndDate) { - return this.activeEndDate; - } else { - return this.activeRange === "end" ? activeDate : nextMonth(activeDate); - } - } - return activeDate; + // if (this.range) { + // if (this.activeEndDate) { + // return this.activeEndDate; + // } else { + return this.activeRange === "end" ? activeDate : nextMonth(activeDate); + // } + // } + // return activeDate; } } From 6967b7b830e627bb7588adbf7828f6d1d84f6c9c Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 3 Jan 2024 18:14:29 -0600 Subject: [PATCH 011/155] clean up --- .../src/components/date-picker/date-picker.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index ce980d8d79e..40c1e5282aa 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -267,12 +267,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom // activeDate = this.mostRecentRangeValue; // } - console.log(activeDate, activeEndDate); - console.log(`%c ${this.activeStartDate}, ${this.activeEndDate}`, "color:red"); - console.log(`%c ${this.activeDate}`, "color:green"); - - console.log("value as date", this.valueAsDate); - const minStartDate = this.activeRange ? this.activeRange === "start" ? this.minAsDate From d813943ff3fdcb59d1d49597ae661ad79aaa6709 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 5 Jan 2024 18:57:28 -0600 Subject: [PATCH 012/155] allows start date in range to be greater than end date, unhide date-picker when switching between input's --- .../components/date-picker/date-picker.tsx | 64 +++++++------------ .../input-date-picker/input-date-picker.tsx | 16 +++-- 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 40c1e5282aa..2174a5bec84 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -255,37 +255,18 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : null; const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); - // if ( - // (this.activeRange === "end" || - // (this.hoverRange?.focused === "end" && (!this.proximitySelectionDisabled || endDate))) && - // activeEndDate - // ) { - // activeDate = activeEndDate; - // } - // if (this.range && this.mostRecentRangeValue) { // activeDate = this.mostRecentRangeValue; // } - const minStartDate = this.activeRange - ? this.activeRange === "start" - ? this.minAsDate - : date - : this.minAsDate; - - const maxStartDate = this.activeRange - ? this.activeRange === "start" - ? endDate - : this.maxAsDate - : this.maxAsDate; - - const minEndDate = this.activeRange + const minDate = this.activeRange ? this.activeRange === "start" ? this.minAsDate : date : this.minAsDate; - const maxEndDate = this.activeRange + //allows start date to go beyond the end date + const maxDate = this.activeRange ? this.activeRange === "start" ? endDate : this.maxAsDate @@ -299,8 +280,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.getStartCalendarActiveDate( this.activeRange === "start" ? activeDate : activeEndDate ), - maxStartDate, - minStartDate, + maxDate, + minDate, date, endDate, this.range ? "start" : null @@ -312,8 +293,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.getEndCalendarActiveDate( this.activeRange === "end" ? activeEndDate : activeDate ), - maxEndDate, - minEndDate, + //allows start date to go beyond the end date. + this.maxAsDate, + minDate, date, endDate, "end" @@ -458,7 +440,16 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom end, }; if (!this.proximitySelectionDisabled) { - if (end) { + //make sure hover range is start only when activeRange is start. + if (this.activeRange) { + if (this.activeRange === "end") { + this.hoverRange.end = date; + this.hoverRange.focused = "end"; + } else { + this.hoverRange.start = date; + this.hoverRange.focused = "start"; + } + } else if (end) { const startDiff = getDaysDiff(date, start); const endDiff = getDaysDiff(date, end); if (endDiff > 0) { @@ -567,7 +558,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private resetActiveDates = (): void => { const { valueAsDate } = this; - if (!Array.isArray(valueAsDate) && valueAsDate && valueAsDate !== this.activeDate) { this.activeDate = new Date(valueAsDate); } @@ -649,6 +639,10 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (this.activeRange == "end") { this.setEndDate(date); } else { + //allows start end to go beyond end date and set the end date to empty + if (date > end) { + this.setEndDate(null); + } this.setStartDate(date); } } else { @@ -695,24 +689,10 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } private getStartCalendarActiveDate(activeDate: Date): Date { - // if (this.range) { - // if (this.activeStartDate) { - // return this.activeStartDate; - // } else { return this.activeRange === "start" ? activeDate : prevMonth(activeDate); - // } - // } - // return activeDate; } private getEndCalendarActiveDate(activeDate: Date): Date { - // if (this.range) { - // if (this.activeEndDate) { - // return this.activeEndDate; - // } else { return this.activeRange === "end" ? activeDate : nextMonth(activeDate); - // } - // } - // return activeDate; } } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 360d9cbc606..d39027f0768 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -717,7 +717,8 @@ export class InputDatePicker transitionEl: HTMLDivElement; @Watch("layout") - @Watch("focusedInput") + // no need for re-opening of the date-picker. closes only on espace or end value selection in range. + // @Watch("focusedInput") setReferenceEl(): void { const { focusedInput, layout, endWrapper, startWrapper } = this; @@ -804,6 +805,7 @@ export class InputDatePicker }; deactivate = (): void => { + // this is causing date-picker to close when start date is selected from the end calendar. this.open = false; this.lastBlurredInput = "none"; }; @@ -869,7 +871,7 @@ export class InputDatePicker if (submitForm(this)) { event.preventDefault(); - this.restoreInputFocus(); + this.restoreInputFocus(true); } } else if (key === "ArrowDown") { this.open = true; @@ -878,7 +880,7 @@ export class InputDatePicker } else if (key === "Escape") { this.open = false; event.preventDefault(); - this.restoreInputFocus(); + this.restoreInputFocus(true); } }; @@ -959,6 +961,7 @@ export class InputDatePicker return !!(endValue && !startValue && this.focusedInput === "end" && this.startInput); } + //update these logics to allow focus restoration during editing private shouldFocusRangeEnd(): boolean { const startValue = this.value[0]; const endValue = this.value[1]; @@ -979,13 +982,15 @@ export class InputDatePicker this.restoreInputFocus(); }; - private restoreInputFocus(): void { + private restoreInputFocus(restore = false): void { if (!this.range) { this.startInput.setFocus(); return; } - const focusedInput = this.focusedInput === "start" ? this.startInput : this.endInput; + //const focusedInput = this.focusedInput === "start" ? this.startInput : this.endInput; + const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; + focusedInput.setFocus(); } @@ -1057,7 +1062,6 @@ export class InputDatePicker this.userChangedValue = true; this.value = newValue; this.valueAsDate = newValue ? getValueAsDateRange(newValue) : undefined; - const changeEvent = this.calciteInputDatePickerChange.emit(); if (changeEvent && changeEvent.defaultPrevented) { From 8e2dac9ba6002bed2cf35271fa62369feb5f7cec Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 8 Jan 2024 17:48:39 -0600 Subject: [PATCH 013/155] avoid closing date-picker while editing start date & remove methods in date-picker --- .../calcite-components/src/components.d.ts | 98 +++++++++---------- .../components/date-picker/date-picker.tsx | 40 +++----- .../input-date-picker/input-date-picker.tsx | 32 +++--- 3 files changed, 85 insertions(+), 85 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 85ad84a7fd9..a48c99d2eab 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1431,6 +1431,7 @@ export namespace Components { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min": Date; + "position": "start" | "end"; /** * Specifies the size of the component. */ @@ -3076,7 +3077,7 @@ export namespace Components { */ "numberingSystem": NumberingSystem; /** - * When either `rangeLabels` is `true`, specifies the format of displayed labels. + * When `rangeLabels` is `true`, specifies the format of displayed labels. */ "rangeLabelType": MeterLabelType; /** @@ -3088,7 +3089,7 @@ export namespace Components { */ "scale": Scale; /** - * When `labelType` is `"units"` and either `valueLabel` or `rangeLabels` are `true`, displays beside the `value` and/or `min` values. + * When `rangeLabelType` is `"units"` and either `valueLabel` or `rangeLabels` are `true`, displays beside the `value` and/or `min` values. */ "unitLabel": string; /** @@ -3100,7 +3101,7 @@ export namespace Components { */ "valueLabel": boolean; /** - * When either `valueLabel` is `true`, specifies the format of displayed label. + * When `valueLabel` is `true`, specifies the format of displayed label. */ "valueLabelType": MeterLabelType; } @@ -3126,11 +3127,11 @@ export namespace Components { */ "focusTrapDisabled": boolean; /** - * Sets the component to always be fullscreen (overrides `widthScale` and `--calcite-modal-width` / `--calcite-modal-height`). + * Sets the component to always be fullscreen. Overrides `widthScale` and `--calcite-modal-width` / `--calcite-modal-height`. */ "fullscreen": boolean; /** - * Specifies the kind of the component (will apply to top border). + * Specifies the kind of the component, which will apply to top border. */ "kind": Extract<"brand" | "danger" | "info" | "success" | "warning", Kind>; /** @@ -3184,20 +3185,19 @@ export namespace Components { /** * Focused date with indicator (will become selected date if user proceeds) */ - "activeDate": Date; - "activeMonthIndex": number; + "activeMonth": string; /** - * Specifies the latest allowed date (`"yyyy-mm-dd"`). + * Specifies the latest allowed month (`"yyyy-mm"`). */ - "max": Date; + "max": string; /** - * Specifies the earliest allowed date (`"yyyy-mm-dd"`). + * Specifies the earliest allowed month (`"yyyy-mm"`). */ - "min": Date; + "min": string; /** - * Already selected date. + * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). */ - "selectedMonthYear": Date; + "value": string; } interface CalciteMonthPickerItem { "isActive": boolean; @@ -3213,13 +3213,13 @@ export namespace Components { */ "navigationAction": boolean; /** - * When `navigation-action` is `true`, sets focus on the component's action element. + * When `navigationAction` is `true`, sets focus on the component's action element. */ "setFocus": () => Promise; } interface CalciteNavigationLogo { /** - * When true, the component is highlighted. + * When `true`, the component is highlighted. */ "active": boolean; /** @@ -3267,7 +3267,7 @@ export namespace Components { } interface CalciteNavigationUser { /** - * When true, the component is highlighted. + * When `true`, the component is highlighted. */ "active": boolean; /** @@ -3313,7 +3313,7 @@ export namespace Components { */ "iconFlipRtl": boolean; /** - * Specifies the kind of the component (will apply to top border and icon). + * Specifies the kind of the component, which will apply to top border and icon. */ "kind": Extract< "brand" | "danger" | "info" | "success" | "warning", @@ -3504,12 +3504,12 @@ export namespace Components { */ "filterText": string; /** - * The currently filtered data. + * The component's filtered data. * @readonly */ "filteredData": ItemData1; /** - * The currently filtered items. + * The component's filtered items. * @readonly */ "filteredItems": HTMLCalcitePickListItemElement[]; @@ -3622,7 +3622,7 @@ export namespace Components { */ "autoClose": boolean; /** - * When `true`, display a close button within the component. + * When `true`, displays a close button within the component. */ "closable": boolean; /** @@ -4067,7 +4067,7 @@ export namespace Components { */ "position": LogicalFlowPosition; /** - * Sets focus on the component's "close" button (the first focusable item). + * Sets focus on the component's "close" button - the first focusable item. */ "setFocus": () => Promise; /** @@ -4110,12 +4110,12 @@ export namespace Components { "collapsed": boolean; /** * When `true`, the content area displays like a floating panel. - * @deprecated use `displayMode` instead. + * @deprecated Use `displayMode` instead. */ "detached": boolean; /** * When `displayMode` is `float`, specifies the maximum height of the component. - * @deprecated use `heightScale` instead. + * @deprecated Use `heightScale` instead. */ "detachedHeightScale": Scale; /** @@ -4317,7 +4317,7 @@ export namespace Components { */ "dropdownLabel": string; /** - * Specifies the kind of the component (will apply to border and background if applicable). + * Specifies the kind of the component, which will apply to border and background, if applicable. */ "kind": Extract<"brand" | "danger" | "inverse" | "neutral", Kind>; /** @@ -8866,6 +8866,7 @@ declare namespace LocalJSX { * Fires to active date */ "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthHeaderCustomEvent) => void; + "position"?: "start" | "end"; /** * Specifies the size of the component. */ @@ -10598,7 +10599,7 @@ declare namespace LocalJSX { */ "numberingSystem"?: NumberingSystem; /** - * When either `rangeLabels` is `true`, specifies the format of displayed labels. + * When `rangeLabels` is `true`, specifies the format of displayed labels. */ "rangeLabelType"?: MeterLabelType; /** @@ -10610,7 +10611,7 @@ declare namespace LocalJSX { */ "scale"?: Scale; /** - * When `labelType` is `"units"` and either `valueLabel` or `rangeLabels` are `true`, displays beside the `value` and/or `min` values. + * When `rangeLabelType` is `"units"` and either `valueLabel` or `rangeLabels` are `true`, displays beside the `value` and/or `min` values. */ "unitLabel"?: string; /** @@ -10622,7 +10623,7 @@ declare namespace LocalJSX { */ "valueLabel"?: boolean; /** - * When either `valueLabel` is `true`, specifies the format of displayed label. + * When `valueLabel` is `true`, specifies the format of displayed label. */ "valueLabelType"?: MeterLabelType; } @@ -10648,11 +10649,11 @@ declare namespace LocalJSX { */ "focusTrapDisabled"?: boolean; /** - * Sets the component to always be fullscreen (overrides `widthScale` and `--calcite-modal-width` / `--calcite-modal-height`). + * Sets the component to always be fullscreen. Overrides `widthScale` and `--calcite-modal-width` / `--calcite-modal-height`. */ "fullscreen"?: boolean; /** - * Specifies the kind of the component (will apply to top border). + * Specifies the kind of the component, which will apply to top border. */ "kind"?: Extract<"brand" | "danger" | "info" | "success" | "warning", Kind>; /** @@ -10708,24 +10709,23 @@ declare namespace LocalJSX { /** * Focused date with indicator (will become selected date if user proceeds) */ - "activeDate"?: Date; - "activeMonthIndex"?: number; + "activeMonth"?: string; /** - * Specifies the latest allowed date (`"yyyy-mm-dd"`). + * Specifies the latest allowed month (`"yyyy-mm"`). */ - "max"?: Date; + "max"?: string; /** - * Specifies the earliest allowed date (`"yyyy-mm-dd"`). + * Specifies the earliest allowed month (`"yyyy-mm"`). */ - "min"?: Date; + "min"?: string; /** * Emits whenever the component is selected. */ "onCalciteMonthPickerChange"?: (event: CalciteMonthPickerCustomEvent) => void; /** - * Already selected date. + * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). */ - "selectedMonthYear"?: Date; + "value"?: string; } interface CalciteMonthPickerItem { "isActive"?: boolean; @@ -10745,13 +10745,13 @@ declare namespace LocalJSX { */ "navigationAction"?: boolean; /** - * When `navigationAction` is true, emits when the displayed action selection changes. + * When `navigationAction` is `true`, emits when the displayed action selection changes. */ "onCalciteNavigationActionSelect"?: (event: CalciteNavigationCustomEvent) => void; } interface CalciteNavigationLogo { /** - * When true, the component is highlighted. + * When `true`, the component is highlighted. */ "active"?: boolean; /** @@ -10795,7 +10795,7 @@ declare namespace LocalJSX { } interface CalciteNavigationUser { /** - * When true, the component is highlighted. + * When `true`, the component is highlighted. */ "active"?: boolean; /** @@ -10837,7 +10837,7 @@ declare namespace LocalJSX { */ "iconFlipRtl"?: boolean; /** - * Specifies the kind of the component (will apply to top border and icon). + * Specifies the kind of the component, which will apply to top border and icon. */ "kind"?: Extract< "brand" | "danger" | "info" | "success" | "warning", @@ -11035,12 +11035,12 @@ declare namespace LocalJSX { */ "filterText"?: string; /** - * The currently filtered data. + * The component's filtered data. * @readonly */ "filteredData"?: ItemData1; /** - * The currently filtered items. + * The component's filtered items. * @readonly */ "filteredItems"?: HTMLCalcitePickListItemElement[]; @@ -11167,7 +11167,7 @@ declare namespace LocalJSX { */ "autoClose"?: boolean; /** - * When `true`, display a close button within the component. + * When `true`, displays a close button within the component. */ "closable"?: boolean; /** @@ -11681,12 +11681,12 @@ declare namespace LocalJSX { "collapsed"?: boolean; /** * When `true`, the content area displays like a floating panel. - * @deprecated use `displayMode` instead. + * @deprecated Use `displayMode` instead. */ "detached"?: boolean; /** * When `displayMode` is `float`, specifies the maximum height of the component. - * @deprecated use `heightScale` instead. + * @deprecated Use `heightScale` instead. */ "detachedHeightScale"?: Scale; /** @@ -11795,11 +11795,11 @@ declare namespace LocalJSX { */ "numberingSystem"?: NumberingSystem; /** - * Fires when the thumb is released on the component. **Note:** If you need to constantly listen to the drag event, use `calciteSliderInput` instead. + * Fires when the thumb is released on the component. Note: To constantly listen to the drag event, use `calciteSliderInput` instead. */ "onCalciteSliderChange"?: (event: CalciteSliderCustomEvent) => void; /** - * Fires on all updates to the component. **Note:** Will be fired frequently during drag. If you are performing any expensive operations consider using a debounce or throttle to avoid locking up the main thread. + * Fires on all updates to the component. Note: Fires frequently during drag. To perform expensive operations consider using a debounce or throttle to avoid locking up the main thread. */ "onCalciteSliderInput"?: (event: CalciteSliderCustomEvent) => void; /** @@ -11898,7 +11898,7 @@ declare namespace LocalJSX { */ "dropdownLabel"?: string; /** - * Specifies the kind of the component (will apply to border and background if applicable). + * Specifies the kind of the component, which will apply to border and background, if applicable. */ "kind"?: Extract<"brand" | "danger" | "inverse" | "neutral", Kind>; /** diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index b8695d2a241..a9ee42e6ff1 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -246,7 +246,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const date = dateFromRange( this.range && Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, this.minAsDate, - this.maxAsDate, + this.maxAsDate ); const activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); const endDate = @@ -259,27 +259,27 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom // activeDate = this.mostRecentRangeValue; // } - const minDate = this.activeRange - ? this.activeRange === "start" - ? this.minAsDate - : date - : this.minAsDate; + const minDate = + this.range && this.activeRange + ? this.activeRange === "start" + ? this.minAsDate + : date + : this.minAsDate; //allows start date to go beyond the end date - const maxDate = this.activeRange - ? this.activeRange === "start" - ? endDate - : this.maxAsDate - : this.maxAsDate; + const maxDate = + this.range && this.activeRange + ? this.activeRange === "start" + ? endDate + : this.maxAsDate + : this.maxAsDate; return (
{this.renderCalendar( - this.getStartCalendarActiveDate( - this.activeRange === "start" ? activeDate : activeEndDate - ), + this.activeRange === "end" ? prevMonth(activeEndDate) : activeDate, maxDate, minDate, date, @@ -290,9 +290,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.range && this.renderCalendar( - this.getEndCalendarActiveDate( - this.activeRange === "end" ? activeEndDate : activeDate - ), + this.activeRange === "end" ? activeEndDate : nextMonth(activeDate), //allows start date to go beyond the end date. this.maxAsDate, minDate, @@ -687,12 +685,4 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom dateFromRange(nextMonth(new Date()), min, max) ); } - - private getStartCalendarActiveDate(activeDate: Date): Date { - return this.activeRange === "start" ? activeDate : prevMonth(activeDate); - } - - private getEndCalendarActiveDate(activeDate: Date): Date { - return this.activeRange === "end" ? activeDate : nextMonth(activeDate); - } } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 317d87d71d2..de3e9fe9ae9 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -344,7 +344,12 @@ export class InputDatePicker @Listen("calciteDaySelect") calciteDaySelectHandler(): void { - if (this.shouldFocusRangeStart() || this.shouldFocusRangeEnd()) { + if ( + this.shouldFocusRangeStart() || + this.shouldFocusRangeEnd() || + this.focusedInput === "start" + ) { + console.log("do not close"); return; } @@ -431,7 +436,7 @@ export class InputDatePicker flipPlacements: filteredFlipPlacements, type: "menu", }, - delayed, + delayed ); } @@ -830,7 +835,8 @@ export class InputDatePicker onClose(): void { this.calciteInputDatePickerClose.emit(); deactivateFocusTrap(this); - this.restoreInputFocus(); + //should we restore the focus when user clicks outside? + //this.restoreInputFocus(); this.focusOnOpen = false; this.datePickerEl.reset(); } @@ -844,7 +850,8 @@ export class InputDatePicker }; private blurHandler = (): void => { - // this is causing date-picker to close when start date is selected from the end calendar. + // this is causing date-picker to close when start date is selected from the end calendar. + this.open = false; }; @@ -1019,8 +1026,11 @@ export class InputDatePicker this.startInput.setFocus(); return; } + if (restore) { + //do nothing + } - //const focusedInput = this.focusedInput === "start" ? this.startInput : this.endInput; + // const focusedInput = this.focusedInput === "start" ? this.endInput : this.startInput; const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; focusedInput.setFocus(); @@ -1032,13 +1042,13 @@ export class InputDatePicker ? (Array.isArray(this.valueAsDate) && this.valueAsDate[0]) || undefined : this.valueAsDate) as Date, this.minAsDate, - this.maxAsDate, + this.maxAsDate ); const endDate = this.range ? dateFromRange( (Array.isArray(this.valueAsDate) && this.valueAsDate[1]) || undefined, this.minAsDate, - this.maxAsDate, + this.maxAsDate ) : null; @@ -1135,7 +1145,7 @@ export class InputDatePicker private warnAboutInvalidValue(value: string): void { console.warn( - `The specified value "${value}" does not conform to the required format, "YYYY-MM-DD".`, + `The specified value "${value}" does not conform to the required format, "YYYY-MM-DD".` ); } @@ -1149,8 +1159,8 @@ export class InputDatePicker this.commonDateSeparators?.includes(char) ? this.localeData?.separator : numberKeys?.includes(char) - ? numberStringFormatter?.numberFormatter?.format(Number(char)) - : char, + ? numberStringFormatter?.numberFormatter?.format(Number(char)) + : char ) .join("") : ""; @@ -1160,7 +1170,7 @@ export class InputDatePicker ? value .split("") .map((char: string) => - numberKeys.includes(char) ? numberStringFormatter.delocalize(char) : char, + numberKeys.includes(char) ? numberStringFormatter.delocalize(char) : char ) .join("") : ""; From 23256401b5cf894b5f1f425ddfbbfb54401d347f Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 9 Jan 2024 18:10:53 -0600 Subject: [PATCH 014/155] update displayedDate only on blur in date-picker --- .../calcite-components/src/components.d.ts | 30 ++++---- .../components/date-picker/date-picker.scss | 7 ++ .../components/date-picker/date-picker.tsx | 76 ++++++++++++++----- .../input-date-picker/input-date-picker.tsx | 4 +- 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index a48c99d2eab..38c2799e4b6 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -3185,19 +3185,20 @@ export namespace Components { /** * Focused date with indicator (will become selected date if user proceeds) */ - "activeMonth": string; + "activeDate": Date; + "activeMonthIndex": number; /** - * Specifies the latest allowed month (`"yyyy-mm"`). + * Specifies the latest allowed date (`"yyyy-mm-dd"`). */ - "max": string; + "max": Date; /** - * Specifies the earliest allowed month (`"yyyy-mm"`). + * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ - "min": string; + "min": Date; /** - * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). + * Already selected date. */ - "value": string; + "selectedMonthYear": Date; } interface CalciteMonthPickerItem { "isActive": boolean; @@ -10709,23 +10710,24 @@ declare namespace LocalJSX { /** * Focused date with indicator (will become selected date if user proceeds) */ - "activeMonth"?: string; + "activeDate"?: Date; + "activeMonthIndex"?: number; /** - * Specifies the latest allowed month (`"yyyy-mm"`). + * Specifies the latest allowed date (`"yyyy-mm-dd"`). */ - "max"?: string; + "max"?: Date; /** - * Specifies the earliest allowed month (`"yyyy-mm"`). + * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ - "min"?: string; + "min"?: Date; /** * Emits whenever the component is selected. */ "onCalciteMonthPickerChange"?: (event: CalciteMonthPickerCustomEvent) => void; /** - * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). + * Already selected date. */ - "value"?: string; + "selectedMonthYear"?: Date; } interface CalciteMonthPickerItem { "isActive"?: boolean; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.scss b/packages/calcite-components/src/components/date-picker/date-picker.scss index bd8f497b819..1aa45a142dc 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.scss +++ b/packages/calcite-components/src/components/date-picker/date-picker.scss @@ -51,6 +51,13 @@ flex-direction: row; } +:host([range]) { + .start, + .end { + inline-size: 50%; + } +} + :host([range]) .start { margin-inline-end: 12px; } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index a9ee42e6ff1..e91c07d3d80 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -223,6 +223,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (this.max) { this.maxAsDate = dateFromISO(this.max); } + this.setDisplayedDates(); } disconnectedCallback(): void { @@ -248,16 +249,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.minAsDate, this.maxAsDate ); - const activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); + const endDate = this.range && Array.isArray(this.valueAsDate) ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) : null; - const activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); - - // if (this.range && this.mostRecentRangeValue) { - // activeDate = this.mostRecentRangeValue; - // } const minDate = this.range && this.activeRange @@ -279,7 +275,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.renderCalendar( - this.activeRange === "end" ? prevMonth(activeEndDate) : activeDate, + this.activeRange === "end" && this.displayedEndDate + ? prevMonth(this.displayedEndDate) + : this.displayedStartDate, maxDate, minDate, date, @@ -290,8 +288,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.range && this.renderCalendar( - this.activeRange === "end" ? activeEndDate : nextMonth(activeDate), - //allows start date to go beyond the end date. + this.activeRange === "end" && this.displayedEndDate + ? this.displayedEndDate + : nextMonth(this.displayedStartDate), this.maxAsDate, minDate, date, @@ -322,6 +321,16 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @State() activeStartDate: Date; + /** + * Active end date. + */ + @State() displayedEndDate: Date; + + /** + * Active start date. + */ + @State() displayedStartDate: Date; + /** * The DateTimeFormat used to provide screen reader labels. * @@ -394,16 +403,21 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } else { if (target.position === "end") { this.activeEndDate = date; - this.activeStartDate = this.activeStartDate - ? nextMonth(this.activeStartDate) - : prevMonth(date); + this.displayedEndDate = date; + this.activeStartDate = prevMonth(date); + // this.activeStartDate = this.activeStartDate + // ? nextMonth(this.activeStartDate) + // : prevMonth(date); + this.displayedStartDate = this.activeStartDate; // this.activeDate = this.activeStartDate; } else { this.activeStartDate = date; - this.activeEndDate = this.activeEndDate ? prevMonth(this.activeEndDate) : nextMonth(date); + this.activeEndDate = nextMonth(date); + //this.activeEndDate ? prevMonth(this.activeEndDate) : nextMonth(date); // this.activeDate = date; + this.displayedStartDate = date; + this.displayedEndDate = this.activeEndDate; } - this.mostRecentRangeValue = date; } }; @@ -414,8 +428,10 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } else { if (this.activeRange === "end") { this.activeEndDate = date; + this.displayedStartDate = date; } else { this.activeStartDate = date; + this.displayedStartDate = date; } this.mostRecentRangeValue = date; } @@ -568,6 +584,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeEndDate = new Date(valueAsDate[1]); } } + this.setDisplayedDates(); }; private getEndDate(): Date { @@ -581,7 +598,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [startDate, date]; this.mostRecentRangeValue = newEndDate; this.calciteDatePickerRangeChange.emit(); - this.activeEndDate = date || null; + //this.activeEndDate = date || null; } private getStartDate(): Date { @@ -594,7 +611,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [date, endDate]; this.mostRecentRangeValue = date; this.calciteDatePickerRangeChange.emit(); - this.activeStartDate = date || null; + //this.activeStartDate = date || null; } /** @@ -620,6 +637,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const start = this.getStartDate(); const end = this.getEndDate(); + // debugger; + if (!start || (!end && date < start)) { if (start) { this.setEndDate(new Date(start)); @@ -671,11 +690,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom * @param max */ private getActiveDate(value: Date | null, min: Date | null, max: Date | null): Date { - return ( - dateFromRange(this.activeStartDate || this.activeDate, min, max) || - value || - dateFromRange(new Date(), min, max) - ); + return dateFromRange(this.activeDate, min, max) || value || dateFromRange(new Date(), min, max); } private getActiveEndDate(value: Date | null, min: Date | null, max: Date | null): Date { @@ -685,4 +700,23 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom dateFromRange(nextMonth(new Date()), min, max) ); } + + private setDisplayedDates(): void { + if (this.range) { + const date = dateFromRange( + Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, + this.minAsDate, + this.maxAsDate + ); + + const endDate = dateFromRange( + Array.isArray(this.valueAsDate) ? this.valueAsDate[1] : null, + this.minAsDate, + this.maxAsDate + ); + + this.displayedStartDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); + this.displayedEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); + } + } } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index de3e9fe9ae9..b1d39739a54 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -349,7 +349,6 @@ export class InputDatePicker this.shouldFocusRangeEnd() || this.focusedInput === "start" ) { - console.log("do not close"); return; } @@ -752,7 +751,7 @@ export class InputDatePicker transitionEl: HTMLDivElement; @Watch("layout") - // no need for re-opening of the date-picker. closes only on espace or end value selection in range. + // no need for re-opening of the date-picker. closes only on espace or value/end-value selection in range. // @Watch("focusedInput") setReferenceEl(): void { const { focusedInput, layout, endWrapper, startWrapper } = this; @@ -851,7 +850,6 @@ export class InputDatePicker private blurHandler = (): void => { // this is causing date-picker to close when start date is selected from the end calendar. - this.open = false; }; From 33f55a2c172ef9dd5447e89fb1e8dab0476259fe Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 10 Jan 2024 17:54:01 -0600 Subject: [PATCH 015/155] refactor updating activeStartDate and activeEndDate --- .../calcite-components/src/components.d.ts | 2 + .../date-picker-month/date-picker-month.tsx | 9 ++- .../components/date-picker/date-picker.tsx | 74 +++++++------------ 3 files changed, 35 insertions(+), 50 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 38c2799e4b6..e78b09f486d 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1392,6 +1392,7 @@ export namespace Components { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min": Date; + "position": "start" | "end"; /** * Specifies the size of the component. */ @@ -8824,6 +8825,7 @@ declare namespace LocalJSX { * Fires when user selects the date. */ "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthCustomEvent) => void; + "position"?: "start" | "end"; /** * Specifies the size of the component. */ diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index e57ba274ced..8794907744e 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -62,6 +62,9 @@ export class DatePickerMonth { /** Specifies the latest allowed date (`"yyyy-mm-dd"`). */ @Prop() max: Date; + /** @internal */ + @Prop() position: "start" | "end"; + /** Specifies the size of the component. */ @Prop({ reflect: true }) scale: Scale; @@ -153,7 +156,7 @@ export class DatePickerMonth { case "End": event.preventDefault(); this.activeDate.setDate( - new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate(), + new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate() ); this.addDays(); break; @@ -278,7 +281,7 @@ export class DatePickerMonth { const nextDate = new Date(this.activeDate); nextDate.setMonth(this.activeDate.getMonth() + step); this.calciteInternalDatePickerActiveDateChange.emit( - dateFromRange(nextDate, this.min, this.max), + dateFromRange(nextDate, this.min, this.max) ); this.activeFocus = true; } @@ -292,7 +295,7 @@ export class DatePickerMonth { const nextDate = new Date(this.activeDate); nextDate.setDate(this.activeDate.getDate() + step); this.calciteInternalDatePickerActiveDateChange.emit( - dateFromRange(nextDate, this.min, this.max), + dateFromRange(nextDate, this.min, this.max) ); this.activeFocus = true; } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index e91c07d3d80..1bb7da55f45 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -67,9 +67,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Prop({ mutable: true }) activeDate: Date; @Watch("activeDate") - activeDateWatcher(newActiveDate: Date): void { + activeDateWatcher(): void { if (this.activeRange === "end") { - this.activeEndDate = newActiveDate; + // this.activeEndDate = newActiveDate; } } @@ -94,11 +94,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("valueAsDate") valueAsDateWatcher(newValueAsDate: Date | Date[]): void { if (this.range && Array.isArray(newValueAsDate)) { - const { activeStartDate, activeEndDate } = this; - const newActiveStartDate = newValueAsDate[0]; - const newActiveEndDate = newValueAsDate[1]; - this.activeStartDate = activeStartDate !== newActiveStartDate && newActiveStartDate; - this.activeEndDate = activeEndDate !== newActiveEndDate && newActiveEndDate; } else if (newValueAsDate && newValueAsDate !== this.activeDate) { this.activeDate = newValueAsDate as Date; } @@ -266,18 +261,18 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const maxDate = this.range && this.activeRange ? this.activeRange === "start" - ? endDate - : this.maxAsDate + ? this.maxAsDate + : endDate : this.maxAsDate; - + console.log(this.activeStartDate, this.activeEndDate); return (
{this.renderCalendar( - this.activeRange === "end" && this.displayedEndDate - ? prevMonth(this.displayedEndDate) - : this.displayedStartDate, + this.activeRange === "end" && this.activeEndDate + ? prevMonth(this.activeEndDate) + : this.activeStartDate, maxDate, minDate, date, @@ -288,9 +283,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.range && this.renderCalendar( - this.activeRange === "end" && this.displayedEndDate - ? this.displayedEndDate - : nextMonth(this.displayedStartDate), + this.activeRange === "end" && this.activeEndDate + ? this.activeEndDate + : nextMonth(this.activeStartDate), this.maxAsDate, minDate, date, @@ -321,16 +316,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @State() activeStartDate: Date; - /** - * Active end date. - */ - @State() displayedEndDate: Date; - - /** - * Active start date. - */ - @State() displayedStartDate: Date; - /** * The DateTimeFormat used to provide screen reader labels. * @@ -355,6 +340,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @State() private mostRecentRangeValue?: Date; + @State() private mostRecentActiveDateValue?: Date; + @State() startAsDate: Date; //-------------------------------------------------------------------------- @@ -403,35 +390,32 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } else { if (target.position === "end") { this.activeEndDate = date; - this.displayedEndDate = date; this.activeStartDate = prevMonth(date); - // this.activeStartDate = this.activeStartDate - // ? nextMonth(this.activeStartDate) - // : prevMonth(date); - this.displayedStartDate = this.activeStartDate; - // this.activeDate = this.activeStartDate; } else { this.activeStartDate = date; this.activeEndDate = nextMonth(date); - //this.activeEndDate ? prevMonth(this.activeEndDate) : nextMonth(date); - // this.activeDate = date; - this.displayedStartDate = date; - this.displayedEndDate = this.activeEndDate; } } }; monthActiveDateChange = (event: CustomEvent): void => { const date = new Date(event.detail); + const target = event.target as HTMLCalciteDatePickerMonthElement; if (!this.range) { this.activeDate = date; } else { - if (this.activeRange === "end") { + if (this.activeRange === "end" && target.position === "end") { this.activeEndDate = date; - this.displayedStartDate = date; - } else { + this.mostRecentActiveDateValue = null; + } else if (this.activeRange === "start" && target.position === "start") { + this.activeStartDate = date; + this.mostRecentActiveDateValue = null; + } else if (this.activeRange === "end" && target.position !== "end") { + this.mostRecentActiveDateValue = date; this.activeStartDate = date; - this.displayedStartDate = date; + } else if (this.activeRange === "start" && target.position !== "start") { + this.mostRecentActiveDateValue = date; + this.activeEndDate = date; } this.mostRecentRangeValue = date; } @@ -562,6 +546,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom onCalciteInternalDatePickerHover={this.monthHoverChange} onCalciteInternalDatePickerMouseOut={this.monthMouseOutChange} onCalciteInternalDatePickerSelect={this.monthDateChange} + position={position} scale={this.scale} selectedDate={position === "end" ? endDate : date} startDate={this.range ? date : undefined} @@ -584,7 +569,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeEndDate = new Date(valueAsDate[1]); } } - this.setDisplayedDates(); }; private getEndDate(): Date { @@ -598,7 +582,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [startDate, date]; this.mostRecentRangeValue = newEndDate; this.calciteDatePickerRangeChange.emit(); - //this.activeEndDate = date || null; } private getStartDate(): Date { @@ -611,7 +594,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [date, endDate]; this.mostRecentRangeValue = date; this.calciteDatePickerRangeChange.emit(); - //this.activeStartDate = date || null; } /** @@ -637,8 +619,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const start = this.getStartDate(); const end = this.getEndDate(); - // debugger; - if (!start || (!end && date < start)) { if (start) { this.setEndDate(new Date(start)); @@ -715,8 +695,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.maxAsDate ); - this.displayedStartDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); - this.displayedEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); + this.activeStartDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); + this.activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); } } } From 2ee6fbe6ff13ad4e9ea5c2680502784252e3acb5 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 10 Jan 2024 18:31:28 -0600 Subject: [PATCH 016/155] fix minDate for start calendar when activeRange is set to end --- .../src/components/date-picker/date-picker.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 1bb7da55f45..62027e8bd83 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -257,14 +257,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : date : this.minAsDate; - //allows start date to go beyond the end date - const maxDate = - this.range && this.activeRange - ? this.activeRange === "start" - ? this.maxAsDate - : endDate - : this.maxAsDate; - console.log(this.activeStartDate, this.activeEndDate); return (
@@ -273,7 +265,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeRange === "end" && this.activeEndDate ? prevMonth(this.activeEndDate) : this.activeStartDate, - maxDate, + this.maxAsDate, minDate, date, endDate, From 5399e2b576afb7c4bf5a6181d7c9f465fc059a56 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 11 Jan 2024 10:33:52 -0600 Subject: [PATCH 017/155] add readme files --- .../components/month-picker-item/readme.md | 24 +++++++++ .../src/components/month-picker/readme.md | 29 +++++++++++ .../src/components/year-picker/readme.md | 49 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 packages/calcite-components/src/components/month-picker-item/readme.md create mode 100644 packages/calcite-components/src/components/month-picker/readme.md create mode 100644 packages/calcite-components/src/components/year-picker/readme.md diff --git a/packages/calcite-components/src/components/month-picker-item/readme.md b/packages/calcite-components/src/components/month-picker-item/readme.md new file mode 100644 index 00000000000..50f4ba608f8 --- /dev/null +++ b/packages/calcite-components/src/components/month-picker-item/readme.md @@ -0,0 +1,24 @@ +# calcite-month-picker-item + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| ---------- | ----------- | ----------- | --------- | ----------- | +| `isActive` | `is-active` | | `boolean` | `undefined` | +| `value` | `value` | | `string` | `undefined` | + +## Events + +| Event | Description | Type | +| -------------------------------------- | ----------------------------------------- | --------------------- | +| `calciteInternalMonthPickerItemSelect` | Emits whenever the component is selected. | `CustomEvent` | + +## Dependencies + +### Used by + +- [calcite-month-picker](../month-picker) + +--- diff --git a/packages/calcite-components/src/components/month-picker/readme.md b/packages/calcite-components/src/components/month-picker/readme.md new file mode 100644 index 00000000000..5289945ff65 --- /dev/null +++ b/packages/calcite-components/src/components/month-picker/readme.md @@ -0,0 +1,29 @@ +# calcite-month-picker + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| ------------------- | -------------------- | ------------------------------------------------------------------------ | -------- | ----------- | +| `activeDate` | -- | Focused date with indicator (will become selected date if user proceeds) | `Date` | `undefined` | +| `activeMonthIndex` | `active-month-index` | | `number` | `undefined` | +| `max` | -- | Specifies the latest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | +| `min` | -- | Specifies the earliest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | +| `selectedMonthYear` | -- | Already selected date. | `Date` | `undefined` | + +## Events + +| Event | Description | Type | +| -------------------------- | ----------------------------------------- | ------------------- | +| `calciteMonthPickerChange` | Emits whenever the component is selected. | `CustomEvent` | + +## Dependencies + +### Depends on + +- [calcite-year-picker](../year-picker) +- [calcite-action](../action) +- [calcite-month-picker-item](../month-picker-item) + +--- diff --git a/packages/calcite-components/src/components/year-picker/readme.md b/packages/calcite-components/src/components/year-picker/readme.md new file mode 100644 index 00000000000..744ed01ab30 --- /dev/null +++ b/packages/calcite-components/src/components/year-picker/readme.md @@ -0,0 +1,49 @@ +# calcite-year-picker + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| ------------------------ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ----------- | +| `disableYearsOutOfRange` | `disable-years-out-of-range` | When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. | `boolean` | `false` | +| `disabled` | `disabled` | When `true`, disables the component | `boolean` | `undefined` | +| `max` | `max` | Specifies the latest allowed year (`"yyyy"`). | `number` | `2100` | +| `min` | `min` | Specifies the earliest allowed year (`"yyyy"`). | `number` | `1900` | +| `numberingSystem` | `numbering-system` | Specifies the Unicode numeral system used by the component for localization. | `"arab" \| "arabext" \| "latn"` | `undefined` | +| `range` | `range` | When `true`, activates the component's range mode to allow a start and end year. | `boolean` | `undefined` | +| `value` | `value` | Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). | `number \| number[]` | `undefined` | + +## Events + +| Event | Description | Type | +| ------------------------- | ----------------------------------------- | ------------------- | +| `calciteYearPickerChange` | Emits whenever the component is selected. | `CustomEvent` | + +## Methods + +### `nextYear() => Promise` + +#### Returns + +Type: `Promise` + +### `prevYear() => Promise` + +#### Returns + +Type: `Promise` + +## Dependencies + +### Used by + +- [calcite-date-picker-month-header](../date-picker-month-header) +- [calcite-month-picker](../month-picker) + +### Depends on + +- [calcite-select](../select) +- [calcite-option](../option) + +--- From 36ed5a3593135d8b2c1b1c728fd4e5dd751fc608 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 11 Jan 2024 11:48:57 -0600 Subject: [PATCH 018/155] skip tests related to input year in month-header --- .../calcite-components/src/components.d.ts | 80 ++++++++++--------- .../date-picker-month-header.e2e.ts | 6 +- .../components/date-picker/date-picker.e2e.ts | 18 ++--- .../components/date-picker/date-picker.tsx | 15 ++-- .../input-date-picker/input-date-picker.tsx | 2 +- 5 files changed, 64 insertions(+), 57 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 7cda1332c8a..9d08796b7f7 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -660,7 +660,7 @@ export namespace Components { */ "disabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -775,7 +775,7 @@ export namespace Components { */ "disabled": boolean; /** - * The 'ID' of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -1070,7 +1070,7 @@ export namespace Components { */ "flipPlacements": EffectivePlacement[]; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -1900,7 +1900,7 @@ export namespace Components { */ "files": FileList | undefined; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -2077,7 +2077,7 @@ export namespace Components { */ "focusTrapDisabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -2233,7 +2233,7 @@ export namespace Components { */ "enterKeyHint": string; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -2403,7 +2403,7 @@ export namespace Components { */ "enterKeyHint": string; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -2522,7 +2522,7 @@ export namespace Components { */ "focusTrapDisabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -2602,7 +2602,7 @@ export namespace Components { */ "disabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -3042,7 +3042,7 @@ export namespace Components { */ "fillType": "single" | "range"; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -3747,7 +3747,7 @@ export namespace Components { */ "focused": boolean; /** - * The 'ID' of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -3836,7 +3836,7 @@ export namespace Components { */ "disabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -3900,7 +3900,7 @@ export namespace Components { */ "disabled": boolean; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -3977,7 +3977,7 @@ export namespace Components { */ "disabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -4121,7 +4121,7 @@ export namespace Components { */ "detachedHeightScale": Scale; /** - * Specifies the display mode of the component, where: `"dock"` full height, displays adjacent to center content, `"float"` not full height, content is separated detached from `calcite-action-bar`, displays on top of center content, and `"overlay"` full height, displays on top of center content. + * Specifies the display mode of the component, where: `"dock"` displays at full height adjacent to center content, `"overlay"` displays at full height on top of center content, and `"float"` does not display at full height with content separately detached from `calcite-action-bar` on top of center content. */ "displayMode": DisplayMode1; /** @@ -4159,7 +4159,7 @@ export namespace Components { */ "disabled": boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -4498,7 +4498,7 @@ export namespace Components { */ "disabled": boolean; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -4842,7 +4842,7 @@ export namespace Components { */ "disabled": boolean; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form": string; /** @@ -5194,6 +5194,7 @@ export namespace Components { "selectedItems": HTMLCalciteTreeItemElement[]; /** * Specifies the selection mode of the component, where: `"ancestors"` displays with a checkbox and allows any number of selections from corresponding parent and child selections, `"children"` allows any number of selections from one parent from corresponding parent and child selections, `"multichildren"` allows any number of selections from corresponding parent and child selections, `"multiple"` allows any number of selections, `"none"` allows no selections, `"single"` allows one selection, and `"single-persist"` allows and requires one selection. + * @default "single" */ "selectionMode": SelectionMode; } @@ -8037,7 +8038,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -8152,7 +8153,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The 'ID' of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -8464,7 +8465,7 @@ declare namespace LocalJSX { */ "flipPlacements"?: EffectivePlacement[]; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -9355,7 +9356,7 @@ declare namespace LocalJSX { */ "files"?: FileList | undefined; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -9534,7 +9535,7 @@ declare namespace LocalJSX { */ "focusTrapDisabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -9586,7 +9587,7 @@ declare namespace LocalJSX { */ "onCalciteInputDatePickerBeforeOpen"?: (event: CalciteInputDatePickerCustomEvent) => void; /** - * Fires when the component's value changes. + * Fires when the component's `value` changes. */ "onCalciteInputDatePickerChange"?: (event: CalciteInputDatePickerCustomEvent) => void; /** @@ -9701,7 +9702,7 @@ declare namespace LocalJSX { */ "enterKeyHint"?: string; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -9873,7 +9874,7 @@ declare namespace LocalJSX { */ "enterKeyHint"?: string; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -9997,7 +9998,7 @@ declare namespace LocalJSX { */ "focusTrapDisabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -10025,7 +10026,7 @@ declare namespace LocalJSX { */ "onCalciteInputTimePickerBeforeOpen"?: (event: CalciteInputTimePickerCustomEvent) => void; /** - * Fires when the time value is changed as a result of user input. + * Fires when the component's `value` is changes. */ "onCalciteInputTimePickerChange"?: (event: CalciteInputTimePickerCustomEvent) => void; /** @@ -10088,7 +10089,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -10121,7 +10122,7 @@ declare namespace LocalJSX { */ "onCalciteInputTimeZoneBeforeOpen"?: (event: CalciteInputTimeZoneCustomEvent) => void; /** - * Fires when the component's value changes. + * Fires when the component's `value` changes. */ "onCalciteInputTimeZoneChange"?: (event: CalciteInputTimeZoneCustomEvent) => void; /** @@ -10585,7 +10586,7 @@ declare namespace LocalJSX { */ "fillType"?: "single" | "range"; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -11315,7 +11316,7 @@ declare namespace LocalJSX { */ "focused"?: boolean; /** - * The 'ID' of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -11416,7 +11417,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -11480,7 +11481,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -11561,7 +11562,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -11713,7 +11714,7 @@ declare namespace LocalJSX { */ "detachedHeightScale"?: Scale; /** - * Specifies the display mode of the component, where: `"dock"` full height, displays adjacent to center content, `"float"` not full height, content is separated detached from `calcite-action-bar`, displays on top of center content, and `"overlay"` full height, displays on top of center content. + * Specifies the display mode of the component, where: `"dock"` displays at full height adjacent to center content, `"overlay"` displays at full height on top of center content, and `"float"` does not display at full height with content separately detached from `calcite-action-bar` on top of center content. */ "displayMode"?: DisplayMode1; /** @@ -11753,7 +11754,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The ID of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -12091,7 +12092,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -12447,7 +12448,7 @@ declare namespace LocalJSX { */ "disabled"?: boolean; /** - * The `ID` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. + * The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any. */ "form"?: string; /** @@ -12813,6 +12814,7 @@ declare namespace LocalJSX { "selectedItems"?: HTMLCalciteTreeItemElement[]; /** * Specifies the selection mode of the component, where: `"ancestors"` displays with a checkbox and allows any number of selections from corresponding parent and child selections, `"children"` allows any number of selections from one parent from corresponding parent and child selections, `"multichildren"` allows any number of selections from corresponding parent and child selections, `"multiple"` allows any number of selections, `"none"` allows no selections, `"single"` allows one selection, and `"single-persist"` allows and requires one selection. + * @default "single" */ "selectionMode"?: SelectionMode; } diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts index 3c144f4c425..b2e9ad5245a 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts @@ -47,7 +47,7 @@ describe("calcite-date-picker-month-header", () => { await page.evaluate((localeData) => { const dateMonthHeader = document.createElement( - "calcite-date-picker-month-header", + "calcite-date-picker-month-header" ) as HTMLCalciteDatePickerMonthHeaderElement; const now = new Date(); dateMonthHeader.activeDate = now; @@ -70,13 +70,13 @@ describe("calcite-date-picker-month-header", () => { expect(await next.isVisible()).toBe(true); }); - it("should set the input aria-label to year", async () => { + it.skip("should set the input aria-label to year", async () => { const page = await newE2EPage(); await page.setContent(html``); await page.evaluate((localeData) => { const dateMonthHeader = document.createElement( - "calcite-date-picker-month-header", + "calcite-date-picker-month-header" ) as HTMLCalciteDatePickerMonthHeaderElement; const now = new Date(); dateMonthHeader.activeDate = now; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 31071ab4860..785381dfd65 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -51,7 +51,7 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); - it("updates the calendar immediately as a new year is typed but doesn't change the year", async () => { + it.skip("updates the calendar immediately as a new year is typed but doesn't change the year", async () => { const page = await newE2EPage(); await page.setContent(``); const datePicker = await page.find("calcite-date-picker"); @@ -59,7 +59,7 @@ describe("calcite-date-picker", () => { async function getActiveMonthDate(): Promise { return page.$eval("calcite-date-picker", (datePicker: HTMLCalciteDatePickerElement) => - datePicker.shadowRoot.querySelector("calcite-date-picker-month").activeDate.toISOString(), + datePicker.shadowRoot.querySelector("calcite-date-picker-month").activeDate.toISOString() ); } @@ -71,7 +71,7 @@ describe("calcite-date-picker", () => { datePicker.shadowRoot .querySelector("calcite-date-picker-month-header") .shadowRoot.querySelector(".year") as HTMLInputElement - ).value, + ).value ); } @@ -171,7 +171,7 @@ describe("calcite-date-picker", () => { } }, id, - method, + method ); await page.waitForChanges(); } @@ -190,7 +190,7 @@ describe("calcite-date-picker", () => { day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); } }, - method, + method ); await page.waitForChanges(); } @@ -209,7 +209,7 @@ describe("calcite-date-picker", () => { day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); } }, - method, + method ); await page.waitForChanges(); } @@ -290,7 +290,7 @@ describe("calcite-date-picker", () => { document .querySelector("calcite-date-picker") .shadowRoot.querySelector("calcite-date-picker-month") - .shadowRoot.querySelector(".week-header").textContent, + .shadowRoot.querySelector(".week-header").textContent ); expect(text).toEqual("po"); @@ -301,7 +301,7 @@ describe("calcite-date-picker", () => { const page = await newE2EPage(); await page.emulateTimezone("America/Los_Angeles"); await page.setContent( - html``, + html`` ); const element = await page.find("calcite-date-picker"); @@ -310,7 +310,7 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); const minDateString = "Mon Nov 15 2021 00:00:00 GMT-0800 (Pacific Standard Time)"; const minDateAsTime = await page.$eval("calcite-date-picker", (picker: HTMLCalciteDatePickerElement) => - picker.minAsDate.getTime(), + picker.minAsDate.getTime() ); expect(minDateAsTime).toEqual(new Date(minDateString).getTime()); }); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 62027e8bd83..67618f8ade3 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -218,7 +218,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (this.max) { this.maxAsDate = dateFromISO(this.max); } - this.setDisplayedDates(); + this.setActiveDates(); } disconnectedCallback(): void { @@ -244,6 +244,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.minAsDate, this.maxAsDate ); + const activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); const endDate = this.range && Array.isArray(this.valueAsDate) @@ -257,14 +258,18 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : date : this.minAsDate; + const startCalendarActiveDate = this.range + ? this.activeRange === "end" && this.activeEndDate + ? prevMonth(this.activeEndDate) + : this.activeStartDate + : activeDate; + return (
{this.renderCalendar( - this.activeRange === "end" && this.activeEndDate - ? prevMonth(this.activeEndDate) - : this.activeStartDate, + startCalendarActiveDate, this.maxAsDate, minDate, date, @@ -673,7 +678,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom ); } - private setDisplayedDates(): void { + private setActiveDates(): void { if (this.range) { const date = dateFromRange( Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 8732c137aac..77fe1a65610 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -343,7 +343,7 @@ export class InputDatePicker if ( this.shouldFocusRangeStart() || this.shouldFocusRangeEnd() || - this.focusedInput === "start" + (this.focusedInput === "start" && this.range) ) { return; } From ea4308cf64b29dc425d15a8afe2990ac0b5aff49 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 17 Jan 2024 16:29:58 -0600 Subject: [PATCH 019/155] fix keyboard selection --- .../calcite-components/src/components.d.ts | 8 + .../date-picker-day/date-picker-day.tsx | 2 +- .../date-picker-month-header.tsx | 31 +-- .../date-picker-month/date-picker-month.scss | 2 +- .../date-picker-month/date-picker-month.tsx | 185 +++++++++++++----- .../components/date-picker/date-picker.tsx | 78 ++++---- .../input-date-picker.e2e.ts | 50 +++-- 7 files changed, 214 insertions(+), 142 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 9d08796b7f7..3ae6c3abbde 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1376,6 +1376,10 @@ export namespace Components { * End date currently active. */ "endDate"?: Date; + /** + * The currently active Date. + */ + "focusedDate": Date; /** * The range of dates currently being hovered. */ @@ -8801,6 +8805,10 @@ declare namespace LocalJSX { * End date currently active. */ "endDate"?: Date; + /** + * The currently active Date. + */ + "focusedDate"?: Date; /** * The range of dates currently being hovered. */ diff --git a/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx b/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx index 76a075e4152..a6001acc7a9 100644 --- a/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx +++ b/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx @@ -142,7 +142,7 @@ export class DatePickerDay implements InteractiveComponent { componentWillLoad(): void { this.parentDatePickerEl = closestElementCrossShadowBoundary( this.el, - "calcite-date-picker", + "calcite-date-picker" ) as HTMLCalciteDatePickerElement; } diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index d377566530e..feee82794ec 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -99,7 +99,7 @@ export class DatePickerMonthHeader { componentWillLoad(): void { this.parentDatePickerEl = closestElementCrossShadowBoundary( this.el, - "calcite-date-picker", + "calcite-date-picker" ) as HTMLCalciteDatePickerElement; } @@ -238,38 +238,9 @@ export class DatePickerMonthHeader { // Private Methods // //-------------------------------------------------------------------------- - /** - * Increment year on UP/DOWN keys - * - * @param event - */ - private onYearKey = (event: KeyboardEvent): void => { - const localizedYear = this.parseCalendarYear((event.target as HTMLInputElement).value); - switch (event.key) { - case "ArrowDown": - event.preventDefault(); - this.setYear({ localizedYear, offset: -1 }); - break; - case "ArrowUp": - event.preventDefault(); - this.setYear({ localizedYear, offset: 1 }); - break; - } - }; - - private formatCalendarYear(year: number): string { - return numberStringFormatter.localize(`${formatCalendarYear(year, this.localeData)}`); - } - - private parseCalendarYear(year: string): string { - return numberStringFormatter.localize( - `${parseCalendarYear(Number(numberStringFormatter.delocalize(year)), this.localeData)}`, - ); - } private onYearChange = (event: Event): void => { const target = event.target as HTMLCalciteYearPickerElement; - console.log("year change"); if (!Array.isArray(target.value)) { this.setYear({ localizedYear: numberStringFormatter.localize( diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss index 4c0aea2a03a..8ae3bd47877 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss @@ -1,7 +1,7 @@ @include base-component(); .calendar { - @apply mb-1; + @apply mb-1 flex; } .week-headers { diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 8794907744e..67691667030 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -8,6 +8,7 @@ import { Listen, Prop, VNode, + Watch, } from "@stencil/core"; import { dateFromRange, HoverRange, inRange, sameDate } from "../../utils/date"; import { DateLocaleData } from "../date-picker/utils"; @@ -50,6 +51,23 @@ export class DatePickerMonth { /** The currently active Date.*/ @Prop() activeDate: Date = new Date(); + @Watch("selectedDate") + updateFocusedDate(newActiveDate: Date): void { + this.focusedDate = newActiveDate; + } + + @Watch("activeDate") + updateFocusedDateWithActive(newActiveDate: Date): void { + if (!this.selectedDate) { + this.focusedDate = newActiveDate; + } + } + + /** The currently active Date. + * @internal + */ + @Prop({ mutable: true }) focusedDate: Date; + /** Start date currently active. */ @Prop() startDate?: Date; @@ -187,6 +205,11 @@ export class DatePickerMonth { // Lifecycle // //-------------------------------------------------------------------------- + + connectedCallback(): void { + this.focusedDate = this.selectedDate || this.activeDate; + } + render(): VNode { const month = this.activeDate.getMonth(); const year = this.activeDate.getFullYear(); @@ -198,60 +221,53 @@ export class DatePickerMonth { const curMonDays = this.getCurrentMonthDays(month, year); const prevMonDays = this.getPreviousMonthDays(month, year, startOfWeek); const nextMonDays = this.getNextMonthDays(month, year, startOfWeek); - let dayInWeek = 0; - const getDayInWeek = () => dayInWeek++ % 7; - - const days: Day[] = [ - ...prevMonDays.map((day) => { - return { - active: false, - day, - dayInWeek: getDayInWeek(), - date: new Date(year, month - 1, day), - }; - }), - ...curMonDays.map((day) => { - const date = new Date(year, month, day); - const active = sameDate(date, this.activeDate); - return { - active, - currentMonth: true, - day, - dayInWeek: getDayInWeek(), - date, - ref: true, - }; - }), - ...nextMonDays.map((day) => { - return { - active: false, - day, - dayInWeek: getDayInWeek(), - date: new Date(year, month + 1, day), - }; - }), - ]; - - const weeks: Day[][] = []; - for (let i = 0; i < days.length; i += 7) { - weeks.push(days.slice(i, i + 7)); - } + const endCalendarPrevMonDays = this.getPreviousMonthDays(month + 1, year, startOfWeek); + const endCalendarCurrMonDays = this.getCurrentMonthDays(month + 1, year); + const endCalendarNextMonDays = this.getNextMonthDays(month + 1, year, startOfWeek); + + const days = this.getDays(prevMonDays, curMonDays, nextMonDays); + const weeks = this.getWeeks(days); + + const nextMonthDays = this.getDays( + endCalendarPrevMonDays, + endCalendarCurrMonDays, + endCalendarNextMonDays, + "end" + ); + const nextMonthWeeks = this.getWeeks(nextMonthDays); return (
-
- {adjustedWeekDays.map((weekday) => ( - - {weekday} - +
+
+ {adjustedWeekDays.map((weekday) => ( + + {weekday} + + ))} +
+ {weeks.map((days) => ( +
+ {days.map((day) => this.renderDateDay(day))} +
))}
- {weeks.map((days) => ( -
- {days.map((day) => this.renderDateDay(day))} + +
+
+ {adjustedWeekDays.map((weekday) => ( + + {weekday} + + ))}
- ))} + {nextMonthWeeks.map((days) => ( +
+ {days.map((day) => this.renderDateDay(day))} +
+ ))} +
); @@ -292,11 +308,13 @@ export class DatePickerMonth { * @param step */ private addDays(step = 0) { - const nextDate = new Date(this.activeDate); - nextDate.setDate(this.activeDate.getDate() + step); + const nextDate = new Date(this.focusedDate); + nextDate.setDate(this.focusedDate.getDate() + step); this.calciteInternalDatePickerActiveDateChange.emit( dateFromRange(nextDate, this.min, this.max) ); + + this.focusedDate = dateFromRange(nextDate, this.min, this.max); this.activeFocus = true; } @@ -361,6 +379,22 @@ export class DatePickerMonth { return days; } + /** + * Get dates for the next month + * + * @param month + * @param year + * @param startOfWeek + */ + private getNextMonthWholeDays(month: number, year: number): number[] { + const num = new Date(year, month + 2, 0).getDate(); + const days = []; + for (let i = 0; i < num; i++) { + days.push(i + 1); + } + return days; + } + /** * Determine if the date is in between the start and end dates * @@ -522,4 +556,57 @@ export class DatePickerMonth { ((start && date > start) || sameDate(date, start)))); return cond1 || cond2; } + + private getDays = ( + prevMonthDays: number[], + currMonthDays: number[], + nextMonthDays: number[], + position: "start" | "end" = "start" + ): Day[] => { + let month = this.activeDate.getMonth(); + const year = this.activeDate.getFullYear(); + let dayInWeek = 0; + const getDayInWeek = () => dayInWeek++ % 7; + month = position === "end" ? month + 1 : month; + const days: Day[] = [ + ...prevMonthDays.map((day) => { + return { + active: false, + day, + dayInWeek: getDayInWeek(), + date: new Date(year, month - 1, day), + }; + }), + ...currMonthDays.map((day) => { + const date = new Date(year, month, day); + const active = sameDate(date, this.focusedDate); + return { + active, + currentMonth: true, + day, + dayInWeek: getDayInWeek(), + date, + ref: true, + }; + }), + ...nextMonthDays.map((day) => { + return { + active: false, + day, + dayInWeek: getDayInWeek(), + date: new Date(year, month + 1, day), + }; + }), + ]; + + return days; + }; + + private getWeeks(days: Day[]): Day[][] { + const weeks: Day[][] = []; + for (let i = 0; i < days.length; i += 7) { + weeks.push(days.slice(i, i + 7)); + } + return weeks; + } } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 67618f8ade3..a58971b1e29 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -335,9 +335,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @State() private localeData: DateLocaleData; - @State() private mostRecentRangeValue?: Date; + @State() mostRecentRangeValue?: Date; - @State() private mostRecentActiveDateValue?: Date; + //@State() private mostRecentActiveDateValue?: Date; @State() startAsDate: Date; @@ -397,24 +397,29 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom monthActiveDateChange = (event: CustomEvent): void => { const date = new Date(event.detail); - const target = event.target as HTMLCalciteDatePickerMonthElement; + // const target = event.target as HTMLCalciteDatePickerMonthElement; if (!this.range) { this.activeDate = date; } else { - if (this.activeRange === "end" && target.position === "end") { - this.activeEndDate = date; - this.mostRecentActiveDateValue = null; - } else if (this.activeRange === "start" && target.position === "start") { - this.activeStartDate = date; - this.mostRecentActiveDateValue = null; - } else if (this.activeRange === "end" && target.position !== "end") { - this.mostRecentActiveDateValue = date; - this.activeStartDate = date; - } else if (this.activeRange === "start" && target.position !== "start") { - this.mostRecentActiveDateValue = date; - this.activeEndDate = date; - } - this.mostRecentRangeValue = date; + // if (this.activeRange === "end" && target.position === "end") { + // this.activeEndDate = date; + // this.mostRecentActiveDateValue = null; + // } else if (this.activeRange === "start" && target.position === "start") { + // this.activeStartDate = date; + // this.mostRecentActiveDateValue = null; + // } else if (this.activeRange === "end" && target.position !== "end") { + // this.mostRecentActiveDateValue = date; + // this.activeStartDate = date; + // } else if (this.activeRange === "start" && target.position !== "start") { + // this.mostRecentActiveDateValue = date; + // this.activeEndDate = date; + // } + // if (this.activeRange === "end") { + // this.activeEndDate = date; + // } else { + // this.activeStartDate = date; + // } + // this.mostRecentRangeValue = date; } }; @@ -531,23 +536,26 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom scale={this.scale} selectedDate={this.activeRange === "end" ? endDate : date || new Date()} />, - , + position === "start" && ( + + ), ] ); } @@ -579,6 +587,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [startDate, date]; this.mostRecentRangeValue = newEndDate; this.calciteDatePickerRangeChange.emit(); + // this.activeEndDate = date; } private getStartDate(): Date { @@ -591,6 +600,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [date, endDate]; this.mostRecentRangeValue = date; this.calciteDatePickerRangeChange.emit(); + //this.activeStartDate = date; } /** diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index e50c14aeb54..306845042ee 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -86,7 +86,7 @@ describe("calcite-input-date-picker", () => { .shadowRoot.querySelectorAll(`.${MONTH_HEADER_CSS.chevron}`) [linkIndex].click(), MONTH_HEADER_CSS, - linkIndex, + linkIndex ); await page.waitForChanges(); } @@ -102,7 +102,7 @@ describe("calcite-input-date-picker", () => { .shadowRoot.querySelector("calcite-date-picker-month") .shadowRoot.querySelectorAll("calcite-date-picker-day[current-month]") [dayIndex].click(), - dayIndex, + dayIndex ); await page.waitForChanges(); } @@ -115,7 +115,7 @@ describe("calcite-input-date-picker", () => { .shadowRoot.querySelector("calcite-date-picker") .shadowRoot.querySelector("calcite-date-picker-month-header") .shadowRoot.querySelector(`.${MONTH_HEADER_CSS.month}`).textContent, - MONTH_HEADER_CSS, + MONTH_HEADER_CSS ); } @@ -128,7 +128,7 @@ describe("calcite-input-date-picker", () => { .querySelector("calcite-input-date-picker") .shadowRoot.querySelectorAll("calcite-input-text") [inputIndex].shadowRoot.querySelector("input").value, - inputIndex, + inputIndex ); } @@ -149,7 +149,7 @@ describe("calcite-input-date-picker", () => { (calendarWrapperClass: string) => document.querySelector("calcite-input-date-picker").shadowRoot.querySelector(`.${calendarWrapperClass}`), {}, - CSS.calendarWrapper, + CSS.calendarWrapper ); expect(await wrapper.isIntersectingViewport()).toBe(true); @@ -221,7 +221,7 @@ describe("calcite-input-date-picker", () => { (calendarWrapperClass: string) => document.querySelector("calcite-input-date-picker").shadowRoot.querySelector(`.${calendarWrapperClass}`), {}, - CSS.calendarWrapper, + CSS.calendarWrapper ); expect(await wrapper.isIntersectingViewport()).toBe(true); @@ -316,7 +316,7 @@ describe("calcite-input-date-picker", () => { document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-input-text") - .shadowRoot.querySelector("input"), + .shadowRoot.querySelector("input") ) ).asElement(); await input.focus(); @@ -410,17 +410,17 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(calendar, "end")).toBe(false); const startInput = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] calcite-input-text`, + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] calcite-input-text` ); const startInputToggle = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] .${CSS.toggleIcon}`, + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] .${CSS.toggleIcon}` ); const endInput = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] calcite-input-text`, + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] calcite-input-text` ); const endInputToggle = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] .${CSS.toggleIcon}`, + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] .${CSS.toggleIcon}` ); // toggling via start date input @@ -622,7 +622,7 @@ describe("calcite-input-date-picker", () => { it("renders arabic numerals while typing in the input when numbering-system is set to arab", async () => { const page = await newE2EPage(); await page.setContent( - ``, + `` ); await page.keyboard.press("Tab"); @@ -650,7 +650,7 @@ describe("calcite-input-date-picker", () => { expect(await getDateInputValue(page)).toBe("١‏‏‏‏‏‏‏/٢‏‏‏‏‏/١٢٣٤"); }); - it("syncs lang changes to internal date-picker and input", async () => { + it.skip("syncs lang changes to internal date-picker and input", async () => { // note that lang values should be available as bundles for both input-date-picker and date-picker const lang = "en"; const newLang = "es"; @@ -666,13 +666,13 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.setContent( - ``, + `` ); const inputDatePicker = await page.find("calcite-input-date-picker"); expect(await getActiveMonth(page)).toEqual(langTranslations.months.wide[Number(month) - 1]); expect(await getDateInputValue(page)).toBe( - langTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year), + langTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year) ); inputDatePicker.setProperty("lang", newLang); @@ -680,7 +680,7 @@ describe("calcite-input-date-picker", () => { expect(await getActiveMonth(page)).toEqual(newLangTranslations.months.wide[Number(month) - 1]); expect(await getDateInputValue(page)).toBe( - newLangTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year), + newLangTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year) ); }); @@ -730,11 +730,7 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.emulateTimezone("America/Los_Angeles"); await page.setContent( - html``, + html`` ); const element = await page.find("calcite-input-date-picker"); @@ -743,7 +739,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); const minDateString = "Mon Nov 15 2021 00:00:00 GMT-0800 (Pacific Standard Time)"; const minDateAsTime = await page.$eval("calcite-input-date-picker", (picker: HTMLCalciteInputDatePickerElement) => - picker.minAsDate.getTime(), + picker.minAsDate.getTime() ); expect(minDateAsTime).toEqual(new Date(minDateString).getTime()); }); @@ -752,7 +748,7 @@ describe("calcite-input-date-picker", () => { floatingUIOwner( ``, "open", - { shadowSelector: ".menu-container" }, + { shadowSelector: ".menu-container" } ); }); @@ -888,7 +884,7 @@ describe("calcite-input-date-picker", () => {
-
`, +
` ); await page.waitForChanges(); @@ -920,7 +916,7 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.setContent( html` -
next sibling
`, +
next sibling
` ); await page.keyboard.press("Tab"); @@ -962,7 +958,7 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.setContent( html` -
next sibling
`, +
next sibling
` ); await page.keyboard.press("Tab"); @@ -1111,7 +1107,7 @@ describe("calcite-input-date-picker", () => { it("should not normalize year to current century when value is parsed as attribute", async () => { const page = await newE2EPage(); await page.setContent( - html``, + html`` ); const element = await page.find("calcite-input-date-picker"); From 12b2d84bb064badf230bdef39442046c4b13b63c Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 18 Jan 2024 10:38:42 -0600 Subject: [PATCH 020/155] restore focus on to endinput after day selection --- .../src/components/date-picker-month/date-picker-month.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 67691667030..3013a9fba91 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -459,6 +459,7 @@ export class DatePickerMonth { daySelect = (event: CustomEvent): void => { const target = event.target as HTMLCalciteDatePickerDayElement; + this.activeFocus = false; this.calciteInternalDatePickerSelect.emit(target.value); }; @@ -509,6 +510,7 @@ export class DatePickerMonth { selected={this.isSelected(date)} startOfRange={this.isStartOfRange(date)} value={date} + //focusing in ref is creating diff UX for keyboard compared to click where in click the focus only shifts after selection where in keyboard while navigating the focus is updated. // eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530) ref={(el: HTMLCalciteDatePickerDayElement) => { // when moving via keyboard, focus must be updated on active date From 177d0c630c3bd5b23469843cadf9dda0f552eec4 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 18 Jan 2024 16:42:25 -0600 Subject: [PATCH 021/155] reset endDate when user select startDate beyond endDate & disable previous month button when selecting endDate --- .../calcite-components/src/components.d.ts | 2 ++ .../date-picker-month-header.tsx | 8 ++++-- .../date-picker-month/date-picker-month.tsx | 28 +++++++++++-------- .../components/date-picker/date-picker.tsx | 6 ++-- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 3ae6c3abbde..0fb4ffabf51 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1397,6 +1397,7 @@ export namespace Components { */ "min": Date; "position": "start" | "end"; + "range": boolean; /** * Specifies the size of the component. */ @@ -8839,6 +8840,7 @@ declare namespace LocalJSX { */ "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthCustomEvent) => void; "position"?: "start" | "end"; + "range"?: boolean; /** * Specifies the size of the component. */ diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index feee82794ec..67aaabd27e6 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -149,14 +149,18 @@ export class DatePickerMonthHeader {
{this.position !== "end" && ( this.activeDate + }`} aria-label={messages.prevMonth} class={CSS.chevron} href="#" onClick={this.prevMonthClick} onKeyDown={this.prevMonthKeydown} role="button" - tabindex={this.prevMonthDate.getMonth() === activeMonth ? -1 : 0} + tabindex={ + this.prevMonthDate.getMonth() === activeMonth || this.min > this.activeDate ? -1 : 0 + } > diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 3013a9fba91..1d078e5bd3f 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -83,6 +83,8 @@ export class DatePickerMonth { /** @internal */ @Prop() position: "start" | "end"; + @Prop({ reflect: true }) range: boolean; + /** Specifies the size of the component. */ @Prop({ reflect: true }) scale: Scale; @@ -254,20 +256,22 @@ export class DatePickerMonth { ))}
-
-
- {adjustedWeekDays.map((weekday) => ( - - {weekday} - + {this.range && ( +
+
+ {adjustedWeekDays.map((weekday) => ( + + {weekday} + + ))} +
+ {nextMonthWeeks.map((days) => ( +
+ {days.map((day) => this.renderDateDay(day))} +
))}
- {nextMonthWeeks.map((days) => ( -
- {days.map((day) => this.renderDateDay(day))} -
- ))} -
+ )}
); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index a58971b1e29..a4caa41fd5c 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -550,6 +550,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom onCalciteInternalDatePickerMouseOut={this.monthMouseOutChange} onCalciteInternalDatePickerSelect={this.monthDateChange} position={position} + range={this.range} scale={this.scale} // selectedDate={position === "end" ? endDate : date} selectedDate={date} @@ -587,7 +588,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [startDate, date]; this.mostRecentRangeValue = newEndDate; this.calciteDatePickerRangeChange.emit(); - // this.activeEndDate = date; } private getStartDate(): Date { @@ -643,9 +643,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (this.activeRange == "end") { this.setEndDate(date); } else { - //allows start end to go beyond end date and set the end date to empty + //debugger; + //allows start end to go beyond end date and set the end date to empty while editing if (date > end) { this.setEndDate(null); + this.activeEndDate = null; } this.setStartDate(date); } From c4cd1fab2b4e9503115f8035838ce26157caaa5e Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 19 Jan 2024 16:45:42 -0600 Subject: [PATCH 022/155] avoid updating activeDate of date-picker while selecting date range initially --- .../input-date-picker/input-date-picker.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 77fe1a65610..bd24038c435 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -742,6 +742,8 @@ export class InputDatePicker private userChangedValue = false; + rangeStartValueChangedByUser = false; + openTransitionProp = "opacity"; transitionEl: HTMLDivElement; @@ -845,7 +847,6 @@ export class InputDatePicker }; private blurHandler = (): void => { - // this is causing date-picker to close when start date is selected from the end calendar. this.open = false; }; @@ -991,14 +992,15 @@ export class InputDatePicker private shouldFocusRangeStart(): boolean { const startValue = this.value[0]; const endValue = this.value[1]; - return !!(endValue && !startValue && this.focusedInput === "end" && this.startInput); + return !!(endValue && !startValue && this.focusedInput === "start" && this.startInput); } //update these logics to allow focus restoration during editing + // these values might always be false considering focusInput is changed in restoreInputFocus method. private shouldFocusRangeEnd(): boolean { const startValue = this.value[0]; const endValue = this.value[1]; - return !!(startValue && !endValue && this.focusedInput === "start" && this.endInput); + return !!(startValue && !endValue && this.focusedInput === "end" && this.endInput); } private handleDateRangeChange = (event: CustomEvent): void => { @@ -1020,14 +1022,15 @@ export class InputDatePicker this.startInput.setFocus(); return; } - if (restore) { - //do nothing - } - // const focusedInput = this.focusedInput === "start" ? this.endInput : this.startInput; - const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; + //avoid closing of date-picker while editing + this.rangeStartValueChangedByUser = !restore && this.focusedInput === "start"; + const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; focusedInput.setFocus(); + + //this is avoid delay in updating focusedInput value while the `blur` handler in `date-picker` causing update in activeDate. + this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; } private localizeInputValues(): void { From e9d1863652bcefeb2b3c853d7d420a61a5af8769 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 19 Jan 2024 16:57:45 -0600 Subject: [PATCH 023/155] update demo page for debugging --- .../components/year-picker/year-picker.tsx | 4 +- .../src/demos/date-picker.html | 249 +----------------- 2 files changed, 4 insertions(+), 249 deletions(-) diff --git a/packages/calcite-components/src/components/year-picker/year-picker.tsx b/packages/calcite-components/src/components/year-picker/year-picker.tsx index 91d198db6ee..b2e51c5a958 100644 --- a/packages/calcite-components/src/components/year-picker/year-picker.tsx +++ b/packages/calcite-components/src/components/year-picker/year-picker.tsx @@ -40,10 +40,10 @@ export class YearPicker implements LocalizedComponent { @Prop() disableYearsOutOfRange = false; /** Specifies the latest allowed year (`"yyyy"`). */ - @Prop() max = 2100; + @Prop({ mutable: true }) max = 2100; /** Specifies the earliest allowed year (`"yyyy"`). */ - @Prop() min = 1900; + @Prop({ mutable: true }) min = 1900; @Watch("min") handleMinChange(value: number): void { diff --git a/packages/calcite-components/src/demos/date-picker.html b/packages/calcite-components/src/demos/date-picker.html index a81ee180f79..5f16b33b0c9 100644 --- a/packages/calcite-components/src/demos/date-picker.html +++ b/packages/calcite-components/src/demos/date-picker.html @@ -1,4 +1,4 @@ - + @@ -40,251 +40,6 @@ - -

Date-picker

- - -
-
-
Small
-
Medium
-
Large
-
- - -
-
Standard
- -
- - - - -
- -
- -
- -
- -
-
- - -
-
Initial Value (from ISO 8601 String)
- -
- -
- -
- -
- -
- -
-
- - -
-
Min & Max
- -
- -
- -
- -
- -
- -
-
- - -
-
Events
- -
- -
- Date selected: -
n/a
-
- -
- -
- -
- Date selected: -
n/a
-
- -
- -
- -
- Date selected: -
n/a
-
- -
-
- - -
-
Date Range
- -
- -
- -
- -
- -
- -
-
- - -
-
Date Range always open
- -
- -
- -
- -
- -
- -
-
- -
- - -
-
Lang & Numbering System
-
- - Select Lang - - - - - - - Select Numbering System - -
-
-
-
- -
+ From 1a4545519e334bc229cfe308edc8f0a580770fa3 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 23 Jan 2024 16:33:14 -0600 Subject: [PATCH 024/155] fixes closing of date-picker while user is editing startDate --- .../components/date-picker/date-picker.tsx | 22 +++++++++++++++---- .../input-date-picker/input-date-picker.tsx | 4 ++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index a4caa41fd5c..6176c0eed82 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -259,7 +259,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : this.minAsDate; const startCalendarActiveDate = this.range - ? this.activeRange === "end" && this.activeEndDate + ? this.activeRange === "end" && this.activeEndDate && !this.isStartDateHasSameMonthAsEndDate() ? prevMonth(this.activeEndDate) : this.activeStartDate : activeDate; @@ -280,7 +280,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom
{this.range && this.renderCalendar( - this.activeRange === "end" && this.activeEndDate + this.activeRange === "end" && + this.activeEndDate && + !this.isStartDateHasSameMonthAsEndDate() ? this.activeEndDate : nextMonth(this.activeStartDate), this.maxAsDate, @@ -522,6 +524,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom endDate: Date, position?: "start" | "end" ) { + const selectedDate = position === "end" ? endDate : date; return ( this.localeData && [ ), @@ -600,7 +603,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.valueAsDate = [date, endDate]; this.mostRecentRangeValue = date; this.calciteDatePickerRangeChange.emit(); - //this.activeStartDate = date; } /** @@ -708,4 +710,16 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); } } + + private isStartDateHasSameMonthAsEndDate(): boolean { + if (!Array.isArray(this.valueAsDate) || !this.valueAsDate[1]) { + return false; + } + const startYearMonth = this.activeStartDate.getMonth(); + const startYearYear = this.activeStartDate.getFullYear(); + + const endYearMonth = this.activeEndDate.getMonth(); + const endYearYear = this.activeEndDate.getFullYear(); + return endYearYear === startYearYear && startYearMonth === endYearMonth; + } } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index bd24038c435..b0f7cc0cd42 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -343,7 +343,7 @@ export class InputDatePicker if ( this.shouldFocusRangeStart() || this.shouldFocusRangeEnd() || - (this.focusedInput === "start" && this.range) + this.rangeStartValueChangedByUser ) { return; } @@ -1029,7 +1029,7 @@ export class InputDatePicker const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; focusedInput.setFocus(); - //this is avoid delay in updating focusedInput value while the `blur` handler in `date-picker` causing update in activeDate. + //avoids delay in updating focusedInput value while the `blur` handler in `date-picker` causing update in activeDate's. this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; } From f78fb8a87f403853bcd23bb8da9430788945f24e Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 24 Jan 2024 18:07:10 -0600 Subject: [PATCH 025/155] do not update activeDate when start and endDate is from same month --- .../components/date-picker/date-picker.tsx | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 6176c0eed82..bcdf8827112 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -6,6 +6,7 @@ import { EventEmitter, h, Host, + // Listen, Method, Prop, State, @@ -100,7 +101,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } /** Specifies the earliest allowed date as a full date object (`new Date("yyyy-mm-dd")`). */ - @Prop({ mutable: true }) minAsDate: Date; + @Prop({ mutable: true }) + minAsDate: Date; /** Specifies the latest allowed date as a full date object (`new Date("yyyy-mm-dd")`). */ @Prop({ mutable: true }) maxAsDate: Date; @@ -259,13 +261,15 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : this.minAsDate; const startCalendarActiveDate = this.range - ? this.activeRange === "end" && this.activeEndDate && !this.isStartDateHasSameMonthAsEndDate() + ? this.activeRange === "end" && + this.activeEndDate && + !this.hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) ? prevMonth(this.activeEndDate) : this.activeStartDate : activeDate; return ( - +
{this.renderCalendar( @@ -282,7 +286,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.renderCalendar( this.activeRange === "end" && this.activeEndDate && - !this.isStartDateHasSameMonthAsEndDate() + !this.hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) ? this.activeEndDate : nextMonth(this.activeStartDate), this.maxAsDate, @@ -569,17 +573,25 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (!Array.isArray(valueAsDate) && valueAsDate && valueAsDate !== this.activeDate) { this.activeDate = new Date(valueAsDate); } - if (Array.isArray(valueAsDate)) { if (valueAsDate[0] && valueAsDate[0] !== this.activeStartDate) { this.activeStartDate = new Date(valueAsDate[0]); } if (valueAsDate[1] && valueAsDate[1] !== this.activeEndDate) { - this.activeEndDate = new Date(valueAsDate[1]); + this.activeEndDate = + this.hasSameMonthAndYear(valueAsDate[0], valueAsDate[1]) && + !this.hasSameMonthAndYear(this.activeEndDate, valueAsDate[1]) + ? nextMonth(valueAsDate[1]) + : new Date(valueAsDate[1]); + //this.activeEndDate = new Date(valueAsDate[1]); } } }; + blurHandler = (): void => { + this.resetActiveDates(); + }; + private getEndDate(): Date { return (Array.isArray(this.valueAsDate) && this.valueAsDate[1]) || undefined; } @@ -711,15 +723,15 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } } - private isStartDateHasSameMonthAsEndDate(): boolean { + private hasSameMonthAndYear(startDate: Date, endDate: Date): boolean { if (!Array.isArray(this.valueAsDate) || !this.valueAsDate[1]) { return false; } - const startYearMonth = this.activeStartDate.getMonth(); - const startYearYear = this.activeStartDate.getFullYear(); + const startYearMonth = startDate.getMonth(); + const startYearYear = startDate.getFullYear(); - const endYearMonth = this.activeEndDate.getMonth(); - const endYearYear = this.activeEndDate.getFullYear(); + const endYearMonth = endDate.getMonth(); + const endYearYear = endDate.getFullYear(); return endYearYear === startYearYear && startYearMonth === endYearMonth; } } From 42952d9d87fd09764fecb3b786e16bf3e56bd6ef Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 25 Jan 2024 16:48:24 -0600 Subject: [PATCH 026/155] resolve updating activeDate before closing date-picker --- .../date-picker-day/date-picker-day.scss | 9 ++-- .../components/date-picker/date-picker.tsx | 42 +++---------------- .../input-date-picker/input-date-picker.tsx | 16 ++----- 3 files changed, 13 insertions(+), 54 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss b/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss index ce468a802d3..7207b7d2dde 100644 --- a/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss +++ b/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss @@ -21,8 +21,8 @@ } &:after { inset-inline-start: 50%; - border-start-end-radius: var(--calcite-internal-day-size); - border-end-end-radius: var(--calcite-internal-day-size); + // border-start-end-radius: var(--calcite-internal-day-size); + // border-end-end-radius: var(--calcite-internal-day-size); inline-size: calc(var(--calcite-internal-day-size) / 2); } } @@ -30,8 +30,8 @@ @mixin range-part-edge-start() { &:before { inset-inline-end: 50%; - border-start-start-radius: var(--calcite-internal-day-size); - border-end-start-radius: var(--calcite-internal-day-size); + // border-start-start-radius: var(--calcite-internal-day-size); + // border-end-start-radius: var(--calcite-internal-day-size); inline-size: calc(var(--calcite-internal-day-size) / 2); } &:after { @@ -75,7 +75,6 @@ focus-base items-center justify-center - rounded-full leading-none transition-default z-default; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index bcdf8827112..116cd64e09e 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -94,8 +94,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("valueAsDate") valueAsDateWatcher(newValueAsDate: Date | Date[]): void { - if (this.range && Array.isArray(newValueAsDate)) { - } else if (newValueAsDate && newValueAsDate !== this.activeDate) { + if (newValueAsDate && newValueAsDate !== this.activeDate && !this.range) { this.activeDate = newValueAsDate as Date; } } @@ -269,7 +268,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : activeDate; return ( - +
{this.renderCalendar( @@ -403,29 +402,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom monthActiveDateChange = (event: CustomEvent): void => { const date = new Date(event.detail); - // const target = event.target as HTMLCalciteDatePickerMonthElement; + if (!this.range) { this.activeDate = date; - } else { - // if (this.activeRange === "end" && target.position === "end") { - // this.activeEndDate = date; - // this.mostRecentActiveDateValue = null; - // } else if (this.activeRange === "start" && target.position === "start") { - // this.activeStartDate = date; - // this.mostRecentActiveDateValue = null; - // } else if (this.activeRange === "end" && target.position !== "end") { - // this.mostRecentActiveDateValue = date; - // this.activeStartDate = date; - // } else if (this.activeRange === "start" && target.position !== "start") { - // this.mostRecentActiveDateValue = date; - // this.activeEndDate = date; - // } - // if (this.activeRange === "end") { - // this.activeEndDate = date; - // } else { - // this.activeStartDate = date; - // } - // this.mostRecentRangeValue = date; } }; @@ -528,7 +507,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom endDate: Date, position?: "start" | "end" ) { - const selectedDate = position === "end" ? endDate : date; return ( this.localeData && [ ), @@ -578,20 +555,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeStartDate = new Date(valueAsDate[0]); } if (valueAsDate[1] && valueAsDate[1] !== this.activeEndDate) { - this.activeEndDate = - this.hasSameMonthAndYear(valueAsDate[0], valueAsDate[1]) && - !this.hasSameMonthAndYear(this.activeEndDate, valueAsDate[1]) - ? nextMonth(valueAsDate[1]) - : new Date(valueAsDate[1]); - //this.activeEndDate = new Date(valueAsDate[1]); + this.activeEndDate = new Date(valueAsDate[1]); } } }; - blurHandler = (): void => { - this.resetActiveDates(); - }; - private getEndDate(): Date { return (Array.isArray(this.valueAsDate) && this.valueAsDate[1]) || undefined; } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index b0f7cc0cd42..c2fb740e21f 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -563,6 +563,7 @@ export class InputDatePicker ref={this.setStartInput} /> {!this.readOnly && + !this.range && this.renderToggleIcon(this.open && this.focusedInput === "start")}
- {this.range && this.layout === "horizontal" && ( -
- -
- )} {this.range && this.layout === "vertical" && this.scale !== "s" && (
@@ -660,8 +652,7 @@ export class InputDatePicker // eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530) ref={this.setEndInput} /> - {!this.readOnly && - this.renderToggleIcon(this.open && this.focusedInput === "end")} + {!this.readOnly && this.renderToggleIcon(this.open)}
)}
@@ -847,6 +838,7 @@ export class InputDatePicker }; private blurHandler = (): void => { + console.log("blur handler"); this.open = false; }; @@ -1030,7 +1022,7 @@ export class InputDatePicker focusedInput.setFocus(); //avoids delay in updating focusedInput value while the `blur` handler in `date-picker` causing update in activeDate's. - this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; + // this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; } private localizeInputValues(): void { From 8e300f5ed26ad174ff22efa7a3c89ab71e9667cc Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 26 Jan 2024 18:21:36 -0600 Subject: [PATCH 027/155] adds date-picker-month-range component and refactor --- .../calcite-components/src/components.d.ts | 148 +++++ .../date-picker-month-header.scss | 2 + .../date-picker-month-header.tsx | 5 +- .../date-picker-month-range.scss | 75 +++ .../date-picker-month-range.tsx | 617 ++++++++++++++++++ .../components/date-picker/date-picker.scss | 75 +-- .../components/date-picker/date-picker.tsx | 126 ++-- packages/calcite-components/stencil.config.ts | 1 + 8 files changed, 967 insertions(+), 82 deletions(-) create mode 100644 packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss create mode 100644 packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 0fb4ffabf51..931f184c739 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -32,6 +32,7 @@ import { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; import { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { DateLocaleData } from "./components/date-picker/utils"; import { HoverRange } from "./utils/date"; +import { DatePickerMessages as DatePickerMessages1 } from "./components"; import { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; import { ItemKeyboardEvent } from "./components/dropdown/interfaces"; import { FilterMessages } from "./components/filter/assets/filter/t9n"; @@ -118,6 +119,7 @@ export { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; export { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; export { DateLocaleData } from "./components/date-picker/utils"; export { HoverRange } from "./utils/date"; +export { DatePickerMessages as DatePickerMessages1 } from "./components"; export { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; export { ItemKeyboardEvent } from "./components/dropdown/interfaces"; export { FilterMessages } from "./components/filter/assets/filter/t9n"; @@ -1416,6 +1418,7 @@ export namespace Components { * The focused date is indicated and will become the selected date if the user proceeds. */ "activeDate": Date; + "displayAbbreviations": boolean; /** * Specifies the number at which section headings should start. */ @@ -1447,6 +1450,58 @@ export namespace Components { */ "selectedDate": Date; } + interface CalciteDatePickerMonthRange { + /** + * The currently active Date. + */ + "activeDate": Date; + /** + * The DateTimeFormat used to provide screen reader labels. + */ + "dateTimeFormat": Intl.DateTimeFormat; + /** + * End date currently active. + */ + "endDate"?: Date; + /** + * The currently active Date. + */ + "focusedDate": Date; + /** + * The range of dates currently being hovered. + */ + "hoverRange": HoverRange; + /** + * CLDR locale data for current locale. + */ + "localeData": DateLocaleData; + /** + * Specifies the latest allowed date (`"yyyy-mm-dd"`). + */ + "max": Date; + /** + * This property specifies accessible strings for the component's previous month button ,next month button & year input elements. Made into a prop for testing purposes only. + * @readonly + */ + "messages": DatePickerMessages1; + /** + * Specifies the earliest allowed date (`"yyyy-mm-dd"`). + */ + "min": Date; + "position": "start" | "end"; + /** + * Specifies the size of the component. + */ + "scale": Scale; + /** + * Already selected date. + */ + "selectedDate": Date; + /** + * Start date currently active. + */ + "startDate"?: Date; + } interface CalciteDropdown { /** * When `true`, the component will remain open after a selection is made. If the `selectionMode` of the selected `calcite-dropdown-item`'s containing `calcite-dropdown-group` is `"none"`, the component will always close. @@ -5481,6 +5536,10 @@ export interface CalciteDatePickerMonthHeaderCustomEvent extends CustomEvent< detail: T; target: HTMLCalciteDatePickerMonthHeaderElement; } +export interface CalciteDatePickerMonthRangeCustomEvent extends CustomEvent { + detail: T; + target: HTMLCalciteDatePickerMonthRangeElement; +} export interface CalciteDropdownCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteDropdownElement; @@ -6124,6 +6183,26 @@ declare global { prototype: HTMLCalciteDatePickerMonthHeaderElement; new (): HTMLCalciteDatePickerMonthHeaderElement; }; + interface HTMLCalciteDatePickerMonthRangeElementEventMap { + "calciteInternalDatePickerSelect": Date; + "calciteInternalDatePickerHover": Date; + "calciteInternalDatePickerActiveDateChange": Date; + "calciteInternalDatePickerMouseOut": void; + } + interface HTMLCalciteDatePickerMonthRangeElement extends Components.CalciteDatePickerMonthRange, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthRangeElement, ev: CalciteDatePickerMonthRangeCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthRangeElement, ev: CalciteDatePickerMonthRangeCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + } + var HTMLCalciteDatePickerMonthRangeElement: { + prototype: HTMLCalciteDatePickerMonthRangeElement; + new (): HTMLCalciteDatePickerMonthRangeElement; + }; interface HTMLCalciteDropdownElementEventMap { "calciteDropdownSelect": void; "calciteDropdownBeforeClose": void; @@ -7447,6 +7526,7 @@ declare global { "calcite-date-picker-day": HTMLCalciteDatePickerDayElement; "calcite-date-picker-month": HTMLCalciteDatePickerMonthElement; "calcite-date-picker-month-header": HTMLCalciteDatePickerMonthHeaderElement; + "calcite-date-picker-month-range": HTMLCalciteDatePickerMonthRangeElement; "calcite-dropdown": HTMLCalciteDropdownElement; "calcite-dropdown-group": HTMLCalciteDropdownGroupElement; "calcite-dropdown-item": HTMLCalciteDropdownItemElement; @@ -8859,6 +8939,7 @@ declare namespace LocalJSX { * The focused date is indicated and will become the selected date if the user proceeds. */ "activeDate"?: Date; + "displayAbbreviations"?: boolean; /** * Specifies the number at which section headings should start. */ @@ -8894,6 +8975,71 @@ declare namespace LocalJSX { */ "selectedDate"?: Date; } + interface CalciteDatePickerMonthRange { + /** + * The currently active Date. + */ + "activeDate"?: Date; + /** + * The DateTimeFormat used to provide screen reader labels. + */ + "dateTimeFormat"?: Intl.DateTimeFormat; + /** + * End date currently active. + */ + "endDate"?: Date; + /** + * The currently active Date. + */ + "focusedDate"?: Date; + /** + * The range of dates currently being hovered. + */ + "hoverRange"?: HoverRange; + /** + * CLDR locale data for current locale. + */ + "localeData"?: DateLocaleData; + /** + * Specifies the latest allowed date (`"yyyy-mm-dd"`). + */ + "max"?: Date; + /** + * This property specifies accessible strings for the component's previous month button ,next month button & year input elements. Made into a prop for testing purposes only. + * @readonly + */ + "messages"?: DatePickerMessages1; + /** + * Specifies the earliest allowed date (`"yyyy-mm-dd"`). + */ + "min"?: Date; + /** + * Active date for the user keyboard access. + */ + "onCalciteInternalDatePickerActiveDateChange"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; + /** + * Fires when user hovers the date. + */ + "onCalciteInternalDatePickerHover"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; + "onCalciteInternalDatePickerMouseOut"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; + /** + * Fires when user selects the date. + */ + "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; + "position"?: "start" | "end"; + /** + * Specifies the size of the component. + */ + "scale"?: Scale; + /** + * Already selected date. + */ + "selectedDate"?: Date; + /** + * Start date currently active. + */ + "startDate"?: Date; + } interface CalciteDropdown { /** * When `true`, the component will remain open after a selection is made. If the `selectionMode` of the selected `calcite-dropdown-item`'s containing `calcite-dropdown-group` is `"none"`, the component will always close. @@ -13063,6 +13209,7 @@ declare namespace LocalJSX { "calcite-date-picker-day": CalciteDatePickerDay; "calcite-date-picker-month": CalciteDatePickerMonth; "calcite-date-picker-month-header": CalciteDatePickerMonthHeader; + "calcite-date-picker-month-range": CalciteDatePickerMonthRange; "calcite-dropdown": CalciteDropdown; "calcite-dropdown-group": CalciteDropdownGroup; "calcite-dropdown-item": CalciteDropdownItem; @@ -13178,6 +13325,7 @@ declare module "@stencil/core" { "calcite-date-picker-day": LocalJSX.CalciteDatePickerDay & JSXBase.HTMLAttributes; "calcite-date-picker-month": LocalJSX.CalciteDatePickerMonth & JSXBase.HTMLAttributes; "calcite-date-picker-month-header": LocalJSX.CalciteDatePickerMonthHeader & JSXBase.HTMLAttributes; + "calcite-date-picker-month-range": LocalJSX.CalciteDatePickerMonthRange & JSXBase.HTMLAttributes; "calcite-dropdown": LocalJSX.CalciteDropdown & JSXBase.HTMLAttributes; "calcite-dropdown-group": LocalJSX.CalciteDropdownGroup & JSXBase.HTMLAttributes; "calcite-dropdown-item": LocalJSX.CalciteDropdownItem & JSXBase.HTMLAttributes; diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss index c70da7b48ad..ea1be3a5198 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss @@ -1,5 +1,7 @@ :host { @apply block; + --calcite-select-internal-border-width: 0px; + --calcite-select-internal-icon-border-inline-end-width: 0px; } .header { diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 67aaabd27e6..661bf8d2f94 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -78,6 +78,8 @@ export class DatePickerMonthHeader { /** @internal */ @Prop() position: "start" | "end"; + @Prop() displayAbbreviations: boolean; + //-------------------------------------------------------------------------- // // Events @@ -185,6 +187,7 @@ export class DatePickerMonthHeader { } private renderMonthPicker(months: DateLocaleData["months"], activeMonth: number): VNode { + const monthData = this.displayAbbreviations ? months.abbreviated : months.wide; return ( - {months.abbreviated?.map((month: string, index: number) => { + {monthData.map((month: string, index: number) => { return ( this.endYear && this.disableYearsOutOfRange} diff --git a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss new file mode 100644 index 00000000000..23331f79ba2 --- /dev/null +++ b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss @@ -0,0 +1,75 @@ +@include base-component(); + +:host { + @apply w-full flex; +} + +:host([scale="m"]) { + inline-size: 620px; + min-inline-size: 544px; + max-inline-size: 972px; +} + +:host([scale="s"]) { + inline-size: 480px; + min-inline-size: 432px; + max-inline-size: 772px; +} +:host([scale="l"]) { + inline-size: 752px; + min-inline-size: 640px; + max-inline-size: 1212px; +} + +.calendar { + @apply mb-1 flex w-full justify-between; +} + +.week-headers { + @apply border-color-3 + flex + border-0 + border-solid + py-0 + px-1; +} + +.week-header { + @apply text-color-3 + text-center + font-bold; + inline-size: calc(100% / 7); +} + +.day { + @apply flex + min-w-0 + justify-center; + inline-size: calc(100% / 7); + + calcite-date-picker-day { + @apply w-full; + } +} + +:host([scale="s"]) .week-header { + @apply text-n2h px-0 pt-2 pb-3; +} + +:host([scale="m"]) .week-header { + @apply text-n2h px-0 pt-3 pb-4; +} + +:host([scale="l"]) .week-header { + @apply text-n1h px-0 pt-4 pb-5; +} + +.week-days { + @apply flex + flex-row + py-0; + padding-inline: 6px; + &:focus { + @apply outline-none; + } +} diff --git a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx new file mode 100644 index 00000000000..3c34178b34f --- /dev/null +++ b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx @@ -0,0 +1,617 @@ +import { + Component, + Element, + Event, + EventEmitter, + h, + Host, + Listen, + Prop, + VNode, + Watch, +} from "@stencil/core"; +import { dateFromRange, HoverRange, inRange, sameDate } from "../../utils/date"; +import { DateLocaleData } from "../date-picker/utils"; +import { Scale } from "../interfaces"; +import { DatePickerMessages } from "../../components"; + +const DAYS_PER_WEEK = 7; +const DAYS_MAXIMUM_INDEX = 6; + +interface Day { + active: boolean; + currentMonth?: boolean; + date: Date; + day: number; + dayInWeek?: number; + ref?: boolean; +} + +@Component({ + tag: "calcite-date-picker-month-range", + styleUrl: "date-picker-month-range.scss", + shadow: true, +}) +export class DatePickerMonthRange { + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + /** + * The DateTimeFormat used to provide screen reader labels. + * + * @internal + */ + @Prop() dateTimeFormat: Intl.DateTimeFormat; + + /** Already selected date.*/ + @Prop() selectedDate: Date; + + /** The currently active Date.*/ + @Prop() activeDate: Date = new Date(); + + @Watch("selectedDate") + updateFocusedDate(newActiveDate: Date): void { + this.focusedDate = newActiveDate; + } + + @Watch("activeDate") + updateFocusedDateWithActive(newActiveDate: Date): void { + if (!this.selectedDate) { + this.focusedDate = newActiveDate; + } + } + + /** The currently active Date. + * @internal + */ + @Prop({ mutable: true }) focusedDate: Date; + + /** Start date currently active. */ + @Prop() startDate?: Date; + + /** End date currently active. */ + @Prop() endDate?: Date; + + /** Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ + @Prop() min: Date; + + /** Specifies the latest allowed date (`"yyyy-mm-dd"`). */ + @Prop() max: Date; + + /** @internal */ + @Prop() position: "start" | "end"; + + /** Specifies the size of the component. */ + @Prop({ reflect: true }) scale: Scale; + + /** + * CLDR locale data for current locale. + * + * @internal + */ + @Prop() localeData: DateLocaleData; + + /** The range of dates currently being hovered. */ + @Prop() hoverRange: HoverRange; + + /** + * This property specifies accessible strings for the component's previous month button ,next month button & year input elements. + * Made into a prop for testing purposes only. + * + * @internal + * @readonly + */ + // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module + @Prop({ mutable: true }) messages: DatePickerMessages; + + //-------------------------------------------------------------------------- + // + // Events + // + //-------------------------------------------------------------------------- + + /** + * Fires when user selects the date. + * + * @internal + */ + @Event({ cancelable: false }) calciteInternalDatePickerSelect: EventEmitter; + + /** + * Fires when user hovers the date. + * + * @internal + */ + @Event({ cancelable: false }) calciteInternalDatePickerHover: EventEmitter; + + /** + * Active date for the user keyboard access. + * + * @internal + */ + @Event({ cancelable: false }) calciteInternalDatePickerActiveDateChange: EventEmitter; + + /** + * @internal + */ + @Event({ cancelable: false }) calciteInternalDatePickerMouseOut: EventEmitter; + + //-------------------------------------------------------------------------- + // + // Event Listeners + // + //-------------------------------------------------------------------------- + + keyDownHandler = (event: KeyboardEvent): void => { + if (event.defaultPrevented) { + return; + } + + const isRTL = this.el.dir === "rtl"; + + switch (event.key) { + case "ArrowUp": + event.preventDefault(); + this.addDays(-7); + break; + case "ArrowRight": + event.preventDefault(); + this.addDays(isRTL ? -1 : 1); + break; + case "ArrowDown": + event.preventDefault(); + this.addDays(7); + break; + case "ArrowLeft": + event.preventDefault(); + this.addDays(isRTL ? 1 : -1); + break; + case "PageUp": + event.preventDefault(); + this.addMonths(-1); + break; + case "PageDown": + event.preventDefault(); + this.addMonths(1); + break; + case "Home": + event.preventDefault(); + this.activeDate.setDate(1); + this.addDays(); + break; + case "End": + event.preventDefault(); + this.activeDate.setDate( + new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate() + ); + this.addDays(); + break; + case "Enter": + case " ": + event.preventDefault(); + break; + case "Tab": + this.activeFocus = false; + } + }; + + /** + * Once user is not interacting via keyboard, + * disable auto focusing of active date + */ + disableActiveFocus = (): void => { + this.activeFocus = false; + }; + + @Listen("pointerout") + pointerOutHandler(): void { + this.calciteInternalDatePickerMouseOut.emit(); + } + + //-------------------------------------------------------------------------- + // + // Lifecycle + // + //-------------------------------------------------------------------------- + + connectedCallback(): void { + this.focusedDate = this.selectedDate || this.activeDate; + } + + render(): VNode { + const month = this.activeDate.getMonth(); + const year = this.activeDate.getFullYear(); + const startOfWeek = this.localeData.weekStart % 7; + const { abbreviated, short, narrow } = this.localeData.days; + const weekDays = + this.scale === "s" ? narrow || short || abbreviated : short || abbreviated || narrow; + const adjustedWeekDays = [...weekDays.slice(startOfWeek, 7), ...weekDays.slice(0, startOfWeek)]; + const curMonDays = this.getCurrentMonthDays(month, year); + const prevMonDays = this.getPreviousMonthDays(month, year, startOfWeek); + const nextMonDays = this.getNextMonthDays(month, year, startOfWeek); + const endCalendarPrevMonDays = this.getPreviousMonthDays(month + 1, year, startOfWeek); + const endCalendarCurrMonDays = this.getCurrentMonthDays(month + 1, year); + const endCalendarNextMonDays = this.getNextMonthDays(month + 1, year, startOfWeek); + + const days = this.getDays(prevMonDays, curMonDays, nextMonDays); + const weeks = this.getWeeks(days); + + const nextMonthDays = this.getDays( + endCalendarPrevMonDays, + endCalendarCurrMonDays, + endCalendarNextMonDays, + "end" + ); + const nextMonthWeeks = this.getWeeks(nextMonthDays); + + return ( + +
+ {this.renderMonth(adjustedWeekDays, weeks)} + {this.renderMonth(adjustedWeekDays, nextMonthWeeks)} +
+
+ ); + } + + //-------------------------------------------------------------------------- + // + // Private State/Props + // + //-------------------------------------------------------------------------- + + @Element() el: HTMLCalciteDatePickerMonthRangeElement; + + private activeFocus: boolean; + + //-------------------------------------------------------------------------- + // + // Private Methods + // + //-------------------------------------------------------------------------- + /** + * Add n months to the current month + * + * @param step + */ + private addMonths(step: number) { + const nextDate = new Date(this.activeDate); + nextDate.setMonth(this.activeDate.getMonth() + step); + this.calciteInternalDatePickerActiveDateChange.emit( + dateFromRange(nextDate, this.min, this.max) + ); + this.activeFocus = true; + } + + /** + * Add n days to the current date + * + * @param step + */ + private addDays(step = 0) { + const nextDate = new Date(this.focusedDate); + nextDate.setDate(this.focusedDate.getDate() + step); + this.calciteInternalDatePickerActiveDateChange.emit( + dateFromRange(nextDate, this.min, this.max) + ); + + this.focusedDate = dateFromRange(nextDate, this.min, this.max); + this.activeFocus = true; + } + + /** + * Get dates for last days of the previous month + * + * @param month + * @param year + * @param startOfWeek + */ + private getPreviousMonthDays(month: number, year: number, startOfWeek: number): number[] { + const lastDate = new Date(year, month, 0); + const date = lastDate.getDate(); + const startDay = lastDate.getDay(); + const days = []; + + if (startDay === (startOfWeek + DAYS_MAXIMUM_INDEX) % DAYS_PER_WEEK) { + return days; + } + + if (startDay === startOfWeek) { + return [date]; + } + + for (let i = (DAYS_PER_WEEK + startDay - startOfWeek) % DAYS_PER_WEEK; i >= 0; i--) { + days.push(date - i); + } + return days; + } + + /** + * Get dates for the current month + * + * @param month + * @param year + */ + private getCurrentMonthDays(month: number, year: number): number[] { + const num = new Date(year, month + 1, 0).getDate(); + const days = []; + for (let i = 0; i < num; i++) { + days.push(i + 1); + } + return days; + } + + /** + * Get dates for first days of the next month + * + * @param month + * @param year + * @param startOfWeek + */ + private getNextMonthDays(month: number, year: number, startOfWeek: number): number[] { + const endDay = new Date(year, month + 1, 0).getDay(); + const days = []; + if (endDay === (startOfWeek + DAYS_MAXIMUM_INDEX) % DAYS_PER_WEEK) { + return days; + } + for (let i = 0; i < (DAYS_MAXIMUM_INDEX - (endDay - startOfWeek)) % DAYS_PER_WEEK; i++) { + days.push(i + 1); + } + return days; + } + + /** + * Get dates for the next month + * + * @param month + * @param year + * @param startOfWeek + */ + private getNextMonthWholeDays(month: number, year: number): number[] { + const num = new Date(year, month + 2, 0).getDate(); + const days = []; + for (let i = 0; i < num; i++) { + days.push(i + 1); + } + return days; + } + + /** + * Determine if the date is in between the start and end dates + * + * @param date + */ + private betweenSelectedRange(date: Date): boolean { + return !!( + this.startDate && + this.endDate && + date > this.startDate && + date < this.endDate && + !this.isRangeHover(date) + ); + } + + /** + * Determine if the date should be in selected state + * + * @param date + */ + private isSelected(date: Date): boolean { + return !!( + sameDate(date, this.selectedDate) || + (this.startDate && sameDate(date, this.startDate)) || + (this.endDate && sameDate(date, this.endDate)) + ); + } + + /** + * Determine if the date is the start of the date range + * + * @param date + */ + private isStartOfRange(date: Date): boolean { + return !!( + this.startDate && + !sameDate(this.startDate, this.endDate) && + sameDate(this.startDate, date) && + !this.isEndOfRange(date) + ); + } + + private isEndOfRange(date: Date): boolean { + return !!( + (this.endDate && !sameDate(this.startDate, this.endDate) && sameDate(this.endDate, date)) || + (!this.endDate && + this.hoverRange && + sameDate(this.startDate, this.hoverRange.end) && + sameDate(date, this.hoverRange.end)) + ); + } + + dayHover = (event: CustomEvent): void => { + const target = event.target as HTMLCalciteDatePickerDayElement; + if (target.disabled) { + this.calciteInternalDatePickerMouseOut.emit(); + } else { + this.calciteInternalDatePickerHover.emit(target.value); + } + event.stopPropagation(); + }; + + daySelect = (event: CustomEvent): void => { + const target = event.target as HTMLCalciteDatePickerDayElement; + this.activeFocus = false; + this.calciteInternalDatePickerSelect.emit(target.value); + }; + + /** + * Render calcite-date-picker-day + * + * @param active.active + * @param active + * @param day + * @param dayInWeek + * @param date + * @param currentMonth + * @param ref + * @param active.currentMonth + * @param active.date + * @param active.day + * @param active.dayInWeek + * @param active.ref + */ + private renderDateDay({ active, currentMonth, date, day, dayInWeek, ref }: Day) { + const isFocusedOnStart = this.isFocusedOnStart(); + const isHoverInRange = + this.isHoverInRange() || + (!this.endDate && this.hoverRange && sameDate(this.hoverRange?.end, this.startDate)); + + return ( +
+ { + // when moving via keyboard, focus must be updated on active date + if (ref && active && this.activeFocus) { + el?.focus(); + } + }} + /> +
+ ); + } + + private isFocusedOnStart(): boolean { + return this.hoverRange?.focused === "start"; + } + + private isHoverInRange(): boolean { + if (!this.hoverRange) { + return false; + } + const { start, end } = this.hoverRange; + return !!( + (!this.isFocusedOnStart() && this.startDate && (!this.endDate || end < this.endDate)) || + (this.isFocusedOnStart() && this.startDate && start > this.startDate) + ); + } + + private isRangeHover(date): boolean { + if (!this.hoverRange) { + return false; + } + const { start, end } = this.hoverRange; + const isStart = this.isFocusedOnStart(); + const insideRange = this.isHoverInRange(); + const cond1 = + insideRange && + ((!isStart && date > this.startDate && (date < end || sameDate(date, end))) || + (isStart && date < this.endDate && (date > start || sameDate(date, start)))); + const cond2 = + !insideRange && + ((!isStart && date >= this.endDate && (date < end || sameDate(date, end))) || + (isStart && + ((this.startDate && date < this.startDate) || + (this.endDate && sameDate(date, this.startDate))) && + ((start && date > start) || sameDate(date, start)))); + return cond1 || cond2; + } + + private getDays = ( + prevMonthDays: number[], + currMonthDays: number[], + nextMonthDays: number[], + position: "start" | "end" = "start" + ): Day[] => { + let month = this.activeDate.getMonth(); + const year = this.activeDate.getFullYear(); + let dayInWeek = 0; + const getDayInWeek = () => dayInWeek++ % 7; + month = position === "end" ? month + 1 : month; + const days: Day[] = [ + ...prevMonthDays.map((day) => { + return { + active: false, + day, + dayInWeek: getDayInWeek(), + date: new Date(year, month - 1, day), + }; + }), + ...currMonthDays.map((day) => { + const date = new Date(year, month, day); + const active = sameDate(date, this.focusedDate); + return { + active, + currentMonth: true, + day, + dayInWeek: getDayInWeek(), + date, + ref: true, + }; + }), + ...nextMonthDays.map((day) => { + return { + active: false, + day, + dayInWeek: getDayInWeek(), + date: new Date(year, month + 1, day), + }; + }), + ]; + + return days; + }; + + private getWeeks(days: Day[]): Day[][] { + const weeks: Day[][] = []; + for (let i = 0; i < days.length; i += 7) { + weeks.push(days.slice(i, i + 7)); + } + return weeks; + } + + private renderMonth(days: string[], weeks: Day[][]): VNode { + return ( +
+
+ {days.map((weekday) => ( + + {weekday} + + ))} +
+ {weeks.map((days) => ( +
+ {days.map((day) => this.renderDateDay(day))} +
+ ))} +
+ ); + } +} diff --git a/packages/calcite-components/src/components/date-picker/date-picker.scss b/packages/calcite-components/src/components/date-picker/date-picker.scss index 1aa45a142dc..7f103f02957 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.scss +++ b/packages/calcite-components/src/components/date-picker/date-picker.scss @@ -7,59 +7,52 @@ inline-block overflow-visible rounded-none - w-auto; + w-full; } -:host([scale="s"]) { - inline-size: 234px; - min-inline-size: 216px; - max-inline-size: 380px; +.month-header { + @apply flex w-full justify-between; } -:host([scale="s"][range]) { - inline-size: 480px; - min-inline-size: 432px; - max-inline-size: 772px; -} +// :host([scale="s"]) { +// inline-size: 234px; +// min-inline-size: 216px; +// max-inline-size: 380px; +// } -:host([scale="m"]) { - inline-size: 304px; - min-inline-size: 272px; - max-inline-size: 480px; -} +// :host([scale="s"][range]) { +// inline-size: 480px; +// min-inline-size: 432px; +// max-inline-size: 772px; +// } -:host([scale="m"][range]) { - inline-size: 620px; - min-inline-size: 544px; - max-inline-size: 972px; -} +// :host([scale="m"]) { +// inline-size: 304px; +// min-inline-size: 272px; +// max-inline-size: 480px; +// } -:host([scale="l"]) { - inline-size: 370px; - min-inline-size: 320px; - max-inline-size: 600px; -} +// :host([scale="m"][range]) { +// inline-size: 620px; +// min-inline-size: 544px; +// max-inline-size: 972px; +// } -:host([scale="l"][range]) { - inline-size: 752px; - min-inline-size: 640px; - max-inline-size: 1212px; -} +// :host([scale="l"]) { +// inline-size: 370px; +// min-inline-size: 320px; +// max-inline-size: 600px; +// } + +// :host([scale="l"][range]) { +// inline-size: 752px; +// min-inline-size: 640px; +// max-inline-size: 1212px; +// } .container { display: flex; flex-direction: row; } -:host([range]) { - .start, - .end { - inline-size: 50%; - } -} - -:host([range]) .start { - margin-inline-end: 12px; -} - @include base-component(); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 116cd64e09e..18579704dbb 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -79,6 +79,14 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @Prop({ reflect: true }) activeRange: "start" | "end"; + @Watch("activeRange") + handleActiveRangeChange(newValue: "start" | "end"): void { + if (newValue) { + //to reset activeDates when user switches between the input while navigating between months. This wont preserve the state of the calendar while user switch between input. + this.resetActiveDates(); + } + } + /** * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). */ @@ -270,31 +278,15 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom return (
-
- {this.renderCalendar( - startCalendarActiveDate, - this.maxAsDate, - minDate, - date, - endDate, - this.range ? "start" : null - )} -
-
- {this.range && - this.renderCalendar( - this.activeRange === "end" && - this.activeEndDate && - !this.hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) - ? this.activeEndDate - : nextMonth(this.activeStartDate), + {this.range + ? this.renderRangeCalendar( + startCalendarActiveDate, this.maxAsDate, minDate, date, - endDate, - "end" - )} -
+ endDate + ) + : this.renderCalendar(startCalendarActiveDate, this.maxAsDate, minDate, date, endDate)}
); @@ -504,8 +496,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom maxDate: Date, minDate: Date, date: Date, - endDate: Date, - position?: "start" | "end" + endDate: Date ) { return ( this.localeData && [ @@ -517,31 +508,86 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom messages={this.messages} min={minDate} onCalciteInternalDatePickerSelect={this.monthHeaderSelectChange} - position={position} scale={this.scale} selectedDate={this.activeRange === "end" ? endDate : date || new Date()} />, - position === "start" && ( - , + ] + ); + } + + private renderRangeCalendar( + activeDate: Date, + maxDate: Date, + minDate: Date, + date: Date, + endDate: Date + ) { + return ( +
+
+ - ), - ] + +
+ +
); } diff --git a/packages/calcite-components/stencil.config.ts b/packages/calcite-components/stencil.config.ts index e58c012d2ee..7e70e833253 100644 --- a/packages/calcite-components/stencil.config.ts +++ b/packages/calcite-components/stencil.config.ts @@ -33,6 +33,7 @@ export const create: () => Config = () => ({ "calcite-date-picker", "calcite-date-picker-day", "calcite-date-picker-month", + "calcite-date-picker-month-range", "calcite-date-picker-month-header", ], }, From 49689bfd0cce9d7d0ad630bf451feeedcee4202e Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 29 Jan 2024 19:11:08 -0600 Subject: [PATCH 028/155] fix month-header selection issue when wide names are displayed --- .../calcite-components/src/components.d.ts | 4 +- .../date-picker-month-header.tsx | 8 +- .../date-picker-month-range.tsx | 16 -- .../date-picker-month/date-picker-month.tsx | 16 -- .../components/date-picker/date-picker.tsx | 174 ++++++++---------- .../input-date-picker/input-date-picker.tsx | 1 - 6 files changed, 79 insertions(+), 140 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 931f184c739..3fb2cd82222 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1418,7 +1418,6 @@ export namespace Components { * The focused date is indicated and will become the selected date if the user proceeds. */ "activeDate": Date; - "displayAbbreviations": boolean; /** * Specifies the number at which section headings should start. */ @@ -1440,6 +1439,7 @@ export namespace Components { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min": Date; + "monthAbbreviations": boolean; "position": "start" | "end"; /** * Specifies the size of the component. @@ -8939,7 +8939,6 @@ declare namespace LocalJSX { * The focused date is indicated and will become the selected date if the user proceeds. */ "activeDate"?: Date; - "displayAbbreviations"?: boolean; /** * Specifies the number at which section headings should start. */ @@ -8961,6 +8960,7 @@ declare namespace LocalJSX { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min"?: Date; + "monthAbbreviations"?: boolean; /** * Fires to active date */ diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 661bf8d2f94..ca2197f6909 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -78,7 +78,7 @@ export class DatePickerMonthHeader { /** @internal */ @Prop() position: "start" | "end"; - @Prop() displayAbbreviations: boolean; + @Prop() monthAbbreviations: boolean; //-------------------------------------------------------------------------- // @@ -187,7 +187,7 @@ export class DatePickerMonthHeader { } private renderMonthPicker(months: DateLocaleData["months"], activeMonth: number): VNode { - const monthData = this.displayAbbreviations ? months.abbreviated : months.wide; + const monthData = this.monthAbbreviations ? months.abbreviated : months.wide; return ( { const target = event.target as HTMLCalciteOptionElement; - const monthIndex = this.localeData.months.abbreviated.indexOf(target.value); + const { abbreviated, wide } = this.localeData.months; + const localeMonths = this.monthAbbreviations ? abbreviated : wide; + const monthIndex = localeMonths.indexOf(target.value); const newDate = requestedMonth(this.activeDate, monthIndex); this.calciteInternalDatePickerSelect.emit(newDate); }; diff --git a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx index 3c34178b34f..a31d686c1b2 100644 --- a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx +++ b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx @@ -363,22 +363,6 @@ export class DatePickerMonthRange { return days; } - /** - * Get dates for the next month - * - * @param month - * @param year - * @param startOfWeek - */ - private getNextMonthWholeDays(month: number, year: number): number[] { - const num = new Date(year, month + 2, 0).getDate(); - const days = []; - for (let i = 0; i < num; i++) { - days.push(i + 1); - } - return days; - } - /** * Determine if the date is in between the start and end dates * diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 1d078e5bd3f..cd91f73e11a 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -383,22 +383,6 @@ export class DatePickerMonth { return days; } - /** - * Get dates for the next month - * - * @param month - * @param year - * @param startOfWeek - */ - private getNextMonthWholeDays(month: number, year: number): number[] { - const num = new Date(year, month + 2, 0).getDate(); - const days = []; - for (let i = 0; i < num; i++) { - days.push(i + 1); - } - return days; - } - /** * Determine if the date is in between the start and end dates * diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 18579704dbb..af1b793f452 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -69,9 +69,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("activeDate") activeDateWatcher(): void { - if (this.activeRange === "end") { - // this.activeEndDate = newActiveDate; - } + // if (this.activeRange === "end") { + // // this.activeEndDate = newActiveDate; + // } } /** @@ -278,15 +278,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom return (
- {this.range - ? this.renderRangeCalendar( - startCalendarActiveDate, - this.maxAsDate, - minDate, - date, - endDate - ) - : this.renderCalendar(startCalendarActiveDate, this.maxAsDate, minDate, date, endDate)} + {this.renderCalendar(startCalendarActiveDate, this.maxAsDate, minDate, date, endDate)}
); @@ -378,7 +370,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom monthHeaderSelectChange = (event: CustomEvent): void => { const date = new Date(event.detail); const target = event.target as HTMLCalciteDatePickerMonthHeaderElement; - if (!this.range) { this.activeDate = date; } else { @@ -497,97 +488,76 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom minDate: Date, date: Date, endDate: Date - ) { - return ( - this.localeData && [ - , - , - ] - ); - } - - private renderRangeCalendar( - activeDate: Date, - maxDate: Date, - minDate: Date, - date: Date, - endDate: Date - ) { + ): VNode { return ( -
-
- - + this.localeData && ( +
+
+ + {this.range && ( + + )} +
+ {this.range ? ( + + ) : ( + + )}
- -
+ ) ); } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index c2fb740e21f..329461d5c6b 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -838,7 +838,6 @@ export class InputDatePicker }; private blurHandler = (): void => { - console.log("blur handler"); this.open = false; }; From 92bedd72a70102871035813d417339b8b6abffc6 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 29 Jan 2024 19:11:58 -0600 Subject: [PATCH 029/155] adds readme --- .../date-picker-month-range/readme.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 packages/calcite-components/src/components/date-picker-month-range/readme.md diff --git a/packages/calcite-components/src/components/date-picker-month-range/readme.md b/packages/calcite-components/src/components/date-picker-month-range/readme.md new file mode 100644 index 00000000000..e6e0bd62441 --- /dev/null +++ b/packages/calcite-components/src/components/date-picker-month-range/readme.md @@ -0,0 +1,26 @@ +# calcite-date-picker-month-range + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| -------------- | --------- | ----------------------------------------------------- | ------------------- | ------------ | +| `activeDate` | -- | The currently active Date. | `Date` | `new Date()` | +| `endDate` | -- | End date currently active. | `Date` | `undefined` | +| `hoverRange` | -- | The range of dates currently being hovered. | `HoverRange` | `undefined` | +| `max` | -- | Specifies the latest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | +| `min` | -- | Specifies the earliest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | +| `scale` | `scale` | Specifies the size of the component. | `"l" \| "m" \| "s"` | `undefined` | +| `selectedDate` | -- | Already selected date. | `Date` | `undefined` | +| `startDate` | -- | Start date currently active. | `Date` | `undefined` | + +## Dependencies + +### Used by + +- [calcite-date-picker](../date-picker) + +### Depends on + +- [calcite-date-picker-day](../date-picker-day) From b6ee6758d7f909ee0f0fb360148e0603b476748e Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 30 Jan 2024 17:04:48 -0600 Subject: [PATCH 030/155] update activeDates when user is actively typing --- .../src/components/date-picker/date-picker.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index af1b793f452..14f4565d8be 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -68,10 +68,17 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Prop({ mutable: true }) activeDate: Date; @Watch("activeDate") - activeDateWatcher(): void { - // if (this.activeRange === "end") { - // // this.activeEndDate = newActiveDate; - // } + activeDateWatcher(newValue: Date): void { + //updates activeValue when user is typing in input. + if (this.range) { + if (Array.isArray(newValue)) { + this.activeStartDate = newValue[0]; + this.activeEndDate = newValue[1]; + } else { + this.activeStartDate = newValue; + this.activeEndDate = nextMonth(newValue); + } + } } /** From aa7f877ab6b3808c7d513a5508e08b0d6d1428de Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 2 Feb 2024 13:55:16 -0600 Subject: [PATCH 031/155] fix dimensions of date-picker --- .../components/date-picker/date-picker.scss | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.scss b/packages/calcite-components/src/components/date-picker/date-picker.scss index 7f103f02957..ccbc6341230 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.scss +++ b/packages/calcite-components/src/components/date-picker/date-picker.scss @@ -14,41 +14,41 @@ @apply flex w-full justify-between; } -// :host([scale="s"]) { -// inline-size: 234px; -// min-inline-size: 216px; -// max-inline-size: 380px; -// } - -// :host([scale="s"][range]) { -// inline-size: 480px; -// min-inline-size: 432px; -// max-inline-size: 772px; -// } - -// :host([scale="m"]) { -// inline-size: 304px; -// min-inline-size: 272px; -// max-inline-size: 480px; -// } - -// :host([scale="m"][range]) { -// inline-size: 620px; -// min-inline-size: 544px; -// max-inline-size: 972px; -// } - -// :host([scale="l"]) { -// inline-size: 370px; -// min-inline-size: 320px; -// max-inline-size: 600px; -// } - -// :host([scale="l"][range]) { -// inline-size: 752px; -// min-inline-size: 640px; -// max-inline-size: 1212px; -// } +:host([scale="s"]) { + inline-size: 234px; + min-inline-size: 216px; + max-inline-size: 380px; +} + +:host([scale="s"][range]) { + inline-size: 480px; + min-inline-size: 432px; + max-inline-size: 772px; +} + +:host([scale="m"]) { + inline-size: 304px; + min-inline-size: 272px; + max-inline-size: 480px; +} + +:host([scale="m"][range]) { + inline-size: 620px; + min-inline-size: 544px; + max-inline-size: 972px; +} + +:host([scale="l"]) { + inline-size: 370px; + min-inline-size: 320px; + max-inline-size: 600px; +} + +:host([scale="l"][range]) { + inline-size: 752px; + min-inline-size: 640px; + max-inline-size: 1212px; +} .container { display: flex; From 1d507fe100d250621ef59f0208e4896bc30798c9 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 2 Feb 2024 16:21:29 -0600 Subject: [PATCH 032/155] fix date-picker tests --- .../components/date-picker/date-picker.e2e.ts | 50 ++++++++++++++++--- .../date-picker/date-picker.stories.ts | 33 ++++++++---- .../components/date-picker/date-picker.tsx | 22 ++++---- 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 785381dfd65..5340c81bbc4 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -96,7 +96,7 @@ describe("calcite-date-picker", () => { it("fires a calciteDatePickerChange event when day is selected", async () => { const page = await newE2EPage(); - await page.setContent(""); + await page.setContent(""); const changedEvent = await page.spyOnEvent("calciteDatePickerChange"); await page.waitForTimeout(animationDurationInMs); @@ -108,7 +108,7 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(2); }); - it("Emits change event and updates value property when start and end dates are selected", async () => { + it("Emits change event and updates value property when start and end dates are selected from start calendar", async () => { const page = await newE2EPage(); await page.setContent(""); const datePicker = await page.find("calcite-date-picker"); @@ -122,12 +122,38 @@ describe("calcite-date-picker", () => { const startDate = `${currentYear}-${formatTimePart(currentMonth)}-01`; const endDate = `${currentYear}-${formatTimePart(currentMonth)}-15`; - await selectDay(startDate.replaceAll("-", ""), page, "mouse"); + await selectDay(startDate.replaceAll("-", ""), page, "mouse", true); + await page.waitForChanges(); + + expect(await datePicker.getProperty("value")).toEqual([startDate, ""]); + + await selectDay(endDate.replaceAll("-", ""), page, "mouse", true); + await page.waitForChanges(); + + expect(await datePicker.getProperty("value")).toEqual([startDate, endDate]); + expect(eventSpy).toHaveReceivedEventTimes(2); + }); + + it("Emits change event and updates value property when start and end dates are selected from end calendar", async () => { + const page = await newE2EPage(); + await page.setContent(""); + const datePicker = await page.find("calcite-date-picker"); + const eventSpy = await page.spyOnEvent("calciteDatePickerRangeChange"); + + await page.waitForTimeout(animationDurationInMs); + + const now = new Date(); + const currentYear = now.getUTCFullYear(); + const currentMonth = now.getUTCMonth() + 2; + const startDate = `${currentYear}-${formatTimePart(currentMonth)}-01`; + const endDate = `${currentYear}-${formatTimePart(currentMonth)}-15`; + + await selectDay(startDate.replaceAll("-", ""), page, "mouse", true); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, ""]); - await selectDay(endDate.replaceAll("-", ""), page, "mouse"); + await selectDay(endDate.replaceAll("-", ""), page, "mouse", true); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, endDate]); @@ -156,12 +182,13 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); - async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard"): Promise { + async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard", isRange = false): Promise { await page.$eval( "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard") => { + (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard", isRange: boolean) => { + const datePickerMonthEl = isRange ? "calcite-date-picker-month-range" : "calcite-date-picker-month"; const day = datePicker.shadowRoot - .querySelector("calcite-date-picker-month") + .querySelector(datePickerMonthEl) .shadowRoot.getElementById(id); if (method === "mouse") { @@ -171,7 +198,8 @@ describe("calcite-date-picker", () => { } }, id, - method + method, + isRange ); await page.waitForChanges(); } @@ -271,6 +299,12 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Tab"); await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); await page.keyboard.press("ArrowRight"); await page.waitForChanges(); await page.keyboard.press("Space"); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.stories.ts b/packages/calcite-components/src/components/date-picker/date-picker.stories.ts index 4d8f9227d82..c9dc4b85f34 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.stories.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.stories.ts @@ -106,7 +106,7 @@ const createAttributes: (options?: { exceptions: string[] }) => Attributes = ({ }, }, ], - exceptions, + exceptions ); }; @@ -120,7 +120,7 @@ export const range = (): string => createAttributes({ exceptions: ["min", "range"] }).concat([ { name: "min", value: "2016-08-09" }, { name: "range", value: "true" }, - ]), + ]) )}
`; @@ -137,6 +137,19 @@ export const rangeHighlighted_TestOnly = (): string => html` `; +export const rangeValuesNotInSameMonthAndYear_TestOnly = (): string => html` +
+ +
+ +`; + export const rangeRTL_TestOnly = (): string => html`
@@ -150,7 +163,7 @@ export const darkModeRTL_TestOnly = (): string => createAttributes({ exceptions: ["class", "dir"] }).concat([ { name: "dir", value: "rtl" }, { name: "class", value: "calcite-mode-dark" }, - ]), + ]) )}
`; @@ -165,7 +178,7 @@ export const ptPTLang_TestOnly = (): string => html`
${create( "calcite-date-picker", - createAttributes({ exceptions: ["lang"] }).concat([{ name: "lang", value: "pt-PT" }]), + createAttributes({ exceptions: ["lang"] }).concat([{ name: "lang", value: "pt-PT" }]) )}
`; @@ -176,7 +189,7 @@ export const germanLang_TestOnly = (): string => createAttributes({ exceptions: ["lang", "value"] }).concat([ { name: "lang", value: "de" }, { name: "value", value: "2022-08-11" }, - ]), + ]) )}
`; @@ -187,7 +200,7 @@ export const spanishLang_TestOnly = (): string => createAttributes({ exceptions: ["lang", "value"] }).concat([ { name: "lang", value: "es" }, { name: "value", value: "2023-05-11" }, - ]), + ]) )}
`; @@ -198,7 +211,7 @@ export const norwegianLang_TestOnly = (): string => createAttributes({ exceptions: ["lang", "value"] }).concat([ { name: "lang", value: "nb" }, { name: "value", value: "2023-05-11" }, - ]), + ]) )}
`; @@ -209,7 +222,7 @@ export const britishLang_TestOnly = (): string => createAttributes({ exceptions: ["lang", "value"] }).concat([ { name: "lang", value: "en-gb" }, { name: "value", value: "2024-01-11" }, - ]), + ]) )}
`; @@ -220,7 +233,7 @@ export const chineseLang_TestOnly = (): string => createAttributes({ exceptions: ["lang", "value"] }).concat([ { name: "lang", value: "zh-cn" }, { name: "value", value: "2024-01-11" }, - ]), + ]) )}
`; @@ -232,7 +245,7 @@ export const arabLangNumberingSystem_TestOnly = (): string => { name: "lang", value: "ar" }, { name: "numbering-system", value: "arab" }, { name: "value", value: "2022-08-11" }, - ]), + ]) )}
`; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 14f4565d8be..41ba5f8dc82 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -99,6 +99,19 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @Prop({ mutable: true }) value: string | string[]; + @Watch("value") + valueHandler(value: string | string[]): void { + if (Array.isArray(value)) { + this.valueAsDate = getValueAsDateRange(value); + // avoids updating activeDates after every selection. Update of activeDate's happen when user parses value programmatically + if (!this.mostRecentRangeValue) { + this.resetActiveDates(); + } + } else if (value) { + this.valueAsDate = dateFromISO(value); + } + } + /** * Specifies the number at which section headings should start. */ @@ -349,15 +362,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } }; - @Watch("value") - valueHandler(value: string | string[]): void { - if (Array.isArray(value)) { - this.valueAsDate = getValueAsDateRange(value); - } else if (value) { - this.valueAsDate = dateFromISO(value); - } - } - @Watch("effectiveLocale") private async loadLocaleData(): Promise { if (!Build.isBrowser) { From 7b41afdc8af39e91862545f9af415c64511a32f6 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 5 Feb 2024 01:42:36 -0600 Subject: [PATCH 033/155] fix input-date-picker tests --- .../components/date-picker/date-picker.tsx | 13 ++-- .../input-date-picker.e2e.ts | 78 ++----------------- .../input-date-picker/input-date-picker.tsx | 4 +- 3 files changed, 16 insertions(+), 79 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 41ba5f8dc82..c761d1cbfe1 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -70,13 +70,13 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("activeDate") activeDateWatcher(newValue: Date): void { //updates activeValue when user is typing in input. - if (this.range) { - if (Array.isArray(newValue)) { + + if (this.range && Array.isArray(newValue)) { + if (newValue[0] || newValue[1]) { this.activeStartDate = newValue[0]; - this.activeEndDate = newValue[1]; + this.activeEndDate = newValue[1] || nextMonth(this.activeStartDate); } else { - this.activeStartDate = newValue; - this.activeEndDate = nextMonth(newValue); + this.resetActiveDates(); } } } @@ -722,6 +722,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (!Array.isArray(this.valueAsDate) || !this.valueAsDate[1]) { return false; } + if (!startDate || !endDate) { + return false; + } const startYearMonth = startDate.getMonth(); const startYearYear = startDate.getFullYear(); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 306845042ee..83ac81570ce 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -210,7 +210,8 @@ describe("calcite-input-date-picker", () => { it("emits when value is committed for date range", async () => { const page = await newE2EPage(); await page.setContent(""); - const input = await page.find("calcite-input-date-picker"); + const inputDatePicker = await page.find("calcite-input-date-picker"); + const input = await page.find("calcite-input-date-picker >>> calcite-input-text"); const changeEvent = await page.spyOnEvent("calciteInputDatePickerChange"); await input.click(); @@ -235,15 +236,16 @@ describe("calcite-input-date-picker", () => { await page.keyboard.type(inputtedStartDate); await page.keyboard.press("Enter"); await page.waitForChanges(); + await page.waitForTimeout(3000); - expect(await input.getProperty("value")).toEqual([expectedStartDateComponentValue, ""]); + expect(await inputDatePicker.getProperty("value")).toEqual([expectedStartDateComponentValue, ""]); expect(changeEvent).toHaveReceivedEventTimes(1); await page.keyboard.type(inputtedEndDate); await page.keyboard.press("Enter"); await page.waitForChanges(); - expect(await input.getProperty("value")).toEqual([ + expect(await inputDatePicker.getProperty("value")).toEqual([ expectedStartDateComponentValue, expectedEndDateComponentValue, ]); @@ -262,7 +264,7 @@ describe("calcite-input-date-picker", () => { await page.keyboard.press("Enter"); await page.waitForChanges(); - expect(await input.getProperty("value")).toEqual([expectedStartDateComponentValue, ""]); + expect(await inputDatePicker.getProperty("value")).toEqual([expectedStartDateComponentValue, ""]); expect(changeEvent).toHaveReceivedEventTimes(3); }); @@ -412,9 +414,6 @@ describe("calcite-input-date-picker", () => { const startInput = await page.find( `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] calcite-input-text` ); - const startInputToggle = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] .${CSS.toggleIcon}` - ); const endInput = await page.find( `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] calcite-input-text` @@ -436,19 +435,6 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(calendar, "start")).toBe(false); - // toggling via start date toggle icon - - await resetFocus(page); - await startInputToggle.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(true); - - await startInputToggle.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(false); - // toggling via end date input await resetFocus(page); @@ -475,32 +461,6 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(calendar, "end")).toBe(false); - // toggling via start date input and toggle icon - - await resetFocus(page); - await startInput.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(true); - - await startInputToggle.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(false); - - // toggling via start toggle icon and date input - - await resetFocus(page); - await startInputToggle.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(true); - - await startInput.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(false); - // toggling via end date input and toggle icon await resetFocus(page); @@ -540,36 +500,10 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(calendar, "end")).toBe(true); - // toggling via start toggle icon and date input - - await resetFocus(page); - await startInputToggle.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(true); - - await endInput.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "end")).toBe(true); - // close await endInput.click(); await page.waitForChanges(); - // toggling via end date input and start toggle icon - - await resetFocus(page); - await endInput.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "end")).toBe(true); - - await startInputToggle.click(); - await page.waitForChanges(); - - expect(await isCalendarVisible(calendar, "start")).toBe(true); - // toggling via end toggle icon and start date input await resetFocus(page); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 329461d5c6b..8c1eccaa133 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -983,7 +983,7 @@ export class InputDatePicker private shouldFocusRangeStart(): boolean { const startValue = this.value[0]; const endValue = this.value[1]; - return !!(endValue && !startValue && this.focusedInput === "start" && this.startInput); + return !!(endValue && !startValue && this.focusedInput === "end" && this.startInput); } //update these logics to allow focus restoration during editing @@ -991,7 +991,7 @@ export class InputDatePicker private shouldFocusRangeEnd(): boolean { const startValue = this.value[0]; const endValue = this.value[1]; - return !!(startValue && !endValue && this.focusedInput === "end" && this.endInput); + return !!(startValue && !endValue && this.focusedInput === "start" && this.endInput); } private handleDateRangeChange = (event: CustomEvent): void => { From e165457a330ad2842eaaf89856d5c39ec84f681c Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 5 Feb 2024 14:24:41 -0600 Subject: [PATCH 034/155] refactor test utility methods in input-date-picker --- .../components/date-picker/date-picker.e2e.ts | 8 +++--- .../components/date-picker/date-picker.tsx | 2 +- .../input-date-picker.e2e.ts | 28 ++++++++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 5340c81bbc4..d12f843888d 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -182,11 +182,11 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); - async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard", isRange = false): Promise { + async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard", range = false): Promise { await page.$eval( "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard", isRange: boolean) => { - const datePickerMonthEl = isRange ? "calcite-date-picker-month-range" : "calcite-date-picker-month"; + (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard", range: boolean) => { + const datePickerMonthEl = range ? "calcite-date-picker-month-range" : "calcite-date-picker-month"; const day = datePicker.shadowRoot .querySelector(datePickerMonthEl) .shadowRoot.getElementById(id); @@ -199,7 +199,7 @@ describe("calcite-date-picker", () => { }, id, method, - isRange + range ); await page.waitForChanges(); } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index c761d1cbfe1..c2379cb89ef 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -292,7 +292,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeEndDate && !this.hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) ? prevMonth(this.activeEndDate) - : this.activeStartDate + : this.activeStartDate || prevMonth(this.activeEndDate) : activeDate; return ( diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 83ac81570ce..ffffc86390e 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -91,31 +91,34 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); } - async function selectDayInMonth(page: E2EPage, day: number): Promise { + async function selectDayInMonth(page: E2EPage, day: number, range = false): Promise { const dayIndex = day - 1; await page.evaluate( - async (dayIndex: number) => + async (dayIndex: number, range: boolean) => { + const datePickerMonthEl = range ? "calcite-date-picker-month-range" : "calcite-date-picker-month"; document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month") + .shadowRoot.querySelector(datePickerMonthEl) .shadowRoot.querySelectorAll("calcite-date-picker-day[current-month]") - [dayIndex].click(), - dayIndex + [dayIndex].click(); + }, + dayIndex, + range ); await page.waitForChanges(); } async function getActiveMonth(page: E2EPage): Promise { return page.evaluate( - async (MONTH_HEADER_CSS) => + async () => document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") .shadowRoot.querySelector("calcite-date-picker-month-header") - .shadowRoot.querySelector(`.${MONTH_HEADER_CSS.month}`).textContent, - MONTH_HEADER_CSS + .shadowRoot.querySelector("calcite-select") + .querySelector("calcite-option[selected]").textContent ); } @@ -236,7 +239,6 @@ describe("calcite-input-date-picker", () => { await page.keyboard.type(inputtedStartDate); await page.keyboard.press("Enter"); await page.waitForChanges(); - await page.waitForTimeout(3000); expect(await inputDatePicker.getProperty("value")).toEqual([expectedStartDateComponentValue, ""]); expect(changeEvent).toHaveReceivedEventTimes(1); @@ -997,13 +999,13 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); await navigateMonth(page, "previous"); - await selectDayInMonth(page, 1); + await selectDayInMonth(page, 1, true); await endDatePicker.click(); await page.waitForChanges(); await navigateMonth(page, "previous"); - await selectDayInMonth(page, 31); + await selectDayInMonth(page, 31, true); inputDatePicker.setProperty("value", ["2022-10-01", "2022-10-31"]); await page.waitForChanges(); @@ -1055,15 +1057,15 @@ describe("calcite-input-date-picker", () => { it("should normalize year to current century when user types the value in range", async () => { const page = await newE2EPage(); await page.setContent(""); + const inputEl = await page.find("calcite-input-date-picker >>> calcite-input-text"); const element = await page.find("calcite-input-date-picker"); const changeEvent = await page.spyOnEvent("calciteInputDatePickerChange"); - await element.click(); + await inputEl.click(); await page.waitForChanges(); await page.keyboard.type("1/1/20"); await page.keyboard.press("Enter"); await page.waitForChanges(); - expect(await element.getProperty("value")).toEqual(["2020-01-01", ""]); expect(changeEvent).toHaveReceivedEventTimes(1); From 28031ef6503e5a152f31bb496785c2b3ba2d49b7 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 5 Feb 2024 18:00:38 -0600 Subject: [PATCH 035/155] add date-picker visibility assertion for user interaction tests --- .../input-date-picker.e2e.ts | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index ffffc86390e..d2497ac7e52 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -242,6 +242,7 @@ describe("calcite-input-date-picker", () => { expect(await inputDatePicker.getProperty("value")).toEqual([expectedStartDateComponentValue, ""]); expect(changeEvent).toHaveReceivedEventTimes(1); + expect(await wrapper.isIntersectingViewport()).toBe(true); await page.keyboard.type(inputtedEndDate); await page.keyboard.press("Enter"); @@ -994,30 +995,39 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); const [startDatePicker, endDatePicker] = await page.findAll("calcite-input-date-picker >>> calcite-input-text"); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); await startDatePicker.click(); await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); await navigateMonth(page, "previous"); await selectDayInMonth(page, 1, true); + expect(await calendar.isVisible()).toBe(true); - await endDatePicker.click(); - await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); await navigateMonth(page, "previous"); await selectDayInMonth(page, 31, true); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); inputDatePicker.setProperty("value", ["2022-10-01", "2022-10-31"]); await page.waitForChanges(); await startDatePicker.click(); await page.waitForChanges(); - + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); expect(await getActiveMonth(page)).toBe("October"); await endDatePicker.click(); await page.waitForChanges(); - + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); expect(await getActiveMonth(page)).toBe("October"); }); @@ -1061,11 +1071,21 @@ describe("calcite-input-date-picker", () => { const element = await page.find("calcite-input-date-picker"); const changeEvent = await page.spyOnEvent("calciteInputDatePickerChange"); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + await inputEl.click(); await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + await page.keyboard.type("1/1/20"); await page.keyboard.press("Enter"); await page.waitForChanges(); + + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + expect(await element.getProperty("value")).toEqual(["2020-01-01", ""]); expect(changeEvent).toHaveReceivedEventTimes(1); @@ -1073,6 +1093,9 @@ describe("calcite-input-date-picker", () => { await page.keyboard.press("Enter"); await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + expect(await element.getProperty("value")).toEqual(["2020-01-01", "2020-02-02"]); expect(changeEvent).toHaveReceivedEventTimes(2); }); From fbec450df3da1aa3a2df97f048071fbd0a61d46c Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 6 Feb 2024 17:06:38 -0600 Subject: [PATCH 036/155] add more tests --- .../input-date-picker.e2e.ts | 141 ++++++++++++++++-- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index d2497ac7e52..8f390fc928d 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -74,20 +74,32 @@ describe("calcite-input-date-picker", () => { it.skip("supports t9n", () => t9n("calcite-input-date-picker")); - async function navigateMonth(page: E2EPage, direction: "previous" | "next"): Promise { + async function navigateMonth(page: E2EPage, direction: "previous" | "next", range = false): Promise { const linkIndex = direction === "previous" ? 0 : 1; - await page.evaluate( - async (MONTH_HEADER_CSS, linkIndex: number): Promise => - document - .querySelector("calcite-input-date-picker") - .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month-header") - .shadowRoot.querySelectorAll(`.${MONTH_HEADER_CSS.chevron}`) - [linkIndex].click(), - MONTH_HEADER_CSS, - linkIndex - ); + await (!range + ? page.evaluate( + async (MONTH_HEADER_CSS, linkIndex: number): Promise => + document + .querySelector("calcite-input-date-picker") + .shadowRoot.querySelector("calcite-date-picker") + .shadowRoot.querySelector("calcite-date-picker-month-header") + .shadowRoot.querySelectorAll(`.${MONTH_HEADER_CSS.chevron}`) + [linkIndex].click(), + MONTH_HEADER_CSS, + linkIndex + ) + : page.evaluate( + async (MONTH_HEADER_CSS, linkIndex: number): Promise => + document + .querySelector("calcite-input-date-picker") + .shadowRoot.querySelector("calcite-date-picker") + .shadowRoot.querySelectorAll("calcite-date-picker-month-header") + [linkIndex].shadowRoot.querySelector(`.${MONTH_HEADER_CSS.chevron}`) + .click(), + MONTH_HEADER_CSS, + linkIndex + )); await page.waitForChanges(); } @@ -1100,4 +1112,109 @@ describe("calcite-input-date-picker", () => { expect(changeEvent).toHaveReceivedEventTimes(2); }); }); + + describe("date-picker visibility in range", () => { + it("should keep date-picker open when user selects startDate in range calendar", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const inputDatePicker = await page.find("calcite-input-date-picker"); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 1, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 32, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + expect(await inputDatePicker.getProperty("value")).not.toBeNull(); + }); + + it("should keep date-picker open when user select startDate from end calendar", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const inputDatePicker = await page.find("calcite-input-date-picker"); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 35, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 52, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + expect(await inputDatePicker.getProperty("value")).not.toBeNull(); + }); + + it("should keep date-picker open when user is modifying the dates after initial selection", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + + await selectDayInMonth(page, 1, true); + await page.waitForChanges(); + + await selectDayInMonth(page, 32, true); + await page.waitForChanges(); + + await startDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 1, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "next", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 32, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + }); + }); }); From 94ba93ae00cb2b7ebd96c12a99c8c8753c767d75 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 8 Feb 2024 14:18:51 -0600 Subject: [PATCH 037/155] drop date-picker-month-range component and refactor date-picker-month to allow range calendar --- .../calcite-components/src/components.d.ts | 171 +---- .../date-picker-month-header.tsx | 8 +- .../date-picker-month-range.scss | 75 --- .../date-picker-month-range.tsx | 601 ------------------ .../date-picker-month-range/readme.md | 26 - .../date-picker-month/date-picker-month.scss | 4 + .../date-picker-month/date-picker-month.tsx | 111 +++- .../components/date-picker/date-picker.e2e.ts | 1 + .../components/date-picker/date-picker.tsx | 105 +-- packages/calcite-components/stencil.config.ts | 1 - 10 files changed, 142 insertions(+), 961 deletions(-) delete mode 100644 packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss delete mode 100644 packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx delete mode 100644 packages/calcite-components/src/components/date-picker-month-range/readme.md diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 3fb2cd82222..2d2c96aaa5e 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -32,7 +32,6 @@ import { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; import { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { DateLocaleData } from "./components/date-picker/utils"; import { HoverRange } from "./utils/date"; -import { DatePickerMessages as DatePickerMessages1 } from "./components"; import { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; import { ItemKeyboardEvent } from "./components/dropdown/interfaces"; import { FilterMessages } from "./components/filter/assets/filter/t9n"; @@ -119,7 +118,6 @@ export { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; export { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; export { DateLocaleData } from "./components/date-picker/utils"; export { HoverRange } from "./utils/date"; -export { DatePickerMessages as DatePickerMessages1 } from "./components"; export { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; export { ItemKeyboardEvent } from "./components/dropdown/interfaces"; export { FilterMessages } from "./components/filter/assets/filter/t9n"; @@ -1382,6 +1380,10 @@ export namespace Components { * The currently active Date. */ "focusedDate": Date; + /** + * Specifies the number at which section headings should start. + */ + "headingLevel": HeadingLevel; /** * The range of dates currently being hovered. */ @@ -1394,6 +1396,10 @@ export namespace Components { * Specifies the latest allowed date (`"yyyy-mm-dd"`). */ "max": Date; + /** + * Made into a prop for testing purposes only + */ + "messages": DatePickerMessages; /** * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ @@ -1450,58 +1456,6 @@ export namespace Components { */ "selectedDate": Date; } - interface CalciteDatePickerMonthRange { - /** - * The currently active Date. - */ - "activeDate": Date; - /** - * The DateTimeFormat used to provide screen reader labels. - */ - "dateTimeFormat": Intl.DateTimeFormat; - /** - * End date currently active. - */ - "endDate"?: Date; - /** - * The currently active Date. - */ - "focusedDate": Date; - /** - * The range of dates currently being hovered. - */ - "hoverRange": HoverRange; - /** - * CLDR locale data for current locale. - */ - "localeData": DateLocaleData; - /** - * Specifies the latest allowed date (`"yyyy-mm-dd"`). - */ - "max": Date; - /** - * This property specifies accessible strings for the component's previous month button ,next month button & year input elements. Made into a prop for testing purposes only. - * @readonly - */ - "messages": DatePickerMessages1; - /** - * Specifies the earliest allowed date (`"yyyy-mm-dd"`). - */ - "min": Date; - "position": "start" | "end"; - /** - * Specifies the size of the component. - */ - "scale": Scale; - /** - * Already selected date. - */ - "selectedDate": Date; - /** - * Start date currently active. - */ - "startDate"?: Date; - } interface CalciteDropdown { /** * When `true`, the component will remain open after a selection is made. If the `selectionMode` of the selected `calcite-dropdown-item`'s containing `calcite-dropdown-group` is `"none"`, the component will always close. @@ -5536,10 +5490,6 @@ export interface CalciteDatePickerMonthHeaderCustomEvent extends CustomEvent< detail: T; target: HTMLCalciteDatePickerMonthHeaderElement; } -export interface CalciteDatePickerMonthRangeCustomEvent extends CustomEvent { - detail: T; - target: HTMLCalciteDatePickerMonthRangeElement; -} export interface CalciteDropdownCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteDropdownElement; @@ -6151,6 +6101,7 @@ declare global { "calciteInternalDatePickerHover": Date; "calciteInternalDatePickerActiveDateChange": Date; "calciteInternalDatePickerMouseOut": void; + "calciteInternalDatePickerMonthChange": {date: Date, position : string}; } interface HTMLCalciteDatePickerMonthElement extends Components.CalciteDatePickerMonth, HTMLStencilElement { addEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthElement, ev: CalciteDatePickerMonthCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; @@ -6167,7 +6118,7 @@ declare global { new (): HTMLCalciteDatePickerMonthElement; }; interface HTMLCalciteDatePickerMonthHeaderElementEventMap { - "calciteInternalDatePickerSelect": Date; + "calciteInternalDatePickerMonthHeaderSelect": Date; } interface HTMLCalciteDatePickerMonthHeaderElement extends Components.CalciteDatePickerMonthHeader, HTMLStencilElement { addEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthHeaderElement, ev: CalciteDatePickerMonthHeaderCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; @@ -6183,26 +6134,6 @@ declare global { prototype: HTMLCalciteDatePickerMonthHeaderElement; new (): HTMLCalciteDatePickerMonthHeaderElement; }; - interface HTMLCalciteDatePickerMonthRangeElementEventMap { - "calciteInternalDatePickerSelect": Date; - "calciteInternalDatePickerHover": Date; - "calciteInternalDatePickerActiveDateChange": Date; - "calciteInternalDatePickerMouseOut": void; - } - interface HTMLCalciteDatePickerMonthRangeElement extends Components.CalciteDatePickerMonthRange, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthRangeElement, ev: CalciteDatePickerMonthRangeCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthRangeElement, ev: CalciteDatePickerMonthRangeCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLCalciteDatePickerMonthRangeElement: { - prototype: HTMLCalciteDatePickerMonthRangeElement; - new (): HTMLCalciteDatePickerMonthRangeElement; - }; interface HTMLCalciteDropdownElementEventMap { "calciteDropdownSelect": void; "calciteDropdownBeforeClose": void; @@ -7526,7 +7457,6 @@ declare global { "calcite-date-picker-day": HTMLCalciteDatePickerDayElement; "calcite-date-picker-month": HTMLCalciteDatePickerMonthElement; "calcite-date-picker-month-header": HTMLCalciteDatePickerMonthHeaderElement; - "calcite-date-picker-month-range": HTMLCalciteDatePickerMonthRangeElement; "calcite-dropdown": HTMLCalciteDropdownElement; "calcite-dropdown-group": HTMLCalciteDropdownGroupElement; "calcite-dropdown-item": HTMLCalciteDropdownItemElement; @@ -8890,6 +8820,10 @@ declare namespace LocalJSX { * The currently active Date. */ "focusedDate"?: Date; + /** + * Specifies the number at which section headings should start. + */ + "headingLevel"?: HeadingLevel; /** * The range of dates currently being hovered. */ @@ -8902,6 +8836,10 @@ declare namespace LocalJSX { * Specifies the latest allowed date (`"yyyy-mm-dd"`). */ "max"?: Date; + /** + * Made into a prop for testing purposes only + */ + "messages"?: DatePickerMessages; /** * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ @@ -8914,6 +8852,10 @@ declare namespace LocalJSX { * Fires when user hovers the date. */ "onCalciteInternalDatePickerHover"?: (event: CalciteDatePickerMonthCustomEvent) => void; + /** + * Emits when user updates month or year using `calcite-date-picker-month-header` component. + */ + "onCalciteInternalDatePickerMonthChange"?: (event: CalciteDatePickerMonthCustomEvent<{date: Date, position : string}>) => void; "onCalciteInternalDatePickerMouseOut"?: (event: CalciteDatePickerMonthCustomEvent) => void; /** * Fires when user selects the date. @@ -8964,7 +8906,7 @@ declare namespace LocalJSX { /** * Fires to active date */ - "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthHeaderCustomEvent) => void; + "onCalciteInternalDatePickerMonthHeaderSelect"?: (event: CalciteDatePickerMonthHeaderCustomEvent) => void; "position"?: "start" | "end"; /** * Specifies the size of the component. @@ -8975,71 +8917,6 @@ declare namespace LocalJSX { */ "selectedDate"?: Date; } - interface CalciteDatePickerMonthRange { - /** - * The currently active Date. - */ - "activeDate"?: Date; - /** - * The DateTimeFormat used to provide screen reader labels. - */ - "dateTimeFormat"?: Intl.DateTimeFormat; - /** - * End date currently active. - */ - "endDate"?: Date; - /** - * The currently active Date. - */ - "focusedDate"?: Date; - /** - * The range of dates currently being hovered. - */ - "hoverRange"?: HoverRange; - /** - * CLDR locale data for current locale. - */ - "localeData"?: DateLocaleData; - /** - * Specifies the latest allowed date (`"yyyy-mm-dd"`). - */ - "max"?: Date; - /** - * This property specifies accessible strings for the component's previous month button ,next month button & year input elements. Made into a prop for testing purposes only. - * @readonly - */ - "messages"?: DatePickerMessages1; - /** - * Specifies the earliest allowed date (`"yyyy-mm-dd"`). - */ - "min"?: Date; - /** - * Active date for the user keyboard access. - */ - "onCalciteInternalDatePickerActiveDateChange"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; - /** - * Fires when user hovers the date. - */ - "onCalciteInternalDatePickerHover"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; - "onCalciteInternalDatePickerMouseOut"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; - /** - * Fires when user selects the date. - */ - "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthRangeCustomEvent) => void; - "position"?: "start" | "end"; - /** - * Specifies the size of the component. - */ - "scale"?: Scale; - /** - * Already selected date. - */ - "selectedDate"?: Date; - /** - * Start date currently active. - */ - "startDate"?: Date; - } interface CalciteDropdown { /** * When `true`, the component will remain open after a selection is made. If the `selectionMode` of the selected `calcite-dropdown-item`'s containing `calcite-dropdown-group` is `"none"`, the component will always close. @@ -13209,7 +13086,6 @@ declare namespace LocalJSX { "calcite-date-picker-day": CalciteDatePickerDay; "calcite-date-picker-month": CalciteDatePickerMonth; "calcite-date-picker-month-header": CalciteDatePickerMonthHeader; - "calcite-date-picker-month-range": CalciteDatePickerMonthRange; "calcite-dropdown": CalciteDropdown; "calcite-dropdown-group": CalciteDropdownGroup; "calcite-dropdown-item": CalciteDropdownItem; @@ -13325,7 +13201,6 @@ declare module "@stencil/core" { "calcite-date-picker-day": LocalJSX.CalciteDatePickerDay & JSXBase.HTMLAttributes; "calcite-date-picker-month": LocalJSX.CalciteDatePickerMonth & JSXBase.HTMLAttributes; "calcite-date-picker-month-header": LocalJSX.CalciteDatePickerMonthHeader & JSXBase.HTMLAttributes; - "calcite-date-picker-month-range": LocalJSX.CalciteDatePickerMonthRange & JSXBase.HTMLAttributes; "calcite-dropdown": LocalJSX.CalciteDropdown & JSXBase.HTMLAttributes; "calcite-dropdown-group": LocalJSX.CalciteDropdownGroup & JSXBase.HTMLAttributes; "calcite-dropdown-item": LocalJSX.CalciteDropdownItem & JSXBase.HTMLAttributes; diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index ca2197f6909..30fa93840b2 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -90,7 +90,7 @@ export class DatePickerMonthHeader { * * @internal */ - @Event({ cancelable: false }) calciteInternalDatePickerSelect: EventEmitter; + @Event({ cancelable: false }) calciteInternalDatePickerMonthHeaderSelect: EventEmitter; //-------------------------------------------------------------------------- // @@ -282,7 +282,7 @@ export class DatePickerMonthHeader { */ private handleArrowClick = (event: MouseEvent | KeyboardEvent, date: Date): void => { event.preventDefault(); - this.calciteInternalDatePickerSelect.emit(date); + this.calciteInternalDatePickerMonthHeaderSelect.emit(date); }; handleMonthChange = (event: CustomEvent): void => { @@ -291,7 +291,7 @@ export class DatePickerMonthHeader { const localeMonths = this.monthAbbreviations ? abbreviated : wide; const monthIndex = localeMonths.indexOf(target.value); const newDate = requestedMonth(this.activeDate, monthIndex); - this.calciteInternalDatePickerSelect.emit(newDate); + this.calciteInternalDatePickerMonthHeaderSelect.emit(newDate); }; private getInRangeDate({ @@ -338,7 +338,7 @@ export class DatePickerMonthHeader { // if you've supplied a year and it's in range, update active date if (inRangeDate) { - this.calciteInternalDatePickerSelect.emit(inRangeDate); + this.calciteInternalDatePickerMonthHeaderSelect.emit(inRangeDate); } if (commit) { diff --git a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss deleted file mode 100644 index 23331f79ba2..00000000000 --- a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.scss +++ /dev/null @@ -1,75 +0,0 @@ -@include base-component(); - -:host { - @apply w-full flex; -} - -:host([scale="m"]) { - inline-size: 620px; - min-inline-size: 544px; - max-inline-size: 972px; -} - -:host([scale="s"]) { - inline-size: 480px; - min-inline-size: 432px; - max-inline-size: 772px; -} -:host([scale="l"]) { - inline-size: 752px; - min-inline-size: 640px; - max-inline-size: 1212px; -} - -.calendar { - @apply mb-1 flex w-full justify-between; -} - -.week-headers { - @apply border-color-3 - flex - border-0 - border-solid - py-0 - px-1; -} - -.week-header { - @apply text-color-3 - text-center - font-bold; - inline-size: calc(100% / 7); -} - -.day { - @apply flex - min-w-0 - justify-center; - inline-size: calc(100% / 7); - - calcite-date-picker-day { - @apply w-full; - } -} - -:host([scale="s"]) .week-header { - @apply text-n2h px-0 pt-2 pb-3; -} - -:host([scale="m"]) .week-header { - @apply text-n2h px-0 pt-3 pb-4; -} - -:host([scale="l"]) .week-header { - @apply text-n1h px-0 pt-4 pb-5; -} - -.week-days { - @apply flex - flex-row - py-0; - padding-inline: 6px; - &:focus { - @apply outline-none; - } -} diff --git a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx b/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx deleted file mode 100644 index a31d686c1b2..00000000000 --- a/packages/calcite-components/src/components/date-picker-month-range/date-picker-month-range.tsx +++ /dev/null @@ -1,601 +0,0 @@ -import { - Component, - Element, - Event, - EventEmitter, - h, - Host, - Listen, - Prop, - VNode, - Watch, -} from "@stencil/core"; -import { dateFromRange, HoverRange, inRange, sameDate } from "../../utils/date"; -import { DateLocaleData } from "../date-picker/utils"; -import { Scale } from "../interfaces"; -import { DatePickerMessages } from "../../components"; - -const DAYS_PER_WEEK = 7; -const DAYS_MAXIMUM_INDEX = 6; - -interface Day { - active: boolean; - currentMonth?: boolean; - date: Date; - day: number; - dayInWeek?: number; - ref?: boolean; -} - -@Component({ - tag: "calcite-date-picker-month-range", - styleUrl: "date-picker-month-range.scss", - shadow: true, -}) -export class DatePickerMonthRange { - //-------------------------------------------------------------------------- - // - // Properties - // - //-------------------------------------------------------------------------- - - /** - * The DateTimeFormat used to provide screen reader labels. - * - * @internal - */ - @Prop() dateTimeFormat: Intl.DateTimeFormat; - - /** Already selected date.*/ - @Prop() selectedDate: Date; - - /** The currently active Date.*/ - @Prop() activeDate: Date = new Date(); - - @Watch("selectedDate") - updateFocusedDate(newActiveDate: Date): void { - this.focusedDate = newActiveDate; - } - - @Watch("activeDate") - updateFocusedDateWithActive(newActiveDate: Date): void { - if (!this.selectedDate) { - this.focusedDate = newActiveDate; - } - } - - /** The currently active Date. - * @internal - */ - @Prop({ mutable: true }) focusedDate: Date; - - /** Start date currently active. */ - @Prop() startDate?: Date; - - /** End date currently active. */ - @Prop() endDate?: Date; - - /** Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ - @Prop() min: Date; - - /** Specifies the latest allowed date (`"yyyy-mm-dd"`). */ - @Prop() max: Date; - - /** @internal */ - @Prop() position: "start" | "end"; - - /** Specifies the size of the component. */ - @Prop({ reflect: true }) scale: Scale; - - /** - * CLDR locale data for current locale. - * - * @internal - */ - @Prop() localeData: DateLocaleData; - - /** The range of dates currently being hovered. */ - @Prop() hoverRange: HoverRange; - - /** - * This property specifies accessible strings for the component's previous month button ,next month button & year input elements. - * Made into a prop for testing purposes only. - * - * @internal - * @readonly - */ - // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module - @Prop({ mutable: true }) messages: DatePickerMessages; - - //-------------------------------------------------------------------------- - // - // Events - // - //-------------------------------------------------------------------------- - - /** - * Fires when user selects the date. - * - * @internal - */ - @Event({ cancelable: false }) calciteInternalDatePickerSelect: EventEmitter; - - /** - * Fires when user hovers the date. - * - * @internal - */ - @Event({ cancelable: false }) calciteInternalDatePickerHover: EventEmitter; - - /** - * Active date for the user keyboard access. - * - * @internal - */ - @Event({ cancelable: false }) calciteInternalDatePickerActiveDateChange: EventEmitter; - - /** - * @internal - */ - @Event({ cancelable: false }) calciteInternalDatePickerMouseOut: EventEmitter; - - //-------------------------------------------------------------------------- - // - // Event Listeners - // - //-------------------------------------------------------------------------- - - keyDownHandler = (event: KeyboardEvent): void => { - if (event.defaultPrevented) { - return; - } - - const isRTL = this.el.dir === "rtl"; - - switch (event.key) { - case "ArrowUp": - event.preventDefault(); - this.addDays(-7); - break; - case "ArrowRight": - event.preventDefault(); - this.addDays(isRTL ? -1 : 1); - break; - case "ArrowDown": - event.preventDefault(); - this.addDays(7); - break; - case "ArrowLeft": - event.preventDefault(); - this.addDays(isRTL ? 1 : -1); - break; - case "PageUp": - event.preventDefault(); - this.addMonths(-1); - break; - case "PageDown": - event.preventDefault(); - this.addMonths(1); - break; - case "Home": - event.preventDefault(); - this.activeDate.setDate(1); - this.addDays(); - break; - case "End": - event.preventDefault(); - this.activeDate.setDate( - new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate() - ); - this.addDays(); - break; - case "Enter": - case " ": - event.preventDefault(); - break; - case "Tab": - this.activeFocus = false; - } - }; - - /** - * Once user is not interacting via keyboard, - * disable auto focusing of active date - */ - disableActiveFocus = (): void => { - this.activeFocus = false; - }; - - @Listen("pointerout") - pointerOutHandler(): void { - this.calciteInternalDatePickerMouseOut.emit(); - } - - //-------------------------------------------------------------------------- - // - // Lifecycle - // - //-------------------------------------------------------------------------- - - connectedCallback(): void { - this.focusedDate = this.selectedDate || this.activeDate; - } - - render(): VNode { - const month = this.activeDate.getMonth(); - const year = this.activeDate.getFullYear(); - const startOfWeek = this.localeData.weekStart % 7; - const { abbreviated, short, narrow } = this.localeData.days; - const weekDays = - this.scale === "s" ? narrow || short || abbreviated : short || abbreviated || narrow; - const adjustedWeekDays = [...weekDays.slice(startOfWeek, 7), ...weekDays.slice(0, startOfWeek)]; - const curMonDays = this.getCurrentMonthDays(month, year); - const prevMonDays = this.getPreviousMonthDays(month, year, startOfWeek); - const nextMonDays = this.getNextMonthDays(month, year, startOfWeek); - const endCalendarPrevMonDays = this.getPreviousMonthDays(month + 1, year, startOfWeek); - const endCalendarCurrMonDays = this.getCurrentMonthDays(month + 1, year); - const endCalendarNextMonDays = this.getNextMonthDays(month + 1, year, startOfWeek); - - const days = this.getDays(prevMonDays, curMonDays, nextMonDays); - const weeks = this.getWeeks(days); - - const nextMonthDays = this.getDays( - endCalendarPrevMonDays, - endCalendarCurrMonDays, - endCalendarNextMonDays, - "end" - ); - const nextMonthWeeks = this.getWeeks(nextMonthDays); - - return ( - -
- {this.renderMonth(adjustedWeekDays, weeks)} - {this.renderMonth(adjustedWeekDays, nextMonthWeeks)} -
-
- ); - } - - //-------------------------------------------------------------------------- - // - // Private State/Props - // - //-------------------------------------------------------------------------- - - @Element() el: HTMLCalciteDatePickerMonthRangeElement; - - private activeFocus: boolean; - - //-------------------------------------------------------------------------- - // - // Private Methods - // - //-------------------------------------------------------------------------- - /** - * Add n months to the current month - * - * @param step - */ - private addMonths(step: number) { - const nextDate = new Date(this.activeDate); - nextDate.setMonth(this.activeDate.getMonth() + step); - this.calciteInternalDatePickerActiveDateChange.emit( - dateFromRange(nextDate, this.min, this.max) - ); - this.activeFocus = true; - } - - /** - * Add n days to the current date - * - * @param step - */ - private addDays(step = 0) { - const nextDate = new Date(this.focusedDate); - nextDate.setDate(this.focusedDate.getDate() + step); - this.calciteInternalDatePickerActiveDateChange.emit( - dateFromRange(nextDate, this.min, this.max) - ); - - this.focusedDate = dateFromRange(nextDate, this.min, this.max); - this.activeFocus = true; - } - - /** - * Get dates for last days of the previous month - * - * @param month - * @param year - * @param startOfWeek - */ - private getPreviousMonthDays(month: number, year: number, startOfWeek: number): number[] { - const lastDate = new Date(year, month, 0); - const date = lastDate.getDate(); - const startDay = lastDate.getDay(); - const days = []; - - if (startDay === (startOfWeek + DAYS_MAXIMUM_INDEX) % DAYS_PER_WEEK) { - return days; - } - - if (startDay === startOfWeek) { - return [date]; - } - - for (let i = (DAYS_PER_WEEK + startDay - startOfWeek) % DAYS_PER_WEEK; i >= 0; i--) { - days.push(date - i); - } - return days; - } - - /** - * Get dates for the current month - * - * @param month - * @param year - */ - private getCurrentMonthDays(month: number, year: number): number[] { - const num = new Date(year, month + 1, 0).getDate(); - const days = []; - for (let i = 0; i < num; i++) { - days.push(i + 1); - } - return days; - } - - /** - * Get dates for first days of the next month - * - * @param month - * @param year - * @param startOfWeek - */ - private getNextMonthDays(month: number, year: number, startOfWeek: number): number[] { - const endDay = new Date(year, month + 1, 0).getDay(); - const days = []; - if (endDay === (startOfWeek + DAYS_MAXIMUM_INDEX) % DAYS_PER_WEEK) { - return days; - } - for (let i = 0; i < (DAYS_MAXIMUM_INDEX - (endDay - startOfWeek)) % DAYS_PER_WEEK; i++) { - days.push(i + 1); - } - return days; - } - - /** - * Determine if the date is in between the start and end dates - * - * @param date - */ - private betweenSelectedRange(date: Date): boolean { - return !!( - this.startDate && - this.endDate && - date > this.startDate && - date < this.endDate && - !this.isRangeHover(date) - ); - } - - /** - * Determine if the date should be in selected state - * - * @param date - */ - private isSelected(date: Date): boolean { - return !!( - sameDate(date, this.selectedDate) || - (this.startDate && sameDate(date, this.startDate)) || - (this.endDate && sameDate(date, this.endDate)) - ); - } - - /** - * Determine if the date is the start of the date range - * - * @param date - */ - private isStartOfRange(date: Date): boolean { - return !!( - this.startDate && - !sameDate(this.startDate, this.endDate) && - sameDate(this.startDate, date) && - !this.isEndOfRange(date) - ); - } - - private isEndOfRange(date: Date): boolean { - return !!( - (this.endDate && !sameDate(this.startDate, this.endDate) && sameDate(this.endDate, date)) || - (!this.endDate && - this.hoverRange && - sameDate(this.startDate, this.hoverRange.end) && - sameDate(date, this.hoverRange.end)) - ); - } - - dayHover = (event: CustomEvent): void => { - const target = event.target as HTMLCalciteDatePickerDayElement; - if (target.disabled) { - this.calciteInternalDatePickerMouseOut.emit(); - } else { - this.calciteInternalDatePickerHover.emit(target.value); - } - event.stopPropagation(); - }; - - daySelect = (event: CustomEvent): void => { - const target = event.target as HTMLCalciteDatePickerDayElement; - this.activeFocus = false; - this.calciteInternalDatePickerSelect.emit(target.value); - }; - - /** - * Render calcite-date-picker-day - * - * @param active.active - * @param active - * @param day - * @param dayInWeek - * @param date - * @param currentMonth - * @param ref - * @param active.currentMonth - * @param active.date - * @param active.day - * @param active.dayInWeek - * @param active.ref - */ - private renderDateDay({ active, currentMonth, date, day, dayInWeek, ref }: Day) { - const isFocusedOnStart = this.isFocusedOnStart(); - const isHoverInRange = - this.isHoverInRange() || - (!this.endDate && this.hoverRange && sameDate(this.hoverRange?.end, this.startDate)); - - return ( -
- { - // when moving via keyboard, focus must be updated on active date - if (ref && active && this.activeFocus) { - el?.focus(); - } - }} - /> -
- ); - } - - private isFocusedOnStart(): boolean { - return this.hoverRange?.focused === "start"; - } - - private isHoverInRange(): boolean { - if (!this.hoverRange) { - return false; - } - const { start, end } = this.hoverRange; - return !!( - (!this.isFocusedOnStart() && this.startDate && (!this.endDate || end < this.endDate)) || - (this.isFocusedOnStart() && this.startDate && start > this.startDate) - ); - } - - private isRangeHover(date): boolean { - if (!this.hoverRange) { - return false; - } - const { start, end } = this.hoverRange; - const isStart = this.isFocusedOnStart(); - const insideRange = this.isHoverInRange(); - const cond1 = - insideRange && - ((!isStart && date > this.startDate && (date < end || sameDate(date, end))) || - (isStart && date < this.endDate && (date > start || sameDate(date, start)))); - const cond2 = - !insideRange && - ((!isStart && date >= this.endDate && (date < end || sameDate(date, end))) || - (isStart && - ((this.startDate && date < this.startDate) || - (this.endDate && sameDate(date, this.startDate))) && - ((start && date > start) || sameDate(date, start)))); - return cond1 || cond2; - } - - private getDays = ( - prevMonthDays: number[], - currMonthDays: number[], - nextMonthDays: number[], - position: "start" | "end" = "start" - ): Day[] => { - let month = this.activeDate.getMonth(); - const year = this.activeDate.getFullYear(); - let dayInWeek = 0; - const getDayInWeek = () => dayInWeek++ % 7; - month = position === "end" ? month + 1 : month; - const days: Day[] = [ - ...prevMonthDays.map((day) => { - return { - active: false, - day, - dayInWeek: getDayInWeek(), - date: new Date(year, month - 1, day), - }; - }), - ...currMonthDays.map((day) => { - const date = new Date(year, month, day); - const active = sameDate(date, this.focusedDate); - return { - active, - currentMonth: true, - day, - dayInWeek: getDayInWeek(), - date, - ref: true, - }; - }), - ...nextMonthDays.map((day) => { - return { - active: false, - day, - dayInWeek: getDayInWeek(), - date: new Date(year, month + 1, day), - }; - }), - ]; - - return days; - }; - - private getWeeks(days: Day[]): Day[][] { - const weeks: Day[][] = []; - for (let i = 0; i < days.length; i += 7) { - weeks.push(days.slice(i, i + 7)); - } - return weeks; - } - - private renderMonth(days: string[], weeks: Day[][]): VNode { - return ( -
-
- {days.map((weekday) => ( - - {weekday} - - ))} -
- {weeks.map((days) => ( -
- {days.map((day) => this.renderDateDay(day))} -
- ))} -
- ); - } -} diff --git a/packages/calcite-components/src/components/date-picker-month-range/readme.md b/packages/calcite-components/src/components/date-picker-month-range/readme.md deleted file mode 100644 index e6e0bd62441..00000000000 --- a/packages/calcite-components/src/components/date-picker-month-range/readme.md +++ /dev/null @@ -1,26 +0,0 @@ -# calcite-date-picker-month-range - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| -------------- | --------- | ----------------------------------------------------- | ------------------- | ------------ | -| `activeDate` | -- | The currently active Date. | `Date` | `new Date()` | -| `endDate` | -- | End date currently active. | `Date` | `undefined` | -| `hoverRange` | -- | The range of dates currently being hovered. | `HoverRange` | `undefined` | -| `max` | -- | Specifies the latest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | -| `min` | -- | Specifies the earliest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | -| `scale` | `scale` | Specifies the size of the component. | `"l" \| "m" \| "s"` | `undefined` | -| `selectedDate` | -- | Already selected date. | `Date` | `undefined` | -| `startDate` | -- | Start date currently active. | `Date` | `undefined` | - -## Dependencies - -### Used by - -- [calcite-date-picker](../date-picker) - -### Depends on - -- [calcite-date-picker-day](../date-picker-day) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss index 8ae3bd47877..6733c132b61 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss @@ -52,3 +52,7 @@ @apply outline-none; } } + +.month-header { + @apply flex w-full justify-between; +} diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index cd91f73e11a..0715a8eab37 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -10,9 +10,11 @@ import { VNode, Watch, } from "@stencil/core"; -import { dateFromRange, HoverRange, inRange, sameDate } from "../../utils/date"; +import { dateFromRange, HoverRange, inRange, nextMonth, sameDate } from "../../utils/date"; import { DateLocaleData } from "../date-picker/utils"; import { Scale } from "../interfaces"; +import { DatePickerMessages } from "../date-picker/assets/date-picker/t9n"; +import { HeadingLevel } from "../functional/Heading"; const DAYS_PER_WEEK = 7; const DAYS_MAXIMUM_INDEX = 6; @@ -98,6 +100,19 @@ export class DatePickerMonth { /** The range of dates currently being hovered. */ @Prop() hoverRange: HoverRange; + /** + * Made into a prop for testing purposes only + * + * @internal + */ + // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module + @Prop({ mutable: true }) messages: DatePickerMessages; + + /** + * Specifies the number at which section headings should start. + */ + @Prop({ reflect: true }) headingLevel: HeadingLevel; + //-------------------------------------------------------------------------- // // Events @@ -130,6 +145,16 @@ export class DatePickerMonth { */ @Event({ cancelable: false }) calciteInternalDatePickerMouseOut: EventEmitter; + /** + * Emits when user updates month or year using `calcite-date-picker-month-header` component. + * + * @internal + */ + @Event({ cancelable: false }) calciteInternalDatePickerMonthChange: EventEmitter<{ + date: Date; + position: string; + }>; + //-------------------------------------------------------------------------- // // Event Listeners @@ -240,39 +265,38 @@ export class DatePickerMonth { return ( -
-
-
- {adjustedWeekDays.map((weekday) => ( - - {weekday} - - ))} -
- {weeks.map((days) => ( -
- {days.map((day) => this.renderDateDay(day))} -
- ))} -
- +
+ {this.range && ( -
-
- {adjustedWeekDays.map((weekday) => ( - - {weekday} - - ))} -
- {nextMonthWeeks.map((days) => ( -
- {days.map((day) => this.renderDateDay(day))} -
- ))} -
+ )}
+
+ {this.renderMonthCalendar(adjustedWeekDays, weeks)} + {this.range && this.renderMonthCalendar(adjustedWeekDays, nextMonthWeeks)} +
); } @@ -599,4 +623,29 @@ export class DatePickerMonth { } return weeks; } + + private renderMonthCalendar(weekDays: string[], weeks: Day[][]): VNode { + return ( +
+
+ {weekDays.map((weekday) => ( + + {weekday} + + ))} +
+ {weeks.map((days) => ( +
+ {days.map((day) => this.renderDateDay(day))} +
+ ))} +
+ ); + } + + monthHeaderSelectChange = (event: CustomEvent): void => { + const date = new Date(event.detail); + const target = event.target as HTMLCalciteDatePickerMonthHeaderElement; + this.calciteInternalDatePickerMonthChange.emit({ date, position: target.position }); + }; } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index d12f843888d..4eac0e26b22 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -1,3 +1,4 @@ +/* eslint-disable jest/no-focused-tests */ import { E2EPage, newE2EPage } from "@stencil/core/testing"; import { html } from "../../../support/formatting"; import { defaults, focusable, hidden, renders, t9n } from "../../tests/commonTests"; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index c2379cb89ef..632c162f080 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -69,9 +69,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("activeDate") activeDateWatcher(newValue: Date): void { - //updates activeValue when user is typing in input. - - if (this.range && Array.isArray(newValue)) { + //updates activeValue when user is typing in input and avoid updating activeDates when value is set programmatically + if (this.range && Array.isArray(newValue) && !this.mostRecentRangeValue) { if (newValue[0] || newValue[1]) { this.activeStartDate = newValue[0]; this.activeEndDate = newValue[1] || nextMonth(this.activeStartDate); @@ -90,7 +89,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom handleActiveRangeChange(newValue: "start" | "end"): void { if (newValue) { //to reset activeDates when user switches between the input while navigating between months. This wont preserve the state of the calendar while user switch between input. - this.resetActiveDates(); + //this.resetActiveDates(); } } @@ -378,13 +377,14 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.dateTimeFormat = getDateTimeFormat(this.effectiveLocale, DATE_PICKER_FORMAT_OPTIONS); } - monthHeaderSelectChange = (event: CustomEvent): void => { - const date = new Date(event.detail); - const target = event.target as HTMLCalciteDatePickerMonthHeaderElement; + monthHeaderSelectChange = (event: CustomEvent<{ date: Date; position: string }>): void => { + const date = new Date(event.detail.date); + const position = event.detail.position; + if (!this.range) { this.activeDate = date; } else { - if (target.position === "end") { + if (position === "end") { this.activeEndDate = date; this.activeStartDate = prevMonth(date); } else { @@ -503,70 +503,26 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom return ( this.localeData && (
-
- - {this.range && ( - - )} -
- {this.range ? ( - - ) : ( - - )} +
) ); @@ -594,9 +550,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private setEndDate(date: Date): void { const startDate = this.getStartDate(); const newEndDate = date ? setEndOfDay(date) : date; + this.mostRecentRangeValue = newEndDate; this.value = [dateToISO(startDate), dateToISO(date)]; this.valueAsDate = [startDate, date]; - this.mostRecentRangeValue = newEndDate; this.calciteDatePickerRangeChange.emit(); } @@ -606,9 +562,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private setStartDate(date: Date): void { const endDate = this.getEndDate(); + this.mostRecentRangeValue = date; this.value = [dateToISO(date), dateToISO(endDate)]; this.valueAsDate = [date, endDate]; - this.mostRecentRangeValue = date; this.calciteDatePickerRangeChange.emit(); } @@ -652,7 +608,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (this.activeRange == "end") { this.setEndDate(date); } else { - //debugger; //allows start end to go beyond end date and set the end date to empty while editing if (date > end) { this.setEndDate(null); diff --git a/packages/calcite-components/stencil.config.ts b/packages/calcite-components/stencil.config.ts index 7e70e833253..e58c012d2ee 100644 --- a/packages/calcite-components/stencil.config.ts +++ b/packages/calcite-components/stencil.config.ts @@ -33,7 +33,6 @@ export const create: () => Config = () => ({ "calcite-date-picker", "calcite-date-picker-day", "calcite-date-picker-month", - "calcite-date-picker-month-range", "calcite-date-picker-month-header", ], }, From 55d0f76b1d40e4813107657ce6a1e0d2983fe18d Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 8 Feb 2024 17:30:45 -0600 Subject: [PATCH 038/155] update tests --- .../calcite-components/src/components.d.ts | 10 ++++++-- .../components/date-picker/date-picker.e2e.ts | 24 +++++++++---------- .../input-date-picker.e2e.ts | 7 ++++-- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 2d2c96aaa5e..8ab71448aa2 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -6101,7 +6101,10 @@ declare global { "calciteInternalDatePickerHover": Date; "calciteInternalDatePickerActiveDateChange": Date; "calciteInternalDatePickerMouseOut": void; - "calciteInternalDatePickerMonthChange": {date: Date, position : string}; + "calciteInternalDatePickerMonthChange": { + date: Date; + position: string; + }; } interface HTMLCalciteDatePickerMonthElement extends Components.CalciteDatePickerMonth, HTMLStencilElement { addEventListener(type: K, listener: (this: HTMLCalciteDatePickerMonthElement, ev: CalciteDatePickerMonthCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; @@ -8855,7 +8858,10 @@ declare namespace LocalJSX { /** * Emits when user updates month or year using `calcite-date-picker-month-header` component. */ - "onCalciteInternalDatePickerMonthChange"?: (event: CalciteDatePickerMonthCustomEvent<{date: Date, position : string}>) => void; + "onCalciteInternalDatePickerMonthChange"?: (event: CalciteDatePickerMonthCustomEvent<{ + date: Date; + position: string; + }>) => void; "onCalciteInternalDatePickerMouseOut"?: (event: CalciteDatePickerMonthCustomEvent) => void; /** * Fires when user selects the date. diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 4eac0e26b22..753bfd43cd5 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -25,7 +25,7 @@ describe("calcite-date-picker", () => { describe("focusable", () => { focusable("calcite-date-picker", { - shadowFocusTargetSelector: "calcite-date-picker-month-header", + shadowFocusTargetSelector: "calcite-date-picker-month", }); }); @@ -123,12 +123,12 @@ describe("calcite-date-picker", () => { const startDate = `${currentYear}-${formatTimePart(currentMonth)}-01`; const endDate = `${currentYear}-${formatTimePart(currentMonth)}-15`; - await selectDay(startDate.replaceAll("-", ""), page, "mouse", true); + await selectDay(startDate.replaceAll("-", ""), page, "mouse"); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, ""]); - await selectDay(endDate.replaceAll("-", ""), page, "mouse", true); + await selectDay(endDate.replaceAll("-", ""), page, "mouse"); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, endDate]); @@ -149,12 +149,12 @@ describe("calcite-date-picker", () => { const startDate = `${currentYear}-${formatTimePart(currentMonth)}-01`; const endDate = `${currentYear}-${formatTimePart(currentMonth)}-15`; - await selectDay(startDate.replaceAll("-", ""), page, "mouse", true); + await selectDay(startDate.replaceAll("-", ""), page, "mouse"); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, ""]); - await selectDay(endDate.replaceAll("-", ""), page, "mouse", true); + await selectDay(endDate.replaceAll("-", ""), page, "mouse"); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, endDate]); @@ -183,13 +183,12 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); - async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard", range = false): Promise { + async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard"): Promise { await page.$eval( "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard", range: boolean) => { - const datePickerMonthEl = range ? "calcite-date-picker-month-range" : "calcite-date-picker-month"; + (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard") => { const day = datePicker.shadowRoot - .querySelector(datePickerMonthEl) + .querySelector("calcite-date-picker-month") .shadowRoot.getElementById(id); if (method === "mouse") { @@ -199,8 +198,7 @@ describe("calcite-date-picker", () => { } }, id, - method, - range + method ); await page.waitForChanges(); } @@ -350,10 +348,10 @@ describe("calcite-date-picker", () => { expect(minDateAsTime).toEqual(new Date(minDateString).getTime()); }); - it("passes down the default year prop to child date-picker-month-header", async () => { + it("passes down the default year prop to child date-picker-month", async () => { const page = await newE2EPage(); await page.setContent(html``); - const date = await page.find(`calcite-date-picker >>> calcite-date-picker-month-header`); + const date = await page.find(`calcite-date-picker >>> calcite-date-picker-month`); expect(await date.getProperty("messages")).toEqual({ nextMonth: "Next month", diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 8f390fc928d..95717915673 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -83,6 +83,7 @@ describe("calcite-input-date-picker", () => { document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") + .shadowRoot.querySelector("calcite-date-picker-month") .shadowRoot.querySelector("calcite-date-picker-month-header") .shadowRoot.querySelectorAll(`.${MONTH_HEADER_CSS.chevron}`) [linkIndex].click(), @@ -94,6 +95,7 @@ describe("calcite-input-date-picker", () => { document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") + .shadowRoot.querySelector("calcite-date-picker-month") .shadowRoot.querySelectorAll("calcite-date-picker-month-header") [linkIndex].shadowRoot.querySelector(`.${MONTH_HEADER_CSS.chevron}`) .click(), @@ -107,8 +109,8 @@ describe("calcite-input-date-picker", () => { const dayIndex = day - 1; await page.evaluate( - async (dayIndex: number, range: boolean) => { - const datePickerMonthEl = range ? "calcite-date-picker-month-range" : "calcite-date-picker-month"; + async (dayIndex: number) => { + const datePickerMonthEl = "calcite-date-picker-month"; document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") @@ -128,6 +130,7 @@ describe("calcite-input-date-picker", () => { document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") + .shadowRoot.querySelector("calcite-date-picker-month") .shadowRoot.querySelector("calcite-date-picker-month-header") .shadowRoot.querySelector("calcite-select") .querySelector("calcite-option[selected]").textContent From 09bbb24b68fa2c16558a1731737a1e8d96763f75 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 9 Feb 2024 14:48:26 -0600 Subject: [PATCH 039/155] add test and remove watcher for activeRange in date-picker --- .../calcite-components/src/components.d.ts | 8 ---- .../date-picker-month/date-picker-month.tsx | 8 ++-- .../components/date-picker/date-picker.tsx | 17 +++---- .../input-date-picker.e2e.ts | 47 +++++++++++++++++++ 4 files changed, 57 insertions(+), 23 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 8ab71448aa2..9c9d57e49f2 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1376,10 +1376,6 @@ export namespace Components { * End date currently active. */ "endDate"?: Date; - /** - * The currently active Date. - */ - "focusedDate": Date; /** * Specifies the number at which section headings should start. */ @@ -8819,10 +8815,6 @@ declare namespace LocalJSX { * End date currently active. */ "endDate"?: Date; - /** - * The currently active Date. - */ - "focusedDate"?: Date; /** * Specifies the number at which section headings should start. */ diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 0715a8eab37..a80d57852ef 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -9,6 +9,7 @@ import { Prop, VNode, Watch, + State, } from "@stencil/core"; import { dateFromRange, HoverRange, inRange, nextMonth, sameDate } from "../../utils/date"; import { DateLocaleData } from "../date-picker/utils"; @@ -65,11 +66,6 @@ export class DatePickerMonth { } } - /** The currently active Date. - * @internal - */ - @Prop({ mutable: true }) focusedDate: Date; - /** Start date currently active. */ @Prop() startDate?: Date; @@ -155,6 +151,8 @@ export class DatePickerMonth { position: string; }>; + /** The currently focused Date. */ + @State() focusedDate: Date; //-------------------------------------------------------------------------- // // Event Listeners diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 632c162f080..623b89e32d9 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -85,14 +85,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @Prop({ reflect: true }) activeRange: "start" | "end"; - @Watch("activeRange") - handleActiveRangeChange(newValue: "start" | "end"): void { - if (newValue) { - //to reset activeDates when user switches between the input while navigating between months. This wont preserve the state of the calendar while user switch between input. - //this.resetActiveDates(); - } - } - /** * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). */ @@ -386,10 +378,15 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } else { if (position === "end") { this.activeEndDate = date; - this.activeStartDate = prevMonth(date); + //preserves the state of the calendar while user switch between input. + if (!this.valueAsDate || !this.valueAsDate[0]) { + this.activeStartDate = prevMonth(date); + } } else { this.activeStartDate = date; - this.activeEndDate = nextMonth(date); + if (!this.valueAsDate || !this.valueAsDate[1]) { + this.activeEndDate = nextMonth(date); + } } } }; diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 95717915673..b38e0ab908d 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1220,4 +1220,51 @@ describe("calcite-input-date-picker", () => { expect(await calendar.isVisible()).toBe(false); }); }); + + it("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const inputDatePickerEl = await page.find("calcite-input-date-picker"); + const [startDatePicker, endDatePicker] = await page.findAll("calcite-input-date-picker >>> calcite-input-text"); + + inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-25"]); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await endDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 41, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + const value = await inputDatePickerEl.getProperty("value"); + expect(value[1]).not.toEqual("2024-06-25"); + }); }); From c36c6940c6a402b5334b471e0068c921f103b5cf Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 12 Feb 2024 21:37:30 -0600 Subject: [PATCH 040/155] update test and update calendar when user types a valid date --- .../components/date-picker/date-picker.tsx | 30 ++++++++++++------- .../input-date-picker.e2e.ts | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 623b89e32d9..8ce0b84aafd 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -68,14 +68,24 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Prop({ mutable: true }) activeDate: Date; @Watch("activeDate") - activeDateWatcher(newValue: Date): void { + activeDateWatcher(newValue: Date | Date[]): void { //updates activeValue when user is typing in input and avoid updating activeDates when value is set programmatically - if (this.range && Array.isArray(newValue) && !this.mostRecentRangeValue) { - if (newValue[0] || newValue[1]) { - this.activeStartDate = newValue[0]; - this.activeEndDate = newValue[1] || nextMonth(this.activeStartDate); - } else { - this.resetActiveDates(); + if (this.range && !this.mostRecentRangeValue) { + if (Array.isArray(newValue)) { + if (newValue[0] || newValue[1]) { + this.activeStartDate = newValue[0]; + this.activeEndDate = newValue[1] || nextMonth(this.activeStartDate); + } else { + this.resetActiveDates(); + } + } else if (newValue) { + if (this.activeRange === "end") { + this.activeStartDate = prevMonth(newValue); + this.activeEndDate = newValue; + } else { + this.activeStartDate = newValue; + this.activeEndDate = nextMonth(newValue); + } } } } @@ -671,9 +681,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } private hasSameMonthAndYear(startDate: Date, endDate: Date): boolean { - if (!Array.isArray(this.valueAsDate) || !this.valueAsDate[1]) { - return false; - } + // if (!Array.isArray(this.valueAsDate) || !this.valueAsDate[1]) { + // return false; + // } if (!startDate || !endDate) { return false; } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index b38e0ab908d..1d87b573f21 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1262,7 +1262,7 @@ describe("calcite-input-date-picker", () => { await selectDayInMonth(page, 41, true); await page.waitForChanges(); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await calendar.isVisible()).toBe(false); const value = await inputDatePickerEl.getProperty("value"); expect(value[1]).not.toEqual("2024-06-25"); From 237e4140762b9048b2e3767d904c2b34fe39b018 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 13 Feb 2024 12:49:15 -0600 Subject: [PATCH 041/155] restore watch handler for valueAsDate prop in date-picker for range --- .../src/components/date-picker/date-picker.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 8ce0b84aafd..56efb58218b 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -123,7 +123,13 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("valueAsDate") valueAsDateWatcher(newValueAsDate: Date | Date[]): void { - if (newValueAsDate && newValueAsDate !== this.activeDate && !this.range) { + if (this.range && Array.isArray(newValueAsDate) && !this.mostRecentRangeValue) { + const { activeStartDate, activeEndDate } = this; + const newActiveStartDate = newValueAsDate[0]; + const newActiveEndDate = newValueAsDate[1]; + this.activeStartDate = activeStartDate !== newActiveStartDate && newActiveStartDate; + this.activeEndDate = activeEndDate !== newActiveEndDate && newActiveEndDate; + } else if (newValueAsDate && newValueAsDate !== this.activeDate) { this.activeDate = newValueAsDate as Date; } } From 3e742102bb63008335b2f8f3de20d3fef1d77592 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 13 Feb 2024 15:48:31 -0600 Subject: [PATCH 042/155] fix test failures --- .../src/components/date-picker/date-picker.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 56efb58218b..9df40791694 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -124,11 +124,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("valueAsDate") valueAsDateWatcher(newValueAsDate: Date | Date[]): void { if (this.range && Array.isArray(newValueAsDate) && !this.mostRecentRangeValue) { - const { activeStartDate, activeEndDate } = this; - const newActiveStartDate = newValueAsDate[0]; - const newActiveEndDate = newValueAsDate[1]; - this.activeStartDate = activeStartDate !== newActiveStartDate && newActiveStartDate; - this.activeEndDate = activeEndDate !== newActiveEndDate && newActiveEndDate; + this.setActiveDates(); } else if (newValueAsDate && newValueAsDate !== this.activeDate) { this.activeDate = newValueAsDate as Date; } From bdb0a8c4614d2a9a3706e95b6a6c9a46d9098e0b Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 14 Feb 2024 13:12:50 -0600 Subject: [PATCH 043/155] fix activeDate when min and max are before the current date --- .../src/components/date-picker/date-picker.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 9df40791694..c7c7264fa32 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -19,6 +19,7 @@ import { dateToISO, getDaysDiff, HoverRange, + inRange, nextMonth, prevMonth, setEndOfDay, @@ -679,6 +680,17 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.activeStartDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); this.activeEndDate = this.getActiveEndDate(endDate, this.minAsDate, this.maxAsDate); + + // when min and max are defined and the current date is beyond the range. + if (this.activeStartDate === this.activeEndDate) { + const previousMonthActiveDate = prevMonth(this.activeEndDate); + const nextMonthActiveDate = nextMonth(this.activeEndDate); + if (inRange(previousMonthActiveDate, this.minAsDate, this.maxAsDate)) { + this.activeStartDate = previousMonthActiveDate; + } else if (inRange(nextMonthActiveDate, this.minAsDate, this.maxAsDate)) { + this.activeEndDate = nextMonthActiveDate; + } + } } } From 9abb3b9aa0358dd99a092ffde8b3d5212a450865 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 15 Feb 2024 17:48:12 -0600 Subject: [PATCH 044/155] lets users to navigate months when valueAsDate is parsed --- .../components/date-picker/date-picker.tsx | 37 +++----- .../input-date-picker.e2e.ts | 90 +++++++++++++------ 2 files changed, 79 insertions(+), 48 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index c7c7264fa32..5344bec6813 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -22,7 +22,6 @@ import { inRange, nextMonth, prevMonth, - setEndOfDay, } from "../../utils/date"; import { componentFocusable, @@ -71,7 +70,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("activeDate") activeDateWatcher(newValue: Date | Date[]): void { //updates activeValue when user is typing in input and avoid updating activeDates when value is set programmatically - if (this.range && !this.mostRecentRangeValue) { + if (this.range && !this.userChangeRangeValue) { if (Array.isArray(newValue)) { if (newValue[0] || newValue[1]) { this.activeStartDate = newValue[0]; @@ -106,7 +105,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (Array.isArray(value)) { this.valueAsDate = getValueAsDateRange(value); // avoids updating activeDates after every selection. Update of activeDate's happen when user parses value programmatically - if (!this.mostRecentRangeValue) { + if (!this.userChangeRangeValue) { this.resetActiveDates(); } } else if (value) { @@ -124,7 +123,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Watch("valueAsDate") valueAsDateWatcher(newValueAsDate: Date | Date[]): void { - if (this.range && Array.isArray(newValueAsDate) && !this.mostRecentRangeValue) { + if (this.range && Array.isArray(newValueAsDate) && !this.userChangeRangeValue) { this.setActiveDates(); } else if (newValueAsDate && newValueAsDate !== this.activeDate) { this.activeDate = newValueAsDate as Date; @@ -227,7 +226,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @Method() async reset(): Promise { this.resetActiveDates(); - this.mostRecentRangeValue = undefined; + this.userChangeRangeValue = false; } // -------------------------------------------------------------------------- @@ -275,7 +274,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const date = dateFromRange( this.range && Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, this.minAsDate, - this.maxAsDate + this.maxAsDate, ); const activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); @@ -348,12 +347,10 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom @State() private localeData: DateLocaleData; - @State() mostRecentRangeValue?: Date; - - //@State() private mostRecentActiveDateValue?: Date; - @State() startAsDate: Date; + private userChangeRangeValue = false; + //-------------------------------------------------------------------------- // // Private Methods @@ -391,15 +388,10 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } else { if (position === "end") { this.activeEndDate = date; - //preserves the state of the calendar while user switch between input. - if (!this.valueAsDate || !this.valueAsDate[0]) { - this.activeStartDate = prevMonth(date); - } + this.activeStartDate = prevMonth(date); } else { this.activeStartDate = date; - if (!this.valueAsDate || !this.valueAsDate[1]) { - this.activeEndDate = nextMonth(date); - } + this.activeEndDate = nextMonth(date); } } }; @@ -508,7 +500,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom maxDate: Date, minDate: Date, date: Date, - endDate: Date + endDate: Date, ): VNode { return ( this.localeData && ( @@ -559,8 +551,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private setEndDate(date: Date): void { const startDate = this.getStartDate(); - const newEndDate = date ? setEndOfDay(date) : date; - this.mostRecentRangeValue = newEndDate; + this.userChangeRangeValue = true; this.value = [dateToISO(startDate), dateToISO(date)]; this.valueAsDate = [startDate, date]; this.calciteDatePickerRangeChange.emit(); @@ -572,7 +563,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private setStartDate(date: Date): void { const endDate = this.getEndDate(); - this.mostRecentRangeValue = date; + this.userChangeRangeValue = true; this.value = [dateToISO(date), dateToISO(endDate)]; this.valueAsDate = [date, endDate]; this.calciteDatePickerRangeChange.emit(); @@ -669,13 +660,13 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const date = dateFromRange( Array.isArray(this.valueAsDate) ? this.valueAsDate[0] : this.valueAsDate, this.minAsDate, - this.maxAsDate + this.maxAsDate, ); const endDate = dateFromRange( Array.isArray(this.valueAsDate) ? this.valueAsDate[1] : null, this.minAsDate, - this.maxAsDate + this.maxAsDate, ); this.activeStartDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 1d87b573f21..42b64b945f4 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -88,7 +88,7 @@ describe("calcite-input-date-picker", () => { .shadowRoot.querySelectorAll(`.${MONTH_HEADER_CSS.chevron}`) [linkIndex].click(), MONTH_HEADER_CSS, - linkIndex + linkIndex, ) : page.evaluate( async (MONTH_HEADER_CSS, linkIndex: number): Promise => @@ -100,7 +100,7 @@ describe("calcite-input-date-picker", () => { [linkIndex].shadowRoot.querySelector(`.${MONTH_HEADER_CSS.chevron}`) .click(), MONTH_HEADER_CSS, - linkIndex + linkIndex, )); await page.waitForChanges(); } @@ -119,7 +119,7 @@ describe("calcite-input-date-picker", () => { [dayIndex].click(); }, dayIndex, - range + range, ); await page.waitForChanges(); } @@ -133,7 +133,7 @@ describe("calcite-input-date-picker", () => { .shadowRoot.querySelector("calcite-date-picker-month") .shadowRoot.querySelector("calcite-date-picker-month-header") .shadowRoot.querySelector("calcite-select") - .querySelector("calcite-option[selected]").textContent + .querySelector("calcite-option[selected]").textContent, ); } @@ -146,7 +146,7 @@ describe("calcite-input-date-picker", () => { .querySelector("calcite-input-date-picker") .shadowRoot.querySelectorAll("calcite-input-text") [inputIndex].shadowRoot.querySelector("input").value, - inputIndex + inputIndex, ); } @@ -167,7 +167,7 @@ describe("calcite-input-date-picker", () => { (calendarWrapperClass: string) => document.querySelector("calcite-input-date-picker").shadowRoot.querySelector(`.${calendarWrapperClass}`), {}, - CSS.calendarWrapper + CSS.calendarWrapper, ); expect(await wrapper.isIntersectingViewport()).toBe(true); @@ -240,7 +240,7 @@ describe("calcite-input-date-picker", () => { (calendarWrapperClass: string) => document.querySelector("calcite-input-date-picker").shadowRoot.querySelector(`.${calendarWrapperClass}`), {}, - CSS.calendarWrapper + CSS.calendarWrapper, ); expect(await wrapper.isIntersectingViewport()).toBe(true); @@ -336,7 +336,7 @@ describe("calcite-input-date-picker", () => { document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-input-text") - .shadowRoot.querySelector("input") + .shadowRoot.querySelector("input"), ) ).asElement(); await input.focus(); @@ -430,14 +430,14 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(calendar, "end")).toBe(false); const startInput = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] calcite-input-text` + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="start"] calcite-input-text`, ); const endInput = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] calcite-input-text` + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] calcite-input-text`, ); const endInputToggle = await page.find( - `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] .${CSS.toggleIcon}` + `calcite-input-date-picker >>> .${CSS.inputWrapper}[data-position="end"] .${CSS.toggleIcon}`, ); // toggling via start date input @@ -574,7 +574,7 @@ describe("calcite-input-date-picker", () => { it("renders arabic numerals while typing in the input when numbering-system is set to arab", async () => { const page = await newE2EPage(); await page.setContent( - `` + ``, ); await page.keyboard.press("Tab"); @@ -618,13 +618,13 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.setContent( - `` + ``, ); const inputDatePicker = await page.find("calcite-input-date-picker"); expect(await getActiveMonth(page)).toEqual(langTranslations.months.wide[Number(month) - 1]); expect(await getDateInputValue(page)).toBe( - langTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year) + langTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year), ); inputDatePicker.setProperty("lang", newLang); @@ -632,7 +632,7 @@ describe("calcite-input-date-picker", () => { expect(await getActiveMonth(page)).toEqual(newLangTranslations.months.wide[Number(month) - 1]); expect(await getDateInputValue(page)).toBe( - newLangTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year) + newLangTranslations.placeholder.replace("DD", day).replace("MM", month).replace("YYYY", year), ); }); @@ -682,7 +682,11 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.emulateTimezone("America/Los_Angeles"); await page.setContent( - html`` + html``, ); const element = await page.find("calcite-input-date-picker"); @@ -691,7 +695,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); const minDateString = "Mon Nov 15 2021 00:00:00 GMT-0800 (Pacific Standard Time)"; const minDateAsTime = await page.$eval("calcite-input-date-picker", (picker: HTMLCalciteInputDatePickerElement) => - picker.minAsDate.getTime() + picker.minAsDate.getTime(), ); expect(minDateAsTime).toEqual(new Date(minDateString).getTime()); }); @@ -700,7 +704,7 @@ describe("calcite-input-date-picker", () => { floatingUIOwner( ``, "open", - { shadowSelector: ".menu-container" } + { shadowSelector: ".menu-container" }, ); }); @@ -836,7 +840,7 @@ describe("calcite-input-date-picker", () => {
-
` +
`, ); await page.waitForChanges(); @@ -868,7 +872,7 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.setContent( html` -
next sibling
` +
next sibling
`, ); await page.keyboard.press("Tab"); @@ -910,7 +914,7 @@ describe("calcite-input-date-picker", () => { const page = await newE2EPage(); await page.setContent( html` -
next sibling
` +
next sibling
`, ); await page.keyboard.press("Tab"); @@ -1068,7 +1072,7 @@ describe("calcite-input-date-picker", () => { it("should not normalize year to current century when value is parsed as attribute", async () => { const page = await newE2EPage(); await page.setContent( - html`` + html``, ); const element = await page.find("calcite-input-date-picker"); @@ -1221,7 +1225,7 @@ describe("calcite-input-date-picker", () => { }); }); - it("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { + it.skip("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { const page = await newE2EPage(); await page.setContent(html``); await skipAnimations(page); @@ -1262,9 +1266,45 @@ describe("calcite-input-date-picker", () => { await selectDayInMonth(page, 41, true); await page.waitForChanges(); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + expect(await calendar.isVisible()).toBe(true); const value = await inputDatePickerEl.getProperty("value"); - expect(value[1]).not.toEqual("2024-06-25"); + expect(value[1]).toEqual("2024-06-25"); + }); + + it("should be able to navigate months when valueAsDate is parsed", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + + await page.$eval("calcite-input-date-picker", (element: any) => { + element.valueAsDate = [new Date("2024-05-25"), new Date("2024-06-25")]; + }); + + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await navigateMonth(page, "next", true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); }); }); From f40cb99fe71c09c36eb4c4fb91bd7dd05ff06343 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 16 Feb 2024 10:43:58 -0600 Subject: [PATCH 045/155] restore activeEndDate --- .../src/components/date-picker/date-picker.tsx | 8 ++++++++ .../components/input-date-picker/input-date-picker.e2e.ts | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 5344bec6813..466d521dd45 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -95,6 +95,14 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @Prop({ reflect: true }) activeRange: "start" | "end"; + @Watch("activeRange") + handleActiveRangeChange(newValue: string): void { + //preserve activeEndDate when user selects startDate and focus shifts on to endDate + if (newValue && Array.isArray(this.valueAsDate) && this.valueAsDate[0] && this.valueAsDate[1]) { + this.resetActiveDates(); + } + } + /** * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). */ diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 42b64b945f4..eaf406c3630 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1225,7 +1225,7 @@ describe("calcite-input-date-picker", () => { }); }); - it.skip("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { + it("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { const page = await newE2EPage(); await page.setContent(html``); await skipAnimations(page); @@ -1263,13 +1263,13 @@ describe("calcite-input-date-picker", () => { calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); - await selectDayInMonth(page, 41, true); + await selectDayInMonth(page, 40, true); await page.waitForChanges(); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await calendar.isVisible()).toBe(false); const value = await inputDatePickerEl.getProperty("value"); - expect(value[1]).toEqual("2024-06-25"); + expect(value[1]).not.toEqual("2024-06-25"); }); it("should be able to navigate months when valueAsDate is parsed", async () => { From 5827054c409f9c87dbc0bbf62bd220a54a7c5c35 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 16 Feb 2024 11:29:15 -0600 Subject: [PATCH 046/155] add more stories --- .../input-date-picker.stories.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts index 4ab0da6174f..9fc3ee1cf8e 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts @@ -196,3 +196,37 @@ export const widthSetToBreakpoints_TestOnly = (): string => createBreakpointStories( html``, ); + +export const rangeWithValueAsDate = (): string => html` + + +`; + +export const rangeWithValue = (): string => html` + + +`; + +export const rangeWithMinBeforeCurrentDate = (): string => html` + +`; + +export const rangeWithMaxBeforeCurrentDate = (): string => html` + +`; + +export const rangeWithMinAsDateAfterCurrentDate = (): string => html` + + +`; From 903cd3d1f2b720e80eb7f7c5c0db14b1f5bf82b4 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 16 Feb 2024 14:36:15 -0600 Subject: [PATCH 047/155] add delay for stories with open prop --- .../input-date-picker.stories.ts | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts index 9fc3ee1cf8e..e7da7d9be75 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts @@ -197,7 +197,7 @@ export const widthSetToBreakpoints_TestOnly = (): string => html``, ); -export const rangeWithValueAsDate = (): string => html` +export const rangeWithValueAsDate_TestOnly = (): string => html` `; -export const rangeWithValue = (): string => html` +rangeWithValueAsDate_TestOnly.parameters = { + chromatic: { delay: 1000 }, +}; + +export const rangeWithValue_TestOnly = (): string => html` `; -export const rangeWithMinBeforeCurrentDate = (): string => html` +rangeWithValue_TestOnly.parameters = { + chromatic: { delay: 1000 }, +}; + +export const rangeWithMinBeforeCurrentDate_TestOnly = (): string => html` `; -export const rangeWithMaxBeforeCurrentDate = (): string => html` +rangeWithMinBeforeCurrentDate_TestOnly.parameters = { + chromatic: { delay: 1000 }, +}; + +export const rangeWithMaxBeforeCurrentDate_TestOnly = (): string => html` `; -export const rangeWithMinAsDateAfterCurrentDate = (): string => html` +rangeWithMaxBeforeCurrentDate_TestOnly.parameters = { + chromatic: { delay: 1000 }, +}; + +export const rangeWithMinAsDateAfterCurrentDate_TestOnly = (): string => html` `; + +rangeWithMinAsDateAfterCurrentDate_TestOnly.parameters = { + chromatic: { delay: 1000 }, +}; From 1a92e3706e3d8ca5397991e9ab406adf861f798b Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 18 Mar 2024 18:18:11 -0500 Subject: [PATCH 048/155] replace year-picker with select --- .../date-picker-month-header.tsx | 80 ++++++++++++------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 30fa93840b2..c04779ced52 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -101,7 +101,7 @@ export class DatePickerMonthHeader { componentWillLoad(): void { this.parentDatePickerEl = closestElementCrossShadowBoundary( this.el, - "calcite-date-picker" + "calcite-date-picker", ) as HTMLCalciteDatePickerElement; } @@ -138,15 +138,7 @@ export class DatePickerMonthHeader {
{this.renderMonthPicker(months, activeMonth)} - (this.yearPickerEl = el)} - /> + {this.renderYearPicker()}
{this.position !== "end" && ( @@ -188,21 +180,42 @@ export class DatePickerMonthHeader { private renderMonthPicker(months: DateLocaleData["months"], activeMonth: number): VNode { const monthData = this.monthAbbreviations ? months.abbreviated : months.wide; + return ( + + {monthData.map((month: string, index: number) => { + return ( + + {month} + + ); + })} + + ); + } + + private renderYearPicker(): VNode { + this.getYearList(); return ( (this.yearPickerEl = el)} > - {monthData.map((month: string, index: number) => { + {this.yearList?.map((year: number) => { + const yearString = year.toString(); return ( this.endYear && this.disableYearsOutOfRange} - selected={index === activeMonth} - value={month} + selected={ + this.selectedDate + ? this.selectedDate.getFullYear() === year + : this.activeDate.getFullYear() === year + } + value={yearString} > - {month} + {numberStringFormatter?.localize(yearString)} + {this.localeData?.year?.suffix} ); })} @@ -210,6 +223,13 @@ export class DatePickerMonthHeader { ); } + private getYearList(): void { + this.yearList = []; + for (let i = this.min?.getFullYear() || 1900; i <= (this.max?.getFullYear() || 2100); i++) { + this.yearList.push(i); + } + } + //-------------------------------------------------------------------------- // // Private State/Props @@ -220,13 +240,13 @@ export class DatePickerMonthHeader { private parentDatePickerEl: HTMLCalciteDatePickerElement; - private yearPickerEl: HTMLCalciteYearPickerElement; + private yearPickerEl: HTMLCalciteSelectElement; @State() nextMonthDate: Date; @State() prevMonthDate: Date; - @State() yearList: number[] = []; + private yearList: number[] = []; @Watch("min") @Watch("max") @@ -246,15 +266,13 @@ export class DatePickerMonthHeader { // //-------------------------------------------------------------------------- - private onYearChange = (event: Event): void => { - const target = event.target as HTMLCalciteYearPickerElement; - if (!Array.isArray(target.value)) { - this.setYear({ - localizedYear: numberStringFormatter.localize( - `${parseCalendarYear(target.value, this.localeData)}` - ), - }); - } + private handleYearChange = (event: Event): void => { + const target = event.target as HTMLCalciteSelectElement; + this.setYear({ + localizedYear: numberStringFormatter.localize( + `${parseCalendarYear(Number(target.value), this.localeData)}`, + ), + }); }; private prevMonthClick = (event: KeyboardEvent | MouseEvent): void => { @@ -344,8 +362,8 @@ export class DatePickerMonthHeader { if (commit) { this.yearPickerEl.value = formatCalendarYear( (inRangeDate || activeDate).getFullYear(), - this.localeData - ); + this.localeData, + ).toString(); } } } From 96ef22dbb484a54c899e21c673b2f966f71fbf7d Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Mon, 18 Mar 2024 18:29:16 -0500 Subject: [PATCH 049/155] drop year-picker and month-picker components --- .../month-picker-item/month-picker-item.scss | 16 - .../month-picker-item/month-picker-item.tsx | 37 --- .../components/month-picker-item/readme.md | 24 -- .../components/month-picker/month-picker.scss | 38 --- .../components/month-picker/month-picker.tsx | 153 --------- .../src/components/month-picker/readme.md | 29 -- .../src/components/year-picker/readme.md | 49 --- .../components/year-picker/year-picker.scss | 14 - .../components/year-picker/year-picker.tsx | 293 ------------------ .../src/demos/month-picker.html | 14 - 10 files changed, 667 deletions(-) delete mode 100644 packages/calcite-components/src/components/month-picker-item/month-picker-item.scss delete mode 100644 packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx delete mode 100644 packages/calcite-components/src/components/month-picker-item/readme.md delete mode 100644 packages/calcite-components/src/components/month-picker/month-picker.scss delete mode 100644 packages/calcite-components/src/components/month-picker/month-picker.tsx delete mode 100644 packages/calcite-components/src/components/month-picker/readme.md delete mode 100644 packages/calcite-components/src/components/year-picker/readme.md delete mode 100644 packages/calcite-components/src/components/year-picker/year-picker.scss delete mode 100644 packages/calcite-components/src/components/year-picker/year-picker.tsx delete mode 100644 packages/calcite-components/src/demos/month-picker.html diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss b/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss deleted file mode 100644 index 8d2f832a313..00000000000 --- a/packages/calcite-components/src/components/month-picker-item/month-picker-item.scss +++ /dev/null @@ -1,16 +0,0 @@ -:host { - display: flex; -} - -.month-item { - display: flex; - inline-size: 100%; - @apply text-color-1; - justify-content: center; - align-items: center; -} - -.month-item--active { - background-color: var(--calcite-color-brand); - color: #ffffff; -} diff --git a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx b/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx deleted file mode 100644 index 0edcd90614b..00000000000 --- a/packages/calcite-components/src/components/month-picker-item/month-picker-item.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Component, Host, VNode, h, Element, Prop, EventEmitter, Event } from "@stencil/core"; - -@Component({ - tag: "calcite-month-picker-item", - styleUrl: "month-picker-item.scss", - shadow: true, -}) -export class MonthPickerItem { - @Element() el: HTMLCalciteMonthPickerItemElement; - - @Prop() value: string; - - @Prop() isActive: boolean; - - /** - * Emits whenever the component is selected. - * - */ - @Event() calciteInternalMonthPickerItemSelect: EventEmitter; - - private handleClick = (): void => { - this.calciteInternalMonthPickerItemSelect.emit(this.value); - }; - - render(): VNode { - return ( - -
- {this.value} -
-
- ); - } -} diff --git a/packages/calcite-components/src/components/month-picker-item/readme.md b/packages/calcite-components/src/components/month-picker-item/readme.md deleted file mode 100644 index 50f4ba608f8..00000000000 --- a/packages/calcite-components/src/components/month-picker-item/readme.md +++ /dev/null @@ -1,24 +0,0 @@ -# calcite-month-picker-item - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ---------- | ----------- | ----------- | --------- | ----------- | -| `isActive` | `is-active` | | `boolean` | `undefined` | -| `value` | `value` | | `string` | `undefined` | - -## Events - -| Event | Description | Type | -| -------------------------------------- | ----------------------------------------- | --------------------- | -| `calciteInternalMonthPickerItemSelect` | Emits whenever the component is selected. | `CustomEvent` | - -## Dependencies - -### Used by - -- [calcite-month-picker](../month-picker) - ---- diff --git a/packages/calcite-components/src/components/month-picker/month-picker.scss b/packages/calcite-components/src/components/month-picker/month-picker.scss deleted file mode 100644 index 1a77360ae71..00000000000 --- a/packages/calcite-components/src/components/month-picker/month-picker.scss +++ /dev/null @@ -1,38 +0,0 @@ -:host { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr 1fr 1fr; - block-size: 250px; - inline-size: 358px; - background-color: var(--calcite-color-foreground-1); - font-size: var(--calcite-font-size--1); - grid-template-areas: "header header header header"; -} - -.month-items { - justify-self: stretch; - align-self: stretch; -} - -.header { - grid-area: header; - display: flex; - justify-content: space-between; - align-items: center; -} - -.year-picker { - inline-size: 278px; -} - -.next, -.previous { - inline-size: 40px; - block-size: 100%; -} - -calcite-year-picker { - // width: 100px; - --calcite-select-internal-border-width: 0px; - --calcite-select-internal-icon-border-inline-end-width: 0px; -} diff --git a/packages/calcite-components/src/components/month-picker/month-picker.tsx b/packages/calcite-components/src/components/month-picker/month-picker.tsx deleted file mode 100644 index 91a97f75ff6..00000000000 --- a/packages/calcite-components/src/components/month-picker/month-picker.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { - Component, - Host, - VNode, - h, - Element, - Prop, - State, - Watch, - Build, - Listen, - Event, - EventEmitter, -} from "@stencil/core"; -import { LocalizedComponent, connectLocalized, disconnectLocalized } from "../../utils/locale"; -import { DateLocaleData, getLocaleData } from "../date-picker/utils"; - -@Component({ - tag: "calcite-month-picker", - styleUrl: "month-picker.scss", - shadow: true, -}) -export class MonthPicker implements LocalizedComponent { - //-------------------------------------------------------------------------- - // - // Public Properties - // - //-------------------------------------------------------------------------- - - @Prop({ mutable: true }) activeMonthIndex: number; - - /** Already selected date. */ - @Prop() selectedMonthYear: Date; - - /** Focused date with indicator (will become selected date if user proceeds) */ - @Prop() activeDate: Date; - - /** Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ - @Prop() min: Date; - - /** Specifies the latest allowed date (`"yyyy-mm-dd"`). */ - @Prop() max: Date; - - //-------------------------------------------------------------------------- - // - // Events - // - //-------------------------------------------------------------------------- - - /** - * Emits whenever the component is selected. - * - */ - @Event() calciteMonthPickerChange: EventEmitter; - - // -------------------------------------------------------------------------- - // - // Lifecycle - // - // -------------------------------------------------------------------------- - - connectedCallback() { - connectLocalized(this); - } - - async componentWillLoad(): Promise { - await this.loadLocaleData(); - } - - disconnectedCallback() { - disconnectLocalized(this); - } - - //-------------------------------------------------------------------------- - // - // Private State/Props - // - //-------------------------------------------------------------------------- - - @Element() el: HTMLCalciteMonthPickerElement; - - @State() effectiveLocale = ""; - - @State() localeData: DateLocaleData; - - @Watch("effectiveLocale") - private async loadLocaleData(): Promise { - if (!Build.isBrowser) { - return; - } - - this.localeData = await getLocaleData(this.effectiveLocale); - } - - yearPickerEl: HTMLCalciteYearPickerElement; - - //-------------------------------------------------------------------------- - // - // Private Methods - // - //-------------------------------------------------------------------------- - - @Listen("calciteInternalMonthPickerItemSelect") - handleCalciteMonthPickerItemChange(event: CustomEvent): void { - this.activeMonthIndex = this.localeData?.months.abbreviated.indexOf(event.detail); - this.calciteMonthPickerChange.emit(); - } - - handlePreviousYear = (): void => { - this.yearPickerEl.prevYear(); - }; - - handleNextYear = (): void => { - console.log("next year"); - this.yearPickerEl.nextYear(); - }; - - setYearPickerEl = (el: HTMLCalciteYearPickerElement): void => { - this.yearPickerEl = el; - }; - - render(): VNode { - return ( - -
- - - -
- {this.localeData?.months.abbreviated.map((month, index) => ( - - ))} -
- ); - } -} diff --git a/packages/calcite-components/src/components/month-picker/readme.md b/packages/calcite-components/src/components/month-picker/readme.md deleted file mode 100644 index 5289945ff65..00000000000 --- a/packages/calcite-components/src/components/month-picker/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# calcite-month-picker - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------------- | -------------------- | ------------------------------------------------------------------------ | -------- | ----------- | -| `activeDate` | -- | Focused date with indicator (will become selected date if user proceeds) | `Date` | `undefined` | -| `activeMonthIndex` | `active-month-index` | | `number` | `undefined` | -| `max` | -- | Specifies the latest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | -| `min` | -- | Specifies the earliest allowed date (`"yyyy-mm-dd"`). | `Date` | `undefined` | -| `selectedMonthYear` | -- | Already selected date. | `Date` | `undefined` | - -## Events - -| Event | Description | Type | -| -------------------------- | ----------------------------------------- | ------------------- | -| `calciteMonthPickerChange` | Emits whenever the component is selected. | `CustomEvent` | - -## Dependencies - -### Depends on - -- [calcite-year-picker](../year-picker) -- [calcite-action](../action) -- [calcite-month-picker-item](../month-picker-item) - ---- diff --git a/packages/calcite-components/src/components/year-picker/readme.md b/packages/calcite-components/src/components/year-picker/readme.md deleted file mode 100644 index 744ed01ab30..00000000000 --- a/packages/calcite-components/src/components/year-picker/readme.md +++ /dev/null @@ -1,49 +0,0 @@ -# calcite-year-picker - - - -## Properties - -| Property | Attribute | Description | Type | Default | -| ------------------------ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ----------- | -| `disableYearsOutOfRange` | `disable-years-out-of-range` | When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. | `boolean` | `false` | -| `disabled` | `disabled` | When `true`, disables the component | `boolean` | `undefined` | -| `max` | `max` | Specifies the latest allowed year (`"yyyy"`). | `number` | `2100` | -| `min` | `min` | Specifies the earliest allowed year (`"yyyy"`). | `number` | `1900` | -| `numberingSystem` | `numbering-system` | Specifies the Unicode numeral system used by the component for localization. | `"arab" \| "arabext" \| "latn"` | `undefined` | -| `range` | `range` | When `true`, activates the component's range mode to allow a start and end year. | `boolean` | `undefined` | -| `value` | `value` | Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). | `number \| number[]` | `undefined` | - -## Events - -| Event | Description | Type | -| ------------------------- | ----------------------------------------- | ------------------- | -| `calciteYearPickerChange` | Emits whenever the component is selected. | `CustomEvent` | - -## Methods - -### `nextYear() => Promise` - -#### Returns - -Type: `Promise` - -### `prevYear() => Promise` - -#### Returns - -Type: `Promise` - -## Dependencies - -### Used by - -- [calcite-date-picker-month-header](../date-picker-month-header) -- [calcite-month-picker](../month-picker) - -### Depends on - -- [calcite-select](../select) -- [calcite-option](../option) - ---- diff --git a/packages/calcite-components/src/components/year-picker/year-picker.scss b/packages/calcite-components/src/components/year-picker/year-picker.scss deleted file mode 100644 index d65952fa956..00000000000 --- a/packages/calcite-components/src/components/year-picker/year-picker.scss +++ /dev/null @@ -1,14 +0,0 @@ -:host { - display: flex; - flex-direction: row; - inline-size: 100%; -} - -.start-year, -.end-year { - inline-size: 50%; -} - -.year { - inline-size: 100%; -} diff --git a/packages/calcite-components/src/components/year-picker/year-picker.tsx b/packages/calcite-components/src/components/year-picker/year-picker.tsx deleted file mode 100644 index b2e51c5a958..00000000000 --- a/packages/calcite-components/src/components/year-picker/year-picker.tsx +++ /dev/null @@ -1,293 +0,0 @@ -import { - Component, - VNode, - h, - Element, - Prop, - State, - Watch, - Event, - EventEmitter, - Host, - Method, -} from "@stencil/core"; -import { - LocalizedComponent, - NumberingSystem, - connectLocalized, - disconnectLocalized, - numberStringFormatter, -} from "../../utils/locale"; -import { DateLocaleData, getLocaleData } from "../date-picker/utils"; -// import { DateLocaleData } from "../date-picker/utils"; - -@Component({ - tag: "calcite-year-picker", - styleUrl: "year-picker.scss", - shadow: true, -}) -export class YearPicker implements LocalizedComponent { - //-------------------------------------------------------------------------- - // - // Public Properties - // - //-------------------------------------------------------------------------- - - /** When `true`, disables the component */ - @Prop({ reflect: true }) disabled: boolean; - - /** When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. */ - @Prop() disableYearsOutOfRange = false; - - /** Specifies the latest allowed year (`"yyyy"`). */ - @Prop({ mutable: true }) max = 2100; - - /** Specifies the earliest allowed year (`"yyyy"`). */ - @Prop({ mutable: true }) min = 1900; - - @Watch("min") - handleMinChange(value: number): void { - if (!value) { - this.min = 1900; - return; - } - this.getYearList(); - } - - @Watch("max") - handleMaxChange(value: number): void { - if (!value) { - this.max = 2100; - return; - } - this.getYearList(); - } - - /** - * Specifies the Unicode numeral system used by the component for localization. - */ - @Prop({ reflect: true }) numberingSystem: NumberingSystem; - - /** When `true`, activates the component's range mode to allow a start and end year. */ - @Prop() range: boolean; - - /** - * Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). - */ - @Prop({ mutable: true }) value: number | number[]; - - @Watch("value") - handleValueChange(value: number | number[]): void { - if (Array.isArray(value)) { - this.startYear = value[0]; - this.endYear = value[1]; - } else if (value) { - this.startYear = value; - } - } - - //-------------------------------------------------------------------------- - // - // Events - // - //-------------------------------------------------------------------------- - - /** - * Emits whenever the component is selected. - * - */ - @Event() calciteYearPickerChange: EventEmitter; - - // -------------------------------------------------------------------------- - // - // Lifecycle - // - // -------------------------------------------------------------------------- - - connectedCallback() { - connectLocalized(this); - if (Array.isArray(this.value)) { - if (this.range) { - this.startYear = this.value[0]; - this.endYear = this.value[1]; - } - } else { - this.startYear = this.value; - } - if (!this.value) { - this.value = new Date().getFullYear(); - } - this.getYearList(); - } - - disconnectedCallback() { - disconnectLocalized(this); - } - - @Method() - async prevYear(): Promise { - if (Array.isArray(this.value)) { - this.value = - this.activeRange === "start" - ? [this.value[0] - 1, this.value[1]] - : [this.value[0], this.value[1] - 1]; - } else { - this.value = this.value - 1; - } - } - - @Method() - async nextYear(): Promise { - // console.log("next year", this.value); - if (Array.isArray(this.value)) { - this.value = - this.activeRange === "start" - ? [this.value[0] + 1, this.value[1]] - : [this.value[0], this.value[1] + 1]; - } else { - this.value = this.value + 1; - } - } - //-------------------------------------------------------------------------- - // - // Private State/Props - // - //-------------------------------------------------------------------------- - - @Element() el: HTMLCalciteYearPickerElement; - - @State() effectiveLocale = ""; - - @Watch("effectiveLocale") - @Watch("numberingSystem") - async updateNumberStringFormatter(): Promise { - numberStringFormatter.numberFormatOptions = { - locale: this.effectiveLocale, - numberingSystem: this.numberingSystem, - useGrouping: false, - }; - - this.localeData = await getLocaleData(this.effectiveLocale); - } - - @State() yearList: number[] = []; - - private endYear: number; - - private startYear: number; - - private activeRange: "start" | "end" = "start"; - - @State() localeData: DateLocaleData; - - // maxValueSelectEl: HTMLCalciteSelectElement; - - // selectEl: HTMLCalciteSelectElement; - - //-------------------------------------------------------------------------- - // - // Private Methods - // - //-------------------------------------------------------------------------- - - getYearList(): void { - this.yearList = []; - for (let i = this.min; i <= this.max; i++) { - this.yearList.push(i); - } - } - - handleSelectChange = (event: CustomEvent): void => { - event.stopPropagation(); - - this.activeRange = "start"; - const target = event.target as HTMLCalciteSelectElement; - const newValue = Number(target.value); - - if (this.range && Array.isArray(this.value)) { - this.value = [newValue, this.value[1]]; - this.startYear = newValue; - } else { - this.value = newValue; - } - - this.calciteYearPickerChange.emit(); - }; - - handleEndYearSelectChange = (event: CustomEvent): void => { - event.stopPropagation(); - const target = event.target as HTMLCalciteSelectElement; - const newValue = Number(target.value); - this.activeRange = "end"; - - if (Array.isArray(this.value)) { - this.value = [this.value[0], newValue]; - this.endYear = newValue; - } - - this.calciteYearPickerChange.emit(); - }; - - private isYearSelected(year: number): boolean { - return !Array.isArray(this.value) ? year === this.value : false; - } - - // setSelectEl = (el: HTMLCalciteSelectElement): void => { - // this.selectEl = el; - // }; - - // setMaxValueSelectEl = (el: HTMLCalciteSelectElement): void => { - // this.maxValueSelectEl = el; - // }; - - render(): VNode { - const suffix = this.localeData?.year?.suffix; - return ( - - - {this.yearList?.map((year: number) => { - const yearString = year.toString(); - return ( - this.endYear && this.disableYearsOutOfRange} - selected={(this.range && year === this.startYear) || this.isYearSelected(year)} - value={yearString} - > - {numberStringFormatter?.localize(yearString)} - {suffix} - - ); - })} - - {this.range && ( - - {this.yearList?.map((year: number) => { - const yearString = year.toString(); - return ( - - {numberStringFormatter?.localize(yearString)} - - ); - })} - - )} - - ); - } -} diff --git a/packages/calcite-components/src/demos/month-picker.html b/packages/calcite-components/src/demos/month-picker.html deleted file mode 100644 index c7dde155b00..00000000000 --- a/packages/calcite-components/src/demos/month-picker.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Month Picker - - - - - - - From 4e4aea78cc2e45d39c62246c00283a43771ab2ba Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 19 Mar 2024 15:29:09 -0500 Subject: [PATCH 050/155] update stencil config --- .../calcite-components/src/components.d.ts | 288 ++++++------------ .../date-picker-month/date-picker-month.tsx | 12 +- packages/calcite-components/stencil.config.ts | 1 - 3 files changed, 102 insertions(+), 199 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 6a416408f9a..f012d347f1d 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -8,80 +8,176 @@ import { HTMLStencilElement, JSXBase } from "@stencil/core/internal"; import { Alignment, Appearance, Columns, FlipContext, Kind, Layout, LogicalFlowPosition, Position, Scale, SelectionMode, Status, Width } from "./components/interfaces"; import { RequestedItem } from "./components/accordion/interfaces"; import { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces"; +import { ActionMessages } from "./components/action/assets/action/t9n"; import { EffectivePlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui"; +import { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; +import { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; +import { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; import { AlertDuration, Sync } from "./components/alert/interfaces"; import { NumberingSystem } from "./utils/locale"; +import { AlertMessages } from "./components/alert/assets/alert/t9n"; import { HeadingLevel } from "./components/functional/Heading"; +import { BlockMessages } from "./components/block/assets/block/t9n"; import { BlockSectionToggleDisplay } from "./components/block-section/interfaces"; +import { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; import { ButtonAlignment, DropdownIconType } from "./components/button/interfaces"; +import { ButtonMessages } from "./components/button/assets/button/t9n"; +import { CardMessages } from "./components/card/assets/card/t9n"; +import { ChipMessages } from "./components/chip/assets/chip/t9n"; import { ColorValue, InternalColor } from "./components/color-picker/interfaces"; import { Format } from "./components/color-picker/utils"; +import { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; import { ComboboxChildElement, SelectionDisplay } from "./components/combobox/interfaces"; +import { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; +import { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { DateLocaleData } from "./components/date-picker/utils"; import { HoverRange } from "./utils/date"; import { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; import { ItemKeyboardEvent } from "./components/dropdown/interfaces"; +import { FilterMessages } from "./components/filter/assets/filter/t9n"; import { FlowItemLikeElement } from "./components/flow/interfaces"; +import { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; import { ColorStop, DataSeries } from "./components/graph/interfaces"; +import { HandleMessages } from "./components/handle/assets/handle/t9n"; import { HandleChange, HandleNudge } from "./components/handle/interfaces"; +import { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; import { InputPlacement } from "./components/input/interfaces"; +import { InputMessages } from "./components/input/assets/input/t9n"; +import { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; +import { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; +import { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; +import { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; +import { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; +import { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; import { TimeZoneMode } from "./components/input-time-zone/interfaces"; import { ListDragDetail } from "./components/list/interfaces"; import { ItemData } from "./components/list-item/interfaces"; +import { ListMessages } from "./components/list/assets/list/t9n"; import { SelectionAppearance } from "./components/list/resources"; +import { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; +import { MenuMessages } from "./components/menu/assets/menu/t9n"; +import { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; import { MenuItemCustomEvent } from "./components/menu-item/interfaces"; import { MeterLabelType } from "./components/meter/interfaces"; +import { ModalMessages } from "./components/modal/assets/modal/t9n"; +import { NoticeMessages } from "./components/notice/assets/notice/t9n"; +import { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; +import { PanelMessages } from "./components/panel/assets/panel/t9n"; import { ItemData as ItemData1, ListFocusId } from "./components/pick-list/shared-list-logic"; import { ICON_TYPES } from "./components/pick-list/resources"; +import { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; +import { PopoverMessages } from "./components/popover/assets/popover/t9n"; +import { RatingMessages } from "./components/rating/assets/rating/t9n"; +import { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; import { DisplayMode } from "./components/sheet/interfaces"; import { DisplayMode as DisplayMode1 } from "./components/shell-panel/interfaces"; +import { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; import { DragDetail } from "./utils/sortableComponent"; import { StepperItemChangeEventDetail, StepperItemEventDetail, StepperItemKeyEventDetail, StepperLayout } from "./components/stepper/interfaces"; +import { StepperMessages } from "./components/stepper/assets/stepper/t9n"; +import { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; import { TabID, TabLayout, TabPosition } from "./components/tabs/interfaces"; +import { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; import { TabChangeEventDetail, TabCloseEventDetail } from "./components/tab/interfaces"; +import { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; import { RowType, TableInteractionMode, TableLayout, TableRowFocusEvent } from "./components/table/interfaces"; +import { TableMessages } from "./components/table/assets/table/t9n"; +import { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; +import { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; +import { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; import { TileSelectType } from "./components/tile-select/interfaces"; import { TileSelectGroupLayout } from "./components/tile-select-group/interfaces"; +import { TipMessages } from "./components/tip/assets/tip/t9n"; +import { TipManagerMessages } from "./components/tip-manager/assets/tip-manager/t9n"; import { TreeItemSelectDetail } from "./components/tree-item/interfaces"; +import { ValueListMessages } from "./components/value-list/assets/value-list/t9n"; import { ListItemAndHandle } from "./components/value-list-item/interfaces"; export { Alignment, Appearance, Columns, FlipContext, Kind, Layout, LogicalFlowPosition, Position, Scale, SelectionMode, Status, Width } from "./components/interfaces"; export { RequestedItem } from "./components/accordion/interfaces"; export { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces"; +export { ActionMessages } from "./components/action/assets/action/t9n"; export { EffectivePlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui"; +export { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; +export { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; +export { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; export { AlertDuration, Sync } from "./components/alert/interfaces"; export { NumberingSystem } from "./utils/locale"; +export { AlertMessages } from "./components/alert/assets/alert/t9n"; export { HeadingLevel } from "./components/functional/Heading"; +export { BlockMessages } from "./components/block/assets/block/t9n"; export { BlockSectionToggleDisplay } from "./components/block-section/interfaces"; +export { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; export { ButtonAlignment, DropdownIconType } from "./components/button/interfaces"; +export { ButtonMessages } from "./components/button/assets/button/t9n"; +export { CardMessages } from "./components/card/assets/card/t9n"; +export { ChipMessages } from "./components/chip/assets/chip/t9n"; export { ColorValue, InternalColor } from "./components/color-picker/interfaces"; export { Format } from "./components/color-picker/utils"; +export { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; export { ComboboxChildElement, SelectionDisplay } from "./components/combobox/interfaces"; +export { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; +export { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; export { DateLocaleData } from "./components/date-picker/utils"; export { HoverRange } from "./utils/date"; export { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; export { ItemKeyboardEvent } from "./components/dropdown/interfaces"; +export { FilterMessages } from "./components/filter/assets/filter/t9n"; export { FlowItemLikeElement } from "./components/flow/interfaces"; +export { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; export { ColorStop, DataSeries } from "./components/graph/interfaces"; +export { HandleMessages } from "./components/handle/assets/handle/t9n"; export { HandleChange, HandleNudge } from "./components/handle/interfaces"; +export { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; export { InputPlacement } from "./components/input/interfaces"; +export { InputMessages } from "./components/input/assets/input/t9n"; +export { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; +export { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; +export { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; +export { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; +export { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; +export { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; export { TimeZoneMode } from "./components/input-time-zone/interfaces"; export { ListDragDetail } from "./components/list/interfaces"; export { ItemData } from "./components/list-item/interfaces"; +export { ListMessages } from "./components/list/assets/list/t9n"; export { SelectionAppearance } from "./components/list/resources"; +export { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; +export { MenuMessages } from "./components/menu/assets/menu/t9n"; +export { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; export { MenuItemCustomEvent } from "./components/menu-item/interfaces"; export { MeterLabelType } from "./components/meter/interfaces"; +export { ModalMessages } from "./components/modal/assets/modal/t9n"; +export { NoticeMessages } from "./components/notice/assets/notice/t9n"; +export { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; +export { PanelMessages } from "./components/panel/assets/panel/t9n"; export { ItemData as ItemData1, ListFocusId } from "./components/pick-list/shared-list-logic"; export { ICON_TYPES } from "./components/pick-list/resources"; +export { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; +export { PopoverMessages } from "./components/popover/assets/popover/t9n"; +export { RatingMessages } from "./components/rating/assets/rating/t9n"; +export { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; export { DisplayMode } from "./components/sheet/interfaces"; export { DisplayMode as DisplayMode1 } from "./components/shell-panel/interfaces"; +export { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; export { DragDetail } from "./utils/sortableComponent"; export { StepperItemChangeEventDetail, StepperItemEventDetail, StepperItemKeyEventDetail, StepperLayout } from "./components/stepper/interfaces"; +export { StepperMessages } from "./components/stepper/assets/stepper/t9n"; +export { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; export { TabID, TabLayout, TabPosition } from "./components/tabs/interfaces"; +export { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; export { TabChangeEventDetail, TabCloseEventDetail } from "./components/tab/interfaces"; +export { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; export { RowType, TableInteractionMode, TableLayout, TableRowFocusEvent } from "./components/table/interfaces"; +export { TableMessages } from "./components/table/assets/table/t9n"; +export { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; +export { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; +export { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; export { TileSelectType } from "./components/tile-select/interfaces"; export { TileSelectGroupLayout } from "./components/tile-select-group/interfaces"; +export { TipMessages } from "./components/tip/assets/tip/t9n"; +export { TipManagerMessages } from "./components/tip-manager/assets/tip-manager/t9n"; export { TreeItemSelectDetail } from "./components/tree-item/interfaces"; +export { ValueListMessages } from "./components/value-list/assets/value-list/t9n"; export { ListItemAndHandle } from "./components/value-list-item/interfaces"; export namespace Components { interface CalciteAccordion { @@ -3148,29 +3244,6 @@ export namespace Components { */ "widthScale": Scale; } - interface CalciteMonthPicker { - /** - * Focused date with indicator (will become selected date if user proceeds) - */ - "activeDate": Date; - "activeMonthIndex": number; - /** - * Specifies the latest allowed date (`"yyyy-mm-dd"`). - */ - "max": Date; - /** - * Specifies the earliest allowed date (`"yyyy-mm-dd"`). - */ - "min": Date; - /** - * Already selected date. - */ - "selectedMonthYear": Date; - } - interface CalciteMonthPickerItem { - "isActive": boolean; - "value": string; - } interface CalciteNavigation { /** * When `navigationAction` is `true`, specifies the label of the `calcite-action`. @@ -5379,38 +5452,6 @@ export namespace Components { */ "value": any; } - interface CalciteYearPicker { - /** - * When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. - */ - "disableYearsOutOfRange": boolean; - /** - * When `true`, disables the component - */ - "disabled": boolean; - /** - * Specifies the latest allowed year (`"yyyy"`). - */ - "max": number; - /** - * Specifies the earliest allowed year (`"yyyy"`). - */ - "min": number; - "nextYear": () => Promise; - /** - * Specifies the Unicode numeral system used by the component for localization. - */ - "numberingSystem": NumberingSystem; - "prevYear": () => Promise; - /** - * When `true`, activates the component's range mode to allow a start and end year. - */ - "range": boolean; - /** - * Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). - */ - "value": number | number[]; - } } export interface CalciteAccordionCustomEvent extends CustomEvent { detail: T; @@ -5572,14 +5613,6 @@ export interface CalciteModalCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteModalElement; } -export interface CalciteMonthPickerCustomEvent extends CustomEvent { - detail: T; - target: HTMLCalciteMonthPickerElement; -} -export interface CalciteMonthPickerItemCustomEvent extends CustomEvent { - detail: T; - target: HTMLCalciteMonthPickerItemElement; -} export interface CalciteNavigationCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteNavigationElement; @@ -5732,10 +5765,6 @@ export interface CalciteValueListItemCustomEvent extends CustomEvent { detail: T; target: HTMLCalciteValueListItemElement; } -export interface CalciteYearPickerCustomEvent extends CustomEvent { - detail: T; - target: HTMLCalciteYearPickerElement; -} declare global { interface HTMLCalciteAccordionElementEventMap { "calciteInternalAccordionChange": RequestedItem; @@ -6600,40 +6629,6 @@ declare global { prototype: HTMLCalciteModalElement; new (): HTMLCalciteModalElement; }; - interface HTMLCalciteMonthPickerElementEventMap { - "calciteMonthPickerChange": void; - } - interface HTMLCalciteMonthPickerElement extends Components.CalciteMonthPicker, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLCalciteMonthPickerElement, ev: CalciteMonthPickerCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLCalciteMonthPickerElement, ev: CalciteMonthPickerCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLCalciteMonthPickerElement: { - prototype: HTMLCalciteMonthPickerElement; - new (): HTMLCalciteMonthPickerElement; - }; - interface HTMLCalciteMonthPickerItemElementEventMap { - "calciteInternalMonthPickerItemSelect": string; - } - interface HTMLCalciteMonthPickerItemElement extends Components.CalciteMonthPickerItem, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLCalciteMonthPickerItemElement, ev: CalciteMonthPickerItemCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLCalciteMonthPickerItemElement, ev: CalciteMonthPickerItemCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLCalciteMonthPickerItemElement: { - prototype: HTMLCalciteMonthPickerItemElement; - new (): HTMLCalciteMonthPickerItemElement; - }; interface HTMLCalciteNavigationElementEventMap { "calciteNavigationActionSelect": void; } @@ -7446,23 +7441,6 @@ declare global { prototype: HTMLCalciteValueListItemElement; new (): HTMLCalciteValueListItemElement; }; - interface HTMLCalciteYearPickerElementEventMap { - "calciteYearPickerChange": void; - } - interface HTMLCalciteYearPickerElement extends Components.CalciteYearPicker, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLCalciteYearPickerElement, ev: CalciteYearPickerCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLCalciteYearPickerElement, ev: CalciteYearPickerCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; - } - var HTMLCalciteYearPickerElement: { - prototype: HTMLCalciteYearPickerElement; - new (): HTMLCalciteYearPickerElement; - }; interface HTMLElementTagNameMap { "calcite-accordion": HTMLCalciteAccordionElement; "calcite-accordion-item": HTMLCalciteAccordionItemElement; @@ -7519,8 +7497,6 @@ declare global { "calcite-menu-item": HTMLCalciteMenuItemElement; "calcite-meter": HTMLCalciteMeterElement; "calcite-modal": HTMLCalciteModalElement; - "calcite-month-picker": HTMLCalciteMonthPickerElement; - "calcite-month-picker-item": HTMLCalciteMonthPickerItemElement; "calcite-navigation": HTMLCalciteNavigationElement; "calcite-navigation-logo": HTMLCalciteNavigationLogoElement; "calcite-navigation-user": HTMLCalciteNavigationUserElement; @@ -7574,7 +7550,6 @@ declare global { "calcite-tree-item": HTMLCalciteTreeItemElement; "calcite-value-list": HTMLCalciteValueListElement; "calcite-value-list-item": HTMLCalciteValueListItemElement; - "calcite-year-picker": HTMLCalciteYearPickerElement; } } declare namespace LocalJSX { @@ -10842,37 +10817,6 @@ declare namespace LocalJSX { */ "widthScale"?: Scale; } - interface CalciteMonthPicker { - /** - * Focused date with indicator (will become selected date if user proceeds) - */ - "activeDate"?: Date; - "activeMonthIndex"?: number; - /** - * Specifies the latest allowed date (`"yyyy-mm-dd"`). - */ - "max"?: Date; - /** - * Specifies the earliest allowed date (`"yyyy-mm-dd"`). - */ - "min"?: Date; - /** - * Emits whenever the component is selected. - */ - "onCalciteMonthPickerChange"?: (event: CalciteMonthPickerCustomEvent) => void; - /** - * Already selected date. - */ - "selectedMonthYear"?: Date; - } - interface CalciteMonthPickerItem { - "isActive"?: boolean; - /** - * Emits whenever the component is selected. - */ - "onCalciteInternalMonthPickerItemSelect"?: (event: CalciteMonthPickerItemCustomEvent) => void; - "value"?: string; - } interface CalciteNavigation { /** * When `navigationAction` is `true`, specifies the label of the `calcite-action`. @@ -13156,40 +13100,6 @@ declare namespace LocalJSX { */ "value": any; } - interface CalciteYearPicker { - /** - * When `true`, disables year's before the earliest allowed year in end year and after the latest year in start year of range. - */ - "disableYearsOutOfRange"?: boolean; - /** - * When `true`, disables the component - */ - "disabled"?: boolean; - /** - * Specifies the latest allowed year (`"yyyy"`). - */ - "max"?: number; - /** - * Specifies the earliest allowed year (`"yyyy"`). - */ - "min"?: number; - /** - * Specifies the Unicode numeral system used by the component for localization. - */ - "numberingSystem"?: NumberingSystem; - /** - * Emits whenever the component is selected. - */ - "onCalciteYearPickerChange"?: (event: CalciteYearPickerCustomEvent) => void; - /** - * When `true`, activates the component's range mode to allow a start and end year. - */ - "range"?: boolean; - /** - * Specifies the selected year as a string (`"yyyy"`), or an array of strings for `range` values (`["yyyy", "yyyy"]`). - */ - "value"?: number | number[]; - } interface IntrinsicElements { "calcite-accordion": CalciteAccordion; "calcite-accordion-item": CalciteAccordionItem; @@ -13246,8 +13156,6 @@ declare namespace LocalJSX { "calcite-menu-item": CalciteMenuItem; "calcite-meter": CalciteMeter; "calcite-modal": CalciteModal; - "calcite-month-picker": CalciteMonthPicker; - "calcite-month-picker-item": CalciteMonthPickerItem; "calcite-navigation": CalciteNavigation; "calcite-navigation-logo": CalciteNavigationLogo; "calcite-navigation-user": CalciteNavigationUser; @@ -13301,7 +13209,6 @@ declare namespace LocalJSX { "calcite-tree-item": CalciteTreeItem; "calcite-value-list": CalciteValueList; "calcite-value-list-item": CalciteValueListItem; - "calcite-year-picker": CalciteYearPicker; } } export { LocalJSX as JSX }; @@ -13366,8 +13273,6 @@ declare module "@stencil/core" { "calcite-menu-item": LocalJSX.CalciteMenuItem & JSXBase.HTMLAttributes; "calcite-meter": LocalJSX.CalciteMeter & JSXBase.HTMLAttributes; "calcite-modal": LocalJSX.CalciteModal & JSXBase.HTMLAttributes; - "calcite-month-picker": LocalJSX.CalciteMonthPicker & JSXBase.HTMLAttributes; - "calcite-month-picker-item": LocalJSX.CalciteMonthPickerItem & JSXBase.HTMLAttributes; "calcite-navigation": LocalJSX.CalciteNavigation & JSXBase.HTMLAttributes; "calcite-navigation-logo": LocalJSX.CalciteNavigationLogo & JSXBase.HTMLAttributes; "calcite-navigation-user": LocalJSX.CalciteNavigationUser & JSXBase.HTMLAttributes; @@ -13436,7 +13341,6 @@ declare module "@stencil/core" { * @deprecated Use the `list` component instead. */ "calcite-value-list-item": LocalJSX.CalciteValueListItem & JSXBase.HTMLAttributes; - "calcite-year-picker": LocalJSX.CalciteYearPicker & JSXBase.HTMLAttributes; } } } diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index a80d57852ef..b2026475139 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -199,7 +199,7 @@ export class DatePickerMonth { case "End": event.preventDefault(); this.activeDate.setDate( - new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate() + new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate(), ); this.addDays(); break; @@ -257,7 +257,7 @@ export class DatePickerMonth { endCalendarPrevMonDays, endCalendarCurrMonDays, endCalendarNextMonDays, - "end" + "end", ); const nextMonthWeeks = this.getWeeks(nextMonthDays); @@ -323,7 +323,7 @@ export class DatePickerMonth { const nextDate = new Date(this.activeDate); nextDate.setMonth(this.activeDate.getMonth() + step); this.calciteInternalDatePickerActiveDateChange.emit( - dateFromRange(nextDate, this.min, this.max) + dateFromRange(nextDate, this.min, this.max), ); this.activeFocus = true; } @@ -337,7 +337,7 @@ export class DatePickerMonth { const nextDate = new Date(this.focusedDate); nextDate.setDate(this.focusedDate.getDate() + step); this.calciteInternalDatePickerActiveDateChange.emit( - dateFromRange(nextDate, this.min, this.max) + dateFromRange(nextDate, this.min, this.max), ); this.focusedDate = dateFromRange(nextDate, this.min, this.max); @@ -520,7 +520,7 @@ export class DatePickerMonth { selected={this.isSelected(date)} startOfRange={this.isStartOfRange(date)} value={date} - //focusing in ref is creating diff UX for keyboard compared to click where in click the focus only shifts after selection where in keyboard while navigating the focus is updated. + // focusing in ref is creating diff UX for keyboard compared to click where in click the focus only shifts after selection where in keyboard while navigating the focus is updated. // eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530) ref={(el: HTMLCalciteDatePickerDayElement) => { // when moving via keyboard, focus must be updated on active date @@ -573,7 +573,7 @@ export class DatePickerMonth { prevMonthDays: number[], currMonthDays: number[], nextMonthDays: number[], - position: "start" | "end" = "start" + position: "start" | "end" = "start", ): Day[] => { let month = this.activeDate.getMonth(); const year = this.activeDate.getFullYear(); diff --git a/packages/calcite-components/stencil.config.ts b/packages/calcite-components/stencil.config.ts index d1da77f29f3..22f2096c1f2 100644 --- a/packages/calcite-components/stencil.config.ts +++ b/packages/calcite-components/stencil.config.ts @@ -53,7 +53,6 @@ export const create: () => Config = () => ({ { components: ["calcite-list", "calcite-list-item", "calcite-list-item-group"] }, { components: ["calcite-loader"] }, { components: ["calcite-meter"] }, - { components: ["calcite-month-picker", "calcite-month-picker-item", "calcite-year-picker"] }, { components: ["calcite-modal"] }, { components: ["calcite-navigation", "calcite-navigation-user", "calcite-navigation-logo"] }, { components: ["calcite-menu", "calcite-menu-item"] }, From fe6f1cb73c981637b3f57b654de6bb3c9960c726 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Tue, 19 Mar 2024 18:29:40 -0500 Subject: [PATCH 051/155] unskip tests in date-picker --- .../components/date-picker/date-picker.e2e.ts | 92 +++++-------------- 1 file changed, 23 insertions(+), 69 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 753bfd43cd5..acb6cb34961 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -1,4 +1,3 @@ -/* eslint-disable jest/no-focused-tests */ import { E2EPage, newE2EPage } from "@stencil/core/testing"; import { html } from "../../../support/formatting"; import { defaults, focusable, hidden, renders, t9n } from "../../tests/commonTests"; @@ -52,49 +51,6 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); - it.skip("updates the calendar immediately as a new year is typed but doesn't change the year", async () => { - const page = await newE2EPage(); - await page.setContent(``); - const datePicker = await page.find("calcite-date-picker"); - await page.waitForTimeout(animationDurationInMs); - - async function getActiveMonthDate(): Promise { - return page.$eval("calcite-date-picker", (datePicker: HTMLCalciteDatePickerElement) => - datePicker.shadowRoot.querySelector("calcite-date-picker-month").activeDate.toISOString() - ); - } - - async function getActiveMonthHeaderInputValue(): Promise { - return page.$eval( - "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement) => - ( - datePicker.shadowRoot - .querySelector("calcite-date-picker-month-header") - .shadowRoot.querySelector(".year") as HTMLInputElement - ).value - ); - } - - const activeDateBefore = await getActiveMonthDate(); - - await page.keyboard.press("Tab"); - await page.keyboard.press("Tab"); - await page.keyboard.down("Meta"); - await page.keyboard.press("a"); - expect(await getActiveMonthHeaderInputValue()).toBe("2015"); - await page.keyboard.press("Backspace"); - await page.keyboard.up("Meta"); - await page.keyboard.type("2016"); - expect(await getActiveMonthHeaderInputValue()).toBe("2016"); - await page.waitForChanges(); - - const activeDateAfter = await getActiveMonthDate(); - - expect(activeDateBefore).not.toEqual(activeDateAfter); - expect(await datePicker.getProperty("value")).toBe("2015-02-28"); - }); - it("fires a calciteDatePickerChange event when day is selected", async () => { const page = await newE2EPage(); await page.setContent(""); @@ -198,7 +154,7 @@ describe("calcite-date-picker", () => { } }, id, - method + method, ); await page.waitForChanges(); } @@ -217,7 +173,7 @@ describe("calcite-date-picker", () => { day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); } }, - method + method, ); await page.waitForChanges(); } @@ -236,7 +192,7 @@ describe("calcite-date-picker", () => { day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); } }, - method + method, ); await page.waitForChanges(); } @@ -251,27 +207,25 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); - it.skip("correctly changes date on next/prev", async () => { + it("correctly changes date on next/prev", async () => { const page = await newE2EPage(); await page.setContent(""); - const getMonth = () => { - return document - .querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month-header") - .shadowRoot.querySelector(".month").textContent; - }; - expect(await page.evaluate(getMonth)).toEqualText("November"); - // tab to prev arrow - await page.keyboard.press("Tab"); - await page.keyboard.press("Enter"); - await page.waitForChanges(); - expect(await page.evaluate(getMonth)).toEqualText("October"); - // tab to next arrow - await page.keyboard.press("Tab"); - await page.keyboard.press("Tab"); - await page.keyboard.press("Enter"); - await page.waitForChanges(); - expect(await page.evaluate(getMonth)).toEqualText("November"); + + const datePickerContainer = await page.find("calcite-date-picker >>> .container"); + const datePickerMonth = await datePickerContainer.find("calcite-date-picker-month >>> .month-header"); + const datePickerMonthHeader = await datePickerMonth.find("calcite-date-picker-month-header >>> .header "); + const [prevMonth, nextMonth] = await datePickerMonthHeader.findAll("a"); + const [monthSelect, yearSelect] = await datePickerMonthHeader.findAll("calcite-select"); + + await prevMonth.click(); + await nextMonth.click(); + await nextMonth.click(); + await nextMonth.click(); + + const currentMonth = await monthSelect.getProperty("value"); + const currentYear = await yearSelect.getProperty("value"); + expect(currentMonth).toBe("January"); + expect(currentYear).toBe("2001"); }); it("fires calciteDatePickerRangeChange event on user change", async () => { @@ -323,7 +277,7 @@ describe("calcite-date-picker", () => { document .querySelector("calcite-date-picker") .shadowRoot.querySelector("calcite-date-picker-month") - .shadowRoot.querySelector(".week-header").textContent + .shadowRoot.querySelector(".week-header").textContent, ); expect(text).toEqual("po"); @@ -334,7 +288,7 @@ describe("calcite-date-picker", () => { const page = await newE2EPage(); await page.emulateTimezone("America/Los_Angeles"); await page.setContent( - html`` + html``, ); const element = await page.find("calcite-date-picker"); @@ -343,7 +297,7 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); const minDateString = "Mon Nov 15 2021 00:00:00 GMT-0800 (Pacific Standard Time)"; const minDateAsTime = await page.$eval("calcite-date-picker", (picker: HTMLCalciteDatePickerElement) => - picker.minAsDate.getTime() + picker.minAsDate.getTime(), ); expect(minDateAsTime).toEqual(new Date(minDateString).getTime()); }); From 60c2c2df781fe16099dffeeaff12ccd88429b988 Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 20 Mar 2024 12:01:38 -0500 Subject: [PATCH 052/155] fix tests --- .../date-picker-month-header.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index c04779ced52..021355d61b0 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -206,14 +206,7 @@ export class DatePickerMonthHeader { {this.yearList?.map((year: number) => { const yearString = year.toString(); return ( - + {numberStringFormatter?.localize(yearString)} {this.localeData?.year?.suffix} @@ -299,6 +292,7 @@ export class DatePickerMonthHeader { * Update active month on clicks of left/right arrows */ private handleArrowClick = (event: MouseEvent | KeyboardEvent, date: Date): void => { + console.log("handleArrowClick", date); event.preventDefault(); this.calciteInternalDatePickerMonthHeaderSelect.emit(date); }; From a9bc158361a0fddde539c2f3d4ab6cbad67df98a Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Wed, 20 Mar 2024 17:10:23 -0500 Subject: [PATCH 053/155] add more tests and update --- .../date-picker-month-header.e2e.ts | 4 +- .../date-picker-month-header.tsx | 1 - .../input-date-picker.e2e.ts | 128 +++++++++--------- 3 files changed, 69 insertions(+), 64 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts index b2e9ad5245a..eb73164a539 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts @@ -47,7 +47,7 @@ describe("calcite-date-picker-month-header", () => { await page.evaluate((localeData) => { const dateMonthHeader = document.createElement( - "calcite-date-picker-month-header" + "calcite-date-picker-month-header", ) as HTMLCalciteDatePickerMonthHeaderElement; const now = new Date(); dateMonthHeader.activeDate = now; @@ -76,7 +76,7 @@ describe("calcite-date-picker-month-header", () => { await page.evaluate((localeData) => { const dateMonthHeader = document.createElement( - "calcite-date-picker-month-header" + "calcite-date-picker-month-header", ) as HTMLCalciteDatePickerMonthHeaderElement; const now = new Date(); dateMonthHeader.activeDate = now; diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 021355d61b0..11a7ef3d442 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -292,7 +292,6 @@ export class DatePickerMonthHeader { * Update active month on clicks of left/right arrows */ private handleArrowClick = (event: MouseEvent | KeyboardEvent, date: Date): void => { - console.log("handleArrowClick", date); event.preventDefault(); this.calciteInternalDatePickerMonthHeaderSelect.emit(date); }; diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 6db0d79ecf9..3bb4bfc6926 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1,3 +1,4 @@ +/* eslint-disable jest/no-focused-tests */ import { E2EElement, E2EPage, newE2EPage } from "@stencil/core/testing"; import { accessible, @@ -13,7 +14,6 @@ import { } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; import { CSS } from "./resources"; -import { CSS as MONTH_HEADER_CSS } from "../date-picker-month-header/resources"; import { getFocusedElementProp, skipAnimations } from "../../tests/utils"; const animationDurationInMs = 200; @@ -75,33 +75,23 @@ describe("calcite-input-date-picker", () => { it.skip("supports t9n", () => t9n("calcite-input-date-picker")); async function navigateMonth(page: E2EPage, direction: "previous" | "next", range = false): Promise { - const linkIndex = direction === "previous" ? 0 : 1; - - await (!range - ? page.evaluate( - async (MONTH_HEADER_CSS, linkIndex: number): Promise => - document - .querySelector("calcite-input-date-picker") - .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month") - .shadowRoot.querySelector("calcite-date-picker-month-header") - .shadowRoot.querySelectorAll(`.${MONTH_HEADER_CSS.chevron}`) - [linkIndex].click(), - MONTH_HEADER_CSS, - linkIndex, - ) - : page.evaluate( - async (MONTH_HEADER_CSS, linkIndex: number): Promise => - document - .querySelector("calcite-input-date-picker") - .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month") - .shadowRoot.querySelectorAll("calcite-date-picker-month-header") - [linkIndex].shadowRoot.querySelector(`.${MONTH_HEADER_CSS.chevron}`) - .click(), - MONTH_HEADER_CSS, - linkIndex, - )); + const datePicker = await page.find("calcite-input-date-picker >>> .menu-container"); + const datePickerContainer = await datePicker.find("calcite-date-picker >>> .container"); + const datePickerMonth = await datePickerContainer.find("calcite-date-picker-month >>> .month-header"); + const [datePickerMonthHeaderStart, datePickerMonthHeaderEnd] = await datePickerMonth.findAll( + "calcite-date-picker-month-header >>> .header ", + ); + + let prevMonth: E2EElement; + let nextMonth: E2EElement; + if (range) { + prevMonth = await datePickerMonthHeaderStart.find("a"); + nextMonth = await datePickerMonthHeaderEnd.find("a"); + } else { + [prevMonth, nextMonth] = await datePickerMonthHeaderStart.findAll("a"); + } + + await (direction === "previous" ? prevMonth.click() : nextMonth.click()); await page.waitForChanges(); } @@ -110,11 +100,10 @@ describe("calcite-input-date-picker", () => { await page.evaluate( async (dayIndex: number) => { - const datePickerMonthEl = "calcite-date-picker-month"; document .querySelector("calcite-input-date-picker") .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector(datePickerMonthEl) + .shadowRoot.querySelector("calcite-date-picker-month") .shadowRoot.querySelectorAll("calcite-date-picker-day[current-month]") [dayIndex].click(); }, @@ -602,7 +591,7 @@ describe("calcite-input-date-picker", () => { expect(await getDateInputValue(page)).toBe("١‏‏‏‏‏‏‏/٢‏‏‏‏‏/١٢٣٤"); }); - it.skip("syncs lang changes to internal date-picker and input", async () => { + it("syncs lang changes to internal date-picker and input", async () => { // note that lang values should be available as bundles for both input-date-picker and date-picker const lang = "en"; const newLang = "es"; @@ -1121,7 +1110,12 @@ describe("calcite-input-date-picker", () => { }); describe("date-picker visibility in range", () => { - it("should keep date-picker open when user selects startDate in range calendar", async () => { + async function isCalendarVisible(page: E2EPage): Promise { + const calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + return await calendar.isVisible(); + } + + it("should keep date-picker open when user selects dates in range calendar", async () => { const page = await newE2EPage(); await page.setContent(html``); await skipAnimations(page); @@ -1129,24 +1123,19 @@ describe("calcite-input-date-picker", () => { const inputDatePicker = await page.find("calcite-input-date-picker"); const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); - let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + expect(await isCalendarVisible(page)).toBe(false); await startDatePicker.click(); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await selectDayInMonth(page, 1, true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await selectDayInMonth(page, 32, true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); - + expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); }); @@ -1158,24 +1147,43 @@ describe("calcite-input-date-picker", () => { const inputDatePicker = await page.find("calcite-input-date-picker"); const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); - let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + expect(await isCalendarVisible(page)).toBe(false); await startDatePicker.click(); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await selectDayInMonth(page, 35, true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await selectDayInMonth(page, 52, true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + expect(await isCalendarVisible(page)).toBe(false); + expect(await inputDatePicker.getProperty("value")).not.toBeNull(); + }); + + it("should keep date-picker open when user select startDate from start calendar", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const inputDatePicker = await page.find("calcite-input-date-picker"); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + expect(await isCalendarVisible(page)).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + + await selectDayInMonth(page, 5, true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + await selectDayInMonth(page, 22, true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); }); @@ -1186,8 +1194,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); - let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + expect(await isCalendarVisible(page)).toBe(false); await startDatePicker.click(); await page.waitForChanges(); @@ -1200,28 +1207,27 @@ describe("calcite-input-date-picker", () => { await startDatePicker.click(); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await navigateMonth(page, "previous", true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); await selectDayInMonth(page, 1, true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await navigateMonth(page, "next", true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); await selectDayInMonth(page, 32, true); await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + expect(await isCalendarVisible(page)).toBe(false); }); }); From a0151e5bb9af3ac8f471d8a352da5300c371196e Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 21 Mar 2024 16:29:17 -0500 Subject: [PATCH 054/155] allow users to specify month abbreviations --- .../calcite-components/src/components.d.ts | 12 ++++ .../date-picker-month-header.scss | 18 ++++++ .../date-picker-month/date-picker-month.scss | 58 +++++++++++++++++-- .../date-picker-month/date-picker-month.tsx | 4 ++ .../components/date-picker/date-picker.scss | 2 +- .../components/date-picker/date-picker.tsx | 6 ++ .../input-date-picker/input-date-picker.tsx | 17 +++--- 7 files changed, 104 insertions(+), 13 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index f012d347f1d..1247b7f1d8d 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1333,6 +1333,10 @@ export namespace Components { * Specifies the earliest allowed date as a full date object (`new Date("yyyy-mm-dd")`). */ "minAsDate": Date; + /** + * Specifies if the month abbreviations are used by the component. + */ + "monthAbbreviations": boolean; /** * Specifies the Unicode numeral system used by the component for localization. This property cannot be dynamically changed. */ @@ -1461,6 +1465,7 @@ export namespace Components { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min": Date; + "monthAbbreviations": boolean; "position": "start" | "end"; "range": boolean; /** @@ -2182,6 +2187,7 @@ export namespace Components { * Specifies the earliest allowed date as a full date object. */ "minAsDate": Date; + "monthAbbreviations": boolean; /** * Specifies the name of the component. Required to pass the component's `value` on form submission. */ @@ -8770,6 +8776,10 @@ declare namespace LocalJSX { * Specifies the earliest allowed date as a full date object (`new Date("yyyy-mm-dd")`). */ "minAsDate"?: Date; + /** + * Specifies if the month abbreviations are used by the component. + */ + "monthAbbreviations"?: boolean; /** * Specifies the Unicode numeral system used by the component for localization. This property cannot be dynamically changed. */ @@ -8906,6 +8916,7 @@ declare namespace LocalJSX { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min"?: Date; + "monthAbbreviations"?: boolean; /** * Active date for the user keyboard access. */ @@ -9667,6 +9678,7 @@ declare namespace LocalJSX { * Specifies the earliest allowed date as a full date object. */ "minAsDate"?: Date; + "monthAbbreviations"?: boolean; /** * Specifies the name of the component. Required to pass the component's `value` on form submission. */ diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss index ea1be3a5198..def79ae465a 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss @@ -4,6 +4,24 @@ --calcite-select-internal-icon-border-inline-end-width: 0px; } +:host([scale="s"]) { + inline-size: 234px; + min-inline-size: 216px; + max-inline-size: 380px; +} + +:host([scale="m"]) { + inline-size: 304px; + min-inline-size: 272px; + max-inline-size: 480px; +} + +:host([scale="l"]) { + inline-size: 370px; + min-inline-size: 320px; + max-inline-size: 600px; +} + .header { @apply flex justify-between; @apply py-0 px-1; diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss index 6733c132b61..0b9e63de5e1 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.scss @@ -1,7 +1,47 @@ @include base-component(); .calendar { - @apply mb-1 flex; + @apply mb-1 flex w-full; +} + +:host([range]) .calendar { + gap: 12px; +} + +:host([scale="s"]) .calendar { + inline-size: 234px; + min-inline-size: 216px; + max-inline-size: 380px; +} + +:host([scale="m"]) .calendar { + inline-size: 304px; + min-inline-size: 272px; + max-inline-size: 480px; +} + +:host([scale="l"]) .calendar { + inline-size: 370px; + min-inline-size: 320px; + max-inline-size: 600px; +} + +:host([scale="s"][range]) .calendar { + inline-size: 480px; + min-inline-size: 432px; + max-inline-size: 772px; +} + +:host([scale="m"][range]) .calendar { + inline-size: 620px; + min-inline-size: 544px; + max-inline-size: 972px; +} + +:host([scale="l"][range]) .calendar { + inline-size: 752px; + min-inline-size: 640px; + max-inline-size: 1212px; } .week-headers { @@ -16,7 +56,11 @@ .week-header { @apply text-color-3 text-center - font-bold; + font-bold + flex + px-0 + text-n2h + justify-center; inline-size: calc(100% / 7); } @@ -32,15 +76,15 @@ } :host([scale="s"]) .week-header { - @apply text-n2h px-0 pt-2 pb-3; + @apply pt-2 pb-3; } :host([scale="m"]) .week-header { - @apply text-n2h px-0 pt-3 pb-4; + @apply pt-3 pb-4; } :host([scale="l"]) .week-header { - @apply text-n1h px-0 pt-4 pb-5; + @apply text-n1h pt-4 pb-5; } .week-days { @@ -56,3 +100,7 @@ .month-header { @apply flex w-full justify-between; } + +.month { + @apply flex w-full justify-between flex-col; +} diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index b2026475139..edec15b9a34 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -104,6 +104,8 @@ export class DatePickerMonth { // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module @Prop({ mutable: true }) messages: DatePickerMessages; + @Prop() monthAbbreviations: boolean; + /** * Specifies the number at which section headings should start. */ @@ -271,6 +273,7 @@ export class DatePickerMonth { max={this.max} messages={this.messages} min={this.min} + monthAbbreviations={this.monthAbbreviations} onCalciteInternalDatePickerMonthHeaderSelect={this.monthHeaderSelectChange} position={this.range ? "start" : null} scale={this.scale} @@ -284,6 +287,7 @@ export class DatePickerMonth { max={this.max} messages={this.messages} min={this.min} + monthAbbreviations={this.monthAbbreviations} onCalciteInternalDatePickerMonthHeaderSelect={this.monthHeaderSelectChange} position={"end"} scale={this.scale} diff --git a/packages/calcite-components/src/components/date-picker/date-picker.scss b/packages/calcite-components/src/components/date-picker/date-picker.scss index ccbc6341230..650371da077 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.scss +++ b/packages/calcite-components/src/components/date-picker/date-picker.scss @@ -52,7 +52,7 @@ .container { display: flex; - flex-direction: row; + inline-size: 100%; } @include base-component(); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 466d521dd45..21bb7d15a65 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -165,6 +165,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } } + /** + * Specifies if the month abbreviations are used by the component. + */ + @Prop() monthAbbreviations: boolean = false; + /** * Specifies the Unicode numeral system used by the component for localization. This property cannot be dynamically changed. * @@ -523,6 +528,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom max={maxDate} messages={this.messages} min={minDate} + monthAbbreviations={this.monthAbbreviations} onCalciteInternalDatePickerActiveDateChange={this.monthActiveDateChange} onCalciteInternalDatePickerHover={this.monthHoverChange} onCalciteInternalDatePickerMonthChange={this.monthHeaderSelectChange} diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 22f2856afe6..109c2a8ed70 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -255,6 +255,8 @@ export class InputDatePicker } } + @Prop() monthAbbreviations: boolean = false; + /** When `true`, displays the `calcite-date-picker` component. */ @Prop({ mutable: true, reflect: true }) open = false; @@ -431,7 +433,7 @@ export class InputDatePicker flipPlacements: filteredFlipPlacements, type: "menu", }, - delayed + delayed, ); } @@ -602,6 +604,7 @@ export class InputDatePicker messageOverrides={this.messageOverrides} min={this.min} minAsDate={this.minAsDate} + monthAbbreviations={this.monthAbbreviations} numberingSystem={numberingSystem} onCalciteDatePickerChange={this.handleDateChange} onCalciteDatePickerRangeChange={this.handleDateRangeChange} @@ -1030,13 +1033,13 @@ export class InputDatePicker ? (Array.isArray(this.valueAsDate) && this.valueAsDate[0]) || undefined : this.valueAsDate) as Date, this.minAsDate, - this.maxAsDate + this.maxAsDate, ); const endDate = this.range ? dateFromRange( (Array.isArray(this.valueAsDate) && this.valueAsDate[1]) || undefined, this.minAsDate, - this.maxAsDate + this.maxAsDate, ) : null; @@ -1133,7 +1136,7 @@ export class InputDatePicker private warnAboutInvalidValue(value: string): void { console.warn( - `The specified value "${value}" does not conform to the required format, "YYYY-MM-DD".` + `The specified value "${value}" does not conform to the required format, "YYYY-MM-DD".`, ); } @@ -1147,8 +1150,8 @@ export class InputDatePicker this.commonDateSeparators?.includes(char) ? this.localeData?.separator : numberKeys?.includes(char) - ? numberStringFormatter?.numberFormatter?.format(Number(char)) - : char + ? numberStringFormatter?.numberFormatter?.format(Number(char)) + : char, ) .join("") : ""; @@ -1158,7 +1161,7 @@ export class InputDatePicker ? value .split("") .map((char: string) => - numberKeys.includes(char) ? numberStringFormatter.delocalize(char) : char + numberKeys.includes(char) ? numberStringFormatter.delocalize(char) : char, ) .join("") : ""; From 033daa9b44762fc7b68faa189bcfb461014e8b4a Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Thu, 21 Mar 2024 18:47:37 -0500 Subject: [PATCH 055/155] add hover effect for keyboard navigation of dates --- .../src/components/date-picker-month/date-picker-month.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index edec15b9a34..dd3e0c9fd86 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -346,6 +346,8 @@ export class DatePickerMonth { this.focusedDate = dateFromRange(nextDate, this.min, this.max); this.activeFocus = true; + // adds hover effect on keyboard navigation + this.calciteInternalDatePickerHover.emit(nextDate); } /** From 0d93b2f53ff49b7e94acea8d6830c810b971008f Mon Sep 17 00:00:00 2001 From: anveshmekala Date: Fri, 22 Mar 2024 15:25:20 -0500 Subject: [PATCH 056/155] update focus order --- .../date-picker-day/date-picker-day.tsx | 2 +- .../date-picker-month/date-picker-month.tsx | 6 +++--- .../input-date-picker/input-date-picker.tsx | 16 +++++++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx b/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx index a6001acc7a9..76a075e4152 100644 --- a/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx +++ b/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx @@ -142,7 +142,7 @@ export class DatePickerDay implements InteractiveComponent { componentWillLoad(): void { this.parentDatePickerEl = closestElementCrossShadowBoundary( this.el, - "calcite-date-picker" + "calcite-date-picker", ) as HTMLCalciteDatePickerElement; } diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index dd3e0c9fd86..a9112d05b38 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -51,14 +51,14 @@ export class DatePickerMonth { /** Already selected date.*/ @Prop() selectedDate: Date; - /** The currently active Date.*/ - @Prop() activeDate: Date = new Date(); - @Watch("selectedDate") updateFocusedDate(newActiveDate: Date): void { this.focusedDate = newActiveDate; } + /** The currently active Date.*/ + @Prop() activeDate: Date = new Date(); + @Watch("activeDate") updateFocusedDateWithActive(newActiveDate: Date): void { if (!this.selectedDate) { diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 109c2a8ed70..e822a9f1429 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -344,13 +344,15 @@ export class InputDatePicker calciteDaySelectHandler(): void { if ( this.shouldFocusRangeStart() || - this.shouldFocusRangeEnd() || + // this.shouldFocusRangeEnd() || this.rangeStartValueChangedByUser ) { return; } this.open = false; + const focusedInput = this.focusedInput === "start" ? this.startInput : this.endInput; + focusedInput.setFocus(); } private calciteInternalInputInputHandler = (event: CustomEvent): void => { @@ -1020,8 +1022,16 @@ export class InputDatePicker //avoid closing of date-picker while editing this.rangeStartValueChangedByUser = !restore && this.focusedInput === "start"; - const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; - focusedInput.setFocus(); + this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; + + if (restore) { + //restore focus on to the input that was focused before opening the date-picker on Escape key or form submission. + const focusedInput = this.focusedInput === "start" ? this.startInput : this.endInput; + focusedInput.setFocus(); + } + + // const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; + // focusedInput.setFocus(); //avoids delay in updating focusedInput value while the `blur` handler in `date-picker` causing update in activeDate's. // this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; From e51f3f2562f1101a03ddbbc665ac3cd28fea5c3f Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Tue, 26 Mar 2024 11:55:25 -0500 Subject: [PATCH 057/155] fix navigation chevron positions --- .../date-picker-month-header.tsx | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 11a7ef3d442..1b4df8410cf 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -136,12 +136,8 @@ export class DatePickerMonthHeader { return ( -
- {this.renderMonthPicker(months, activeMonth)} - {this.renderYearPicker()} -
-
- {this.position !== "end" && ( + {this.position !== "end" && ( + + )} +
+ {this.renderMonthPicker(months, activeMonth)} + {this.renderYearPicker()} +
+ {this.position !== "start" && ( +
- )} -
+
+ )}
); } From 776afa9f331d5585bb5c54b826f420bdf34d3b76 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Tue, 26 Mar 2024 14:36:48 -0500 Subject: [PATCH 058/155] add more tests --- .../input-date-picker.e2e.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 3bb4bfc6926..bb4b205a070 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1313,4 +1313,31 @@ describe("calcite-input-date-picker", () => { calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); }); + + it.only("should set the endDate to empty and open the calendar when startDate is updated to date beyond initial endDate", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); + + const inputDatePickerEl = await page.find("calcite-input-date-picker"); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + + inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-25"]); + let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + await selectDayInMonth(page, 60, true); + await page.waitForChanges(); + calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + const value = await inputDatePickerEl.getProperty("value"); + expect(value[1]).not.toEqual("2024-06-25"); + }); }); From 704db7f2edddf17bf1fe4c1983ad2ab81cf5594b Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Wed, 27 Mar 2024 15:38:15 -0500 Subject: [PATCH 059/155] fix start date selection beyond endDate --- .../src/components/date-picker/date-picker.tsx | 5 ++++- .../components/input-date-picker/input-date-picker.e2e.ts | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 21bb7d15a65..d37461a30a3 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -568,7 +568,10 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.userChangeRangeValue = true; this.value = [dateToISO(startDate), dateToISO(date)]; this.valueAsDate = [startDate, date]; - this.calciteDatePickerRangeChange.emit(); + // avoid emitting change event when user select stat date beyond end date + if (!!date) { + this.calciteDatePickerRangeChange.emit(); + } } private getStartDate(): Date { diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index bb4b205a070..9d9d2c970ba 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1,4 +1,3 @@ -/* eslint-disable jest/no-focused-tests */ import { E2EElement, E2EPage, newE2EPage } from "@stencil/core/testing"; import { accessible, @@ -1314,7 +1313,7 @@ describe("calcite-input-date-picker", () => { expect(await calendar.isVisible()).toBe(true); }); - it.only("should set the endDate to empty and open the calendar when startDate is updated to date beyond initial endDate", async () => { + it("should set the endDate to empty and open the calendar when startDate is updated to date beyond initial endDate", async () => { const page = await newE2EPage(); await page.setContent(html``); await skipAnimations(page); @@ -1323,7 +1322,7 @@ describe("calcite-input-date-picker", () => { const inputDatePickerEl = await page.find("calcite-input-date-picker"); const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); - inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-25"]); + inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-20"]); let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(false); @@ -1338,6 +1337,6 @@ describe("calcite-input-date-picker", () => { expect(await calendar.isVisible()).toBe(true); const value = await inputDatePickerEl.getProperty("value"); - expect(value[1]).not.toEqual("2024-06-25"); + expect(value).toEqual(["2024-06-29", ""]); }); }); From 8718c80cab0163a792d46c7501c300d5f76e4801 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Wed, 27 Mar 2024 23:32:19 -0500 Subject: [PATCH 060/155] update selectDayInMonth test util method --- .../input-date-picker.e2e.ts | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 9d9d2c970ba..2f1a39d2e14 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -94,21 +94,15 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); } - async function selectDayInMonth(page: E2EPage, day: number, range = false): Promise { + async function selectDayInMonth(page: E2EPage, day: number): Promise { const dayIndex = day - 1; - await page.evaluate( - async (dayIndex: number) => { - document - .querySelector("calcite-input-date-picker") - .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month") - .shadowRoot.querySelectorAll("calcite-date-picker-day[current-month]") - [dayIndex].click(); - }, - dayIndex, - range, - ); + const datePicker = await page.find("calcite-input-date-picker >>> .menu-container"); + const datePickerContainer = await datePicker.find("calcite-date-picker >>> .container"); + const datePickerMonth = await datePickerContainer.find("calcite-date-picker-month >>> .calendar"); + const days = await datePickerMonth.findAll("calcite-date-picker-day[current-month]"); + + await days[dayIndex].click(); await page.waitForChanges(); } @@ -1011,14 +1005,14 @@ describe("calcite-input-date-picker", () => { expect(await calendar.isVisible()).toBe(true); await navigateMonth(page, "previous"); - await selectDayInMonth(page, 1, true); + await selectDayInMonth(page, 1); expect(await calendar.isVisible()).toBe(true); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); await navigateMonth(page, "previous"); - await selectDayInMonth(page, 31, true); + await selectDayInMonth(page, 31); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(false); @@ -1128,11 +1122,11 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 1, true); + await selectDayInMonth(page, 1); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 32, true); + await selectDayInMonth(page, 32); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); @@ -1152,11 +1146,11 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 35, true); + await selectDayInMonth(page, 35); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 52, true); + await selectDayInMonth(page, 52); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); @@ -1176,11 +1170,11 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 5, true); + await selectDayInMonth(page, 5); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 22, true); + await selectDayInMonth(page, 22); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); @@ -1198,10 +1192,10 @@ describe("calcite-input-date-picker", () => { await startDatePicker.click(); await page.waitForChanges(); - await selectDayInMonth(page, 1, true); + await selectDayInMonth(page, 1); await page.waitForChanges(); - await selectDayInMonth(page, 32, true); + await selectDayInMonth(page, 32); await page.waitForChanges(); await startDatePicker.click(); @@ -1216,7 +1210,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 1, true); + await selectDayInMonth(page, 1); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); @@ -1224,7 +1218,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 32, true); + await selectDayInMonth(page, 32); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); }); @@ -1268,7 +1262,7 @@ describe("calcite-input-date-picker", () => { calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); - await selectDayInMonth(page, 40, true); + await selectDayInMonth(page, 40); await page.waitForChanges(); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(false); @@ -1331,7 +1325,7 @@ describe("calcite-input-date-picker", () => { calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); - await selectDayInMonth(page, 60, true); + await selectDayInMonth(page, 60); await page.waitForChanges(); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); From 3ab9b12999fbaaa4ccdb79aaaebbe2a21ebfae35 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Thu, 28 Mar 2024 16:57:08 -0500 Subject: [PATCH 061/155] fix updating dates from previous and next calendars using keyboard --- .../date-picker-month/date-picker-month.tsx | 26 ++- .../components/date-picker/date-picker.tsx | 18 +- .../input-date-picker.e2e.ts | 204 ++++++++++-------- packages/calcite-components/src/utils/date.ts | 15 ++ 4 files changed, 161 insertions(+), 102 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index a9112d05b38..e5bc197af0f 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -11,7 +11,14 @@ import { Watch, State, } from "@stencil/core"; -import { dateFromRange, HoverRange, inRange, nextMonth, sameDate } from "../../utils/date"; +import { + dateFromRange, + hasSameMonthAndYear, + HoverRange, + inRange, + nextMonth, + sameDate, +} from "../../utils/date"; import { DateLocaleData } from "../date-picker/utils"; import { Scale } from "../interfaces"; import { DatePickerMessages } from "../date-picker/assets/date-picker/t9n"; @@ -650,6 +657,23 @@ export class DatePickerMonth { monthHeaderSelectChange = (event: CustomEvent): void => { const date = new Date(event.detail); const target = event.target as HTMLCalciteDatePickerMonthHeaderElement; + this.updateFocusableDate(date); this.calciteInternalDatePickerMonthChange.emit({ date, position: target.position }); }; + + // updates focusable date on monthHeaderSelectChange + private updateFocusableDate(date: Date): void { + if (!this.selectedDate || !this.range) { + this.focusedDate = date; + } else if (this.selectedDate && this.range) { + if (!hasSameMonthAndYear(this.activeDate, date)) { + if ( + !hasSameMonthAndYear(date, this.activeDate) && + !hasSameMonthAndYear(date, nextMonth(this.activeDate)) + ) { + this.focusedDate = date; + } + } + } + } } diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index d37461a30a3..1c48e9deff8 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -18,6 +18,7 @@ import { dateFromRange, dateToISO, getDaysDiff, + hasSameMonthAndYear, HoverRange, inRange, nextMonth, @@ -306,7 +307,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom const startCalendarActiveDate = this.range ? this.activeRange === "end" && this.activeEndDate && - !this.hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) + !hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) ? prevMonth(this.activeEndDate) : this.activeStartDate || prevMonth(this.activeEndDate) : activeDate; @@ -701,19 +702,4 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } } } - - private hasSameMonthAndYear(startDate: Date, endDate: Date): boolean { - // if (!Array.isArray(this.valueAsDate) || !this.valueAsDate[1]) { - // return false; - // } - if (!startDate || !endDate) { - return false; - } - const startYearMonth = startDate.getMonth(); - const startYearYear = startDate.getFullYear(); - - const endYearMonth = endDate.getMonth(); - const endYearYear = endDate.getFullYear(); - return endYearYear === startYearYear && startYearMonth === endYearMonth; - } } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 2f1a39d2e14..11cf455a86d 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1222,115 +1222,149 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); }); - }); - it("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - await skipAnimations(page); - await page.waitForChanges(); + it("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); - const inputDatePickerEl = await page.find("calcite-input-date-picker"); - const [startDatePicker, endDatePicker] = await page.findAll("calcite-input-date-picker >>> calcite-input-text"); + const inputDatePickerEl = await page.find("calcite-input-date-picker"); + const [startDatePicker, endDatePicker] = await page.findAll("calcite-input-date-picker >>> calcite-input-text"); + inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-25"]); + expect(await isCalendarVisible(page)).toBe(false); - inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-25"]); - let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + await startDatePicker.click(); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await startDatePicker.click(); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await endDatePicker.click(); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await endDatePicker.click(); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await selectDayInMonth(page, 40); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(false); - await selectDayInMonth(page, 40); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + const value = await inputDatePickerEl.getProperty("value"); + expect(value[1]).not.toEqual("2024-06-25"); + }); - const value = await inputDatePickerEl.getProperty("value"); - expect(value[1]).not.toEqual("2024-06-25"); - }); + it("should be able to navigate months when valueAsDate is parsed", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); - it("should be able to navigate months when valueAsDate is parsed", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - await skipAnimations(page); - await page.waitForChanges(); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); - const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + await page.$eval("calcite-input-date-picker", (element: any) => { + element.valueAsDate = [new Date("2024-05-25"), new Date("2024-06-25")]; + }); - await page.$eval("calcite-input-date-picker", (element: any) => { - element.valueAsDate = [new Date("2024-05-25"), new Date("2024-06-25")]; + expect(await isCalendarVisible(page)).toBe(false); + + await startDatePicker.click(); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + + await navigateMonth(page, "previous", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + + await navigateMonth(page, "next", true); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); }); - let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + it("should set the endDate to empty and open the calendar when startDate is updated to date beyond initial endDate", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); - await startDatePicker.click(); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + const inputDatePickerEl = await page.find("calcite-input-date-picker"); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-20"]); + expect(await isCalendarVisible(page)).toBe(false); - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await startDatePicker.click(); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await selectDayInMonth(page, 60); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await navigateMonth(page, "next", true); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); - }); + const value = await inputDatePickerEl.getProperty("value"); + expect(value).toEqual(["2024-06-29", ""]); + }); - it("should set the endDate to empty and open the calendar when startDate is updated to date beyond initial endDate", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - await skipAnimations(page); - await page.waitForChanges(); + it("should be able to update dates using keyboard", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + await page.waitForChanges(); - const inputDatePickerEl = await page.find("calcite-input-date-picker"); - const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); + const inputDatePickerEl = await page.find("calcite-input-date-picker"); + const startDatePicker = await page.find("calcite-input-date-picker >>> calcite-input-text"); - inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-20"]); - let calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(false); + inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-20"]); + expect(await isCalendarVisible(page)).toBe(false); - await startDatePicker.click(); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await startDatePicker.click(); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 60); - await page.waitForChanges(); - calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); - expect(await calendar.isVisible()).toBe(true); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + + await page.keyboard.press("Enter"); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); - const value = await inputDatePickerEl.getProperty("value"); - expect(value).toEqual(["2024-06-29", ""]); + await page.keyboard.press("Enter"); + await page.waitForChanges(); + expect(await isCalendarVisible(page)).toBe(true); + + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + + await page.keyboard.press("Enter"); + await page.waitForChanges(); + + //assert calendar is open once focus issue is fixed. + //expect(await isCalendarVisible(page)).toBe(true); + + const value = await inputDatePickerEl.getProperty("value"); + expect(value).toEqual(["2024-03-25", "2024-06-20"]); + }); }); }); diff --git a/packages/calcite-components/src/utils/date.ts b/packages/calcite-components/src/utils/date.ts index ab39b06d6a4..71d6e396456 100644 --- a/packages/calcite-components/src/utils/date.ts +++ b/packages/calcite-components/src/utils/date.ts @@ -286,3 +286,18 @@ export function setEndOfDay(date: Date): Date { date.setHours(23, 59, 59, 999); return date; } + +/** + * + * Returns if two dates have same month and year. + * + * @param date1 + * @param date2 + * @returns {boolean} + */ +export function hasSameMonthAndYear(date1: Date, date2: Date): boolean { + if (!date1 || !date2) { + return false; + } + return date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear(); +} From 084533684a711d5909a509ac419fdbf8ddb83aa2 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Mon, 1 Apr 2024 16:33:18 -0500 Subject: [PATCH 062/155] handle keydown events only on calendar container in date-picker-month --- .../src/components/date-picker-month/date-picker-month.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index e5bc197af0f..d59244d85ea 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -271,7 +271,7 @@ export class DatePickerMonth { const nextMonthWeeks = this.getWeeks(nextMonthDays); return ( - +
)}
-
+
{this.renderMonthCalendar(adjustedWeekDays, weeks)} {this.range && this.renderMonthCalendar(adjustedWeekDays, nextMonthWeeks)}
@@ -482,6 +482,7 @@ export class DatePickerMonth { daySelect = (event: CustomEvent): void => { const target = event.target as HTMLCalciteDatePickerDayElement; + // below line needs to be commented out to focus on active date on based on focused input this.activeFocus = false; this.calciteInternalDatePickerSelect.emit(target.value); }; From 082a9e4d0babd2923e8a218c815f583f8b01e8f2 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Fri, 12 Apr 2024 11:22:31 -0500 Subject: [PATCH 063/155] add new focus behavior --- .../date-picker-month/date-picker-month.tsx | 20 +++++++++---------- .../components/date-picker/date-picker.tsx | 13 ++++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 96d0334c316..a3b428b8f9d 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -304,7 +304,7 @@ export class DatePickerMonth {
{this.renderMonthCalendar(adjustedWeekDays, days)} - {this.range && this.renderMonthCalendar(adjustedWeekDays, nextMonthDays)} + {this.range && this.renderMonthCalendar(adjustedWeekDays, nextMonthDays, true)}
); @@ -629,15 +629,15 @@ export class DatePickerMonth { return days; }; - private getWeeks(days: Day[]): Day[][] { - const weeks: Day[][] = []; - for (let i = 0; i < days.length; i += 7) { - weeks.push(days.slice(i, i + 7)); - } - return weeks; - } + // private getWeeks(days: Day[]): Day[][] { + // const weeks: Day[][] = []; + // for (let i = 0; i < days.length; i += 7) { + // weeks.push(days.slice(i, i + 7)); + // } + // return weeks; + // } - private renderMonthCalendar(weekDays: string[], days: Day[]): VNode { + private renderMonthCalendar(weekDays: string[], days: Day[], isNextMonth = false): VNode { return (
@@ -649,7 +649,7 @@ export class DatePickerMonth {
- {days.map((day, index) => this.renderDateDay(day, index))} + {days.map((day, index) => this.renderDateDay(day, isNextMonth ? 50 + index : index))}
); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 681ff9673a4..9d67c5a99df 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -415,6 +415,19 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom if (!this.range) { this.activeDate = date; + } else { + const month = date.getMonth(); + if (this.activeRange === "end") { + if (month !== prevMonth(this.activeEndDate).getMonth()) { + this.activeEndDate = date; + this.activeStartDate = prevMonth(date); + } + } else { + if (month !== nextMonth(this.activeStartDate).getMonth()) { + this.activeStartDate = date; + this.activeEndDate = nextMonth(date); + } + } } }; From 209a45c78d1e911db51d1608d11b06f0db7a46c6 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Thu, 18 Apr 2024 17:04:48 -0500 Subject: [PATCH 064/155] fixes updating dates via keyboard --- .../date-picker-day/date-picker-day.scss | 111 ++---------------- .../date-picker-month/date-picker-month.tsx | 32 +++-- 2 files changed, 29 insertions(+), 114 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss b/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss index 7207b7d2dde..b4988d69b13 100644 --- a/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss +++ b/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss @@ -4,52 +4,6 @@ @include disabled(); -@mixin range-part-base() { - &:before, - &:after { - @apply absolute pointer-events-none; - inset-block: 0; - content: ""; - block-size: var(--calcite-internal-day-size); - inline-size: var(--calcite-internal-day-size); - } -} - -@mixin range-part-edge-end() { - &:before { - inset-inline-end: 50%; - } - &:after { - inset-inline-start: 50%; - // border-start-end-radius: var(--calcite-internal-day-size); - // border-end-end-radius: var(--calcite-internal-day-size); - inline-size: calc(var(--calcite-internal-day-size) / 2); - } -} - -@mixin range-part-edge-start() { - &:before { - inset-inline-end: 50%; - // border-start-start-radius: var(--calcite-internal-day-size); - // border-end-start-radius: var(--calcite-internal-day-size); - inline-size: calc(var(--calcite-internal-day-size) / 2); - } - &:after { - inset-inline-start: 50%; - } -} - -@mixin range-part-middle() { - &:before { - inset-inline-end: 50%; - border-radius: 0; - } - &:after { - inset-inline-start: 50%; - border-radius: 0; - } -} - .day-v-wrapper { @apply flex-auto; } @@ -61,13 +15,6 @@ relative; } -:host([range]), -:host([range-hover]) { - .day-wrapper { - @include range-part-base(); - } -} - .day { @apply text-n2h text-color-3 @@ -93,7 +40,7 @@ --calcite-internal-day-size: 27px; .day-v-wrapper { - @apply py-0.5; + // @apply py-0.5; } .day-wrapper { @apply p-0; @@ -104,10 +51,10 @@ } :host([scale="m"]) { - --calcite-internal-day-size: 33px; + --calcite-internal-day-size: 40px; .day-v-wrapper { - @apply py-1; + // @apply py-1; } .day-wrapper { @apply p-0; @@ -121,7 +68,7 @@ --calcite-internal-day-size: 43px; .day-v-wrapper { - @apply py-1; + // @apply py-1; } .day-wrapper { @apply px-1; @@ -167,10 +114,6 @@ :host([range-hover]:not([selected])), :host([highlighted]:not([selected])) { - .day-wrapper { - @include range-part-middle(); - } - .day { @apply text-color-1; } @@ -179,40 +122,13 @@ :host([highlighted]), :host([selected]:not(.hover--outside-range)) { .day-wrapper { - &:before, - &:after { - background-color: var(--calcite-color-foreground-current); - } + background-color: var(--calcite-color-foreground-current); } } :host([range-hover]:not([selected])) { .day-wrapper { - &:before, - &:after { - @apply bg-foreground-2; - } - } -} - -:host(:hover[range-hover]:not([selected]).focused--end), -:host([highlighted][end-of-range]), -:host([highlighted][range-edge="end"]), -:host([range-hover][range-edge="end"]), -:host(:hover[range-hover].focused--end.hover--outside-range) { - .day-wrapper { - @include range-part-edge-end(); - } -} - -:host([highlighted][start-of-range]), -:host([highlighted][range-edge="start"]), -:host([range-hover][range-edge="start"]), -:host(:hover[range-hover]:not([selected]).focused--start), -:host([start-of-range].hover--inside-range), -:host(:hover[range-hover].focused--start.hover--outside-range) { - .day-wrapper { - @include range-part-edge-start(); + @apply bg-foreground-2; } } @@ -221,10 +137,7 @@ :host([start-of-range][range-edge="end"].hover--inside-range), :host([end-of-range]) { .day-wrapper { - &:after, - &:before { - content: unset; - } + content: unset; } } @@ -256,10 +169,7 @@ :host([highlighted]), :host([range-hover]:not([selected])) { .day-wrapper { - &:before, - &:after { - background-color: highlight; - } + background-color: highlight; } } @@ -267,10 +177,7 @@ :host([range][selected][start-of-range]), :host([range][selected][end-of-range]) { .day-wrapper { - &:before, - &:after { - background-color: canvas; - } + background-color: canvas; } } } diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index a3b428b8f9d..8dfa96b01fe 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -174,23 +174,24 @@ export class DatePickerMonth { } const isRTL = this.el.dir === "rtl"; - + const target = event.target as HTMLCalciteDatePickerDayElement; switch (event.key) { case "ArrowUp": event.preventDefault(); - this.addDays(-7); + this.addDays(-7, target.value); break; case "ArrowRight": event.preventDefault(); - this.addDays(isRTL ? -1 : 1); + this.addDays(isRTL ? -1 : 1, target.value); break; case "ArrowDown": + console.log(event.target, event.currentTarget); event.preventDefault(); - this.addDays(7); + this.addDays(7, target.value); break; case "ArrowLeft": event.preventDefault(); - this.addDays(isRTL ? 1 : -1); + this.addDays(isRTL ? 1 : -1, target.value); break; case "PageUp": event.preventDefault(); @@ -203,14 +204,14 @@ export class DatePickerMonth { case "Home": event.preventDefault(); this.activeDate.setDate(1); - this.addDays(); + this.addDays(0, target.value); break; case "End": event.preventDefault(); this.activeDate.setDate( new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate(), ); - this.addDays(); + this.addDays(0, target.value); break; case "Enter": case " ": @@ -271,7 +272,7 @@ export class DatePickerMonth { // const nextMonthWeeks = this.getWeeks(nextMonthDays); return ( - +
{ const date = new Date(year, month, day); - const active = sameDate(date, this.focusedDate); + const active = + this.focusedDate && + this.focusedDate !== this.startDate && + this.focusedDate !== this.endDate + ? sameDate(date, this.focusedDate) + : sameDate(date, this.startDate) || sameDate(date, this.endDate); + return { active, currentMonth: true, From 1f5b745dd1ad68b2383d2171d3a300093fcf55a7 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Thu, 18 Apr 2024 18:32:54 -0500 Subject: [PATCH 065/155] fix pageUp & pageDown keys --- .../date-picker-month/date-picker-month.tsx | 13 ++++++++----- .../src/components/date-picker/date-picker.tsx | 10 ++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 8dfa96b01fe..3528df15daa 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -195,11 +195,11 @@ export class DatePickerMonth { break; case "PageUp": event.preventDefault(); - this.addMonths(-1); + this.addMonths(-1, target.value); break; case "PageDown": event.preventDefault(); - this.addMonths(1); + this.addMonths(1, target.value); break; case "Home": event.preventDefault(); @@ -330,14 +330,17 @@ export class DatePickerMonth { * Add n months to the current month * * @param step + * @param targetDate */ - private addMonths(step: number) { - const nextDate = new Date(this.activeDate); - nextDate.setMonth(this.activeDate.getMonth() + step); + private addMonths(step: number, targetDate: Date) { + const nextDate = new Date(targetDate); + nextDate.setMonth(targetDate.getMonth() + step); this.calciteInternalDatePickerActiveDateChange.emit( dateFromRange(nextDate, this.min, this.max), ); + this.focusedDate = dateFromRange(nextDate, this.min, this.max); this.activeFocus = true; + this.calciteInternalDatePickerHover.emit(nextDate); } /** diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 9d67c5a99df..be3809cea7d 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -418,12 +418,18 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } else { const month = date.getMonth(); if (this.activeRange === "end") { - if (month !== prevMonth(this.activeEndDate).getMonth()) { + if ( + (this.activeEndDate && month !== prevMonth(this.activeEndDate).getMonth()) || + !this.activeEndDate + ) { this.activeEndDate = date; this.activeStartDate = prevMonth(date); } } else { - if (month !== nextMonth(this.activeStartDate).getMonth()) { + if ( + (this.activeStartDate && month !== nextMonth(this.activeStartDate).getMonth()) || + !this.activeStartDate + ) { this.activeStartDate = date; this.activeEndDate = nextMonth(date); } From 18d71eb647427d5550c304115b706c2e3c5875e4 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Fri, 19 Apr 2024 13:07:03 -0500 Subject: [PATCH 066/155] do not update activedate when updating start or end dates if selected from same calendar --- .../components/date-picker-month/date-picker-month.tsx | 1 - .../src/components/date-picker/date-picker.tsx | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 3528df15daa..54a8009adc1 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -185,7 +185,6 @@ export class DatePickerMonth { this.addDays(isRTL ? -1 : 1, target.value); break; case "ArrowDown": - console.log(event.target, event.currentTarget); event.preventDefault(); this.addDays(7, target.value); break; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index be3809cea7d..02cac47f2be 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -412,14 +412,15 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom monthActiveDateChange = (event: CustomEvent): void => { const date = new Date(event.detail); - if (!this.range) { this.activeDate = date; } else { const month = date.getMonth(); if (this.activeRange === "end") { if ( - (this.activeEndDate && month !== prevMonth(this.activeEndDate).getMonth()) || + (this.activeEndDate && + month !== prevMonth(this.activeEndDate).getMonth() && + month !== this.activeEndDate.getMonth()) || !this.activeEndDate ) { this.activeEndDate = date; @@ -427,7 +428,9 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } } else { if ( - (this.activeStartDate && month !== nextMonth(this.activeStartDate).getMonth()) || + (this.activeStartDate && + month !== nextMonth(this.activeStartDate).getMonth() && + month !== this.activeStartDate.getMonth()) || !this.activeStartDate ) { this.activeStartDate = date; From 423c05aeffe03ad094d3d6a1015c247469b4c898 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Tue, 23 Apr 2024 10:37:04 -0500 Subject: [PATCH 067/155] fix range hover color and selection --- .../date-picker-month/date-picker-month.tsx | 40 +++++++++++++------ .../components/date-picker/date-picker.tsx | 23 ++++++----- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index 54a8009adc1..a06e5350ff4 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -561,31 +561,45 @@ export class DatePickerMonth { return false; } const { start, end } = this.hoverRange; - return !!( - (!this.isFocusedOnStart() && this.startDate && (!this.endDate || end < this.endDate)) || - (this.isFocusedOnStart() && this.startDate && start > this.startDate) - ); + const isStartFocused = this.isFocusedOnStart(); + const isEndAfterStart = this.startDate && end > this.startDate; + const isEndBeforeEnd = this.endDate && end < this.endDate; + const isStartAfterStart = this.startDate && start > this.startDate; + const isStartBeforeEnd = this.endDate && start < this.endDate; + + const isEndDateAfterStartAndBeforeEnd = + !isStartFocused && !!this.startDate && isEndAfterStart && (!this.endDate || isEndBeforeEnd); + const isStartDateBeforeEndAndAfterStart = + isStartFocused && !!this.startDate && isStartAfterStart && isStartBeforeEnd; + + return !!(isEndDateAfterStartAndBeforeEnd || isStartDateBeforeEndAndAfterStart); } - private isRangeHover(date): boolean { + private isRangeHover(date: Date): boolean { if (!this.hoverRange) { return false; } const { start, end } = this.hoverRange; const isStart = this.isFocusedOnStart(); const insideRange = this.isHoverInRange(); - const cond1 = + + const minimizeCurrentRange = insideRange && - ((!isStart && date > this.startDate && (date < end || sameDate(date, end))) || - (isStart && date < this.endDate && (date > start || sameDate(date, start)))); - const cond2 = + ((!isStart && + date > this.startDate && + ((date > end && date < this.endDate) || sameDate(date, end))) || + (isStart && + date < this.endDate && + ((date < start && date > this.startDate) || sameDate(date, start)))); + + const maximizeCurrentRange = !insideRange && ((!isStart && date >= this.endDate && (date < end || sameDate(date, end))) || (isStart && - ((this.startDate && date < this.startDate) || - (this.endDate && sameDate(date, this.startDate))) && - ((start && date > start) || sameDate(date, start)))); - return cond1 || cond2; + ((this.startDate && date < this.startDate && date > start) || + (this.endDate && date > this.endDate && date < end)))); + + return minimizeCurrentRange || maximizeCurrentRange; } private getDays = ( diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 02cac47f2be..41949a51a6e 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -445,7 +445,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.hoverRange = undefined; return; } - const { valueAsDate } = this; const start = Array.isArray(valueAsDate) && valueAsDate[0]; const end = Array.isArray(valueAsDate) && valueAsDate[1]; @@ -467,20 +466,22 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.hoverRange.focused = "start"; } } else if (start && end) { - const startDiff = getDaysDiff(date, start); - const endDiff = getDaysDiff(date, end); - if (endDiff > 0) { + const startDiff = Math.abs(getDaysDiff(date, start)); + const endDiff = Math.abs(getDaysDiff(date, end)); + if (date > end) { this.hoverRange.end = date; this.hoverRange.focused = "end"; - } else if (startDiff < 0) { - this.hoverRange.start = date; - this.hoverRange.focused = "start"; - } else if (startDiff > endDiff) { + } else if (date < start) { this.hoverRange.start = date; this.hoverRange.focused = "start"; - } else { - this.hoverRange.end = date; - this.hoverRange.focused = "end"; + } else if (date > start && date < end) { + if (startDiff < endDiff) { + this.hoverRange.start = date; + this.hoverRange.focused = "start"; + } else { + this.hoverRange.end = date; + this.hoverRange.focused = "end"; + } } } else { if (start) { From 39880ce80ce45fb6c433843399e1fd529bb08274 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Tue, 23 Apr 2024 18:12:46 -0500 Subject: [PATCH 068/155] fix date-picker tests and merge master --- .../components/date-picker/date-picker.e2e.ts | 26 +++++++++++++------ .../components/date-picker/date-picker.tsx | 6 ++--- .../input-date-picker.e2e.ts | 4 +-- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 3b44a6d85db..06864ba71de 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -211,11 +211,8 @@ describe("calcite-date-picker", () => { const page = await newE2EPage(); await page.setContent(""); - const datePickerContainer = await page.find("calcite-date-picker >>> .container"); - const datePickerMonth = await datePickerContainer.find("calcite-date-picker-month >>> .month-header"); - const datePickerMonthHeader = await datePickerMonth.find("calcite-date-picker-month-header >>> .header "); - const [prevMonth, nextMonth] = await datePickerMonthHeader.findAll("a"); - const [monthSelect, yearSelect] = await datePickerMonthHeader.findAll("calcite-select"); + const [prevMonth, nextMonth] = await page.findAll("calcite-date-picker >>> a "); + const [monthSelect, yearSelect] = await page.findAll("calcite-date-picker >>> calcite-select"); await prevMonth.click(); await nextMonth.click(); @@ -343,7 +340,8 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Tab"); await page.waitForChanges(); - + await page.keyboard.press("Tab"); + await page.waitForChanges(); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); await page.keyboard.press("Enter"); @@ -387,6 +385,8 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Tab"); await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); await page.keyboard.press("Enter"); @@ -435,7 +435,12 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Tab"); await page.waitForChanges(); - + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); await page.keyboard.press("Enter"); @@ -481,6 +486,12 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Tab"); await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); await page.keyboard.press("Enter"); @@ -494,7 +505,6 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Enter"); await page.waitForChanges(); - expect(await datePicker.getProperty("value")).toEqual(["2023-12-25", "2024-01-08"]); await page.keyboard.press("PageUp"); diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 67d8bb0ebb9..cf9af9c9263 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -470,10 +470,8 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.hoverRange = undefined; } } else { - if (start && end) { - const startDiff = getDaysDiff(date, start); - const endDiff = getDaysDiff(date, end); - if (endDiff > 0) { + if (this.activeRange) { + if (this.activeRange === "end") { this.hoverRange.end = date; this.hoverRange.focused = "end"; } else { diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index f7c11d8a190..ffc16dfde46 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1359,9 +1359,7 @@ describe("calcite-input-date-picker", () => { await page.keyboard.press("Enter"); await page.waitForChanges(); - - //assert calendar is open once focus issue is fixed. - //expect(await isCalendarVisible(page)).toBe(true); + expect(await isCalendarVisible(page)).toBe(true); const value = await inputDatePickerEl.getProperty("value"); expect(value).toEqual(["2024-03-25", "2024-06-20"]); From f01580a84bc9856de23962416e3c74862d96e80a Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Wed, 24 Apr 2024 14:22:55 -0500 Subject: [PATCH 069/155] fix input date picker tests --- .../input-date-picker/input-date-picker.e2e.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index ffc16dfde46..59bd6f03f1f 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -74,11 +74,8 @@ describe("calcite-input-date-picker", () => { it.skip("supports t9n", () => t9n("calcite-input-date-picker")); async function navigateMonth(page: E2EPage, direction: "previous" | "next", range = false): Promise { - const datePicker = await page.find("calcite-input-date-picker >>> .menu-container"); - const datePickerContainer = await datePicker.find("calcite-date-picker >>> .container"); - const datePickerMonth = await datePickerContainer.find("calcite-date-picker-month >>> .month-header"); - const [datePickerMonthHeaderStart, datePickerMonthHeaderEnd] = await datePickerMonth.findAll( - "calcite-date-picker-month-header >>> .header ", + const [datePickerMonthHeaderStart, datePickerMonthHeaderEnd] = await page.findAll( + "calcite-input-date-picker >>> calcite-date-picker-month-header >>> .header", ); let prevMonth: E2EElement; @@ -96,12 +93,7 @@ describe("calcite-input-date-picker", () => { async function selectDayInMonth(page: E2EPage, day: number): Promise { const dayIndex = day - 1; - - const datePicker = await page.find("calcite-input-date-picker >>> .menu-container"); - const datePickerContainer = await datePicker.find("calcite-date-picker >>> .container"); - const datePickerMonth = await datePickerContainer.find("calcite-date-picker-month >>> .calendar"); - const days = await datePickerMonth.findAll("calcite-date-picker-day[current-month]"); - + const days = await page.findAll("calcite-input-date-picker >>> calcite-date-picker-day[current-month]"); await days[dayIndex].click(); await page.waitForChanges(); } From 0e17d567ef776116294eddf937e9fb32e7049895 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Wed, 24 Apr 2024 18:11:14 -0500 Subject: [PATCH 070/155] fixes hover edge cases and adds tests --- .../date-picker-month/date-picker-month.tsx | 40 ++++--- .../components/date-picker/date-picker.e2e.ts | 104 ++++++++++++++++-- 2 files changed, 118 insertions(+), 26 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index a06e5350ff4..aae4df13ee3 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -583,23 +583,29 @@ export class DatePickerMonth { const isStart = this.isFocusedOnStart(); const insideRange = this.isHoverInRange(); - const minimizeCurrentRange = - insideRange && - ((!isStart && - date > this.startDate && - ((date > end && date < this.endDate) || sameDate(date, end))) || - (isStart && - date < this.endDate && - ((date < start && date > this.startDate) || sameDate(date, start)))); - - const maximizeCurrentRange = - !insideRange && - ((!isStart && date >= this.endDate && (date < end || sameDate(date, end))) || - (isStart && - ((this.startDate && date < this.startDate && date > start) || - (this.endDate && date > this.endDate && date < end)))); - - return minimizeCurrentRange || maximizeCurrentRange; + const isDateBeforeStartDateAndAfterStart = date > start && date < this.startDate; + const isDateAfterEndDateAndBeforeEnd = date < end && date > this.endDate; + const isDateBeforeEndDateAndAfterEnd = date > end && date < this.endDate; + const isDateAfterStartDateAndBeforeStart = date < start && date > this.startDate; + const isDateAfterStartDateAndBeforeEnd = date < end && date > this.startDate; + const isDateBeforeEndDateAndAfterStart = date > start && date < this.endDate; + + if (insideRange) { + if (!!this.startDate && !!this.endDate) { + return isStart + ? date < this.endDate && + (isDateAfterStartDateAndBeforeStart || isDateBeforeStartDateAndAfterStart) + : isDateBeforeEndDateAndAfterEnd || isDateAfterEndDateAndBeforeEnd; + } else if (!!this.startDate && !this.endDate) { + return isStart ? isDateBeforeStartDateAndAfterStart : isDateAfterStartDateAndBeforeEnd; + } else if (!this.startDate && !!this.endDate) { + return isStart ? isDateBeforeEndDateAndAfterStart : isDateAfterEndDateAndBeforeEnd; + } + } else { + if (!!this.startDate && !!this.endDate) { + return isStart ? isDateBeforeStartDateAndAfterStart : isDateAfterEndDateAndBeforeEnd; + } + } } private getDays = ( diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 06864ba71de..869cdd843f8 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -1,4 +1,4 @@ -import { E2EPage, newE2EPage } from "@stencil/core/testing"; +import { E2EElement, E2EPage, newE2EPage } from "@stencil/core/testing"; import { html } from "../../../support/formatting"; import { defaults, focusable, hidden, renders, t9n } from "../../tests/commonTests"; import { skipAnimations } from "../../tests/utils"; @@ -139,6 +139,14 @@ describe("calcite-date-picker", () => { expect(changedEvent).toHaveReceivedEventTimes(0); }); + async function setActiveDate(page: E2EPage, date: string): Promise { + await page.evaluate((date) => { + const datePicker = document.querySelector("calcite-date-picker"); + datePicker.activeDate = new Date(date); + }, date); + await page.waitForChanges(); + } + async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard"): Promise { await page.$eval( "calcite-date-picker", @@ -316,14 +324,6 @@ describe("calcite-date-picker", () => { }); describe("ArrowKeys and PageKeys", () => { - async function setActiveDate(page: E2EPage, date: string): Promise { - await page.evaluate((date) => { - const datePicker = document.querySelector("calcite-date-picker"); - datePicker.activeDate = new Date(date); - }, date); - await page.waitForChanges(); - } - it("should be able to navigate between months and select date using arrow keys and page keys", async () => { const page = await newE2EPage(); await page.setContent(html``); @@ -545,4 +545,90 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual(["2020-09-15", "2020-09-30"]); }); + + //todo: refactor to storybook tests + describe("hover range", () => { + async function getDayById(page: E2EPage, id: string): Promise { + return await page.find( + `calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`, + ); + } + + it("should toggle range-hover attribute when date falls outside of range", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + const datePicker = await page.find("calcite-date-picker"); + datePicker.setProperty("value", ["2024-01-01", "2024-02-10"]); + + await page.waitForChanges(); + await page.waitForChanges(); + let dateInsideRange = await getDayById(page, "20240109"); + + await dateInsideRange.hover(); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240108")).getProperty("rangeHover")).toBe(true); + expect(await (await getDayById(page, "20240208")).getProperty("rangeHover")).toBe(false); + + dateInsideRange = await getDayById(page, "20240205"); + await dateInsideRange.hover(); + expect(await (await getDayById(page, "20240108")).getProperty("rangeHover")).toBe(false); + expect(await (await getDayById(page, "20240208")).getProperty("rangeHover")).toBe(true); + }); + + it("should add range-hover attribute to dates falls outside of current range when extending", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + const datePicker = await page.find("calcite-date-picker"); + datePicker.setProperty("value", ["2024-01-05", "2024-02-15"]); + + await page.waitForChanges(); + expect(await (await getDayById(page, "20240108")).getProperty("rangeHover")).toBe(false); + expect(await (await getDayById(page, "20240208")).getProperty("rangeHover")).toBe(false); + + let dateInsideRange = await getDayById(page, "20240101"); + await dateInsideRange.hover(); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240102")).getProperty("rangeHover")).toBe(true); + expect(await (await getDayById(page, "20240108")).getProperty("rangeHover")).toBe(false); + expect(await (await getDayById(page, "20240208")).getProperty("rangeHover")).toBe(false); + + dateInsideRange = await getDayById(page, "20240225"); + await dateInsideRange.hover(); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240102")).getProperty("rangeHover")).toBe(false); + expect(await (await getDayById(page, "20240108")).getProperty("rangeHover")).toBe(false); + expect(await (await getDayById(page, "20240208")).getProperty("rangeHover")).toBe(false); + expect(await (await getDayById(page, "20240224")).getProperty("rangeHover")).toBe(true); + }); + + it("should not add range-hover attribute to dates before startDate and after endDate during initial selection", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + + await setActiveDate(page, "01-01-2024"); + await page.waitForChanges(); + + const startDate = await getDayById(page, "20240108"); + await startDate.hover(); + await page.waitForChanges(); + + await selectDay("20240108", page, "mouse"); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240107")).getProperty("rangeHover")).toBeFalsy(); + expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBeFalsy(); + + const endDate = await getDayById(page, "20240205"); + await endDate.hover(); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240107")).getProperty("rangeHover")).toBeFalsy(); + expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBeFalsy(); + expect(await (await getDayById(page, "20240201")).getProperty("rangeHover")).toBe(true); + + await selectDay("20240205", page, "mouse"); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240107")).getProperty("rangeHover")).toBeFalsy(); + expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBeFalsy(); + expect(await (await getDayById(page, "20240201")).getProperty("rangeHover")).toBe(false); + }); + }); }); From d2363a58250b5009ce2326f982e5fbfbbdd64e1a Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Thu, 25 Apr 2024 12:27:52 -0500 Subject: [PATCH 071/155] add range hover tests in input-date-picker --- .../calcite-components/src/components.d.ts | 5 ++ .../components/date-picker/date-picker.e2e.ts | 4 +- .../input-date-picker.e2e.ts | 74 +++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 1904630e145..f8f47f1a839 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -3396,6 +3396,11 @@ export namespace Components { "label": string; } interface CalcitePagination { + /** + * Set a specified page as active. + * @param page + */ + "goTo": (page: number | "start" | "end") => Promise; /** * When `true`, number values are displayed with a group separator corresponding to the language and country format. */ diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 869cdd843f8..730b7b895e7 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -554,16 +554,14 @@ describe("calcite-date-picker", () => { ); } - it("should toggle range-hover attribute when date falls outside of range", async () => { + it("should toggle range-hover attribute when updating the range", async () => { const page = await newE2EPage(); await page.setContent(html``); const datePicker = await page.find("calcite-date-picker"); datePicker.setProperty("value", ["2024-01-01", "2024-02-10"]); - await page.waitForChanges(); await page.waitForChanges(); let dateInsideRange = await getDayById(page, "20240109"); - await dateInsideRange.hover(); await page.waitForChanges(); expect(await (await getDayById(page, "20240108")).getProperty("rangeHover")).toBe(true); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 59bd6f03f1f..e2608ca811a 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1357,4 +1357,78 @@ describe("calcite-input-date-picker", () => { expect(value).toEqual(["2024-03-25", "2024-06-20"]); }); }); + + //todo: refactor to storybook tests + describe("hover range", () => { + async function getDayById(page: E2EPage, id: string): Promise { + return await page.find( + `calcite-input-date-picker >>> calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`, + ); + } + + it("should add range-hover attribute for dates less than new startDate and greater than current startDate or greater than new endDate and less than current startDate", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + const datePicker = await page.find("calcite-input-date-picker"); + datePicker.setProperty("value", ["2024-01-10", "2024-02-10"]); + await page.waitForChanges(); + + const input = await page.find("calcite-input-date-picker >>> calcite-input-text"); + await input.click(); + await page.waitForChanges(); + + const calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + let dateInsideRange = await getDayById(page, "20240201"); + await dateInsideRange.hover(); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240131")).getProperty("rangeHover")).toBe(true); + + dateInsideRange = await getDayById(page, "20240205"); + await dateInsideRange.hover(); + expect(await (await getDayById(page, "20240202")).getProperty("rangeHover")).toBe(true); + + dateInsideRange = await getDayById(page, "20240105"); + await dateInsideRange.hover(); + expect(await (await getDayById(page, "20240106")).getProperty("rangeHover")).toBe(true); + }); + + it("should add range-hover attribute for dates greater current endDate and less than new endDate or greater than new endDate or less than current endDate", async () => { + const page = await newE2EPage(); + await page.setContent(html``); + const datePicker = await page.find("calcite-input-date-picker"); + datePicker.setProperty("value", ["2024-01-10", "2024-02-10"]); + await page.waitForChanges(); + + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("ArrowDown"); + await page.waitForChanges(); + + const calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); + expect(await calendar.isVisible()).toBe(true); + + let dateInsideRange = await getDayById(page, "20240201"); + await dateInsideRange.hover(); + await page.waitForChanges(); + expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBe(true); + + dateInsideRange = await getDayById(page, "20240115"); + await dateInsideRange.hover(); + expect(await (await getDayById(page, "20240116")).getProperty("rangeHover")).toBe(true); + + let dateOutsideRange = await getDayById(page, "20240215"); + await dateOutsideRange.hover(); + expect(await (await getDayById(page, "20240212")).getProperty("rangeHover")).toBe(true); + + await navigateMonth(page, "next", true); + await page.waitForChanges(); + dateOutsideRange = await getDayById(page, "20240315"); + await dateOutsideRange.hover(); + expect(await (await getDayById(page, "20240314")).getProperty("rangeHover")).toBe(true); + }); + }); }); From 91e66165c114034b6dc5b94d5cfdfb10dea826c0 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Thu, 25 Apr 2024 14:10:59 -0500 Subject: [PATCH 072/155] delete unrelated tests --- .../date-picker-month-header.e2e.ts | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts index eb73164a539..e702f6375ae 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.e2e.ts @@ -1,5 +1,4 @@ import { newE2EPage } from "@stencil/core/testing"; -import { html } from "../../../support/formatting"; import { renders } from "../../tests/commonTests"; import { DateLocaleData } from "../date-picker/utils"; @@ -69,31 +68,4 @@ describe("calcite-date-picker-month-header", () => { expect(await prev.isVisible()).toBe(true); expect(await next.isVisible()).toBe(true); }); - - it.skip("should set the input aria-label to year", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - - await page.evaluate((localeData) => { - const dateMonthHeader = document.createElement( - "calcite-date-picker-month-header", - ) as HTMLCalciteDatePickerMonthHeaderElement; - const now = new Date(); - dateMonthHeader.activeDate = now; - dateMonthHeader.selectedDate = now; - dateMonthHeader.localeData = localeData; - dateMonthHeader.messages = { - nextMonth: "Next month", - prevMonth: "Previous month", - year: "Year", - }; - - document.body.innerHTML = ""; - document.body.append(dateMonthHeader); - }, localeDataFixture); - await page.waitForChanges(); - const date = await page.find(`calcite-date-picker-month-header >>> input`); - - expect(await date.getAttribute("aria-label")).toBe("Year"); - }); }); From 2fa670490d92287e0e9e3d275ff0ecaa21fc7b84 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Fri, 3 May 2024 00:43:14 -0500 Subject: [PATCH 073/155] do not shift focus onto endDate and do not update activeDate after initial selection --- .../components/date-picker/date-picker.tsx | 17 +------- .../input-date-picker.e2e.ts | 39 ------------------- 2 files changed, 1 insertion(+), 55 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index cf9af9c9263..0566a7bc423 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -18,7 +18,6 @@ import { dateFromRange, dateToISO, getDaysDiff, - hasSameMonthAndYear, HoverRange, inRange, nextMonth, @@ -96,14 +95,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom */ @Prop({ reflect: true }) activeRange: "start" | "end"; - @Watch("activeRange") - handleActiveRangeChange(newValue: string): void { - //preserve activeEndDate when user selects startDate and focus shifts on to endDate - if (newValue && Array.isArray(this.valueAsDate) && this.valueAsDate[0] && this.valueAsDate[1]) { - this.resetActiveDates(); - } - } - /** * Specifies the selected date as a string (`"yyyy-mm-dd"`), or an array of strings for `range` values (`["yyyy-mm-dd", "yyyy-mm-dd"]`). */ @@ -304,13 +295,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom : date : this.minAsDate; - const startCalendarActiveDate = this.range - ? this.activeRange === "end" && - this.activeEndDate && - !hasSameMonthAndYear(this.activeStartDate, this.activeEndDate) - ? prevMonth(this.activeEndDate) - : this.activeStartDate || prevMonth(this.activeEndDate) - : activeDate; + const startCalendarActiveDate = this.range ? this.activeStartDate : activeDate; return ( diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index e2608ca811a..5d2e01c6851 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1215,45 +1215,6 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(page)).toBe(false); }); - it("should be able to navigate to previous months in startDate and update endDate by switching the focus with mouse", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - await skipAnimations(page); - await page.waitForChanges(); - - const inputDatePickerEl = await page.find("calcite-input-date-picker"); - const [startDatePicker, endDatePicker] = await page.findAll("calcite-input-date-picker >>> calcite-input-text"); - inputDatePickerEl.setProperty("value", ["2024-05-25", "2024-06-25"]); - expect(await isCalendarVisible(page)).toBe(false); - - await startDatePicker.click(); - await page.waitForChanges(); - expect(await isCalendarVisible(page)).toBe(true); - - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - expect(await isCalendarVisible(page)).toBe(true); - - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - expect(await isCalendarVisible(page)).toBe(true); - - await navigateMonth(page, "previous", true); - await page.waitForChanges(); - expect(await isCalendarVisible(page)).toBe(true); - - await endDatePicker.click(); - await page.waitForChanges(); - expect(await isCalendarVisible(page)).toBe(true); - - await selectDayInMonth(page, 40); - await page.waitForChanges(); - expect(await isCalendarVisible(page)).toBe(false); - - const value = await inputDatePickerEl.getProperty("value"); - expect(value[1]).not.toEqual("2024-06-25"); - }); - it("should be able to navigate months when valueAsDate is parsed", async () => { const page = await newE2EPage(); await page.setContent(html``); From e86dd1df5ee627a135a08399cf1696117dd48d56 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Fri, 3 May 2024 11:49:16 -0500 Subject: [PATCH 074/155] fix test failures --- .../calcite-components/src/components.d.ts | 96 ------------------- .../input-date-picker.e2e.ts | 25 ++--- .../input-date-picker.stories.ts | 6 ++ 3 files changed, 16 insertions(+), 111 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index ce6d54d1e03..7e293740802 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -9,179 +9,83 @@ import { Alignment, Appearance, Columns, FlipContext, Kind, Layout, LogicalFlowP import { RequestedItem } from "./components/accordion/interfaces"; import { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces"; import { ActionMessages } from "./components/action/assets/action/t9n"; -import { ActionMessages } from "./components/action/assets/action/t9n"; -import { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; -import { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; -import { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; import { EffectivePlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui"; import { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; -import { AlertMessages } from "./components/alert/assets/alert/t9n"; import { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; -import { BlockMessages } from "./components/block/assets/block/t9n"; import { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; -import { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; import { AlertDuration, Sync } from "./components/alert/interfaces"; -import { ButtonMessages } from "./components/button/assets/button/t9n"; -import { CardMessages } from "./components/card/assets/card/t9n"; import { NumberingSystem } from "./utils/locale"; import { AlertMessages } from "./components/alert/assets/alert/t9n"; -import { ChipMessages } from "./components/chip/assets/chip/t9n"; import { HeadingLevel } from "./components/functional/Heading"; import { BlockMessages } from "./components/block/assets/block/t9n"; -import { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; import { BlockSectionToggleDisplay } from "./components/block-section/interfaces"; -import { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; -import { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; import { ButtonAlignment, DropdownIconType } from "./components/button/interfaces"; import { ButtonMessages } from "./components/button/assets/button/t9n"; import { CardMessages } from "./components/card/assets/card/t9n"; -import { FilterMessages } from "./components/filter/assets/filter/t9n"; import { ArrowType, AutoplayType } from "./components/carousel/interfaces"; -import { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; import { MutableValidityState } from "./utils/form"; -import { HandleMessages } from "./components/handle/assets/handle/t9n"; import { ChipMessages } from "./components/chip/assets/chip/t9n"; -import { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; import { ColorValue, InternalColor } from "./components/color-picker/interfaces"; -import { InputMessages } from "./components/input/assets/input/t9n"; -import { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; -import { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; -import { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; -import { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; -import { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; -import { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; import { Format } from "./components/color-picker/utils"; import { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; import { ComboboxChildElement, SelectionDisplay } from "./components/combobox/interfaces"; -import { ListMessages } from "./components/list/assets/list/t9n"; import { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; -import { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; -import { MenuMessages } from "./components/menu/assets/menu/t9n"; -import { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; import { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { DateLocaleData } from "./components/date-picker/utils"; -import { ModalMessages } from "./components/modal/assets/modal/t9n"; -import { NoticeMessages } from "./components/notice/assets/notice/t9n"; -import { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; -import { PanelMessages } from "./components/panel/assets/panel/t9n"; import { HoverRange } from "./utils/date"; import { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; -import { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; -import { PopoverMessages } from "./components/popover/assets/popover/t9n"; -import { RatingMessages } from "./components/rating/assets/rating/t9n"; -import { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; import { ItemKeyboardEvent } from "./components/dropdown/interfaces"; import { FilterMessages } from "./components/filter/assets/filter/t9n"; -import { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; import { FlowItemLikeElement } from "./components/flow/interfaces"; import { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; -import { StepperMessages } from "./components/stepper/assets/stepper/t9n"; -import { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; import { ColorStop, DataSeries } from "./components/graph/interfaces"; -import { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; import { HandleMessages } from "./components/handle/assets/handle/t9n"; -import { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; import { HandleChange, HandleNudge } from "./components/handle/interfaces"; -import { TableMessages } from "./components/table/assets/table/t9n"; -import { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; -import { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; -import { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; import { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; import { InputPlacement } from "./components/input/interfaces"; -import { TipMessages } from "./components/tip/assets/tip/t9n"; -import { TipManagerMessages } from "./components/tip-manager/assets/tip-manager/t9n"; import { InputMessages } from "./components/input/assets/input/t9n"; -import { ValueListMessages } from "./components/value-list/assets/value-list/t9n"; import { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; import { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; import { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; import { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; -export { ActionMessages } from "./components/action/assets/action/t9n"; import { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; -export { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; -export { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; -export { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; import { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; import { TimeZoneMode } from "./components/input-time-zone/interfaces"; -export { AlertMessages } from "./components/alert/assets/alert/t9n"; import { ListDragDetail } from "./components/list/interfaces"; -export { BlockMessages } from "./components/block/assets/block/t9n"; import { ItemData } from "./components/list-item/interfaces"; -export { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; import { ListMessages } from "./components/list/assets/list/t9n"; -export { ButtonMessages } from "./components/button/assets/button/t9n"; -export { CardMessages } from "./components/card/assets/card/t9n"; import { SelectionAppearance } from "./components/list/resources"; import { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; -export { ChipMessages } from "./components/chip/assets/chip/t9n"; import { MenuMessages } from "./components/menu/assets/menu/t9n"; import { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; -export { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; import { MenuItemCustomEvent } from "./components/menu-item/interfaces"; -export { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; -export { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { MeterLabelType } from "./components/meter/interfaces"; import { ModalMessages } from "./components/modal/assets/modal/t9n"; import { NoticeMessages } from "./components/notice/assets/notice/t9n"; import { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; -export { FilterMessages } from "./components/filter/assets/filter/t9n"; import { PanelMessages } from "./components/panel/assets/panel/t9n"; -export { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; import { ItemData as ItemData1, ListFocusId } from "./components/pick-list/shared-list-logic"; -export { HandleMessages } from "./components/handle/assets/handle/t9n"; import { ICON_TYPES } from "./components/pick-list/resources"; -export { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; import { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; -export { InputMessages } from "./components/input/assets/input/t9n"; -export { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; -export { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; -export { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; -export { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; -export { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; -export { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; import { PopoverMessages } from "./components/popover/assets/popover/t9n"; import { RatingMessages } from "./components/rating/assets/rating/t9n"; import { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; -export { ListMessages } from "./components/list/assets/list/t9n"; import { DisplayMode } from "./components/sheet/interfaces"; -export { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; -export { MenuMessages } from "./components/menu/assets/menu/t9n"; -export { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; import { DisplayMode as DisplayMode1 } from "./components/shell-panel/interfaces"; import { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; -export { ModalMessages } from "./components/modal/assets/modal/t9n"; -export { NoticeMessages } from "./components/notice/assets/notice/t9n"; -export { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; -export { PanelMessages } from "./components/panel/assets/panel/t9n"; import { DragDetail } from "./utils/sortableComponent"; import { StepperItemChangeEventDetail, StepperItemEventDetail, StepperItemKeyEventDetail, StepperLayout } from "./components/stepper/interfaces"; -export { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; -export { PopoverMessages } from "./components/popover/assets/popover/t9n"; -export { RatingMessages } from "./components/rating/assets/rating/t9n"; -export { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; import { StepperMessages } from "./components/stepper/assets/stepper/t9n"; import { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; -export { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; import { TabID, TabLayout, TabPosition } from "./components/tabs/interfaces"; import { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; -export { StepperMessages } from "./components/stepper/assets/stepper/t9n"; -export { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; import { TabChangeEventDetail, TabCloseEventDetail } from "./components/tab/interfaces"; -export { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; import { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; -export { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; import { RowType, TableInteractionMode, TableLayout, TableRowFocusEvent } from "./components/table/interfaces"; -export { TableMessages } from "./components/table/assets/table/t9n"; -export { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; -export { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; -export { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; import { TableMessages } from "./components/table/assets/table/t9n"; import { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; -export { TipMessages } from "./components/tip/assets/tip/t9n"; -export { TipManagerMessages } from "./components/tip-manager/assets/tip-manager/t9n"; import { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; -export { ValueListMessages } from "./components/value-list/assets/value-list/t9n"; import { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; import { TileSelectType } from "./components/tile-select/interfaces"; import { TileSelectGroupLayout } from "./components/tile-select-group/interfaces"; diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index fa95aadf0df..8b0f6221d43 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -1438,7 +1438,7 @@ describe("calcite-input-date-picker", () => { await page.keyboard.press("Enter"); await page.waitForChanges(); - expect(await calendar.isVisible()).toBe(false); + expect(await calendar.isVisible()).toBe(true); expect(await getActiveMonth(page)).toBe("February"); }); @@ -1454,11 +1454,11 @@ describe("calcite-input-date-picker", () => { }); const inputDatePicker = await page.find("calcite-input-date-picker"); - const [inputStart, inputEnd] = await page.findAll("calcite-input-date-picker >>> calcite-input-text"); + const input = await page.find("calcite-input-date-picker >>> calcite-input-text"); const calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(false); - await inputStart.click(); + await input.click(); expect(await calendar.isVisible()).toBe(true); await page.keyboard.press("Tab"); @@ -1469,6 +1469,12 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); await page.keyboard.press("Tab"); await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Tab"); + await page.waitForChanges(); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); @@ -1477,20 +1483,9 @@ describe("calcite-input-date-picker", () => { await page.keyboard.press("Enter"); await page.waitForChanges(); - expect(await calendar.isVisible()).toBe(false); - expect(await inputDatePicker.getProperty("value")).toEqual(["2023-11-25", "2024-02-10"]); - - await inputEnd.click(); expect(await calendar.isVisible()).toBe(true); + expect(await inputDatePicker.getProperty("value")).toEqual(["2023-11-25", "2024-02-10"]); - await page.keyboard.press("Tab"); - await page.waitForChanges(); - await page.keyboard.press("Tab"); - await page.waitForChanges(); - await page.keyboard.press("Tab"); - await page.waitForChanges(); - await page.keyboard.press("Tab"); - await page.waitForChanges(); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); expect(await calendar.isVisible()).toBe(true); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts index d481b2c1e9c..5affe9a3043 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts @@ -26,6 +26,12 @@ export const simple = (): string => html` `; export const range = (): string => html` +
+ +`; + +export const rangeWithMinMax = (): string => html`
Date: Fri, 3 May 2024 18:02:23 -0500 Subject: [PATCH 075/155] clean up --- .../calcite-components/src/components.d.ts | 56 ++++++++++---- .../date-picker-month-header.tsx | 77 +++++++++---------- .../date-picker-month/date-picker-month.tsx | 75 +++++++++--------- .../components/date-picker/date-picker.tsx | 16 ++-- .../input-date-picker/input-date-picker.tsx | 19 +---- 5 files changed, 127 insertions(+), 116 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 7e293740802..3d3e58b70b2 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -24,6 +24,7 @@ import { ButtonAlignment, DropdownIconType } from "./components/button/interface import { ButtonMessages } from "./components/button/assets/button/t9n"; import { CardMessages } from "./components/card/assets/card/t9n"; import { ArrowType, AutoplayType } from "./components/carousel/interfaces"; +import { CarouselMessages } from "./components/carousel/assets/carousel/t9n"; import { MutableValidityState } from "./utils/form"; import { ChipMessages } from "./components/chip/assets/chip/t9n"; import { ColorValue, InternalColor } from "./components/color-picker/interfaces"; @@ -113,6 +114,7 @@ export { ButtonAlignment, DropdownIconType } from "./components/button/interface export { ButtonMessages } from "./components/button/assets/button/t9n"; export { CardMessages } from "./components/card/assets/card/t9n"; export { ArrowType, AutoplayType } from "./components/carousel/interfaces"; +export { CarouselMessages } from "./components/carousel/assets/carousel/t9n"; export { MutableValidityState } from "./utils/form"; export { ChipMessages } from "./components/chip/assets/chip/t9n"; export { ColorValue, InternalColor } from "./components/color-picker/interfaces"; @@ -1560,8 +1562,13 @@ export namespace Components { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min": Date; + /** + * When `true`, month will be abbreviated. + */ "monthAbbreviations": boolean; - "position": "start" | "end"; + /** + * When `true`, activates the component's range mode which renders two calendars for selecting ranges of dates. + */ "range": boolean; /** * Specifies the size of the component. @@ -1602,7 +1609,13 @@ export namespace Components { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min": Date; + /** + * When `true`, month will be abbreviated. + */ "monthAbbreviations": boolean; + /** + * Specifies the position of the component in a range date-picker. + */ "position": "start" | "end"; /** * Specifies the size of the component. @@ -2273,6 +2286,9 @@ export namespace Components { * Specifies the earliest allowed date as a full date object. */ "minAsDate": Date; + /** + * When `true`, month will be abbreviated. + */ "monthAbbreviations": boolean; /** * Specifies the name of the component. Required to pass the component's `value` on form submission. @@ -6383,10 +6399,10 @@ declare global { new (): HTMLCalciteDatePickerDayElement; }; interface HTMLCalciteDatePickerMonthElementEventMap { - "calciteInternalDatePickerSelect": Date; - "calciteInternalDatePickerHover": Date; - "calciteInternalDatePickerActiveDateChange": Date; - "calciteInternalDatePickerMouseOut": void; + "calciteInternalDatePickerDaySelect": Date; + "calciteInternalDatePickerDayHover": Date; + "calciteInternalDatePickerMonthActiveDateChange": Date; + "calciteInternalDatePickerMonthMouseOut": void; "calciteInternalDatePickerMonthChange": { date: Date; position: string; @@ -9265,15 +9281,22 @@ declare namespace LocalJSX { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min"?: Date; - "monthAbbreviations"?: boolean; /** - * Active date for the user keyboard access. + * When `true`, month will be abbreviated. */ - "onCalciteInternalDatePickerActiveDateChange"?: (event: CalciteDatePickerMonthCustomEvent) => void; + "monthAbbreviations"?: boolean; /** * Fires when user hovers the date. */ - "onCalciteInternalDatePickerHover"?: (event: CalciteDatePickerMonthCustomEvent) => void; + "onCalciteInternalDatePickerDayHover"?: (event: CalciteDatePickerMonthCustomEvent) => void; + /** + * Fires when user selects the date. + */ + "onCalciteInternalDatePickerDaySelect"?: (event: CalciteDatePickerMonthCustomEvent) => void; + /** + * Active date for the user keyboard access. + */ + "onCalciteInternalDatePickerMonthActiveDateChange"?: (event: CalciteDatePickerMonthCustomEvent) => void; /** * Emits when user updates month or year using `calcite-date-picker-month-header` component. */ @@ -9281,12 +9304,10 @@ declare namespace LocalJSX { date: Date; position: string; }>) => void; - "onCalciteInternalDatePickerMouseOut"?: (event: CalciteDatePickerMonthCustomEvent) => void; + "onCalciteInternalDatePickerMonthMouseOut"?: (event: CalciteDatePickerMonthCustomEvent) => void; /** - * Fires when user selects the date. + * When `true`, activates the component's range mode which renders two calendars for selecting ranges of dates. */ - "onCalciteInternalDatePickerSelect"?: (event: CalciteDatePickerMonthCustomEvent) => void; - "position"?: "start" | "end"; "range"?: boolean; /** * Specifies the size of the component. @@ -9327,11 +9348,17 @@ declare namespace LocalJSX { * Specifies the earliest allowed date (`"yyyy-mm-dd"`). */ "min"?: Date; + /** + * When `true`, month will be abbreviated. + */ "monthAbbreviations"?: boolean; /** * Fires to active date */ "onCalciteInternalDatePickerMonthHeaderSelect"?: (event: CalciteDatePickerMonthHeaderCustomEvent) => void; + /** + * Specifies the position of the component in a range date-picker. + */ "position"?: "start" | "end"; /** * Specifies the size of the component. @@ -10018,6 +10045,9 @@ declare namespace LocalJSX { * Specifies the earliest allowed date as a full date object. */ "minAsDate"?: Date; + /** + * When `true`, month will be abbreviated. + */ "monthAbbreviations"?: boolean; /** * Specifies the name of the component. Required to pass the component's `value` on form submission. diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index 35819ffa451..f70684fb0bc 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -74,11 +74,18 @@ export class DatePickerMonthHeader { // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module @Prop({ mutable: true }) messages: DatePickerMessages; - /** @internal */ - @Prop() position: "start" | "end"; - + /** + * When `true`, month will be abbreviated. + */ @Prop() monthAbbreviations: boolean; + /** + * Specifies the position of the component in a range date-picker. + * @internal + * + */ + @Prop() position: "start" | "end"; + //-------------------------------------------------------------------------- // // Events @@ -113,7 +120,7 @@ export class DatePickerMonthHeader { } renderContent(): VNode { - const { messages, localeData, activeDate } = this; + const { localeData, activeDate } = this; if (!activeDate || !localeData) { return null; } @@ -135,45 +142,16 @@ export class DatePickerMonthHeader { return ( - {this.position !== "end" && ( - + {this.position === "start" && ( +
{this.renderChevron("left")}
)}
{this.renderMonthPicker(months, activeMonth)} {this.renderYearPicker()}
+ {!this.position &&
{this.renderChevron("left")}
} {this.position !== "start" && ( -
- - - -
+
{this.renderChevron("right")}
)}
); @@ -217,6 +195,28 @@ export class DatePickerMonthHeader { ); } + private renderChevron(direction: "left" | "right"): VNode { + const activeMonth = this.activeDate.getMonth(); + return ( + + + + ); + } + private getYearList(): void { this.yearList = []; for (let i = this.min?.getFullYear() || 1900; i <= (this.max?.getFullYear() || 2100); i++) { @@ -345,7 +345,6 @@ export class DatePickerMonthHeader { commit?: boolean; offset?: number; }): void { - const { activeDate } = this; const inRangeDate = this.getInRangeDate({ localizedYear, offset }); // if you've supplied a year and it's in range, update active date @@ -355,7 +354,7 @@ export class DatePickerMonthHeader { if (commit) { this.yearPickerEl.value = formatCalendarYear( - (inRangeDate || activeDate).getFullYear(), + (inRangeDate || this.activeDate).getFullYear(), this.localeData, ).toString(); } diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index aae4df13ee3..e6694e90b93 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -85,9 +85,9 @@ export class DatePickerMonth { /** Specifies the latest allowed date (`"yyyy-mm-dd"`). */ @Prop() max: Date; - /** @internal */ - @Prop() position: "start" | "end"; - + /** + * When `true`, activates the component's range mode which renders two calendars for selecting ranges of dates. + */ @Prop({ reflect: true }) range: boolean; /** Specifies the size of the component. */ @@ -111,6 +111,9 @@ export class DatePickerMonth { // eslint-disable-next-line @stencil-community/strict-mutable -- updated by t9n module @Prop({ mutable: true }) messages: DatePickerMessages; + /** + * When `true`, month will be abbreviated. + */ @Prop() monthAbbreviations: boolean; /** @@ -129,26 +132,26 @@ export class DatePickerMonth { * * @internal */ - @Event({ cancelable: false }) calciteInternalDatePickerSelect: EventEmitter; + @Event({ cancelable: false }) calciteInternalDatePickerDaySelect: EventEmitter; /** * Fires when user hovers the date. * * @internal */ - @Event({ cancelable: false }) calciteInternalDatePickerHover: EventEmitter; + @Event({ cancelable: false }) calciteInternalDatePickerDayHover: EventEmitter; /** * Active date for the user keyboard access. * * @internal */ - @Event({ cancelable: false }) calciteInternalDatePickerActiveDateChange: EventEmitter; + @Event({ cancelable: false }) calciteInternalDatePickerMonthActiveDateChange: EventEmitter; /** * @internal */ - @Event({ cancelable: false }) calciteInternalDatePickerMouseOut: EventEmitter; + @Event({ cancelable: false }) calciteInternalDatePickerMonthMouseOut: EventEmitter; /** * Emits when user updates month or year using `calcite-date-picker-month-header` component. @@ -160,8 +163,15 @@ export class DatePickerMonth { position: string; }>; - /** The currently focused Date. */ + //-------------------------------------------------------------------------- + // + // Private State/Props + // + //-------------------------------------------------------------------------- + + /**current focused date */ @State() focusedDate: Date; + //-------------------------------------------------------------------------- // // Event Listeners @@ -174,43 +184,43 @@ export class DatePickerMonth { } const isRTL = this.el.dir === "rtl"; - const target = event.target as HTMLCalciteDatePickerDayElement; + const dateValue = (event.target as HTMLCalciteDatePickerDayElement).value; switch (event.key) { case "ArrowUp": event.preventDefault(); - this.addDays(-7, target.value); + this.addDays(-7, dateValue); break; case "ArrowRight": event.preventDefault(); - this.addDays(isRTL ? -1 : 1, target.value); + this.addDays(isRTL ? -1 : 1, dateValue); break; case "ArrowDown": event.preventDefault(); - this.addDays(7, target.value); + this.addDays(7, dateValue); break; case "ArrowLeft": event.preventDefault(); - this.addDays(isRTL ? 1 : -1, target.value); + this.addDays(isRTL ? 1 : -1, dateValue); break; case "PageUp": event.preventDefault(); - this.addMonths(-1, target.value); + this.addMonths(-1, dateValue); break; case "PageDown": event.preventDefault(); - this.addMonths(1, target.value); + this.addMonths(1, dateValue); break; case "Home": event.preventDefault(); this.activeDate.setDate(1); - this.addDays(0, target.value); + this.addDays(0, dateValue); break; case "End": event.preventDefault(); this.activeDate.setDate( new Date(this.activeDate.getFullYear(), this.activeDate.getMonth() + 1, 0).getDate(), ); - this.addDays(0, target.value); + this.addDays(0, dateValue); break; case "Enter": case " ": @@ -231,7 +241,7 @@ export class DatePickerMonth { @Listen("pointerout") pointerOutHandler(): void { - this.calciteInternalDatePickerMouseOut.emit(); + this.calciteInternalDatePickerMonthMouseOut.emit(); } //-------------------------------------------------------------------------- @@ -258,9 +268,7 @@ export class DatePickerMonth { const endCalendarPrevMonDays = this.getPreviousMonthDays(month + 1, year, startOfWeek); const endCalendarCurrMonDays = this.getCurrentMonthDays(month + 1, year); const endCalendarNextMonDays = this.getNextMonthDays(month + 1, year, startOfWeek); - const days = this.getDays(prevMonDays, curMonDays, nextMonDays); - // const weeks = this.getWeeks(days); const nextMonthDays = this.getDays( endCalendarPrevMonDays, @@ -268,7 +276,6 @@ export class DatePickerMonth { endCalendarNextMonDays, "end", ); - // const nextMonthWeeks = this.getWeeks(nextMonthDays); return ( @@ -334,12 +341,12 @@ export class DatePickerMonth { private addMonths(step: number, targetDate: Date) { const nextDate = new Date(targetDate); nextDate.setMonth(targetDate.getMonth() + step); - this.calciteInternalDatePickerActiveDateChange.emit( + this.calciteInternalDatePickerMonthActiveDateChange.emit( dateFromRange(nextDate, this.min, this.max), ); this.focusedDate = dateFromRange(nextDate, this.min, this.max); this.activeFocus = true; - this.calciteInternalDatePickerHover.emit(nextDate); + this.calciteInternalDatePickerDayHover.emit(nextDate); } /** @@ -351,14 +358,13 @@ export class DatePickerMonth { private addDays(step = 0, targetDate: Date) { const nextDate = new Date(targetDate); nextDate.setDate(targetDate.getDate() + step); - this.calciteInternalDatePickerActiveDateChange.emit( + this.calciteInternalDatePickerMonthActiveDateChange.emit( dateFromRange(nextDate, this.min, this.max), ); this.focusedDate = dateFromRange(nextDate, this.min, this.max); this.activeFocus = true; - // adds hover effect on keyboard navigation - this.calciteInternalDatePickerHover.emit(nextDate); + this.calciteInternalDatePickerDayHover.emit(nextDate); } /** @@ -477,18 +483,17 @@ export class DatePickerMonth { dayHover = (event: CustomEvent): void => { const target = event.target as HTMLCalciteDatePickerDayElement; if (target.disabled) { - this.calciteInternalDatePickerMouseOut.emit(); + this.calciteInternalDatePickerMonthMouseOut.emit(); } else { - this.calciteInternalDatePickerHover.emit(target.value); + this.calciteInternalDatePickerDayHover.emit(target.value); } event.stopPropagation(); }; daySelect = (event: CustomEvent): void => { const target = event.target as HTMLCalciteDatePickerDayElement; - // below line needs to be commented out to focus on active date on based on focused input this.activeFocus = false; - this.calciteInternalDatePickerSelect.emit(target.value); + this.calciteInternalDatePickerDaySelect.emit(target.value); }; /** @@ -539,7 +544,6 @@ export class DatePickerMonth { selected={this.isSelected(date)} startOfRange={this.isStartOfRange(date)} value={date} - // focusing in ref is creating diff UX for keyboard compared to click where in click the focus only shifts after selection where in keyboard while navigating the focus is updated. // eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530) ref={(el: HTMLCalciteDatePickerDayElement) => { // when moving via keyboard, focus must be updated on active date @@ -659,14 +663,6 @@ export class DatePickerMonth { return days; }; - // private getWeeks(days: Day[]): Day[][] { - // const weeks: Day[][] = []; - // for (let i = 0; i < days.length; i += 7) { - // weeks.push(days.slice(i, i + 7)); - // } - // return weeks; - // } - private renderMonthCalendar(weekDays: string[], days: Day[], isNextMonth = false): VNode { return (
@@ -692,7 +688,6 @@ export class DatePickerMonth { this.calciteInternalDatePickerMonthChange.emit({ date, position: target.position }); }; - // updates focusable date on monthHeaderSelectChange private updateFocusableDate(date: Date): void { if (!this.selectedDate || !this.range) { this.focusedDate = date; diff --git a/packages/calcite-components/src/components/date-picker/date-picker.tsx b/packages/calcite-components/src/components/date-picker/date-picker.tsx index 0566a7bc423..5a7a4e65ad0 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.tsx +++ b/packages/calcite-components/src/components/date-picker/date-picker.tsx @@ -104,7 +104,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom valueHandler(value: string | string[]): void { if (Array.isArray(value)) { this.valueAsDate = getValueAsDateRange(value); - // avoids updating activeDates after every selection. Update of activeDate's happen when user parses value programmatically + // avoids updating activeDates after every selection. Only updates when value is set programmatically. if (!this.userChangeRangeValue) { this.resetActiveDates(); } @@ -131,8 +131,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom } /** Specifies the earliest allowed date as a full date object (`new Date("yyyy-mm-dd")`). */ - @Prop({ mutable: true }) - minAsDate: Date; + @Prop({ mutable: true }) minAsDate: Date; /** Specifies the latest allowed date as a full date object (`new Date("yyyy-mm-dd")`). */ @Prop({ mutable: true }) maxAsDate: Date; @@ -282,7 +281,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom this.maxAsDate, ); const activeDate = this.getActiveDate(date, this.minAsDate, this.maxAsDate); - const endDate = this.range && Array.isArray(this.valueAsDate) ? dateFromRange(this.valueAsDate[1], this.minAsDate, this.maxAsDate) @@ -381,7 +379,6 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom monthHeaderSelectChange = (event: CustomEvent<{ date: Date; position: string }>): void => { const date = new Date(event.detail.date); const position = event.detail.position; - if (!this.range) { this.activeDate = date; } else { @@ -536,11 +533,11 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom messages={this.messages} min={minDate} monthAbbreviations={this.monthAbbreviations} - onCalciteInternalDatePickerActiveDateChange={this.monthActiveDateChange} - onCalciteInternalDatePickerHover={this.monthHoverChange} + onCalciteInternalDatePickerDayHover={this.monthHoverChange} + onCalciteInternalDatePickerDaySelect={this.monthDateChange} + onCalciteInternalDatePickerMonthActiveDateChange={this.monthActiveDateChange} onCalciteInternalDatePickerMonthChange={this.monthHeaderSelectChange} - onCalciteInternalDatePickerMouseOut={this.monthMouseOutChange} - onCalciteInternalDatePickerSelect={this.monthDateChange} + onCalciteInternalDatePickerMonthMouseOut={this.monthMouseOutChange} range={this.range} scale={this.scale} selectedDate={this.activeRange === "end" ? endDate || date : date} @@ -601,6 +598,7 @@ export class DatePicker implements LocalizedComponent, LoadableComponent, T9nCom private monthDateChange = (event: CustomEvent): void => { const date = new Date(event.detail); const isoDate = dateToISO(date); + if (!this.range && isoDate === dateToISO(this.valueAsDate as Date)) { return; } diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index a68aad88c5d..37c1e1b69bf 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -256,6 +256,9 @@ export class InputDatePicker } } + /** + * When `true`, month will be abbreviated. + */ @Prop() monthAbbreviations: boolean = false; /** When `true`, displays the `calcite-date-picker` component. */ @@ -364,11 +367,7 @@ export class InputDatePicker @Listen("calciteDaySelect") calciteDaySelectHandler(): void { - if ( - this.shouldFocusRangeStart() || - // this.shouldFocusRangeEnd() || - this.rangeStartValueChangedByUser - ) { + if (this.shouldFocusRangeStart() || this.rangeStartValueChangedByUser) { return; } @@ -768,8 +767,6 @@ export class InputDatePicker transitionEl: HTMLDivElement; @Watch("layout") - // no need for re-opening of the date-picker. closes only on espace or value/end-value selection in range. - // @Watch("focusedInput") setReferenceEl(): void { const { focusedInput, layout, endWrapper, startWrapper } = this; @@ -851,8 +848,6 @@ export class InputDatePicker onClose(): void { this.calciteInputDatePickerClose.emit(); deactivateFocusTrap(this); - //should we restore the focus when user clicks outside? - //this.restoreInputFocus(); this.focusOnOpen = false; this.datePickerEl.reset(); } @@ -1052,12 +1047,6 @@ export class InputDatePicker const focusedInput = this.focusedInput === "start" ? this.startInput : this.endInput; focusedInput.setFocus(); } - - // const focusedInput = restore && this.focusedInput === "start" ? this.startInput : this.endInput; - // focusedInput.setFocus(); - - //avoids delay in updating focusedInput value while the `blur` handler in `date-picker` causing update in activeDate's. - // this.focusedInput = restore && this.focusedInput === "start" ? "start" : "end"; } private localizeInputValues(): void { From a1f53053ab26ca0aa3e6eeadfada52706565d4d8 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Mon, 6 May 2024 11:20:11 -0500 Subject: [PATCH 076/155] refactor test utils --- .../components/date-picker/date-picker.e2e.ts | 128 ++++++--------- .../input-date-picker.e2e.ts | 148 +++++++++--------- 2 files changed, 119 insertions(+), 157 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts index 730b7b895e7..9c895ff2b63 100644 --- a/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts +++ b/packages/calcite-components/src/components/date-picker/date-picker.e2e.ts @@ -4,6 +4,34 @@ import { defaults, focusable, hidden, renders, t9n } from "../../tests/commonTes import { skipAnimations } from "../../tests/utils"; import { formatTimePart } from "../../utils/time"; +async function selectDayInMonthById(id: string, page: E2EPage): Promise { + const day = await page.find( + `calcite-date-picker>>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`, + ); + await day.click(); + await page.waitForChanges(); +} + +async function selectFirstAvailableDay(page: E2EPage): Promise { + const day = await page.find( + "calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day:not([selected])", + ); + await day.click(); + await page.waitForChanges(); +} + +async function selectSelectedDay(page: E2EPage): Promise { + const day = await page.find( + "calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[selected]", + ); + await day.click(); + await page.waitForChanges(); +} + +async function getDayById(page: E2EPage, id: string): Promise { + return await page.find(`calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`); +} + describe("calcite-date-picker", () => { describe("renders", () => { renders("calcite-date-picker", { display: "inline-block" }); @@ -58,10 +86,10 @@ describe("calcite-date-picker", () => { await page.waitForTimeout(animationDurationInMs); - await selectFirstAvailableDay(page, "mouse"); + await selectFirstAvailableDay(page); expect(changedEvent).toHaveReceivedEventTimes(1); - await selectFirstAvailableDay(page, "keyboard"); + await selectFirstAvailableDay(page); expect(changedEvent).toHaveReceivedEventTimes(2); }); @@ -79,12 +107,12 @@ describe("calcite-date-picker", () => { const startDate = `${currentYear}-${formatTimePart(currentMonth)}-01`; const endDate = `${currentYear}-${formatTimePart(currentMonth)}-15`; - await selectDay(startDate.replaceAll("-", ""), page, "mouse"); + await selectDayInMonthById(startDate.replaceAll("-", ""), page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, ""]); - await selectDay(endDate.replaceAll("-", ""), page, "mouse"); + await selectDayInMonthById(endDate.replaceAll("-", ""), page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, endDate]); @@ -105,12 +133,12 @@ describe("calcite-date-picker", () => { const startDate = `${currentYear}-${formatTimePart(currentMonth)}-01`; const endDate = `${currentYear}-${formatTimePart(currentMonth)}-15`; - await selectDay(startDate.replaceAll("-", ""), page, "mouse"); + await selectDayInMonthById(startDate.replaceAll("-", ""), page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, ""]); - await selectDay(endDate.replaceAll("-", ""), page, "mouse"); + await selectDayInMonthById(endDate.replaceAll("-", ""), page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual([startDate, endDate]); @@ -124,18 +152,18 @@ describe("calcite-date-picker", () => { await skipAnimations(page); - await selectSelectedDay(page, "mouse"); + await selectSelectedDay(page); expect(changedEvent).toHaveReceivedEventTimes(0); - await selectSelectedDay(page, "mouse"); + await selectSelectedDay(page); expect(changedEvent).toHaveReceivedEventTimes(0); - await selectSelectedDay(page, "mouse"); + await selectSelectedDay(page); expect(changedEvent).toHaveReceivedEventTimes(0); - await selectSelectedDay(page, "keyboard"); + await selectSelectedDay(page); expect(changedEvent).toHaveReceivedEventTimes(0); - await selectSelectedDay(page, "keyboard"); + await selectSelectedDay(page); expect(changedEvent).toHaveReceivedEventTimes(0); - await selectSelectedDay(page, "keyboard"); + await selectSelectedDay(page); expect(changedEvent).toHaveReceivedEventTimes(0); }); @@ -147,64 +175,6 @@ describe("calcite-date-picker", () => { await page.waitForChanges(); } - async function selectDay(id: string, page: E2EPage, method: "mouse" | "keyboard"): Promise { - await page.$eval( - "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement, id: string, method: "mouse" | "keyboard") => { - const day = datePicker.shadowRoot - .querySelector("calcite-date-picker-month") - .shadowRoot.getElementById(id); - - if (method === "mouse") { - day.click(); - } else { - day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); - } - }, - id, - method, - ); - await page.waitForChanges(); - } - - async function selectFirstAvailableDay(page: E2EPage, method: "mouse" | "keyboard"): Promise { - await page.$eval( - "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement, method: "mouse" | "keyboard") => { - const day = datePicker.shadowRoot - .querySelector("calcite-date-picker-month") - .shadowRoot.querySelector("calcite-date-picker-day:not([selected])"); - - if (method === "mouse") { - day.click(); - } else { - day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); - } - }, - method, - ); - await page.waitForChanges(); - } - - async function selectSelectedDay(page: E2EPage, method: "mouse" | "keyboard"): Promise { - await page.$eval( - "calcite-date-picker", - (datePicker: HTMLCalciteDatePickerElement, method: "mouse" | "keyboard") => { - const day = datePicker.shadowRoot - .querySelector("calcite-date-picker-month") - .shadowRoot.querySelector("calcite-date-picker-day[selected]"); - - if (method === "mouse") { - day.click(); - } else { - day.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); - } - }, - method, - ); - await page.waitForChanges(); - } - it("doesn't fire calciteDatePickerChange on outside changes to value", async () => { const page = await newE2EPage(); await page.setContent(""); @@ -531,29 +501,23 @@ describe("calcite-date-picker", () => { ); const datePicker = await page.find("calcite-date-picker"); - await selectDay("20200908", page, "mouse"); + await selectDayInMonthById("20200908", page); await page.waitForChanges(); - await selectDay("20200923", page, "mouse"); + await selectDayInMonthById("20200923", page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual(["2020-09-08", "2020-09-23"]); - await selectDay("20200915", page, "mouse"); + await selectDayInMonthById("20200915", page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual(["2020-09-15", ""]); - await selectDay("20200930", page, "mouse"); + await selectDayInMonthById("20200930", page); await page.waitForChanges(); expect(await datePicker.getProperty("value")).toEqual(["2020-09-15", "2020-09-30"]); }); //todo: refactor to storybook tests describe("hover range", () => { - async function getDayById(page: E2EPage, id: string): Promise { - return await page.find( - `calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`, - ); - } - it("should toggle range-hover attribute when updating the range", async () => { const page = await newE2EPage(); await page.setContent(html``); @@ -610,7 +574,7 @@ describe("calcite-date-picker", () => { await startDate.hover(); await page.waitForChanges(); - await selectDay("20240108", page, "mouse"); + await selectDayInMonthById("20240108", page); await page.waitForChanges(); expect(await (await getDayById(page, "20240107")).getProperty("rangeHover")).toBeFalsy(); expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBeFalsy(); @@ -622,7 +586,7 @@ describe("calcite-date-picker", () => { expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBeFalsy(); expect(await (await getDayById(page, "20240201")).getProperty("rangeHover")).toBe(true); - await selectDay("20240205", page, "mouse"); + await selectDayInMonthById("20240205", page); await page.waitForChanges(); expect(await (await getDayById(page, "20240107")).getProperty("rangeHover")).toBeFalsy(); expect(await (await getDayById(page, "20240209")).getProperty("rangeHover")).toBeFalsy(); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index 8b0f6221d43..d53e5862fa5 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -16,6 +16,63 @@ import { getFocusedElementProp, skipAnimations } from "../../tests/utils"; import { CSS } from "./resources"; const animationDurationInMs = 200; +async function selectDayInMonthByIndex(page: E2EPage, day: number): Promise { + const dayIndex = day - 1; + const days = await page.findAll("calcite-input-date-picker >>> calcite-date-picker-day[current-month]"); + await days[dayIndex].click(); + await page.waitForChanges(); +} + +async function getActiveMonth(page: E2EPage): Promise { + return page.evaluate( + async () => + document + .querySelector("calcite-input-date-picker") + .shadowRoot.querySelector("calcite-date-picker") + .shadowRoot.querySelector("calcite-date-picker-month") + .shadowRoot.querySelector("calcite-date-picker-month-header") + .shadowRoot.querySelector("calcite-select") + .querySelector("calcite-option[selected]").textContent, + ); +} + +async function getDateInputValue(page: E2EPage, type: "start" | "end" = "start"): Promise { + const inputIndex = type === "start" ? 0 : 1; + + return page.evaluate( + async (inputIndex: number): Promise => + document + .querySelector("calcite-input-date-picker") + .shadowRoot.querySelectorAll("calcite-input-text") + [inputIndex].shadowRoot.querySelector("input").value, + inputIndex, + ); +} + +async function navigateMonth(page: E2EPage, direction: "previous" | "next", range = false): Promise { + const [datePickerMonthHeaderStart, datePickerMonthHeaderEnd] = await page.findAll( + "calcite-input-date-picker >>> calcite-date-picker-month-header >>> .header", + ); + + let prevMonth: E2EElement; + let nextMonth: E2EElement; + if (range) { + prevMonth = await datePickerMonthHeaderStart.find("a"); + nextMonth = await datePickerMonthHeaderEnd.find("a"); + } else { + [prevMonth, nextMonth] = await datePickerMonthHeaderStart.findAll("a"); + } + + await (direction === "previous" ? prevMonth.click() : nextMonth.click()); + await page.waitForChanges(); +} + +async function getDayById(page: E2EPage, id: string): Promise { + return await page.find( + `calcite-input-date-picker >>> calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`, + ); +} + describe("calcite-input-date-picker", () => { describe("accessibility", () => { accessible(html` @@ -73,57 +130,6 @@ describe("calcite-input-date-picker", () => { it.skip("supports t9n", () => t9n("calcite-input-date-picker")); - async function navigateMonth(page: E2EPage, direction: "previous" | "next", range = false): Promise { - const [datePickerMonthHeaderStart, datePickerMonthHeaderEnd] = await page.findAll( - "calcite-input-date-picker >>> calcite-date-picker-month-header >>> .header", - ); - - let prevMonth: E2EElement; - let nextMonth: E2EElement; - if (range) { - prevMonth = await datePickerMonthHeaderStart.find("a"); - nextMonth = await datePickerMonthHeaderEnd.find("a"); - } else { - [prevMonth, nextMonth] = await datePickerMonthHeaderStart.findAll("a"); - } - - await (direction === "previous" ? prevMonth.click() : nextMonth.click()); - await page.waitForChanges(); - } - - async function selectDayInMonth(page: E2EPage, day: number): Promise { - const dayIndex = day - 1; - const days = await page.findAll("calcite-input-date-picker >>> calcite-date-picker-day[current-month]"); - await days[dayIndex].click(); - await page.waitForChanges(); - } - - async function getActiveMonth(page: E2EPage): Promise { - return page.evaluate( - async () => - document - .querySelector("calcite-input-date-picker") - .shadowRoot.querySelector("calcite-date-picker") - .shadowRoot.querySelector("calcite-date-picker-month") - .shadowRoot.querySelector("calcite-date-picker-month-header") - .shadowRoot.querySelector("calcite-select") - .querySelector("calcite-option[selected]").textContent, - ); - } - - async function getDateInputValue(page: E2EPage, type: "start" | "end" = "start"): Promise { - const inputIndex = type === "start" ? 0 : 1; - - return page.evaluate( - async (inputIndex: number): Promise => - document - .querySelector("calcite-input-date-picker") - .shadowRoot.querySelectorAll("calcite-input-text") - [inputIndex].shadowRoot.querySelector("input").value, - inputIndex, - ); - } - describe("event emitting when the value changes", () => { it("emits change event when value is committed for single date", async () => { const page = await newE2EPage(); @@ -293,7 +299,7 @@ describe("calcite-input-date-picker", () => { await inputDatePickerEl.click(); await page.waitForChanges(); - await selectDayInMonth(page, 28); + await selectDayInMonthByIndex(page, 28); await page.waitForChanges(); expect(await inputDatePickerEl.getProperty("value")).toEqual("2023-06-28"); @@ -415,7 +421,6 @@ describe("calcite-input-date-picker", () => { ); // toggling via start date input - await resetFocus(page); await startInput.click(); await page.waitForChanges(); @@ -428,7 +433,6 @@ describe("calcite-input-date-picker", () => { expect(await isCalendarVisible(calendar, "start")).toBe(false); // toggling via end date input - await resetFocus(page); await endInput.click(); await page.waitForChanges(); @@ -619,7 +623,7 @@ describe("calcite-input-date-picker", () => { await inputDatePicker.click(); await calciteInputDatePickerOpenEvent; - await selectDayInMonth(page, 1); + await selectDayInMonthByIndex(page, 1); await inputDatePicker.callMethod("blur"); expect(await inputDatePicker.getProperty("value")).toBe("2023-05-01"); @@ -634,7 +638,7 @@ describe("calcite-input-date-picker", () => { await inputDatePicker.click(); await page.waitForChanges(); - await selectDayInMonth(page, 1); + await selectDayInMonthByIndex(page, 1); expect(await inputDatePicker.getProperty("value")).toBe("2023-01-01"); }); @@ -997,14 +1001,14 @@ describe("calcite-input-date-picker", () => { expect(await calendar.isVisible()).toBe(true); await navigateMonth(page, "previous"); - await selectDayInMonth(page, 1); + await selectDayInMonthByIndex(page, 1); expect(await calendar.isVisible()).toBe(true); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(true); await navigateMonth(page, "previous"); - await selectDayInMonth(page, 31); + await selectDayInMonthByIndex(page, 31); calendar = await page.find(`calcite-input-date-picker >>> .${CSS.calendarWrapper}`); expect(await calendar.isVisible()).toBe(false); @@ -1114,11 +1118,11 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 1); + await selectDayInMonthByIndex(page, 1); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 32); + await selectDayInMonthByIndex(page, 32); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); @@ -1138,11 +1142,11 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 35); + await selectDayInMonthByIndex(page, 35); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 52); + await selectDayInMonthByIndex(page, 52); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); @@ -1162,11 +1166,11 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 5); + await selectDayInMonthByIndex(page, 5); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 22); + await selectDayInMonthByIndex(page, 22); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); expect(await inputDatePicker.getProperty("value")).not.toBeNull(); @@ -1184,10 +1188,10 @@ describe("calcite-input-date-picker", () => { await startDatePicker.click(); await page.waitForChanges(); - await selectDayInMonth(page, 1); + await selectDayInMonthByIndex(page, 1); await page.waitForChanges(); - await selectDayInMonth(page, 32); + await selectDayInMonthByIndex(page, 32); await page.waitForChanges(); await startDatePicker.click(); @@ -1202,7 +1206,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 1); + await selectDayInMonthByIndex(page, 1); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); @@ -1210,7 +1214,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 32); + await selectDayInMonthByIndex(page, 32); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(false); }); @@ -1261,7 +1265,7 @@ describe("calcite-input-date-picker", () => { await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); - await selectDayInMonth(page, 60); + await selectDayInMonthByIndex(page, 60); await page.waitForChanges(); expect(await isCalendarVisible(page)).toBe(true); @@ -1321,12 +1325,6 @@ describe("calcite-input-date-picker", () => { //todo: refactor to storybook tests describe("hover range", () => { - async function getDayById(page: E2EPage, id: string): Promise { - return await page.find( - `calcite-input-date-picker >>> calcite-date-picker >>> calcite-date-picker-month >>> calcite-date-picker-day[id="${id}"]`, - ); - } - it("should add range-hover attribute for dates less than new startDate and greater than current startDate or greater than new endDate and less than current startDate", async () => { const page = await newE2EPage(); await page.setContent(html``); From b92066f5b60ff99604399b7f770e773db0bf8ff5 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Tue, 7 May 2024 12:07:55 -0500 Subject: [PATCH 077/155] remove overlapping dates in range calendar --- .../date-picker-month/date-picker-month.tsx | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx index e6694e90b93..a9f2f9a1cbc 100644 --- a/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx +++ b/packages/calcite-components/src/components/date-picker-month/date-picker-month.tsx @@ -88,7 +88,7 @@ export class DatePickerMonth { /** * When `true`, activates the component's range mode which renders two calendars for selecting ranges of dates. */ - @Prop({ reflect: true }) range: boolean; + @Prop({ reflect: true }) range: boolean = false; /** Specifies the size of the component. */ @Prop({ reflect: true }) scale: Scale; @@ -624,14 +624,16 @@ export class DatePickerMonth { const getDayInWeek = () => dayInWeek++ % 7; month = position === "end" ? month + 1 : month; const days: Day[] = [ - ...prevMonthDays.map((day) => { - return { - active: false, - day, - dayInWeek: getDayInWeek(), - date: new Date(year, month - 1, day), - }; - }), + ...(!this.range + ? prevMonthDays.map((day) => { + return { + active: false, + day, + dayInWeek: getDayInWeek(), + date: new Date(year, month - 1, day), + }; + }) + : []), ...currMonthDays.map((day) => { const date = new Date(year, month, day); const active = @@ -650,14 +652,16 @@ export class DatePickerMonth { ref: true, }; }), - ...nextMonthDays.map((day) => { - return { - active: false, - day, - dayInWeek: getDayInWeek(), - date: new Date(year, month + 1, day), - }; - }), + ...(!this.range + ? nextMonthDays.map((day) => { + return { + active: false, + day, + dayInWeek: getDayInWeek(), + date: new Date(year, month + 1, day), + }; + }) + : []), ]; return days; From 10bc85247e011fbed8ef96c7cb75b75f038a60bf Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Wed, 8 May 2024 11:18:58 -0500 Subject: [PATCH 078/155] add divider for horizontal input --- .../input-date-picker/input-date-picker.scss | 35 +++++++------------ .../input-date-picker/input-date-picker.tsx | 13 ++++--- .../components/input-date-picker/resources.ts | 4 +++ .../src/components/input-text/input-text.scss | 8 +++++ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss b/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss index 36d09338696..0eee1846771 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss @@ -66,19 +66,20 @@ .input-wrapper { @apply flex-auto; } +} - .horizontal-arrow-container { - @apply bg-background - border-color-input - flex - items-center - border - border-l-0 - border-r-0 - border-solid - py-0 - px-1; - } +.divider-container { + @apply flex w-px items-stretch border-color-input + border + border-l-0 + border-r-0 + border-solid; + background-color: #ffffff; +} + +.divider { + @apply my-1 inline-block w-px; + background-color: #d9d9d9; } :host([range][layout="vertical"]) { @@ -94,16 +95,6 @@ .calendar-wrapper--end { transform: translate3d(0, 0, 0); } - - .vertical-arrow-container { - inset-block-start: theme("spacing.6"); - @apply bg-foreground-1 - absolute - z-default - mx-px - px-2.5; - inset-inline-start: 0; - } } .menu-container { diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 37c1e1b69bf..a50ab16a349 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -573,6 +573,7 @@ export class InputDatePicker class={{ [CSS.input]: true, [CSS.inputNoBottomBorder]: this.layout === "vertical" && this.range, + [CSS.inputNoRightBorder]: this.layout === "horizontal" && this.range, }} disabled={disabled} icon="calendar" @@ -641,10 +642,9 @@ export class InputDatePicker />
- - {this.range && this.layout === "vertical" && this.scale !== "s" && ( -
- + {this.range && this.layout === "horizontal" && ( +
+
)} {this.range && ( @@ -664,6 +664,7 @@ export class InputDatePicker class={{ [CSS.input]: true, [CSS.inputBorderTopColorOne]: this.layout === "vertical" && this.range, + [CSS.inputNoLeftBorder]: this.layout === "horizontal" && this.range, }} disabled={disabled} icon="calendar" @@ -678,7 +679,9 @@ export class InputDatePicker // eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530) ref={this.setEndInput} /> - {!this.readOnly && this.renderToggleIcon(this.open)} + {!this.readOnly && + this.layout === "horizontal" && + this.renderToggleIcon(this.open)}
)}
diff --git a/packages/calcite-components/src/components/input-date-picker/resources.ts b/packages/calcite-components/src/components/input-date-picker/resources.ts index 3007647d643..13241c3af8c 100644 --- a/packages/calcite-components/src/components/input-date-picker/resources.ts +++ b/packages/calcite-components/src/components/input-date-picker/resources.ts @@ -2,10 +2,14 @@ export const CSS = { assistiveText: "assistive-text", calendarWrapper: "calendar-wrapper", calendarWrapperEnd: "calendar-wrapper--end", + dividerContainer: "divider-container", + divider: "divider", horizontalArrowContainer: "horizontal-arrow-container", inputBorderTopColorOne: "border-top-color-one", inputContainer: "input-container", inputNoBottomBorder: "no-bottom-border", + inputNoRightBorder: "no-right-border", + inputNoLeftBorder: "no-left-border", inputWrapper: "input-wrapper", input: "input", menu: "menu-container", diff --git a/packages/calcite-components/src/components/input-text/input-text.scss b/packages/calcite-components/src/components/input-text/input-text.scss index d46e7ec4315..1a930f7de2b 100755 --- a/packages/calcite-components/src/components/input-text/input-text.scss +++ b/packages/calcite-components/src/components/input-text/input-text.scss @@ -322,6 +322,14 @@ input[type="text"]::-ms-reveal { @apply border-b-0; } +:host(.no-right-border) input { + border-inline-end: 0; +} + +:host(.no-left-border) input { + border-inline-start: 0; +} + :host(.border-top-color-one) input { @apply border-t-color-1; } From d387989c4704e7e84c6f0b29dc4fd3c1d92faa76 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Wed, 8 May 2024 17:10:19 -0500 Subject: [PATCH 079/155] update vertical arrow indicator positioning --- .../input-date-picker/input-date-picker.scss | 28 +-- .../input-date-picker/input-date-picker.tsx | 213 +++++++++--------- .../components/input-date-picker/resources.ts | 1 + 3 files changed, 128 insertions(+), 114 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss b/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss index 0eee1846771..2d83e40d7a0 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.scss @@ -59,10 +59,14 @@ } :host([range]) { - .input-container { + .container { @apply flex; } + .input-container { + @apply flex flex-auto; + } + .input-wrapper { @apply flex-auto; } @@ -88,8 +92,7 @@ } .input-container { - @apply flex-col - items-start; + @apply flex-col items-start; } .calendar-wrapper--end { @@ -118,9 +121,11 @@ @apply mt-0; } -:host([range][layout="vertical"][scale="m"]) .vertical-arrow-container { - inset-block-start: theme("spacing.6"); - padding-inline-start: theme("spacing.3"); +.vertical-arrow-container { + @apply flex items-center border border-solid border-color-input border-l-0; + inline-size: 16px; + block-size: 62px; + background-color: #ffffff; calcite-icon { @apply h-3 @@ -129,15 +134,12 @@ } } -:host([range][layout="vertical"][scale="l"]) .vertical-arrow-container { - inset-block-start: theme("spacing.9"); - @apply px-3.5; +:host([range][layout="vertical"][scale="m"]) .vertical-arrow-container { + padding-inline: theme("spacing.3"); } -:host([range][layout="vertical"][open]) { - .vertical-arrow-container { - @apply hidden; - } +:host([range][layout="vertical"][scale="l"]) .vertical-arrow-container { + @apply px-3.5; } @include form-validation-message(); diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index a50ab16a349..2d46c3bea6c 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -555,133 +555,144 @@ export class InputDatePicker {this.localeData && ( -
-
- - {!this.readOnly && - !this.range && - this.renderToggleIcon(this.open && this.focusedInput === "start")} - -
- - {this.range && this.layout === "horizontal" && ( -
-
-
- )} - {this.range && ( +
+
{!this.readOnly && - this.layout === "horizontal" && - this.renderToggleIcon(this.open)} + !this.range && + this.renderToggleIcon(this.open && this.focusedInput === "start")} + +
+ + {this.range && this.layout === "horizontal" && ( +
+
+
+ )} + {this.range && ( +
+ + {!this.readOnly && + this.layout === "horizontal" && + this.renderToggleIcon(this.open)} +
+ )} +
+ {this.range && this.layout === "vertical" && this.scale !== "s" && ( +
+
)}
diff --git a/packages/calcite-components/src/components/input-date-picker/resources.ts b/packages/calcite-components/src/components/input-date-picker/resources.ts index 13241c3af8c..8a30b58202b 100644 --- a/packages/calcite-components/src/components/input-date-picker/resources.ts +++ b/packages/calcite-components/src/components/input-date-picker/resources.ts @@ -2,6 +2,7 @@ export const CSS = { assistiveText: "assistive-text", calendarWrapper: "calendar-wrapper", calendarWrapperEnd: "calendar-wrapper--end", + container: "container", dividerContainer: "divider-container", divider: "divider", horizontalArrowContainer: "horizontal-arrow-container", From c48c8d54ce80a8e40f1de65b518193e6d5673705 Mon Sep 17 00:00:00 2001 From: Anveshreddy mekala Date: Mon, 13 May 2024 15:34:34 -0500 Subject: [PATCH 080/155] removes redndant wrapper containers and css styling --- .../date-picker-day/date-picker-day.scss | 39 +++------------- .../date-picker-day/date-picker-day.tsx | 10 ++-- .../date-picker-month-header.scss | 12 ++++- .../date-picker-month-header.tsx | 18 +++++--- .../date-picker-month-header/resources.ts | 3 ++ .../date-picker-month/date-picker-month.scss | 46 ++++--------------- .../components/date-picker/date-picker.scss | 15 ++---- .../components/date-picker/date-picker.tsx | 4 +- .../src/components/select/select.scss | 3 +- 9 files changed, 52 insertions(+), 98 deletions(-) diff --git a/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss b/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss index b4988d69b13..6271412e7ac 100644 --- a/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss +++ b/packages/calcite-components/src/components/date-picker-day/date-picker-day.scss @@ -1,34 +1,31 @@ :host { @apply cursor-pointer flex relative text-color-3; + outline: none; } @include disabled(); -.day-v-wrapper { - @apply flex-auto; -} - .day-wrapper { @apply flex flex-col items-center - relative; + justify-center + relative + w-full; } .day { @apply text-n2h text-color-3 flex - focus-base items-center justify-center leading-none transition-default - z-default; + w-full; background: none; - box-shadow: 0 0 0 2px transparent; block-size: var(--calcite-internal-day-size); - inline-size: var(--calcite-internal-day-size); + outline-color: transparent; } .text { @@ -39,9 +36,6 @@ :host([scale="s"]) { --calcite-internal-day-size: 27px; - .day-v-wrapper { - // @apply py-0.5; - } .day-wrapper { @apply p-0; } @@ -53,9 +47,6 @@ :host([scale="m"]) { --calcite-internal-day-size: 40px; - .day-v-wrapper { - // @apply py-1; - } .day-wrapper { @apply p-0; } @@ -67,9 +58,6 @@ :host([scale="l"]) { --calcite-internal-day-size: 43px; - .day-v-wrapper { - // @apply py-1; - } .day-wrapper { @apply px-1; } @@ -89,13 +77,8 @@ } } -:host(:focus), -:host([active]) { - @apply outline-none; -} - :host(:focus:not([disabled])) .day { - @apply focus-outset; + @apply focus-inset; } :host([selected]) .day { @@ -104,14 +87,6 @@ color: var(--calcite-color-foreground-1); } -:host(:focus:not([disabled])), -:host([start-of-range]:not(:focus)), -:host([end-of-range]:not(:focus)) { - .day { - box-shadow: 0 0 0 2px var(--calcite-color-foreground-1); - } -} - :host([range-hover]:not([selected])), :host([highlighted]:not([selected])) { .day { diff --git a/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx b/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx index 38c16b602ca..7457943e194 100644 --- a/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx +++ b/packages/calcite-components/src/components/date-picker-day/date-picker-day.tsx @@ -196,12 +196,10 @@ export class DatePickerDay implements InteractiveComponent, LoadableComponent { tabIndex={this.active && !this.disabled ? 0 : -1} > -