Skip to content

Commit 16d299f

Browse files
committed
Add context provider documentation for companion/compat packages
1 parent f928b43 commit 16d299f

File tree

5 files changed

+91
-14
lines changed

5 files changed

+91
-14
lines changed

docs/api/misc.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import TypeScriptAdmonition from './_ts_admonition.md';
88

99
<TypeScriptAdmonition />
1010

11+
A non-comprehensive list of exports from `react-querybuilder`.
12+
1113
## Utilities
1214

1315
### `defaultValidator`
@@ -85,6 +87,7 @@ The default components are also exported:
8587

8688
- `ActionElement` - used for action buttons (to add rules, remove groups, etc.)
8789
- `DragHandle` - used for the drag handle on rules and group headers
90+
- `InlineCombinator` - used when either `showCombinatorsBetweenRules` or `independentCombinators` are `true`
8891
- `NotToggle` - used for the "Invert this group" toggle switch
8992
- `Rule` - the default rule component
9093
- `RuleGroup` - the default rule group component

docs/api/querybuilder.mdx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -780,24 +780,39 @@ When the `independentCombinators` option is enabled, the `query` (or `defaultQue
780780

781781
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#enableDragAndDrop=true)
782782

783-
Pass `true` to display a drag handle to the left of each group header and rule. Clicking and dragging the handle element allows visual reordering of rules and groups.
783+
:::caution
784+
785+
This prop does not need to be set directly. If used directly, it has no effect unless the following conditions are met:
786+
787+
1. A `QueryBuilderDnD` context provider from the companion package [`@react-querybuilder/dnd`](https://www.npmjs.com/package/@react-querybuilder/dnd) is rendered higher up in the component tree.
788+
2. [`react-dnd`](https://www.npmjs.com/package/react-dnd) and [`react-dnd-html5-backend`](https://www.npmjs.com/package/react-dnd-html5-backend) are also installed.
784789

785-
Drag-and-drop functionality is only enabled when `<QueryBuilder />` is wrapped in `QueryBuilderDnD` from the companion package [`@react-querybuilder/dnd`](https://www.npmjs.com/package/@react-querybuilder/dnd). [`react-dnd`](https://www.npmjs.com/package/react-dnd) and [`react-dnd-html5-backend`](https://www.npmjs.com/package/react-dnd-html5-backend) will also need to be installed.
790+
If those conditions are met, and `enableDragAndDrop` is not explicitly set to `false` on the `<QueryBuilder />` element, then `enableDragAndDrop` is implicitly set to `true`.
791+
792+
:::
793+
794+
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.
795+
796+
#### Example usage
797+
798+
```bash
799+
yarn add react-querybuilder @react-querybuilder/dnd react-dnd react-dnd-html5-backend
800+
```
786801

787802
```tsx
788803
import { QueryBuilderDnD } from '@react-querybuilder/dnd';
789804
import { QueryBuilder } from 'react-querybuilder';
790805

791806
const App = () => (
792807
<QueryBuilderDnD>
793-
<QueryBuilder enableDragAndDrop />
808+
<QueryBuilder />
794809
</QueryBuilderDnD>
795810
);
796811
```
797812

798813
:::tip
799814

800-
If your application already uses [`react-dnd`](https://react-dnd.github.io/react-dnd/), wrap `<QueryBuilder />` in `QueryBuilderWithoutDndProvider` instead of `QueryBuilderDnD`. They add the same functionality, but the former will rely on your pre-existing `<DndProvider />`. The latter implements its own provider and will clash with a separate `<DndProvider />` higher up in the component tree. (If you use the wrong component, you will probably see the error message "Cannot have two HTML5 backends at the same time.")
815+
If your application already uses [`react-dnd`](https://react-dnd.github.io/react-dnd/), use `QueryBuilderWithoutDndProvider` instead of `QueryBuilderDnD`. They are functionally equivalent, but the former relies on your pre-existing `<DndProvider />` (as long as it is higher up in the component tree). The latter renders its own provider which will clash with an ancestor `DndProvider`. (If you use the wrong component, you will probably see the error message "Cannot have two HTML5 backends at the same time.")
801816

802817
:::
803818

docs/compat.mdx

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
title: Compatibility packages
33
---
44

5-
The default React Query Builder components, being basic HTML5 form controls, are very flexible when it comes to styling (primarily through the [`controlClassnames` prop](./api/querybuilder#controlclassnames)). But some style libraries require different HTML structure to style their form controls correctly.
5+
The default React Query Builder components, being basic HTML5 form controls, are very flexible when it comes to styling (primarily through the [`controlClassnames` prop](./api/querybuilder#controlclassnames)). However, some style libraries require different HTML structure to style their form controls correctly.
66

77
## Packages
88

99
Official component packages compatible with several popular style libraries are available under the [`@react-querybuilder` org on npm](https://www.npmjs.com/org/react-querybuilder).
1010

11-
You can see each alternate component package in action by selecting different options in the "Style" dropdown list on the [demo page](https://react-querybuilder.js.org/react-querybuilder/). The "Demo" links in the table below will load the demo with the respective style library preselected, and the CodeSandbox links will open [codesandbox.io](https://codesandbox.io) with an editable example of the library preloaded.
11+
You can see each alternate component package in action by selecting different options in the "Style" dropdown list on the [demo page](https://react-querybuilder.js.org/react-querybuilder/). The "Demo" links in the table below will load the demo with the respective style library preselected, and the CodeSandbox links will open [codesandbox.io](https://codesandbox.io) with a live, editable example of the library preloaded.
1212

1313
| Official site | Compatibility package | Demo | CodeSandbox |
1414
| -------------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
@@ -18,9 +18,68 @@ You can see each alternate component package in action by selecting different op
1818
| [Chakra UI](https://chakra-ui.com/) | [@react-querybuilder/chakra](https://www.npmjs.com/package/@react-querybuilder/chakra) | [Demo](https://react-querybuilder.js.org/react-querybuilder/#style=chakra) | [CodeSandbox](https://codesandbox.io/s/github/react-querybuilder/react-querybuilder/tree/main/examples/chakra) |
1919
| [MUI](https://mui.com/) | [@react-querybuilder/material](https://www.npmjs.com/package/@react-querybuilder/material) | [Demo](https://react-querybuilder.js.org/react-querybuilder/#style=material) | [CodeSandbox](https://codesandbox.io/s/github/react-querybuilder/react-querybuilder/tree/main/examples/material) |
2020

21-
## Exports
21+
## Usage
2222

23-
Each compatibility package exports a `*ControlElements` object that can be used as the [`controlElements` prop](./api/querybuilder#controlelements) in `<QueryBuilder />`. Some packages also export a `*ControlClassnames` object for use as the [`controlClassnames` prop](./api/querybuilder#controlclassnames).
23+
The recommended way to apply a compatibility package to `<QueryBuilder />` is to wrap it in the `QueryBuilder*` context provider from the compatibility library.
24+
25+
This example uses the Ant Design library:
26+
27+
```tsx
28+
import { QueryBuilderAntD } from '@react-querybuilder/antd';
29+
import 'antd/dist/antd.compact.css';
30+
import { QueryBuilder } from 'react-querybuilder';
31+
import 'react-querybuilder/dist/query-builder.css';
32+
import { defaultQuery, fields } from './constants';
33+
34+
export function App() {
35+
return (
36+
<QueryBuilderAntD>
37+
<QueryBuilder fields={fields} defaultQuery={defaultQuery} />
38+
</QueryBuilderAntD>
39+
);
40+
}
41+
```
42+
43+
Each compatibility package exports its own context provider.
44+
45+
| Compatibility package | Context provider |
46+
| ------------------------------- | ----------------------- |
47+
| `@react-querybuilder/antd` | `QueryBuilderAntD` |
48+
| `@react-querybuilder/bootstrap` | `QueryBuilderBootstrap` |
49+
| `@react-querybuilder/bulma` | `QueryBuilderBulma` |
50+
| `@react-querybuilder/chakra` | `QueryBuilderChakra` |
51+
| `@react-querybuilder/material` | `QueryBuilderMaterial` |
52+
53+
:::tip
54+
55+
React Query Builder context providers can be nested beneath one another to progressively add features and customization. For example, `QueryBuilderDnD` adds drag-and-drop features to the query builder, and you can nest the compatibility package context providers beneath it (or vice versa) to add the style library's components while maintaining the drag-and-drop features.
56+
57+
This example uses the Bulma library _and_ enables drag-and-drop:
58+
59+
```tsx
60+
import { QueryBuilderBulma } from '@react-querybuilder/bulma';
61+
import { QueryBuilderDnD } from '@react-querybuilder/dnd';
62+
import 'bulma/bulma.sass';
63+
import { QueryBuilder } from 'react-querybuilder';
64+
import 'react-querybuilder/dist/query-builder.css';
65+
import { defaultQuery, fields } from './constants';
66+
67+
export function App() {
68+
return (
69+
<QueryBuilderDnD>
70+
<QueryBuilderBulma>
71+
<QueryBuilder fields={fields} defaultQuery={defaultQuery} />
72+
</QueryBuilderBulma>
73+
</QueryBuilderDnD>
74+
);
75+
}
76+
```
77+
78+
:::
79+
80+
## Other exports
81+
82+
Each compatibility package exports a `*ControlElements` object that can be used as the [`controlElements` prop](./api/querybuilder#controlelements) in `<QueryBuilder />`. Some packages also export a `*ControlClassnames` object for use with the [`controlClassnames` prop](./api/querybuilder#controlclassnames). Use these exports if you need more fine-grained control over which standard components get replaced. For even more detailed [customization](#customization), continue reading below.
2483

2584
This example uses the Bootstrap library:
2685

@@ -29,8 +88,8 @@ import {
2988
bootstrapControlClassnames,
3089
bootstrapControlElements,
3190
} from '@react-querybuilder/bootstrap';
32-
import { QueryBuilder } from 'react-querybuilder';
3391
import 'bootstrap/scss/bootstrap.scss';
92+
import { QueryBuilder } from 'react-querybuilder';
3493
import { defaultQuery, fields } from './constants';
3594

3695
export function App() {
@@ -47,11 +106,11 @@ export function App() {
47106

48107
## Customization
49108

50-
Many of the compatibility components accept any props defined by the style library for the actual rendered component in addition to the standard props defined by `react-querybuilder`. This allows you to idiomatically customize the library component while leaving the integration with the query builder up to the compatibility component.
109+
Many of the compatibility components accept props defined by the style library for the actual rendered component in addition to the standard props defined by `react-querybuilder`. This allows you to idiomatically customize the style library's component while leaving the query builder integration up to the compatibility layer.
51110

52111
For example, the `AntDActionElement` component from `@react-querybuilder/antd` renders the `Button` component from `antd`, so it can accept properties of the `ActionWithRulesProps` interface from `react-querybuilder` _and_ the `ButtonProps` interface from `antd`.
53112

54-
In the example below, the `size` prop is not available on `ActionWithRulesProps`, but it's accepted because it's one of `antd`'s `Button` props (from the `ButtonProps` interface).
113+
In the example below, the `size` prop is accepted because it's one of `antd`'s `Button` props (from the `ButtonProps` interface), even though it's not included in the `ActionWithRulesProps` interface.
55114

56115
```tsx
57116
import { AntDActionElement, antdControlElements } from '@react-querybuilder/antd';
@@ -82,7 +141,7 @@ export const App = () => {
82141

83142
This list shows which library components' props will be accepted by the compatibility components, in addition to those defined by `react-querybuilder`.
84143

85-
| Compatibility component | Base props | Rendered library component |
144+
| Component | Base props (from RQB) | Rendered library component |
86145
| ----------------------- | ------------------------ | --------------------------------------------------------------- |
87146
| `AntDActionElement` | `ActionWithRulesProps` | `import { Button } from 'antd'` |
88147
| `AntDDragHandle` | `DragHandleProps` | `import { HolderOutlined } from '@ant-design/icons'` |

docs/tips/common-mistakes.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const App = () => {
3232
};
3333
```
3434

35-
This is wrong and can lead to undesirable behavior, such as the value editor losing focus after each keystroke. This happens because the `CustomValueEditor` component is being redefined each time the `App` component renders. Fortunately, the fix is very simple: move the custom component declaration outside of the other function component (it can still be in the same file, just not within the function body):
35+
This can lead to undesirable behavior, such as the value editor losing focus after each keystroke. This happens because the `CustomValueEditor` component is being redefined each time the `App` component renders. To fix the problem, move the custom component declaration outside of the other function component (it can still be in the same file, just not within the function body):
3636

3737
```tsx title="App.tsx"
3838
// highlight-start

versioned_docs/version-4.5.2/tips/common-mistakes.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const App = () => {
3232
};
3333
```
3434

35-
This is wrong and can lead to undesirable behavior, such as the value editor losing focus after each keystroke. This happens because the `CustomValueEditor` component is being redefined each time the `App` component renders. Fortunately, the fix is very simple: move the custom component declaration outside of the other function component (it can still be in the same file, just not within the function body):
35+
This can lead to undesirable behavior, such as the value editor losing focus after each keystroke. This happens because the `CustomValueEditor` component is being redefined each time the `App` component renders. To fix the problem, move the custom component declaration outside of the other function component (it can still be in the same file, just not within the function body):
3636

3737
```tsx title="App.tsx"
3838
// highlight-start

0 commit comments

Comments
 (0)