{"_id":"@abaktiar/ql-input","_rev":"8-feaa9b4239101b77fcaa9e8029816350","name":"@abaktiar/ql-input","dist-tags":{"latest":"1.5.0"},"versions":{"1.0.0":{"name":"@abaktiar/ql-input","version":"1.0.0","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","syntax-highlighting","validation"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.0.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"dist":{"shasum":"98aa843d69830830745c2573da7c2549d5140958","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.0.0.tgz","fileCount":5,"integrity":"sha512-G18gm3a9BCJjrjOwkYNV1u0eHKW5BfwSSXFdFe7XW7Bvp9s5YFQ5RL1NLGEk3h4J5kZDjmtygZKeJMlH7ikMUw==","signatures":[{"sig":"MEUCIQCXCXzAckGcfUZ7b0+XwdJGsAXfgMzFFtn1CazKPYpPigIgOkv6SBmTjQx5n5EaLfiqzwWX7EQPcplYAnnNoY7buTo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":485572},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"710bcf124f562e87f3f53bbb972b2c070300ca1e","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete, syntax highlighting, and query validation. Built with TypeScript and shadcn/ui components.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","dependencies":{"clsx":"^2.1.1","cmdk":"^1.0.4","lucide-react":"^0.511.0","tailwind-merge":"^3.3.0","@radix-ui/react-slot":"^1.2.3","@radix-ui/react-popover":"^1.1.3","class-variance-authority":"^0.7.1"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.0.0_1748050467767_0.9208607859608351","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@abaktiar/ql-input","version":"1.0.1","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","syntax-highlighting","validation"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.0.1","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"13ff11ee0d9158cadc678c5542dd3d1d0a204587","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.0.1.tgz","fileCount":5,"integrity":"sha512-1gy4g88OqHUl/rnFwih3HJJneypbY47QRFRXp8jvaBCF58lMXXZMIPApVVw9ImMTAlKQpkVYWosuccITiyXing==","signatures":[{"sig":"MEQCIEioFQrI5HHA9TXDVmNwUK/R3j+69oJfjajX5M/90GfgAiBAWLtP7sWB19o7pkSomxFeAUWkGQgtioHfLxl0HyTOIg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":485771},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"710bcf124f562e87f3f53bbb972b2c070300ca1e","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete, syntax highlighting, and query validation. Built with TypeScript and shadcn/ui components.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","dependencies":{"clsx":"^2.1.1","cmdk":"^1.0.4","lucide-react":"^0.511.0","tailwind-merge":"^3.3.0","@radix-ui/react-slot":"^1.2.3","@radix-ui/react-popover":"^1.1.3","class-variance-authority":"^0.7.1"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.0.1_1748050714019_0.7859476025055523","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@abaktiar/ql-input","version":"1.1.0","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","syntax-highlighting","validation"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.1.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"c91c5895edddb88d004911e65f25be4bbb2a622b","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.1.0.tgz","fileCount":5,"integrity":"sha512-5QMK0o0ejUbDBQOqUCtwWJwsO6jNq6/xKIWzg9MFJb6xh1AX6w/i+UR8STStsbOvtD1r3Vp2m1z1287IRGMY5g==","signatures":[{"sig":"MEYCIQDImCg+dbl5rTAXB6/Owtoz7gcJp0X6DpzJmLT9xxwx1wIhAIT0q6FHK7QY9Y26M1JUhTNqaAABMdjZoUCs48IC2oQP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116605},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"d004549602573f5371c512e27427f9ae50fbd64f","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete, syntax highlighting, and query validation. Framework-independent with zero external dependencies.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","dependencies":{"clsx":"^2.1.1"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.1.0_1748053468591_0.7706009630973796","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@abaktiar/ql-input","version":"1.2.0","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","syntax-highlighting","validation"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.2.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"942c206bed5ecd3bc5523a65713fae0ee2bccc8d","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.2.0.tgz","fileCount":5,"integrity":"sha512-7Ejer706UvPLMkWeeGBBKM5zH81Kw2JUdfi1w8PnJlsD+a4VSjI0CAo6ye0/qLChLymgyD1kJ/kwxDPZOChHsg==","signatures":[{"sig":"MEYCIQDf6TG88WJsamUE2iGjxFVMOoeePcGr/RgOaTcAHEriYQIhAO7/O+smDYNsOF071fz+0rhVV0cxaueZZlhLt8ul0NYz","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118144},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"d004549602573f5371c512e27427f9ae50fbd64f","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete, syntax highlighting, and query validation. Framework-independent with zero external dependencies.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","dependencies":{"clsx":"^2.1.1"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.2.0_1748056972476_0.11184033310385488","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@abaktiar/ql-input","version":"1.3.0","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","validation"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.3.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"2c7865eb5669a0d95a43d44a061a2908e9e3e688","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.3.0.tgz","fileCount":5,"integrity":"sha512-vKCXHDDU5atSKtxfCsL1RwfK6NSvloPCL3mFlBmOvGOWfUtD4xymRxrdUNthprhDORizcaMsBsZJ0EeqJqoh+Q==","signatures":[{"sig":"MEQCIFQuNna8szf34vtDLwdVzVvmiWdkcLkzFVvQZUcNUcPhAiAhgrYBFGYDVnIYMEJSmBCOSQ7xFvF4/cgom72vAG+kkg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112243},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"3f464c32d99b415e3b1b3c69fb2c3a2e2f8bff23","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete and query validation. Framework-independent with zero external dependencies.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","dependencies":{"clsx":"^2.1.1"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.3.0_1748064059153_0.7779007889472414","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@abaktiar/ql-input","version":"1.3.1","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","validation"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.3.1","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"7cf8bcc77874bfd7de106fae42b6e8aac40955f0","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.3.1.tgz","fileCount":6,"integrity":"sha512-aAZcBF1PnwsDRSl0bCkx87nnkiT/GoFb8zDG7fVh2N6lRyaeRxFOgfc/vdZ/UuMCOwsEScCLfKWl0GbxhQG+bA==","signatures":[{"sig":"MEUCIQCGUvTptnMS6XSMBCQmPunJykcv9mecg/QlG7HbRDGIdgIgYThZBI6ogoCDk5lsZIJJLBT4vdAHdzsLSP4nN05aIV8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":121698},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"16992089ad1cda03c9fdb1255974315e25130a28","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete and query validation. Framework-independent with zero external dependencies.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.3.1_1748345854226_0.02794189795571511","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@abaktiar/ql-input","version":"1.4.0","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","parameterized-functions","validation","jql"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-input@1.4.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"d3a88b781b3f19b5fb6bc2a973a3b567a9844175","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.4.0.tgz","fileCount":6,"integrity":"sha512-VNDsHWEQvFmd4pVD1nOZy0YWD1kDCcBKp923NTbkzwWH3gB4bk/ntAX/jXbqU0EleTM++qZT+0ZJifxPQLG3gA==","signatures":[{"sig":"MEQCIA5sOyKixNsogHrTOgygZ9pVnX05It7cUyJaJNhW4SZeAiAp/VkaJ99dLi5CVX4mdFJFyg5CdkDMMwK5dp/CLwjvNQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":127849},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"},"./styles.css":"./styles.css"},"gitHead":"d55521804cdcb28d7666022f149cf4721e31ebee","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"React QL input component with intelligent autocomplete, parameterized functions, and query validation. Framework-independent with zero external dependencies.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ql-input_1.4.0_1748442494252_0.6792403964414628","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@abaktiar/ql-input","version":"1.5.0","description":"React QL input component with intelligent autocomplete, parameterized functions, and query validation. Framework-independent with zero external dependencies.","main":"./index.js","module":"./index.mjs","types":"./index.d.ts","exports":{".":{"import":"./index.mjs","require":"./index.js","types":"./index.d.ts"},"./styles.css":"./styles.css"},"keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","parameterized-functions","validation","jql"],"author":{"name":"abaktiar"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/abaktiar/ql-input.git"},"bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"homepage":"https://github.com/abaktiar/ql-input#readme","engines":{"node":">=16.0.0"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"sideEffects":["*.css"],"_id":"@abaktiar/ql-input@1.5.0","gitHead":"73b48921a26b488fd187edc4e7d8ec5abe90224f","_nodeVersion":"20.19.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-F/1IEiYtrGRwLDTsHyNZJUI2dDMyqPyWeVABy08Ew1PG1jmVmbtZAxDwT5HUcpJgmkYH120kCDwPSbuaoSR6YA==","shasum":"8d2a6a48ee8e0ff606b3fe85d1997e244944bfa0","tarball":"https://registry.npmjs.org/@abaktiar/ql-input/-/ql-input-1.5.0.tgz","fileCount":6,"unpackedSize":130598,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC/yh9WrxHYdx8QVw8iLEFX9SbFoKE0asNBFAjO2q4uPAiAML8aL1HF7MDpZWOgMztXdsOuIpPPnrHf149H1U6+BTw=="}]},"_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"directories":{},"maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ql-input_1.5.0_1749226092054_0.3732211717675369"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-24T01:34:27.652Z","modified":"2025-06-06T16:08:12.417Z","1.0.0":"2025-05-24T01:34:28.031Z","1.0.1":"2025-05-24T01:38:34.262Z","1.1.0":"2025-05-24T02:24:28.754Z","1.2.0":"2025-05-24T03:22:52.664Z","1.3.0":"2025-05-24T05:20:59.306Z","1.3.1":"2025-05-27T11:37:34.436Z","1.4.0":"2025-05-28T14:28:14.432Z","1.5.0":"2025-06-06T16:08:12.248Z"},"bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"author":{"name":"abaktiar"},"license":"MIT","homepage":"https://github.com/abaktiar/ql-input#readme","keywords":["react","query","input","autocomplete","typescript","shadcn","ui-component","query-builder","parameterized-functions","validation","jql"],"repository":{"type":"git","url":"git+https://github.com/abaktiar/ql-input.git"},"description":"React QL input component with intelligent autocomplete, parameterized functions, and query validation. Framework-independent with zero external dependencies.","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"readme":"# @abaktiar/ql-input\n\nA comprehensive React QL (Query Language) input component with intelligent autocomplete, query validation, and a beautiful UI built with TypeScript and shadcn/ui components.\n\n**🌐 [Live Demo](https://ql-input.netlify.app/)** - Try the component in action!\n\n[![npm version](https://badge.fury.io/js/@abaktiar%2Fql-input.svg)](https://badge.fury.io/js/@abaktiar%2Fql-input)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-18+-blue.svg)](https://reactjs.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## 🎉 What's New in v1.5.0\n\n✨ **Smart Suggestion Behavior** - Enhanced UX with manual control and `Ctrl+Space` shortcuts  \n🚀 **Smooth & Minimal Design** - Lightning-fast 80ms transitions with beautiful visual states  \n⌨️ **Enhanced Keyboard Navigation** - Auto-scroll to selection with seamless long-list navigation  \n🎯 **Perfect Accessibility** - Unified mouse and keyboard interactions with smooth scrolling  \n🔧 **Parameterized Functions** - Advanced function support with type validation and error handling\n\n## ✨ Features\n\n### Core Functionality\n- 🔍 **Context-aware autocomplete** - Smart suggestions based on query context\n- 🎨 **Visual feedback** - Query validation status and condition count\n- ⌨️ **Keyboard navigation** - Full keyboard support (↑↓ Enter Esc Tab)\n- 🔧 **Configurable fields** - Define custom fields, operators, and values\n- 📝 **Query parsing** - Complete QL query structure parsing\n- 🎯 **Parentheses grouping** - Support for complex condition grouping\n\n### Advanced Features\n- 🌐 **Async value suggestions** - Server-side value fetching with debouncing\n- 🔄 **Function support** - Built-in functions like `currentUser()`, `now()`, and parameterized functions like `daysAgo(30)`, `userInRole(\"admin\")`\n- 📊 **ORDER BY clauses** - Sorting with ASC/DESC support\n- 🌙 **Dark mode** - Full theming support\n- ♿ **Accessibility** - ARIA attributes for screen readers\n- 📱 **Responsive design** - Works across different screen sizes\n\n## 📦 Installation\n\n```bash\nnpm install @abaktiar/ql-input\n```\n\n```bash\nyarn add @abaktiar/ql-input\n```\n\n```bash\npnpm add @abaktiar/ql-input\n```\n\n### Peer Dependencies\n\nMake sure you have the required peer dependencies installed:\n\n```bash\nnpm install react react-dom\n```\n\n## 🚀 Quick Start\n\n### Basic Setup\n\n```tsx\nimport React from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\nimport '@abaktiar/ql-input/styles.css';\nimport type { QLInputConfig, QLQuery } from '@abaktiar/ql-input';\n\nconst config: QLInputConfig = {\n  fields: [\n    {\n      name: 'status',\n      displayName: 'Status',\n      type: 'option',\n      operators: ['=', '!=', 'IN', 'NOT IN'],\n      options: [\n        { value: 'open', label: 'Open' },\n        { value: 'closed', label: 'Closed' },\n        { value: 'pending', label: 'Pending' }\n      ]\n    },\n    {\n      name: 'assignee',\n      displayName: 'Assignee',\n      type: 'user',\n      operators: ['=', '!=', 'IS EMPTY', 'IS NOT EMPTY']\n    },\n    {\n      name: 'created',\n      displayName: 'Created Date',\n      type: 'date',\n      operators: ['=', '>', '<', '>=', '<='],\n      sortable: true\n    }\n  ],\n  maxSuggestions: 10,\n  caseSensitive: false,\n  allowParentheses: true,\n  allowOrderBy: true,\n  allowFunctions: true\n};\n\nfunction MyComponent() {\n  const handleChange = (value: string, query: QLQuery) => {\n    console.log('Query changed:', value);\n    console.log('Parsed query:', query);\n  };\n\n  const handleExecute = (query: QLQuery) => {\n    console.log('Query executed:', query);\n    // Handle query execution (e.g., API call)\n  };\n\n  return (\n    <QLInput\n      config={config}\n      placeholder=\"Enter your query...\"\n      onChange={handleChange}\n      onExecute={handleExecute}\n    />\n  );\n}\n```\n\n### Framework Independent\n\nThe component is completely framework-independent and doesn't require Tailwind CSS or any other CSS framework. Simply import the CSS file and you're ready to go:\n\n```css\n@import '@abaktiar/ql-input/styles.css';\n```\n\nThe component includes comprehensive styling with CSS custom properties for easy theming and dark mode support.\n\n## 🎯 Component Props\n\n### QLInput Props\n\n```typescript\ninterface QLInputProps {\n  // Configuration\n  config: QLInputConfig;\n\n  // Value control\n  value?: string;\n  onChange?: (value: string, query: QLQuery) => void;\n  onExecute?: (query: QLQuery) => void;\n\n  // Appearance\n  placeholder?: string;\n  disabled?: boolean;\n  className?: string;\n  showSearchIcon?: boolean;  // Default: true\n  showClearIcon?: boolean;   // Default: true\n\n  // Async suggestions\n  getAsyncValueSuggestions?: (field: string, typedValue: string) => Promise<QLValue[]>;\n  getPredefinedValueSuggestions?: (field: string) => QLValue[];\n}\n```\n\n### Configuration Options\n\n```typescript\ninterface QLInputConfig {\n  fields: QLField[];\n  maxSuggestions?: number;\n  caseSensitive?: boolean;\n  allowParentheses?: boolean;\n  allowOrderBy?: boolean;\n  allowFunctions?: boolean;\n  functions?: QLFunction[];\n}\n```\n\n## 💡 Usage Examples\n\n### Controlled Component\n\n```tsx\nimport React, { useState } from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nfunction ControlledExample() {\n  const [query, setQuery] = useState('status = \"open\"');\n\n  return (\n    <QLInput\n      config={config}\n      value={query}\n      onChange={(value) => setQuery(value)}\n      placeholder=\"Search issues...\"\n    />\n  );\n}\n```\n\n### With Async Value Suggestions\n\n```tsx\nimport React from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nfunction AsyncExample() {\n  const getAsyncValueSuggestions = async (field: string, typedValue: string) => {\n    if (field === 'assignee') {\n      // Fetch users from API\n      const response = await fetch(`/api/users?search=${typedValue}`);\n      const users = await response.json();\n      return users.map(user => ({\n        value: user.id,\n        label: user.name\n      }));\n    }\n    return [];\n  };\n\n  return (\n    <QLInput\n      config={config}\n      getAsyncValueSuggestions={getAsyncValueSuggestions}\n      placeholder=\"Search with async suggestions...\"\n    />\n  );\n}\n```\n\n### With Custom Functions\n\n```tsx\nimport React from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nconst configWithFunctions: QLInputConfig = {\n  fields: [\n    // ... your fields\n  ],\n  allowFunctions: true,\n  functions: [\n    {\n      name: 'currentUser',\n      displayName: 'currentUser()',\n      description: 'The currently logged-in user',\n    },\n    {\n      name: 'daysAgo',\n      displayName: 'daysAgo(days)',\n      description: 'Date N days ago from today',\n      parameters: [{\n        name: 'days',\n        type: 'number',\n        required: true,\n        description: 'Number of days'\n      }]\n    },\n    {\n      name: 'userInRole',\n      displayName: 'userInRole(role)',\n      description: 'Users with specific role',\n      parameters: [{\n        name: 'role',\n        type: 'text',\n        required: true,\n        description: 'User role name'\n      }]\n    },\n    {\n      name: 'dateRange',\n      displayName: 'dateRange(start, end)',\n      description: 'Date range between two dates',\n      parameters: [\n        {\n          name: 'startDate',\n          type: 'date',\n          required: true,\n          description: 'Start date'\n        },\n        {\n          name: 'endDate',\n          type: 'date',\n          required: true,\n          description: 'End date'\n        }\n      ]\n    }\n  ]\n};\n\nfunction CustomFunctionsExample() {\n  return (\n    <QLInput\n      config={configWithFunctions}\n      placeholder=\"Try: assignee = userInRole(&quot;admin&quot;) AND created >= daysAgo(30)\"\n    />\n  );\n}\n```\n\n## 🎯 Query Examples\n\nThe component supports powerful QL queries with parameterized functions:\n\n### Basic Function Queries\n```sql\n-- User functions\nassignee = currentUser()\nassignee = userInRole(\"admin\")\nassignee IN (currentUser(), userInRole(\"manager\"))\n\n-- Date functions\ncreated >= daysAgo(30)\nupdated <= daysFromNow(7)\ncreated = dateRange(\"2023-01-01\", \"2023-12-31\")\n\n-- Project functions\nproject = projectsWithPrefix(\"PROJ\")\n```\n\n### Complex Expressions\n```sql\n-- Combined conditions with functions\nassignee = currentUser() AND created >= daysAgo(30)\n\n-- Functions in IN lists\nassignee IN (currentUser(), userInRole(\"admin\")) AND priority = High\n\n-- Complex grouping with functions\n(created >= daysAgo(30) AND assignee = currentUser()) OR priority = Highest\n\n-- Multiple function parameters\ncreated = dateRange(\"2023-01-01\", daysAgo(90)) AND status = Open\n```\n\n### Real-World Use Cases\n```sql\n-- Find my recent work\nassignee = currentUser() AND updated >= daysAgo(7)\n\n-- Admin oversight\nassignee = userInRole(\"admin\") AND status = \"In Progress\"\n\n-- Project timeline queries\nproject = projectsWithPrefix(\"PROJ\") AND created >= dateRange(\"2023-01-01\", \"2023-12-31\")\n\n-- Team management\nassignee IN (userInRole(\"developer\"), userInRole(\"qa\")) AND priority >= High\n```\n\n### Form Integration\n\n```tsx\nimport React from 'react';\nimport { useForm } from 'react-hook-form';\nimport { QLInput } from '@abaktiar/ql-input';\n\ninterface FormData {\n  query: string;\n  // ... other fields\n}\n\nfunction FormExample() {\n  const { register, handleSubmit, setValue, watch } = useForm<FormData>();\n  const queryValue = watch('query');\n\n  const onSubmit = (data: FormData) => {\n    console.log('Form submitted:', data);\n  };\n\n  return (\n    <form onSubmit={handleSubmit(onSubmit)}>\n      <QLInput\n        config={config}\n        value={queryValue}\n        onChange={(value) => setValue('query', value)}\n        placeholder=\"Enter search query...\"\n      />\n      <button type=\"submit\">Search</button>\n    </form>\n  );\n}\n```\n\n### Dark Mode Support\n\n```tsx\nimport React from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nfunction DarkModeExample() {\n  return (\n    <div className=\"dark\"> {/* or use ql-dark, or data-theme=\"dark\" */}\n      <QLInput\n        config={config}\n        placeholder=\"Dark mode supported automatically...\"\n      />\n    </div>\n  );\n}\n```\n\nThe component automatically detects dark mode using these selectors:\n- `.dark` (Tailwind CSS convention)\n- `.ql-dark` (component-specific)\n- `[data-theme=\"dark\"]` (data attribute approach)\n\n## 🎨 Styling & Customization\n\n### CSS Custom Properties\n\nThe component uses CSS custom properties for comprehensive theming:\n\n```css\n:root {\n  /* Colors */\n  --ql-input-border: #e2e8f0;\n  --ql-input-background: #ffffff;\n  --ql-input-foreground: #1a202c;\n  --ql-input-muted: #f7fafc;\n  --ql-input-muted-foreground: #718096;\n  --ql-input-ring: #3182ce;\n  --ql-input-destructive: #e53e3e;\n  --ql-input-success: #38a169;\n  --ql-input-warning: #d69e2e;\n\n  /* Spacing and sizing */\n  --ql-input-radius: 0.375rem;\n  --ql-input-spacing-sm: 0.5rem;\n  --ql-input-spacing-md: 0.75rem;\n\n  /* Typography */\n  --ql-input-font-size-sm: 0.875rem;\n  --ql-input-line-height: 1.5;\n\n  /* Transitions */\n  --ql-input-transition: all 0.2s ease-in-out;\n}\n\n/* Dark theme */\n.dark .ql-input-container,\n.ql-dark,\n[data-theme=\"dark\"] .ql-input-container {\n  --ql-input-border: #4a5568;\n  --ql-input-background: #2d3748;\n  --ql-input-foreground: #f7fafc;\n  --ql-input-muted: #4a5568;\n  --ql-input-muted-foreground: #a0aec0;\n  --ql-input-ring: #63b3ed;\n  --ql-input-destructive: #fc8181;\n  --ql-input-success: #68d391;\n  --ql-input-warning: #f6e05e;\n}\n```\n\n### Custom Styling\n\nYou can customize the component by overriding CSS custom properties:\n\n```css\n/* Custom theme */\n.my-custom-theme {\n  --ql-input-border: #3b82f6;\n  --ql-input-ring: #1d4ed8;\n  --ql-input-background: #f8fafc;\n  --ql-input-radius: 0.75rem;\n}\n```\n\n```tsx\nimport React from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nfunction StyledExample() {\n  return (\n    <div className=\"my-custom-theme\">\n      <QLInput\n        config={config}\n        placeholder=\"Custom styled input...\"\n      />\n    </div>\n  );\n}\n```\n\n## 🔧 Advanced Usage\n\n### Using the Hook Directly\n\n```tsx\nimport React from 'react';\nimport { useQLInput } from '@abaktiar/ql-input';\n\nfunction CustomInputComponent() {\n  const { state, handleInputChange, handleKeyDown, selectSuggestion } = useQLInput({\n    config,\n    onChange: (value, query) => console.log(value, query)\n  });\n\n  return (\n    <div>\n      <input\n        value={state.value}\n        onChange={handleInputChange}\n        onKeyDown={handleKeyDown}\n      />\n      {state.showSuggestions && (\n        <div>\n          {state.suggestions.map((suggestion, index) => (\n            <div\n              key={index}\n              onClick={() => selectSuggestion(suggestion)}\n              className={index === state.selectedSuggestionIndex ? 'selected' : ''}\n            >\n              {suggestion.label}\n            </div>\n          ))}\n        </div>\n      )}\n    </div>\n  );\n}\n```\n\n### Custom Suggestion Rendering\n\n```tsx\nimport React from 'react';\nimport { QLInput, QLSuggestion } from '@abaktiar/ql-input';\n\nfunction CustomSuggestionExample() {\n  const renderSuggestion = (suggestion: QLSuggestion) => (\n    <div className=\"flex items-center gap-2\">\n      <span className=\"font-medium\">{suggestion.label}</span>\n      {suggestion.description && (\n        <span className=\"text-sm text-gray-500\">{suggestion.description}</span>\n      )}\n    </div>\n  );\n\n  // Note: This is a conceptual example - actual implementation may vary\n  return (\n    <QLInput\n      config={config}\n      placeholder=\"Custom suggestions...\"\n    />\n  );\n}\n```\n\n## 🧪 Testing\n\n### Testing with React Testing Library\n\n```tsx\nimport React from 'react';\nimport { render, screen, fireEvent } from '@testing-library/react';\nimport { QLInput } from '@abaktiar/ql-input';\n\ntest('renders QL input component', () => {\n  render(<QLInput config={config} placeholder=\"Test input\" />);\n\n  const input = screen.getByPlaceholderText('Test input');\n  expect(input).toBeInTheDocument();\n});\n\ntest('handles input changes', () => {\n  const handleChange = jest.fn();\n\n  render(\n    <QLInput\n      config={config}\n      onChange={handleChange}\n      placeholder=\"Test input\"\n    />\n  );\n\n  const input = screen.getByPlaceholderText('Test input');\n  fireEvent.change(input, { target: { value: 'status = \"open\"' } });\n\n  expect(handleChange).toHaveBeenCalled();\n});\n```\n\n## 🤝 Related Packages\n\n- **[@abaktiar/ql-parser](https://www.npmjs.com/package/@abaktiar/ql-parser)** - The underlying parser (included as dependency)\n\n## 📄 License\n\nMIT © [abaktiar](https://github.com/abaktiar)\n\n## 🎯 Field Types & Operators\n\n### Supported Field Types\n\n```typescript\ntype FieldType = 'text' | 'number' | 'date' | 'datetime' | 'boolean' | 'option' | 'multiselect' | 'user';\n```\n\n#### Text Fields\n```typescript\n{\n  name: 'title',\n  displayName: 'Title',\n  type: 'text',\n  operators: ['=', '!=', '~', '!~', 'IS EMPTY', 'IS NOT EMPTY']\n}\n```\n\n#### Number Fields\n```typescript\n{\n  name: 'priority',\n  displayName: 'Priority',\n  type: 'number',\n  operators: ['=', '!=', '>', '<', '>=', '<=']\n}\n```\n\n#### Date/DateTime Fields\n```typescript\n{\n  name: 'created',\n  displayName: 'Created Date',\n  type: 'date', // or 'datetime'\n  operators: ['=', '!=', '>', '<', '>=', '<='],\n  sortable: true\n}\n```\n\n#### Option Fields\n```typescript\n{\n  name: 'status',\n  displayName: 'Status',\n  type: 'option',\n  operators: ['=', '!=', 'IN', 'NOT IN'],\n  options: [\n    { value: 'open', label: 'Open' },\n    { value: 'closed', label: 'Closed' }\n  ]\n}\n```\n\n#### Boolean Fields\n```typescript\n{\n  name: 'isPublic',\n  displayName: 'Is Public',\n  type: 'boolean',\n  operators: ['=', '!=']\n}\n```\n\n#### User Fields\n```typescript\n{\n  name: 'assignee',\n  displayName: 'Assignee',\n  type: 'user',\n  operators: ['=', '!=', 'IS EMPTY', 'IS NOT EMPTY'],\n  asyncValueSuggestions: true\n}\n```\n\n### Complete Configuration Example\n\n```typescript\nimport { QLInputConfig } from '@abaktiar/ql-input';\n\nconst fullConfig: QLInputConfig = {\n  fields: [\n    {\n      name: 'title',\n      displayName: 'Title',\n      type: 'text',\n      operators: ['=', '!=', '~', '!~', 'IS EMPTY', 'IS NOT EMPTY'],\n      description: 'Issue title or summary'\n    },\n    {\n      name: 'status',\n      displayName: 'Status',\n      type: 'option',\n      operators: ['=', '!=', 'IN', 'NOT IN'],\n      options: [\n        { value: 'open', label: 'Open' },\n        { value: 'in-progress', label: 'In Progress' },\n        { value: 'closed', label: 'Closed' },\n        { value: 'pending', label: 'Pending Review' }\n      ]\n    },\n    {\n      name: 'priority',\n      displayName: 'Priority',\n      type: 'number',\n      operators: ['=', '!=', '>', '<', '>=', '<='],\n      sortable: true,\n      options: [\n        { value: '1', label: 'Low' },\n        { value: '2', label: 'Medium' },\n        { value: '3', label: 'High' },\n        { value: '4', label: 'Critical' }\n      ]\n    },\n    {\n      name: 'assignee',\n      displayName: 'Assignee',\n      type: 'user',\n      operators: ['=', '!=', 'IS EMPTY', 'IS NOT EMPTY'],\n      asyncValueSuggestions: true\n    },\n    {\n      name: 'created',\n      displayName: 'Created Date',\n      type: 'date',\n      operators: ['=', '!=', '>', '<', '>=', '<='],\n      sortable: true\n    },\n    {\n      name: 'tags',\n      displayName: 'Tags',\n      type: 'multiselect',\n      operators: ['IN', 'NOT IN'],\n      options: [\n        { value: 'bug', label: 'Bug' },\n        { value: 'feature', label: 'Feature' },\n        { value: 'enhancement', label: 'Enhancement' }\n      ]\n    }\n  ],\n  maxSuggestions: 15,\n  caseSensitive: false,\n  allowParentheses: true,\n  allowOrderBy: true,\n  allowFunctions: true,\n  functions: [\n    {\n      name: 'currentUser',\n      displayName: 'currentUser()',\n      description: 'The currently logged-in user',\n    },\n    {\n      name: 'now',\n      displayName: 'now()',\n      description: 'Current date and time',\n    },\n    {\n      name: 'today',\n      displayName: 'today()',\n      description: 'Today\\'s date',\n    },\n    {\n      name: 'daysAgo',\n      displayName: 'daysAgo(days)',\n      description: 'Date N days ago from today',\n      parameters: [{\n        name: 'days',\n        type: 'number',\n        required: true,\n        description: 'Number of days'\n      }]\n    },\n    {\n      name: 'userInRole',\n      displayName: 'userInRole(role)',\n      description: 'Users with specific role',\n      parameters: [{\n        name: 'role',\n        type: 'text',\n        required: true,\n        description: 'User role name'\n      }]\n    }\n  ]\n};\n```\n\n## 🚀 Real-World Examples\n\n### Issue Tracking System\n\n```tsx\nimport React, { useState } from 'react';\nimport { QLInput, QLQuery } from '@abaktiar/ql-input';\n\nfunction IssueTracker() {\n  const [issues, setIssues] = useState([]);\n  const [loading, setLoading] = useState(false);\n\n  const handleSearch = async (query: QLQuery) => {\n    if (!query.valid) return;\n\n    setLoading(true);\n    try {\n      const response = await fetch('/api/issues/search', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ query: query.raw })\n      });\n      const data = await response.json();\n      setIssues(data.issues);\n    } catch (error) {\n      console.error('Search failed:', error);\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  const getUsers = async (field: string, search: string) => {\n    if (field !== 'assignee') return [];\n\n    const response = await fetch(`/api/users?search=${search}`);\n    const users = await response.json();\n    return users.map(user => ({\n      value: user.id,\n      label: `${user.name} (${user.email})`\n    }));\n  };\n\n  return (\n    <div>\n      <QLInput\n        config={issueConfig}\n        placeholder='Search issues... e.g., status = \"open\" AND assignee = currentUser()'\n        onExecute={handleSearch}\n        getAsyncValueSuggestions={getUsers}\n      />\n\n      {loading && <div>Searching...</div>}\n\n      <div>\n        {issues.map(issue => (\n          <div key={issue.id} className=\"issue-card\">\n            <h3>{issue.title}</h3>\n            <p>Status: {issue.status}</p>\n            <p>Assignee: {issue.assignee}</p>\n          </div>\n        ))}\n      </div>\n    </div>\n  );\n}\n```\n\n### E-commerce Product Search\n\n```tsx\nimport React from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nconst productConfig = {\n  fields: [\n    {\n      name: 'name',\n      displayName: 'Product Name',\n      type: 'text',\n      operators: ['~', '!~', 'IS EMPTY', 'IS NOT EMPTY']\n    },\n    {\n      name: 'category',\n      displayName: 'Category',\n      type: 'option',\n      operators: ['=', '!=', 'IN', 'NOT IN'],\n      options: [\n        { value: 'electronics', label: 'Electronics' },\n        { value: 'clothing', label: 'Clothing' },\n        { value: 'books', label: 'Books' }\n      ]\n    },\n    {\n      name: 'price',\n      displayName: 'Price',\n      type: 'number',\n      operators: ['=', '>', '<', '>=', '<='],\n      sortable: true\n    },\n    {\n      name: 'inStock',\n      displayName: 'In Stock',\n      type: 'boolean',\n      operators: ['=', '!=']\n    }\n  ],\n  allowOrderBy: true,\n  allowParentheses: true\n};\n\nfunction ProductSearch() {\n  const handleProductSearch = (value: string, query: QLQuery) => {\n    console.log('Searching products:', query);\n    // Implement product search logic\n  };\n\n  return (\n    <QLInput\n      config={productConfig}\n      placeholder='Search products... e.g., category = \"electronics\" AND price < 500 ORDER BY price ASC'\n      onChange={handleProductSearch}\n    />\n  );\n}\n```\n\n## 🎨 Icon Customization\n\n### Icon Visibility Control\n\nControl which icons are displayed in the input:\n\n```tsx\n// Hide search icon for minimal design\n<QLInput\n  config={config}\n  showSearchIcon={false}\n  placeholder=\"Enter query...\"\n/>\n\n// Hide clear icon to prevent accidental clearing\n<QLInput\n  config={config}\n  showClearIcon={false}\n  placeholder=\"Enter query...\"\n/>\n\n// Hide both icons for ultra-minimal design\n<QLInput\n  config={config}\n  showSearchIcon={false}\n  showClearIcon={false}\n  placeholder=\"Enter query...\"\n/>\n\n// Default behavior (both icons shown)\n<QLInput\n  config={config}\n  showSearchIcon={true}  // Default\n  showClearIcon={true}   // Default\n  placeholder=\"Enter query...\"\n/>\n```\n\n### Use Cases for Icon Control\n\n- **Minimal Design**: Hide search icon when the context is clear\n- **Prevent Accidental Clearing**: Hide clear icon in critical forms\n- **Mobile Optimization**: Reduce visual clutter on small screens\n- **Custom Branding**: Match your application's design system\n\n## 🎨 Theming Examples\n\n### Custom Theme\n\n```css\n/* Custom theme variables */\n.my-custom-theme {\n  --ql-input-border: #e2e8f0;\n  --ql-input-background: #ffffff;\n  --ql-input-foreground: #1a202c;\n  --ql-input-muted: #f7fafc;\n  --ql-input-muted-foreground: #718096;\n  --ql-input-ring: #3182ce;\n}\n\n.my-custom-theme .ql-input {\n  border-radius: 12px;\n  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n}\n\n.my-custom-theme .ql-suggestion-item {\n  padding: 12px;\n  border-radius: 8px;\n}\n\n.my-custom-theme .ql-suggestion-item:hover {\n  background-color: #ebf8ff;\n}\n```\n\n### Material Design Theme\n\n```css\n.material-theme {\n  --ql-input-border: #e0e0e0;\n  --ql-input-background: #ffffff;\n  --ql-input-foreground: #212121;\n  --ql-input-muted: #f5f5f5;\n  --ql-input-muted-foreground: #757575;\n  --ql-input-ring: #2196f3;\n}\n\n.material-theme .ql-input {\n  border-radius: 4px;\n  border-bottom: 2px solid var(--ql-input-ring);\n  border-top: none;\n  border-left: none;\n  border-right: none;\n  background: transparent;\n}\n```\n\n## 🔧 Performance Optimization\n\n### Debounced Async Suggestions\n\n```tsx\nimport React, { useMemo } from 'react';\nimport { QLInput, useDebounce } from '@abaktiar/ql-input';\n\nfunction OptimizedComponent() {\n  const debouncedGetSuggestions = useMemo(\n    () => useDebounce(async (field: string, search: string) => {\n      // Expensive API call\n      const response = await fetch(`/api/suggestions/${field}?q=${search}`);\n      return response.json();\n    }, 300),\n    []\n  );\n\n  return (\n    <QLInput\n      config={config}\n      getAsyncValueSuggestions={debouncedGetSuggestions}\n    />\n  );\n}\n```\n\n### Memoized Configuration\n\n```tsx\nimport React, { useMemo } from 'react';\nimport { QLInput } from '@abaktiar/ql-input';\n\nfunction MemoizedConfig({ fields, options }) {\n  const config = useMemo(() => ({\n    fields: fields.map(field => ({\n      ...field,\n      options: options[field.name] || []\n    })),\n    maxSuggestions: 10,\n    allowParentheses: true,\n    allowOrderBy: true\n  }), [fields, options]);\n\n  return <QLInput config={config} />;\n}\n```\n\n## 🧪 Testing Examples\n\n### Complete Test Suite\n\n```tsx\nimport React from 'react';\nimport { render, screen, fireEvent, waitFor } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { QLInput } from '@abaktiar/ql-input';\n\nconst testConfig = {\n  fields: [\n    {\n      name: 'status',\n      displayName: 'Status',\n      type: 'option',\n      operators: ['=', '!='],\n      options: [\n        { value: 'open', label: 'Open' },\n        { value: 'closed', label: 'Closed' }\n      ]\n    }\n  ]\n};\n\ndescribe('QLInput Component', () => {\n  test('shows suggestions when typing', async () => {\n    render(<QLInput config={testConfig} />);\n\n    const input = screen.getByRole('textbox');\n    await userEvent.type(input, 'sta');\n\n    await waitFor(() => {\n      expect(screen.getByText('Status')).toBeInTheDocument();\n    });\n  });\n\n  test('executes query on Enter', async () => {\n    const handleExecute = jest.fn();\n    render(<QLInput config={testConfig} onExecute={handleExecute} />);\n\n    const input = screen.getByRole('textbox');\n    await userEvent.type(input, 'status = \"open\"');\n    await userEvent.keyboard('{Enter}');\n\n    expect(handleExecute).toHaveBeenCalledWith(\n      expect.objectContaining({\n        raw: 'status = \"open\"',\n        valid: true\n      })\n    );\n  });\n\n  test('handles async suggestions', async () => {\n    const getAsyncSuggestions = jest.fn().mockResolvedValue([\n      { value: 'user1', label: 'User 1' }\n    ]);\n\n    render(\n      <QLInput\n        config={testConfig}\n        getAsyncValueSuggestions={getAsyncSuggestions}\n      />\n    );\n\n    const input = screen.getByRole('textbox');\n    await userEvent.type(input, 'assignee = \"u');\n\n    await waitFor(() => {\n      expect(getAsyncSuggestions).toHaveBeenCalledWith('assignee', 'u');\n    });\n  });\n});\n```\n\n## 🐛 Issues & Support\n\nPlease report issues on [GitHub Issues](https://github.com/abaktiar/ql-input/issues).\n","readmeFilename":"README.md"}