-
Notifications
You must be signed in to change notification settings - Fork 162
Time Picker Specification
- Overview
- User Stories
- Functionality
- Test Scenarios
- Accessibility
- Assumptions and Limitations
- References
Team Name
Developer Name
Yoanna Ivanova
- Peer Developer Name | Date:
- Stefan Ivanov | Date: 17 Feb 2021
- Radoslav Mirchev | Date:
- Damyan Petev | Date:
Version | Users | Date | Notes |
---|---|---|---|
1 | Names of Developers and Designers | Date |
IgxTimePicker
- Angular native time picker widget, that lets users input or select a time portion. The display and input formats are customizable.
In dropdown mode, which is the default one, the input field is editable and the user can type time or select one from the dropdown that appears below the input field.
In dialog mode the user experience includes a read-only input that holds time in the following format by default - hh:mm a
. Clicking on the input will result in a dropdown pop-up that holds time portions from which the end-user may select a value.
Here is the basic definition of an igx-time-picker
:
<igx-time-picker [(ngModel)]="time">
<label igxLabel>Select time</label>
</igx-time-picker>
- Selecting a time portion from the dropdown
- Dropdown mode (by default) and dialog mode for the dropdown
- Typing, pasting, dragging, and dropping a time string (in a pre-defined format) into the editor (dropdown mode)
- Support for min and max value, custom validation with bound model
- Model binding
- Customizable input mask and display format
- Localization
- Keyboard navigation in the editor with specified key combinations for expanding and collapsing of the dropdown (dropdown mode) igxDateTimeEditor keyboard navigation
- Keyboard/mouse navigation through each time portion in the editor and the dropdown
- Changing the orientation of the dropdown's header (dialog mode only) - horizontal or vertical
- Customizable positioning and open/close animation of the dropdown
- Customizable action buttons
- ARIA support
Setting the label:
<igx-time-picker>
<label igxLabel>Custom Label</label>
</igx-time-picker>
The igxPrefix
and igxSuffix
directives may be used to project elements before and after the input field.
You can add multiple instances of the igxPrefix
and igxSuffix
directives which will stack one after the other. For example, these could be used to provide the end-user with the ability to spin a time portion with two buttons. Also, having projected icons like this will not affect the default toggle icon.
<igx-time-picker #picker>
<igx-icon (click)="picker.increment(DatePart.Minutes, 2)" igxSuffix>expand_more</igx-icon>
<igx-icon (click)="picker.decrement(DatePart.Minutes, 2)" igxSuffix>expand_less</igx-icon>
</igx-time-picker>
Additionally, the IgxPickerToggleComponent
can be used as wrapper around a projected element. This adds a default click handler to it. It should also be mentioned that this acts as an override to the default toggle icon and as such it can not be stacked.
<igx-time-picker>
<igx-picker-toggle igxPrefix>
<igx-icon>access_time</igx-icon>
</igx-picker-toggle>
</igx-time-picker>
The default action buttons(OK and Cancel) in the drop down can be customized by using ng-template.
<igx-time-picker #picker [value]="date">
<ng-template igxPickerActions>
<div class="action-buttons">
<button igxButton="flat" (click)="selectCurrentTime(picker)">Current Time</button>
</div>
</ng-template>
</igx-time-picker>
All user stories must be satisfied.
Developer stories:
- Story 1: As a developer, I want to be able to choose whether to show the picker in a dropdown or a dialog.
- Story 2: As a developer, I want to be able to set the default time format.
- Story 3: As a developer, I want to be able to set the time format based on users' locale.
- Story 4: As a developer, I want to have support for 12H/24H with a 12-hour clock format AM/PM accordingly.
- Story 5: As a developer, I want to be able to set whether the seconds, minutes, and hour spinning will wrap around.
- Story 6: As a developer, I want to be able to set the delta by which hour and minute items will be changed.
- Story 7: As a developer, I want to be able to set a time range to limit user selection within that range.
- Story 8: As a developer, I want to be able to customize the handling in case the user selects time outside the allowed range.
- Story 9: As a developer, I want to be able to bind
ngModel
to the time picker. - Story 10: As a developer, I want to have a mechanism for canceling the opening and closing of the time picker dropdown/dialog.
- Story 11: As a developer, I want to be able to provide custom formatting functionality.
- Story 12: As a developer, I want to be able to set the label of the time picker input field.
- Story 13: As a developer, I want to be able to customize the style and look of the input field.
- Story 14: As a developer, I want to have a default template that does not require any additional configuration.
- Story 15: As a developer, I want to be able to customize the buttons shown on the picker interface.
- Story 16: As a developer, I want to be able to change the header orientation to horizontal or vertical (dialog mode only).
- Story 17: As a developer, I want to be able to customize the position and animation of the dropdown.
End-user stories:
- Story 1: As an end-user, I want to be able to visually differentiate the selected time.
- Story 2: As an end-user, I want to have a clear visual highlighting of the currently focused time portion.
- Story 3: As an end-user, I want to be able to select the desired time from a dropdown/dialog.
- Story 4: As an end-user, I want to be able to navigate the time portions and change their values via the keyboard arrow keys or by scrolling in the input field and in the dropdown/dialog.
- Story 5: As an end-user, I want to be able to edit the time portions in the input (dropdown mode only).
- Story 6: As an end-user, I want to be able to discard any changes via the cancel button (identical behavior hitting the ESC key).
- Story 7: As an end-user, I want to be able to confirm my current time selection via the OK button or a click outside the picker (identical behavior hitting the ENTER key).
- Story 8: As an end-user, I expect to have a clear indication of when a range is specified to limit the possible selections (if such is specified).
- Story 9: As an end-user, I want to be informed if the time I've entered is valid.
- Story 10: As an end-user, I want to be able to clear the selected time.
- Story 11: As an end-user, I expect to see time in my locale standard e.g. 12hr mode with AM/PM vs. a 24hr mode.
-
Time input or selection
- When
IgxTimePicker
is in a dropdown mode (default mode), the user can either type a time portion in the input field, select time from its dropdown, and press the confirmation buttonOK
(by default)/press theenter
key, or click outside which will fill in the input field with the corresponding value. Pressing theCANCEL
button (by default) orescape
key will revert any selection made to the time picker's value at the moment of dropdown opening. In dialog mode, the input is read-only so the user can select a time portion from its dropdown and press the confirmation buttonOK
(by default), press theenter
key, or click outside the dialog, which will fill in the input field with the corresponding value. Pressing theCANCEL
button (by default) orescape
key will revert any selection made. Any of these actions results in hiding the dropdown and dialog when pressed. - When the value is a string pressing the clear button will set it to null. However if the value is a Date object, pressing the clear button will reset the time to
00:00:00
.
- When
-
Dropdown/Dialog
- Each time portion navigation
- Selected time highlight (incl. header in dialog mode)
-
Custom date display format
- The
IgxTimePicker
makes use of IgxDateTimeEditor which allows passing in of display format based on Angular DatePipe's standards. - Custom formatting can be applied using the
inputFormat
property.
- The
-
Time Validation (min/max check)
- Min and max values can be set which can configure the validity of the picker. Additionally, the picker's UI will display all time parts that are outside of the min-max range as grayed out and they will not be selectable from its UI. If a time span that is outside of the specified range is written in the editable editor, the picker will become invalid after blurring (by default).
3.1. End-User Experience
A user can select a time from the dropdown, be it in dropdown or dialog mode. In dropdown mode, the user will additionally be able to type, copy/paste, drag/drop values in the input field. Opening of the dropdown menu is achieved by clicking on the toggle icon or via the keyboard. In dialog mode, the input will always be read-only, and clicking anywhere on it opens the dialog. The user can navigate each time portion separately with arrow keys or mouse wheel. While in dialog mode time portion navigation is possible only from the picker interface, in dropdown mode this is possible in both the dropdown and the input. The caret position in the input signifies which time portion will be incremented/decremented. A header is shown only in dialog mode displayed in a horizontal or vertical orientation.
Filled Input Dropdown/Dialog Mode
Focused Input in Editable Dropdown Mode
Dropdown Mode (default) 24H
Dialog Mode 12H (the header in horizontal orientation)
Dialog Mode 12H (the header in vertical orientation)
3.2. Developer Experience
By default, the time picker will be in a dropdown mode with an editable input. Templating of icons, hint, etc. is achieved through content projection.
3.3. Globalization/Localization
- locale property
- supports date pipe formats
3.4. Keyboard Navigation
Keys | Description |
---|---|
Space | Opens the dropdown/dialog picker interface and focuses it |
Alt + ↓ | Opens the dropdown picker interface and focuses it |
Esc | Closes the dropdown/dialog and focuses the last focused input field |
Enter | Closes the dropdown/dialog, applying the selected time and moves the focus to the last focused input field |
Alt + ↑ | Closes the dropdown/dialog and focuses the last focused input field |
- For keyboard navigation inside of an editable editor please refer to IgxDateTimeEditorDirective specification
The Time Picker integrates with Angular's Form Control allowing ngModel
and formControlName
directives to be applied on the component. Given that, when the underlying model becomes invalid the Time Picker will reflect that visually. This allows for any built-in (e.g. required
) as well as custom validators applied to be reflected in the component state. The Time Picker also implements the Validator
interface so the minValue
and maxValue
options will also affect the validity of the model (rather than just the editor).
3.5. API
Name | Description | Type |
---|---|---|
cancelButtonLabel | Sets the text of the cancel button label. | string |
disabled | Disables or enables the picker. | boolean |
displayFormat | The display value of the editor. | string |
headerOrientation | Determines whether the dialog's header renders in vertical or horizontal state. Applies only in dialog mode. |
'horizontal' | 'vertical' |
id | Sets the value of the id attribute. | string |
inputFormat | The format that the editor will use to display the time. | string |
maxValue | The maximum time value that can be set. | Date | string |
minValue | The minimum time value that can be set. | Date | string |
mode | Sets whether IgxTimePickerComponent is in dialog or dropdown mode. |
InteractionMode |
okButtonLabel | Sets the text of the ok button label. | string |
outlet | The container used for the pop-up element. | IgxOverlayOutletDirective | ElementRef |
overlaySettings | Changes the default overlay settings used by the IgxTimePickerComponent . |
OverlaySettings |
placeholder | Sets the placeholder text for empty input. | string |
spinDelta | Sets the threshold by which each time portion would be changed. | object |
spinLoop | Sets whether the time spinning will wrap around. Default is true . |
boolean |
tabindex | The editor's tabindex. | number |
value | The value of the time picker. | Date |
Name | Description | Return type |
---|---|---|
open | Opens the dropdown. | void |
close | Closes the dropdown. | void |
toggle | Toggles the dropdown between opened and closed states. | void |
select | Accepts a Date object and selects the corresponding time from the dropdown. | void |
increment | Increments a given DatePart by a given threshold. |
void |
decrement | Decrements a given DatePart by a given threshold. |
void |
scrollHourIntoView | Scrolls an hour item into view. | void |
scrollMinuteIntoView | Scrolls a minute item into view. | void |
scrollSecondIntoView | Scrolls a second item into view. | void |
scrollAmPmIntoView | Scrolls between AM and PM item into view. | void |
Name | Description | Emitted with |
---|---|---|
opening | Fired when the dropdown has started opening, cancelable. | IBaseCancelableBrowserEventArgs |
opened | Fired after the dropdown has opened. | IBaseEventArgs |
closing | Fired when the dropdown has started closing, cancelable. | IBaseCancelableBrowserEventArgs |
closed | Fired after the dropdown has closed. | IBaseEventArgs |
selecting | Fired before the picker finishes a selection, cancelable. | IBaseCancelableBrowserEventArgs |
selected | Fired when the selected time value has changed. | Date | string |
valueChange | Emitted when the picker's value changes. Allows two-way binding of value . |
IgxTimePickerValueChangedEventArgs |
validationFailed | Emitted when a user enters an invalid time string or when the value is not within a min/max range. ITimePickerValidationFailedEventArgs |
Interaction
- Scenario 1: Toggle icon should open/close the dropdown and keep the current selection.
- Scenario 2:
Alt
+ArrowDown
keys should open the dropdown; outside click closes it and the input accepts current selection. - Scenario 3:
Space
key opens the dropdown;Enter
key closes it and the input accepts current selection. - Scenario 4:
Escape
key closes the dropdown discarding the selected time in it. - Scenario 5: While the dropdown is open clicking outside the dropdown closes it and accepts the current selection.
- Scenario 6: In dialog mode outside click while the dialog is open closes it and accepts the current selection.
- Scenario 7: Selecting invalid time from the dropdown should trigger validationFailed event.
- Scenario 8: Clear button should reset the time value if the value is Date and clear it (set to null) if it is a string.
- Scenario 9: User is able to increase and decrease each time portion in the input, depending on the current caret position, using:
- arrows
- mouse wheel
- Scenario 10: User is able to increase and decrease each time portion in the UI, depending on the current caret position, using:
- arrows
- mouse wheel
- Scenario 11: User can navigate through time portions with arrow keys. If in dropdown mode the values in the input should change accordingly.
- Scenario 12: Setting spinLoop to false should stop looping the drop-down over "00:00" for the hours and "00" - "60" for the minutes.
- Scenario 13: Setting spinLoop to false should not accept values from the drop-down before/over the min/max values when they are set.
- Scenario 14: Setting spinLoop to false should prevent scrolling with mouse/arrows the input before/over the min/max values if they are set. If they are not set it should break at "00:00" for the hours and "00" - "60" for the minutes.
- Scenario 15: Should spin over time portions with the spinDelta value.
- Scenario 16: When setting the spinDelta to an invalid value, it should default to
{hours: 1, minutes: 1, seconds: 1}
. - Scenario 17: When spinLoop enabled in 12-hour format iterating over hours should loop from "11PM" to "12AM".
Rendering
- Scenario 1: All input properties are initialized with their default values.
- Scenario 2: Should be able to change the dropdown mode at runtime.
- Scenario 3: Selected times are highlighted.
- Scenario 4: When disabled the 'disabled' class is applied to the input.
- Scenario 5: Time portions outside the range of the min and max values will be grayed out by applying a disabled theme.
- Scenario 6: When in dialog mode, the selected time should be displayed in the dialog header.
- Scenario 7: All aria attributes should be applied correctly.
API
- Scenario 1: All ControlValueAccessor interface methods are correctly implemented.
- Scenario 2: The open() method opens the dropdown and triggers opening and opened events.
- Scenario 3: The close() method closes the dropdown and triggers closing and closed events.
- Scenario 4: The toggle() method opens/closes the dropdown and triggers opening/closing and opened/closed events.
- Scenario 5: Increment() and decrement() methods should change date parts correctly.
- Scenario 6: Opening and closing events are cancelable.
- Scenario 7: The select() method selects time and triggers selecting and selected events.
- Scenario 8: Selecting event is cancelable.
- Scenario 9: Selecting time within the minValue and maxValue range sets the value and fires valueChange event.
- Scenario 10: Selecting time outside the minValue and maxValue range does not set the value and triggers validationFailed event.
ARIA Support
The IgxTimePickerComponent
is decorated with the following properties:
Input ARIA
-
role
iscombobox
-
aria-haspopup
isdialog
-
aria-expanded
- indicates the expanded state of the dropdown -
aria-labelledby
- which relates to a specified label -
autocomplete
isoff
to prevent the browser from remembering previous inputs (when editable) - the default toggle icon will have a
title
that is initially set toChoose Time
, after selecting time from the picker, it will change toChange Time
, clearing the picker's value will revert thetitle
back to its initial state -
aria-required
- indicates whether the picker is required
Dialog ARIA
- spinbutton + label (either label should read the hour/minute or the entire time)
- role="dialog"
- trap the focus inside the dialog (until ESC) (implement that in the overlay).
RTL Support
Assumptions | Limitation Notes |
---|---|
Specify all referenced external sources