Skip to content
This repository was archived by the owner on Aug 7, 2020. It is now read-only.

Commit e2434da

Browse files
authored
feat(oui-timepicker): add timepicker component (#344)
1 parent af4e3dd commit e2434da

File tree

14 files changed

+388
-56
lines changed

14 files changed

+388
-56
lines changed

packages/oui-angular/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Switch from "@ovh-ui/oui-switch";
3939
import Tabs from "@ovh-ui/oui-tabs";
4040
import Textarea from "@ovh-ui/oui-textarea";
4141
import Tile from "@ovh-ui/oui-tile";
42+
import Timepicker from "@ovh-ui/oui-timepicker";
4243
import Tooltip from "@ovh-ui/oui-tooltip";
4344

4445
export default angular
@@ -84,6 +85,7 @@ export default angular
8485
Tabs,
8586
Textarea,
8687
Tile,
88+
Timepicker,
8789
Tooltip
8890
])
8991
.name;

packages/oui-calendar/README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,16 @@ Use `mode` to set a different selection mode for the calendar
160160
* `selectedDates` returns an array of Date objects selected by the user. When there are no dates selected, the array is empty.
161161
* `dateStr` returns a string representation of the latest selected Date object by the user. The string is formatted as per the `dateFormat` option.
162162

163+
## Variants
164+
165+
### Timepicker
166+
167+
See <a href="#!/oui-angular/timepicker">Action menu component</a>.
168+
169+
```html:preview
170+
<oui-timepicker model="$ctrl.timepickerModel" placeholder="HH:MM"></oui-timepicker>
171+
```
172+
163173
## API
164174

165175
| Attribute | Type | Binding | One-time Binding | Values | Default | Description
@@ -168,19 +178,19 @@ Use `mode` to set a different selection mode for the calendar
168178
| `id` | string | @? | yes | n/a | n/a | id attribute of the field
169179
| `name` | string | @? | yes | n/a | n/a | name attribute of the field
170180
| `placeholder` | string | @? | yes | n/a | n/a | placeholder text
171-
| `inline` | boolean | <? | no | `true`, `false` | `false` | show the calendar below the input
172-
| `static` | boolean | <? | no | `true`, `false` | `false` | position the calendar relatively to the input
173181
| `mode` | string | @? | yes | `single`, `multiple`, `range` | `single` | selection mode
174182
| `format` | string | @? | yes | See [Formatting Tokens](https://flatpickr.js.org/formatting/) | `Y-m-d` | format the date of the model
175183
| `alt-format` | string | @? | yes | See [Formatting Tokens](https://flatpickr.js.org/formatting/) | `Y-m-d` | format the date of the field. `format` is used if undefined
176184
| `append-to-body` | boolean | <? | yes | `true`, `false` | `false` | append the calendar to the body of the page
177-
| `inline` | boolean | <? | yes | `true`, `false` | `false` | show the calendar below the input in `inline-block`
185+
| `inline` | boolean | <? | no | `true`, `false` | `false` | show the calendar below the input
186+
| `static` | boolean | <? | no | `true`, `false` | `false` | position the calendar relatively to the input
178187
| `max-date` | object | <? | yes | See [Supplying Dates](https://flatpickr.js.org/examples/#supplying-dates-for-flatpickr) | n/a | specifies the maximum/latest date (inclusively) allowed for selection
179188
| `min-date` | object | <? | yes | See [Supplying Dates](https://flatpickr.js.org/examples/#supplying-dates-for-flatpickr) | n/a | specifies the minimum/earliest date (inclusively) allowed for selection
180189
| `disable-date` | array | <? | yes | See [Supplying Dates](https://flatpickr.js.org/examples/#supplying-dates-for-flatpickr) | n/a | make certain dates unavailable for selection
181190
| `enable-date` | array | <? | yes | See [Supplying Dates](https://flatpickr.js.org/examples/#supplying-dates-for-flatpickr) | n/a | make certain dates only available for selection
182191
| `enable-time` | boolean | <? | yes | `true`, `false` | `false` | enables time selection
183192
| `week-numbers` | boolean | <? | yes | `true`, `false` | `false` | week numbers flag
193+
| `options` | object | <? | yes | See [Options](https://flatpickr.js.org/options/) | n/a | flatpickr options for more advanced configuration
184194
| `disabled` | boolean | <? | no | `true`, `false` | `false` | disabled flag
185195
| `required` | boolean | <? | no | `true`, `false` | `false` | required flag
186196
| `on-change` | function | & | no | n/a | n/a | handler triggered when the user selects a date, or changes the time on a selected date

packages/oui-calendar/src/calendar.component.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ export default {
1414

1515
appendToBody: "<?",
1616
inline: "<?",
17+
"static": "<?",
1718
maxDate: "<?",
1819
minDate: "<?",
1920
disableDate: "<?",
2021
enableDate: "<?",
21-
2222
enableTime: "<?",
23+
weekNumbers: "<?",
24+
25+
options: "<?",
2326

2427
disabled: "<?",
2528
required: "<?",
26-
weekNumbers: "<?",
2729

2830
onChange: "&",
2931
onClose: "&",

packages/oui-calendar/src/calendar.controller.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
import { addBooleanParameter } from "@ovh-ui/common/component-utils";
1+
import { addBooleanParameter, addDefaultParameter } from "@ovh-ui/common/component-utils";
22
import Flatpickr from "flatpickr";
3+
import merge from "lodash/merge";
34

45
export default class {
5-
constructor ($attrs, $element, $timeout, ouiCalendarConfiguration) {
6+
constructor ($attrs, $element, $scope, $timeout, ouiCalendarConfiguration) {
67
"ngInject";
78

89
this.$attrs = $attrs;
910
this.$element = $element;
11+
this.$id = $scope.$id;
1012
this.$timeout = $timeout;
1113
this.locale = ouiCalendarConfiguration.locale;
12-
this.options = angular.copy(ouiCalendarConfiguration.options);
14+
this.config = angular.copy(ouiCalendarConfiguration.options);
1315
}
1416

1517
setModelValue (value) {
@@ -19,7 +21,7 @@ export default class {
1921
setEventHooks (hooks) {
2022
// Add a callback for each events
2123
hooks.forEach((hook) => {
22-
this.options[hook] = (selectedDates, dateStr) => {
24+
this.config[hook] = (selectedDates, dateStr) => {
2325
this.model = dateStr;
2426
this.$timeout(this[hook]({ selectedDates, dateStr }));
2527
};
@@ -28,11 +30,15 @@ export default class {
2830

2931
setOptionsProperty (property, value) {
3032
if (angular.isDefined(value)) {
31-
this.options[property] = value;
33+
this.config[property] = value;
3234
}
3335
}
3436

3537
initCalendarInstance () {
38+
if (this.options) {
39+
this.config = merge(this.config, this.options);
40+
}
41+
3642
// Set options from attributes
3743
this.setOptionsProperty("appendTo", this.appendTo);
3844
this.setOptionsProperty("defaultDate", this.model);
@@ -50,7 +56,7 @@ export default class {
5056
this.setOptionsProperty("dateFormat", this.format);
5157

5258
if (angular.isDefined(this.altFormat)) {
53-
this.setOptionsProperty("altInput", true);
59+
this.setOptionsProperty("altInput", !this.disabled);
5460
this.setOptionsProperty("altFormat", this.altFormat);
5561
}
5662

@@ -76,18 +82,22 @@ export default class {
7682
});
7783

7884
// Init the flatpickr instance
79-
this.flatpickr = new Flatpickr(this.$element.find("input")[0], this.options);
85+
this.flatpickr = new Flatpickr(this.$element.find("input")[0], this.config);
8086
}
8187

8288
$onInit () {
8389
addBooleanParameter(this, "appendToBody");
8490
addBooleanParameter(this, "disabled");
8591
addBooleanParameter(this, "enableTime");
8692
addBooleanParameter(this, "inline");
93+
addBooleanParameter(this, "noCalendar");
8794
addBooleanParameter(this, "required");
8895
addBooleanParameter(this, "static");
8996
addBooleanParameter(this, "weekNumbers");
9097

98+
addDefaultParameter(this, "id", `ouiCalendar${this.$id}`);
99+
addDefaultParameter(this, "name", `ouiCalendar${this.$id}`);
100+
91101
this.initCalendarInstance();
92102
}
93103

@@ -96,16 +106,20 @@ export default class {
96106
}
97107

98108
$postLink () {
99-
// Avoid $element DOM unsync for jqLite methods
100109
this.$timeout(() => {
110+
const controls = angular.element(this.$element[0].querySelectorAll(".oui-calendar__control"));
111+
101112
this.$element
102113
.addClass("oui-calendar")
103114
.removeAttr("id")
104115
.removeAttr("name");
105116

106-
// Add class for `inline`
117+
// Avoid 'alt-input' to take bad value of placeholder
118+
controls.attr("placeholder", this.placeholder);
119+
107120
if (this.inline) {
108121
this.$element.addClass("oui-calendar_inline");
122+
controls.attr("type", "hidden");
109123
}
110124
});
111125
}

packages/oui-calendar/src/calendar.html

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,7 @@
33
autocomplete="off"
44
ng-attr-id="{{::$ctrl.id}}"
55
ng-attr-name="{{::$ctrl.name}}"
6-
ng-attr-placeholder="{{::$ctrl.placeholder}}"
76
ng-model="$ctrl.model"
87
ng-disabled="$ctrl.disabled"
98
ng-required="$ctrl.required" />
109
</div>
11-
<!-- TEMP: Waiting for UI (Uncomment specs too)
12-
<button type="button"
13-
ng-disabled="$ctrl.disabled"
14-
ng-click="$ctrl.setModelValue('today')">
15-
Today
16-
</button>
17-
<button type="button"
18-
ng-disabled="$ctrl.disabled"
19-
ng-show="$ctrl.model.length"
20-
ng-click="$ctrl.setModelValue()">
21-
Reset
22-
</button> -->

packages/oui-calendar/src/index.spec.js

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ describe("ouiCalendar", () => {
6565

6666
$timeout.flush();
6767

68-
expect(controller.options.inline).toBe(true);
68+
expect(controller.config.inline).toBe(true);
6969
expect(component.hasClass("oui-calendar_inline")).toBe(true);
7070
});
7171

@@ -76,7 +76,7 @@ describe("ouiCalendar", () => {
7676

7777
$timeout.flush();
7878

79-
expect(controller.options.appendTo).toBeUndefined();
79+
expect(controller.config.appendTo).toBeUndefined();
8080
expect(calendar).toBeNull();
8181
});
8282

@@ -98,6 +98,8 @@ describe("ouiCalendar", () => {
9898
const component = testUtils.compileTemplate('<oui-calendar model="$ctrl.model" placeholder="foo"></oui-calendar>');
9999
const input = component.find("input");
100100

101+
$timeout.flush();
102+
101103
expect(input.attr("placeholder")).toBe("foo");
102104
});
103105

@@ -106,7 +108,7 @@ describe("ouiCalendar", () => {
106108
const ctrl = component.controller("ouiCalendar");
107109

108110
ctrl.setOptionsProperty("foo", "bar");
109-
expect(ctrl.options.foo).toBe("bar");
111+
expect(ctrl.config.foo).toBe("bar");
110112
});
111113

112114
it("should change the value formatting of the model and the input", () => {
@@ -124,9 +126,9 @@ describe("ouiCalendar", () => {
124126
const input = component[0].querySelector(".oui-calendar__control");
125127
const altInput = component[0].querySelector(".oui-calendar__control_alt");
126128

127-
expect(ctrl.options.dateFormat).toBe(format);
128-
expect(ctrl.options.altInput).toBe(true);
129-
expect(ctrl.options.altFormat).toBe(altFormat);
129+
expect(ctrl.config.dateFormat).toBe(format);
130+
expect(ctrl.config.altInput).toBe(true);
131+
expect(ctrl.config.altFormat).toBe(altFormat);
130132
expect(input.value).toBe(formatDate);
131133
expect(altInput.value).toBe(altFormatDate);
132134
});
@@ -136,7 +138,7 @@ describe("ouiCalendar", () => {
136138
const ctrl = component.controller("ouiCalendar");
137139

138140
ctrl.setEventHooks(["foo"]);
139-
expect(typeof ctrl.options.foo).toBe("function");
141+
expect(typeof ctrl.config.foo).toBe("function");
140142
});
141143

142144
it("should call function of events attributes", () => {
@@ -153,7 +155,7 @@ describe("ouiCalendar", () => {
153155
onOpenSpy
154156
});
155157
const ctrl = component.controller("ouiCalendar");
156-
const today = ctrl.flatpickr.parseDate("today", ctrl.options.dateFormat);
158+
const today = ctrl.flatpickr.parseDate("today", ctrl.config.dateFormat);
157159

158160
ctrl.setModelValue(today);
159161
expect(onChangeSpy).toHaveBeenCalledWith([today], ctrl.model);
@@ -162,26 +164,5 @@ describe("ouiCalendar", () => {
162164
ctrl.flatpickr.close();
163165
expect(onCloseSpy).toHaveBeenCalledWith([today], ctrl.model);
164166
});
165-
166-
// it("should set the value to today's date when 'today' button is clicked", () => {
167-
// const component = testUtils.compileTemplate('<oui-calendar model="$ctrl.model"></oui-calendar>');
168-
// const ctrl = component.controller("ouiCalendar");
169-
// const button = component.find("button").eq(0);
170-
// const today = ctrl.flatpickr.formatDate(new Date(), ctrl.options.dateFormat);
171-
172-
// button.triggerHandler("click");
173-
// expect(ctrl.model).toBe(today);
174-
// });
175-
176-
// it("should reset the value when 'reset' button is clicked", () => {
177-
// const component = testUtils.compileTemplate('<oui-calendar model="$ctrl.model"></oui-calendar>', {
178-
// model: "today"
179-
// });
180-
// const ctrl = component.controller("ouiCalendar");
181-
// const button = component.find("button").eq(1);
182-
183-
// button.triggerHandler("click");
184-
// expect(ctrl.model).toBe("");
185-
// });
186167
});
187168
});

0 commit comments

Comments
 (0)