diff --git a/CHANGELOG.md b/CHANGELOG.md
index 563f70ac175..b1ed6061abc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
All notable changes for each version of this project will be documented in this file.
+
+## 7.1.2
+### Features
+- `IgxTimePickerComponent`: in addition to the current dialog interaction mode, now the user can select or edit a time value, using an editable masked input with a dropdown.
+
## 7.1.1
### Bug Fixes
@@ -14,6 +19,7 @@ All notable changes for each version of this project will be documented in this
### Other
* update typedoc-plugin-localization version to 1.4.1 ([#3440](https://github.com/IgniteUI/igniteui-angular/issues/3440))
+
## 7.1.0
### Features
- **New component** `IgxBannerComponent`:
@@ -40,6 +46,7 @@ All notable changes for each version of this project will be documented in this
- `IgxOverlayService`:
- `ElasticPositioningStrategy` added. This strategy positions the element as in **Connected** positioning strategy and resize the element to fit in the view port in case the element is partially getting out of view.
+
## 7.0.5
### Bug Fixes
@@ -60,6 +67,7 @@ All notable changes for each version of this project will be documented in this
* update typedoc-plugin-localization version to 1.4.1 ([#3440](https://github.com/IgniteUI/igniteui-angular/issues/3440))
* Move all keyboard navigation tests in a separate file ([#2975](https://github.com/IgniteUI/igniteui-angular/issues/2975))
+
## 7.0.4
### Bug fixes
- Fix(igx-grid): revert row editing styles ([#2672](https://github.com/IgniteUI/igniteui-angular/issues/2672))
diff --git a/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-component.scss
index b827e7b8c0c..cdabb3b3a8a 100644
--- a/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-component.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-component.scss
@@ -1,90 +1,71 @@
@include b(igx-time-picker) {
+ @extend %time-picker-display !optional;
@include e(header) {
- @extend %igx-time-picker__header !optional;
+ @extend %time-picker__header !optional;
}
@include e(header-ampm) {
- @extend %igx-time-picker__header-ampm !optional;
+ @extend %time-picker__header-ampm !optional;
}
@include e(header-hour){
- @extend %igx-time-picker__header-hour !optional;
+ @extend %time-picker__header-hour !optional;
+ }
+
+ @include e(main) {
+ @extend %time-picker__main !optional;
}
// COLUMN
@include e(column) {
- @extend %igx-time-picker__column !optional;
+ @extend %time-picker__column !optional;
}
@include e(item) {
- @extend %igx-time-picker__item !optional;
+ @extend %time-picker__item !optional;
}
@include e(item, $mod: selected) {
- @extend %igx-time-picker__item--selected !optional;
+ @extend %time-picker__item--selected !optional;
}
@include e(item, $m: active) {
- @extend %igx-time-picker__item--active !optional;
+ @extend %time-picker__item--active !optional;
}
// HOUR
@include e(hourList) {
- @extend %igx-time-picker__hourList !optional;
+ @extend %time-picker__hourList !optional;
}
-
// MINUTE
@include e(minuteList) {
- @extend %igx-time-picker__minuteList !optional;
+ @extend %time-picker__minuteList !optional;
}
// AM PM
@include e(ampmList) {
- @extend %igx-time-picker__ampmList !optional;
+ @extend %time-picker__ampmList !optional;
}
@include e(body) {
- @extend %igx-time-picker__body !optional;
+ @extend %time-picker__body !optional;
}
- .igx-dialog__window {
- @extend %time-picker-display !optional;
+ @include e(buttons) {
+ @extend %time-picker__buttons !optional;
}
- @include m(vertical) {
- .igx-dialog__window {
- @extend %time-picker-display--vertical !optional;
- }
-
- .igx-time-picker__wrapper {
- @extend %igx-time-picker__wrapper !optional;
- }
-
- .igx-time-picker__header {
- @extend %igx-time-picker__header--vertical !optional;
-
- &::after {
- @extend %igx-time-picker__header--vertical-after !optional;
- }
- }
-
- .igx-time-picker__body {
- @extend %igx-time-picker__body--vertical !optional;
- }
- }
-
- .igx-dialog__window,
- .igx-dialog__window-content {
- @extend %time-picker-content !optional;
+ @include m(dropdown) {
+ @extend %time-picker--dropdown !optional;
}
- .igx-dialog__window-title {
- @extend %time-picker-dialog-title !optional;
- }
+ @include m(vertical) {
+ @extend %time-picker-display--vertical !optional;
- .igx-dialog__window-actions {
- @extend %time-picker-dialog-actions !optional;
+ @include e(header) {
+ @extend %time-picker__header--vertical !optional;
+ }
}
}
diff --git a/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss
index dacd15c91f2..81aaea7aeaa 100644
--- a/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss
@@ -92,31 +92,35 @@
$vertical-header-width: rem(168px);
- %igx-time-picker__body {
+ %time-picker-display {
display: flex;
- padding: 10px 0;
- justify-content: center;
- background: --var($theme, 'background-color');
+ flex-flow: column nowrap;
+ max-width: 340px;
+ min-width: 320px;
+ border-radius: rem(4px);
+ box-shadow: igx-elevation($elevations, 24);
+ overflow: hidden;
}
- %igx-time-picker__body--vertical {
- flex: 1 1 auto;
+ %time-picker-display--vertical {
+ flex-flow: row nowrap;
+ min-width: 540px;
}
- %time-picker-display {
- max-width: 340px;
- min-width: 320px;
- padding: 0;
+ %time-picker__main {
+ background: --var($theme, 'background-color');
+ flex: 1 1 auto;
}
- %time-picker-display--vertical {
- width: 540px;
+ %time-picker--dropdown {
+ min-width: 200px;
+ box-shadow: igx-elevation($elevations, 3);
}
- // Take effect only in vertical mode
- %igx-time-picker__wrapper {
+ %time-picker__body {
display: flex;
- flex-wrap: nowrap;
+ padding: 10px 0;
+ justify-content: center;
}
%time-picker-content {
@@ -134,21 +138,21 @@
margin: 0;
}
- %igx-time-picker__hourList {
+ %time-picker__hourList {
text-align: right;
}
- %igx-time-picker__minuteList {
+ %time-picker__minuteList {
text-align: center;
}
- %igx-time-picker__ampmList {
+ %time-picker__ampmList {
display: flex;
flex-direction: column;
padding-top: 48px;
}
- %igx-time-picker__column {
+ %time-picker__column {
max-width: 64px;
height: 325px;
padding: 0;
@@ -166,7 +170,7 @@
}
}
- %igx-time-picker__item {
+ %time-picker__item {
width: 54px;
padding: 5px 10px;
border-radius: 15px;
@@ -185,48 +189,44 @@
}
}
- %igx-time-picker__item--selected {
+ %time-picker__item--selected {
font-size: rem(24px);
color: --var($theme, 'selected-text-color');
}
- %igx-time-picker__item--active {
+ %time-picker__item--active {
background: --var($theme, 'active-item-background');
}
- %igx-time-picker__header {
+ %time-picker__header {
background: --var($theme, 'header-background');
padding: rem(24px) rem(16px);
}
- %igx-time-picker__header-ampm {
+ %time-picker__header-ampm {
color: --var($theme, 'header-time-period-color');
}
- %igx-time-picker__header--vertical {
+ %time-picker__header--vertical {
width: $vertical-header-width;
- position: relative;
}
- %igx-time-picker__header--vertical-after {
- content: '';
- position: absolute;
- left: 0;
- right: 0;
- top: 100%;
- height: 100%;
- background: --var($theme, 'header-background');
- }
-
- %igx-time-picker__header-hour {
- color: --var($theme, 'header-hour-text-color');
+ %time-picker__header-hour {
display: flex;
+ color: --var($theme, 'header-hour-text-color');
}
- %igx-time-picker__header-ampm,
- %igx-time-picker__header-hour {
+ %time-picker__header-ampm,
+ %time-picker__header-hour {
margin: 0;
}
+
+ %time-picker__buttons {
+ display: flex;
+ justify-content: flex-end;
+ height: rem(52px);
+ padding: rem(8px);
+ }
}
/// Adds typography styles for the igx-calendar component.
@@ -246,15 +246,15 @@
$content: map-get($categories, 'content');
@include igx-scope('.igx-typography') {
- %igx-time-picker__header-ampm {
+ %time-picker__header-ampm {
@include igx-type-style($type-scale, $time-period);
}
- %igx-time-picker__header-hour {
+ %time-picker__header-hour {
@include igx-type-style($type-scale, $header-hour);
}
- %igx-time-picker__column {
+ %time-picker__column {
@include igx-type-style($type-scale, $content);
}
}
diff --git a/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts
index 245deeb6128..6436cd2558d 100644
--- a/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts
+++ b/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts
@@ -1,4 +1,4 @@
-import { Component, Input, ViewChild, OnInit, ElementRef, Pipe, PipeTransform } from '@angular/core';
+import { Component, Input, ViewChild, ElementRef, Pipe, PipeTransform } from '@angular/core';
import {
async,
fakeAsync,
@@ -68,6 +68,7 @@ describe('igxMask', () => {
input.nativeElement.dispatchEvent(new Event('focus'));
tick();
+ fixture.detectChanges();
expect(input.nativeElement.value).toEqual('555 55');
@@ -81,6 +82,7 @@ describe('igxMask', () => {
input.nativeElement.dispatchEvent(new Event('focus'));
tick();
+ fixture.detectChanges();
expect(input.nativeElement.value).toEqual('+359-884 19 08 54');
}));
@@ -296,23 +298,22 @@ describe('igxMask', () => {
it('Apply display and input pipes on blur and focus.', fakeAsync(() => {
const fixture = TestBed.createComponent(PipesMaskComponent);
fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
const input = fixture.componentInstance.input;
- input.nativeElement.focus();
+ input.nativeElement.dispatchEvent(new Event('focus'));
tick();
+ fixture.detectChanges();
expect(input.nativeElement.value).toEqual('SSS');
input.nativeElement.dispatchEvent(new Event('blur'));
tick();
+ fixture.detectChanges();
expect(input.nativeElement.value).toEqual('sss');
-
- input.nativeElement.dispatchEvent(new Event('focus'));
- tick();
-
- expect(input.nativeElement.value).toEqual('SSS');
}));
it('Apply placehodler when value is not defined.', fakeAsync(() => {
@@ -325,13 +326,13 @@ describe('igxMask', () => {
expect(input.nativeElement.placeholder).toEqual('hello');
input.nativeElement.dispatchEvent(new Event('focus'));
- tick();
+ fixture.detectChanges();
expect(input.nativeElement.value).toEqual('(__) (__)');
expect(input.nativeElement.placeholder).toEqual('hello');
input.nativeElement.dispatchEvent(new Event('blur'));
- tick();
+ fixture.detectChanges();
expect(input.nativeElement.value).toEqual('');
expect(input.nativeElement.placeholder).toEqual('hello');
diff --git a/projects/igniteui-angular/src/lib/directives/mask/mask.directive.ts b/projects/igniteui-angular/src/lib/directives/mask/mask.directive.ts
index d8fd233fc8e..cf0d61b1ea3 100644
--- a/projects/igniteui-angular/src/lib/directives/mask/mask.directive.ts
+++ b/projects/igniteui-angular/src/lib/directives/mask/mask.directive.ts
@@ -12,6 +12,7 @@ import {
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { KEYS, MaskHelper } from './mask-helper';
+import { isIE } from '../../core/utils';
const noop = () => { };
@@ -170,6 +171,8 @@ export class IgxMaskDirective implements OnInit, ControlValueAccessor {
*/
private _valOnPaste;
+ private _stopPropagation: boolean;
+
/**
*@hidden
*/
@@ -249,6 +252,11 @@ export class IgxMaskDirective implements OnInit, ControlValueAccessor {
*/
@HostListener('input', ['$event'])
public onInputChanged(event): void {
+ if (isIE() && this._stopPropagation) {
+ this._stopPropagation = false;
+ return;
+ }
+
if (this._paste) {
this._paste = false;
@@ -283,6 +291,9 @@ export class IgxMaskDirective implements OnInit, ControlValueAccessor {
@HostListener('focus', ['$event.target.value'])
public onFocus(value) {
if (this.focusedValuePipe) {
+ if (isIE()) {
+ this._stopPropagation = true;
+ }
this.value = this.focusedValuePipe.transform(value);
} else {
this.value = this.maskHelper.parseValueByMaskOnInit(this.value, this._maskOptions);
@@ -323,8 +334,9 @@ export class IgxMaskDirective implements OnInit, ControlValueAccessor {
this._maskOptions.promptChar = this.promptChar.substring(0, 1);
}
- if (value) {
- this.value = this.maskHelper.parseValueByMaskOnInit(value, this._maskOptions);
+ this.value = value ? this.maskHelper.parseValueByMaskOnInit(value, this._maskOptions) : '';
+ if (this.displayValuePipe) {
+ this.value = this.displayValuePipe.transform(this.value);
}
this.dataValue = this.includeLiterals ? this.value : value;
diff --git a/projects/igniteui-angular/src/lib/time-picker/README.md b/projects/igniteui-angular/src/lib/time-picker/README.md
index 578f3beea97..e3320be44ab 100644
--- a/projects/igniteui-angular/src/lib/time-picker/README.md
+++ b/projects/igniteui-angular/src/lib/time-picker/README.md
@@ -58,6 +58,15 @@ The TimePicker input group could be retemplated.
```
+The TimePicker supports another interaction mode - an editable masked input and a dropdown. The user can enter or edit the time value inside the text input or select a vlaue from a dropdown, that will be applied on the text input.
+```typescript
+mode = InteractionMode.dropdown;
+```
+
+```html
+
+
+```
# API
@@ -83,6 +92,8 @@ List of time-flags:
"mm": minutes field with leading zero
"tt": 2 characters of string which represents AM/PM field |
| `isSpinLoop` | boolean | Determines the spin behavior. By default `isSpinLoop` is set to true. |
+| `mode` | InteractionMode | Determines the interaction mode - a dialog picker or a dropdown with editable masked input. Default is dialog picker.|
+| `promptChar` | string | Sets the character used to prompt the user for input. The default is a dash. Only applicable for dropdown mode.
### Outputs
| Name | Description |
@@ -102,4 +113,4 @@ List of time-flags:
| `ampmInView` | | `string[]` | Returns an array of the ampm currently in view. |
| `scrollHourIntoView` | `(item: string)` | `void` | Scrolls a hour item into view. |
| `scrollMinuteIntoView` | `(item: string)` | `void` | Scrolls a minute item into view. |
-| `scrollAmPmIntoView` | `(item: string)` | `void` | Scrolls a period item into view. |
\ No newline at end of file
+| `scrollAmPmIntoView` | `(item: string)` | `void` | Scrolls a period item into view. |
diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts
index a44fcbe06f2..e6ec19b6ddf 100644
--- a/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts
+++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts
@@ -12,6 +12,11 @@ export interface IgxTimePickerBase {
selectedHour: string;
selectedMinute: string;
selectedAmPm: string;
+ format: string;
+ promptChar: string;
+ cleared: boolean;
+ collapsed: boolean;
+ mode: TimePickerInteractionMode;
nextHour();
prevHour();
nextMinute();
@@ -23,4 +28,14 @@ export interface IgxTimePickerBase {
scrollHourIntoView(item: string): void;
scrollMinuteIntoView(item: string): void;
scrollAmPmIntoView(item: string): void;
+ hideOverlay(): void;
+ parseMask(preserveAmPm?: boolean): string;
+}
+
+/**
+ * Defines the posible values of the igxTimePicker's time selection mode.
+ */
+export enum TimePickerInteractionMode {
+ dialog,
+ dropdown
}
diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html
index 20da254c3a0..388b20af257 100644
--- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html
+++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html
@@ -1,3 +1,27 @@
+
+
+
+
+ access_time
+
+
+
+ clear
+
+
+
@@ -8,30 +32,35 @@
-
-
-