Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions packages/nativescript-calendar/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,17 @@ export abstract class NCalendarCommon extends View {
}

selectDateRange(start: Date, end: Date): void {
this._rangeStart = normalizeDate(start);
this._rangeEnd = normalizeDate(end);
const normalizedStart = normalizeDate(start);
const normalizedEnd = normalizeDate(end);

if (normalizedStart.getTime() <= normalizedEnd.getTime()) {
this._rangeStart = normalizedStart;
this._rangeEnd = normalizedEnd;
} else {
this._rangeStart = normalizedEnd;
this._rangeEnd = normalizedStart;
}

this._selectedKeys.clear();
const cursor = new Date(this._rangeStart.getTime());
while (cursor.getTime() <= this._rangeEnd.getTime()) {
Expand All @@ -371,6 +380,9 @@ export abstract class NCalendarCommon extends View {
}
this._syncSelectedDateRange();
this._refreshAfterSelectionChange();

// Keep programmatic range selection behavior intuitive by navigating to the range start.
this.scrollToDate(this._rangeStart, false);
}

clearSelection(): void {
Expand Down Expand Up @@ -484,12 +496,39 @@ firstDayOfWeekProperty.register(NCalendarCommon);
export const selectedDatesProperty = new Property<NCalendarCommon, Date[]>({
name: 'selectedDates',
defaultValue: [],
valueChanged: (target, _oldValue, newValue) => {
if (target._internalSelectionChange) return;
target._selectedKeys.clear();
if (newValue && newValue.length) {
for (const d of newValue) {
target._selectedKeys.add(target._toDateKey(d));
}
}
},
});
selectedDatesProperty.register(NCalendarCommon);

export const selectedDateRangeProperty = new Property<NCalendarCommon, DateRange>({
name: 'selectedDateRange',
defaultValue: undefined,
valueChanged: (target, _oldValue, newValue) => {
if (target._internalSelectionChange) return;
if (newValue && newValue.start && newValue.end) {
target._rangeStart = newValue.start;
target._rangeEnd = newValue.end;
target._selectedKeys.clear();
const cursor = new Date(newValue.start.getTime());
const endTime = newValue.end.getTime();
while (cursor.getTime() <= endTime) {
target._selectedKeys.add(target._toDateKey(cursor));
cursor.setDate(cursor.getDate() + 1);
}
} else {
target._rangeStart = null;
target._rangeEnd = null;
target._selectedKeys.clear();
}
},
});
selectedDateRangeProperty.register(NCalendarCommon);

Expand Down
54 changes: 50 additions & 4 deletions packages/nativescript-calendar/index.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,14 @@ export class NCalendar extends NCalendarCommon {
const localDate = jsDateToLocalDate(date);

if (this.displayMode === DisplayMode.Month) {
if (animated) {
if (this.orientation === Orientation.Horizontal && this.scrollPaged) {
const ym = java.time.YearMonth.of(date.getFullYear(), date.getMonth() + 1);
if (animated) {
this._calendarView.smoothScrollToMonth(ym);
} else {
this._calendarView.scrollToMonth(ym);
}
} else if (animated) {
this._calendarView.smoothScrollToDate(localDate);
} else {
this._calendarView.scrollToDate(localDate);
Expand Down Expand Up @@ -870,19 +877,54 @@ export class NCalendar extends NCalendarCommon {
[selectedDatesProperty.setNative](value: Date[]) {
if (this._internalSelectionChange) return;
this._selectedKeys.clear();
const normalizedDates: Date[] = [];
if (value && value.length) {
for (const d of value) {
this._selectedKeys.add(this._toDateKey(d));
const normalized = new Date(d.getFullYear(), d.getMonth(), d.getDate());
normalizedDates.push(normalized);
this._selectedKeys.add(this._toDateKey(normalized));
}
}

if (this.selectionMode === SelectionMode.Range) {
normalizedDates.sort((a, b) => a.getTime() - b.getTime());
if (normalizedDates.length) {
this._rangeStart = normalizedDates[0];
this._rangeEnd = normalizedDates[normalizedDates.length - 1];
this._selectedKeys.clear();
const cursor = new Date(this._rangeStart.getTime());
while (cursor.getTime() <= this._rangeEnd.getTime()) {
this._selectedKeys.add(this._toDateKey(cursor));
cursor.setDate(cursor.getDate() + 1);
}
} else {
this._rangeStart = null;
this._rangeEnd = null;
}
this._internalSelectionChange = true;
this._syncSelectedDateRange();
this._internalSelectionChange = false;
}

this._refreshCalendar();

if (normalizedDates.length) {
this.scrollToDate(normalizedDates[0], false);
}
}

[selectedDateRangeProperty.setNative](value: any) {
if (this._internalSelectionChange) return;
if (value && value.start && value.end) {
this._rangeStart = value.start;
this._rangeEnd = value.end;
const start = new Date(value.start.getFullYear(), value.start.getMonth(), value.start.getDate());
const end = new Date(value.end.getFullYear(), value.end.getMonth(), value.end.getDate());
if (start.getTime() <= end.getTime()) {
this._rangeStart = start;
this._rangeEnd = end;
} else {
this._rangeStart = end;
this._rangeEnd = start;
}
this._selectedKeys.clear();
const cursor = new Date(this._rangeStart.getTime());
while (cursor.getTime() <= this._rangeEnd.getTime()) {
Expand All @@ -895,6 +937,10 @@ export class NCalendar extends NCalendarCommon {
this._selectedKeys.clear();
}
this._refreshCalendar();

if (this._rangeStart) {
this.scrollToDate(this._rangeStart, false);
}
}

[eventsProperty.setNative](_value: any) {
Expand Down
49 changes: 46 additions & 3 deletions packages/nativescript-calendar/index.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,25 +248,64 @@ export class NCalendar extends NCalendarCommon {
[firstDayOfWeekProperty.setNative](value: number) {
if (this._calView) {
this._calView.firstDayOfWeekJS = value;
// After recreating the CalendarView, restore scroll position
if (this._currentMonth) {
this.scrollToMonth(this._currentMonth.year, this._currentMonth.month, false);
}
}
}

[selectedDatesProperty.setNative](value: Date[]) {
if (this._internalSelectionChange) return;
this._selectedKeys.clear();
const normalizedDates: Date[] = [];
if (value && value.length) {
for (const d of value) {
this._selectedKeys.add(this._toDateKey(d));
const normalized = new Date(d.getFullYear(), d.getMonth(), d.getDate());
normalizedDates.push(normalized);
this._selectedKeys.add(this._toDateKey(normalized));
}
}

if (this.selectionMode === SelectionMode.Range) {
normalizedDates.sort((a, b) => a.getTime() - b.getTime());
if (normalizedDates.length) {
this._rangeStart = normalizedDates[0];
this._rangeEnd = normalizedDates[normalizedDates.length - 1];
this._selectedKeys.clear();
const cursor = new Date(this._rangeStart.getTime());
while (cursor.getTime() <= this._rangeEnd.getTime()) {
this._selectedKeys.add(this._toDateKey(cursor));
cursor.setDate(cursor.getDate() + 1);
}
} else {
this._rangeStart = null;
this._rangeEnd = null;
}
this._internalSelectionChange = true;
this._syncSelectedDateRange();
this._internalSelectionChange = false;
}

this._syncSelectionToBridge();

if (normalizedDates.length) {
this.scrollToDate(normalizedDates[0], false);
}
}

[selectedDateRangeProperty.setNative](value: any) {
if (this._internalSelectionChange) return;
if (value && value.start && value.end) {
this._rangeStart = value.start;
this._rangeEnd = value.end;
const start = new Date(value.start.getFullYear(), value.start.getMonth(), value.start.getDate());
const end = new Date(value.end.getFullYear(), value.end.getMonth(), value.end.getDate());
if (start.getTime() <= end.getTime()) {
this._rangeStart = start;
this._rangeEnd = end;
} else {
this._rangeStart = end;
this._rangeEnd = start;
}
this._selectedKeys.clear();
const cursor = new Date(this._rangeStart.getTime());
while (cursor.getTime() <= this._rangeEnd.getTime()) {
Expand All @@ -279,6 +318,10 @@ export class NCalendar extends NCalendarCommon {
this._selectedKeys.clear();
}
this._syncSelectionToBridge();

if (this._rangeStart) {
this.scrollToDate(this._rangeStart, false);
}
}

[eventsProperty.setNative](value: any) {
Expand Down
Loading