DocSpace-client/packages/components/time-picker/index.js

192 lines
4.2 KiB
JavaScript
Raw Normal View History

2023-04-10 07:14:06 +00:00
import React, { useRef, useState } from "react";
2023-04-18 10:19:24 +00:00
import PropTypes from "prop-types";
import moment from "moment";
import styled, { css } from "styled-components";
2023-04-10 07:14:06 +00:00
import { TextInput } from "@docspace/components";
const TimeInput = styled.div`
width: 57px;
height: 32px;
box-sizing: border-box;
padding: 6px 8px;
border: 1px solid #d0d5da;
border-radius: 3px;
transition: "all 0.2s ease 0s";
display: flex;
2023-05-01 08:17:16 +00:00
border-color: ${(props) => (props.hasError ? "#f21c0e" : "#d0d5da")};
${(props) =>
props.isFocused &&
css`
border-color: #4781d1;
`}
2023-04-10 07:14:06 +00:00
:focus {
border-color: #4781d1;
}
input {
padding: 0;
}
input:last-of-type {
text-align: end;
}
`;
const TimePicker = ({
date,
setDate,
onChange,
className,
hasError,
tabIndex,
}) => {
2023-04-10 07:14:06 +00:00
const hoursInputRef = useRef(null);
const minutesInputRef = useRef(null);
const timeInputRef = useRef(null);
const [isInputFocused, setIsInputFocused] = useState(false);
const [hours, setHours] = useState(moment(date, "HH:mm").format("HH"));
2023-04-10 07:14:06 +00:00
const [minutes, setMinutes] = useState(moment(date, "HH:mm").format("mm"));
const handleHoursChange = (time) => {
setHours(time);
2023-04-18 10:19:24 +00:00
setDate(moment(date.format("YYYY-MM-DD") + " " + time + ":" + minutes));
onChange(time);
};
const handleMinutesChange = (time) => {
setMinutes(time);
2023-04-18 10:19:24 +00:00
setDate(moment(date.format("YYYY-MM-DD") + " " + hours + ":" + time));
onChange(time);
};
2023-04-10 07:14:06 +00:00
const handleChangeHours = (e) => {
const hours = e.target.value;
if (hours === "") {
handleHoursChange("00");
return;
}
if (!/^\d+$/.test(hours)) return;
if (hours > 23) {
focusMinutesInput();
hours.length === 2 && handleHoursChange("0" + hours[0]);
return;
}
if (hours.length === 1 && hours > 2) {
handleHoursChange("0" + hours);
focusMinutesInput();
return;
}
hours.length === 2 && focusMinutesInput();
handleHoursChange(hours);
2023-04-10 07:14:06 +00:00
};
2023-04-10 07:14:06 +00:00
const handleChangeMinutes = (e) => {
const minutes = e.target.value;
if (minutes === "") {
handleMinutesChange("00");
return;
}
if (!/^\d+$/.test(minutes)) return;
if (minutes > 59) return;
if (minutes.length === 1 && minutes > 5) {
handleMinutesChange("0" + minutes);
blurMinutesInput();
return;
}
minutes.length === 2 && blurMinutesInput();
handleMinutesChange(minutes);
2023-04-10 07:14:06 +00:00
};
const focusHoursInput = (e) => {
const target = e.target;
2023-05-14 22:35:00 +00:00
if (!minutesInputRef.current.contains(target))
hoursInputRef.current.select();
};
const focusMinutesInput = () => {
minutesInputRef.current.select();
};
const blurMinutesInput = () => {
minutesInputRef.current.blur();
2023-04-10 07:14:06 +00:00
};
const onHoursBlur = (e) => {
e.target.value.length === 1 && handleHoursChange("0" + e.target.value);
setIsInputFocused(false);
};
const onMinutesBlur = (e) => {
e.target.value.length === 1 && handleMinutesChange("0" + e.target.value);
setIsInputFocused(false);
};
2023-04-10 07:14:06 +00:00
return (
2023-05-01 08:17:16 +00:00
<TimeInput
ref={timeInputRef}
onClick={focusHoursInput}
className={className}
2023-05-14 22:35:00 +00:00
hasError={hasError}
isFocused={isInputFocused}
2023-05-14 22:35:00 +00:00
>
<TextInput
withBorder={false}
forwardedRef={hoursInputRef}
value={hours}
onChange={handleChangeHours}
onBlur={onHoursBlur}
tabIndex={tabIndex}
onFocus={() => setIsInputFocused(true)}
/>
:
<TextInput
withBorder={false}
forwardedRef={minutesInputRef}
value={minutes}
onChange={handleChangeMinutes}
onClick={focusMinutesInput}
onBlur={onMinutesBlur}
onFocus={() => setIsInputFocused(true)}
/>
2023-04-10 07:14:06 +00:00
</TimeInput>
);
};
2023-04-18 10:19:24 +00:00
TimePicker.propTypes = {
2023-05-14 22:35:00 +00:00
/** Inital date */
2023-04-18 10:19:24 +00:00
date: PropTypes.object,
2023-05-14 22:35:00 +00:00
/** State setter function */
2023-04-18 10:19:24 +00:00
setDate: PropTypes.func,
2023-05-14 22:35:00 +00:00
/** Allows to set classname */
2023-04-25 07:06:08 +00:00
className: PropTypes.string,
2023-04-18 10:19:24 +00:00
/** Allow you to handle changing events of component */
onChange: PropTypes.func,
2023-05-14 22:35:00 +00:00
/** Indicates error */
2023-05-01 08:17:16 +00:00
hasError: PropTypes.bool,
/** Tab index allows to make element focusable */
hasError: PropTypes.bool,
2023-04-18 10:19:24 +00:00
};
TimePicker.defaultProps = {
onChange: () => {},
2023-04-25 07:06:08 +00:00
className: "",
2023-05-01 08:17:16 +00:00
hasError: false,
2023-04-18 10:19:24 +00:00
};
2023-05-14 22:35:00 +00:00
export default TimePicker;