migrate from @material-ui/pickers to @mui/lab

This commit is contained in:
Sidney Alcantara
2021-09-23 19:38:54 +10:00
parent 5c1d9d7f81
commit afe4927de8
25 changed files with 438 additions and 358 deletions

View File

@@ -1,16 +1,13 @@
import { useTheme } from "@mui/material";
import { Skeleton } from "@mui/material";
import { SkeletonProps } from "@mui/lab";
import { Skeleton, SkeletonProps } from "@mui/material";
export default function FieldSkeleton(props: SkeletonProps) {
const theme = useTheme();
return (
<Skeleton
variant="rectangular"
width="100%"
height={56}
height={32}
animation="wave"
style={{ borderRadius: theme.shape.borderRadius }}
sx={{ borderRadius: 1 }}
{...props}
/>
);

View File

@@ -73,7 +73,7 @@ export default function Form({ values }: IFormProps) {
getValues={getValues}
/>
<Grid container spacing={4} direction="column" wrap="nowrap">
<Grid container spacing={3} direction="column" wrap="nowrap">
{fields.map((field, i) => {
// Derivative/aggregate field support
let type = field.type;

View File

@@ -23,7 +23,7 @@ export const useFieldStyles = makeStyles((theme) =>
createStyles({
root: {
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(0.75, 1, 0.75, 1.5),
padding: theme.spacing(0.5, 1),
backgroundColor: theme.palette.action.input,
boxShadow: `0 0 0 1px ${

View File

@@ -24,9 +24,7 @@ export default function EmptyTable() {
<Typography>
There is existing data in the Firestore collection:
<br />
<Typography component="span" sx={{ fontFamily: "mono" }}>
{tableState?.tablePath}
</Typography>
<code>{tableState?.tablePath}</code>
</Typography>
</div>
@@ -58,9 +56,7 @@ export default function EmptyTable() {
<Typography>
There is no data in the Firestore collection:
<br />
<Typography component="span" sx={{ fontFamily: "mono" }}>
{tableState?.tablePath}
</Typography>
<code>{tableState?.tablePath}</code>
</Typography>
</div>
@@ -139,7 +135,6 @@ export default function EmptyTable() {
maxWidth: 480,
margin: "0 auto",
textAlign: "center",
userSelect: "none",
}}
>
{contents}

View File

@@ -79,11 +79,10 @@ export const useStyles = makeStyles((theme) =>
position: "relative",
},
"& .rdg-cell-frozen": {
position: "sticky",
},
"& .rdg-cell-frozen-last": {
// boxShadow:
// theme.palette.mode === "light"
// ? "2px 0 4px 0px rgba(0, 0, 0, .08)"
// : "2px 0 4px 0px rgba(0, 0, 0, .67)",
boxShadow: theme.shadows[2]
.replace(/, 0 (\d+px)/g, ", $1 0")
.split("),")
@@ -144,8 +143,8 @@ export const useStyles = makeStyles((theme) =>
},
".cell-collapse-padding": {
margin: theme.spacing(0, -1.5),
width: `calc(100% + ${theme.spacing(3)})`,
margin: theme.spacing(0, -1.25),
width: `calc(100% + ${theme.spacing(1.25 * 2)})`,
},
},
})

View File

@@ -1,17 +1,16 @@
import { IBasicCellProps } from "../types";
import { format } from "date-fns";
import { DATE_FORMAT } from "constants/dates";
import { DateIcon } from ".";
export default function Date_({ value }: IBasicCellProps) {
export default function Date_({
value,
format: formatProp,
}: IBasicCellProps & { format?: string }) {
if (!!value && "toDate" in value) {
try {
const formatted = format(value.toDate(), DATE_FORMAT);
const formatted = format(value.toDate(), formatProp || DATE_FORMAT);
return (
<>
<DateIcon style={{ marginRight: 5 }} />
{formatted}
</>
<span style={{ fontVariantNumeric: "tabular-nums" }}>{formatted}</span>
);
} catch (e) {
return null;

View File

@@ -1,20 +1,39 @@
import { ISettingsProps } from "../types";
import Subheading from "components/Table/ColumnMenu/Subheading";
import { Typography, Link } from "@mui/material";
import InlineOpenInNewIcon from "components/InlineOpenInNewIcon";
import MultiSelect from "@rowy/multiselect";
import { DATE_FORMAT } from "constants/dates";
import { EXTERNAL_LINKS } from "constants/externalLinks";
export default function Settings({ handleChange, config }: ISettingsProps) {
return (
<>
<Subheading>Date Config</Subheading>
<MultiSelect
options={["yyyy/MM/dd", "dd/MM/yyyy", "MM/dd/yyyy"]}
options={[DATE_FORMAT, "yyyy/MM/dd", "dd/MM/yyyy", "MM/dd/yyyy"]}
itemRenderer={(option) => (
<Typography sx={{ fontFamily: "mono" }}>{option.label}</Typography>
)}
label="Format"
freeText={false}
multiple={false}
freeText
clearable={false}
searchable={false}
value={config.format ?? DATE_FORMAT}
onChange={handleChange("format")}
multiple={false}
TextFieldProps={{
helperText: (
<Link
href={EXTERNAL_LINKS.dateFormat}
target="_blank"
rel="noopener noreferrer"
>
Date format reference
<InlineOpenInNewIcon />
</Link>
),
}}
/>
</>
);

View File

@@ -1,58 +1,68 @@
import { Controller } from "react-hook-form";
import { ISideDrawerFieldProps } from "../types";
import { useTheme } from "@mui/material";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import DatePicker from "@mui/lab/DatePicker";
import { TextField } from "@mui/material";
import { transformValue, sanitizeValue } from "./utils";
import { DATE_FORMAT } from "constants/dates";
import { DateIcon } from ".";
export interface IDateProps extends ISideDrawerFieldProps {}
export default function Date_({ column, control }: IDateProps) {
const theme = useTheme();
const format = column.config?.format ?? DATE_FORMAT;
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Controller
control={control}
name={column.key}
render={({ onChange, value }) => {
const transformedValue = transformValue(value);
<Controller
control={control}
name={column.key}
render={({ onChange, value }) => {
const transformedValue = transformValue(value);
const handleChange = (date: Date | null) => {
const sanitized = sanitizeValue(date);
if (sanitized === undefined) return;
onChange(sanitized);
};
const handleChange = (date: Date | null) => {
const sanitized = sanitizeValue(date);
if (sanitized === undefined) return;
onChange(sanitized);
};
return <></>;
// TODO:
// <DatePicker
// inputFormat={column.config?.format ?? DATE_FORMAT}
// {...props}
// renderInput={(props) => (
// <TextField
// {...props}
// fullWidth
// margin="none"
// placeholder={column.config?.format ?? DATE_FORMAT}
// // TODO: InputAdornmentProps={{
// // style: { marginRight: theme.spacing(-1) },
// // }}
// // TODO: move this out to side drawer
// id={`sidedrawer-field-${column.key}`}
// onBlur={onBlur}
// label=""
// hiddenLabel
// />
// )}
// value={transformedValue}
// onChange={handleChange}
// disabled={disabled}
// />
}}
/>
</LocalizationProvider>
return (
<DatePicker
renderInput={(props) => (
<TextField
{...props}
fullWidth
label=""
hiddenLabel
aria-label={column.name as string}
InputProps={{
...props.InputProps,
endAdornment: props.InputProps?.endAdornment || (
<DateIcon color="action" />
),
}}
sx={{
"& .MuiInputBase-input": {
fontVariantNumeric: "tabular-nums",
},
"& .MuiInputAdornment-root": { m: 0 },
}}
// Touch mode: make the whole field clickable
onClick={props.inputProps?.onClick as any}
/>
)}
label={column.name}
value={transformedValue}
onChange={handleChange}
inputFormat={format}
mask={format.replace(/[A-Za-z]/g, "_")}
clearable
OpenPickerButtonProps={{ size: "small" }}
components={{ OpenPickerIcon: DateIcon }}
disableOpenPicker={false}
/>
);
}}
/>
);
}

View File

@@ -1,124 +1,115 @@
import { useDebouncedCallback } from "use-debounce";
import { IHeavyCellProps } from "../types";
import { makeStyles, createStyles } from "@mui/styles";
import MobileDatePicker from "@mui/lab/MobileDatePicker";
import DatePicker from "@mui/lab/DatePicker";
import { TextField } from "@mui/material";
import { transformValue } from "./utils";
// import DateFnsUtils from "@date-io/date-fns";
// import {
// MuiPickersUtilsProvider,
// KeyboardDatePicker,
// DatePickerProps,
// } from "@material-ui/pickers";
import { useProjectContext } from "contexts/ProjectContext";
import { transformValue, sanitizeValue } from "./utils";
import { DATE_FORMAT } from "constants/dates";
import BasicCell from "./BasicCell";
import { DateIcon } from ".";
const useStyles = makeStyles((theme) =>
createStyles({
root: { height: "100%" },
inputBase: {
height: "100%",
color: "inherit",
},
inputAdornment: {
height: "100%",
marginLeft: theme.spacing(9 / 8),
marginRight: theme.spacing(0.25),
},
input: {
...theme.typography.body2,
fontSize: "0.75rem",
color: "inherit",
height: "100%",
padding: theme.spacing(1.5, 0),
},
dateTabIcon: {
color: theme.palette.primary.contrastText,
},
disabledCell: {
color: theme.palette.text.disabled,
display: "flex",
alignItems: "center",
},
})
);
export default function Date_({ column, value, disabled }: IHeavyCellProps) {
const classes = useStyles();
const { updateCell } = useProjectContext();
export default function Date_({
column,
value,
disabled,
onSubmit,
}: IHeavyCellProps) {
const format = column.config?.format ?? DATE_FORMAT;
const transformedValue = transformValue(value);
// const [handleDateChange] = useDebouncedCallback<DatePickerProps["onChange"]>(
// (date) => {
// const sanitized = sanitizeValue(date);
// if (sanitized === undefined) return;
// onSubmit(sanitized);
// if (dataGridRef?.current?.selectCell)
// dataGridRef.current.selectCell({ rowIdx, idx: column.idx });
// },
// 500
// );
const [handleDateChange] = useDebouncedCallback((date: Date | null) => {
const sanitized = sanitizeValue(date);
if (sanitized === undefined) return;
onSubmit(sanitized);
}, 500);
if (disabled)
return (
<div className={classes.disabledCell}>
<BasicCell
value={value}
type={(column as any).type}
name={column.key}
/>
</div>
<BasicCell
value={value}
type={(column as any).type}
name={column.key}
format={format}
/>
);
return (
<MobileDatePicker
<DatePicker
renderInput={(props) => (
<TextField
{...props}
fullWidth
variant="standard"
label=""
hiddenLabel
aria-label={column.name as string}
InputProps={{
disableUnderline: true,
classes: { root: classes.inputBase, input: classes.input },
...props.InputProps,
endAdornment: props.InputProps?.endAdornment || (
<DateIcon
className="row-hover-iconButton"
sx={{
borderRadius: 1,
p: (32 - 24) / 2 / 8,
boxSizing: "content-box",
mr: 0.5,
}}
/>
),
}}
// InputAdornmentProps={{
// position: "start",
// classes: { root: classes.inputAdornment },
// }}
className="cell-collapse-padding"
sx={{
width: "100%",
height: "100%",
"& .MuiInputBase-root": {
height: "100%",
font: "inherit", // Prevent text jumping
letterSpacing: "inherit", // Prevent text jumping
".rdg-cell &": {
background: "none !important",
boxShadow: "none",
borderRadius: 0,
padding: 0,
"&::after": { width: "100%", left: 0 },
},
},
"& .MuiInputBase-input": {
height: "100%",
font: "inherit", // Prevent text jumping
letterSpacing: "inherit", // Prevent text jumping
fontVariantNumeric: "tabular-nums",
".rdg-cell &": {
padding: "var(--cell-padding)",
pr: 0,
},
},
"& .MuiInputAdornment-root": { m: 0 },
}}
// Prevent react-data-grid showing NullEditor, which unmounts this field
onDoubleClick={(e) => e.stopPropagation()}
onKeyDown={(e) => e.stopPropagation()}
// Touch mode: make the whole field clickable
onClick={props.inputProps?.onClick as any}
/>
)}
label={column.name}
value={transformedValue}
onChange={console.log}
// onChange={handleDateChange}
// onClick={(e) => e.stopPropagation()}
// format={column.config?.format ?? DATE_FORMAT}
onChange={handleDateChange}
inputFormat={format}
mask={format.replace(/[A-Za-z]/g, "_")}
clearable
// keyboardIcon={<DateIcon />}
// className={clsx("cell-collapse-padding", classes.root)}
// inputVariant="standard"
// InputProps={{
// disableUnderline: true,
// classes: { root: classes.inputBase, input: classes.input },
// }}
// InputAdornmentProps={{
// position: "start",
// classes: { root: classes.inputAdornment },
// }}
// KeyboardButtonProps={{
// size: "small",
// classes: { root: !disabled ? "row-hover-iconButton" : undefined },
// }}
// DialogProps={{ onClick: (e) => e.stopPropagation() }}
// disabled={disabled}
OpenPickerButtonProps={{
size: "small",
className: "row-hover-iconButton",
edge: false,
sx: { mr: 0.5 },
}}
components={{ OpenPickerIcon: DateIcon }}
disableOpenPicker={false}
/>
);
}

View File

@@ -3,6 +3,7 @@ import { IFieldConfig, FieldType } from "components/fields/types";
import withHeavyCell from "../_withTableCell/withHeavyCell";
import { parse, format } from "date-fns";
import { DATE_FORMAT } from "constants/dates";
import DateIcon from "@mui/icons-material/TodayOutlined";
import BasicCell from "./BasicCell";
import NullEditor from "components/Table/editors/NullEditor";
@@ -15,7 +16,7 @@ const SideDrawerField = lazy(
import("./SideDrawerField" /* webpackChunkName: "SideDrawerField-Date" */)
);
const Settings = lazy(
() => import("./Settings" /* webpackChunkName: "Settings-ConnectTable" */)
() => import("./Settings" /* webpackChunkName: "Settings-Date" */)
);
export const config: IFieldConfig = {
@@ -26,8 +27,7 @@ export const config: IFieldConfig = {
initialValue: null,
initializable: true,
icon: <DateIcon />,
description:
"Date displayed and input by default as YYYY/MM/DD or input using a picker module.",
description: `Date displayed by default as ${DATE_FORMAT}.`,
TableCell: withHeavyCell(BasicCell, TableCell),
TableEditor: NullEditor as any,
SideDrawerField,

View File

@@ -1,17 +1,16 @@
import { IBasicCellProps } from "../types";
import { format } from "date-fns";
import { DATE_TIME_FORMAT } from "constants/dates";
import { DateTimeIcon } from ".";
export default function DateTime({ value }: IBasicCellProps) {
export default function DateTime({
value,
format: formatProp,
}: IBasicCellProps & { format?: string }) {
if (!!value && "toDate" in value) {
try {
const formatted = format(value.toDate(), DATE_TIME_FORMAT);
const formatted = format(value.toDate(), formatProp || DATE_TIME_FORMAT);
return (
<>
<DateTimeIcon style={{ marginRight: 5 }} />
{formatted}
</>
<span style={{ fontVariantNumeric: "tabular-nums" }}>{formatted}</span>
);
} catch (e) {
return null;

View File

@@ -0,0 +1,46 @@
import { ISettingsProps } from "../types";
import { Typography, Link } from "@mui/material";
import InlineOpenInNewIcon from "components/InlineOpenInNewIcon";
import MultiSelect from "@rowy/multiselect";
import { DATE_TIME_FORMAT } from "constants/dates";
import { EXTERNAL_LINKS } from "constants/externalLinks";
export default function Settings({ handleChange, config }: ISettingsProps) {
return (
<>
<MultiSelect
options={[
DATE_TIME_FORMAT,
"yyyy/MM/dd HH:mm",
"dd/MM/yyyy HH:mm",
"dd/MM/yyyy hh:mm aa",
"MM/dd/yyyy hh:mm aa",
]}
itemRenderer={(option) => (
<Typography sx={{ fontFamily: "mono" }}>{option.label}</Typography>
)}
label="Format"
multiple={false}
freeText
clearable={false}
searchable={false}
value={config.format ?? DATE_TIME_FORMAT}
onChange={handleChange("format")}
TextFieldProps={{
helperText: (
<Link
href={EXTERNAL_LINKS.dateFormat}
target="_blank"
rel="noopener noreferrer"
>
Date format reference
<InlineOpenInNewIcon />
</Link>
),
}}
/>
</>
);
}

View File

@@ -1,74 +1,68 @@
import { Controller } from "react-hook-form";
import { ISideDrawerFieldProps } from "../types";
import { useTheme } from "@mui/material";
// import {
// KeyboardDateTimePicker,
// KeyboardDateTimePickerProps,
// } from "@material-ui/pickers";
import DatePicker from "@mui/lab/DatePicker";
import { TextField } from "@mui/material";
// import { MuiPickersUtilsProvider } from "@material-ui/pickers";
// import DateFnsUtils from "@date-io/date-fns";
import { transformValue, sanitizeValue } from "../Date/utils";
import { DATE_TIME_FORMAT } from "constants/dates";
import { DateTimeIcon } from ".";
export interface IDateTimeProps extends ISideDrawerFieldProps {
// ,Omit<
// KeyboardDateTimePickerProps,
// "name" | "onChange" | "value" | "disabled"
// >
}
export default function DateTime({}: IDateTimeProps) {
const theme = useTheme();
return <></>;
// TODO: return (
// <Controller
// control={control}
// name={column.key}
// render={({ onChange, onBlur, value }) => {
// const transformedValue = transformValue(value);
// const handleChange = (date: Date | null) => {
// const sanitized = sanitizeValue(date);
// if (sanitized === undefined) return;
// onChange(sanitized);
// };
// return (
// <MuiPickersUtilsProvider utils={DateFnsUtils}>
// <KeyboardDateTimePicker
// variant="inline"
// inputVariant="filled"
// fullWidth
// margin="none"
// format={DATE_TIME_FORMAT}
// placeholder={DATE_TIME_FORMAT}
// InputAdornmentProps={{
// style: { marginRight: theme.spacing(-1) },
// }}
// keyboardIcon={<TimeIcon />}
// {...props}
// value={transformedValue}
// onChange={handleChange}
// onBlur={onBlur}
// label=""
// hiddenLabel
// id={`sidedrawer-field-${column.key}`}
// dateRangeIcon={
// <DateRangeIcon
// style={{ color: theme.palette.primary.contrastText }}
// />
// }
// timeIcon={
// <TimeIcon
// style={{ color: theme.palette.primary.contrastText }}
// />
// }
// disabled={disabled}
// />
// </MuiPickersUtilsProvider>
// );
// }}
// />
// );
export interface IDateProps extends ISideDrawerFieldProps {}
export default function Date_({ column, control }: IDateProps) {
const format = column.config?.format ?? DATE_TIME_FORMAT;
return (
<Controller
control={control}
name={column.key}
render={({ onChange, value }) => {
const transformedValue = transformValue(value);
const handleChange = (date: Date | null) => {
const sanitized = sanitizeValue(date);
if (sanitized === undefined) return;
onChange(sanitized);
};
return (
<DatePicker
renderInput={(props) => (
<TextField
{...props}
fullWidth
label=""
hiddenLabel
aria-label={column.name as string}
InputProps={{
...props.InputProps,
endAdornment: props.InputProps?.endAdornment || (
<DateTimeIcon color="action" />
),
}}
sx={{
"& .MuiInputBase-input": {
fontVariantNumeric: "tabular-nums",
},
"& .MuiInputAdornment-root": { m: 0 },
}}
// Touch mode: make the whole field clickable
onClick={props.inputProps?.onClick as any}
/>
)}
label={column.name}
value={transformedValue}
onChange={handleChange}
inputFormat={format}
mask={format.replace(/[A-Za-z]/g, "_")}
clearable
OpenPickerButtonProps={{ size: "small" }}
components={{ OpenPickerIcon: DateTimeIcon }}
disableOpenPicker={false}
/>
);
}}
/>
);
}

View File

@@ -1,105 +1,116 @@
import { useDebouncedCallback } from "use-debounce";
import { IHeavyCellProps } from "../types";
import { makeStyles, createStyles } from "@mui/styles";
import DateTimePicker from "@mui/lab/MobileDateTimePicker";
import { TextField } from "@mui/material";
import { transformValue } from "../Date/utils";
// import {
// MuiPickersUtilsProvider,
// KeyboardDateTimePicker,
// DatePickerProps,
// } from "@material-ui/pickers";
import { useProjectContext } from "contexts/ProjectContext";
import { transformValue, sanitizeValue } from "../Date/utils";
import { DATE_TIME_FORMAT } from "constants/dates";
import BasicCell from "./BasicCell";
import { DateTimeIcon } from ".";
const useStyles = makeStyles((theme) =>
createStyles({
root: { height: "100%" },
inputBase: {
height: "100%",
color: "inherit",
},
inputAdornment: {
height: "100%",
marginLeft: theme.spacing(9 / 8),
marginRight: theme.spacing(0.25),
},
input: {
...theme.typography.body2,
fontSize: "0.75rem",
color: "inherit",
height: "100%",
padding: theme.spacing(1.5, 0),
},
dateTabIcon: {
color: theme.palette.primary.contrastText,
},
disabledCell: {
color: theme.palette.text.disabled,
display: "flex",
alignItems: "center",
},
})
);
export default function DateTime({ column, value }: IHeavyCellProps) {
const classes = useStyles();
const {} = useProjectContext();
export default function DateTime({
column,
value,
disabled,
onSubmit,
}: IHeavyCellProps) {
const transformedValue = transformValue(value);
// const [handleDateChange] = useDebouncedCallback<DatePickerProps["onChange"]>(
// (date) => {
// const sanitized = sanitizeValue(date);
// if (sanitized === undefined) return;
const [handleDateChange] = useDebouncedCallback((date: Date | null) => {
const sanitized = sanitizeValue(date);
if (sanitized === undefined) return;
onSubmit(sanitized);
}, 500);
// onSubmit(sanitized);
// if (dataGridRef?.current?.selectCell)
// dataGridRef.current.selectCell({ rowIdx, idx: column.idx });
// },
// 500
// );
const format = column.config?.format ?? DATE_TIME_FORMAT;
if (disabled)
return (
<BasicCell
value={value}
type={(column as any).type}
name={column.key}
format={format}
/>
);
// if (disabled)
return (
<div className={classes.disabledCell}>
<BasicCell value={value} type={(column as any).type} name={column.key} />
</div>
);
<DateTimePicker
renderInput={(props) => (
<TextField
{...props}
fullWidth
label=""
hiddenLabel
aria-label={column.name as string}
InputProps={{
...props.InputProps,
endAdornment: props.InputProps?.endAdornment || (
<DateTimeIcon
className="row-hover-iconButton"
sx={{
borderRadius: 1,
p: (32 - 24) / 2 / 8,
boxSizing: "content-box",
mr: 0.5,
}}
/>
),
}}
className="cell-collapse-padding"
sx={{
width: "100%",
height: "100%",
// return (
// <MuiPickersUtilsProvider utils={DateFnsUtils}>
// <KeyboardDateTimePicker
// value={transformedValue}
// onChange={handleDateChange}
// onClick={(e) => e.stopPropagation()}
// format={DATE_TIME_FORMAT}
// fullWidth
// clearable
// keyboardIcon={<DateTimeIcon />}
// className={clsx("cell-collapse-padding", classes.root)}
// inputVariant="standard"
// InputProps={{
// disableUnderline: true,
// classes: { root: classes.inputBase, input: classes.input },
// }}
// InputAdornmentProps={{
// position: "start",
// classes: { root: classes.inputAdornment },
// }}
// KeyboardButtonProps={{
// size: "small",
// classes: { root: "row-hover-iconButton" },
// }}
// DialogProps={{ onClick: (e) => e.stopPropagation() }}
// dateRangeIcon={<DateRangeIcon className={classes.dateTabIcon} />}
// timeIcon={<TimeIcon className={classes.dateTabIcon} />}
// />
// </MuiPickersUtilsProvider>
// );
"& .MuiInputBase-root": {
height: "100%",
font: "inherit", // Prevent text jumping
letterSpacing: "inherit", // Prevent text jumping
".rdg-cell &": {
background: "none !important",
boxShadow: "none",
borderRadius: 0,
padding: 0,
"&::after": { width: "100%", left: 0 },
},
},
"& .MuiInputBase-input": {
height: "100%",
font: "inherit", // Prevent text jumping
letterSpacing: "inherit", // Prevent text jumping
fontVariantNumeric: "tabular-nums",
".rdg-cell &": {
padding: "var(--cell-padding)",
pr: 0,
},
},
"& .MuiInputAdornment-root": { m: 0 },
}}
// Prevent react-data-grid showing NullEditor, which unmounts this field
onDoubleClick={(e) => e.stopPropagation()}
onKeyDown={(e) => e.stopPropagation()}
// Touch mode: make the whole field clickable
onClick={props.inputProps?.onClick as any}
/>
)}
label={column.name}
value={transformedValue}
onChange={handleDateChange}
inputFormat={format}
mask={format.replace(/[A-Za-z]/g, "_")}
clearable
OpenPickerButtonProps={{
size: "small",
className: "row-hover-iconButton",
edge: false,
sx: { mr: 0.5 },
}}
components={{ OpenPickerIcon: DateTimeIcon }}
disableOpenPicker={false}
/>
);
}

View File

@@ -1,7 +1,8 @@
import { lazy } from "react";
import { IFieldConfig, FieldType } from "components/fields/types";
import withHeavyCell from "../_withTableCell/withHeavyCell";
import { parseJSON } from "date-fns";
import { parseJSON, format } from "date-fns";
import { DATE_TIME_FORMAT } from "constants/dates";
import DateTimeIcon from "@mui/icons-material/AccessTime";
import BasicCell from "./BasicCell";
@@ -16,21 +17,26 @@ const SideDrawerField = lazy(
"./SideDrawerField" /* webpackChunkName: "SideDrawerField-DateTime" */
)
);
const Settings = lazy(
() => import("./Settings" /* webpackChunkName: "Settings-DateTime" */)
);
export const config: IFieldConfig = {
type: FieldType.dateTime,
name: "Time & Date",
name: "Date & Time",
group: "Date & Time",
dataType: "firebase.firestore.Timestamp",
initialValue: null,
initializable: true,
icon: <DateTimeIcon />,
description:
"Time and Date can be written as YYYY/MM/DD hh:mm (am/pm) or input using a picker module.",
description: `Date & Time displayed by default as ${DATE_TIME_FORMAT}.`,
TableCell: withHeavyCell(BasicCell, TableCell),
TableEditor: NullEditor as any,
SideDrawerField,
settings: Settings,
csvImportParser: (value) => parseJSON(value).getTime(),
csvExportFormatter: (value: any, config?: any) =>
format(value.toDate(), config?.format ?? DATE_TIME_FORMAT),
};
export default config;

View File

@@ -18,7 +18,6 @@ export default function Email({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={onChange}
onBlur={onBlur}
value={value}

View File

@@ -18,7 +18,6 @@ export default function LongText({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={onChange}
onBlur={onBlur}
value={value}

View File

@@ -20,7 +20,6 @@ export default function Number_({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={handleChange}
onBlur={onBlur}
value={value}

View File

@@ -47,7 +47,6 @@ export default function Percentage({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={handleChange}
onBlur={onBlur}
value={typeof value === "number" ? value * 100 : value}

View File

@@ -18,7 +18,6 @@ export default function Phone({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={onChange}
onBlur={onBlur}
value={value}

View File

@@ -18,7 +18,6 @@ export default function ShortText({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={onChange}
onBlur={onBlur}
value={value}

View File

@@ -20,7 +20,6 @@ export default function Url({
variant="filled"
fullWidth
margin="none"
placeholder={column.name as string}
onChange={onChange}
onBlur={onBlur}
value={value}

View File

@@ -1,2 +1,2 @@
export const DATE_FORMAT = "yyyy-MM-dd";
export const DATE_TIME_FORMAT = DATE_FORMAT + " hh:mm a";
export const DATE_TIME_FORMAT = DATE_FORMAT + " HH:mm";

View File

@@ -33,4 +33,6 @@ export const EXTERNAL_LINKS = {
rowyRunDocs: meta.homepage.replace("//", "//docs.") + "/rowyRun",
rowyAppHostName: "rowy.app",
dateFormat: "https://date-fns.org/v2.24.0/docs/format",
};

View File

@@ -1,4 +1,5 @@
import { Theme, ThemeOptions } from "@mui/material/styles";
import type {} from "@mui/lab/themeAugmentation";
import { toRem } from "./typography";
import RadioIcon from "theme/RadioIcon";
@@ -352,10 +353,10 @@ export const components = (theme: Theme): ThemeOptions => {
display: "block",
position: "absolute",
top: (32 - 16) / 2,
bottom: (32 - 16) / 2,
left: 0,
width: 3,
height: 16,
borderRadius: 1.5,
backgroundColor: theme.palette.primary.main,
},
@@ -869,6 +870,24 @@ export const components = (theme: Theme): ThemeOptions => {
bar: { borderRadius: theme.shape.borderRadius },
},
},
MuiYearPicker: {
styleOverrides: {
root: {
"& .PrivatePickersYear-yearButton": {
...theme.typography.button,
fontSize: "1rem",
},
},
},
},
MuiPickersDay: {
styleOverrides: {
root: {
background: "none",
},
},
},
},
};
};