glide-design-system
Version:
Glide design system is an open-source React component library. It offers numerous benefits that make them essential tools for design and development teams.
267 lines (247 loc) • 7.18 kB
JavaScript
import React, { useState, useEffect, useRef } from "react";
import classes from "./TimePicker.module.css";
const TimePicker = ({
label,
required,
width,
height,
style,
onChange,
value,
id,
}) => {
const timeRef = useRef();
const [timeFocused, setTimeFocused] = useState();
const [hours, setHour] = useState();
const [minutes, setMinutes] = useState();
const [timeFormats, setTimeFormats] = useState();
const handleTimeFocuse = () => {
setTimeFocused(true);
};
const timeClick = () => {
setTimeFocused(true);
if (document.getElementById(`timeFields-${id}`).style.display === "block") {
document.getElementById(`timeFields-${id}`).style.display = "none";
} else {
document.getElementById(`timeFields-${id}`).style.display = "block";
}
};
const combinedStyle = {
width: width ? width : "350px",
height: height ? height : "40px",
...style,
};
const time = [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
];
const mins = [
"05",
"10",
"15",
"20",
"25",
"30",
"35",
"40",
"45",
"50",
"55",
];
const merdiants = ["AM", "PM"];
const selectHour = (hour) => {
setHour(hour);
getFullTime(hour, minutes, timeFormats);
};
const selectMin = (min) => {
setMinutes(min);
getFullTime(hours, min, timeFormats);
};
const selectTimeFomat = (format) => {
setTimeFormats(format);
getFullTime(hours, minutes, format);
};
const getFullTime = (hr, min, format) => {
const timeString = `${hr ? hr : ""}:${min ? min : ""} ${
format ? format : ""
}`;
const [time1, meridian] = timeString.split(" ");
const [hoursStr, minutesStr] = time1.split(":");
let hours1 = parseInt(hoursStr);
const minutes1 = parseInt(minutesStr);
if (meridian === "PM" && hours < 12) {
hours1 += 12;
} else if (meridian === "AM" && hours === 12) {
hours1 = 0;
}
const now = new Date();
now.setHours(hours1);
now.setMinutes(minutes1);
const timestampString = `${now.getFullYear()}-${(now.getMonth() + 1)
.toString()
.padStart(2, "0")}-${now.getDate().toString().padStart(2, "0")}T${now
.getHours()
.toString()
.padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now
.getSeconds()
.toString()
.padStart(2, "0")}.${now.getMilliseconds().toString().padStart(3, "0")}`;
if (hours || minutes || timeFormats) {
onChange(timestampString);
}
};
useEffect(() => {
const handleClickOutside = (event) => {
if (timeRef.current && !timeRef.current.contains(event.target)) {
setTimeFocused(false);
document.getElementById(`timeFields-${id}`).style.display = "none";
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
useEffect(() => {
if (value) {
const timestamp = value;
const date = new Date(timestamp);
const hour = date.getHours();
const minute = date.getMinutes();
setHour((hour % 12 || 12).toString().padStart(2, "0"));
setMinutes(minute.toString().padStart(2, "0"));
setTimeFormats(hours >= 12 ? "PM" : "AM");
}
}, [value]);
return (
<>
<p className={classes.label}>
{label ? label : ""}
{required && <span className={`required`}>*</span>}
</p>
<div
style={{
position:'relative',
width: width
? width
: combinedStyle?.width
? combinedStyle?.width
: "350px",
}}
ref={timeRef}>
<div id="heades">
<div
style={combinedStyle}
onFocus={handleTimeFocuse}
className={`${classes.mailContainer} ${
timeFocused && classes.focused
}`}>
{hours || minutes || timeFormats ? (
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
marginLeft: "14px",
marginRight: "14px",
}}>
<div
style={{
fontFamily: "'Roboto',sans-serif",
}}>
{`${hours ? hours : ""}:${minutes ? minutes : ""} ${
timeFormats ? timeFormats : ""
}`}
</div>
<span
onClick={timeClick}
style={{ fontSize: "20px", cursor: "pointer" }}
className="material-symbols-outlined">
schedule
</span>
</div>
) : (
<div
style={{
marginLeft: "14px",
fontFamily: "'Roboto',sans-serif",
position:'relative'
}}>
Select Time
</div>
)}
</div>
</div>
<div
style={{ display: "none" }}
id={`timeFields-${id}`}
className={classes.timeHeader}>
<div className={classes.timeContainer}>
<div style={{ height: "100%" }} className={classes.hourField}>
{time?.map((times) => {
return (
<div
key={times}
onClick={() => {
selectHour(times);
}}
className={`${classes.timeField} ${
times === hours && classes.selecetedField
}`}>
{times}
</div>
);
})}
</div>
<div style={{ height: "100%" }} className={classes.minsField}>
{mins?.map((min) => {
return (
<div
key={min}
className={`${classes.minutesField} ${
min === minutes && classes.selecetedField
}`}
onClick={() => {
selectMin(min);
}}>
{min}
</div>
);
})}
</div>
<div
style={{ height: "100%" }}
className={classes.timeFormatHeader}>
{merdiants?.map((merdiant) => {
return (
<div
key={merdiant}
onClick={() => {
selectTimeFomat(merdiant);
}}
className={`${classes.timeFormat} ${
merdiant === timeFormats && classes.selecetedField
}`}>
{merdiant}
</div>
);
})}
</div>
</div>
</div>
</div>
</>
);
};
export default TimePicker;