Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
df36861
feat(drp): use templates for calendar header parts as DP + test
ddaribo Aug 11, 2025
0fe1c0f
chore(dp): add calendar header templates to public api dirs array
ddaribo Aug 11, 2025
e7553e7
refactor(picker-base): port headerOrientation prop in base class+test…
ddaribo Aug 11, 2025
999a915
feat(picker-base): add hideHeader prop + tests
ddaribo Aug 11, 2025
37fd4d4
feat(dp, drp): add orientation property + tests
ddaribo Aug 11, 2025
b94049e
feat(drp): limit displayMonthsCount between 1 and 2
ddaribo Aug 11, 2025
062203d
feat(drp): add specialDates prop + test
ddaribo Aug 12, 2025
93cb0b0
feat(drp): add disabledDates prop + test
ddaribo Aug 12, 2025
bdf35c1
feat(dp): update calendar selection on typing + test
ddaribo Aug 13, 2025
bcdb253
refactor(calendar): don't block selection for disabled date through m…
ddaribo Aug 13, 2025
f3c0c78
feat(dp): add activeDate property + tests
ddaribo Aug 13, 2025
0cb144b
refactor(dp): align the calendar activeDate with WC
ddaribo Aug 13, 2025
5b4821b
feat(dp): update calendar days view on typing & value is another view…
ddaribo Aug 13, 2025
62cfb04
fix(drp): check start and end values for disabledDates validation
ddaribo Aug 13, 2025
cc7b014
feat(drp): align activeDate behavior with WC + tests
ddaribo Aug 13, 2025
c0858a8
feat(drp): typing a single value results in calendar range of single …
ddaribo Aug 13, 2025
dd21608
feat(drp-sample): add WC drp + properties panel for manual testing
ddaribo Aug 13, 2025
421e62a
chore(changelog): update with new features for DRP & DP
ddaribo Aug 14, 2025
97499af
Merge branch 'master' into bpachilova/dp-drp-calendar-props-16131
ddaribo Aug 26, 2025
3155f94
chore(*): remove fdescribe
ddaribo Aug 26, 2025
ee66490
chore(drp-dev-sample): bind hideHeader properly
ddaribo Aug 26, 2025
8766c98
Merge branch 'master' into bpachilova/dp-drp-calendar-props-16131
ChronosSF Aug 27, 2025
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
41 changes: 34 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@

All notable changes for each version of this project will be documented in this file.


## 20.1.0
### New Features
`IgxDateRangePicker`
- Added cancel button to the dialog, allowing the user to cancel the selection.

- `IgxCarousel`
- Added `select` method overload accepting index.
```ts
Expand Down Expand Up @@ -35,13 +31,44 @@ All notable changes for each version of this project will be documented in this
If property `pinningPosition` is not set on a column, the column will default to the position specified on the grid's `pinning` options for `columns`.

- `IgxDateRangePicker`
- Added new properties:
- Now has a complete set of properties to customize the calendar:
- `headerOrientation`
- `orientation`
- `hideHeader`
- `activeDate`
- `disabledDates`
- `specialDates`

- As well as the following templates, available to customize the contents of the calendar header in `dialog` mode:
- `igxCalendarHeader`
- `igxCalendarHeaderTitle`
- `igxCalendarSubheader`

- Added new properties:
- `usePredefinedRanges` - Whether to render built-in predefined ranges
- `customRanges` - Allows the user to provide custom ranges rendered as chips
- `resourceStrings` - Allows the user to provide set of resource strings

- `IgxPredefinedRangesAreaComponent`
- Added new component for rendering the predefined or custom ranges inside the calendar of the `IgxDateRangePicker`
- **Behavioral Changes**
- Added cancel button to the dialog, allowing the user to cancel the selection.
- The calendar is displayed with header in `dialog` mode by default.
- The picker remains open when typing (in two-inputs and `dropdown` mode).
- The calendar selection is updated with the typed value.
- The calendar view is updated as per the typed value.
- The picker displays a clear icon by default in single input mode.

- `IgxPredefinedRangesAreaComponent`
- Added new component for rendering the predefined or custom ranges inside the calendar of the `IgxDateRangePicker`

- `IgxDatePicker`
- Similar to the `IgxDateRangePicker`, also completes the ability to customize the calendar by introducing the following
properties in addition to the existing ones:
- `hideHeader`
- `orientation`
- `activeDate`
- **Behavioral Changes**
- The calendar selection is updated with the typed value.
- The calendar view is updated as per the typed date value.

- `IgxOverlay`
- Position Settings now accept a new optional `offset` input property of type `number`. Used to set the offset of the element from the target in pixels.
Expand Down
8 changes: 3 additions & 5 deletions projects/igniteui-angular/src/lib/calendar/calendar-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,15 +707,15 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor {

switch (this.selection) {
case CalendarSelection.SINGLE:
if (isDate(value) && !this.isDateDisabled(value as Date)) {
if (isDate(value)) {
this.selectSingle(value as Date);
}
break;
case CalendarSelection.MULTI:
this.selectMultiple(value);
break;
case CalendarSelection.RANGE:
this.selectRange(value, true);
this.selectRange(value);
break;
}
}
Expand Down Expand Up @@ -807,9 +807,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor {
: [value, this.lastSelectedDate];

const unselectedDates = [this._startDate, ...this.generateDateRange(this._startDate, this._endDate)]
.filter(date => !this.isDateDisabled(date)
&& this.selectedDates.every((d: Date) => d.getTime() !== date.getTime())
);
.filter(date => this.selectedDates.every((d: Date) => d.getTime() !== date.getTime()));

// select all dates from last selected to shift clicked date
if (this.selectedDates.some((date: Date) => date.getTime() === this.lastSelectedDate.getTime())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,8 @@ describe("IgxCalendar - ", () => {
});

it("Should not select date from model, if it is part of disabled dates", () => {
expect(calendar.value).toBeFalsy();
// Changed per WC alignment task #16131 - calendar should not block selection of dates through API/model
expect(calendar.value).toBeTruthy();
});

it("Should not select date from model in range selection, if model passes null", () => {
Expand Down
42 changes: 28 additions & 14 deletions projects/igniteui-angular/src/lib/calendar/common/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,34 @@ export function getClosestActiveDate(
* @remarks
* By default, `unit` is set to 'day'.
*/
export function* calendarRange(options: CalendarRangeParams) {
let low = toCalendarDay(options.start);
const unit = options.unit ?? "day";
const high =
typeof options.end === "number"
? low.add(unit, options.end)
: toCalendarDay(options.end);

const reverse = high.lessThan(low);
const step = reverse ? -1 : 1;

while (!reverse ? low.lessThan(high) : low.greaterThan(high)) {
yield low;
low = low.add(unit, step);
export function* calendarRange(
options: CalendarRangeParams
): Generator<CalendarDay, void, unknown> {
const { start, end, unit = 'day', inclusive = false } = options;

let currentDate = toCalendarDay(start);
const endDate =
typeof end === 'number'
? toCalendarDay(start).add(unit, end)
: toCalendarDay(end);

const isReversed = endDate.lessThan(currentDate);
const step = isReversed ? -1 : 1;

const shouldContinue = () => {
if (inclusive) {
return isReversed
? currentDate.greaterThanOrEqual(endDate)
: currentDate.lessThanOrEqual(endDate);
}
return isReversed
? currentDate.greaterThan(endDate)
: currentDate.lessThan(endDate);
};

while (shouldContinue()) {
yield currentDate;
currentDate = currentDate.add(unit, step);
}
}

Expand Down
8 changes: 8 additions & 0 deletions projects/igniteui-angular/src/lib/calendar/common/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type CalendarRangeParams = {
start: DayParameter;
end: DayParameter | number;
unit?: DayInterval;
inclusive?: boolean;
};

type CalendarDayParams = {
Expand Down Expand Up @@ -237,11 +238,18 @@ export class CalendarDay {
public greaterThan(value: DayParameter) {
return this.timestamp > toCalendarDay(value).timestamp;
}
public greaterThanOrEqual(value: DayParameter) {
return this.timestamp >= toCalendarDay(value).timestamp;
}

public lessThan(value: DayParameter) {
return this.timestamp < toCalendarDay(value).timestamp;
}

public lessThanOrEqual(value: DayParameter) {
return this.timestamp <= toCalendarDay(value).timestamp;
}

public toString() {
return `${this.native}`;
}
Expand Down
13 changes: 13 additions & 0 deletions projects/igniteui-angular/src/lib/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ export const isEqual = (obj1, obj2): boolean => {
return obj1 === obj2;
};

/**
* Limits a number to a range between a minimum and a maximum value.
*
* @param number
* @param min
* @param max
* @returns: `number`
* @hidden
*/
export const clamp = (number: number, min: number, max: number) =>
Math.max(min, Math.min(number, max));


/**
* Utility service taking care of various utility functions such as
* detecting browser features, general cross browser DOM manipulation, etc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IBaseCancelableBrowserEventArgs, IBaseEventArgs } from '../core/utils';
import { IgxOverlayOutletDirective } from '../directives/toggle/toggle.directive';
import { OverlaySettings } from '../services/overlay/utilities';
import { IgxPickerToggleComponent } from './picker-icons.common';
import { PickerInteractionMode } from './types';
import { PickerHeaderOrientation, PickerInteractionMode } from './types';
import { WEEKDAYS } from '../calendar/calendar';
import { DateRange } from '../date-range-picker/date-range-picker-inputs.common';
import { IGX_INPUT_GROUP_TYPE, IgxInputGroupType } from '../input-group/inputGroupType';
Expand Down Expand Up @@ -78,6 +78,28 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider
@Input()
public mode: PickerInteractionMode = PickerInteractionMode.DropDown;

/**
* Gets/Sets the orientation of the `IgxDatePickerComponent` header.
*
* @example
* ```html
* <igx-date-picker headerOrientation="vertical"></igx-date-picker>
* ```
*/
@Input()
public headerOrientation: PickerHeaderOrientation = PickerHeaderOrientation.Horizontal;

/**
* Gets/Sets whether the header is hidden in dialog mode.
*
* @example
* ```html
* <igx-date-picker mode="dialog" [hideHeader]="true"></igx-date-picker>
* ```
*/
@Input({ transform: booleanAttribute })
public hideHeader = false;

/**
* Overlay settings used to display the pop-up element.
*
Expand Down
7 changes: 7 additions & 0 deletions projects/igniteui-angular/src/lib/date-common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ export const PickerHeaderOrientation = {
} as const;
export type PickerHeaderOrientation = (typeof PickerHeaderOrientation)[keyof typeof PickerHeaderOrientation];

/** Calendar orientation. */
export const PickerCalendarOrientation = {
Horizontal: 'horizontal',
Vertical: 'vertical'
} as const;
export type PickerCalendarOrientation = (typeof PickerCalendarOrientation)[keyof typeof PickerCalendarOrientation];

/**
* This enumeration is used to configure whether the date/time picker has an editable input with drop down
* or is readonly - the date/time is selected only through a dialog.
Expand Down
Loading
Loading