diff --git a/samples/interactions/query-builder/template/package.json b/samples/interactions/query-builder/template/package.json
index 907622b310..55f004921c 100644
--- a/samples/interactions/query-builder/template/package.json
+++ b/samples/interactions/query-builder/template/package.json
@@ -15,7 +15,7 @@
},
"dependencies": {
"igniteui-react": "19.5.0-beta.2",
- "igniteui-react-core": "19.5.0-beta.2",
+ "igniteui-react-core": "19.3.1",
"igniteui-webcomponents": "^6.3.0",
"igniteui-webcomponents-grids": "6.3.0-alpha.2",
"lit-html": "^3.2.0",
@@ -33,7 +33,7 @@
"eslint": "^8.33.0",
"eslint-config-react": "^1.1.7",
"eslint-plugin-react": "^7.20.0",
- "typescript": "^4.8.4",
+ "typescript": "^5.9.3",
"vite": "^7.1.9",
"vitest": "^3.2.4",
"vitest-canvas-mock": "^0.3.3",
diff --git a/samples/interactions/query-builder/template/src/index.tsx b/samples/interactions/query-builder/template/src/index.tsx
index a0847cd055..8dd452423f 100644
--- a/samples/interactions/query-builder/template/src/index.tsx
+++ b/samples/interactions/query-builder/template/src/index.tsx
@@ -8,8 +8,7 @@ import {
IgcFilteringExpressionsTree,
IgcExpressionTree,
FilteringLogic,
- IgcStringFilteringOperand,
- defineComponents as defineGridComponents
+ IgcStringFilteringOperand
} from 'igniteui-webcomponents-grids/grids';
import {
@@ -30,7 +29,8 @@ import { html, render } from 'lit-html';
import 'igniteui-webcomponents-grids/grids/themes/light/material.css';
// Register components
-defineGridComponents(IgcQueryBuilderComponent, IgcQueryBuilderHeaderComponent);
+IgcQueryBuilderComponent.register();
+IgcQueryBuilderHeaderComponent.register();
defineComponents(
IgcDatePickerComponent,
IgcDateTimeInputComponent,
@@ -42,6 +42,16 @@ defineComponents(
IgcIconComponent
);
+// Declare JSX types for custom elements
+declare global {
+ namespace JSX {
+ interface IntrinsicElements {
+ 'igc-query-builder': any;
+ 'igc-query-builder-header': any;
+ }
+ }
+}
+
// Types
interface Field {
field: string;
@@ -354,7 +364,7 @@ const QueryBuilderTemplate: React.FC = () => {
// Set up query builder
useEffect(() => {
- if (!queryBuilderRef.current || !expressionTree) return;
+ if (!queryBuilderRef.current || !expressionTree) return undefined;
const queryBuilder = queryBuilderRef.current;
queryBuilder.entities = entities as any;
From 2aa59bc23d4102cd9ff66dbbf5ee4c8bb517d6d1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 1 Feb 2026 22:50:20 +0000
Subject: [PATCH 4/6] Address code review feedback: fix TypeScript version
consistency and indentation
Co-authored-by: onlyexeption <19392175+onlyexeption@users.noreply.github.com>
---
samples/interactions/query-builder/overview/.eslintrc.js | 2 +-
samples/interactions/query-builder/overview/package.json | 2 +-
samples/interactions/query-builder/template/.eslintrc.js | 2 +-
samples/interactions/query-builder/template/package.json | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/samples/interactions/query-builder/overview/.eslintrc.js b/samples/interactions/query-builder/overview/.eslintrc.js
index 0280480e75..0c41c2db83 100644
--- a/samples/interactions/query-builder/overview/.eslintrc.js
+++ b/samples/interactions/query-builder/overview/.eslintrc.js
@@ -58,7 +58,7 @@ module.exports = {
"no-throw-literal": "off",
"no-useless-concat": "off",
"no-mixed-operators": "off",
- "no-mixed-spaces-and-tabs": 0,
+ "no-mixed-spaces-and-tabs": 0,
"no-prototype-builtins": "off",
"prefer-const": "off",
"prefer-rest-params": "off",
diff --git a/samples/interactions/query-builder/overview/package.json b/samples/interactions/query-builder/overview/package.json
index 8553d05c28..6a9253739d 100644
--- a/samples/interactions/query-builder/overview/package.json
+++ b/samples/interactions/query-builder/overview/package.json
@@ -32,7 +32,7 @@
"eslint": "^8.33.0",
"eslint-config-react": "^1.1.7",
"eslint-plugin-react": "^7.20.0",
- "typescript": "^5.0.0",
+ "typescript": "5.0.2",
"vite": "^7.1.9",
"vitest": "^3.2.4",
"vitest-canvas-mock": "^0.3.3",
diff --git a/samples/interactions/query-builder/template/.eslintrc.js b/samples/interactions/query-builder/template/.eslintrc.js
index 0280480e75..0c41c2db83 100644
--- a/samples/interactions/query-builder/template/.eslintrc.js
+++ b/samples/interactions/query-builder/template/.eslintrc.js
@@ -58,7 +58,7 @@ module.exports = {
"no-throw-literal": "off",
"no-useless-concat": "off",
"no-mixed-operators": "off",
- "no-mixed-spaces-and-tabs": 0,
+ "no-mixed-spaces-and-tabs": 0,
"no-prototype-builtins": "off",
"prefer-const": "off",
"prefer-rest-params": "off",
diff --git a/samples/interactions/query-builder/template/package.json b/samples/interactions/query-builder/template/package.json
index 55f004921c..2991dec303 100644
--- a/samples/interactions/query-builder/template/package.json
+++ b/samples/interactions/query-builder/template/package.json
@@ -33,7 +33,7 @@
"eslint": "^8.33.0",
"eslint-config-react": "^1.1.7",
"eslint-plugin-react": "^7.20.0",
- "typescript": "^5.9.3",
+ "typescript": "5.0.2",
"vite": "^7.1.9",
"vitest": "^3.2.4",
"vitest-canvas-mock": "^0.3.3",
From be087d8e8bc033f7ab27ba9e4213b241574c145a Mon Sep 17 00:00:00 2001
From: onlyexeption
Date: Mon, 2 Feb 2026 12:40:27 +0200
Subject: [PATCH 5/6] fix: convert to class component & minor changes
---
.../overview/.devcontainer/devcontainer.json | 4 +
.../query-builder/overview/README.md | 69 +++--
.../query-builder/overview/package.json | 4 +-
.../query-builder/overview/src/index.tsx | 258 +++++++++-------
.../template/.devcontainer/devcontainer.json | 4 +
.../query-builder/template/README.md | 81 ++---
.../query-builder/template/package.json | 4 +-
.../query-builder/template/src/index.tsx | 286 ++++++++++--------
8 files changed, 397 insertions(+), 313 deletions(-)
create mode 100644 samples/interactions/query-builder/overview/.devcontainer/devcontainer.json
create mode 100644 samples/interactions/query-builder/template/.devcontainer/devcontainer.json
diff --git a/samples/interactions/query-builder/overview/.devcontainer/devcontainer.json b/samples/interactions/query-builder/overview/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..e0b8e9c925
--- /dev/null
+++ b/samples/interactions/query-builder/overview/.devcontainer/devcontainer.json
@@ -0,0 +1,4 @@
+{
+ "name": "Node.js",
+ "image": "mcr.microsoft.com/devcontainers/javascript-node:22"
+}
\ No newline at end of file
diff --git a/samples/interactions/query-builder/overview/README.md b/samples/interactions/query-builder/overview/README.md
index b9fb56c46f..d61a218431 100644
--- a/samples/interactions/query-builder/overview/README.md
+++ b/samples/interactions/query-builder/overview/README.md
@@ -1,33 +1,56 @@
-# Query Builder Overview Sample
+
+
-This sample demonstrates the Query Builder component with Grid integration.
+This folder contains implementation of React application with example of Overview feature using [Query Builder](https://www.infragistics.com/products/ignite-ui-react/react/components/general-getting-started.html) component.
-## Features
-- Query Builder with entity selection (Customers/Orders)
-- Dynamic field management based on selected entity
-- Expression tree construction with filtering logic
-- Grid integration with auto-generated columns
-- API integration with Northwind backend
-- Dynamic column visibility based on return fields
-- Loading state handling
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-## Running the Sample
+## Branches
-```bash
-npm install
-npm start
+> **_NOTE:_** You should use [master](https://github.com/IgniteUI/igniteui-react-examples/tree/master) branch of this repository if you want to run samples on your computer. Use the [vnext](https://github.com/IgniteUI/igniteui-react-examples/tree/vnext) branch only when you want to contribute new samples to this repository.
+
+## Instructions
+
+Follow these instructions to run this example:
+
+
+```
+git clone https://github.com/IgniteUI/igniteui-react-examples.git
+git checkout master
+cd ./igniteui-react-examples
+cd ./samples/interactions/query-builder/overview
+```
+
+open above folder in VS Code or type:
+```
+code .
+```
+
+In terminal window, run:
+```
+npm install --legacy-peer-deps
+npm run-script start
```
-## API Integration
+Then open http://localhost:4200/ in your browser
-The sample connects to the Northwind Query Builder API:
-- Endpoint: `https://data-northwind.indigo.design/QueryBuilder/ExecuteQuery`
-- Method: POST
-- Body: Expression tree JSON
-## Components Used
+## Learn More
-- `IgcQueryBuilderComponent` - Main query builder component
-- `IgcGridComponent` - Data grid for displaying results
-- `IgcFilteringExpressionsTree` - Expression tree structure
+To learn more about **Ignite UI for React** components, check out the [React documentation](https://www.infragistics.com/products/ignite-ui-react/react/components/general-getting-started.html).
diff --git a/samples/interactions/query-builder/overview/package.json b/samples/interactions/query-builder/overview/package.json
index 6a9253739d..9d39178a3d 100644
--- a/samples/interactions/query-builder/overview/package.json
+++ b/samples/interactions/query-builder/overview/package.json
@@ -1,6 +1,6 @@
{
- "name": "example-ignite-ui-react",
- "description": "This project provides example of using Ignite UI for React components",
+ "name": "react-query-builder-overview",
+ "description": "This project provides example of Query Builder Overview using Ignite UI for React components",
"author": "Infragistics",
"version": "1.4.0",
"license": "",
diff --git a/samples/interactions/query-builder/overview/src/index.tsx b/samples/interactions/query-builder/overview/src/index.tsx
index fca6e4c9d9..4247ffd539 100644
--- a/samples/interactions/query-builder/overview/src/index.tsx
+++ b/samples/interactions/query-builder/overview/src/index.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useRef } from 'react';
+import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
@@ -39,39 +39,27 @@ interface Entity {
fields: Field[];
}
-const QueryBuilderOverview: React.FC = () => {
- const queryBuilderRef = useRef(null);
- const gridRef = useRef(null);
- const [expressionTree, setExpressionTree] = useState(null);
-
- // Define field structures
- const customersFields: Field[] = [
- { field: 'customerId', dataType: 'string' },
- { field: 'companyName', dataType: 'string' },
- { field: 'contactName', dataType: 'string' },
- { field: 'contactTitle', dataType: 'string' }
- ];
-
- const ordersFields: Field[] = [
- { field: 'orderId', dataType: 'number' },
- { field: 'customerId', dataType: 'string' },
- { field: 'employeeId', dataType: 'number' },
- { field: 'shipperId', dataType: 'number' },
- { field: 'orderDate', dataType: 'date' },
- { field: 'requiredDate', dataType: 'date' },
- { field: 'shipVia', dataType: 'string' },
- { field: 'freight', dataType: 'number' },
- { field: 'shipName', dataType: 'string' },
- { field: 'completed', dataType: 'boolean' }
- ];
-
- const entities: Entity[] = [
- { name: 'Customers', fields: customersFields },
- { name: 'Orders', fields: ordersFields }
- ];
-
- // Initialize expression tree
- useEffect(() => {
+interface SampleState {
+ expressionTree: IgcExpressionTree | null;
+}
+
+export default class Sample extends React.Component {
+ private queryBuilderRef: React.RefObject;
+ private gridRef: React.RefObject;
+
+ constructor(props: any) {
+ super(props);
+
+ this.queryBuilderRef = React.createRef();
+ this.gridRef = React.createRef();
+
+ this.state = {
+ expressionTree: null
+ };
+ }
+
+ componentDidMount() {
+ // Initialize expression tree
const tree = new IgcFilteringExpressionsTree();
tree.operator = FilteringLogic.And;
tree.entity = 'Orders';
@@ -88,46 +76,89 @@ const QueryBuilderOverview: React.FC = () => {
'completed'
];
- setExpressionTree(tree);
- }, []);
+ this.setState({ expressionTree: tree });
- // Set up query builder
- useEffect(() => {
- if (!queryBuilderRef.current || !expressionTree) return undefined;
+ // Set up query builder
+ if (this.queryBuilderRef.current && tree) {
+ const queryBuilder = this.queryBuilderRef.current;
+ queryBuilder.entities = this.entities as any;
+ queryBuilder.expressionTree = tree;
- const queryBuilder = queryBuilderRef.current;
- queryBuilder.entities = entities as any;
- queryBuilder.expressionTree = expressionTree;
+ queryBuilder.addEventListener('expressionTreeChange', this.handleExpressionTreeChange);
+ }
- const handleExpressionTreeChange = (event: CustomEvent) => {
- setExpressionTree(event.detail);
- };
+ // Set up grid
+ if (this.gridRef.current) {
+ const grid = this.gridRef.current;
+ grid.height = '420px';
+ grid.autoGenerate = true;
+ }
+ }
- queryBuilder.addEventListener('expressionTreeChange', handleExpressionTreeChange as EventListener);
+ componentDidUpdate(prevProps: any, prevState: any) {
+ // Fetch data when expression tree changes
+ if (prevState.expressionTree !== this.state.expressionTree && this.state.expressionTree) {
+ this.fetchData();
+ }
- return () => {
- queryBuilder.removeEventListener('expressionTreeChange', handleExpressionTreeChange as EventListener);
- };
- }, [expressionTree?.entity]); // Only re-run if entity changes
-
- // Set up grid
- useEffect(() => {
- if (!gridRef.current) return undefined;
-
- const grid = gridRef.current;
- grid.height = '420px';
- grid.autoGenerate = true;
- }, []);
-
- // Calculate which columns should be visible based on returnFields
- const calculateColumnsInView = () => {
- if (!gridRef.current || !expressionTree) return;
-
- const grid = gridRef.current;
+ // Update query builder if expression tree changed
+ if (this.queryBuilderRef.current && this.state.expressionTree &&
+ prevState.expressionTree !== this.state.expressionTree) {
+ const queryBuilder = this.queryBuilderRef.current;
+ queryBuilder.expressionTree = this.state.expressionTree;
+ }
+ }
+
+ componentWillUnmount() {
+ if (this.queryBuilderRef.current) {
+ this.queryBuilderRef.current.removeEventListener('expressionTreeChange', this.handleExpressionTreeChange);
+ }
+ }
+
+ private handleExpressionTreeChange = (event: CustomEvent) => {
+ this.setState({ expressionTree: event.detail });
+ };
+
+ private get customersFields(): Field[] {
+ return [
+ { field: 'customerId', dataType: 'string' },
+ { field: 'companyName', dataType: 'string' },
+ { field: 'contactName', dataType: 'string' },
+ { field: 'contactTitle', dataType: 'string' }
+ ];
+ }
+
+ private get ordersFields(): Field[] {
+ return [
+ { field: 'orderId', dataType: 'number' },
+ { field: 'customerId', dataType: 'string' },
+ { field: 'employeeId', dataType: 'number' },
+ { field: 'shipperId', dataType: 'number' },
+ { field: 'orderDate', dataType: 'date' },
+ { field: 'requiredDate', dataType: 'date' },
+ { field: 'shipVia', dataType: 'string' },
+ { field: 'freight', dataType: 'number' },
+ { field: 'shipName', dataType: 'string' },
+ { field: 'completed', dataType: 'boolean' }
+ ];
+ }
+
+ private get entities(): Entity[] {
+ return [
+ { name: 'Customers', fields: this.customersFields },
+ { name: 'Orders', fields: this.ordersFields }
+ ];
+ }
+
+ private calculateColumnsInView = () => {
+ if (!this.gridRef.current || !this.state.expressionTree) return;
+
+ const grid = this.gridRef.current;
+ const expressionTree = this.state.expressionTree;
const returnFields = expressionTree.returnFields ?? [];
if (returnFields.length === 0 || returnFields[0] === '*') {
- const selectedEntity = entities.find(e => e.name === expressionTree.entity);
+ const selectedEntity = this.entities.find(e => e.name === expressionTree.entity);
const selectedEntityFields = (selectedEntity?.fields ?? []).map(f => f.field);
grid.columns.forEach(column => {
@@ -140,58 +171,55 @@ const QueryBuilderOverview: React.FC = () => {
}
};
- // Fetch data when expression tree changes
- useEffect(() => {
- if (!expressionTree || !gridRef.current) return;
-
- const fetchData = async () => {
- const grid = gridRef.current;
- if (!grid) return;
-
- grid.isLoading = true;
-
- try {
- const response = await fetch(`${API_ENDPOINT}/QueryBuilder/ExecuteQuery`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(expressionTree)
- });
-
- if (!response.ok) {
- throw new Error(`ExecuteQuery failed: ${response.status} ${response.statusText}`);
- }
-
- const json = await response.json();
- const data = (Object.values(json)[0] as any[]) ?? [];
- grid.data = data;
-
- // Calculate column visibility after data loads
- await new Promise(resolve => requestAnimationFrame(() => resolve(null)));
- calculateColumnsInView();
- } catch (err) {
- console.error(err);
- grid.data = [];
- } finally {
- grid.isLoading = false;
+ private async fetchData() {
+ const grid = this.gridRef.current;
+ const expressionTree = this.state.expressionTree;
+
+ if (!grid || !expressionTree) return;
+
+ grid.isLoading = true;
+
+ try {
+ const response = await fetch(`${API_ENDPOINT}/QueryBuilder/ExecuteQuery`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(expressionTree)
+ });
+
+ if (!response.ok) {
+ throw new Error(`ExecuteQuery failed: ${response.status} ${response.statusText}`);
}
- };
- fetchData();
- }, [expressionTree]);
+ const json = await response.json();
+ const data = (Object.values(json)[0] as any[]) ?? [];
+ grid.data = data;
+
+ // Calculate column visibility after data loads
+ await new Promise(resolve => requestAnimationFrame(() => resolve(null)));
+ this.calculateColumnsInView();
+ } catch (err) {
+ console.error(err);
+ grid.data = [];
+ } finally {
+ grid.isLoading = false;
+ }
+ }
- return (
-
-
-
-
-
-
+ public render(): JSX.Element {
+ return (
+
-
- );
-};
+ );
+ }
+}
-// Rendering component in the React DOM
-const root = ReactDOM.createRoot(document.getElementById('root')!);
-root.render(
);
+// rendering above component in the React DOM
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render(
);
diff --git a/samples/interactions/query-builder/template/.devcontainer/devcontainer.json b/samples/interactions/query-builder/template/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..e0b8e9c925
--- /dev/null
+++ b/samples/interactions/query-builder/template/.devcontainer/devcontainer.json
@@ -0,0 +1,4 @@
+{
+ "name": "Node.js",
+ "image": "mcr.microsoft.com/devcontainers/javascript-node:22"
+}
\ No newline at end of file
diff --git a/samples/interactions/query-builder/template/README.md b/samples/interactions/query-builder/template/README.md
index 2a87b7e69a..b61472b1b1 100644
--- a/samples/interactions/query-builder/template/README.md
+++ b/samples/interactions/query-builder/template/README.md
@@ -1,49 +1,56 @@
-# Query Builder Template Sample
+
+
-This sample demonstrates the Query Builder component with custom search value templates.
+This folder contains implementation of React application with example of Custom Search Template feature using [Query Builder](https://www.infragistics.com/products/ignite-ui-react/react/components/general-getting-started.html) component.
-## Features
-- Query Builder with custom search value templates
-- **Region field**: Custom Select dropdown with predefined options
-- **OrderStatus field**: Radio button group for status selection
-- **Date fields**: Date picker component
-- **Time fields**: Time input with custom clock icon
-- **Default fields**: Standard input (text/number)
-- Expression tree JSON output display
-- Query Builder Header with custom title
-- Field formatters for display values
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-## Running the Sample
+## Branches
-```bash
-npm install
-npm start
+> **_NOTE:_** You should use [master](https://github.com/IgniteUI/igniteui-react-examples/tree/master) branch of this repository if you want to run samples on your computer. Use the [vnext](https://github.com/IgniteUI/igniteui-react-examples/tree/vnext) branch only when you want to contribute new samples to this repository.
+
+## Instructions
+
+Follow these instructions to run this example:
+
+
+```
+git clone https://github.com/IgniteUI/igniteui-react-examples.git
+git checkout master
+cd ./igniteui-react-examples
+cd ./samples/interactions/query-builder/template
```
-## Custom Templates
+open above folder in VS Code or type:
+```
+code .
+```
-The sample demonstrates the `searchValueTemplate` prop which allows customization of the search value input based on:
-- Field name
-- Data type
-- Condition type
+In terminal window, run:
+```
+npm install --legacy-peer-deps
+npm run-script start
+```
-### Template Examples
+Then open http://localhost:4200/ in your browser
-- **Region**: Dropdown with predefined region options (CNA, CEU, MED, etc.)
-- **OrderStatus**: Radio buttons for New, Shipped, Done
-- **Date fields**: Date picker for dates
-- **Time fields**: Time input with clock icon
-- **Boolean fields**: Automatically handled by Query Builder
-- **Other fields**: Standard text/number inputs
-## Components Used
+## Learn More
-- `IgcQueryBuilderComponent` - Main query builder component
-- `IgcQueryBuilderHeaderComponent` - Header with custom title
-- `IgcDatePickerComponent` - Date selection
-- `IgcDateTimeInputComponent` - Time selection
-- `IgcSelectComponent` - Dropdown for region
-- `IgcRadioGroupComponent` - Radio buttons for status
-- `IgcInputComponent` - Standard input fields
-- `IgcIconComponent` - Clock icon for time input
+To learn more about **Ignite UI for React** components, check out the [React documentation](https://www.infragistics.com/products/ignite-ui-react/react/components/general-getting-started.html).
diff --git a/samples/interactions/query-builder/template/package.json b/samples/interactions/query-builder/template/package.json
index 2991dec303..22bed77a06 100644
--- a/samples/interactions/query-builder/template/package.json
+++ b/samples/interactions/query-builder/template/package.json
@@ -1,6 +1,6 @@
{
- "name": "example-ignite-ui-react",
- "description": "This project provides example of using Ignite UI for React components",
+ "name": "react-query-builder-template",
+ "description": "This project provides example of Query Builder Template using Ignite UI for React components",
"author": "Infragistics",
"version": "1.4.0",
"license": "",
diff --git a/samples/interactions/query-builder/template/src/index.tsx b/samples/interactions/query-builder/template/src/index.tsx
index 8dd452423f..23f540d70c 100644
--- a/samples/interactions/query-builder/template/src/index.tsx
+++ b/samples/interactions/query-builder/template/src/index.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useRef, useCallback } from 'react';
+import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
@@ -81,12 +81,15 @@ interface QueryBuilderSearchValueContext {
defaultSearchValueTemplate?: any;
}
-const QueryBuilderTemplate: React.FC = () => {
- const queryBuilderRef = useRef
(null);
- const expressionOutputRef = useRef(null);
- const [expressionTree, setExpressionTree] = useState(null);
+interface SampleState {
+ expressionTree: IgcExpressionTree | null;
+}
+
+export default class Sample extends React.Component {
+ private queryBuilderRef: React.RefObject;
+ private expressionOutputRef: React.RefObject;
- const regionOptions: RegionOption[] = [
+ private regionOptions: RegionOption[] = [
{ text: 'Central North America', value: 'CNA' },
{ text: 'Central Europe', value: 'CEU' },
{ text: 'Mediterranean region', value: 'MED' },
@@ -98,69 +101,29 @@ const QueryBuilderTemplate: React.FC = () => {
{ text: 'Northern Australia', value: 'NAU' }
];
- const statusOptions: StatusOption[] = [
+ private statusOptions: StatusOption[] = [
{ text: 'New', value: 1 },
{ text: 'Shipped', value: 2 },
{ text: 'Done', value: 3 }
];
- // Register icon
- useEffect(() => {
+ constructor(props: any) {
+ super(props);
+
+ this.queryBuilderRef = React.createRef();
+ this.expressionOutputRef = React.createRef();
+
+ this.state = {
+ expressionTree: null
+ };
+ }
+
+ componentDidMount() {
+ // Register icon
const clockIcon = "";
registerIconFromText('clock', clockIcon, 'material');
- }, []);
-
- // Define fields with formatters
- const ordersFields: Field[] = [
- { field: 'CompanyID', dataType: 'string' },
- { field: 'OrderID', dataType: 'number' },
- { field: 'Freight', dataType: 'number' },
- { field: 'ShipCountry', dataType: 'string' },
- { field: 'IsRushOrder', dataType: 'boolean' },
- {
- field: 'RequiredTime',
- dataType: 'time',
- formatter: (value: any) => {
- if (!value || !(value instanceof Date)) return '';
- return value.toLocaleTimeString('en-US', {
- hour: '2-digit',
- minute: '2-digit'
- });
- }
- },
- {
- field: 'OrderDate',
- dataType: 'date',
- formatter: (value: any) => {
- if (!value || !(value instanceof Date)) return '';
- return value.toLocaleDateString('en-US', {
- month: 'short',
- day: 'numeric',
- year: 'numeric'
- });
- }
- },
- {
- field: 'Region',
- dataType: 'string',
- formatter: (value: any) => value?.text ?? value?.value ?? value
- },
- {
- field: 'OrderStatus',
- dataType: 'number',
- formatter: (value: number) => statusOptions.find(option => option.value === value)?.text ?? value
- }
- ];
- const entities: Entity[] = [
- {
- name: 'Orders',
- fields: ordersFields
- }
- ];
-
- // Initialize expression tree
- useEffect(() => {
+ // Initialize expression tree
const tree = new IgcFilteringExpressionsTree();
tree.operator = FilteringLogic.And;
tree.entity = 'Orders';
@@ -169,20 +132,106 @@ const QueryBuilderTemplate: React.FC = () => {
fieldName: 'Region',
condition: IgcStringFilteringOperand.instance().condition('equals'),
conditionName: 'equals',
- searchVal: regionOptions[0]
+ searchVal: this.regionOptions[0]
} as any);
tree.filteringOperands.push({
fieldName: 'OrderStatus',
condition: IgcStringFilteringOperand.instance().condition('equals'),
conditionName: 'equals',
- searchVal: statusOptions[0].value
+ searchVal: this.statusOptions[0].value
} as any);
- setExpressionTree(tree);
- }, []);
+ this.setState({ expressionTree: tree });
+
+ // Set up query builder
+ if (this.queryBuilderRef.current && tree) {
+ const queryBuilder = this.queryBuilderRef.current;
+ queryBuilder.entities = this.entities as any;
+ queryBuilder.expressionTree = tree;
+ queryBuilder.searchValueTemplate = this.buildSearchValueTemplate as any;
+
+ queryBuilder.addEventListener('expressionTreeChange', this.handleExpressionTreeChange);
+ }
+ }
+
+ componentDidUpdate(prevProps: any, prevState: any) {
+ // Update query builder if expression tree changed
+ if (this.queryBuilderRef.current && this.state.expressionTree &&
+ prevState.expressionTree !== this.state.expressionTree) {
+ const queryBuilder = this.queryBuilderRef.current;
+ queryBuilder.expressionTree = this.state.expressionTree;
+ }
+
+ // Render expression tree output
+ if (this.expressionOutputRef.current && this.state.expressionTree &&
+ prevState.expressionTree !== this.state.expressionTree) {
+ this.expressionOutputRef.current.textContent = JSON.stringify(this.state.expressionTree, null, 2);
+ }
+ }
- // Normalize time value
- const normalizeTimeValue = (value: unknown): Date | null => {
+ componentWillUnmount() {
+ if (this.queryBuilderRef.current) {
+ this.queryBuilderRef.current.removeEventListener('expressionTreeChange', this.handleExpressionTreeChange);
+ }
+ }
+
+ private handleExpressionTreeChange = (event: CustomEvent) => {
+ this.setState({ expressionTree: event.detail });
+ };
+
+ private get ordersFields(): Field[] {
+ return [
+ { field: 'CompanyID', dataType: 'string' },
+ { field: 'OrderID', dataType: 'number' },
+ { field: 'Freight', dataType: 'number' },
+ { field: 'ShipCountry', dataType: 'string' },
+ { field: 'IsRushOrder', dataType: 'boolean' },
+ {
+ field: 'RequiredTime',
+ dataType: 'time',
+ formatter: (value: any) => {
+ if (!value || !(value instanceof Date)) return '';
+ return value.toLocaleTimeString('en-US', {
+ hour: '2-digit',
+ minute: '2-digit'
+ });
+ }
+ },
+ {
+ field: 'OrderDate',
+ dataType: 'date',
+ formatter: (value: any) => {
+ if (!value || !(value instanceof Date)) return '';
+ return value.toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric'
+ });
+ }
+ },
+ {
+ field: 'Region',
+ dataType: 'string',
+ formatter: (value: any) => value?.text ?? value?.value ?? value
+ },
+ {
+ field: 'OrderStatus',
+ dataType: 'number',
+ formatter: (value: number) => this.statusOptions.find(option => option.value === value)?.text ?? value
+ }
+ ];
+ }
+
+ private get entities(): Entity[] {
+ return [
+ {
+ name: 'Orders',
+ fields: this.ordersFields
+ }
+ ];
+ }
+
+ private normalizeTimeValue = (value: unknown): Date | null => {
if (!value) return null;
if (value instanceof Date) return value;
@@ -200,8 +249,7 @@ const QueryBuilderTemplate: React.FC = () => {
return null;
};
- // Build search value template
- const buildSearchValueTemplate = useCallback((ctx: QueryBuilderSearchValueContext) => {
+ private buildSearchValueTemplate = (ctx: QueryBuilderSearchValueContext) => {
const field = ctx.selectedField?.field;
const condition = ctx.selectedCondition;
const matchesEqualityCondition = condition === 'equals' || condition === 'doesNotEqual';
@@ -211,26 +259,25 @@ const QueryBuilderTemplate: React.FC = () => {
}
if (field === 'Region' && matchesEqualityCondition) {
- return buildRegionSelect(ctx);
+ return this.buildRegionSelect(ctx);
}
if (field === 'OrderStatus' && matchesEqualityCondition) {
- return buildStatusRadios(ctx);
+ return this.buildStatusRadios(ctx);
}
if (ctx.selectedField?.dataType === 'date') {
- return buildDatePicker(ctx);
+ return this.buildDatePicker(ctx);
}
if (ctx.selectedField?.dataType === 'time') {
- return buildTimeInput(ctx);
+ return this.buildTimeInput(ctx);
}
- return buildDefaultInput(ctx, matchesEqualityCondition);
- }, []);
+ return this.buildDefaultInput(ctx, matchesEqualityCondition);
+ };
- // Build region select template
- const buildRegionSelect = (ctx: QueryBuilderSearchValueContext) => {
+ private buildRegionSelect = (ctx: QueryBuilderSearchValueContext) => {
const currentValue = ctx?.implicit?.value?.value ?? '';
return html`
@@ -243,17 +290,16 @@ const QueryBuilderTemplate: React.FC = () => {
if (!value || value === currentKey) return;
- ctx.implicit.value = regionOptions.find(option => option.value === value) ?? null;
+ ctx.implicit.value = this.regionOptions.find(option => option.value === value) ?? null;
}}>
- ${regionOptions.map(option => html`
+ ${this.regionOptions.map(option => html`
${option.text}
`)}
`;
};
- // Build status radios template
- const buildStatusRadios = (ctx: QueryBuilderSearchValueContext) => {
+ private buildStatusRadios = (ctx: QueryBuilderSearchValueContext) => {
const implicitValue = ctx.implicit?.value;
const currentValue = implicitValue === null ? '' : implicitValue.toString();
@@ -271,7 +317,7 @@ const QueryBuilderTemplate: React.FC = () => {
ctx.implicit.value = numericValue;
}}>
- ${statusOptions.map(option => html`
+ ${this.statusOptions.map(option => html`
{
`;
};
- // Build date picker template
- const buildDatePicker = (ctx: QueryBuilderSearchValueContext) => {
+ private buildDatePicker = (ctx: QueryBuilderSearchValueContext) => {
const implicitValue = ctx.implicit?.value;
const currentValue = implicitValue instanceof Date
? implicitValue
@@ -293,7 +338,7 @@ const QueryBuilderTemplate: React.FC = () => {
: null;
const allowedConditions = ['equals', 'doesNotEqual', 'before', 'after'];
- const isEnabled = allowedConditions.includes(ctx.selectedCondition ?? '');
+ const isEnabled = allowedConditions.indexOf(ctx.selectedCondition ?? '') !== -1;
return html`
{
`;
};
- // Build time input template
- const buildTimeInput = (ctx: QueryBuilderSearchValueContext) => {
- const currentValue = normalizeTimeValue(ctx.implicit?.value);
+ private buildTimeInput = (ctx: QueryBuilderSearchValueContext) => {
+ const currentValue = this.normalizeTimeValue(ctx.implicit?.value);
const allowedConditions = ['at', 'not_at', 'at_before', 'at_after', 'before', 'after'];
- const isDisabled = ctx.selectedField == null || !allowedConditions.includes(ctx.selectedCondition ?? '');
+ const isDisabled = ctx.selectedField == null || allowedConditions.indexOf(ctx.selectedCondition ?? '') === -1;
return html`
{
`;
};
- // Build default input template
- const buildDefaultInput = (ctx: QueryBuilderSearchValueContext, matchesEqualityCondition: boolean) => {
+ private buildDefaultInput = (ctx: QueryBuilderSearchValueContext, matchesEqualityCondition: boolean) => {
const selectedField = ctx.selectedField;
const dataType = selectedField?.dataType;
const isNumber = dataType === 'number';
@@ -344,7 +387,7 @@ const QueryBuilderTemplate: React.FC = () => {
const inputValue = currentValue == null ? '' : currentValue;
const disabledConditions = ['empty', 'notEmpty', 'null', 'notNull', 'inQuery', 'notInQuery'];
- const isDisabled = isBoolean || selectedField == null || disabledConditions.includes(ctx.selectedCondition ?? '');
+ const isDisabled = isBoolean || selectedField == null || disabledConditions.indexOf(ctx.selectedCondition ?? '') !== -1;
return html`
{
`;
};
- // Set up query builder
- useEffect(() => {
- if (!queryBuilderRef.current || !expressionTree) return undefined;
-
- const queryBuilder = queryBuilderRef.current;
- queryBuilder.entities = entities as any;
- queryBuilder.expressionTree = expressionTree;
- queryBuilder.searchValueTemplate = buildSearchValueTemplate as any;
-
- const handleExpressionTreeChange = (event: CustomEvent) => {
- setExpressionTree(event.detail);
- };
-
- queryBuilder.addEventListener('expressionTreeChange', handleExpressionTreeChange as EventListener);
-
- return () => {
- queryBuilder.removeEventListener('expressionTreeChange', handleExpressionTreeChange as EventListener);
- };
- }, [expressionTree?.entity, buildSearchValueTemplate]);
-
- // Render expression tree output
- useEffect(() => {
- if (expressionOutputRef.current && expressionTree) {
- expressionOutputRef.current.textContent = JSON.stringify(expressionTree, null, 2);
- }
- }, [expressionTree]);
-
- return (
-
-
-
-
-
-
-
-
+ public render(): JSX.Element {
+ return (
+
-
- );
-};
+ );
+ }
+}
-// Rendering component in the React DOM
-const root = ReactDOM.createRoot(document.getElementById('root')!);
-root.render(
);
+// rendering above component in the React DOM
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render(
);
From a15988169c326c4dd8875db9090d141290d21dd3 Mon Sep 17 00:00:00 2001
From: onlyexeption
Date: Mon, 2 Feb 2026 14:58:24 +0200
Subject: [PATCH 6/6] fix: use react grids instead of wc
---
.../query-builder/overview/package.json | 2 +-
.../query-builder/overview/src/index.tsx | 41 +--
.../query-builder/template/package.json | 3 +-
.../query-builder/template/src/index.tsx | 251 +++++++++---------
4 files changed, 147 insertions(+), 150 deletions(-)
diff --git a/samples/interactions/query-builder/overview/package.json b/samples/interactions/query-builder/overview/package.json
index 9d39178a3d..bd516b4cb2 100644
--- a/samples/interactions/query-builder/overview/package.json
+++ b/samples/interactions/query-builder/overview/package.json
@@ -16,7 +16,7 @@
"dependencies": {
"igniteui-react": "19.5.0-beta.2",
"igniteui-react-core": "19.3.1",
- "igniteui-webcomponents-grids": "6.3.0-alpha.2",
+ "igniteui-react-grids": "19.5.0-beta.2",
"lit-html": "^3.2.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
diff --git a/samples/interactions/query-builder/overview/src/index.tsx b/samples/interactions/query-builder/overview/src/index.tsx
index 4247ffd539..d1aed10fbb 100644
--- a/samples/interactions/query-builder/overview/src/index.tsx
+++ b/samples/interactions/query-builder/overview/src/index.tsx
@@ -1,30 +1,15 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
-
import {
- IgcQueryBuilderComponent,
- IgcGridComponent,
- IgcFilteringExpressionsTree,
- IgcExpressionTree,
+ IgrQueryBuilder,
+ IgrGrid,
+ IgrFilteringExpressionsTree,
+ IgrExpressionTree,
FilteringLogic
-} from 'igniteui-webcomponents-grids/grids';
-
-import 'igniteui-webcomponents-grids/grids/themes/light/material.css';
-
-// Register components
-IgcQueryBuilderComponent.register();
-IgcGridComponent.register();
+} from 'igniteui-react-grids';
-// Declare JSX types for custom elements
-declare global {
- namespace JSX {
- interface IntrinsicElements {
- 'igc-query-builder': any;
- 'igc-grid': any;
- }
- }
-}
+import 'igniteui-react-grids/grids/themes/light/material.css';
const API_ENDPOINT = 'https://data-northwind.indigo.design';
@@ -40,12 +25,12 @@ interface Entity {
}
interface SampleState {
- expressionTree: IgcExpressionTree | null;
+ expressionTree: IgrExpressionTree | null;
}
export default class Sample extends React.Component {
- private queryBuilderRef: React.RefObject;
- private gridRef: React.RefObject;
+ private queryBuilderRef: React.RefObject;
+ private gridRef: React.RefObject;
constructor(props: any) {
super(props);
@@ -60,7 +45,7 @@ export default class Sample extends React.Component {
componentDidMount() {
// Initialize expression tree
- const tree = new IgcFilteringExpressionsTree();
+ const tree = new IgrFilteringExpressionsTree();
tree.operator = FilteringLogic.And;
tree.entity = 'Orders';
tree.returnFields = [
@@ -115,7 +100,7 @@ export default class Sample extends React.Component {
}
}
- private handleExpressionTreeChange = (event: CustomEvent) => {
+ private handleExpressionTreeChange = (event: any) => {
this.setState({ expressionTree: event.detail });
};
@@ -209,10 +194,10 @@ export default class Sample extends React.Component {
return (
diff --git a/samples/interactions/query-builder/template/package.json b/samples/interactions/query-builder/template/package.json
index 22bed77a06..43f9546945 100644
--- a/samples/interactions/query-builder/template/package.json
+++ b/samples/interactions/query-builder/template/package.json
@@ -16,8 +16,7 @@
"dependencies": {
"igniteui-react": "19.5.0-beta.2",
"igniteui-react-core": "19.3.1",
- "igniteui-webcomponents": "^6.3.0",
- "igniteui-webcomponents-grids": "6.3.0-alpha.2",
+ "igniteui-react-grids": "19.5.0-beta.2",
"lit-html": "^3.2.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
diff --git a/samples/interactions/query-builder/template/src/index.tsx b/samples/interactions/query-builder/template/src/index.tsx
index 23f540d70c..ff3ba8dbd4 100644
--- a/samples/interactions/query-builder/template/src/index.tsx
+++ b/samples/interactions/query-builder/template/src/index.tsx
@@ -3,54 +3,45 @@ import ReactDOM from 'react-dom/client';
import './index.css';
import {
- IgcQueryBuilderComponent,
- IgcQueryBuilderHeaderComponent,
- IgcFilteringExpressionsTree,
- IgcExpressionTree,
+ IgrQueryBuilder,
+ IgrQueryBuilderModule,
+ IgrQueryBuilderHeader,
+ IgrFilteringExpressionsTree,
+ IgrExpressionTree,
FilteringLogic,
- IgcStringFilteringOperand
-} from 'igniteui-webcomponents-grids/grids';
+ IgrStringFilteringOperand
+} from 'igniteui-react-grids';
import {
- IgcDatePickerComponent,
- IgcDateTimeInputComponent,
- IgcSelectComponent,
- IgcSelectItemComponent,
- IgcRadioGroupComponent,
- IgcRadioComponent,
- IgcInputComponent,
- IgcIconComponent,
- defineComponents,
- registerIconFromText
-} from 'igniteui-webcomponents';
-
-import { html, render } from 'lit-html';
-
-import 'igniteui-webcomponents-grids/grids/themes/light/material.css';
+ IgrDatePicker,
+ IgrDatePickerModule,
+ IgrDateTimeInput,
+ IgrDateTimeInputModule,
+ IgrSelect,
+ IgrSelectModule,
+ IgrSelectItem,
+ IgrRadioGroup,
+ IgrRadioGroupModule,
+ IgrRadio,
+ IgrInput,
+ IgrInputModule,
+ IgrIcon,
+ IgrIconModule
+} from 'igniteui-react';
+
+import 'igniteui-react-grids/grids/themes/light/material.css';
// Register components
-IgcQueryBuilderComponent.register();
-IgcQueryBuilderHeaderComponent.register();
-defineComponents(
- IgcDatePickerComponent,
- IgcDateTimeInputComponent,
- IgcSelectComponent,
- IgcSelectItemComponent,
- IgcRadioGroupComponent,
- IgcRadioComponent,
- IgcInputComponent,
- IgcIconComponent
-);
-
-// Declare JSX types for custom elements
-declare global {
- namespace JSX {
- interface IntrinsicElements {
- 'igc-query-builder': any;
- 'igc-query-builder-header': any;
- }
- }
-}
+const mods: any[] = [
+ IgrQueryBuilderModule,
+ IgrDatePickerModule,
+ IgrDateTimeInputModule,
+ IgrSelectModule,
+ IgrRadioGroupModule,
+ IgrInputModule,
+ IgrIconModule
+];
+mods.forEach((m) => m.register());
// Types
interface Field {
@@ -82,11 +73,11 @@ interface QueryBuilderSearchValueContext {
}
interface SampleState {
- expressionTree: IgcExpressionTree | null;
+ expressionTree: IgrExpressionTree | null;
}
export default class Sample extends React.Component {
- private queryBuilderRef: React.RefObject;
+ private queryBuilderRef: React.RefObject;
private expressionOutputRef: React.RefObject;
private regionOptions: RegionOption[] = [
@@ -119,24 +110,20 @@ export default class Sample extends React.Component {
}
componentDidMount() {
- // Register icon
- const clockIcon = "";
- registerIconFromText('clock', clockIcon, 'material');
-
// Initialize expression tree
- const tree = new IgcFilteringExpressionsTree();
+ const tree = new IgrFilteringExpressionsTree();
tree.operator = FilteringLogic.And;
tree.entity = 'Orders';
tree.returnFields = ['*'];
tree.filteringOperands.push({
fieldName: 'Region',
- condition: IgcStringFilteringOperand.instance().condition('equals'),
+ condition: IgrStringFilteringOperand.instance().condition('equals'),
conditionName: 'equals',
searchVal: this.regionOptions[0]
} as any);
tree.filteringOperands.push({
fieldName: 'OrderStatus',
- condition: IgcStringFilteringOperand.instance().condition('equals'),
+ condition: IgrStringFilteringOperand.instance().condition('equals'),
conditionName: 'equals',
searchVal: this.statusOptions[0].value
} as any);
@@ -148,7 +135,6 @@ export default class Sample extends React.Component {
const queryBuilder = this.queryBuilderRef.current;
queryBuilder.entities = this.entities as any;
queryBuilder.expressionTree = tree;
- queryBuilder.searchValueTemplate = this.buildSearchValueTemplate as any;
queryBuilder.addEventListener('expressionTreeChange', this.handleExpressionTreeChange);
}
@@ -175,7 +161,7 @@ export default class Sample extends React.Component {
}
}
- private handleExpressionTreeChange = (event: CustomEvent) => {
+ private handleExpressionTreeChange = (event: any) => {
this.setState({ expressionTree: event.detail });
};
@@ -279,54 +265,65 @@ export default class Sample extends React.Component {
private buildRegionSelect = (ctx: QueryBuilderSearchValueContext) => {
const currentValue = ctx?.implicit?.value?.value ?? '';
+ const key = `region-select-${currentValue}`;
- return html`
- ) => {
- const value = event.detail?.value;
+ return (
+ {
+ const value = sender.value;
const currentKey = ctx?.implicit?.value?.value ?? '';
if (!value || value === currentKey) return;
- ctx.implicit.value = this.regionOptions.find(option => option.value === value) ?? null;
+ setTimeout(() => {
+ ctx.implicit.value = this.regionOptions.find(option => option.value === value) ?? null;
+ });
}}>
- ${this.regionOptions.map(option => html`
- ${option.text}
- `)}
-
- `;
+ {this.regionOptions.map(option => (
+
+ {option.text}
+
+ ))}
+
+ );
};
private buildStatusRadios = (ctx: QueryBuilderSearchValueContext) => {
const implicitValue = ctx.implicit?.value;
const currentValue = implicitValue === null ? '' : implicitValue.toString();
+ const key = `status-radio-${currentValue}`;
- return html`
- ) => {
- const value = event.detail?.value;
+ return (
+ {
+ const value = sender.value;
if (value === undefined) return;
const numericValue = Number(value);
if (ctx.implicit.value === numericValue) return;
- ctx.implicit.value = numericValue;
+ setTimeout(() => {
+ ctx.implicit.value = numericValue;
+ });
}}>
- ${this.statusOptions.map(option => html`
- (
+
- ${option.text}
-
- `)}
-
- `;
+ value={option.value.toString()}
+ checked={option.value.toString() === currentValue}
+ labelText={option.text}>
+
+ ))}
+
+ );
};
private buildDatePicker = (ctx: QueryBuilderSearchValueContext) => {
@@ -339,36 +336,45 @@ export default class Sample extends React.Component {
const allowedConditions = ['equals', 'doesNotEqual', 'before', 'after'];
const isEnabled = allowedConditions.indexOf(ctx.selectedCondition ?? '') !== -1;
+ const key = `date-picker-${currentValue}`;
- return html`
- (event.currentTarget as IgcDatePickerComponent).show()}
- @igcChange=${(event: CustomEvent) => {
- ctx.implicit.value = event.detail;
+ return (
+ sender.show()}
+ change={(sender: any) => {
+ setTimeout(() => {
+ ctx.implicit.value = sender.value;
+ });
}}>
-
- `;
+
+ );
};
private buildTimeInput = (ctx: QueryBuilderSearchValueContext) => {
const currentValue = this.normalizeTimeValue(ctx.implicit?.value);
const allowedConditions = ['at', 'not_at', 'at_before', 'at_after', 'before', 'after'];
const isDisabled = ctx.selectedField == null || allowedConditions.indexOf(ctx.selectedCondition ?? '') === -1;
+ const key = `time-input-${currentValue}`;
- return html`
- {
- const picker = event.currentTarget as IgcDateTimeInputComponent;
- ctx.implicit.value = picker.value;
+ return (
+ {
+ setTimeout(() => {
+ ctx.implicit.value = sender.value;
+ });
}}>
-
-
- `;
+
+
+
+
+ );
};
private buildDefaultInput = (ctx: QueryBuilderSearchValueContext, matchesEqualityCondition: boolean) => {
@@ -388,30 +394,37 @@ export default class Sample extends React.Component {
const inputValue = currentValue == null ? '' : currentValue;
const disabledConditions = ['empty', 'notEmpty', 'null', 'notNull', 'inQuery', 'notInQuery'];
const isDisabled = isBoolean || selectedField == null || disabledConditions.indexOf(ctx.selectedCondition ?? '') !== -1;
+ const key = `default-input-${inputValue}`;
- return html`
- {
- const target = event.target as HTMLInputElement;
- ctx.implicit.value = isNumber
- ? target.value === '' ? null : Number(target.value)
- : target.value;
+ return (
+ {
+ const value = sender.value;
+ setTimeout(() => {
+ ctx.implicit.value = isNumber
+ ? value === '' ? null : Number(value)
+ : value;
+ });
}}>
-
- `;
+
+ );
};
public render(): JSX.Element {
return (