Closed fweinaug closed 1 year ago
The step
property is already supported :)
See this example: https://stackblitz.com/edit/timescape-react-brnnek?file=src%2FApp.tsx
Thank you for the quick reply! Unfortunately it's a litte bit different: When you enter for example 33 minutes and press the up arrow the minutes change to 48. The expected behaviour would be 45 minutes. This is also the default behaviour of a 'datetime-local' input, at least in Chrome.
My use-case is to allow the user to select an appointment date which is more likely to be in 15 minute steps. It would be amazing if Timescape could support it :)
Interesting! Didn't know this was the case. Looks like Firefox and Safari don't adhere to this behavior. What do you think about a new option, something like snapToStep
to explictely enable this?
Sounds good :) it makes total sense to make it an explicit option.
should i try to create a PR? @dan-lee
That would be appreciated, not sure when I come around to implement it this week
I started looking into it. Adding this code to the handler of the ArrowUp/Down keys could be enough.
This expects snapToStep to be in seconds, not sure if minutes would be better.
let step;
if (this.snapToStep && type === 'minutes') {
const minutes = date.getMinutes()
const snapMinutes = Math.max(Math.round(this.snapToStep / 60), 1)
if (e.key === 'ArrowUp') {
step = Math.ceil((minutes + 1) / snapMinutes) * snapMinutes - minutes
} else {
step = Math.floor((minutes - 1) / snapMinutes) * snapMinutes - minutes
}
} else {
step = (elementStep || 1) * factor
}
edit: updated the code, arrow down was not handled properly
what do you think @dan-lee ?
Yeah, I think that works!
Why only limit this to minutes? I thought of snapToStep
to be a boolean and to snap for every field. Admittedly not every field makes sense, but I don't think we should limit it to that.
good point! here is the updated code:
const elementStep = Number(inputElement.step) || 1
let step;
if (this.snapToStep) {
const getValue = (date: Date, type: DateType) => {
switch (type) {
case 'days':
return date.getDay()
case 'months':
return date.getMonth()
case 'years':
return date.getFullYear()
case 'hours':
return date.getHours()
case 'minutes':
return date.getMinutes()
case 'seconds':
return date.getSeconds()
}
}
const value = getValue(date, type)
if (e.key === 'ArrowUp') {
step = Math.ceil((value + 1) / elementStep) * elementStep - value
} else {
step = Math.floor((value - 1) / elementStep) * elementStep - value
}
} else {
const factor = e.key === 'ArrowUp' ? 1 : -1
step = elementStep * factor
}
would you be open to add it or should i create a PR? you would be way faster, especially with storybook 😅
Yeah, I can take care of it. Got some spare time today :)
It would be great to have an option to increment the minutes in steps when using the arrow up/down keys. For example when setting step=15 the minutes cycle through 15/30/45/00 when pressing the arrow keys.
Using the step attribute of the input for minutes will lead to a different result because it will just add or subtract the given value.