Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed min and max for KolInputDate #6892

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ac07ea4
max no longer use always default
AlexanderSchmidtCE Sep 27, 2024
a38ef70
Added Sample for MinMax
AlexanderSchmidtCE Sep 27, 2024
84343c3
added e2e Tests
AlexanderSchmidtCE Sep 27, 2024
26229e0
updated unitTest
AlexanderSchmidtCE Sep 27, 2024
c639d3c
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Sep 27, 2024
5b52a18
updated unitTest
AlexanderSchmidtCE Sep 27, 2024
d621b82
Merge remote-tracking branch 'origin/6849-_min-und-_max-werden-beim-i…
AlexanderSchmidtCE Sep 27, 2024
83a03ea
updated unitTest
AlexanderSchmidtCE Sep 27, 2024
75011fc
Merge branch 'feature/revert-deps-update' into 6849-_min-und-_max-wer…
laske185 Sep 30, 2024
c9ffc4d
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 7, 2024
f2bee0a
lint fix
AlexanderSchmidtCE Oct 8, 2024
94e09a7
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 8, 2024
b95e1e2
lint fix
AlexanderSchmidtCE Oct 8, 2024
803f7b8
Merge remote-tracking branch 'origin/6849-_min-und-_max-werden-beim-i…
AlexanderSchmidtCE Oct 8, 2024
3bfda36
lint fix
AlexanderSchmidtCE Oct 8, 2024
be6b095
Fixed getWeekNumberOfDate()
AlexanderSchmidtCE Oct 8, 2024
1618059
lint fix
AlexanderSchmidtCE Oct 8, 2024
7356931
Update all snapshots$
AlexanderSchmidtCE Oct 8, 2024
3a5d060
added unit test for getWeekNumberOfDate
AlexanderSchmidtCE Oct 9, 2024
e4f8114
added e2e test for InputDate
AlexanderSchmidtCE Oct 9, 2024
bebabc6
lint fixes
AlexanderSchmidtCE Oct 9, 2024
1e12ae4
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 9, 2024
183fe9e
removed samples e2e test for inputDate
AlexanderSchmidtCE Oct 9, 2024
a4992d6
update Date to UTC
AlexanderSchmidtCE Oct 9, 2024
d1b3d55
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 9, 2024
53fc0d9
Update all snapshots$
AlexanderSchmidtCE Oct 9, 2024
c1cdb00
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 11, 2024
3ea2551
Added Tests for Year Change
AlexanderSchmidtCE Oct 11, 2024
a853315
e2e update
AlexanderSchmidtCE Oct 11, 2024
298a5b9
Merge branch 'develop' into 6849-_min-und-_max-werden-beim-inputdate-…
AlexanderSchmidtCE Oct 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ describe('InputDateController', () => {
expect(InputDateController.tryParseToString(TEST_DATE, 'time', 10)).toBe('03:02:01');
});

it('throws an Error for type week', () => {
expect(() => InputDateController.tryParseToString(TEST_DATE, 'week')).toThrowError('Auto convert to week is not supported!');
it('returns a ISO8601 week string for type week', () => {
expect(InputDateController.tryParseToString(TEST_DATE, 'week')).toBe('2020-W10');
});
});
});
Expand Down
51 changes: 33 additions & 18 deletions packages/components/src/components/input-date/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { inputDateTypeOptions, setState, validateReadOnly, validateSuggestions,
import { InputIconController } from '../@deprecated/input/controller-icon';

import type { Generic } from 'adopted-style-sheets';

export class InputDateController extends InputIconController implements InputDateWatches {
// test: https://regex101.com/r/NTVh4L/1
private static readonly isoDateRegex = /^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])/;
Expand Down Expand Up @@ -75,11 +76,38 @@ export class InputDateController extends InputIconController implements InputDat
return formattedTimeWithSeconds;
}
case 'week':
throw new Error('Auto convert to week is not supported!');
return `${formattedYear}-W${this.getWeekNumberOfDate(value)}`;
}
}
}

static getWeekNumberOfDate(date: Date): string {
AlexanderSchmidtCE marked this conversation as resolved.
Show resolved Hide resolved
// ISO week date weeks start on Monday, so correct the day number
const nDay = (date.getDay() + 6) % 7;

// ISO 8601 states that week 1 is the week with the first Thursday of that year
// Set the target date to the Thursday in the target week
date.setDate(date.getDate() - nDay + 3);

// Store the millisecond value of the target date
const n1stThursday = date.valueOf();

// Set the target to the first Thursday of the year
// First, set the target to January 1st
date.setMonth(0, 1);

// Not a Thursday? Correct the date to the next Thursday
if (date.getDay() !== 4) {
date.setMonth(0, 1 + ((4 - date.getDay() + 7) % 7));
}

// The week number is the number of weeks between the first Thursday of the year
// and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
const dayOfYear = 1 + Math.ceil((n1stThursday - date.valueOf()) / 604800000);

return dayOfYear.toString().padStart(2, '0');
}

private validateDateString(value: string): boolean {
switch (this.component._type) {
case 'date':
Expand Down Expand Up @@ -127,29 +155,16 @@ export class InputDateController extends InputIconController implements InputDat

public validateMax(value?: Iso8601 | Date): void {
const ensuredValue =
((value === undefined || value === null) && this.component._type === 'date') ||
this.component._type === 'month' ||
this.component._type === 'datetime-local'
(value === undefined || value === null) &&
(this.component._type === 'date' || this.component._type === 'month' || this.component._type === 'datetime-local')
? InputDateController.DEFAULT_MAX_DATE
: value;

watchValidator(
this.component,
'_max',
(value): boolean => value === undefined || (value !== null && this.validateDateString(value)),
new Set(['Iso8601', 'Date']),
InputDateController.tryParseToString(ensuredValue, this.component._type, this.component._step),
);
this.validateIso8601('_max', ensuredValue);
}

public validateMin(value?: Iso8601 | Date): void {
watchValidator(
this.component,
'_min',
(value): boolean => value === undefined || (value !== null && this.validateDateString(value)),
new Set(['Iso8601', 'Date']),
InputDateController.tryParseToString(value, this.component._type, this.component._step),
);
this.validateIso8601('_min', value);
}

public validateOn(value?: InputTypeOnDefault) {
Expand Down
105 changes: 105 additions & 0 deletions packages/samples/react/e2e/input-date.spec.ts
AlexanderSchmidtCE marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { expect, test } from '@playwright/test';

test.describe('KolInputDate', () => {
test.describe('when _min and _max is set with Iso8601', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/#/input-date/basic?hideMenus');
});

test('should set correct min and max for type date', async ({ page }) => {
const minDate = '2024-09-26';
const maxDate = '2024-09-27';
const input = page.getByTestId('isoDate').locator('input');

await expect(input).toHaveAttribute('min', minDate);
await expect(input).toHaveAttribute('max', maxDate);
});

test('should set correct min and max for type time', async ({ page }) => {
const minTime = '12:00';
const maxTime = '15:00';
const input = page.getByTestId('isoTime').locator('input');

await expect(input).toHaveAttribute('min', minTime);
await expect(input).toHaveAttribute('max', maxTime);
});

test('should set correct min and max for type datetime_locale', async ({ page }) => {
const minDayTime = '2024-09-26T12:00';
const maxDaytime = '2024-09-27T15:00';
const input = page.getByTestId('isoDatetime').locator('input');

await expect(input).toHaveAttribute('min', minDayTime);
await expect(input).toHaveAttribute('max', maxDaytime);
});

test('should set correct min and max for type week', async ({ page }) => {
const minWeek = '2024-W10';
const maxWeek = '2024-W50';
const input = page.getByTestId('isoWeek').locator('input');

await expect(input).toHaveAttribute('min', minWeek);
await expect(input).toHaveAttribute('max', maxWeek);
});

test('should set correct min and max for type month', async ({ page }) => {
const minMonth = '2024-02';
const maxMonth = '2024-10';
const input = page.getByTestId('isoMonth').locator('input');

await expect(input).toHaveAttribute('min', minMonth);
await expect(input).toHaveAttribute('max', maxMonth);
});
});

test.describe('when _min and _max is set with JS Date', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/#/input-date/basic?hideMenus');
});

test('should set correct min and max for type date', async ({ page }) => {
const minDate = '2024-01-10';
const maxDate = '2024-10-20';
const input = page.getByTestId('dateDate').locator('input');

await expect(input).toHaveAttribute('min', minDate);
await expect(input).toHaveAttribute('max', maxDate);
});

test('should set correct min and max for type time', async ({ page }) => {
const minTime = '12:00';
const maxTime = '15:00';
const input = page.getByTestId('dateTime').locator('input');

await expect(input).toHaveAttribute('min', minTime);
await expect(input).toHaveAttribute('max', maxTime);
});

test('should set correct min and max for type datetime_locale', async ({ page }) => {
const minDayTime = '2024-01-10T12:00:00';
const maxDaytime = '2024-10-20T15:00:00';
const input = page.getByTestId('dateDatetime').locator('input');

await expect(input).toHaveAttribute('min', minDayTime);
await expect(input).toHaveAttribute('max', maxDaytime);
});

test('should set correct min and max for type week', async ({ page }) => {
const minWeek = '2024-W02';
const maxWeek = '2024-W42';
const input = page.getByTestId('dateWeek').locator('input');

await expect(input).toHaveAttribute('min', minWeek);
await expect(input).toHaveAttribute('max', maxWeek);
});

test('should set correct min and max for type month', async ({ page }) => {
const minMonth = '2024-01';
const maxMonth = '2024-10';
const input = page.getByTestId('dateMonth').locator('input');

await expect(input).toHaveAttribute('min', minMonth);
await expect(input).toHaveAttribute('max', maxMonth);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { forwardRef } from 'react';
import { KolInputDate } from '@public-ui/react';
import type { Components } from '@public-ui/components';

export const InputDateMinMaxCases = forwardRef<HTMLKolInputDateElement, Components.KolInputDate>(function InputDateCases(props) {
const minDateIso = '2024-09-26';
const maxDateIso = '2024-09-27';

const minTimeIso = '12:00';
const maxTimeIso = '15:00';

const minDayTimeIso = '2024-09-26T12:00';
const maxDaytimeIso = '2024-09-27T15:00';

const minWeekIso = '2024-W10';
const maxWeekIso = '2024-W50';

const minMonthIso = '2024-02';
const maxMonthIso = '2024-10';

const minDate = new Date('January 10, 2024, 12:00');
const maxDate = new Date('October 20, 2024, 15:00');
return (
<div className="grid gap-4">
<KolInputDate data-testid="isoDate" {...props} _type="date" _label="Date with Iso" _min={minDateIso} _max={maxDateIso} />
<KolInputDate data-testid="dateDate" {...props} _type="date" _label="Date with Date" _min={minDate} _max={maxDate} />

<KolInputDate data-testid="isoTime" {...props} _type="time" _label="Time with Iso" _min={minTimeIso} _max={maxTimeIso} />
<KolInputDate data-testid="dateTime" {...props} _type="time" _label="Time with Date" _min={minDate} _max={maxDate} />

<KolInputDate data-testid="isoDatetime" {...props} _type="datetime-local" _label="DayTime with Iso" _min={minDayTimeIso} _max={maxDaytimeIso} />
<KolInputDate data-testid="dateDatetime" {...props} _type="datetime-local" _label="DayTime with Date" _min={minDate} _max={maxDate} />

<KolInputDate data-testid="isoWeek" {...props} _type="week" _label="Week with Iso" _min={minWeekIso} _max={maxWeekIso} />
<KolInputDate data-testid="dateWeek" {...props} _type="week" _label="Week with Date" _min={minDate} _max={maxDate} />

<KolInputDate data-testid="isoMonth" {...props} _type="month" _label="Month with Iso" _min={minMonthIso} _max={maxMonthIso} />
<KolInputDate data-testid="dateMonth" {...props} _type="month" _label="Month with Date" _min={minDate} _max={maxDate} />
</div>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { forwardRef } from 'react';
import { InputDateCases } from './cases';

import type { Components } from '@public-ui/components';
import { InputDateMinMaxCases } from './minMax';
export const InputDateVariants = forwardRef<HTMLKolInputDateElement, Components.KolInputDate>(function InputDateVariant(props, ref) {
return (
<div className="grid md:grid-cols-2 gap-4">
Expand All @@ -14,6 +15,10 @@ export const InputDateVariants = forwardRef<HTMLKolInputDateElement, Components.
<legend>Date (hideLabel)</legend>
<InputDateCases ref={ref} {...props} _hideLabel />
</fieldset>
<fieldset>
<legend>Date (with min/max)</legend>
<InputDateMinMaxCases ref={ref} {...props} />
</fieldset>
</div>
);
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading