@react-awesome-query-builder/ui
Version:
User-friendly query builder for React. Core React UI
123 lines (111 loc) • 3.76 kB
JSX
import React, { useMemo, memo } from "react";
import { Utils } from "@react-awesome-query-builder/core";
import omit from "lodash/omit";
const { getTitleInListValues } = Utils.ListUtils;
const { _widgetDefKeysToOmit } = Utils.ConfigUtils;
const { _fixImmutableValue, isImmutable } = Utils.TreeUtils;
const WidgetFactoryMemo = memo(({
widgetFactory,
...widgetProps
}) => {
const { config, isFuncArg, fieldDefinition } = widgetProps;
const { fieldSettings, defaultValue, valueSources } = fieldDefinition || {};
const isConst = isFuncArg && valueSources?.length == 1 && valueSources?.[0] === "const";
const listValues = fieldSettings?.treeValues || fieldSettings?.listValues;
if (isConst && defaultValue) {
if (typeof defaultValue === "boolean") {
return defaultValue ? (widgetProps.labelYes || "YES") : (widgetProps.labelNo || "NO");
} else if (listValues) {
if (Array.isArray(defaultValue))
return defaultValue.map(v => getTitleInListValues(listValues, v) || v).join(", ");
else
return (getTitleInListValues(listValues, defaultValue) || defaultValue);
}
return ""+defaultValue;
}
if (!widgetFactory) {
return "?";
}
return widgetFactory(widgetProps, config.ctx);
});
WidgetFactoryMemo.displayName = "WidgetFactoryMemo";
const WidgetFactory = ({
delta, parentDelta, isFuncArg, valueSrc,
value: immValue, valueError: immValueError, fieldError, asyncListValues,
isSpecialRange, fieldDefinition,
widget, widgetDefinition, widgetValueLabel, valueLabels, textSeparators, setValue, setFuncValue,
config, field, fieldSrc, fieldPath, fieldType, isLHS, operator, readonly, parentField, parentFuncs, id, groupId, widgetId,
}) => {
const {factory: widgetFactory, ...fieldWidgetProps} = widgetDefinition;
// Widget value (if it's not a func with args) should NOT be Immutable
// Eg. for multiselect value should be a JS Array, not Immutable List
const fixedImmValue = immValue ? immValue.map(v => _fixImmutableValue(v)) : undefined;
const value = useMemo(() => {
if (isSpecialRange) {
let value = [ fixedImmValue?.get(0), fixedImmValue?.get(1) ];
if (value[0] === undefined && value[1] === undefined)
value = undefined;
return value;
}
return fixedImmValue?.get(delta);
}, [ isSpecialRange, immValue ]);
const valueError = useMemo(() => {
if (!immValueError) {
return null;
}
if (isSpecialRange) {
return [ immValueError.get(0), immValueError.get(1), immValueError.get(2) ];
}
return immValueError?.get?.(delta);
}, [ isSpecialRange, immValue ]);
const errorMessage = isLHS ? fieldError : valueError;
const { fieldSettings } = fieldDefinition || {};
const { label, placeholder } = widgetValueLabel;
const placeholders = valueLabels ? valueLabels.placeholder : null;
const simpleField = isImmutable(field) ? null : field;
const widgetProps = omit({
...fieldWidgetProps,
...fieldSettings,
config,
field: simpleField, // !!! using of field prop in widget is strongly discouraged
fieldPath,
fieldSrc,
fieldType,
isLHS,
parentField,
parentFuncs,
fieldDefinition,
operator,
delta,
parentDelta,
isSpecialRange,
isFuncArg,
value,
valueSrc,
valueError,
fieldError,
errorMessage,
label,
placeholder,
placeholders,
textSeparators,
setValue,
setFuncValue,
readonly,
asyncListValues,
id,
groupId,
widgetId,
widgetFactory,
widget,
}, [
..._widgetDefKeysToOmit,
"toJS"
]);
return <WidgetFactoryMemo
widgetFactory={widgetFactory}
{...widgetProps}
/>;
};
WidgetFactory.displayName = "WidgetFactory";
export default WidgetFactory;