diff --git a/projects/demo-app/src/app/app.component.html b/projects/demo-app/src/app/app.component.html
index 52d0f77a..b345abc9 100644
--- a/projects/demo-app/src/app/app.component.html
+++ b/projects/demo-app/src/app/app.component.html
@@ -38,6 +38,12 @@
hug/ngx-components Demo
Splitter
+
+
+ access_time
+ Timpe Picker
+
+
diff --git a/projects/demo-app/src/app/app.routes.ts b/projects/demo-app/src/app/app.routes.ts
index 9f7ce28f..82ffcdc5 100644
--- a/projects/demo-app/src/app/app.routes.ts
+++ b/projects/demo-app/src/app/app.routes.ts
@@ -7,5 +7,6 @@ export const appRoutes: Routes = [
{ path: 'overlay', loadComponent: () => import('./overlay/overlay-demo.component').then(m => m.OverlayDemoComponent), data: { title: 'Overlay' } },
{ path: 'snackbar', loadComponent: () => import('./snackbar/snackbar-demo.component').then(m => m.SnackbarDemoComponent), data: { title: 'Snackbar' } },
{ path: 'splitter', loadComponent: () => import('./splitter/splitter-demo.component').then(m => m.SplitterDemoComponent), data: { title: 'Splitter' } },
+ { path: 'time-picker', loadComponent: () => import('./time-picker/time-picker-demo.component').then(m => m.TimePickerDemoComponent), data: { title: 'Time Picker' } },
{ path: '**', redirectTo: 'message-box', pathMatch: 'prefix' }
];
diff --git a/projects/demo-app/src/app/message-box/message-box-demo.component.ts b/projects/demo-app/src/app/message-box/message-box-demo.component.ts
index 06458e37..f0ea203f 100644
--- a/projects/demo-app/src/app/message-box/message-box-demo.component.ts
+++ b/projects/demo-app/src/app/message-box/message-box-demo.component.ts
@@ -27,9 +27,9 @@ import { Subject, switchMap, takeUntil } from 'rxjs';
]
})
export class MessageBoxDemoComponent extends Destroy {
- public tabIndex = 1;
+ protected tabIndex = 1;
- public closeAction = [
+ protected closeAction = [
{
action: (): void => alert('test action'),
icon: 'clear'
diff --git a/projects/demo-app/src/app/numeric-stepper/numeric-stepper-demo.component.ts b/projects/demo-app/src/app/numeric-stepper/numeric-stepper-demo.component.ts
index 923bfe30..842a50fc 100644
--- a/projects/demo-app/src/app/numeric-stepper/numeric-stepper-demo.component.ts
+++ b/projects/demo-app/src/app/numeric-stepper/numeric-stepper-demo.component.ts
@@ -8,7 +8,7 @@ import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { Destroy } from '@hug/ngx-core';
import { NumericStepperComponent } from '@hug/ngx-numeric-stepper';
-import { debounceTime, distinctUntilChanged, map, Subject, takeUntil } from 'rxjs';
+import { Subject, debounceTime, distinctUntilChanged, map, takeUntil } from 'rxjs';
interface NumberFormControls {
numberValue3: FormControl;
@@ -47,19 +47,19 @@ const numberValidator = (control: AbstractControl): string[] | null => {
]
})
export class NumericStepperDemoComponent extends Destroy {
- public tabIndex = 1;
+ protected tabIndex = 1;
- public value1 = 90;
- public value2 = 9.5;
- public value3 = 5;
- public value4 = 1;
- public value5 = 1;
- public value6 = 1;
- public value6min = 0;
- public value6max = 20;
+ protected value1 = 90;
+ protected value2 = 9.5;
+ protected value3 = 5;
+ protected value4 = 1;
+ protected value5 = 1;
+ protected value6 = 1;
+ protected value6min = 0;
+ protected value6max = 20;
- public numberForm: FormGroup;
- public onInput1Change$ = new Subject();
+ protected numberForm: FormGroup;
+ protected onInput1Change$ = new Subject();
private changeDetectorRef = inject(ChangeDetectorRef);
private formBuilder = inject(FormBuilder);
@@ -85,19 +85,19 @@ export class NumericStepperDemoComponent extends Destroy {
});
}
- public changeValue3(step: number): void {
+ protected changeValue3(step: number): void {
this.numberForm.controls.numberValue3.setValue(+this.numberForm.controls.numberValue3.value + step);
}
- public changeValue4(step: number): void {
+ protected changeValue4(step: number): void {
this.numberForm.controls.numberValue4.setValue(+this.numberForm.controls.numberValue4.value + step);
}
- public changeValue5(step: number): void {
+ protected changeValue5(step: number): void {
this.numberForm.controls.numberValue5.setValue(+this.numberForm.controls.numberValue5.value + step);
}
- public changeValue6(step: number): void {
+ protected changeValue6(step: number): void {
const value = Math.max(Math.min(+this.numberForm.controls.numberValue6.value + step, this.value6max), this.value6min);
this.numberForm.controls.numberValue6.setValue(value);
}
diff --git a/projects/demo-app/src/app/overlay/overlay-demo.component.ts b/projects/demo-app/src/app/overlay/overlay-demo.component.ts
index 8506dc0e..a0f135dc 100644
--- a/projects/demo-app/src/app/overlay/overlay-demo.component.ts
+++ b/projects/demo-app/src/app/overlay/overlay-demo.component.ts
@@ -31,21 +31,21 @@ export class OverlayDemoComponent {
@ViewChild('contextMenu')
private contextMenu?: OverlayComponent;
- public selected = '';
- public items = [
+ protected selected = '';
+ protected items = [
{ text: 'Refresh' },
{ text: 'Settings' },
{ text: 'Help', disabled: true },
{ text: 'Sign Out' }
];
- public tabIndex = 1;
+ protected tabIndex = 1;
- public select(text: string): void {
+ protected select(text: string): void {
this.selected = text;
}
- public onContextMenu(event: MouseEvent): boolean {
+ protected onContextMenu(event: MouseEvent): boolean {
const parent = event.currentTarget as HTMLElement;
const parentRect = parent.getBoundingClientRect();
this.contextMenu?.show(event.pageX - parentRect.left, event.pageY - parentRect.top);
diff --git a/projects/demo-app/src/app/snackbar/snackbar-demo.component.ts b/projects/demo-app/src/app/snackbar/snackbar-demo.component.ts
index 6f1335d8..94270b0e 100644
--- a/projects/demo-app/src/app/snackbar/snackbar-demo.component.ts
+++ b/projects/demo-app/src/app/snackbar/snackbar-demo.component.ts
@@ -8,7 +8,7 @@ import { MatToolbarModule } from '@angular/material/toolbar';
import { MessageBoxComponent } from '@hug/ngx-message-box';
import { SnackbarComponent } from '@hug/ngx-snackbar';
import { StatusService, StatusType } from '@hug/ngx-status';
-import { defaultIfEmpty, filter, from, interval, map, Observable, scan, shareReplay } from 'rxjs';
+import { Observable, defaultIfEmpty, filter, from, interval, map, scan, shareReplay } from 'rxjs';
class Message {
public constructor(public content = 'Some snackbar', public gate = true) { }
@@ -34,21 +34,21 @@ class Message {
]
})
export class SnackbarDemoComponent {
- public tabIndex = 1;
+ protected tabIndex = 1;
/*
The example below demonstrate how you can dynamically add snackbars using *ngFor structural directive.
Here the Observable simulate items being push from the server
*/
- public messages$: Observable;
+ protected messages$: Observable;
- public dangers$: Observable;
- public warnings$: Observable;
- public successes$: Observable;
- public infos$: Observable;
+ protected dangers$: Observable;
+ protected warnings$: Observable;
+ protected successes$: Observable;
+ protected infos$: Observable;
- public push = new EventEmitter();
+ protected push = new EventEmitter();
- public simpleGate = false;
+ protected simpleGate = false;
private statusService = inject(StatusService);
diff --git a/projects/demo-app/src/app/time-picker/time-picker-demo.component.html b/projects/demo-app/src/app/time-picker/time-picker-demo.component.html
new file mode 100644
index 00000000..cc5c720d
--- /dev/null
+++ b/projects/demo-app/src/app/time-picker/time-picker-demo.component.html
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+ Basic Time Picker with ngModel and ngModelChange event
+
+
+
+
Without initial hours and minutes (null)
+
+
+
+
Selected : {{ date0 | date: 'HH:mm' }}
+
+
+
With initial hours and minutes (09:05)
+
+
+
+
Selected : {{ date1 | date: 'HH:mm' }}
+
+
+
+
+
+ Time Picker modes
+
+
+
+
With hours disabled
+
+
+
+
Selected date : {{ date2 | date: 'HH:mm' }}
+
+
+
With minutes disabled
+
+
+
+
Selected date : {{ date3 | date: 'HH:mm' }}
+
+
+
With hours displayed only
+
+
+
+
Selected date : {{ date4 | date: 'HH:mm' }}
+
+
+
With minutes displayed only inline in a form
+
+
+
+
+
+
+
Selected date : {{ date5 | date: 'HH:mm' }}
+
+
+
+
+
+ Time Picker disable
+
+
+
+
Time Picker disabled
+
+
+
+
+ Disable time-picker
+
+
Selected date : {{ date6 | date: 'HH:mm' }}
+
+
+
+
+
+ Time Picker form control
+
+
+
+
+
diff --git a/projects/demo-app/src/app/time-picker/time-picker-demo.component.scss b/projects/demo-app/src/app/time-picker/time-picker-demo.component.scss
new file mode 100644
index 00000000..341baf4f
--- /dev/null
+++ b/projects/demo-app/src/app/time-picker/time-picker-demo.component.scss
@@ -0,0 +1,42 @@
+app-time-picker-demo {
+ .flex-layout {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+
+ > div,
+ > form {
+ flex: 1 1 auto;
+ }
+ }
+
+ .flex-layout-center {
+ display: flex;
+ align-items: center;
+ }
+
+ .time-picker-actions {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-evenly;
+ }
+
+ /* Override Material datepicker style */
+ .mat-calendar-body-cell-content.mat-focus-indicator {
+ position: absolute !important;
+ }
+
+ .mat-datepicker-content-container {
+ flex-direction: row !important;
+ }
+
+ .mat-datepicker-actions {
+ margin-left: 64px !important;
+ }
+
+ time-picker[inform] {
+ padding-right: 1rem;
+ }
+}
diff --git a/projects/demo-app/src/app/time-picker/time-picker-demo.component.ts b/projects/demo-app/src/app/time-picker/time-picker-demo.component.ts
new file mode 100644
index 00000000..8601c2f1
--- /dev/null
+++ b/projects/demo-app/src/app/time-picker/time-picker-demo.component.ts
@@ -0,0 +1,136 @@
+/*
+ * @license
+ * Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
+ *
+ * Use of this source code is governed by an Apache-2.0 license that can be
+ * found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
+ */
+
+import { DatePipe, NgIf } from '@angular/common';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewEncapsulation } from '@angular/core';
+import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatCardModule } from '@angular/material/card';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+import { MAT_DATE_FORMATS } from '@angular/material/core';
+import { MatDatepickerInputEvent } from '@angular/material/datepicker';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatTabsModule } from '@angular/material/tabs';
+import { MatToolbarModule } from '@angular/material/toolbar';
+import { TimePickerComponent } from '@hug/ngx-time-picker';
+
+export const myFormats = {
+ parse: {
+ dateInput: 'DD/MM/YYYY HH:mm'
+ },
+ display: {
+ dateInput: 'DD/MM/YYYY HH:mm',
+ monthYearLabel: 'MMM YYYY',
+ dateA11yLabel: 'DD/MM/YYYY HH:mm',
+ monthYearA11yLabel: 'MMMM YYYY'
+ }
+};
+
+interface DateFormControl {
+ date7: FormControl;
+}
+
+@Component({
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ selector: 'app-time-picker-demo',
+ styleUrls: ['./time-picker-demo.component.scss'],
+ templateUrl: './time-picker-demo.component.html',
+ encapsulation: ViewEncapsulation.None,
+ standalone: true,
+ imports: [
+ DatePipe,
+ FormsModule,
+ MatCardModule,
+ MatCheckboxModule,
+ MatInputModule,
+ MatFormFieldModule,
+ MatTabsModule,
+ MatToolbarModule,
+ ReactiveFormsModule,
+ TimePickerComponent,
+ NgIf
+ ],
+ providers: [
+ { provide: MAT_DATE_FORMATS, useValue: myFormats }
+ ]
+})
+export class TimePickerDemoComponent {
+ protected tabIndex = 1;
+
+ protected date0: Date | null = null;
+ protected date1 = new Date(2021, 4, 6, 9, 5, 0);
+ protected date2 = new Date();
+ protected date3 = new Date();
+ protected date4 = new Date();
+ protected date5 = new Date();
+ protected date6 = new Date();
+ protected date7 = new Date(2021, 4, 28, 12, 55, 0);
+ protected disable6 = true;
+ protected dateForm: FormGroup;
+ protected fakeInput = '';
+
+ public constructor(private changeDetectorRef: ChangeDetectorRef) {
+ this.dateForm = new FormGroup({
+ date7: new FormControl(this.date7, { nonNullable: true })
+ });
+ }
+
+ protected matDateChange(event: MatDatepickerInputEvent): void {
+ const date = event.value;
+ if (!date || !this.date0) {
+ return;
+ }
+ const clone = new Date(date);
+ clone.setHours(this.date0.getHours());
+ clone.setMinutes(this.date0.getMinutes());
+ this.date0 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date0Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date0 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date1Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date1 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date2Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date2 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date3Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date3 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date4Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date4 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date5Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date5 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+
+ protected date6Changed(date: Date): void {
+ const clone = date && new Date(date.getTime());
+ this.date6 = clone;
+ this.changeDetectorRef.markForCheck();
+ }
+}