QueryBuilder
Refer to the TypeScript reference page for information about the types and interfaces referenced below.
The primary export of react-querybuilder
is the <QueryBuilder />
React component.
QueryBuilder
calls the useQueryBuilder
Hook to merge props and context values with defaults, generate update methods, consume the context, prepare the query, and finalize the schema.
Subcomponents
QueryBuilder
renders a RuleGroup
representing the root of the query.
That root RuleGroup
is nested within a <div>
that has the standard queryBuilder
class, any classes added by controlClassnames.queryBuilder
, and data-
properties with "enabled"/"disabled" values indicating whether drag-and-drop or inline combinators (either showCombinatorsBetweenRules
is true
or the query is using independent combinators) are enabled.
Finally, everything is wrapped in <QueryBuilderStateProvider>
and <QueryBuilderContext.Provider>
. The latter inherits any values from ancestor context providers and propogates them down to subcomponents. Props supersede context values.
Props
All QueryBuilder
props are optional, but as stated in the getting started guide, the query builder is really only useful when at least the fields
and onQueryChange
props are implemented.
When you see RuleGroupTypeAny
below (e.g. for query, defaultQuery, and onQueryChange), that means the type must either be RuleGroupType
or RuleGroupTypeIC
. For more information about RuleGroupTypeIC
, see the independent combinators section below.
fields
OptionList<Field> | Record<string, Field>
The array of fields that should be used or an array of option groups containing arrays of fields. (Alternatively, fields
can be an object where the keys correspond to each field name
and the values are the field definitions. If fields
is an object, then the options
array passed to the fieldSelector
component will be sorted alphabetically by the label
property.)
Field objects can also contain custom properties. Each field object will be passed in its entirety to the appropriate OperatorSelector
and ValueEditor
components as the fieldData
prop (see the section on controlElements
).
onQueryChange
(query: RuleGroupTypeAny) => void
This function is invoked with the updated query whenever a change is made from within the component.
query
RuleGroupTypeAny
The query is an object of type RuleGroupType
or RuleGroupTypeIC
. If this prop is provided, <QueryBuilder />
will be a controlled component.
The query
prop follows the same format as the parameter passed to the onQueryChange
callback since they are meant to be used in concert to control the component. See examples here.
defaultQuery
RuleGroupTypeAny
The initial query when <QueryBuilder />
is uncontrolled.
Do not provide both query
and defaultQuery
props. To use <QueryBuilder />
as a controlled component, provide and manage the query
prop in combination with the onQueryChange
callback. Use defaultQuery
(or neither query prop) to render an uncontrolled component. The onQueryChange
callback will be invoked for every update regardless of which prop is used.
If both props are defined, an error will be logged to the console during runtime (in "development" mode only). Errors will also be logged to the console if the query
prop is defined during one render and undefined in the next, or vice versa.
context
any
A "bucket" for passing arbitrary props down to custom components. The default components ignore this prop, but it is passed to each and every component so it's accessible anywhere in the QueryBuilder
component tree.
operators
OptionList<Operator>
The array of operators that should be used. Custom operators must define a label
property and either a name
or value
(value
takes precedence). An arity
property, which can be "unary", "binary", or a number, may also be defined for each operator. If arity
is either "unary" or a number less than 2, the value editor component will not be rendered when that operator is selected.
To build the operator list dynamically depending on a rule's field
property, use getOperators
. The result of getOperators
, if not null
, will supersede the operators
prop.
The default operator list is below.
export const defaultOperators: DefaultOperators = [
{ name: '=', value: '=', label: '=' },
{ name: '!=', value: '!=', label: '!=' },
{ name: '<', value: '<', label: '<' },
{ name: '>', value: '>', label: '>' },
{ name: '<=', value: '<=', label: '<=' },
{ name: '>=', value: '>=', label: '>=' },
{ name: 'contains', value: 'contains', label: 'contains' },
{ name: 'beginsWith', value: 'beginsWith', label: 'begins with' },
{ name: 'endsWith', value: 'endsWith', label: 'ends with' },
{ name: 'doesNotContain', value: 'doesNotContain', label: 'does not contain' },
{ name: 'doesNotBeginWith', value: 'doesNotBeginWith', label: 'does not begin with' },
{ name: 'doesNotEndWith', value: 'doesNotEndWith', label: 'does not end with' },
{ name: 'null', value: 'null', label: 'is null' },
{ name: 'notNull', value: 'notNull', label: 'is not null' },
{ name: 'in', value: 'in', label: 'in' },
{ name: 'notIn', value: 'notIn', label: 'not in' },
{ name: 'between', value: 'between', label: 'between' },
{ name: 'notBetween', value: 'notBetween', label: 'not between' },
];
Source: /packages/react-querybuilder/src/defaults.ts#L141-L160
combinators
OptionList
The array of combinators that should be used for RuleGroups. The default combinator list is below.
export const defaultCombinators: DefaultCombinators = [
{ name: 'and', value: 'and', label: 'AND' } as const,
{ name: 'or', value: 'or', label: 'OR' } as const,
];
Source: /packages/react-querybuilder/src/defaults.ts#L193-L196
baseField
Record<string, unknown>
Properties defined in this prop will be applied to each object in the fields
prop. Corresponding properties defined for individual fields will override the "base" properties.
baseOperator
Record<string, unknown>
Properties defined in this prop will be applied to each object in the operators
prop or the list returned from getOperators
. Corresponding properties defined for individual operators will override the "base" properties.
baseCombinator
Record<string, unknown>
Properties defined in this prop will be applied to each object in the combinators
prop. Corresponding properties defined for individual combinators will override the "base" properties.
controlClassnames
Partial<Classnames>
This prop can be used to assign custom CSS classes to the various controls rendered by the <QueryBuilder />
component. Each attribute is a Classname
which can be a string
, string[]
, or Record<string, any>
(see documentation for clsx
):
Usage example
In the example below, any "+ Rule" buttons in the query builder will have the "bold" class which might have the associated CSS rule .bold { font-weight: bold; }
.
function App() {
return (
<QueryBuilder controlClassnames={{ addRule: 'bold' }}>
)
}
Property | Classes are applied to... |
---|---|
queryBuilder | ...the outermost <div> element |
ruleGroup | ...each <div> wrapping a group |
header | ...each <div> wrapping a group's header controls |
body | ...each <div> wrapping a group's body elements (child rules/groups) |
combinators | ...each <select> control for combinators |
addRule | ...each <button> that adds a rule |
addGroup | ...each <button> that adds a group |
cloneRule | ...each <button> that clones a rule |
cloneGroup | ...each <button> that clones a group |
removeGroup | ...each <button> that removes a group |
lockRule | ...each <button> that locks/disables a rule |
lockGroup | ...each <button> that locks/disables a group |
notToggle | ...each <label> on a "not" (aka "inversion") toggle |
rule | ...each <div> containing a rule |
fields | ...each <select> control for selecting a field |
operators | ...each <select> control for selecting an operator |
value | ...each <input> for entering a value |
removeRule | ...each <button> that removes a rule |
dragHandle | ...each <span> acting as a drag handle |
valueSource | ...each <select> control for selecting a value source |
actionElement | ...each <button> control |
valueSelector | ...each <select> control |
controlElements
Partial<Controls>
This object allows you to override the default components.
Usage example
function App() {
return (
<QueryBuilder controlElements={{ valueEditor: CustomValueEditor }}>
)
}
The following control overrides are supported per the Controls
interface. Setting a control override to null
will hide the element by rendering it as () => null
.
Property | Type |
---|---|
actionElement | React.ComponentType<ActionProps> |
addGroupAction | React.ComponentType<ActionWithRulesAndAddersProps> | null |
addRuleAction | React.ComponentType<ActionWithRulesAndAddersProps> | null |
cloneGroupAction | React.ComponentType<ActionWithRulesProps> | null |
cloneRuleAction | React.ComponentType<ActionProps> | null |
combinatorSelector | React.ComponentType<CombinatorSelectorProps> | null |
dragHandle | React.ForwardRefExoticComponent<DragHandleProps & React.RefAttributes<HTMLSpanElement>> | null |
fieldSelector | React.ComponentType<FieldSelectorProps> | null |
inlineCombinator | React.ComponentType<InlineCombinatorProps> | null |
lockGroupAction | React.ComponentType<ActionWithRulesProps> | null |
lockRuleAction | React.ComponentType<ActionProps> | null |
notToggle | React.ComponentType<NotToggleProps> | null |
operatorSelector | React.ComponentType<OperatorSelectorProps> | null |
removeGroupAction | React.ComponentType<ActionWithRulesProps> | null |
removeRuleAction | React.ComponentType<ActionProps> | null |
rule | React.ComponentType<RuleProps> |
ruleGroup | React.ComponentType<RuleGroupProps> |
ruleGroupBodyElements | React.ComponentType<RuleGroupProps & ReturnType<typeof useRuleGroup>> |
ruleGroupHeaderElements | React.ComponentType<RuleGroupProps & ReturnType<typeof useRuleGroup>> |
shiftActions | React.ComponentType<ShiftActionsProps> | null |
valueEditor | React.ComponentType<ValueEditorProps> | null |
valueSelector | React.ComponentType<ValueSelectorProps> |
valueSourceSelector | React.ComponentType<ValueSourceSelectorProps> | null |
actionElement
The component for all button-type controls. Default is ActionElement
. Receives props per the ActionProps
, ActionWithRulesProps
, or ActionWithRulesAndAddersProps
interface depending on the control, which can be any of the following:
addGroupAction
addRuleAction
cloneGroupAction
cloneRuleAction
lockGroupAction
lockRuleAction
removeGroupAction
removeRuleAction
For example, this:
<QueryBuilder controlElements={{ actionElement: MyAwesomeButton }} />
...is equivalent to this:
<QueryBuilder
controlElements={{
addGroupAction: MyAwesomeButton
addRuleAction: MyAwesomeButton
cloneGroupAction: MyAwesomeButton
cloneRuleAction: MyAwesomeButton
lockGroupAction: MyAwesomeButton
lockRuleAction: MyAwesomeButton
removeGroupAction: MyAwesomeButton
removeRuleAction: MyAwesomeButton
}}
/>
addGroupAction
Adds a sub-group to the current group. Default is ActionElement
.
Props for addGroupAction
Per the ActionWithRulesAndAddersProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.addGroup.label , e.g. "+ Group" |
title | string | translations.addGroup.title , e.g. "Add group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent, context?: any) => void | Adds a new sub-group to this group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | Path | Path of this group |
schema | Schema | Query schema |
addRuleAction
Adds a rule to the current group. Default is ActionElement
.
Props for addRuleAction
Per the ActionWithRulesAndAddersProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.addRule.label , e.g. "+ Rule" |
title | string | translations.addRule.title , e.g. "Add rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent, context?: any) => void | Adds a new rule to this rule |
rules | RuleOrGroupArray | The rules array for this rule |
ruleOrGroup | RuleGroupTypeAny | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
cloneGroupAction
Clones the current group. Default is ActionElement
.
Props for cloneGroupAction
Per the ActionWithRulesProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.cloneRuleGroup.label , e.g. "⧉" |
title | string | translations.cloneRuleGroup.title , e.g. "Clone group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Clones this group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | Path | Path of this group |
schema | Schema | Query schema |
cloneRuleAction
Clones the current rule. Default is ActionElement
.
Props for cloneRuleAction
Per the ActionProps
interface:
Prop | Type | Description |
---|---|---|
label | string | translations.cloneRule.label , e.g. "⧉" |
title | string | translations.cloneRule.title , e.g. "Clone rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Clones the rule |
ruleOrGroup | RuleType | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
combinatorSelector
Selects the combinator
property for the current group, or the current independent combinator value. Default is ValueSelector
.
Props for combinatorSelector
Per the CombinatorSelectorProps
interface:
Prop | Type | Description |
---|---|---|
options | OptionList | Same as combinators prop passed into QueryBuilder |
value | string | Selected combinator from the existing query representation, if any |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the group's combinator |
rules | RuleOrGroupArray | The rules array for this group |
title | string | translations.combinators.title , e.g. "Combinators" |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | Path | Path of this group |
schema | Schema | Query schema |
dragHandle
Provides a draggable handle for reordering rules and groups. Default is DragHandle
. Only rendered if drag-and-drop is enabled. Note that this component must be based on React.forwardRef
.
Props for dragHandle
Receives the forwarded ref
and the following props per the DragHandleProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.dragHandle.label , e.g. "⁞⁞" |
title | string | translations.dragHandle.title , e.g. "Drag handle" |
className | string | CSS classNames to be applied |
level | number | The level of this rule/group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule/group |
disabled | boolean | Whether this rule/group is disabled/locked |
path | Path | Path of this rule/group |
schema | Schema | Query schema |
ruleOrGroup | RuleGroupTypeAny | RuleType | This group or rule, depending on the parent component |
fieldSelector
Selects the field
property for the current rule. Default is ValueSelector
.
Props for fieldSelector
Per the FieldSelectorProps
interface:
Prop | Type | Description |
---|---|---|
options | OptionList<Field> | Same as fields prop passed into QueryBuilder |
value | string | Selected field from the existing query representation, if any |
title | string | translations.fields.title , e.g. "Fields" |
operator | string | Selected operator from the existing query representation, if any |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the rule's field |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
rule | RuleType | This rule |
inlineCombinator
A small wrapper around the combinatorSelector
component. Default is InlineCombinator
.
Props for inlineCombinator
Per the InlineCombinatorProps
interface, which extends CombinatorSelectorProps
:
Prop | Type | Description |
---|---|---|
component | Schema['controls']['combinatorSelector'] | Same as the combinatorSelector component |
lockGroupAction
Locks the current group (sets the disabled
property to true
). Default is ActionElement
.
Props for lockGroupAction
Per the ActionWithRulesProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.lockGroup.label or translations.lockGroupDisabled.label , e.g. "🔓" when unlocked and "🔒" when locked |
title | string | translations.lockGroup.title or translations.lockGroupDisabled.title , e.g. "Lock group" or "Unlock group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Locks the group |
rules | RuleOrGroupArray | The rules present for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
disabledTranslation | string | translations.lockGroupDisabled if parent group is not disabled, otherwise undefined |
path | Path | Path of this group |
schema | Schema | Query schema |
lockRuleAction
Locks the current rule (sets the disabled
property to true
). Default is ActionElement
.
Props for lockRuleAction
Per the ActionWithRulesProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.lockRule.label or translations.lockRuleDisabled.label , e.g. "🔓" when unlocked and "🔒" when locked |
title | string | translations.lockRule.title or translations.lockRuleDisabled.title , e.g. "Lock rule" or "Unlock rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Locks the rule |
ruleOrGroup | RuleType | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
disabledTranslation | string | translations.lockRuleDisabled if parent group is not disabled, otherwise undefined |
path | Path | Path of this rule |
schema | Schema | Query schema |
notToggle
Toggles the not
property of the current group between true
and false
. Default is NotToggle
.
Props for notToggle
Per the NotToggleProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.notToggle.label , e.g. "Not" |
title | string | translations.notToggle.title , e.g. "Invert this group" |
className | string | CSS classNames to be applied |
handleOnChange | (checked: boolean) => void | Updates the group's not property |
checked | boolean | Whether the input should be checked or not |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | Path | Path of this group |
schema | Schema | Query schema |
ruleGroup | RuleGroupTypeAny | This group |
operatorSelector
Selects the operator
property for the current rule. Default is ValueSelector
.
Props for operatorSelector
Per the OperatorSelectorProps
interface:
Prop | Type | Description |
---|---|---|
field | string | Field name corresponding to this rule |
fieldData | Field | The entire object from the fields array for this field |
options | OptionList<Operator> | Return value of getOperators(field, { fieldData }) |
value | string | Selected operator from the existing query representation, if any |
title | string | translations.operators.title , e.g. "Operators" |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the rule's operator |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
rule | RuleType | This rule |
removeGroupAction
Removes the current group from its parent group's rules
array. Default is ActionElement
.
Props for removeGroupAction
Per the ActionWithRulesProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.removeGroup.label , e.g. "⨯" |
title | string | translations.removeGroup.title , e.g. "Remove group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Removes the group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | Path | Path of this group |
schema | Schema | Query schema |
removeRuleAction
Removes the current rule from its parent group's rules
array. Default is ActionElement
.
Props for removeRuleAction
Per the ActionProps
interface:
Prop | Type | Description |
---|---|---|
label | ReactNode | translations.removeRule.label , e.g. "⨯" |
title | string | translations.removeRule.title , e.g. "Remove rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Removes the rule |
ruleOrGroup | RuleType | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
rule
Rule layout component. Default is Rule
.
Props for rule
Per the RuleProps
interface:
Prop | Type | Description |
---|---|---|
id | string | Unique identifier for this rule |
path | Path | Path of this rule |
rule | RuleType | The rule object |
translations | Translations | The default translations merged with the translations prop |
schema | Schema | Query schema |
actions | QueryActions | Query update functions |
context | any | Container for custom props that are passed to all components |
disabled | boolean | Whether the rule itself is disabled |
shiftUpDisabled | boolean | Whether shifting the rule up is disallowed |
shiftDownDisabled | boolean | Whether shifting the rule down is disallowed |
parentDisabled | boolean | Whether the parent group of this rule is disabled |
If you enable drag-and-drop and want to use a custom Rule
component, use the controlElements
prop on the QueryBuilderDnD
context provider instead of QueryBuilder
.
ruleGroup
Rule group layout component. Default is RuleGroup
.
Props for ruleGroup
Per the RuleGroupProps
interface:
Prop | Type | Description |
---|---|---|
id | string | Unique identifier for this group |
path | Path | Path of this group |
ruleGroup | RuleGroupTypeAny | The group object |
translations | Translations | The default translations merged with the translations prop |
schema | Schema | Query schema |
actions | QueryActions | Query update functions |
context | any | Container for custom props that are passed to all components |
disabled | boolean | Whether the group itself is disabled |
shiftUpDisabled | boolean | Whether shifting the group up is disallowed |
shiftDownDisabled | boolean | Whether shifting the group down is disallowed |
parentDisabled | boolean | Whether the parent group of this group is disabled |
If you enable drag-and-drop and want to use a custom RuleGroup
component, use the controlElements
prop on the QueryBuilderDnD
context provider instead of QueryBuilder
.
ruleGroupBodyElements
Rule group body elements. Default is RuleGroupBodyComponents
, which returns an array containing only the elements themselves (no HTML or React Native wrapper element). Receives the same props as ruleGroup
, in addition to the return value of the useRuleGroup
hook.
ruleGroupHeaderElements
Rule group header elements. Default is RuleGroupHeaderComponents
, which returns a React Fragment
containing only the elements themselves (no HTML or React Native wrapper element). Receives the same props as ruleGroup
, in addition to the return value of the useRuleGroup
hook.
shiftActions
Shifts the current rule/group up or down in the query hierarchy. Default is ShiftActions
.
Props for shiftActions
Per the ShiftActionsProps
interface:
Prop | Type | Description |
---|---|---|
labels | { shiftUp: ReactNode; shiftDown: ReactNode; } | translations.shiftActionUp.label and translations.shiftActionDown.label , e.g. "˄" and "˅" |
titles | { shiftUp: string; shiftDown: string; } | translations.shiftActionUp.title and translations.shiftActionDown.title , e.g. "Shift up" and "Shift down" |
className | string | CSS classNames to be applied |
ruleOrGroup | RuleGroupTypeAny | This rule/group |
level | number | The level of this rule/group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule/group |
disabled | boolean | Whether this rule/group is disabled/locked |
path | Path | Path of this rule/group |
schema | Schema | Query schema |
shiftUp | () => void | Method to shift the rule/group up one place |
shiftDown | () => void | Method to shift the rule/group down one place |
shiftUpDisabled | boolean | Whether shifting the rule/group up is disallowed |
shiftDownDisabled | boolean | Whether shifting the rule/group down is disallowed |
valueEditor
Updates the value
property for the current rule. Default is ValueEditor
.
Props for valueEditor
Per the ValueEditorProps
interface:
Prop | Type | Description |
---|---|---|
field | string | Field name corresponding to this rule |
fieldData | Field | The entire object from the fields array for this field |
operator | string | Operator name corresponding to this rule |
value | string | value from the existing query representation, if any |
title | string | translations.value.title , e.g. "Value" |
handleOnChange | (value: any) => void | Updates the rule's value |
type | ValueEditorType | Type of editor to be displayed |
inputType | string | Intended @type attribute of the <input> , if type prop is "text" |
values | any[] | List of available values for this rule |
className | string | CSS classNames to be applied |
valueSource | ValueSource | Value source for this rule |
listsAsArrays | boolean | Whether to manage value lists (i.e. "between"/"in" operators) as arrays |
parseNumbers | ParseNumberMethod | Whether to parse real numbers from strings |
separator | ReactNode | Separator element for series of editors (i.e. "between" operator) |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
rule | RuleType | This rule |
valueSelector
The component for all value selector controls. Default is ValueSelector
. Receives props per the CombinatorSelectorProps
, FieldSelectorProps
, OperatorSelectorProps
, or ValueSourceSelectorProps
interface depending on the control, which can be any of the following:
For example, this:
<QueryBuilder controlElements={{ valueSelector: MyAwesomeSelector }} />
...is equivalent to this:
<QueryBuilder
controlElements={{
combinatorSelector: MyAwesomeSelector
fieldSelector: MyAwesomeSelector
operatorSelector: MyAwesomeSelector
valueSourceSelector: MyAwesomeSelector
}}
/>
valueSourceSelector
Selects the valueSource
property for the current rule. Default is ValueSelector
.
Props for valueSourceSelector
Per the ValueSourceSelectorProps
interface:
Prop | Type | Description |
---|---|---|
field | string | Field name corresponding to this rule |
fieldData | Field | The entire object from the fields array for the selected field |
options | OptionList<ValueSourceOption> | Return value of getValueSources(field, operator, { fieldData }) |
value | ValueSource | Selected value source for this rule, if any |
title | string | translations.valueSourceSelector.title , e.g. "Value source" |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the rule's valueSource |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | Path | Path of this rule |
schema | Schema | Query schema |
rule | RuleType | This rule |
getOperators
(field: string, misc: { fieldData: Field }) => OptionList<Operator> | null
This function is invoked to get the list of allowed operators for the given field
. If null
is returned, the operators prop is used (or the default operators if the operators
prop is not defined).
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getValueEditorType
(field: string, operator: string, misc: { fieldData: Field }) => ValueEditorType
This function is invoked to get the type of ValueEditor
for the given field
and operator
. Allowed values are "text"
(the default if the function is not provided or if null
is returned), "select"
, "multiselect"
, "checkbox"
, "radio"
, "textarea"
, and "switch"
.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getValueSources
(field: string, operator: string, misc: { fieldData: Field }) => ValueSources
;
This function is invoked to get the list of allowed value sources for a given field
and operator
. The return value must be an array with one or two elements: "value"
, "field"
, or both (in either order). If the prop is not defined, () => ["value"]
is used. The first element in the array will be the initial selection.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getValueEditorSeparator
(field: string, operator: string, misc: { fieldData: Field }) => ReactNode
;
This function should return the separator element for a given field
and operator
. It will be placed in between value editors when multiple are rendered, e.g. when the operator is "between". The element can be any valid React element, including a plain string (e.g. "and" or "to") or an HTML element like <span />
.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getInputType
(field: string, operator: string, misc: { fieldData: Field }) => string
This function is invoked to get the type
attribute which will be applied to the rendered <input />
for the given field
and operator
. This prop is only applicable when getValueEditorType
returns "text"
or a falsy value. If no function is provided, "text"
is used.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getValues
(field: string, operator: string, misc: { fieldData: Field }) => OptionList
This function is invoked to get the list of allowed values for the given field
and operator
. This prop is only applicable when getValueEditorType
returns "select"
, "multiselect"
, or "radio"
. If no function is provided, an empty array is used.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getDefaultField
string | ((fieldsData: OptionList<Field>) => string)
The default field
for new rules. This can be a field name
or a function that returns a field name
based on the fields
prop.
getDefaultOperator
string | ((field: string, misc: { fieldData: Field }) => string)
The default operator
for new rules. This can be an operator name
or a function that returns an operator name
.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getDefaultValue
(rule: RuleType, misc: { fieldData: Field }) => any
This function returns the default value
for new rules based on the existing rule properties.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getRuleClassname
(rule: RuleType, misc: { fieldData: Field }) => Classname
Generate custom classes which will be added to the outer div
of a rule based on the rule properties.
fieldData
is the full Field
object from the fields
array prop. This can be used to access additional and/or custom properties of the field.
getRuleGroupClassname
(ruleGroup: RuleGroupTypeAny) => Classname
Generate custom classes which will be added to the outer div
of a group based on the group properties.
onAddRule
(rule: RuleType, parentPath: Path, query: RuleGroupTypeAny, context?: any) => RuleType | false
This callback is invoked immediately before a new rule is added. The function should either manipulate the rule and return it as an object of type RuleType
or return false
to cancel the addition of the rule. You can use findPath
to locate the parent group to which the new rule will be added within the query hierarchy. The context
parameter (fourth argument) can be passed from a custom addRuleAction
component to its onHandleClick
prop, which will in turn pass it to onAddRule
. This allows one to change the rule that gets added (or avoid the action completely) based on arbitrary data.
If the query is using independent combinators, you can specify the combinator inserted immediately before the new rule (if the parent group is not empty) by adding a combinatorPreceding
property (with a combinator name
as the value) to the rule before returning it. Otherwise the combinator preceding the last rule, or the first combinator in the default list if the parent group has only one rule, will be used.
To completely prevent the addition of new rules, pass controlElements={{ addRuleAction: () => null }}
which will prevent the "+ Rule" button from rendering.
onAddGroup
<RG extends RuleGroupTypeAny>(ruleGroup: RG, parentPath: Path, query: RG, context?: any) => RG | false
This callback is invoked before a new group is added. The function should either manipulate the group and return it as an object of the same type (either RuleGroupType
or RuleGroupTypeIC
), or return false
to cancel the addition of the group. You can use findPath
to locate the parent group to which the new group will be added within the query hierarchy. The context
parameter (fourth argument) can be passed from a custom addGroupAction
component to its onHandleClick
prop, which will in turn pass it to onAddGroup
. This allows one to change the group that gets added (or avoid the action completely) based on arbitrary data.
If the query is using independent combinators, you can specify the combinator inserted immediately before the new group (if the parent group is not empty) by adding a combinatorPreceding
property (with a combinator name
as the value) to the group before returning it. Otherwise the combinator preceding the last rule, or the first combinator in the default list if the parent group has only one rule, will be used.
To completely prevent the addition of new groups, pass controlElements={{ addGroupAction: () => null }}
which will prevent the "+ Group" button from rendering.
onMoveRule
<RG extends RuleGroupTypeAny>(
rule: RuleType,
fromPath: Path,
toPath: Path | 'up' | 'down',
query: RG,
nextQuery: RG,
options: MoveOptions,
context?: any
) => RG | boolean;
This callback is invoked immediately before a rule is moved or shifted. The function should return one of three things:
true
to allow the move/shift to proceed as normal.false
to cancel the move/shift.- A new query object (presumably based on the
query
ornextQuery
parameters passed to it).
onMoveGroup
<RG extends RuleGroupTypeAny>(
ruleGroup: RG,
fromPath: Path,
toPath: Path | 'up' | 'down',
query: RG,
nextQuery: RG,
options: MoveOptions,
context?: any
) => RG | boolean;
This callback is invoked immediately before a group is moved or shifted. The function should return one of three things:
true
to allow the move/shift to proceed as normal.false
to cancel the move/shift.- A new query object (presumably based on the
query
ornextQuery
parameters passed to it).
onRemove
<RG extends RuleGroupTypeAny>(ruleOrGroup: RG | RuleType, path: Path, query: RG, context?: any) => boolean
This callback is invoked before a rule or group is removed. The function should return true
if the removal should proceed as normal, or false
if the removal should be aborted.
translations
Partial<Translations>
This prop provides basic internationalization (i18n) support. It can be used to override translatable texts applied to the various controls created by the <QueryBuilder />
component for a specific locale.
All keys in the object and all properties within each key are optional. The translations
prop object will be deep-merged with the default object below. (The default placeholder names referenced below are all "~"
, and the default placeholder labels are "------"
.)
export const defaultTranslations: TranslationsFull = {
fields: {
title: 'Fields',
placeholderName: defaultPlaceholderFieldName,
placeholderLabel: defaultPlaceholderFieldLabel,
placeholderGroupLabel: defaultPlaceholderFieldGroupLabel,
} as const,
operators: {
title: 'Operators',
placeholderName: defaultPlaceholderOperatorName,
placeholderLabel: defaultPlaceholderOperatorLabel,
placeholderGroupLabel: defaultPlaceholderOperatorGroupLabel,
} as const,
value: {
title: 'Value',
} as const,
removeRule: {
label: '⨯',
title: 'Remove rule',
} as const,
removeGroup: {
label: '⨯',
title: 'Remove group',
} as const,
addRule: {
label: '+ Rule',
title: 'Add rule',
} as const,
addGroup: {
label: '+ Group',
title: 'Add group',
} as const,
combinators: {
title: 'Combinators',
} as const,
notToggle: {
label: 'Not',
title: 'Invert this group',
} as const,
cloneRule: {
label: '⧉',
title: 'Clone rule',
} as const,
cloneRuleGroup: {
label: '⧉',
title: 'Clone group',
} as const,
shiftActionUp: {
label: '˄',
title: 'Shift up',
} as const,
shiftActionDown: {
label: '˅',
title: 'Shift down',
} as const,
dragHandle: {
label: '⁞⁞',
title: 'Drag handle',
} as const,
lockRule: {
label: '🔓',
title: 'Lock rule',
} as const,
lockGroup: {
label: '🔓',
title: 'Lock group',
} as const,
lockRuleDisabled: {
label: '🔒',
title: 'Unlock rule',
} as const,
lockGroupDisabled: {
label: '🔒',
title: 'Unlock group',
} as const,
valueSourceSelector: {
title: 'Value source',
} as const,
} satisfies TranslationsFull;
Source: /packages/react-querybuilder/src/defaults.ts#L53-L131
showCombinatorsBetweenRules
boolean
(default false
) Click here for demo
Pass true
to render the combinator selector between each child rule/group in the group body instead of in the group header. This can make some queries easier to understand as it encourages a more natural style of reading.
Note that when this option is enabled, the combinator
property is still managed at the group level even though selectors are displayed among the rules. Selecting a new combinator with one of the inline selectors will update all combinator selectors within the same group since they all use the same value. To display inline combinator selectors that are managed independently, use independent combinators.
showNotToggle
boolean
(default false
) Click here for demo
Pass true
to display the "Not" (aka inversion) toggle switch for each rule group.
showCloneButtons
boolean
(default false
) Click here for demo
Pass true
to display a "clone" button on each group header and rule. Clicking a "clone" button will create an exact duplicate (with new id
/id
s) of the rule or group, positioned immediately after the original, within the same rules
array.
showLockButtons
boolean
(default false
) Click here for demo
Pass true
to display the "Lock rule" and "Lock group" buttons. When a rule is locked, all elements within the rule will be disabled except for the lock button itself (so the user can unlock the rule). When a group is locked, all elements within the group header (except the lock button itself), as well as all child rule/group elements (including their lock buttons), will be disabled.
showShiftActions
boolean
(default false
) Click here for demo
Pass true
to display the "shift up"/"shift down" buttons. The buttons will appear at the front of each rule and group (except the root group), stacked vertically by default. The first/upper button will shift the rule or group one spot higher, while the second/lower button will shift it one spot lower. The translations
properties shiftActionUp
and shiftActionDown
allow configuration of the label and title of each button.
resetOnFieldChange
boolean
(default true
) Click here for demo with this feature disabled
Pass false
to avoid resetting the operator
and value
when the field
is updated.
resetOnOperatorChange
boolean
(default false
) Click here for demo
Pass true
to reset the value
when the operator
is updated.
enableMountQueryChange
boolean
(default true
)
Pass false
to disable the onQueryChange
call on initial mount of the component. This is enabled by default because the query
/defaultQuery
prop is processed during the first render and may be slightly different than the object passed in (id
s would have been generated if they were missing, for example).
autoSelectField
boolean
(default true
) Click here for demo with this feature disabled
Pass false
to automatically add an "empty" option (value "~"
and label "------"
; see translations.fields.placeholder*
to customize) to the fields
array as the first element. The "empty" option will be the initial field selection for all new rules. When the empty field
option is selected, the operator selector and value components will not be rendered for that rule.
autoSelectOperator
boolean
(default true
) Click here for demo with this feature disabled
Pass false
to automatically add an "empty" option (value "~"
and label "------"
; see translations.operators.placeholder*
to customize) to the operators
array as the first element. The "empty" option will be the initial operator selection for all new rules. When the empty operator
option is selected, the value components will not be rendered for that rule.
addRuleToNewGroups
boolean
(default false
) Click here for demo
Pass true
to automatically add a rule to new groups. If neither a query
nor defaultQuery
prop is not passed in, a rule will be added to the root group when the component is mounted. If a query
/defaultQuery
prop is passed in with an empty rules
array, no rule will be added automatically.
listsAsArrays
boolean
(default false
) Click here for demo
Pass true
to update rule values that represent lists with proper arrays instead of comma-separated strings. This prop applies when valueEditorType
is "multiselect"
and when a rule's operator
is "between"
, "notBetween"
, "in"
, or "notIn"
.
For example, the default behavior for the "between" operator might produce this rule:
{
"field": "f1",
"operator": "between",
"value": "f2,f3",
"valueSource": "field"
}
When listsAsArrays
is true, the rule's value
will be an array:
{
"field": "f1",
"operator": "between",
"value": ["f2", "f3"],
"valueSource": "field"
}
parseNumbers
boolean | "enhanced" | "enhanced-limited" | "native" | "native-limited" | "strict" | "strict-limited"
(default false
) Click here for demo
Sets the value
with type number
instead of string
when possible.
Tip: Try the
"strict-limited"
option first.
- The
"*-limited"
options are equivalent to their non-suffixed counterparts except that numeric parsing is only performed when the value editor'sinputType
is"number"
. true
,"strict"
, and"enhanced"
will retain the original value when numeric parsing fails."enhanced"
and"native"
can lead to information loss since any trailing invalid characters will be removed.true
and"strict"
determine numericity usingnumeric-quantity
withallowTrailingInvalid: false
. Values must be numeric in their entirety to be considered numeric, not just start with a number as withparseFloat
."enhanced"
usesnumeric-quantity
withallowTrailingInvalid: true
."native"
uses JavaScript's nativeparseFloat
method, which is similar to the "enhanced" algorithm in that it will strip trailing invalid characters, but it will returnNaN
for non-numeric values instead of the original value.
enableDragAndDrop
boolean
(default false
) Click here for demo
This prop does not need to be set directly on the <QueryBuilder />
component. It has no effect unless the following conditions are met:
- A
QueryBuilderDnD
context provider from the companion package@react-querybuilder/dnd
is rendered higher up in the component tree. react-dnd
andreact-dnd-html5-backend
are installed/imported.
If those conditions are met, and enableDragAndDrop
is not explicitly set to false
on the <QueryBuilder />
component, then enableDragAndDrop
is implicitly true
.
When true
(under the conditions detailed above), a drag handle is displayed on the left-hand side of each group header and each rule. Clicking and dragging the handle element allows users to visually reorder the rules and groups.
Recommended usage
npm i react-querybuilder @react-querybuilder/dnd react-dnd react-dnd-html5-backend
# OR yarn add / pnpm add / bun add
import { QueryBuilderDnD } from '@react-querybuilder/dnd';
import * as ReactDnD from 'react-dnd';
import * as ReactDndHtml5Backend from 'react-dnd-html5-backend';
import { QueryBuilder } from 'react-querybuilder';
const App = () => (
<QueryBuilderDnD dnd={{ ...ReactDnD, ...ReactDndHtml5Backend }}>
<QueryBuilder />
</QueryBuilderDnD>
);
If your application already uses react-dnd
, use QueryBuilderDndWithoutProvider
instead of QueryBuilderDnD
. They are functionally equivalent, but the former assumes a <DndProvider />
already exists higher up in the component tree. The latter renders its own DndProvider
which will conflict with any pre-existing ones. (If you use the wrong component, you will probably see the error message "Cannot have two HTML5 backends at the same time" in the console.)
disabled
boolean | Path[]
(default false
) Click here for demo
Pass true
to disable all subcomponents and prevent changes to the query. Pass an array of paths to disable specific rules and/or groups. For example, disabled={[[0]]}
will disable the top-most rule/group and its subcomponents, but nothing else.
suppressStandardClassnames
boolean
(default false
) Click here for demo
Pass true
to disable the application of standard classnames, including conditional and event-based classes for validation, drag-and-drop, etc..
debugMode
boolean
(default false
) Click here for demo
Pass true
to enabled logging debug information with the onLog
function.
onLog
(message: any) => void
(default console.log
)
Receives logging messages when debugMode
is true
.
idGenerator
() => string
(default generateID
)
Used to generate id
s for rules and groups without them (or clones that need a new id
). By default, QueryBuilder
generates valid v4 UUIDs per RFC 4122, using the crypto
package if available or a Math.random()
-based method otherwise.
accessibleDescriptionGenerator
(props: { path: Path; qbId: string; }) => string
(default generateAccessibleDescription
)
Used to generate the title
attribute applied to the outermost <div>
of each rule group. As this is intended to help with accessibility, the text output from this function should be meaningful, descriptive, and unique within the page.
validator
QueryValidator
Click here for demo
This function is executed each time QueryBuilder
renders. The return value should be a boolean (true
for valid queries, false
for invalid) or an object whose keys are the id
s of each validated rule and group in the query tree. If an object is returned, the values associated to each key should be a boolean (true
for valid rules/groups, false
for invalid) or an object with a valid
boolean property and an optional reasons
array. The full object will be passed to each rule and group component, and all sub-components of each rule/group will receive the value associated with the id
of its rule or group. See the validation documentation for more information.
Independent combinators
The props listed above that specify RuleGroupTypeAny
will actually be inferred as one of the more specific types, RuleGroupType
or RuleGroupTypeIC
. When a query is of type RuleGroupTypeIC
, we say that it is using "independent combinators."
What this means is that a combinator value is defined between each neighboring pair of rules/groups in a group's rules
array (every odd-numbered index). Visually, this has a similar effect to the showCombinatorsBetweenRules
option, except that each combinator is independently controlled by its own selector. You may find that users take to this configuration more easily as it can allow them to express queries more like they would in natural language.
A standard query (RuleGroupType
) might look like this:
const query: RuleGroupType = {
combinator: 'and',
rules: [
{ field: 'f1', operator: '=', value: 'v1' },
{ field: 'f2', operator: '=', value: 'v2' },
],
};
The same query using independent combinators would look like this:
const query: RuleGroupTypeIC = {
rules: [
{ field: 'f1', operator: '=', value: 'v1' },
'and',
{ field: 'f2', operator: '=', value: 'v2' },
],
};
Click here to load the demo with a query using independent combinators.