Better handle falsy values in Select & GraphQL cells
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
@@ -24,7 +24,7 @@ type Props<Q extends OperationType, T> = {
|
|||||||
| { defaultValue: T[]; multiple: true }
|
| { defaultValue: T[]; multiple: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
export function GraphQLCell<Q extends OperationType, T>(props: Props<Q, T>) {
|
export function GraphQLCell<Q extends OperationType, T extends NonNullable<unknown>>(props: Props<Q, T>) {
|
||||||
const [value, setValue, valueRef] = useStateWithRef<T | T[] | undefined>(
|
const [value, setValue, valueRef] = useStateWithRef<T | T[] | undefined>(
|
||||||
props.defaultValue,
|
props.defaultValue,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { GraphQLTaggedNode } from "relay-runtime";
|
import type { GraphQLTaggedNode } from "relay-runtime";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
|
|
||||||
export type MutationFieldUpdate<T> = (
|
export type MutationFieldUpdate<T extends Record<string, unknown>, TKey extends keyof T> = (
|
||||||
field: keyof T,
|
field: TKey,
|
||||||
value: T[typeof field],
|
value: T[TKey],
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,14 +4,18 @@ import { useCallback, useRef, useState } from "react";
|
|||||||
* A useState hook that also returns a ref to the current state (usable in callbacks)
|
* A useState hook that also returns a ref to the current state (usable in callbacks)
|
||||||
*/
|
*/
|
||||||
export function useStateWithRef<T>(initialValue: T) {
|
export function useStateWithRef<T>(initialValue: T) {
|
||||||
const [state, setState] = useState(initialValue);
|
const [state, setState] = useState<T>(initialValue);
|
||||||
const ref = useRef(state);
|
const ref = useRef(state);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
state,
|
state,
|
||||||
useCallback((v: T) => {
|
useCallback((v: T | ((prevState: T) => T)) => {
|
||||||
setState(v);
|
setState(prev => {
|
||||||
ref.current = v;
|
const nextState = typeof v === "function"
|
||||||
|
? (v as (prevState: T) => T)(prev) : v;
|
||||||
|
ref.current = nextState;
|
||||||
|
return nextState;
|
||||||
|
});
|
||||||
}, []),
|
}, []),
|
||||||
ref,
|
ref,
|
||||||
] as const;
|
] as const;
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ export const selectCell = tv({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function SelectCell<T>(props: Props<T>) {
|
export function SelectCell<T extends NonNullable<unknown>>(props: Props<T>) {
|
||||||
const [value, setValue, valueRef] = useStateWithRef<T | T[]>(
|
const [value, setValue, valueRef] = useStateWithRef<T | T[]>(
|
||||||
props.defaultValue,
|
props.defaultValue,
|
||||||
);
|
);
|
||||||
const cellRef = useEditableCellRef();
|
const cellRef = useEditableCellRef();
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const filteredValue = Array.isArray(value) ? value.filter(Boolean) : value ? [value] : [];
|
const filteredValue = Array.isArray(value) ? value.filter(v => v !== undefined) : value ? [value] : [];
|
||||||
const usedKeys = new Set<string>(filteredValue.map(getKey).filter(Boolean) as string[]);
|
const usedKeys = new Set<string>(filteredValue.map(getKey).filter(Boolean) as string[]);
|
||||||
const { onUpdate } = useEditableRowContext();
|
const { onUpdate } = useEditableRowContext();
|
||||||
|
|
||||||
@@ -103,12 +103,12 @@ export function SelectCell<T>(props: Props<T>) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SelectValue<T>(props: {
|
export function SelectValue<T extends NonNullable<unknown>>(props: {
|
||||||
itemRenderer: Props<T>["itemRenderer"];
|
itemRenderer: Props<T>["itemRenderer"];
|
||||||
onValueChange?: (value: T | T[]) => void;
|
onValueChange?: (value: T | T[]) => void;
|
||||||
value: T | T[] | undefined;
|
value: T | T[] | undefined;
|
||||||
}) {
|
}) {
|
||||||
if (!props.value) {
|
if (props.value === undefined) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (!Array.isArray(props.value)) {
|
if (!Array.isArray(props.value)) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export function TextCell(props: Props) {
|
|||||||
if (props.required && inputValue === "") {
|
if (props.required && inputValue === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (inputValue !== props.defaultValue) {
|
if (inputValue !== value) {
|
||||||
setValue(inputValue);
|
setValue(inputValue);
|
||||||
onUpdate(props.name, inputValue);
|
onUpdate(props.name, inputValue);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user