# React Components/Query Filter

## Props


| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `allowCustomValue` | `` | No |  | Whether to allow adding a custom filter. |
| `defaultOpen` | `` | No |  | The initial open state of the query filter. Use when you don't need to control the open state of the query filter. |
| `defaultValue` | `` | No |  | The initial selected value(s). Use when you don't need to control the selected value(s) of the query filter. |
| `disabled` | `` | No |  | Whether the component is disabled. |
| `filterOption` | `` | Yes |  | The property filter options (operator and value). |
| `filterProperty` | `` | Yes |  | The properties that may be used as a filter. |
| `highlightResults` | `` | No | false | Whether to highlight the matching part of filtered items. |
| `i18n` | `` | No |  | Internal translations override (see Input i18n keys). |
| `invalid` | `` | No |  | Whether the component is in error state. |
| `locale` | `` | No |  | The locale used for the translation of the internal elements. |
| `name` | `` | No |  | The name of the form element. Useful for form submission. |
| `newElementLabel` | `` | No | 'Use: ' | Label displayed in front of a custom filter to add. |
| `noResultLabel` | `` | No | 'No results found' | Label displayed when no values match the current input value. |
| `onInputValueChange` | `` | No |  | Callback fired when the input value changes. |
| `onOpenChange` | `` | No |  | Callback fired when the query filter open state changes. |
| `onValueChange` | `` | No |  | Callback fired when the value(s) changes. |
| `open` | `` | No |  | The controlled open state of the query filter. |
| `overlayConfig` | `` | No |  | The overlay configuration. |
| `readOnly` | `` | No |  | Whether the component is readonly. |
| `required` | `` | No |  | Whether the component is required. |
| `value` | `` | No |  | The controlled selected value(s). |


## Subcomponents


### QueryFilterClear



#### Props


| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `color` | `` | No |  | @type=BUTTON_COLOR The color preset to use. |
| `loading` | `` | No |  | Whether the component is in loading state, disabling it. |
| `size` | `` | No |  | The size preset to use. |
| `variant` | `` | No |  | The variant preset to use. |



### QueryFilterContent



#### Props


| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `createPortal` | `` | No | true | Whether the component should be rendered in the DOM close to the body tag. |



### QueryFilterControl



#### Props


| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `clearable` | `` | No |  | Whether the clear button is displayed. |
| `loading` | `` | No |  | Whether the component is in loading state. |
| `placeholder` | `` | No |  | The placeholder text to display in the input. |



### QueryFilterTags



## Examples


### Anatomy Tech

```tsx
{
  parameters: {
    layout: 'start'
  },
  tags: ['!dev'],
  render: ({}) => <QueryFilter filterOption={filterOption} filterProperty={filterProperty} open overlayConfig={{
    flip: false
  }} value={[['instance-id', '!=', 'instance-1'], ['states', '===', 'running']]}>
      <QueryFilterControl />

      <QueryFilterContent createPortal={false} />

      <div style={{
      display: 'flex',
      flexDirection: 'row',
      gap: '8px',
      alignItems: 'center',
      marginTop: '100px'
    }}>
        <QueryFilterTags style={{
        justifyContent: 'end'
      }} />

        <QueryFilterClear>
          Clear
        </QueryFilterClear>
      </div>
    </QueryFilter>
}
```

### Default

```tsx
{
  globals: {
    imports: `import { QueryFilter, QueryFilterClear, QueryFilterControl, QueryFilterContent, QueryFilterTags } from '@ovhcloud/ods-react';
import { useMemo } from 'react';`
  },
  parameters: {
    docs: {
      source: {
        ...staticSourceRenderConfig()
      }
    }
  },
  tags: ['!dev'],
  render: ({}) => {
    const filterProperty = useMemo(() => ({
      label: 'Properties',
      options: [{
        label: 'Instance ID',
        value: 'instance-id'
      }, {
        label: 'States',
        value: 'states'
      }]
    }), []);
    const filterOption = useMemo(() => ({
      ['instance-id']: {
        operator: {
          label: 'Operators I',
          options: [{
            label: 'equals',
            value: '='
          }, {
            label: 'does not equal',
            value: '!='
          }]
        },
        value: {
          label: 'Instance Values',
          options: [{
            label: 'instance 1',
            value: 'instance-1'
          }, {
            label: 'instance 2',
            value: 'instance-2'
          }]
        }
      },
      states: {
        operator: {
          label: 'Operators S',
          options: [{
            label: 'equals',
            value: '='
          }, {
            label: 'does not equal',
            value: '!='
          }]
        },
        value: {
          label: 'State Values',
          options: [{
            label: 'Running',
            value: 'running'
          }, {
            label: 'Stopped',
            value: 'stopped'
          }]
        }
      }
    }), []);
    return <QueryFilter filterOption={filterOption} filterProperty={filterProperty}>
        <QueryFilterControl />

        <QueryFilterContent />

        <QueryFilterTags />

        <QueryFilterClear>
          Clear all
        </QueryFilterClear>
      </QueryFilter>;
  }
}
```

### Demo

```tsx
{
  render: (arg: DemoArg) => <QueryFilter allowCustomValue={arg.allowCustomValue} disabled={arg.disabled} highlightResults={arg.highlightResults} invalid={arg.invalid} filterOption={filterOption} filterProperty={filterProperty} newElementLabel={arg.newElementLabel} noResultLabel={arg.noResultLabel} readOnly={arg.readOnly}>
      <QueryFilterControl clearable={arg.clearable} loading={arg.loading} placeholder={arg.placeholder} />

      <QueryFilterContent />

      <QueryFilterTags />

      <QueryFilterClear>
        {arg.clearAllLabel}
      </QueryFilterClear>
    </QueryFilter>,
  argTypes: orderControls({
    allowCustomValue: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'boolean'
    },
    clearAllLabel: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'text'
    },
    clearable: {
      table: {
        category: CONTROL_CATEGORY.general,
        type: {
          summary: 'boolean'
        }
      },
      control: 'boolean'
    },
    disabled: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'boolean'
    },
    highlightResults: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'boolean'
    },
    invalid: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'boolean'
    },
    loading: {
      table: {
        category: CONTROL_CATEGORY.general,
        type: {
          summary: 'boolean'
        }
      },
      control: 'boolean'
    },
    newElementLabel: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'text'
    },
    noResultLabel: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'text'
    },
    placeholder: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'text'
    },
    readOnly: {
      table: {
        category: CONTROL_CATEGORY.general
      },
      control: 'boolean'
    }
  }),
  args: {
    clearAllLabel: 'Clear all',
    placeholder: 'Add filters'
  }
}
```

### Overview

```tsx
{
  tags: ['!dev'],
  parameters: {
    layout: 'centered'
  },
  render: ({}) => <QueryFilter filterOption={filterOption} filterProperty={filterProperty}>
      <QueryFilterControl style={{
      alignSelf: 'end',
      width: '300px'
    }} />

      <QueryFilterContent />

      <div style={{
      display: 'flex',
      flexDirection: 'row',
      gap: '8px',
      alignItems: 'center'
    }}>
        <QueryFilterTags style={{
        justifyContent: 'end'
      }} />

        <QueryFilterClear>
          Clear
        </QueryFilterClear>
      </div>
    </QueryFilter>
}
```

### Theme Generator

```tsx
{
  parameters: {
    layout: 'fullscreen'
  },
  tags: ['!dev'],
  render: ({}) => <QueryFilter filterOption={filterOption} filterProperty={filterProperty}>
      <QueryFilterControl />

      <QueryFilterContent />

      <QueryFilterTags />

      <QueryFilterClear>
        Clear all
      </QueryFilterClear>
    </QueryFilter>
}
```