# NumberRangeFilter

**Category:** Features/Filter/Components

## Design

### Overview

# NumberRangeFilter Component

A flexible numeric range filter component that enables users to filter data within specified minimum and maximum bounds. Perfect for filtering prices, quantities, or any numeric values.

## Quick Start

```typescript
import { NumberRangeFilter, numberRangeFilter } from '@wix/patterns';

function PriceRangeExample() {
  const [filter] = React.useState(() =>
    numberRangeFilter({
      name: 'price',
      initialValue: { from: 0, to: 100 },
    }),
  );

  return ;
}
```

## Props

| Prop      | Type                             | Default     | Description                                                     |
| --------- | -------------------------------- | ----------- | --------------------------------------------------------------- |
| `filter`  | `FilterProps>` | Required    | Filter object containing current range values and update method |
| `decimal` | `boolean`                        | `false`     | Enable decimal number support                                   |
| `min`     | `number`                         | `undefined` | Minimum allowed value                                           |
| `max`     | `number`                         | `undefined` | Maximum allowed value                                           |

## Features

### 1. Input Validation

- Automatically validates numeric inputs
- Enforces min/max constraints
- Prevents invalid number formats

### 2. Smart Error Handling

The component displays error messages in the following scenarios:

```typescript
// Below minimum value error
 // "Value must be greater than or equal to 10"

// Above maximum value error
 // "Value must be less than or equal to 100"

// Invalid range error
// When 'from' value is greater than 'to' value
// Shows on the relevant input field that caused the invalid range
"Minimum value cannot be greater than maximum value"
"Maximum value cannot be less than minimum value"
```

### 3. Performance Optimization

- Implements 500ms debounced updates to prevent excessive filtering
- Updates only occur after user stops typing

## Complete Example

```typescript
import { NumberRangeFilter, numberRangeFilter } from '@wix/patterns';
import { useCollection } from '@wix/patterns';

function ProductFilters() {
  // Initialize filter
  const [priceFilter] = React.useState(() =>
    numberRangeFilter({
      name: 'price',
      initialValue: { from: 10, to: 50 },
      onChange: (value) => {
        // Optional: Handle changes directly
        console.log('Price range:', value);
      },
    }),
  );

  // Use with collection (recommended approach)
  const collection = useCollection({
    queryName: 'products-query',
    filters: {
      price: priceFilter,
    },
    fetchData: async (query) => {
      const { filters } = query;
      // Access price range via filters.price
      return fetchProducts(filters);
    },
  });

  return (
    
  );
}
```

## Best Practices

1. **Initialize with Factory Function**

```typescript
// Recommended
const [filter] = React.useState(() =>
  numberRangeFilter({
    name: 'priceRange',
    initialValue: { from: 0, to: 100 },
  }),
);

// Avoid direct initialization
const [filter] = React.useState({ from: 0, to: 100 });
```

2. **Use with Collections**

```typescript
// Recommended - Integration with collection
const collection = useCollection({
  filters: {
    price: numberRangeFilter(),
  },
  // ... other collection config
});

// Avoid standalone usage without collection integration
const [range, setRange] = useState({ from: 0, to: 100 });
```

## Error States

The component handles various error states automatically:

1. **Input Validation Errors**

   - Non-numeric input
   - Values outside min/max bounds
   - Invalid decimal formats when `decimal={false}`

2. **Range Logic Errors**

   - From value greater than To value
   - To value less than From value

3. **Boundary Errors**
   - Values below specified minimum
   - Values above specified maximum

Each error state displays appropriate error messages below the relevant input field and highlights the field in error state.


```tsx
import { NumberRangeFilter } from '@wix/patterns';
```

---

### Examples

### Without passing config props, integer only values, without min or max limitations

```tsx
import React from 'react';
import { NumberRangeFilter, numberRangeFilter } from '@wix/patterns';

function DefaultNumberRangeFilter() {
  const [filter] = React.useState(() => numberRangeFilter());

  return <NumberRangeFilter filter={filter} />;
}
```

---

### With decimal values

```tsx
import React from 'react';
import { NumberRangeFilter, numberRangeFilter } from '@wix/patterns';

function DecimalNumberRangeFilter() {
  const [filter] = React.useState(() => numberRangeFilter());

  return <NumberRangeFilter filter={filter} decimal />;
}
```

---

### With min and max limitations.

```tsx
import React from 'react';
import { NumberRangeFilter, numberRangeFilter } from '@wix/patterns';

function DecimalNumberRangeFilter() {
  const [filter] = React.useState(() => numberRangeFilter());

  return <NumberRangeFilter filter={filter} decimal min={0} max={5} />;
}
```

## API

### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `filter` | `Filter<RangeItem<number>>` | Yes | - | A filter state object such as [ArrayFilter](./?path=/story/features-filter-factories--arrayfilter) |
| `fieldType` | `"SHORT_TEXT" \| "LONG_TEXT" \| "NUMBER" \| "BOOLEAN" \| "DATE" \| "DATE_TIME" \| "DATETIME" \| "TIME" \| "URL" \| "EMAIL" \| "IMAGE" \| "MEDIA_GALLERY" \| "AUDIO" \| "DOCUMENT" \| "MULTI_DOCUMENT" \| "RICH_TEXT" \| "RICH_CONTENT" \| "REFERENCE" \| "MULTI_REFERENCE" \| "OBJECT" \| "ARRAY" \| "ADDRESS" \| "COLOR" \| "INTEGER" \| "DECIMAL" \| "CHECKBOX" \| "DROPDOWN" \| "FILES" \| "MULTI_SELECT"` | No | - | The field type string used to resolve a prefix icon for the filter. Cairo maps this to the appropriate icon internally. |
| `layout` | `"button"` | No | - | Padding settings. If this prop it omitted, padding will exist on the sides of the filter.<br> <br> Supported values: <br> - `"button"`: Removes padding from the sides of the filter. |
| `toolbarItemProps` | `{ label?: ReactNode; }` | No | - | Customizes the filter in the toolbar.<br> <br> Supported properties: <br> - `label`: [string] Prefix for the filter element. |
| `toolbarTagProps` | `{ label?: string; }` | No | - | Customizes the filter tag in the toolbar.<br> <br> Supported properties: <br> - `label`: [string] Overrides the default filter name when filtered tag is shown. |
| `initiallyOpen` | `boolean` | No | - | Indicates whether the filter should be visible by default in the filters panel |
| `accordionItemProps` | `(AccordionItemType & { label?: string; })` | No | - | Customizes the filter [accordion](https://www.docs.wixdesignsystem.com/?path=/story/components-lists--accordion).<br> <br> Supported properties: <br> - `label`: [string] Accordion item title. You can also use `AccordionProps['items'][number].title` for more flexibility. <br> - Extends [AccordionProps['items'[number]](https://www.docs.wixdesignsystem.com/?path=/story/components-lists--accordion). |
| `popoverProps` | `PopoverCommonProps` | No | - | @deprecated |
| `onAppliedFilterTagRemove` | `((item: RangeItem<number>) => unknown)` | No | - | Callback that's run when a filter is removed by a visitor from the sub-toolbar. @param item |
| `renderToolbarTag` | `((item: RangeItem<number>) => Partial<TagListTag>)` | No | - | Customizes how the tag list in the sub-toolbar is rendered. <br><br> Extends [`TagListProps['tags'][number]`](https://www.docs.wixdesignsystem.com/?path=/story/components-lists-table--taglist). |
| `sectionTitle` | `string` | No | - | Title for the section in the accordion. |

