Skip to content

Commit 81e1bb1

Browse files
committed
Initial commit
0 parents  commit 81e1bb1

37 files changed

+1459
-0
lines changed

.gitignore

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Generated files
5+
build/
6+
dist/
7+
coverage/
8+
build-analysis.*
9+
10+
# Misc
11+
.DS_Store
12+
.env
13+
.env.local
14+
.env.development.local
15+
.env.test.local
16+
.env.production.local
17+
18+
.idea
19+
*.log
20+
.tmp
21+
build-stats.*
22+
23+
.pnp.*
24+
.yarn/*
25+
!.yarn/patches
26+
!.yarn/plugins
27+
!.yarn/releases
28+
!.yarn/sdks
29+
!.yarn/versions
30+
yarn.lock

.prettierignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Hidden(ish) files
2+
**/.*
3+
4+
# Generated
5+
*Parser.js
6+
7+
# Binaries
8+
*.jpeg
9+
*.jpg
10+
*.png
11+
*.svg
12+
bun.lockb
13+
14+
# Unsupported
15+
*.jison
16+
*.toml
17+
CNAME

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"editor.formatOnSave": true,
3+
"files.eol": "\n",
4+
"typescript.tsdk": "node_modules/typescript/lib"
5+
}

README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
## @react-querybuilder/chakra2
2+
3+
Official [react-querybuilder](https://npmjs.com/package/react-querybuilder) compatibility package for [Chakra UI version 2](https://chakra-ui.com/).
4+
5+
> [!WARNING] This package is only compatible with Chakra UI version 2
6+
>
7+
> For Chakra UI version 3 compatibility, use [`@react-querybuilder/chakra`](https://npmjs.com/package/@react-querybuilder/chakra).
8+
9+
- [Demo (using latest Chakra UI)](https://react-querybuilder.js.org/demo/chakra)
10+
- [Full documentation](https://react-querybuilder.js.org/)
11+
- [CodeSandbox](https://react-querybuilder.js.org/sandbox?t=chakra2) / [StackBlitz](https://react-querybuilder.js.org/sandbox?p=stackblitz&t=chakra2) example projects
12+
13+
![Screenshot](./screenshot.png)
14+
15+
## Installation
16+
17+
```bash
18+
npm i react-querybuilder @react-querybuilder/chakra @chakra-ui/icons @chakra-ui/react @chakra-ui/system @emotion/react @emotion/styled framer-motion
19+
# OR yarn add / pnpm add / bun add
20+
```
21+
22+
## Usage
23+
24+
To configure the query builder to use Chakra-compatible components, place `QueryBuilderChakra` above `QueryBuilder` and beneath `ChakraProvider` in the component hierarchy.
25+
26+
```tsx
27+
import { ChakraProvider, extendTheme } from "@chakra-ui/react";
28+
import { QueryBuilderChakra } from "@react-querybuilder/chakra";
29+
import { useState } from "react";
30+
import {
31+
type Field,
32+
QueryBuilder,
33+
type RuleGroupType,
34+
} from "react-querybuilder";
35+
36+
const chakraTheme = extendTheme();
37+
38+
const fields: Field[] = [
39+
{ name: "firstName", label: "First Name" },
40+
{ name: "lastName", label: "Last Name" },
41+
];
42+
43+
export function App() {
44+
const [query, setQuery] = useState<RuleGroupType>({
45+
combinator: "and",
46+
rules: [],
47+
});
48+
49+
return (
50+
<ChakraProvider theme={chakraTheme}>
51+
<QueryBuilderChakra>
52+
<QueryBuilder
53+
fields={fields}
54+
defaultQuery={query}
55+
onQueryChange={setQuery}
56+
/>
57+
</QueryBuilderChakra>
58+
</ChakraProvider>
59+
);
60+
}
61+
```
62+
63+
> [!NOTE]
64+
>
65+
> Some additional styling may be necessary. We recommend the following:
66+
>
67+
> ```css
68+
> .queryBuilder .chakra-select__wrapper {
69+
> width: fit-content;
70+
> display: inline-block;
71+
> }
72+
>
73+
> .queryBuilder .chakra-input {
74+
> width: auto;
75+
> display: inline-block;
76+
> }
77+
>
78+
> .queryBuilder .chakra-radio-group {
79+
> display: inline-block;
80+
> }
81+
> ```
82+
83+
`QueryBuilderChakra` is a React context provider that assigns the following props to all descendant `QueryBuilder` elements. The props can be overridden on the `QueryBuilder` or used directly without the context provider.
84+
85+
| Export | `QueryBuilder` prop |
86+
| ----------------------- | ------------------------------- |
87+
| `chakraControlElements` | `controlElements` |
88+
| `chakraTranslations` | `translations` |
89+
| `ChakraActionElement` | `controlElements.actionElement` |
90+
| `ChakraDragHandle` | `controlElements.dragHandle` |
91+
| `ChakraNotToggle` | `controlElements.notToggle` |
92+
| `ChakraValueEditor` | `controlElements.valueEditor` |
93+
| `ChakraValueSelector` | `controlElements.valueSelector` |
94+
95+
> [!TIP]
96+
>
97+
> By default, this package uses icons from `@chakra-ui/icons` for button labels. To reset button labels to their default strings, use `defaultTranslations` from `react-querybuilder`.
98+
>
99+
> ```tsx
100+
> <QueryBuilderChakra translations={defaultTranslations}>
101+
> ```

bun.lockb

153 KB
Binary file not shown.

dev/constants.ts

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import type { BaseOption, Field, RuleGroupType, RuleGroupTypeIC } from 'react-querybuilder';
2+
import { convertToIC, defaultOperators, generateID } from 'react-querybuilder';
3+
import { musicalInstruments } from './musicalInstruments';
4+
5+
const dos = defaultOperators as BaseOption[];
6+
7+
export const fields: Field[] = [
8+
{
9+
name: 'firstName',
10+
label: 'First Name',
11+
placeholder: 'Enter first name',
12+
},
13+
{
14+
name: 'lastName',
15+
label: 'Last Name',
16+
placeholder: 'Enter last name',
17+
defaultOperator: 'beginsWith',
18+
},
19+
{ name: 'age', label: 'Age', inputType: 'number' },
20+
{
21+
name: 'isMusician',
22+
label: 'Is a musician',
23+
valueEditorType: 'checkbox',
24+
operators: dos.filter(op => op.name === '='),
25+
defaultValue: false,
26+
},
27+
{
28+
name: 'instrument',
29+
label: 'Primary instrument',
30+
valueEditorType: 'select',
31+
values: musicalInstruments,
32+
defaultValue: 'Cowbell',
33+
operators: dos.filter(op => op.name === '=' || op.name === 'in'),
34+
},
35+
{
36+
name: 'alsoPlays',
37+
label: 'Also plays',
38+
valueEditorType: 'multiselect',
39+
values: musicalInstruments,
40+
defaultValue: 'More cowbell',
41+
operators: dos.filter(op => op.name === 'in'),
42+
},
43+
{
44+
name: 'gender',
45+
label: 'Gender',
46+
operators: dos.filter(op => op.name === '='),
47+
valueEditorType: 'radio',
48+
values: [
49+
{ name: 'M', label: 'Male' },
50+
{ name: 'F', label: 'Female' },
51+
{ name: 'O', label: 'Other' },
52+
],
53+
},
54+
{ name: 'height', label: 'Height', inputType: 'number' },
55+
{ name: 'job', label: 'Job' },
56+
{ name: 'email', label: 'Email', inputType: 'email' },
57+
{ name: 'description', label: 'Description', valueEditorType: 'textarea' },
58+
{ name: 'birthdate', label: 'Birth Date', inputType: 'date' },
59+
{ name: 'datetime', label: 'Show Time', inputType: 'datetime-local' },
60+
{ name: 'alarm', label: 'Daily Alarm', inputType: 'time' },
61+
{
62+
name: 'groupedField1',
63+
label: 'Grouped Field 1',
64+
comparator: 'groupNumber',
65+
groupNumber: 'group1',
66+
valueSources: ['field', 'value'],
67+
},
68+
{
69+
name: 'groupedField2',
70+
label: 'Grouped Field 2',
71+
comparator: 'groupNumber',
72+
groupNumber: 'group1',
73+
valueSources: ['field', 'value'],
74+
},
75+
{
76+
name: 'groupedField3',
77+
label: 'Grouped Field 3',
78+
comparator: 'groupNumber',
79+
groupNumber: 'group1',
80+
valueSources: ['field', 'value'],
81+
},
82+
{
83+
name: 'groupedField4',
84+
label: 'Grouped Field 4',
85+
comparator: 'groupNumber',
86+
groupNumber: 'group1',
87+
valueSources: ['field', 'value'],
88+
},
89+
];
90+
91+
export const emptyQuery: RuleGroupType = { combinator: 'and', rules: [] };
92+
export const emptyQueryIC: RuleGroupTypeIC = convertToIC(emptyQuery);
93+
94+
export const initialQuery: RuleGroupType = {
95+
id: generateID(),
96+
combinator: 'and',
97+
not: false,
98+
rules: [
99+
{
100+
id: generateID(),
101+
field: 'firstName',
102+
value: 'Stev',
103+
operator: 'beginsWith',
104+
},
105+
{
106+
id: generateID(),
107+
field: 'lastName',
108+
value: 'Vai, Vaughan',
109+
operator: 'in',
110+
},
111+
{
112+
id: generateID(),
113+
field: 'age',
114+
operator: '>',
115+
value: '28',
116+
},
117+
{
118+
id: generateID(),
119+
combinator: 'or',
120+
rules: [
121+
{
122+
id: generateID(),
123+
field: 'isMusician',
124+
operator: '=',
125+
value: true,
126+
},
127+
{
128+
id: generateID(),
129+
field: 'instrument',
130+
operator: '=',
131+
value: 'Guitar',
132+
},
133+
],
134+
},
135+
{
136+
id: generateID(),
137+
field: 'groupedField1',
138+
operator: '=',
139+
value: 'groupedField4',
140+
valueSource: 'field',
141+
},
142+
{
143+
id: generateID(),
144+
field: 'birthdate',
145+
operator: 'between',
146+
value: '1954-10-03,1960-06-06',
147+
},
148+
],
149+
};
150+
151+
export const initialQueryIC: RuleGroupTypeIC = convertToIC(initialQuery);

dev/main.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
2+
import * as React from 'react';
3+
import { createRoot } from 'react-dom/client';
4+
import { QueryBuilder } from 'react-querybuilder';
5+
import { QueryBuilderChakra } from '../src';
6+
import './styles.scss';
7+
import { fields, initialQuery } from './constants';
8+
9+
const chakraTheme = extendTheme({
10+
components: {
11+
Button: {
12+
baseStyle: {
13+
color: 'rebeccapurple',
14+
fontWeight: 'bold', // Normally "semibold"
15+
},
16+
},
17+
},
18+
config: {
19+
initialColorMode: 'light',
20+
useSystemColorMode: false,
21+
},
22+
});
23+
24+
const App = () => {
25+
return (
26+
<div id="app">
27+
<ChakraProvider theme={chakraTheme}>
28+
<QueryBuilderChakra>
29+
<QueryBuilder fields={fields} defaultQuery={initialQuery} />
30+
</QueryBuilderChakra>
31+
</ChakraProvider>
32+
</div>
33+
);
34+
};
35+
36+
createRoot(document.querySelector('#app')!).render(
37+
<React.StrictMode>
38+
<App />
39+
</React.StrictMode>
40+
);

0 commit comments

Comments
 (0)