Skip to content

Commit

Permalink
fix(core/time-picker): make inputs editable (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
nuke-ellington committed May 5, 2023
1 parent 07fc8a4 commit 864eb14
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 52 deletions.
2 changes: 1 addition & 1 deletion packages/core/component-doc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8341,7 +8341,7 @@
{
"name": "timeReference",
"type": "\"AM\" | \"PM\"",
"mutable": false,
"mutable": true,
"attr": "time-reference",
"reflectToAttr": false,
"docs": "Set time reference",
Expand Down
34 changes: 19 additions & 15 deletions packages/core/src/components/time-picker/time-picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
.title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: bold;
line-height: 20px;
min-height: 40px;
font: var(--theme-text-default-title);
min-height: $large-control-height;
color: var(--theme-datepicker-time-header--color);
}

Expand All @@ -30,38 +28,40 @@
display: flex;
justify-content: center;
align-items: center;
padding: 80px 0;
padding: 5rem 0;
}

input {
background-color: var(--theme-input--background);
border-radius: 2px;
border: 1px solid var(--theme-input--border-color);
box-shadow: inset 0 2px 4px 0 var(--theme-color-1) 12;
width: 42px;
height: 32px;
text-align: right;
color: var(--theme-input--color);
input,
.time-reference {
width: 2.625rem;
height: $large-space;
text-align: center;
margin-top: $small-space;
margin-bottom: $small-space;

/* Chrome, Safari, Edge, Opera */
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0 5px;
margin: 0 0.3125rem;
}

/* Firefox */
&[type='number'] {
-moz-appearance: textfield;
}

}

.form-control[type=number] {
text-align: center;
}

.columns {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}

.column-seperator {
Expand All @@ -86,3 +86,7 @@ input {
.hidden {
display: none;
}

.time-reference {
margin: $medium-space 0;
}
190 changes: 154 additions & 36 deletions packages/core/src/components/time-picker/time-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class TimePicker {
/**
* Set time reference
*/
@Prop() timeReference: 'AM' | 'PM' = DateTime.fromFormat(
@Prop({ mutable: true }) timeReference: 'AM' | 'PM' = DateTime.fromFormat(
this.time,
this.format
).toFormat('a') as 'PM' | 'AM';
Expand Down Expand Up @@ -121,43 +121,123 @@ export class TimePicker {

private _time: DateTime = DateTime.now();

private updateInput(
step: 'up' | 'down',
{ hours = undefined, minutes = undefined, seconds = undefined }
private setInputValue(
inputElement: HTMLInputElement,
value: number,
max: number
) {
if (hours)
step === 'up' ? this.hourInputRef.stepUp() : this.hourInputRef.stepDown();
if (minutes)
step === 'up'
? this.minuteInputRef.stepUp()
: this.minuteInputRef.stepDown();
if (seconds)
step === 'up'
? this.secondInputRef.stepUp()
: this.secondInputRef.stepDown();
if (value > max) {
inputElement.value = max.toString();
} else if (value < 0) {
inputElement.value = '0';
} else {
inputElement.value = value.toString();
}

this.updateAndEmitTime();
}

private updateAndEmitTime() {
this._time = this._time.set({
hour: Number(this.hourInputRef.value),
minute: Number(this.minuteInputRef.value),
second: Number(this.secondInputRef.value),
});

this.setHourAccordingToReference();

this.emitTimeChange();
}

private toggleInputValue(
inputElement: HTMLInputElement,
currentValue: number,
step: 'up' | 'down',
max: number
) {
if (step === 'up') {
if (currentValue === max) {
inputElement.value = '0';
} else {
inputElement.stepUp();
}
} else {
if (currentValue === 0) {
inputElement.value = max.toString();
} else {
inputElement.stepDown();
}
}
}

private toggleHourInputWithRef(
inputElement: HTMLInputElement,
currentValue: number,
step: 'up' | 'down'
) {
if (step === 'up') {
if (currentValue === this.getMaxHour()) {
inputElement.value = '0';
} else {
inputElement.stepUp();
}
} else {
if (
(this.showTimeReference &&
this.timeReference === 'PM' &&
currentValue === 12) ||
currentValue === 0
) {
inputElement.value = this.getMaxDisplayedHour().toString();
} else {
inputElement.stepDown();
}
}
}

private updateInput(
step: 'up' | 'down',
{ hours = undefined, minutes = undefined, seconds = undefined }
) {
if (hours) {
if (this.showTimeReference) {
this.toggleHourInputWithRef(this.hourInputRef, this.hour, step);
} else {
this.toggleInputValue(this.hourInputRef, this.hour, step, 23);
}
}

if (minutes) {
this.toggleInputValue(this.minuteInputRef, this.minutes, step, 59);
}

if (seconds) {
this.toggleInputValue(this.secondInputRef, this.seconds, step, 59);
}

this.updateAndEmitTime();
}

private changeReference() {
this.referenceInputRef.value =
this.referenceInputRef.value === 'PM' ? 'AM' : 'PM';
if (this.timeReference === 'AM') {
this.timeReference = 'PM';
} else {
this.timeReference = 'AM';
}

this.setHourAccordingToReference();

this.emitTimeChange();
}

private setHourAccordingToReference() {
if (!this.showTimeReference) {
return;
}

let hour = Number(this.hourInputRef.value);

if (this.referenceInputRef.value === 'PM') hour += 12;
if (this.timeReference === 'PM') hour += 12;

this._time = this._time.set({ hour });
}
Expand Down Expand Up @@ -185,14 +265,38 @@ export class TimePicker {
return this._time.toFormat(this.format);
}

private getDisplayedHour() {
if (this.showTimeReference && this.timeReference === 'PM') {
return this._time.hour - 12;
}

return this._time.hour;
}

private getMaxDisplayedHour() {
if (this.showTimeReference) {
return 11;
}

return 23;
}

private getMaxHour() {
if (this.showTimeReference && this.timeReference === 'AM') {
return 11;
}

return 23;
}

render() {
let hideHour = !this.showHour;
let hideMinutes = !this.showMinutes;
let hideSeconds = !this.showSeconds;
const hideTimeReference = !this.showTimeReference;
const hideIndividual = !this.individual;

if (!this.showHour && !this.showMinutes && !this.showSeconds) {
if (hideHour && hideMinutes && hideSeconds) {
hideHour = false;
hideMinutes = false;
hideSeconds = false;
Expand All @@ -219,14 +323,21 @@ export class TimePicker {
class="arrows"
></ix-icon-button>
<input
class="form-control"
name="hours"
type="number"
placeholder="00"
value={this.hour}
placeholder="HH"
min="0"
disabled
max={this.showTimeReference === true ? 11 : 23}
max={this.getMaxDisplayedHour()}
value={this.getDisplayedHour()}
ref={(ref) => (this.hourInputRef = ref)}
onChange={() =>
this.setInputValue(
this.hourInputRef,
Number(this.hourInputRef.value),
this.getMaxDisplayedHour()
)
}
></input>
<ix-icon-button
size="16"
Expand Down Expand Up @@ -254,14 +365,21 @@ export class TimePicker {
class="arrows"
></ix-icon-button>
<input
class="form-control"
name="minutes"
type="number"
placeholder="00"
value={this.minutes}
placeholder="MM"
min="0"
max="59"
disabled
value={this.minutes}
ref={(ref) => (this.minuteInputRef = ref)}
onChange={() =>
this.setInputValue(
this.minuteInputRef,
Number(this.minuteInputRef.value),
59
)
}
></input>
<ix-icon-button
size="16"
Expand Down Expand Up @@ -289,14 +407,21 @@ export class TimePicker {
class="arrows"
></ix-icon-button>
<input
class="form-control"
name="seconds"
type="number"
placeholder="00"
value={this.seconds}
disabled
placeholder="SS"
min="0"
max="59"
value={this.seconds}
ref={(ref) => (this.secondInputRef = ref)}
onChange={() =>
this.setInputValue(
this.secondInputRef,
Number(this.secondInputRef.value),
59
)
}
></input>
<ix-icon-button
size="16"
Expand All @@ -323,14 +448,7 @@ export class TimePicker {
variant="Primary"
class="arrows"
></ix-icon-button>
<input
name="reference"
type="text"
ref={(ref) => (this.referenceInputRef = ref)}
value={this.timeReference}
disabled
class="text-align"
></input>
<div class="time-reference">{this.timeReference}</div>
<ix-icon-button
size="16"
onClick={() => this.changeReference()}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions packages/core/src/tests/time-picker/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0"
/>
<title>Stencil Component Starter</title>
<style>
ix-time-picker {
margin-inline-end: 1rem;
}
</style>
</head>
<body>
<div
Expand All @@ -23,6 +28,13 @@
"
>
<ix-time-picker time="10:11:12"></ix-time-picker>
<ix-time-picker time="10:11:12" show-hour></ix-time-picker>
<ix-time-picker time="10:11:12" show-minutes></ix-time-picker>
<ix-time-picker time="10:11:12" show-seconds></ix-time-picker>
<ix-time-picker
time="10:11:12"
show-time-reference="true"
></ix-time-picker>
</div>
<script src="http://127.0.0.1:8080/scripts/e2e/load-e2e-runtime.js"></script>
</body>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 864eb14

Please sign in to comment.