mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
Merge branch 'develop' of https://github.com/rowyio/rowy into feat/formula-esm
This commit is contained in:
@@ -3,7 +3,7 @@ import useStateRef from "react-usestateref";
|
|||||||
import { isEqual, isEmpty } from "lodash-es";
|
import { isEqual, isEmpty } from "lodash-es";
|
||||||
|
|
||||||
import FieldWrapper from "./FieldWrapper";
|
import FieldWrapper from "./FieldWrapper";
|
||||||
import { IFieldConfig } from "@src/components/fields/types";
|
import { FieldType, IFieldConfig } from "@src/components/fields/types";
|
||||||
import { getFieldProp } from "@src/components/fields";
|
import { getFieldProp } from "@src/components/fields";
|
||||||
import { ColumnConfig, TableRowRef } from "@src/types/table";
|
import { ColumnConfig, TableRowRef } from "@src/types/table";
|
||||||
import { TableRow } from "@src/types/table";
|
import { TableRow } from "@src/types/table";
|
||||||
@@ -44,6 +44,9 @@ export const MemoizedField = memo(
|
|||||||
}, [field.fieldName, localValueRef, onSubmit]);
|
}, [field.fieldName, localValueRef, onSubmit]);
|
||||||
|
|
||||||
let type = field.type;
|
let type = field.type;
|
||||||
|
if (field.type !== FieldType.formula && field.config?.renderFieldType) {
|
||||||
|
type = field.config.renderFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
const fieldComponent: IFieldConfig["SideDrawerField"] = getFieldProp(
|
const fieldComponent: IFieldConfig["SideDrawerField"] = getFieldProp(
|
||||||
"SideDrawerField",
|
"SideDrawerField",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { spreadSx } from "@src/utils/ui";
|
|||||||
|
|
||||||
export interface IEditorCellTextFieldProps extends IEditorCellProps<string> {
|
export interface IEditorCellTextFieldProps extends IEditorCellProps<string> {
|
||||||
InputProps?: Partial<InputBaseProps>;
|
InputProps?: Partial<InputBaseProps>;
|
||||||
|
onBlur?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EditorCellTextField({
|
export default function EditorCellTextField({
|
||||||
@@ -11,6 +12,7 @@ export default function EditorCellTextField({
|
|||||||
value,
|
value,
|
||||||
onDirty,
|
onDirty,
|
||||||
onChange,
|
onChange,
|
||||||
|
onBlur,
|
||||||
setFocusInsideCell,
|
setFocusInsideCell,
|
||||||
InputProps = {},
|
InputProps = {},
|
||||||
}: IEditorCellTextFieldProps) {
|
}: IEditorCellTextFieldProps) {
|
||||||
@@ -19,7 +21,12 @@ export default function EditorCellTextField({
|
|||||||
return (
|
return (
|
||||||
<InputBase
|
<InputBase
|
||||||
value={value}
|
value={value}
|
||||||
onBlur={() => onDirty()}
|
onBlur={() => {
|
||||||
|
if (onBlur) {
|
||||||
|
onBlur();
|
||||||
|
}
|
||||||
|
onDirty();
|
||||||
|
}}
|
||||||
onChange={(e) => onChange(e.target.value)}
|
onChange={(e) => onChange(e.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
autoFocus
|
autoFocus
|
||||||
@@ -42,6 +49,11 @@ export default function EditorCellTextField({
|
|||||||
setTimeout(() => setFocusInsideCell(false));
|
setTimeout(() => setFocusInsideCell(false));
|
||||||
}
|
}
|
||||||
if (e.key === "Enter" && !e.shiftKey) {
|
if (e.key === "Enter" && !e.shiftKey) {
|
||||||
|
// Trigger an onBlur in case we have any final mutations
|
||||||
|
if (onBlur) {
|
||||||
|
onBlur();
|
||||||
|
}
|
||||||
|
|
||||||
// Removes focus from inside cell, triggering save on unmount
|
// Removes focus from inside cell, triggering save on unmount
|
||||||
setFocusInsideCell(false);
|
setFocusInsideCell(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||||
|
|
||||||
export default function Number_(props: IEditorCellProps<number>) {
|
export default function Number_(props: IEditorCellProps<number | string>) {
|
||||||
return (
|
return (
|
||||||
<EditorCellTextField
|
<EditorCellTextField
|
||||||
{...(props as any)}
|
{...(props as any)}
|
||||||
InputProps={{ type: "number" }}
|
InputProps={{ type: "number" }}
|
||||||
onChange={(v) => props.onChange(Number(v))}
|
onChange={(v) => {
|
||||||
|
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
|
||||||
|
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
|
||||||
|
// typing. We want to avoid that.
|
||||||
|
const parsedValue = v === "" ? v : Number(v);
|
||||||
|
props.onChange(parsedValue);
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
// Cast to number when the user has finished editing
|
||||||
|
props.onChange(Number(props.value));
|
||||||
|
props.onDirty();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,25 @@ export default function Number_({
|
|||||||
onChange,
|
onChange,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
disabled,
|
disabled,
|
||||||
}: ISideDrawerFieldProps) {
|
}: ISideDrawerFieldProps<number | string>) {
|
||||||
return (
|
return (
|
||||||
<TextField
|
<TextField
|
||||||
variant="filled"
|
variant="filled"
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="none"
|
margin="none"
|
||||||
onChange={(e) => onChange(Number(e.target.value))}
|
onChange={(e) => {
|
||||||
onBlur={onSubmit}
|
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
|
||||||
|
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
|
||||||
|
// typing. We want to avoid that.
|
||||||
|
const parsedValue =
|
||||||
|
e.target.value === "" ? e.target.value : Number(e.target.value);
|
||||||
|
onChange(parsedValue);
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
// Cast to number when the user has finished editing
|
||||||
|
onChange(Number(value));
|
||||||
|
onSubmit();
|
||||||
|
}}
|
||||||
value={value}
|
value={value}
|
||||||
id={getFieldId(column.key)}
|
id={getFieldId(column.key)}
|
||||||
label=""
|
label=""
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { IEditorCellProps } from "@src/components/fields/types";
|
|||||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||||
import { multiply100WithPrecision, divide100WithPrecision } from "./utils";
|
import { multiply100WithPrecision, divide100WithPrecision } from "./utils";
|
||||||
|
|
||||||
export default function Percentage(props: IEditorCellProps<number>) {
|
export default function Percentage(props: IEditorCellProps<number | string>) {
|
||||||
return (
|
return (
|
||||||
<EditorCellTextField
|
<EditorCellTextField
|
||||||
{...(props as any)}
|
{...(props as any)}
|
||||||
@@ -13,7 +13,16 @@ export default function Percentage(props: IEditorCellProps<number>) {
|
|||||||
: props.value
|
: props.value
|
||||||
}
|
}
|
||||||
onChange={(v) => {
|
onChange={(v) => {
|
||||||
props.onChange(divide100WithPrecision(Number(v)));
|
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
|
||||||
|
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
|
||||||
|
// typing. We want to avoid that.
|
||||||
|
const parsedValue = v === "" ? v : divide100WithPrecision(Number(v));
|
||||||
|
props.onChange(parsedValue);
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
// Cast to number when the user has finished editing
|
||||||
|
props.onChange(Number(props.value));
|
||||||
|
props.onDirty();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default function Percentage({
|
|||||||
onChange,
|
onChange,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
disabled,
|
disabled,
|
||||||
}: ISideDrawerFieldProps) {
|
}: ISideDrawerFieldProps<number | string>) {
|
||||||
const { colors } = (column as any).config;
|
const { colors } = (column as any).config;
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
@@ -19,8 +19,19 @@ export default function Percentage({
|
|||||||
variant="filled"
|
variant="filled"
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="none"
|
margin="none"
|
||||||
onChange={(e) => onChange(Number(e.target.value) / 100)}
|
onChange={(e) => {
|
||||||
onBlur={onSubmit}
|
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
|
||||||
|
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
|
||||||
|
// typing. We want to avoid that.
|
||||||
|
const parsedValue =
|
||||||
|
e.target.value === "" ? e.target.value : Number(e.target.value) / 100;
|
||||||
|
onChange(parsedValue);
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
// Cast to number when the user has finished editing
|
||||||
|
onChange(Number(value));
|
||||||
|
onSubmit();
|
||||||
|
}}
|
||||||
value={
|
value={
|
||||||
typeof value === "number" ? multiply100WithPrecision(value) : value
|
typeof value === "number" ? multiply100WithPrecision(value) : value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export interface ISideDrawerFieldProps<T = any> {
|
|||||||
/** Call when the user has input but changes have not been saved */
|
/** Call when the user has input but changes have not been saved */
|
||||||
onDirty: (dirty?: boolean) => void;
|
onDirty: (dirty?: boolean) => void;
|
||||||
/** Update the local value. Also calls onDirty */
|
/** Update the local value. Also calls onDirty */
|
||||||
onChange: (T: any) => void;
|
onChange: (value: T) => void;
|
||||||
/** Call when user input is ready to be saved (e.g. onBlur) */
|
/** Call when user input is ready to be saved (e.g. onBlur) */
|
||||||
onSubmit: () => void;
|
onSubmit: () => void;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user