@material-ui/pickers#KeyboardTimePicker TypeScript Examples
The following examples show how to use
@material-ui/pickers#KeyboardTimePicker.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TimePicker.tsx From glific-frontend with GNU Affero General Public License v3.0 | 5 votes |
TimePicker: React.SFC<TimePickerProps> = ({
variant = 'inline',
inputVariant = 'outlined',
field,
form: { setFieldValue, touched, errors },
placeholder,
disabled = false,
helperText,
}) => {
moment.defaultFormat = 'Thh:mm:ss';
const dateValue = field.value ? moment(field.value, moment.defaultFormat).toDate() : null;
const [open, setOpen] = useState(false);
const errorText = getIn(errors, field.name);
const touchedVal = getIn(touched, field.name);
const hasError = touchedVal && errorText !== undefined;
const handleDateChange = (time: Date | null) => {
const value = time ? moment(time).format('THH:mm:ss') : null;
setFieldValue(field.name, value);
};
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid className={styles.TimePicker}>
<KeyboardTimePicker
error={hasError}
autoOk
open={open}
variant={variant}
inputVariant={inputVariant}
label={placeholder}
data-testid="time-picker"
mask="__:__ _M"
value={dateValue}
onClick={() => !disabled && setOpen(true)}
onClose={() => setOpen(false)}
disabled={disabled}
onChange={(date) => handleDateChange(date)}
keyboardIcon={<ScheduleIcon />}
helperText={hasError ? errorText : ''}
className={styles.picker}
/>
{helperText && (
<div id="helper-text" className={styles.HelperText}>
{helperText}
</div>
)}
</Grid>
</MuiPickersUtilsProvider>
);
}
Example #2
Source File: time-picker.tsx From keycaplendar with MIT License | 4 votes |
TimePicker = ({
pickerProps,
modalProps,
value,
fallbackValue,
onChange,
showNowButton,
saveOnClose,
required,
helpTextProps = {},
...props
}: TimePickerProps) => {
const device = useAppSelector(selectDevice);
const useInline = device === "desktop";
const orientation = useAppSelector(selectOrientation);
const landscape = orientation === "landscape";
const [touched, setTouched] = useState(false);
const invalid = touched ? invalidTime(value, { required }) : false;
const validFallback = invalidTime(fallbackValue || "") ? "" : fallbackValue;
const rifm = useRifm({
accept: /\d:/g,
format: formatTime,
onChange,
value,
});
const [open, setOpen] = useState(false);
const [dialogVal, setDialogVal] = useState(value);
useEffect(() => {
if (dialogVal !== value) {
setDialogVal(
value ||
validFallback ||
DateTime.now().toLocaleString(DateTime.TIME_24_SIMPLE)
);
}
}, [value, fallbackValue]);
const confirmVal = useInline && !saveOnClose ? onChange : setDialogVal;
const handleTimePickerChange: KeyboardTimePickerProps["onChange"] = (
date,
value
) => {
const finalValue =
date?.toLocaleString(DateTime.TIME_24_SIMPLE) || value || "";
confirmVal(finalValue);
};
const setNow = () => {
confirmVal(DateTime.now().toLocaleString(DateTime.TIME_24_SIMPLE));
};
const closeDialog = () => {
setOpen(false);
};
const confirmDialog = () => {
onChange(
dialogVal ||
validFallback ||
DateTime.now().toLocaleString(DateTime.TIME_24_SIMPLE)
);
closeDialog();
};
const modal = useInline ? (
<MenuSurface
{...modalProps}
anchorCorner="bottomLeft"
className={bemClasses("modal", { open }, [modalProps?.className || ""])}
onClose={saveOnClose ? confirmDialog : undefined}
open={open}
>
<KeyboardTimePicker
ampm={false}
onChange={handleTimePickerChange}
openTo="hours"
orientation="portrait"
value={`2020-12-20T${
saveOnClose
? dialogVal
: value || validFallback || DateTime.now().toISODate()
}`}
variant="static"
{...pickerProps}
/>
{showNowButton ? (
<div className={bemClasses("buttons")}>
<Button label="Now" onClick={setNow} type="button" />
</div>
) : null}
</MenuSurface>
) : (
<Dialog
{...modalProps}
className={bemClasses("modal", { open }, [modalProps?.className || ""])}
onClose={closeDialog}
open={open}
renderToPortal
>
<KeyboardTimePicker
ampm={false}
onChange={handleTimePickerChange}
openTo="hours"
orientation={orientation}
value={`2020-12-20T${
dialogVal ||
validFallback ||
DateTime.now().toLocaleString(DateTime.TIME_24_SIMPLE)
}`}
variant="static"
{...pickerProps}
/>
<ConditionalWrapper
condition={landscape}
wrapper={(children) => (
<div className={bemClasses("bottom-bar")}>{children}</div>
)}
>
<DialogActions>
{showNowButton ? (
<Button
className={bemClasses("show-now-button")}
label="Now"
onClick={setNow}
type="button"
/>
) : null}
<DialogButton isDefaultAction label="Cancel" onClick={closeDialog} />
<DialogButton label="Confirm" onClick={confirmDialog} />
</DialogActions>
</ConditionalWrapper>
</Dialog>
);
return (
<ConditionalWrapper
condition={useInline}
wrapper={(children) => (
<MenuSurfaceAnchor className={bemClasses("anchor")}>
{children}
</MenuSurfaceAnchor>
)}
>
<TextField
{...props}
className={bemClasses("field", { inline: useInline })}
helpText={{
children: invalid ? capitalise(invalid) : "Format: HH:YY (24hr)",
persistent: true,
validationMsg: true,
...helpTextProps,
}}
inputMode="numeric"
invalid={!!invalid}
onBlur={() => {
if (!touched) {
setTouched(true);
}
if (useInline && !saveOnClose) {
setOpen(false);
}
}}
onChange={rifm.onChange}
onFocus={() => {
if (touched) {
setTouched(false);
}
if (useInline) {
setOpen(true);
}
}}
pattern="^\d{2}:\d{2}"
required={required}
trailingIcon={
useInline
? undefined
: withTooltip(
<IconButton
icon={iconObject(<Event />)}
onClick={() => setOpen(true)}
/>,
"Time picker"
)
}
value={rifm.value}
/>
{modal}
</ConditionalWrapper>
);
}
Example #3
Source File: index.tsx From aqualink-app with MIT License | 4 votes |
SurveyForm = ({
siteId,
timeZone,
onSubmit,
classes,
}: SurveyFormProps) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("xs"));
const diveLocation = useSelector(diveLocationSelector);
const [diveDateTime, setDiveDateTime] = useState<Date | null>(null);
const [weather, setWeather] =
useState<SurveyData["weatherConditions"]>("calm");
const itemsSize = isMobile ? "small" : "medium";
const iconSize = isMobile ? "small" : "default";
const { register, errors, handleSubmit, reset } = useForm({
reValidateMode: "onSubmit",
});
const handleDiveDateTimeChange = (date: Date | null) => {
if (date) {
setDiveDateTime(date);
}
};
const handleWeatherChange = (event: ChangeEvent<{ value: unknown }>) => {
setWeather(event.target.value as SurveyData["weatherConditions"]);
};
const nativeSubmit = useCallback(
(data: { comments: string }) => {
if (diveDateTime) {
const dateTime = new Date(
setTimeZone(diveDateTime, timeZone) || diveDateTime
).toISOString();
const weatherConditions = weather;
const { comments } = data;
onSubmit(dateTime, diveLocation, weatherConditions, comments);
}
},
[onSubmit, diveDateTime, timeZone, weather, diveLocation]
);
const resetForm = () => {
reset({
diveTime: null,
diveDate: null,
comments: null,
});
setDiveDateTime(null);
setWeather("calm");
};
return (
<form onSubmit={handleSubmit(nativeSubmit)}>
{/* Dive Date and Time */}
<Grid
className={classes.section}
container
justify="space-between"
spacing={2}
>
<Grid item xs={12} sm={6}>
<Typography variant="h6" gutterBottom>
Dive Date
</Typography>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
className={classes.textField}
disableToolbar
format="MM/dd/yyyy"
fullWidth
id="dive-date"
name="diveDate"
autoOk
showTodayButton
size={itemsSize}
helperText={errors?.diveDate?.message || ""}
inputRef={register({
required: "This is a required field",
validate: {
validDate: (value) =>
moment(value, "MM/DD/YYYY", true).isValid() ||
"Invalid date",
},
})}
error={!!errors.diveDate}
value={diveDateTime}
onChange={handleDiveDateTimeChange}
KeyboardButtonProps={{
"aria-label": "change date",
}}
inputProps={{
className: classes.textField,
}}
inputVariant="outlined"
keyboardIcon={<EventIcon fontSize={iconSize} />}
/>
</MuiPickersUtilsProvider>
</Grid>
<Grid item xs={12} sm={6}>
<Typography variant="h6" gutterBottom>
Dive Local Time
</Typography>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardTimePicker
className={classes.textField}
id="time-picker"
name="diveTime"
fullWidth
autoOk
size={itemsSize}
helperText={errors?.diveTime?.message || ""}
inputRef={register({
required: "This is a required field",
pattern: {
value: /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/,
message: "Invalid time format",
},
})}
error={!!errors.diveTime}
format="HH:mm"
value={diveDateTime}
onChange={handleDiveDateTimeChange}
KeyboardButtonProps={{
"aria-label": "change time",
}}
InputProps={{
className: classes.textField,
}}
keyboardIcon={<AccessTimeIcon fontSize={iconSize} />}
inputVariant="outlined"
/>
</MuiPickersUtilsProvider>
</Grid>
</Grid>
<Typography variant="h6" gutterBottom>
Dive Location
</Typography>
<Grid className={classes.section} container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
variant="outlined"
inputProps={{ className: classes.textField }}
fullWidth
placeholder="LAT"
label="Latitude"
value={diveLocation?.lat || ""}
disabled
size={itemsSize}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
variant="outlined"
inputProps={{ className: classes.textField }}
fullWidth
placeholder="LONG"
label="Longitude"
value={diveLocation?.lng || ""}
disabled
size={itemsSize}
/>
</Grid>
</Grid>
{/* Weather Conditions */}
<Grid item xs={12}>
<Typography variant="h6" gutterBottom>
Weather Conditions
</Typography>
</Grid>
<Grid className={classes.extraMargin} item xs={12}>
<TextField
className={classes.textField}
select
id="weather"
name="weather"
value={weather}
onChange={handleWeatherChange}
placeholder="Select One"
fullWidth
variant="outlined"
size={itemsSize}
inputProps={{
className: classes.textField,
}}
>
<MenuItem className={classes.textField} value="calm">
Calm
</MenuItem>
<MenuItem className={classes.textField} value="waves">
Waves
</MenuItem>
<MenuItem className={classes.textField} value="storm">
Stormy
</MenuItem>
</TextField>
</Grid>
<Grid item xs={12}>
<Typography variant="h6" gutterBottom>
Comments
</Typography>
</Grid>
<Grid className={classes.extraMargin} item xs={12}>
<TextField
className={classes.textField}
variant="outlined"
multiline
name="comments"
placeholder="Did anything stand out during this survey"
inputRef={register()}
fullWidth
size={itemsSize}
inputProps={{
className: classes.textField,
}}
/>
</Grid>
{/* SUBMIT */}
<Grid
className={classes.section}
container
justify="flex-end"
item
spacing={2}
>
<Grid item>
<Button
component={Link}
to={`/sites/${siteId}`}
onClick={resetForm}
color="primary"
variant="outlined"
size={itemsSize}
>
Cancel
</Button>
</Grid>
<Grid item>
<Button
size={itemsSize}
onClick={resetForm}
color="primary"
variant="outlined"
>
Clear
</Button>
</Grid>
<Grid item>
<Button
size={itemsSize}
type="submit"
color="primary"
variant="contained"
>
Next
</Button>
</Grid>
</Grid>
</form>
);
}
Example #4
Source File: index.tsx From aqualink-app with MIT License | 4 votes |
ExclusionDatesDialog = ({
dialogType,
open,
token,
timeZone,
siteId,
onClose,
classes,
}: ExclusionDatesDialogProps) => {
const dispatch = useDispatch();
// State variables for deploy dialog
const [deployDateTime, setDeployDateTime] = useState<Date | null>(null);
const [deployLoading, setDeployLoading] = useState(false);
const [deployError, setDeployError] = useState<string>();
const [pickerError, setPickerError] = useState("");
// State variables for maintain dialog
const [maintainStartDateTime, setMaintainStartDateTime] =
useState<Date | null>(null);
const [maintainEndDateTime, setMaintainEndDateTime] = useState<Date | null>(
null
);
const [maintainLoading, setMaintainLoading] = useState(false);
const [maintainError, setMaintainError] = useState<string>();
const [startPickerError, setStartPickerError] = useState("");
const [endPickerError, setEndPickerError] = useState("");
const [isConfirmationDialogOpen, setIsConfirmationDialogOpen] =
useState(false);
const isMaintainDisabled =
!maintainStartDateTime || !maintainEndDateTime || maintainLoading;
useEffect(() => {
switch (dialogType) {
case "deploy":
if (deployDateTime) {
setPickerError("");
}
break;
case "maintain":
if (maintainStartDateTime) {
setStartPickerError("");
}
if (maintainEndDateTime) {
setEndPickerError("");
}
break;
default:
break;
}
}, [deployDateTime, dialogType, maintainEndDateTime, maintainStartDateTime]);
const onDeployDialogClose = () => {
setDeployLoading(false);
setDeployDateTime(null);
setDeployError(undefined);
setPickerError("");
onClose();
};
const onMaintainDialogClose = () => {
setMaintainLoading(false);
setMaintainStartDateTime(null);
setMaintainEndDateTime(null);
setMaintainError(undefined);
setStartPickerError("");
setEndPickerError("");
onClose();
};
const onDeploy = () => {
const localDate = setTimeZone(deployDateTime, timeZone);
if (localDate) {
setDeployLoading(true);
siteServices
.deploySpotter(siteId, { endDate: localDate.toString() }, token)
.then(() => {
setPickerError("");
onDeployDialogClose();
dispatch(siteRequest(`${siteId}`));
dispatch(liveDataRequest(`${siteId}`));
})
.catch((err) =>
setDeployError(err?.response?.data?.message || "Something went wrong")
)
.finally(() => setDeployLoading(false));
} else {
setPickerError("Cannot be empty");
}
};
const onMaintainAdd = () => {
const localStartDate = setTimeZone(maintainStartDateTime, timeZone);
const localEndDate = setTimeZone(maintainEndDateTime, timeZone);
if (!localStartDate) {
setStartPickerError("Cannot be empty");
}
if (!localEndDate) {
setEndPickerError("Cannot be empty");
}
if (localStartDate && localEndDate) {
setMaintainLoading(true);
siteServices
.maintainSpotter(
siteId,
{
endDate: localEndDate,
startDate: localStartDate,
},
token
)
.then(() => {
setStartPickerError("");
setEndPickerError("");
onMaintainDialogClose();
dispatch(clearTimeSeriesData());
dispatch(clearTimeSeriesDataRange());
dispatch(setSelectedSite(undefined));
dispatch(siteRequest(`${siteId}`));
dispatch(liveDataRequest(`${siteId}`));
})
.catch((err) =>
setMaintainError(
err?.response?.data?.message || "Something went wrong"
)
)
.finally(() => {
setMaintainLoading(false);
onConfirmationDialogClose();
});
}
};
const confirmActionButtonText = () => {
switch (dialogType) {
case "deploy":
return deployLoading ? "Deploying..." : "Deploy";
case "maintain":
return "Add Period";
default:
return "";
}
};
const onConfirmationDialogOpen = () => setIsConfirmationDialogOpen(true);
const onConfirmationDialogClose = () => setIsConfirmationDialogOpen(false);
const actions: Action[] = [
{
action:
dialogType === "deploy" ? onDeployDialogClose : onMaintainDialogClose,
color: "secondary",
size: "small",
text: "Cancel",
variant: "outlined",
},
{
action: dialogType === "deploy" ? onDeploy : onConfirmationDialogOpen,
color: "primary",
size: "small",
text: confirmActionButtonText(),
variant: "outlined",
disabled: dialogType === "deploy" ? deployLoading : isMaintainDisabled,
},
];
return (
<>
<ConfirmationDialog
open={isConfirmationDialogOpen}
isConfirmLoading={maintainLoading}
onClose={onConfirmationDialogClose}
handleMaintainPeriodAddition={onMaintainAdd}
start={maintainStartDateTime || undefined}
end={maintainEndDateTime || undefined}
timeZone={timeZone || "UTC"}
/>
<Dialog
open={open}
actions={actions}
header={
dialogType === "deploy" ? "Mark as deployed" : "Data Exclusion Dates"
}
onClose={
dialogType === "deploy" ? onDeployDialogClose : onMaintainDialogClose
}
content={
<div className={classes.dialogContent}>
<Box mb="20px">
<Alert severity="info">
{dialogType === "deploy"
? "Spotter data before this date will be deleted."
: "Spotter data between these dates will be deleted."}{" "}
Note: The dates below are in the site's local timezone (
{timeZone || "UTC"}).
</Alert>
</Box>
<Box mb="5px">
{(deployError || maintainError) && (
<Alert severity="error">{deployError || maintainError}</Alert>
)}
</Box>
<Typography
className={classes.dateTitle}
color="textSecondary"
variant="h5"
>
{dialogType === "deploy" ? "Activation Date" : "Start"}
</Typography>
<Grid
className={
dialogType === "maintain"
? classes.startDateContainer
: undefined
}
container
item
spacing={1}
>
<Grid item xs={12} sm={6}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
className={classes.textField}
disableToolbar
format="MM/dd/yyyy"
autoOk
size="small"
fullWidth
showTodayButton
value={
dialogType === "deploy"
? deployDateTime
: maintainStartDateTime
}
onChange={
dialogType === "deploy"
? setDeployDateTime
: setMaintainStartDateTime
}
KeyboardButtonProps={{
"aria-label": "change date",
}}
inputProps={{
className: classes.textField,
}}
inputVariant="outlined"
error={
dialogType === "deploy"
? pickerError !== ""
: startPickerError !== ""
}
helperText={
dialogType === "deploy" ? pickerError : startPickerError
}
/>
</MuiPickersUtilsProvider>
</Grid>
<Grid item xs={12} sm={6}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardTimePicker
className={classes.textField}
id="time-picker"
name="diveTime"
size="small"
autoOk
fullWidth
format="HH:mm"
value={
dialogType === "deploy"
? deployDateTime
: maintainStartDateTime
}
onChange={
dialogType === "deploy"
? setDeployDateTime
: setMaintainStartDateTime
}
KeyboardButtonProps={{
"aria-label": "change time",
}}
InputProps={{
className: classes.textField,
}}
keyboardIcon={<AccessTimeIcon />}
inputVariant="outlined"
error={
dialogType === "deploy"
? pickerError !== ""
: startPickerError !== ""
}
helperText={
dialogType === "deploy" ? pickerError : startPickerError
}
/>
</MuiPickersUtilsProvider>
</Grid>
</Grid>
{dialogType === "maintain" && (
<>
<Typography
className={classes.dateTitle}
color="textSecondary"
variant="h5"
>
End
</Typography>
<Grid container item spacing={1}>
<Grid item xs={12} sm={6}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
className={classes.textField}
disableToolbar
format="MM/dd/yyyy"
size="small"
autoOk
fullWidth
showTodayButton
value={maintainEndDateTime}
onChange={setMaintainEndDateTime}
KeyboardButtonProps={{
"aria-label": "change date",
}}
inputProps={{
className: classes.textField,
}}
inputVariant="outlined"
error={endPickerError !== ""}
helperText={endPickerError}
/>
</MuiPickersUtilsProvider>
</Grid>
<Grid item xs={12} sm={6}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardTimePicker
className={classes.textField}
id="time-picker"
name="diveTime"
size="small"
autoOk
fullWidth
format="HH:mm"
value={maintainEndDateTime}
onChange={setMaintainEndDateTime}
KeyboardButtonProps={{
"aria-label": "change time",
}}
InputProps={{
className: classes.textField,
}}
keyboardIcon={<AccessTimeIcon />}
inputVariant="outlined"
error={endPickerError !== ""}
helperText={endPickerError}
/>
</MuiPickersUtilsProvider>
</Grid>
</Grid>
</>
)}
</div>
}
/>
</>
);
}