Skip to main content
Version: Next

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.

note

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.)

tip

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.

caution

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' }}>
)
}
PropertyClasses 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.

PropertyType
actionElementReact.ComponentType<ActionProps>
addGroupActionReact.ComponentType<ActionWithRulesAndAddersProps> | null
addRuleActionReact.ComponentType<ActionWithRulesAndAddersProps> | null
cloneGroupActionReact.ComponentType<ActionWithRulesProps> | null
cloneRuleActionReact.ComponentType<ActionProps> | null
combinatorSelectorReact.ComponentType<CombinatorSelectorProps> | null
dragHandleReact.ForwardRefExoticComponent<DragHandleProps & React.RefAttributes<HTMLSpanElement>> | null
fieldSelectorReact.ComponentType<FieldSelectorProps> | null
inlineCombinatorReact.ComponentType<InlineCombinatorProps> | null
lockGroupActionReact.ComponentType<ActionWithRulesProps> | null
lockRuleActionReact.ComponentType<ActionProps> | null
notToggleReact.ComponentType<NotToggleProps> | null
operatorSelectorReact.ComponentType<OperatorSelectorProps> | null
removeGroupActionReact.ComponentType<ActionWithRulesProps> | null
removeRuleActionReact.ComponentType<ActionProps> | null
ruleReact.ComponentType<RuleProps>
ruleGroupReact.ComponentType<RuleGroupProps>
ruleGroupBodyElementsReact.ComponentType<RuleGroupProps & ReturnType<typeof useRuleGroup>>
ruleGroupHeaderElementsReact.ComponentType<RuleGroupProps & ReturnType<typeof useRuleGroup>>
shiftActionsReact.ComponentType<ShiftActionsProps> | null
valueEditorReact.ComponentType<ValueEditorProps> | null
valueSelectorReact.ComponentType<ValueSelectorProps>
valueSourceSelectorReact.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:

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:

PropTypeDescription
labelReactNodetranslations.addGroup.label, e.g. "+ Group"
titlestringtranslations.addGroup.title, e.g. "Add group"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent, context?: any) => voidAdds a new sub-group to this group
rulesRuleOrGroupArrayThe rules array for this group
ruleOrGroupRuleGroupTypeAnyThis group
levelnumberThe level of this group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this group
disabledbooleanWhether this group is disabled/locked
pathPathPath of this group
schemaSchemaQuery schema

addRuleAction

Adds a rule to the current group. Default is ActionElement.

Props for addRuleAction

Per the ActionWithRulesAndAddersProps interface:

PropTypeDescription
labelReactNodetranslations.addRule.label, e.g. "+ Rule"
titlestringtranslations.addRule.title, e.g. "Add rule"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent, context?: any) => voidAdds a new rule to this rule
rulesRuleOrGroupArrayThe rules array for this rule
ruleOrGroupRuleGroupTypeAnyThis rule
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery schema

cloneGroupAction

Clones the current group. Default is ActionElement.

Props for cloneGroupAction

Per the ActionWithRulesProps interface:

PropTypeDescription
labelReactNodetranslations.cloneRuleGroup.label, e.g. "⧉"
titlestringtranslations.cloneRuleGroup.title, e.g. "Clone group"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent) => voidClones this group
rulesRuleOrGroupArrayThe rules array for this group
ruleOrGroupRuleGroupTypeAnyThis group
levelnumberThe level of this group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this group
disabledbooleanWhether this group is disabled/locked
pathPathPath of this group
schemaSchemaQuery schema

cloneRuleAction

Clones the current rule. Default is ActionElement.

Props for cloneRuleAction

Per the ActionProps interface:

PropTypeDescription
labelstringtranslations.cloneRule.label, e.g. "⧉"
titlestringtranslations.cloneRule.title, e.g. "Clone rule"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent) => voidClones the rule
ruleOrGroupRuleTypeThis rule
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery 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:

PropTypeDescription
optionsOptionListSame as combinators prop passed into QueryBuilder
valuestringSelected combinator from the existing query representation, if any
classNamestringCSS classNames to be applied
handleOnChange(value: any) => voidUpdates the group's combinator
rulesRuleOrGroupArrayThe rules array for this group
titlestringtranslations.combinators.title, e.g. "Combinators"
levelnumberThe level of this group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this group
disabledbooleanWhether this group is disabled/locked
pathPathPath of this group
schemaSchemaQuery 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:

PropTypeDescription
labelReactNodetranslations.dragHandle.label, e.g. "⁞⁞"
titlestringtranslations.dragHandle.title, e.g. "Drag handle"
classNamestringCSS classNames to be applied
levelnumberThe level of this rule/group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule/group
disabledbooleanWhether this rule/group is disabled/locked
pathPathPath of this rule/group
schemaSchemaQuery schema
ruleOrGroupRuleGroupTypeAny | RuleTypeThis 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:

PropTypeDescription
optionsOptionList<Field>Same as fields prop passed into QueryBuilder
valuestringSelected field from the existing query representation, if any
titlestringtranslations.fields.title, e.g. "Fields"
operatorstringSelected operator from the existing query representation, if any
classNamestringCSS classNames to be applied
handleOnChange(value: any) => voidUpdates the rule's field
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery schema
ruleRuleTypeThis rule

inlineCombinator

A small wrapper around the combinatorSelector component. Default is InlineCombinator.

Props for inlineCombinator

Per the InlineCombinatorProps interface, which extends CombinatorSelectorProps:

PropTypeDescription
componentSchema['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:

PropTypeDescription
labelReactNodetranslations.lockGroup.label or translations.lockGroupDisabled.label, e.g. "🔓" when unlocked and "🔒" when locked
titlestringtranslations.lockGroup.title or translations.lockGroupDisabled.title, e.g. "Lock group" or "Unlock group"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent) => voidLocks the group
rulesRuleOrGroupArrayThe rules present for this group
ruleOrGroupRuleGroupTypeAnyThis group
levelnumberThe level of this group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this group
disabledbooleanWhether this group is disabled/locked
disabledTranslationstringtranslations.lockGroupDisabled if parent group is not disabled, otherwise undefined
pathPathPath of this group
schemaSchemaQuery schema

lockRuleAction

Locks the current rule (sets the disabled property to true). Default is ActionElement.

Props for lockRuleAction

Per the ActionWithRulesProps interface:

PropTypeDescription
labelReactNodetranslations.lockRule.label or translations.lockRuleDisabled.label, e.g. "🔓" when unlocked and "🔒" when locked
titlestringtranslations.lockRule.title or translations.lockRuleDisabled.title, e.g. "Lock rule" or "Unlock rule"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent) => voidLocks the rule
ruleOrGroupRuleTypeThis rule
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
disabledTranslationstringtranslations.lockRuleDisabled if parent group is not disabled, otherwise undefined
pathPathPath of this rule
schemaSchemaQuery schema

notToggle

Toggles the not property of the current group between true and false. Default is NotToggle.

Props for notToggle

Per the NotToggleProps interface:

PropTypeDescription
labelReactNodetranslations.notToggle.label, e.g. "Not"
titlestringtranslations.notToggle.title, e.g. "Invert this group"
classNamestringCSS classNames to be applied
handleOnChange(checked: boolean) => voidUpdates the group's not property
checkedbooleanWhether the input should be checked or not
levelnumberThe level of this group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this group
disabledbooleanWhether this group is disabled/locked
pathPathPath of this group
schemaSchemaQuery schema
ruleGroupRuleGroupTypeAnyThis group

operatorSelector

Selects the operator property for the current rule. Default is ValueSelector.

Props for operatorSelector

Per the OperatorSelectorProps interface:

PropTypeDescription
fieldstringField name corresponding to this rule
fieldDataFieldThe entire object from the fields array for this field
optionsOptionList<Operator>Return value of getOperators(field, { fieldData })
valuestringSelected operator from the existing query representation, if any
titlestringtranslations.operators.title, e.g. "Operators"
classNamestringCSS classNames to be applied
handleOnChange(value: any) => voidUpdates the rule's operator
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery schema
ruleRuleTypeThis rule

removeGroupAction

Removes the current group from its parent group's rules array. Default is ActionElement.

Props for removeGroupAction

Per the ActionWithRulesProps interface:

PropTypeDescription
labelReactNodetranslations.removeGroup.label, e.g. "⨯"
titlestringtranslations.removeGroup.title, e.g. "Remove group"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent) => voidRemoves the group
rulesRuleOrGroupArrayThe rules array for this group
ruleOrGroupRuleGroupTypeAnyThis group
levelnumberThe level of this group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this group
disabledbooleanWhether this group is disabled/locked
pathPathPath of this group
schemaSchemaQuery schema

removeRuleAction

Removes the current rule from its parent group's rules array. Default is ActionElement.

Props for removeRuleAction

Per the ActionProps interface:

PropTypeDescription
labelReactNodetranslations.removeRule.label, e.g. "⨯"
titlestringtranslations.removeRule.title, e.g. "Remove rule"
classNamestringCSS classNames to be applied
handleOnClick(e: React.MouseEvent) => voidRemoves the rule
ruleOrGroupRuleTypeThis rule
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery schema

rule

Rule layout component. Default is Rule.

Props for rule

Per the RuleProps interface:

PropTypeDescription
idstringUnique identifier for this rule
pathPathPath of this rule
ruleRuleTypeThe rule object
translationsTranslationsThe default translations merged with the translations prop
schemaSchemaQuery schema
actionsQueryActionsQuery update functions
contextanyContainer for custom props that are passed to all components
disabledbooleanWhether the rule itself is disabled
shiftUpDisabledbooleanWhether shifting the rule up is disallowed
shiftDownDisabledbooleanWhether shifting the rule down is disallowed
parentDisabledbooleanWhether the parent group of this rule is disabled
tip

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:

PropTypeDescription
idstringUnique identifier for this group
pathPathPath of this group
ruleGroupRuleGroupTypeAnyThe group object
translationsTranslationsThe default translations merged with the translations prop
schemaSchemaQuery schema
actionsQueryActionsQuery update functions
contextanyContainer for custom props that are passed to all components
disabledbooleanWhether the group itself is disabled
shiftUpDisabledbooleanWhether shifting the group up is disallowed
shiftDownDisabledbooleanWhether shifting the group down is disallowed
parentDisabledbooleanWhether the parent group of this group is disabled
tip

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:

PropTypeDescription
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"
classNamestringCSS classNames to be applied
ruleOrGroupRuleGroupTypeAnyThis rule/group
levelnumberThe level of this rule/group
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule/group
disabledbooleanWhether this rule/group is disabled/locked
pathPathPath of this rule/group
schemaSchemaQuery schema
shiftUp() => voidMethod to shift the rule/group up one place
shiftDown() => voidMethod to shift the rule/group down one place
shiftUpDisabledbooleanWhether shifting the rule/group up is disallowed
shiftDownDisabledbooleanWhether 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:

PropTypeDescription
fieldstringField name corresponding to this rule
fieldDataFieldThe entire object from the fields array for this field
operatorstringOperator name corresponding to this rule
valuestringvalue from the existing query representation, if any
titlestringtranslations.value.title, e.g. "Value"
handleOnChange(value: any) => voidUpdates the rule's value
typeValueEditorTypeType of editor to be displayed
inputTypestringIntended @type attribute of the <input>, if type prop is "text"
valuesany[]List of available values for this rule
classNamestringCSS classNames to be applied
valueSourceValueSourceValue source for this rule
listsAsArraysbooleanWhether to manage value lists (i.e. "between"/"in" operators) as arrays
parseNumbersParseNumberMethodWhether to parse real numbers from strings
separatorReactNodeSeparator element for series of editors (i.e. "between" operator)
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery schema
ruleRuleTypeThis 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:

PropTypeDescription
fieldstringField name corresponding to this rule
fieldDataFieldThe entire object from the fields array for the selected field
optionsOptionList<ValueSourceOption>Return value of getValueSources(field, operator, { fieldData })
valueValueSourceSelected value source for this rule, if any
titlestringtranslations.valueSourceSelector.title, e.g. "Value source"
classNamestringCSS classNames to be applied
handleOnChange(value: any) => voidUpdates the rule's valueSource
levelnumberThe level of this rule
contextanyContainer for custom props that are passed to all components
validationboolean | ValidationResultValidation result of this rule
disabledbooleanWhether this rule is disabled/locked
pathPathPath of this rule
schemaSchemaQuery schema
ruleRuleTypeThis 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.

tip

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.

tip

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:

  1. true to allow the move/shift to proceed as normal.
  2. false to cancel the move/shift.
  3. A new query object (presumably based on the query or nextQuery 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:

  1. true to allow the move/shift to proceed as normal.
  2. false to cancel the move/shift.
  3. A new query object (presumably based on the query or nextQuery 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/ids) 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 (ids 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's inputType 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 using numeric-quantity with allowTrailingInvalid: false. Values must be numeric in their entirety to be considered numeric, not just start with a number as with parseFloat.
  • "enhanced" uses numeric-quantity with allowTrailingInvalid: true.
  • "native" uses JavaScript's native parseFloat method, which is similar to the "enhanced" algorithm in that it will strip trailing invalid characters, but it will return NaN for non-numeric values instead of the original value.

enableDragAndDrop

boolean (default false) Click here for demo

caution

This prop does not need to be set directly on the <QueryBuilder /> component. It has no effect unless the following conditions are met:

  1. A QueryBuilderDnD context provider from the companion package @react-querybuilder/dnd is rendered higher up in the component tree.
  2. react-dnd and react-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.

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>
);
tip

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 ids 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 ids 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.