Skip to content

Commit

Permalink
refactor: Addressed PR review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
rkaraivanov committed Nov 13, 2024
1 parent 17ab398 commit a2695ac
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 77 deletions.
22 changes: 11 additions & 11 deletions src/components/calendar/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ export class IgcCalendarBaseComponent extends LitElement {
@state()
protected _disabledDates: DateRangeDescriptor[] = [];

public get value(): Date | null {
return this._value ? this._value.native : null;
}

/* blazorSuppress */
/**
* The current value of the calendar.
Expand All @@ -63,13 +59,13 @@ export class IgcCalendarBaseComponent extends LitElement {
* @attr value
*/
@property({ converter: convertToDate })
public set value(value: Date | string | null) {
public set value(value: Date | string | null | undefined) {
const converted = convertToDate(value);
this._value = converted ? CalendarDay.from(converted) : null;
}

public get values(): Date[] {
return this._values ? this._values.map((v) => v.native) : [];
public get value(): Date | null {
return this._value ? this._value.native : null;
}

/* blazorSuppress */
Expand All @@ -80,26 +76,30 @@ export class IgcCalendarBaseComponent extends LitElement {
* @attr values
*/
@property({ converter: convertToDates })
public set values(values: Date[] | string | null) {
public set values(values: (Date | string)[] | string | null | undefined) {
const converted = convertToDates(values);
this._values = converted ? converted.map((v) => CalendarDay.from(v)) : [];
}

public get activeDate(): Date {
return this._activeDate.native;
public get values(): Date[] {
return this._values ? this._values.map((v) => v.native) : [];
}

/* blazorSuppress */
/** Get/Set the date which is shown in view and is highlighted. By default it is the current date. */
@property({ attribute: 'active-date', converter: convertToDate })
public set activeDate(value: Date | string) {
public set activeDate(value: Date | string | null | undefined) {
this._initialActiveDateSet = true;
const converted = convertToDate(value);
this._activeDate = converted
? CalendarDay.from(converted)
: CalendarDay.today;
}

public get activeDate(): Date {
return this._activeDate.native;
}

/**
* Sets the type of selection in the component.
* @attr selection
Expand Down
50 changes: 42 additions & 8 deletions src/components/calendar/calendar.interaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ describe('Calendar interactions', () => {
expect(date.equalTo(calendar.value!)).to.be.true;

// Invalid date
calendar.value = new Date('s');
expect(calendar.value).to.be.null;
for (const each of [new Date('s'), '', null, undefined]) {
calendar.value = each;
expect(calendar.value).to.be.null;
}
});

it('setting `values` attribute', async () => {
Expand All @@ -76,19 +78,51 @@ describe('Calendar interactions', () => {
const date_1 = new CalendarDay({ year: 2022, month: 0, date: 19 });
const date_2 = date_1.set({ date: 22 });

const date_1_str = date_1.native.toISOString();
const date_2_str = date_2.native.toISOString();

calendar.selection = 'multiple';
calendar.values = `${date_1.native.toISOString()}, ${date_2.native.toISOString()}`;
calendar.values = `${date_1_str}, ${date_2_str}`;

expect(calendar.values).lengthOf(2);
expect(date_1.equalTo(first(calendar.values))).to.be.true;
expect(date_2.equalTo(last(calendar.values))).to.be.true;

// Invalid dates
calendar.values = 'nope, nope again';
expect(calendar.values).is.empty;
// Valid date combinations
const validDates = [
[date_1_str, date_2_str],
[date_1.native, date_2.native],
[date_1_str, date_2.native],
];

for (const each of validDates) {
calendar.values = each;
expect(calendar.values).lengthOf(2);
expect(date_1.equalTo(first(calendar.values))).to.be.true;
expect(date_2.equalTo(last(calendar.values))).to.be.true;
}

// Mixed date combinations
calendar.values = [date_1.native, new Date(), new Date('s'), date_1_str];
expect(calendar.values).lengthOf(3);

calendar.values = ['invalid', date_1_str, date_2_str, date_2.native];
expect(calendar.values).lengthOf(3);

// Invalid date combinations
const invalidDates = [
'',
null,
undefined,
[new Date('s'), 'abc'],
'abcde, abcde',
['a', 'b', 'c', new Date('invalid')],
];

calendar.values = '';
expect(calendar.values).is.empty;
for (const each of invalidDates) {
calendar.values = each;
expect(calendar.values).is.empty;
}
});

it('clicking previous/next buttons in days view', async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/calendar/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ export default class IgcCalendarComponent extends EventEmitterMixin<
}

this.emitEvent('igcChange', {
detail: this._isSingle ? this.value : this.values,
detail: this._isSingle ? (this.value as Date) : this.values,
});
}

Expand Down
56 changes: 7 additions & 49 deletions src/components/calendar/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,8 @@ const DaysMap = {
* If the value is a string, it is parsed into a Date object.
* If the value is null or undefined, null is returned.
* If the parsing fails, null is returned.
*
* @param value The value to convert.
* @returns The converted Date object, or null if the conversion fails.
*
* @example
* ```typescript
* const dateString = '2023-11-11T12:34:56Z';
* const dateObject = new Date('2023-11-11T12:34:56Z');
* const nullValue = null;
* const result1 = convertToDate(dateString); // Date object
* const result2 = convertToDate(dateObject); // Date object
* const result3 = convertToDate(nullValue); // null
* const result4 = convertToDate('invalid-date-string'); // null
* ```
*/
export function convertToDate(value: Date | string | null): Date | null {
export function convertToDate(value?: Date | string | null): Date | null {
if (!value) {
return null;
}
Expand All @@ -74,47 +59,21 @@ export function convertToDate(value: Date | string | null): Date | null {
*
* If the `value` is a `Date` object, it is converted to an ISO 8601 string.
* If the `value` is null or undefined, null is returned.
*
* @param value The Date object to convert.
* @returns The ISO 8601 string representation of the Date object, or null if the value is null or undefined.
*
* @example
* ```typescript
* const dateObject = new Date('2023-11-11T12:34:56Z');
* const nullValue = null;
* const result1 = getDateFormValue(dateObject); // "2023-11-11T12:34:56.000Z"
* const result2 = getDateFormValue(nullValue); // null
* ```
*/
export function getDateFormValue(value: Date | null) {
return value ? value.toISOString() : null;
}

/**
* Converts an array of Date objects or a comma-separated string of ISO 8601 dates into an array of Date objects.
* If the `value` is an array of `Date` objects, it is returned directly.
* If the `value` is a string, it is split by commas and each part is parsed into a `Date` object.
* Converts a comma-separated string of ISO 8601 dates or an array of Date objects | ISO 8601 strings into
* an array of Date objects.
*
* If the `value` is null or undefined, null is returned.
* If the `value` is an array of `Date` objects, a filtered array of valid `Date` objects is returned.
* If the `value` is a string, it is split by commas and each part is parsed into a `Date` object.
* If the parsing fails for any date, it is skipped.
* @param value The value to convert.
* @returns An array of Date objects, or null if the conversion fails for all values.
* @example
* ```typescript
* const dateStrings = '2023-11-11T12:34:56Z,2023-12-12T13:45:00Z';
* const dateObjects = [new Date('2023-11-11T12:34:56Z'), new Date('2023-12-12T13:45:00Z')];
* const nullValue = null;
* const result1 = convertToDates(dateStrings); // [Date, Date]
* const result2 = convertToDates(dateObjects); // [Date, Date]
* const result3 = convertToDates(nullValue); // null
* const result4 = convertToDates('invalid-date-string,2023-11-11T12:34:56Z'); // [Date]
* ```
*/
export function convertToDates(value: Date[] | string | null) {
export function convertToDates(value?: (Date | string)[] | string | null) {
if (!value) {
return null;
}
Expand All @@ -134,7 +93,6 @@ export function convertToDates(value: Date[] | string | null) {

/**
* Returns the value of the selected/activated element (day/month/year) in the calendar view.
*
*/
export function getViewElement(event: Event) {
const element = findElementFromEventPath<HTMLElement>('[data-value]', event);
Expand Down
2 changes: 1 addition & 1 deletion src/components/calendar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ export type WeekDays =
| 'saturday';

export interface IgcCalendarComponentEventMap {
igcChange: CustomEvent<Date | Date[] | null>;
igcChange: CustomEvent<Date | Date[]>;
}
8 changes: 4 additions & 4 deletions src/components/date-picker/date-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export default class IgcDatePickerComponent extends FormAssociatedRequiredMixin(
* @attr
*/
@property({ converter: convertToDate })
public set value(value: Date | string | null) {
public set value(value: Date | string | null | undefined) {
this._value = convertToDate(value);
this._setFormValue(getDateFormValue(this._value));
this._validate();
Expand All @@ -260,7 +260,7 @@ export default class IgcDatePickerComponent extends FormAssociatedRequiredMixin(
* By default it is the current date.
*/
@property({ attribute: 'active-date', converter: convertToDate })
public set activeDate(value: Date | null) {
public set activeDate(value: Date | string | null | undefined) {
this._activeDate = convertToDate(value);
}

Expand All @@ -273,7 +273,7 @@ export default class IgcDatePickerComponent extends FormAssociatedRequiredMixin(
* @attr
*/
@property({ converter: convertToDate })
public set min(value: Date | string) {
public set min(value: Date | string | null | undefined) {
this._min = convertToDate(value);
this.setDateConstraints();
this._updateValidity();
Expand All @@ -288,7 +288,7 @@ export default class IgcDatePickerComponent extends FormAssociatedRequiredMixin(
* @attr
*/
@property({ converter: convertToDate })
public set max(value: Date | string) {
public set max(value: Date | string | null | undefined) {
this._max = convertToDate(value);
this.setDateConstraints();
this._updateValidity();
Expand Down
6 changes: 3 additions & 3 deletions src/components/date-time-input/date-time-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
* @attr
*/
@property({ converter: convertToDate })
public set value(value: Date | string | null) {
public set value(value: Date | string | null | undefined) {
this._value = convertToDate(value);
this._setFormValue(getDateFormValue(this._value));
this.updateMask();
Expand All @@ -139,7 +139,7 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
* @attr
*/
@property({ converter: convertToDate })
public set min(value: Date | string | null) {
public set min(value: Date | string | null | undefined) {
this._min = convertToDate(value);
this._updateValidity();
}
Expand All @@ -153,7 +153,7 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
* @attr
*/
@property({ converter: convertToDate })
public set max(value: Date | string | null) {
public set max(value: Date | string | null | undefined) {
this._max = convertToDate(value);
this._updateValidity();
}
Expand Down

0 comments on commit a2695ac

Please sign in to comment.