From cd7f26594b66e6af221042e66dd76df2361fabf4 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Sun, 7 Jun 2026 15:42:53 +0530 Subject: [PATCH] range components --- react-openapi/components/FilterBar.tsx | 52 ++++--------------- .../components/fields/DateRangeField.tsx | 30 +++++++++++ .../components/fields/NumberRangeField.tsx | 28 ++++++++++ react-openapi/components/fields/index.ts | 2 + react-openapi/types/overrides.ts | 2 + 5 files changed, 72 insertions(+), 42 deletions(-) create mode 100644 react-openapi/components/fields/DateRangeField.tsx create mode 100644 react-openapi/components/fields/NumberRangeField.tsx diff --git a/react-openapi/components/FilterBar.tsx b/react-openapi/components/FilterBar.tsx index 87fe15c..6dbac35 100644 --- a/react-openapi/components/FilterBar.tsx +++ b/react-openapi/components/FilterBar.tsx @@ -13,6 +13,8 @@ import FilterListIcon from "@mui/icons-material/FilterList"; import { ResourceField, ResourceMode } from "../types/config"; import { FilterBarComponents, FieldComponents } from "../types/overrides"; import { getFieldOptions, resolveTemplate } from "../utils/options"; +import DateRangeField from './fields/DateRangeField'; +import NumberRangeField from './fields/NumberRangeField'; export function FilterAutocomplete({ options, @@ -160,56 +162,22 @@ function renderFilterInput( components?: FilterBarComponents, fieldComponents?: FieldComponents, ) { - const CustomInput = components?.filterInputs?.[fieldName]; - if (CustomInput) { - return onChange("value", val)} options={options} />; - } - const filterType = field.filterType; if (filterType === "number-range") { - const NumberComponent = fieldComponents?.number; - if (NumberComponent) { - const rangeVal = (value as { min?: string; max?: string }) || {}; - return ( - - onChange("min", val === "" ? undefined : val)} /> - onChange("max", val === "" ? undefined : val)} /> - - ); - } + const RangeComponent = fieldComponents?.numberRange; + if (!RangeComponent) throw new Error(`Number range component not found for field ${fieldName}`); + const rangeVal = (value as { min?: string; max?: string }) || {}; - return ( - - onChange("min", e.target.value || undefined)} sx={{ width: 100 }} /> - onChange("max", e.target.value || undefined)} sx={{ width: 100 }} /> - - ); + return onChange("value", val)} />; } if (filterType === "date-range") { - const DateComponent = fieldComponents?.date; - if (DateComponent) { - const rangeVal = (value as { start?: string; end?: string }) || {}; - const dateField = { ...field, type: 'date' as const }; - return ( - - onChange("start", val || undefined)} /> - onChange("end", val || undefined)} /> - - ); - } + const RangeComponent = fieldComponents?.dateRange; + if (!RangeComponent) throw new Error(`Number range component not found for field ${fieldName}`); + const rangeVal = (value as { start?: string; end?: string }) || {}; - return ( - - onChange("start", e.target.value || undefined)} InputLabelProps={{ shrink: true }} sx={{ width: 170 }} /> - onChange("end", e.target.value || undefined)} InputLabelProps={{ shrink: true }} sx={{ width: 170 }} /> - - ); + return onChange("value", val)} />; } const selected = Array.isArray(value) ? value : []; diff --git a/react-openapi/components/fields/DateRangeField.tsx b/react-openapi/components/fields/DateRangeField.tsx new file mode 100644 index 0000000..b8458f2 --- /dev/null +++ b/react-openapi/components/fields/DateRangeField.tsx @@ -0,0 +1,30 @@ +import { Box, TextField as MuiTextField } from '@mui/material'; +import { FieldComponentProps } from '../../types/overrides'; + +export default function DateRangeField({ value, onChange, disabled }: FieldComponentProps) { + const rangeVal = (value as { start?: string; end?: string }) || {}; + return ( + + onChange({ ...rangeVal, start: e.target.value || undefined })} + InputLabelProps={{ shrink: true }} + sx={{ width: 170 }} + disabled={disabled} + /> + onChange({ ...rangeVal, end: e.target.value || undefined })} + InputLabelProps={{ shrink: true }} + sx={{ width: 170 }} + disabled={disabled} + /> + + ); +} diff --git a/react-openapi/components/fields/NumberRangeField.tsx b/react-openapi/components/fields/NumberRangeField.tsx new file mode 100644 index 0000000..ecaa36f --- /dev/null +++ b/react-openapi/components/fields/NumberRangeField.tsx @@ -0,0 +1,28 @@ +import { Box, TextField as MuiTextField } from '@mui/material'; +import { FieldComponentProps } from '../../types/overrides'; + +export default function NumberRangeField({ value, onChange, disabled }: FieldComponentProps) { + const rangeVal = (value as { min?: string; max?: string }) || {}; + return ( + + onChange({ ...rangeVal, min: e.target.value || undefined })} + sx={{ width: 100 }} + disabled={disabled} + /> + onChange({ ...rangeVal, max: e.target.value || undefined })} + sx={{ width: 100 }} + disabled={disabled} + /> + + ); +} diff --git a/react-openapi/components/fields/index.ts b/react-openapi/components/fields/index.ts index 8bc1a85..9baa425 100644 --- a/react-openapi/components/fields/index.ts +++ b/react-openapi/components/fields/index.ts @@ -8,5 +8,7 @@ export { default as EnumField } from './EnumField'; export { default as RelationField } from './RelationField'; export { default as ObjectField } from './ObjectField'; export { default as FallbackField } from './FallbackField'; +export { default as DateRangeField } from './DateRangeField'; +export { default as NumberRangeField } from './NumberRangeField'; export { defaultFieldComponents } from './DefaultFieldComponents'; export type { ObjectFieldProps } from './ObjectField'; diff --git a/react-openapi/types/overrides.ts b/react-openapi/types/overrides.ts index 59a7b8b..67a9ae2 100644 --- a/react-openapi/types/overrides.ts +++ b/react-openapi/types/overrides.ts @@ -52,6 +52,8 @@ export type FieldComponents = Partial> & { relation?: FieldComponent; image?: FieldComponent; default?: FieldComponent; + dateRange?: FieldComponent; + numberRange?: FieldComponent; FormField?: React.ComponentType; GenericForm?: React.ComponentType; };