From 46edd75f9417a5ea923a3e5716fe12a5bd53b44b Mon Sep 17 00:00:00 2001 From: Alexandra Date: Tue, 12 Jan 2021 11:06:40 +0100 Subject: [PATCH] feat(datepicker): Add min and max limits to the timepicker/timeinput + disable cursor on disabled dates and update readme. --- apps/demos/src/app-routing.module.ts | 2 + apps/demos/src/nav-items.ts | 4 + .../datepicker/datepicker-demo.component.html | 28 +++++- .../datepicker/datepicker-demo.component.scss | 10 ++- .../datepicker/datepicker-demo.component.ts | 4 + .../experimental/datepicker/README.md | 4 + .../experimental/datepicker/barista.json | 7 +- .../datepicker/src/calendar-body.scss | 1 + .../src/datepicker-utils/util.spec.ts | 32 +++++++ .../datepicker/src/datepicker-utils/util.ts | 85 +++++++++++++++++-- .../datepicker/src/timeinput.html | 2 + .../datepicker/src/timeinput.spec.ts | 7 ++ .../experimental/datepicker/src/timeinput.ts | 72 +++++++++++++--- .../datepicker/src/timepicker.html | 4 + .../experimental/datepicker/src/timepicker.ts | 12 +++ libs/examples/src/datepicker/BUILD.bazel | 13 ++- .../calendar-min-max-example.html | 4 +- .../calendar-min-max-example.scss | 6 +- .../datepicker-dark-example.scss | 4 + .../datepicker-default-example.scss | 4 + .../datepicker/datepicker-examples.module.ts | 13 ++- libs/examples/src/datepicker/index.ts | 1 + .../timepicker-min-max-example.html | 23 +++++ .../timepicker-min-max-example.scss | 11 +++ .../timepicker-min-max-example.ts | 29 +++++++ libs/examples/src/index.ts | 3 + 26 files changed, 351 insertions(+), 34 deletions(-) create mode 100644 libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.html create mode 100644 libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.scss create mode 100644 libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.ts diff --git a/apps/demos/src/app-routing.module.ts b/apps/demos/src/app-routing.module.ts index c6e409349e..33ea6df1ac 100644 --- a/apps/demos/src/app-routing.module.ts +++ b/apps/demos/src/app-routing.module.ts @@ -325,6 +325,7 @@ import { DtExampleFilterFieldInfiniteDataDepth, DtExampleSelectCustomValueTemplate, DtExampleCalendarMinMax, + DtExampleTimepickerMinMax, DtExampleDatepickerDark, DtExampleDatepickerDefault } from '@dynatrace/barista-examples'; @@ -585,6 +586,7 @@ const ROUTES: Routes = [ { path: 'drawer-nested-example', component: DtExampleDrawerNested }, { path: 'drawer-over-example', component: DtExampleDrawerOver }, { path: 'calendar-min-max-example', component: DtExampleCalendarMinMax}, + { path: 'timepicker-min-max-example', component: DtExampleTimepickerMinMax}, { path: 'datepicker-dark-example', component: DtExampleDatepickerDark}, { path: 'datepicker-default-example', component: DtExampleDatepickerDefault}, { diff --git a/apps/demos/src/nav-items.ts b/apps/demos/src/nav-items.ts index 6d1a72dab6..db6b43028e 100644 --- a/apps/demos/src/nav-items.ts +++ b/apps/demos/src/nav-items.ts @@ -453,6 +453,10 @@ export const DT_DEMOS_EXAMPLE_NAV_ITEMS = [ name: 'calendar-min-max-example', route: '/calendar-min-max-example', }, + { + name: 'timepicker-min-max-example', + route: '/timepicker-min-max-example', + }, ], }, { diff --git a/apps/dev/src/datepicker/datepicker-demo.component.html b/apps/dev/src/datepicker/datepicker-demo.component.html index d4208e3e84..d06f6f726a 100644 --- a/apps/dev/src/datepicker/datepicker-demo.component.html +++ b/apps/dev/src/datepicker/datepicker-demo.component.html @@ -31,7 +31,7 @@

Calendar with min and max date

>Show Calendar Today Button -
+
Minimum date: {{ formattedMinDate }}
Maximum date: {{ formattedMaxDate }}
Dark Mode Timepicker > Disabled
+ +

Timepicker with min and max hour and minute

+ + + Minimum hour for timepicker: {{ minHourTimepicker }} + + + + Maximum hour for timepicker: {{ maxHourTimepicker }} + + + + Minimum minute for timepicker: {{ minMinuteTimepicker }} + + + + Maximum minute for timepicker: {{ maxMinuteTimepicker }} + + + + diff --git a/apps/dev/src/datepicker/datepicker-demo.component.scss b/apps/dev/src/datepicker/datepicker-demo.component.scss index f8f4a02d3b..fc8e47ba56 100644 --- a/apps/dev/src/datepicker/datepicker-demo.component.scss +++ b/apps/dev/src/datepicker/datepicker-demo.component.scss @@ -2,13 +2,21 @@ margin-top: 10px; } +.dt-checkbox + .dt-checkbox { + margin-left: 10px; +} + .dt-example-dark h2 { color: white; } -.dt-calendar-limit-wrapper { +.dt-limit-wrapper { display: grid; grid-template-columns: 1fr 1fr; row-gap: 10px; margin-bottom: 10px; } + +.dt-timepicker { + margin-top: 10px; +} diff --git a/apps/dev/src/datepicker/datepicker-demo.component.ts b/apps/dev/src/datepicker/datepicker-demo.component.ts index b4a8e2a10e..a8cffec01b 100644 --- a/apps/dev/src/datepicker/datepicker-demo.component.ts +++ b/apps/dev/src/datepicker/datepicker-demo.component.ts @@ -24,6 +24,10 @@ import { DtDatePicker } from '@dynatrace/barista-components/experimental/datepic styleUrls: ['datepicker-demo.component.scss'], }) export class DatepickerDemo { + minHourTimepicker = ''; + maxHourTimepicker = ''; + minMinuteTimepicker = ''; + maxMinuteTimepicker = ''; startAt = new Date(2020, 7, 31); minDate = new Date(2020, 5, 31); maxDate = new Date(2020, 11, 31); diff --git a/libs/barista-components/experimental/datepicker/README.md b/libs/barista-components/experimental/datepicker/README.md index b439795880..00df1df45c 100644 --- a/libs/barista-components/experimental/datepicker/README.md +++ b/libs/barista-components/experimental/datepicker/README.md @@ -132,3 +132,7 @@ The following methods are on the `DtDatepicker` class: ## Calendar with limited date range + +## Timepicker with limited hour or minutes ranges + + diff --git a/libs/barista-components/experimental/datepicker/barista.json b/libs/barista-components/experimental/datepicker/barista.json index 6901701790..78d661e0b9 100644 --- a/libs/barista-components/experimental/datepicker/barista.json +++ b/libs/barista-components/experimental/datepicker/barista.json @@ -1,6 +1,6 @@ { - "title": "Datepicker", - "description": "ToDo", + "title": "Datepicker (experimental)", + "description": "Datepicker with or without an embedded timepicker for selecting a date with the option of adding a time", "postid": "datepicker", "identifier": "Da", "category": "components", @@ -28,5 +28,6 @@ ] }, "properties": ["work in progress", "experimental"], - "tags": ["datepicker", "component", "angular"] + "tags": ["datepicker", "component", "angular"], + "imageUrl": "https://dt-cdn.net/images/barista-preview-datepicker-307-c5c958d02e.png" } diff --git a/libs/barista-components/experimental/datepicker/src/calendar-body.scss b/libs/barista-components/experimental/datepicker/src/calendar-body.scss index 9108368d34..f2c25d150d 100644 --- a/libs/barista-components/experimental/datepicker/src/calendar-body.scss +++ b/libs/barista-components/experimental/datepicker/src/calendar-body.scss @@ -55,4 +55,5 @@ .dt-calendar-cell-disabled { color: $disabledcolor; + cursor: not-allowed; } diff --git a/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.spec.ts b/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.spec.ts index e57e00ba6d..caecf59030 100644 --- a/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.spec.ts +++ b/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.spec.ts @@ -21,6 +21,7 @@ import { isValid, isPastedTimeValid, isOutsideMinMaxRange, + hasMininmumTwoDigits, } from './util'; import { DtNativeDateAdapter } from '@dynatrace/barista-components/core'; @@ -36,6 +37,37 @@ describe('timeinput', () => { }); }); + describe('hasMininmumTwoDigits', () => { + it('should return true if a number with at least two digits is passed in', () => { + expect(hasMininmumTwoDigits(15)).toBeTruthy(); + expect(hasMininmumTwoDigits(20)).toBeTruthy(); + expect(hasMininmumTwoDigits(123)).toBeTruthy(); + }); + it('should return false if a number with less than two digits is passed in', () => { + expect(hasMininmumTwoDigits(5)).toBeFalsy(); + expect(hasMininmumTwoDigits(2)).toBeFalsy(); + expect(hasMininmumTwoDigits(0)).toBeFalsy(); + }); + it('should return true if a string representing a number with at least two digits is passed in (e.g. if there is a leading 0)', () => { + expect(hasMininmumTwoDigits('15')).toBeTruthy(); + expect(hasMininmumTwoDigits('20')).toBeTruthy(); + expect(hasMininmumTwoDigits('02')).toBeTruthy(); + expect(hasMininmumTwoDigits('05')).toBeTruthy(); + expect(hasMininmumTwoDigits('00')).toBeTruthy(); + }); + it('should return false if a string representing a number with less than two digits is passed in', () => { + expect(hasMininmumTwoDigits('5')).toBeFalsy(); + expect(hasMininmumTwoDigits('2')).toBeFalsy(); + expect(hasMininmumTwoDigits('0')).toBeFalsy(); + }); + it('should return false if empty values are passed in', () => { + expect(hasMininmumTwoDigits('')).toBeFalsy(); + expect(hasMininmumTwoDigits(' ')).toBeFalsy(); + expect(hasMininmumTwoDigits(' ')).toBeFalsy(); + expect(hasMininmumTwoDigits(null)).toBeFalsy(); + }); + }); + describe('isOutsideMinMaxRange', () => { const dateAdapter = new DtNativeDateAdapter(); it('should return true if a date earlier than the minDate is passed in', () => { diff --git a/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.ts b/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.ts index fd25720b59..9d600ea2f9 100644 --- a/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.ts +++ b/libs/barista-components/experimental/datepicker/src/datepicker-utils/util.ts @@ -15,6 +15,7 @@ */ import { + clamp, DtDateAdapter, isEmpty, isNumberLike, @@ -76,13 +77,25 @@ export function isOutsideMinMaxRange( } /** Check if the hour value is valid. */ -export function isValidHour(value: any): boolean { - return isValid(value, MIN_HOURS, MAX_HOURS); +export function isValidHour( + value: any, + min?: string | number | null, + max?: string | number | null, +): boolean { + let minHour = getParsedMinHour(min); + let maxHour = getParsedMaxHour(max); + return isValid(value, minHour, maxHour); } /** Check if the minute value is valid. */ -export function isValidMinute(value: any): boolean { - return isValid(value, MIN_MINUTES, MAX_MINUTES); +export function isValidMinute( + value: any, + min?: string | number | null, + max?: string | number | null, +): boolean { + let minMinute = getParsedMinMinute(min); + let maxMinute = getParsedMaxMinute(max); + return isValid(value, minMinute, maxMinute); } /** @@ -90,12 +103,16 @@ export function isValidMinute(value: any): boolean { * Note that if a number is passed directly in with the format 'n.0', such as 5.0, it will be truncated to 5 and validation will fail. * However, this cannot happen with the input event, since it will be passed as a string. Also, typing '.' is prevented on keydown. */ -export function isValid(value: any, min: number, max: number): boolean { +export function isValid( + value: any, + min: string | number, + max: string | number, +): boolean { if (isEmpty(value) || !isNumberLike(value)) { return false; } - // the regex is necessary for invalidating chars like '-' or '.', as well as multiple leading 0s. + // the regex is necessary for invalidating chars like '-' or '.', as well as multiple leading zeros. const stringifiedVal = isString(value) ? value : value.toString(); if (stringifiedVal.match(INVALID_TIME_FORMAT_REGEX)) { return false; @@ -105,9 +122,12 @@ export function isValid(value: any, min: number, max: number): boolean { return parsedValue >= min && parsedValue <= max; } -/** Check if a number has at least two digits or is null. */ -export function hasMininmumTwoDigits(input: number | null): boolean { - return input !== null && input >= 10; +/** Check if a passed in value has at least two digits. */ +export function hasMininmumTwoDigits(input: string | number | null): boolean { + return ( + input !== null && + (typeof input === 'string' ? input.trim().length >= 2 : input >= 10) + ); } /** @@ -122,3 +142,50 @@ export function valueTo2DigitString(value: number): string { export function isPastedTimeValid(value: string): boolean { return Boolean(value.match(HOURMIN_REGEX)); } + +/** Clamp the hour with the given min and max values. */ +export function clampHours( + hour: number, + min?: string | number | null, + max?: string | number | null, +): string { + const minHour = getParsedMinHour(min); + const maxHour = getParsedMaxHour(max); + return `${clamp(hour, minHour, maxHour)}`; +} + +/** Clamp the minute with the given min and max values. */ +export function clampMinutes( + minute: number, + min?: string | number | null, + max?: string | number | null, +): string { + const minMinute = getParsedMinMinute(min); + const maxMinute = getParsedMaxMinute(max); + return `${clamp(minute, minMinute, maxMinute)}`; +} + +function getParsedMinHour(min?: string | number | null): number { + const minHour = isString(min) ? parseInt(min) : min; + return !isEmpty(minHour) && minHour >= MIN_HOURS + ? Math.min(minHour, MAX_HOURS) + : MIN_HOURS; +} +function getParsedMaxHour(max?: string | number | null): number { + const maxHour = isString(max) ? parseInt(max) : max; + return !isEmpty(maxHour) && maxHour <= MAX_HOURS ? maxHour : MAX_HOURS; +} + +function getParsedMinMinute(min?: string | number | null): number { + const minMinute = isString(min) ? parseInt(min) : min; + return !isEmpty(minMinute) && minMinute >= MIN_MINUTES + ? Math.min(minMinute, MAX_MINUTES) + : MIN_MINUTES; +} + +function getParsedMaxMinute(max?: string | number | null): number { + const maxMinute = isString(max) ? parseInt(max) : max; + return !isEmpty(maxMinute) && maxMinute <= MAX_MINUTES + ? maxMinute + : MAX_MINUTES; +} diff --git a/libs/barista-components/experimental/datepicker/src/timeinput.html b/libs/barista-components/experimental/datepicker/src/timeinput.html index c9a1652d75..f36c5936f9 100644 --- a/libs/barista-components/experimental/datepicker/src/timeinput.html +++ b/libs/barista-components/experimental/datepicker/src/timeinput.html @@ -21,6 +21,7 @@ (keydown)="_handleKeydown($event)" (keyup)="_onHourKeyUp($event)" (paste)="_onTimePaste($event)" + (blur)="_onHourInputBlur()" aria-label="Please insert the hour" />
@@ -45,6 +46,7 @@ [ngModel]="minute" (input)="_handleMinuteInput($event)" (keydown)="_handleKeydown($event)" + (blur)="_onMinuteInputBlur()" aria-label="Please insert the minutes" /> diff --git a/libs/barista-components/experimental/datepicker/src/timeinput.spec.ts b/libs/barista-components/experimental/datepicker/src/timeinput.spec.ts index de8ea514dd..45298a2491 100644 --- a/libs/barista-components/experimental/datepicker/src/timeinput.spec.ts +++ b/libs/barista-components/experimental/datepicker/src/timeinput.spec.ts @@ -108,6 +108,8 @@ describe('DtTimeInput', () => { it('should switch focus from the hour to the minute input when typing in 2 digits in the hour input', fakeAsync(() => { component.timeInput.minute = null; component.timeInput.hour = 14; + component.timeInput._hourInput.nativeElement.value = '14'; + component.timeInput._minuteInput.nativeElement.value = ''; fixture.detectChanges(); dispatchKeyboardEvent(hourEl, 'keyup', NUMPAD_ONE); @@ -120,6 +122,8 @@ describe('DtTimeInput', () => { it('should switch focus from the hour to the minute input when typing in 2 digits in the hour input, but the minute input only had a valid 1 digit value', fakeAsync(() => { component.timeInput.hour = 15; component.timeInput.minute = 3; + component.timeInput._hourInput.nativeElement.value = '15'; + component.timeInput._minuteInput.nativeElement.value = '3'; fixture.detectChanges(); dispatchKeyboardEvent(hourEl, 'keyup', NUMPAD_ONE); @@ -132,6 +136,7 @@ describe('DtTimeInput', () => { it('should not switch focus from the hour to the minute input when typing in only one digit in the hour input', fakeAsync(() => { component.timeInput.minute = null; component.timeInput.hour = 1; + component.timeInput._hourInput.nativeElement.value = '1'; fixture.detectChanges(); dispatchKeyboardEvent(hourEl, 'keyup', NUMPAD_ONE); @@ -143,6 +148,8 @@ describe('DtTimeInput', () => { it('should not switch focus from the hour to the minute input when typing in 2 digits in the hour input, but the minute input already had a valid 2 digit value', fakeAsync(() => { component.timeInput.hour = 15; + component.timeInput._hourInput.nativeElement.value = '15'; + component.timeInput._minuteInput.nativeElement.value = '53'; fixture.detectChanges(); dispatchKeyboardEvent(hourEl, 'keyup', NUMPAD_ONE); diff --git a/libs/barista-components/experimental/datepicker/src/timeinput.ts b/libs/barista-components/experimental/datepicker/src/timeinput.ts index ace6d699b5..3be07d9172 100644 --- a/libs/barista-components/experimental/datepicker/src/timeinput.ts +++ b/libs/barista-components/experimental/datepicker/src/timeinput.ts @@ -29,11 +29,13 @@ import { ViewEncapsulation, } from '@angular/core'; import { - isDefined, isEmpty, + isString, _readKeyCode, } from '@dynatrace/barista-components/core'; import { + clampHours, + clampMinutes, hasMininmumTwoDigits, isPastedTimeValid, isValidHour, @@ -90,6 +92,18 @@ export class DtTimeInput { } private _minute: number | null = null; + /** The minimum selectable hour. */ + @Input() minHour: number | null = null; + + /** The minimum selectable minute. */ + @Input() minMinute: number | null = null; + + /** The maximum selectable hour. */ + @Input() maxHour: number | null = null; + + /** The maximum selectable minute. */ + @Input() maxMinute: number | null = null; + /** Binding for the disabled state. */ @Input() get disabled(): boolean { @@ -128,14 +142,17 @@ export class DtTimeInput { /** * @internal * Add the focus switch from the hour input to the minute input when the user typed in 2 digits. + * Note: the nativeElement values are used here because otherwise the number values with leading zeros + * would be converted to 1 digit (e.g. 05 would be 5), which would falsely evaluate as 1 digit numbers + * and not switch the focus. */ _onHourKeyUp(event: KeyboardEvent): void { const keyCode = _readKeyCode(event); if ( keyCode !== SHIFT && keyCode !== TAB && - hasMininmumTwoDigits(this._hour) && - !hasMininmumTwoDigits(this._minute) + hasMininmumTwoDigits(this._hourInput.nativeElement.value) && + !hasMininmumTwoDigits(this._minuteInput.nativeElement.value) ) { this._minuteInput.nativeElement.focus(); } @@ -151,6 +168,26 @@ export class DtTimeInput { } } + /** + * @internal + * Called on hour input blur and check the min - max limits to validate the hour. + */ + _onHourInputBlur(): void { + this._handleHourInputValidation(this.hour, this.minHour, this.maxHour); + } + + /** + * @internal + * Called on minute input blur and check the min - max limits to validate the minute. + */ + _onMinuteInputBlur(): void { + this._handleMinuteInputValidation( + this.minute, + this.minMinute, + this.maxMinute, + ); + } + /** * @internal Handler for the user's hour input events. * NOTE: If keydown event is used to prevent adding invalid input, @@ -164,17 +201,21 @@ export class DtTimeInput { /** * @internal Check if the hour input is valid and set the new value accordingly. */ - _handleHourInputValidation(value: string): void { - if (isValidHour(value)) { - this._hour = parseInt(value, 10); + _handleHourInputValidation( + value: string | number | null, + min?: number | null, + max?: number | null, + ): void { + if (isValidHour(value, min, max)) { + this._hour = isString(value) ? parseInt(value, 10) : value; } else { // reset the value to something valid - use fallback value if it exists and the new value is not empty, otherwise reset to empty if (isEmpty(value)) { this._hour = null; } - this._hourInput.nativeElement.value = isDefined(this._hour) - ? `${this._hour}` + this._hourInput.nativeElement.value = !isEmpty(this._hour) + ? clampHours(this._hour, this.minHour, this.maxHour) : ''; } @@ -190,15 +231,20 @@ export class DtTimeInput { /** * @internal Check if the minute input is valid and set the new value accordingly. */ - _handleMinuteInputValidation(value: string): void { - if (isValidMinute(value)) { - this._minute = parseInt(value, 10); + _handleMinuteInputValidation( + value: string | number | null, + min?: number | null, + max?: number | null, + ): void { + if (isValidMinute(value, min, max)) { + this._minute = isString(value) ? parseInt(value, 10) : value; } else { if (isEmpty(value)) { this._minute = null; } - this._minuteInput.nativeElement.value = isDefined(this._minute) - ? `${this._minute}` + + this._minuteInput.nativeElement.value = !isEmpty(this._minute) + ? clampMinutes(this._minute, this.minMinute, this.maxMinute) : ''; } diff --git a/libs/barista-components/experimental/datepicker/src/timepicker.html b/libs/barista-components/experimental/datepicker/src/timepicker.html index 4fb4da3585..c09da58d00 100644 --- a/libs/barista-components/experimental/datepicker/src/timepicker.html +++ b/libs/barista-components/experimental/datepicker/src/timepicker.html @@ -7,6 +7,10 @@ [disabled]="disabled" [hour]="hour" [minute]="minute" + [minHour]="minHour" + [minMinute]="minMinute" + [maxHour]="maxHour" + [maxMinute]="maxMinute" > diff --git a/libs/barista-components/experimental/datepicker/src/timepicker.ts b/libs/barista-components/experimental/datepicker/src/timepicker.ts index cb32a2e749..04e27ddd10 100644 --- a/libs/barista-components/experimental/datepicker/src/timepicker.ts +++ b/libs/barista-components/experimental/datepicker/src/timepicker.ts @@ -53,6 +53,18 @@ export class DtTimepicker { @Input() minute: number | null; + /** The minimum selectable hour. */ + @Input() minHour: number | null = null; + + /** The minimum selectable minute. */ + @Input() minMinute: number | null = null; + + /** The maximum selectable hour. */ + @Input() maxHour: number | null = null; + + /** The maximum selectable minute. */ + @Input() maxMinute: number | null = null; + /** * @internal * Property used for enabling the time range mode. diff --git a/libs/examples/src/datepicker/BUILD.bazel b/libs/examples/src/datepicker/BUILD.bazel index a6c0f66731..0db75511a8 100644 --- a/libs/examples/src/datepicker/BUILD.bazel +++ b/libs/examples/src/datepicker/BUILD.bazel @@ -16,16 +16,20 @@ ng_module( "datepicker-dark-example/datepicker-dark-example.html", "datepicker-default-example/datepicker-default-example.html", "calendar-min-max-example/calendar-min-max-example.html", + "timepicker-min-max-example/timepicker-min-max-example.html", ":styles_dark_example", ":styles_default_example", - ":styles_min_max_example", + ":styles_calendar_min_max_example", + ":styles_timepicker_min_max_example", ], module_name = "@dynatrace/barista-examples/datepicker", tsconfig = "//libs/examples:tsconfig_lib", deps = [ "//libs/barista-components/checkbox:compile", + "//libs/barista-components/input:compile", "//libs/barista-components/core:compile", "//libs/barista-components/experimental/datepicker:compile", + "//libs/barista-components/form-field:compile", "//libs/barista-components/theming:compile", "@npm//@angular/core", "@npm//@angular/forms", @@ -43,10 +47,15 @@ sass_binary( ) sass_binary( - name = "styles_min_max_example", + name = "styles_calendar_min_max_example", src = "calendar-min-max-example/calendar-min-max-example.scss", ) +sass_binary( + name = "styles_timepicker_min_max_example", + src = "timepicker-min-max-example/timepicker-min-max-example.scss", +) + stylelint( name = "stylelint", srcs = glob(["**/*.scss"]), diff --git a/libs/examples/src/datepicker/calendar-min-max-example/calendar-min-max-example.html b/libs/examples/src/datepicker/calendar-min-max-example/calendar-min-max-example.html index 5cc50c6648..a0c8a7f4db 100644 --- a/libs/examples/src/datepicker/calendar-min-max-example/calendar-min-max-example.html +++ b/libs/examples/src/datepicker/calendar-min-max-example/calendar-min-max-example.html @@ -1,10 +1,8 @@ -

Calendar with min and max date

- Enable Calendar Today Button -
+
Minimum date: {{ formattedMinDate }}
Maximum date: {{ formattedMaxDate }}
+ Minimum hour: {{ minHour }} + + + + Maximum hour: {{ maxHour }} + + + + Minimum minute: {{ minMinute }} + + + + Maximum minute: {{ maxMinute }} + + + + diff --git a/libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.scss b/libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.scss new file mode 100644 index 0000000000..a5a11093ba --- /dev/null +++ b/libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.scss @@ -0,0 +1,11 @@ +.dt-checkbox { + margin-bottom: 20px; +} + +.dt-checkbox + .dt-checkbox { + margin-left: 10px; +} + +.dt-timepicker { + margin-top: 10px; +} diff --git a/libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.ts b/libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.ts new file mode 100644 index 0000000000..7f0309c628 --- /dev/null +++ b/libs/examples/src/datepicker/timepicker-min-max-example/timepicker-min-max-example.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Dynatrace LLC + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'dt-example-timepicker-minmax', + templateUrl: 'timepicker-min-max-example.html', + styleUrls: ['timepicker-min-max-example.scss'], +}) +export class DtExampleTimepickerMinMax { + minHour = ''; + maxHour = ''; + minMinute = ''; + maxMinute = ''; +} diff --git a/libs/examples/src/index.ts b/libs/examples/src/index.ts index 1899ebafd8..bf4dfda490 100644 --- a/libs/examples/src/index.ts +++ b/libs/examples/src/index.ts @@ -334,6 +334,7 @@ import { DtExampleTreeTableSimple } from './tree-table/tree-table-simple-example import { DtExampleComboboxCustomOptionHeight } from './combobox/combobox-custom-option-height-example/combobox-custom-option-height-example'; import { DtExampleFilterFieldInfiniteDataDepth } from './filter-field/filter-field-infinite-data-depth-example/filter-field-infinite-data-depth-example'; import { DtExampleCalendarMinMax } from './datepicker/calendar-min-max-example/calendar-min-max-example'; +import { DtExampleTimepickerMinMax } from './datepicker/timepicker-min-max-example/timepicker-min-max-example'; import { DtExampleDatepickerDark } from './datepicker/datepicker-dark-example/datepicker-dark-example'; import { DtExampleDatepickerDefault } from './datepicker/datepicker-default-example/datepicker-default-example'; @@ -712,6 +713,7 @@ export { DtExampleFilterFieldInfiniteDataDepth, DtExampleSelectCustomValueTemplate, DtExampleCalendarMinMax, + DtExampleTimepickerMinMax, DtExampleDatepickerDark, DtExampleDatepickerDefault, }; @@ -831,6 +833,7 @@ export const EXAMPLES_MAP = new Map>([ ['DtExampleDrawerOver', DtExampleDrawerOver], ['DtExampleDrawerTableDefault', DtExampleDrawerTableDefault], ['DtExampleCalendarMinMax', DtExampleCalendarMinMax], + ['DtExampleTimepickerMinMax', DtExampleTimepickerMinMax], ['DtExampleDatepickerDark', DtExampleDatepickerDark], ['DtExampleDatepickerDefault', DtExampleDatepickerDefault], ['DtExampleCustomEmptyStateTable', DtExampleCustomEmptyStateTable],