UNPKG

@abaktiar/ql-input

Version:

React QL input component with intelligent autocomplete, parameterized functions, and query validation. Framework-independent with zero external dependencies.

3 lines (2 loc) 27.2 kB
"use strict";var e=Object.defineProperty,t=(t,n,s)=>((t,n,s)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s)(t,"symbol"!=typeof n?n+"":n,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),s=require("react");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const r=i(s);class o{constructor(){t(this,"tokens",[]),t(this,"position",0)}parse(e){if(this.tokens=e.filter((e=>"whitespace"!==e.type)),this.position=0,0===this.tokens.length)return null;return this.tokens.some((e=>"keyword"!==e.type&&"whitespace"!==e.type))?this.parseExpression():null}parseExpression(){return this.parseOrExpression()}parseOrExpression(){var e,t;let n=this.parseAndExpression();for(;"logical"===(null==(e=this.current())?void 0:e.type)&&"OR"===(null==(t=this.current())?void 0:t.value);){this.advance();const e=this.parseAndExpression();this.isLogicalGroup(n)&&"OR"===n.operator?n.conditions.push(e):n={operator:"OR",conditions:[n,e]}}return n}parseAndExpression(){var e,t;let n=this.parsePrimaryExpression();for(;"logical"===(null==(e=this.current())?void 0:e.type)&&"AND"===(null==(t=this.current())?void 0:t.value);){this.advance();const e=this.parsePrimaryExpression();this.isLogicalGroup(n)&&"AND"===n.operator?n.conditions.push(e):n={operator:"AND",conditions:[n,e]}}return n}parsePrimaryExpression(){var e,t;const n=this.current();if(!n)throw new Error("Unexpected end of input");if("logical"===n.type&&"NOT"===n.value){this.advance();const e=this.parsePrimaryExpression();return{...e,not:!0}}if("parenthesis"===n.type&&"("===n.value){this.advance();const n=this.parseExpression();if("parenthesis"!==(null==(e=this.current())?void 0:e.type)||")"!==(null==(t=this.current())?void 0:t.value))throw new Error("Expected closing parenthesis");return this.advance(),n}if("field"===n.type)return this.parseCondition();throw new Error(`Unexpected token: ${n.type} "${n.value}"`)}parseCondition(){const e=this.current();if(!e||"field"!==e.type)throw new Error("Expected field name");const t={field:e.value};this.advance();const n=this.current();if(!n||"operator"!==n.type)throw new Error("Expected operator");return t.operator=n.value,this.advance(),this.operatorRequiresValue(t.operator)&&(t.value=this.parseValue(t.operator)),t}parseValue(e){if("IN"===e||"NOT IN"===e)return this.parseInList();const t=this.current();if(!t)throw new Error("Expected value");if("value"===t.type||"field"===t.type||"function"===t.type||"unknown"===t.type){let e=t.value;const n=this.tokens[this.position+1];return n&&"parenthesis"===n.type&&"("===n.value?this.parseFunctionCall(e):((e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))&&(e=e.slice(1,-1)),this.advance(),e)}throw new Error(`Expected value, got ${t.type} "${t.value}"`)}parseFunctionCall(e){var t,n,s,i,r;this.advance(),this.advance();const o=[];for(;this.current()&&("parenthesis"!==(null==(t=this.current())?void 0:t.type)||")"!==(null==(n=this.current())?void 0:n.value));){const e=this.current();if("value"!==(null==e?void 0:e.type)&&"field"!==(null==e?void 0:e.type)&&"function"!==(null==e?void 0:e.type)&&"unknown"!==(null==e?void 0:e.type))throw new Error(`Unexpected token in function parameters: ${null==e?void 0:e.type} "${null==e?void 0:e.value}"`);{let t=e.value;const n=this.tokens[this.position+1];n&&"parenthesis"===n.type&&"("===n.value?t=this.parseFunctionCall(t):((t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1)),this.advance()),o.push(t),"comma"===(null==(s=this.current())?void 0:s.type)&&this.advance()}}if("parenthesis"!==(null==(i=this.current())?void 0:i.type)||")"!==(null==(r=this.current())?void 0:r.value))throw new Error("Expected closing parenthesis for function call");return this.advance(),0===o.length?`${e}()`:`${e}(${o.join(", ")})`}parseInList(){var e,t,n,s,i,r,o;if("parenthesis"!==(null==(e=this.current())?void 0:e.type)||"("!==(null==(t=this.current())?void 0:t.value))throw new Error("Expected opening parenthesis for IN list");this.advance();const a=[];for(;this.current()&&("parenthesis"!==(null==(n=this.current())?void 0:n.type)||")"!==(null==(s=this.current())?void 0:s.value));){const e=this.current();if("value"!==(null==e?void 0:e.type)&&"field"!==(null==e?void 0:e.type)&&"function"!==(null==e?void 0:e.type)&&"unknown"!==(null==e?void 0:e.type))throw new Error(`Unexpected token in IN list: ${null==e?void 0:e.type} "${null==e?void 0:e.value}"`);{let t=e.value;const n=this.tokens[this.position+1];n&&"parenthesis"===n.type&&"("===n.value?t=this.parseFunctionCall(t):((t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&(t=t.slice(1,-1)),this.advance()),a.push(t),"comma"===(null==(i=this.current())?void 0:i.type)&&this.advance()}}if("parenthesis"!==(null==(r=this.current())?void 0:r.type)||")"!==(null==(o=this.current())?void 0:o.value))throw new Error("Expected closing parenthesis for IN list");return this.advance(),a}operatorRequiresValue(e){return!["IS EMPTY","IS NOT EMPTY"].includes(e)}current(){return this.tokens[this.position]}advance(){this.position++}isLogicalGroup(e){return"operator"in e&&"conditions"in e}}const a=["AND","OR","NOT"],l=["=","!=",">","<",">=","<=","~","!~","IN","NOT IN","IS EMPTY","IS NOT EMPTY"],u=["ORDER","BY","ASC","DESC"];class c{constructor(e){}tokenize(e){const t=[];let n=0;for(;n<e.length;){const s=e[n],i=e.slice(n);if(/\s/.test(s)){const s=n;for(;n<e.length&&/\s/.test(e[n]);)n++;t.push({type:"whitespace",value:e.slice(s,n),start:s,end:n});continue}let r=!1;if('"'===s||"'"===s){const i=s,r=n;for(n++;n<e.length&&e[n]!==i;)"\\"===e[n]?n+=2:n++;n<e.length&&n++,t.push({type:"value",value:e.slice(r,n),start:r,end:n});continue}if("("===s||")"===s){t.push({type:"parenthesis",value:s,start:n,end:n+1}),n++;continue}if(","===s){t.push({type:"comma",value:s,start:n,end:n+1}),n++;continue}if(["=","!",">","<","~"].includes(s)){const i=n;let r=s;if(n+1<e.length){const t=e[n+1];("!"===s&&"="===t||">"===s&&"="===t||"<"===s&&"="===t||"!"===s&&"~"===t)&&(r+=t,n++)}t.push({type:"operator",value:r,start:i,end:n+1}),n++;continue}for(const e of l.sort(((e,t)=>t.length-e.length)))if(i.toUpperCase().startsWith(e)){const s=i[e.length];if(!s||/\s/.test(s)||"("===s||")"===s){t.push({type:"operator",value:e,start:n,end:n+e.length}),n+=e.length,r=!0;break}}if(r)continue;for(const e of a)if(i.toUpperCase().startsWith(e)){const s=i[e.length];if(!s||/\s/.test(s)||"("===s||")"===s){t.push({type:"logical",value:e,start:n,end:n+e.length}),n+=e.length,r=!0;break}}if(r)continue;for(const e of u)if(i.toUpperCase().startsWith(e)){const s=i[e.length];if(!s||/\s/.test(s)||"("===s||")"===s){t.push({type:"keyword",value:e,start:n,end:n+e.length}),n+=e.length,r=!0;break}}if(r)continue;const o=n;for(;n<e.length&&!/\s/.test(e[n])&&"("!==e[n]&&")"!==e[n]&&","!==e[n]&&'"'!==e[n]&&"'"!==e[n];)n++;if(n>o){const s=e.slice(o,n);t.push({type:"unknown",value:s,start:o,end:n})}else n++}return this.classifyTokens(t)}classifyTokens(e){const t={expectingField:!0,expectingOperator:!1,expectingValue:!1,expectingLogical:!1,parenthesesLevel:0,inOrderBy:!1};for(let n=0;n<e.length;n++){const s=e[n];"whitespace"!==s.type&&("unknown"===s.type&&(t.expectingField?(s.type="field",t.expectingField=!1,t.expectingOperator=!0):t.expectingValue?(s.type="value",t.expectingValue=!1,t.expectingLogical=!0):s.type="field"),"field"===s.type?(t.expectingOperator=!0,t.expectingField=!1,t.expectingValue=!1,t.expectingLogical=!1):"operator"===s.type?(t.expectingValue=!0,t.expectingField=!1,t.expectingOperator=!1,t.expectingLogical=!1):"value"===s.type?(t.expectingLogical=!0,t.expectingField=!1,t.expectingOperator=!1,t.expectingValue=!1):"logical"===s.type?(t.expectingField=!0,t.expectingOperator=!1,t.expectingValue=!1,t.expectingLogical=!1):"parenthesis"===s.type?"("===s.value?(t.parenthesesLevel++,t.expectingField=!0,t.expectingOperator=!1,t.expectingValue=!1,t.expectingLogical=!1):(t.parenthesesLevel--,t.expectingLogical=!0,t.expectingField=!1,t.expectingOperator=!1,t.expectingValue=!1):"keyword"===s.type&&("ORDER"===s.value.toUpperCase()?(t.inOrderBy=!0,t.expectingField=!1,t.expectingOperator=!1,t.expectingValue=!1,t.expectingLogical=!1):"BY"===s.value.toUpperCase()&&(t.expectingField=!0,t.expectingOperator=!1,t.expectingValue=!1,t.expectingLogical=!1)))}return e}parse(e){const t=[];let n,s=[];try{const{whereClause:t,orderByClause:i}=this.splitQuery(e);if(t.trim()){const e=this.tokenize(t),s=new o;n=s.parse(e)||void 0}i.trim()&&(s=this.parseOrderBy(i))}catch(i){t.push(i instanceof Error?i.message:"Parse error")}return{where:n||void 0,orderBy:s,raw:e,valid:0===t.length,errors:t}}splitQuery(e){const t=e.match(/\s*ORDER\s+BY\s+/i);if(!t)return{whereClause:e,orderByClause:""};const n=t.index+t[0].length;return{whereClause:e.substring(0,t.index),orderByClause:e.substring(n)}}parseOrderBy(e){const t=[],n=e.split(",").map((e=>e.trim()));for(const s of n){const e=s.trim().split(/\s+/);if(0===e.length||!e[0])continue;const n=e[0],i=e.length>1&&"DESC"===e[1].toUpperCase()?"DESC":"ASC";t.push({field:n,direction:i})}return t}}function p(e){return"field"in e&&"operator"in e}function g(e){return"operator"in e&&"conditions"in e}function d(e){return p(e)?function(e){const{field:t,operator:n,value:s}=e;switch(n){case"=":return{[t]:s};case"!=":return{[t]:{$ne:s}};case">":return{[t]:{$gt:s}};case"<":return{[t]:{$lt:s}};case">=":return{[t]:{$gte:s}};case"<=":return{[t]:{$lte:s}};case"IN":return{[t]:{$in:Array.isArray(s)?s:[s]}};case"NOT IN":return{[t]:{$nin:Array.isArray(s)?s:[s]}};case"~":return{[t]:{$regex:s,$options:"i"}};case"!~":return{[t]:{$not:{$regex:s,$options:"i"}}};case"IS EMPTY":return{$or:[{[t]:null},{[t]:{$exists:!1}}]};case"IS NOT EMPTY":return{[t]:{$ne:null,$exists:!0}};default:return{[t]:s}}}(e):g(e)?function(e){const t=e.conditions.map(d);if("AND"===e.operator)return{$and:t};if("OR"===e.operator)return{$or:t};return{}}(e):{}}function h(e){return p(e)?function(e){const{field:t,operator:n,value:s}=e;switch(n){case"=":default:return`${t} = '${s}'`;case"!=":return`${t} != '${s}'`;case">":return`${t} > '${s}'`;case"<":return`${t} < '${s}'`;case">=":return`${t} >= '${s}'`;case"<=":return`${t} <= '${s}'`;case"IN":return`${t} IN (${(Array.isArray(s)?s:[s]).map((e=>`'${e}'`)).join(", ")})`;case"NOT IN":return`${t} NOT IN (${(Array.isArray(s)?s:[s]).map((e=>`'${e}'`)).join(", ")})`;case"~":return`${t} LIKE '%${s}%'`;case"!~":return`${t} NOT LIKE '%${s}%'`;case"IS EMPTY":return`${t} IS NULL`;case"IS NOT EMPTY":return`${t} IS NOT NULL`}}(e):g(e)?function(e){const t=e.conditions.map(h),n=e.operator;if(1===t.length)return t[0];return`(${t.join(` ${n} `)})`}(e):""}function v(...e){return e.filter(Boolean).join(" ")}class f{constructor(e){t(this,"config"),this.config=e}getSuggestions(e){const t=[],{partialInput:n=""}=e;e.expectingField?(t.push(...this.getFieldSuggestions()),this.config.allowFunctions&&t.push(...this.getFunctionSuggestions())):e.expectingOperator&&e.lastField?t.push(...this.getOperatorSuggestions(e.lastField)):e.expectingValue&&e.lastField?e.inInList?t.push(...this.getInListValueSuggestions(e.lastField)):t.push(...this.getValueSuggestions(e.lastField)):e.expectingLogical?t.push(...this.getLogicalOperatorSuggestions()):e.inOrderBy&&(e.expectingField?t.push(...this.getSortableFieldSuggestions()):t.push(...this.getSortDirectionSuggestions())),this.config.allowParentheses&&(e.expectingField||e.expectingLogical)&&t.push({type:"parenthesis",value:"(",displayValue:"(",description:"Group conditions",insertText:"("}),e.inInList&&t.push({type:"comma",value:",",displayValue:",",description:"Add another value",insertText:", "});const s=this.filterSuggestions(t,n),i=this.config.maxSuggestions||10;return s.slice(0,i)}getFieldSuggestions(){return this.config.fields.map((e=>({type:"field",value:e.name,displayValue:e.displayName||e.name,description:e.description,category:"Fields"})))}getOperatorSuggestions(e){const t=this.config.fields.find((t=>t.name===e));return t?t.operators.map((e=>{const t="IN"===e||"NOT IN"===e?`${e} (`:e;return{type:"operator",value:e,displayValue:e,description:this.getOperatorDescription(e),insertText:t,category:"Operators"}})):[]}getValueSuggestions(e){const t=this.config.fields.find((t=>t.name===e));if(!t)return[];const n=[];return t.options&&n.push(...t.options.map((e=>{const t=/\s/.test(e.value)||/[,()"]/.test(e.value),n=t?`"${e.value}"`:e.value;return{type:"value",value:e.value,displayValue:e.displayValue||e.value,description:e.description,category:"Values",insertText:t?n:void 0}}))),"boolean"===t.type&&n.push({type:"value",value:"true",displayValue:"true",category:"Values"},{type:"value",value:"false",displayValue:"false",category:"Values"}),this.config.allowFunctions&&n.push(...this.getFunctionSuggestions()),n}getOperatorDescription(e){return{"=":"Equals","!=":"Not equals",">":"Greater than","<":"Less than",">=":"Greater than or equal","<=":"Less than or equal","~":"Contains","!~":"Does not contain",IN:"In list","NOT IN":"Not in list","IS EMPTY":"Is empty","IS NOT EMPTY":"Is not empty"}[e]||e}getLogicalOperatorSuggestions(){return(this.config.logicalOperators||["AND","OR","NOT"]).map((e=>({type:"logical",value:e,displayValue:e,description:this.getLogicalOperatorDescription(e),category:"Logical"})))}getSortableFieldSuggestions(){return this.config.fields.filter((e=>!1!==e.sortable)).map((e=>({type:"field",value:e.name,displayValue:e.displayName||e.name,description:e.description,category:"Sortable Fields"})))}getSortDirectionSuggestions(){return["ASC","DESC"].map((e=>({type:"keyword",value:e,displayValue:e,description:"ASC"===e?"Ascending":"Descending",category:"Sort Direction"})))}getFunctionSuggestions(){return this.config.functions?this.config.functions.map((e=>{var t;let n,s;if(e.parameters&&e.parameters.length>0){const i=e.parameters.map((e=>{let t;switch(e.type){case"text":t=e.required?`"${e.name}"`:`"${e.name}?"`;break;case"number":default:t=e.required?e.name:`${e.name}?`;break;case"date":case"datetime":t=e.required?'"YYYY-MM-DD"':'"YYYY-MM-DD?"'}return t}));n=`${e.name}(${i.join(", ")})`,s=e.displayName||`${e.name}(${(null==(t=e.parameters)?void 0:t.map((e=>e.name)).join(", "))||""})`}else n=`${e.name}()`,s=e.displayName||`${e.name}()`;return{type:"function",value:e.name,displayValue:s,description:e.description,insertText:n,category:"Functions"}})):[]}getInListValueSuggestions(e){const t=this.config.fields.find((t=>t.name===e));if(!t)return[];const n=[];return t.options&&n.push(...t.options.map((e=>{const t=/\s/.test(e.value)||/[,()"]/.test(e.value)?`"${e.value}"`:e.value;return{type:"value",value:e.value,displayValue:e.displayValue||e.value,description:e.description,category:"Values",insertText:`${t}, `}}))),this.config.allowFunctions&&this.config.functions&&n.push(...this.config.functions.map((e=>({type:"function",value:e.name,displayValue:e.displayName||e.name,description:e.description,category:"Functions",insertText:`${e.name}(), `})))),n}getLogicalOperatorDescription(e){return{AND:"Both conditions must be true",OR:"Either condition can be true",NOT:"Negates the condition"}[e]||e}filterSuggestions(e,t){if(!t.trim())return e;const n=this.config.caseSensitive?t:t.toLowerCase();return e.filter((e=>{const t=this.config.caseSensitive?e.value:e.value.toLowerCase(),s=this.config.caseSensitive?e.displayValue||e.value:(e.displayValue||e.value).toLowerCase();return t.includes(n)||s.includes(n)}))}getSuggestionContext(e,t,n){const s={input:e,cursorPosition:t,tokens:n,expectingField:!0,expectingOperator:!1,expectingValue:!1,expectingLogical:!1,inOrderBy:!1,parenthesesLevel:0,inInList:!1};let i=-1;for(let f=0;f<n.length;f++){const e=n[f];if(e.start<=t&&t<=e.end){i=f;break}if(e.start>t){i=f-1;break}}-1===i&&n.length>0&&(i=n.length-1),i>=0&&(s.currentToken=n[i],s.previousToken=i>0?n[i-1]:void 0,s.nextToken=i<n.length-1?n[i+1]:void 0);let r,o,a,l=!0,u=!1,c=!1,p=!1,g=!1,d=0,h=!1;for(let f=0;f<=i;f++){const e=n[f];if("whitespace"!==e.type)if("keyword"===e.type&&"ORDER"===e.value.toUpperCase())g=!0,l=!1,u=!1,c=!1,p=!1;else if("keyword"===e.type&&"BY"===e.value.toUpperCase())l=!0,u=!1,c=!1,p=!1;else if("field"===e.type)h||(r=e.value,a=e.value),g?(l=!1,u=!1,c=!1,p=!1):h||(l=!1,u=!0,c=!1,p=!1);else if("operator"===e.type){if(o=e.value,l=!1,u=!1,c=!0,p=!1,"IN"===e.value||"NOT IN"===e.value)for(let t=f+1;t<n.length;t++){const e=n[t];if("whitespace"!==e.type){"parenthesis"===e.type&&"("===e.value&&(h=!0);break}}}else"value"===e.type?(l=!1,u=!1,c=!1,p=!0):"logical"===e.type?(l=!0,u=!1,c=!1,p=!1):"parenthesis"===e.type?"("===e.value?(d++,h||(l=!0,u=!1,c=!1,p=!1)):")"===e.value&&(d--,h&&0===d?(h=!1,l=!1,u=!1,c=!1,p=!0):(l=!1,u=!1,c=!1,p=!0)):"comma"===e.type&&h&&(l=!1,u=!1,c=!0,p=!1)}let v="";if(s.currentToken&&"whitespace"!==s.currentToken.type){const n=s.currentToken.start,i=s.currentToken.end;t>=n&&t<=i?(v=e.slice(n,t),"parenthesis"!==s.currentToken.type&&"comma"!==s.currentToken.type||(v="")):(v=s.currentToken.value,"parenthesis"!==s.currentToken.type&&"comma"!==s.currentToken.type||(v=""))}else{const n=e.slice(0,t).match(/(\w+)$/);n&&(v=n[1])}if(s.currentToken&&"whitespace"!==s.currentToken.type&&v){t>=s.currentToken.start&&t<=s.currentToken.end&&("field"===s.currentToken.type||"unknown"===s.currentToken.type?h?(l=!1,u=!1,c=!0,p=!1):(l=!0,u=!1,c=!1,p=!1):"operator"===s.currentToken.type?(l=!1,u=!0,c=!1,p=!1):"value"===s.currentToken.type?(l=!1,u=!1,c=!0,p=!1):"logical"===s.currentToken.type?(l=!1,u=!1,c=!1,p=!0):"function"===s.currentToken.type&&(l=!1,u=!1,c=!0,p=!1))}return s.expectingField=l,s.expectingOperator=u,s.expectingValue=c,s.expectingLogical=p,s.inOrderBy=g,s.parenthesesLevel=d,s.inInList=h,s.lastField=h&&a?a:r,s.lastOperator=o,s.partialInput=v,s}}function y({config:e,initialValue:t="",onChange:n,onExecute:i,getAsyncValueSuggestions:r,getPredefinedValueSuggestions:o}){const[a,l]=s.useState({value:t,tokens:[],suggestions:[],showSuggestions:!1,selectedSuggestionIndex:0,cursorPosition:0,query:{raw:t,valid:!0,errors:[]},validationErrors:[],isLoading:!1,justSelectedSuggestion:!1}),u=s.useRef(new c(e)),p=s.useRef(new f(e)),g=s.useCallback((e=>{const t=u.current.tokenize(e),s=u.current.parse(e);l((e=>({...e,tokens:t,query:s}))),null==n||n(e,s)}),[n]),d=s.useCallback((async(t,n)=>{const s=u.current.tokenize(t),i=p.current.getSuggestionContext(t,n,s);let a=p.current.getSuggestions(i);if(i.expectingValue&&i.lastField&&r){const t=e.fields.find((e=>e.name===i.lastField));if((null==t?void 0:t.asyncValueSuggestions)&&i.partialInput){l((e=>({...e,isLoading:!0})));try{const e=(await r(i.lastField,i.partialInput)).map((e=>({type:"value",value:e.value,displayValue:e.displayValue||e.value,description:e.description,insertText:e.value.includes(" ")?`"${e.value}"`:e.value,category:"Dynamic Values"})));a=[...e,...a]}catch(c){console.error("Failed to fetch async suggestions:",c)}finally{l((e=>({...e,isLoading:!1})))}}}if(i.expectingValue&&i.lastField&&o){const e=o(i.lastField).map((e=>({type:"value",value:e.value,displayValue:e.displayValue||e.value,description:e.description,insertText:e.value.includes(" ")?`"${e.value}"`:e.value,category:"Predefined Values"})));a=[...e,...a]}l((e=>({...e,suggestions:a,selectedSuggestionIndex:0,showSuggestions:a.length>0})))}),[e.fields,r,o]),h=s.useCallback(((e,t)=>{const n=a,s=n.value,i=e.length>s.length?e[e.length-1]:"",r=!n.justSelectedSuggestion||" "===i;l((n=>({...n,value:e,cursorPosition:t,justSelectedSuggestion:n.justSelectedSuggestion&&" "!==i}))),g(e),r?d(e,t):l((e=>({...e,showSuggestions:!1,suggestions:[],selectedSuggestionIndex:0})))}),[a,g,d]),v=s.useCallback((e=>{const{value:t,cursorPosition:n,tokens:s}=a,i=s.find((e=>n>=e.start&&n<=e.end));let r,o;if(i&&"whitespace"!==i.type){if(!("parenthesis"===i.type&&"("===i.value||"comma"===i.type)||"value"!==e.type&&"function"!==e.type){const n=t.slice(0,i.start),s=t.slice(i.end),a=e.insertText||e.value;r=n+a+s,o=i.start+a.length}else{const n=t.slice(0,i.end),s=t.slice(i.end),a=e.insertText||e.value;r=n+a+s,o=i.end+a.length}}else{const s=t.slice(0,n),i=t.slice(n),a=e.insertText||e.value;r=s+a+i,o=n+a.length}l((e=>({...e,value:r,cursorPosition:o,showSuggestions:!1,selectedSuggestionIndex:0,justSelectedSuggestion:!0}))),g(r)}),[a,g]),y=s.useCallback((e=>{if(e.ctrlKey&&" "===e.key)return e.preventDefault(),l((e=>({...e,justSelectedSuggestion:!1}))),void d(a.value,a.cursorPosition);if(!a.showSuggestions)return"Enter"===e.key?void(null==i||i(a.query)):void 0;switch(e.key){case"ArrowDown":e.preventDefault(),l((e=>({...e,selectedSuggestionIndex:Math.min(e.selectedSuggestionIndex+1,e.suggestions.length-1)})));break;case"ArrowUp":e.preventDefault(),l((e=>({...e,selectedSuggestionIndex:Math.max(e.selectedSuggestionIndex-1,0)})));break;case"Enter":case"Tab":e.preventDefault(),a.suggestions[a.selectedSuggestionIndex]&&v(a.suggestions[a.selectedSuggestionIndex]);break;case"Escape":e.preventDefault(),l((e=>({...e,showSuggestions:!1,selectedSuggestionIndex:0})))}}),[a.showSuggestions,a.suggestions,a.selectedSuggestionIndex,a.query,a.value,a.cursorPosition,i,v,d]),x=s.useCallback((()=>{l((e=>({...e,showSuggestions:!1,selectedSuggestionIndex:0})))}),[]);return{state:a,handleInputChange:h,handleKeyDown:y,selectSuggestion:v,hideSuggestions:x}}const x=({className:e="",size:t=16})=>n.jsxs("svg",{className:`ql-icon-search ${e}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[n.jsx("circle",{cx:"11",cy:"11",r:"8"}),n.jsx("path",{d:"m21 21-4.35-4.35"})]}),m=({className:e="",size:t=16})=>n.jsxs("svg",{className:`ql-icon-x ${e}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:[n.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),n.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),S=({className:e="",size:t=16})=>n.jsx("svg",{className:`ql-icon-loader ${e}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:n.jsx("path",{d:"M21 12a9 9 0 11-6.219-8.56"})}),k=r.forwardRef((({value:e,onChange:t,onExecute:s,config:i,placeholder:o="Enter QL query...",disabled:a=!1,className:l,showSearchIcon:u=!0,showClearIcon:c=!0,getAsyncValueSuggestions:p,getPredefinedValueSuggestions:g,...d},h)=>{const f=r.useRef(null),k=r.useRef(null),[w,$]=r.useState(!1),{state:N,handleInputChange:I,handleKeyDown:E,selectSuggestion:T}=y({config:i,initialValue:e||"",onChange:t,onExecute:s,getAsyncValueSuggestions:p,getPredefinedValueSuggestions:g});r.useEffect((()=>{var t;void 0!==e&&e!==N.value&&I(e,(null==(t=f.current)?void 0:t.selectionStart)||0)}),[e,N.value,I]);const L=r.useCallback((e=>{const t=e.target.value,n=e.target.selectionStart||0;I(t,n)}),[I]),O=r.useCallback((()=>{if(f.current){const e=f.current.selectionStart||0;I(N.value,e)}}),[I,N.value]),C=r.useCallback((e=>{var t;T(e),$(!1),null==(t=f.current)||t.focus()}),[T]),V=r.useCallback((()=>{var e;I("",0),null==(e=f.current)||e.focus()}),[I]);r.useEffect((()=>{$(N.showSuggestions&&N.suggestions.length>0)}),[N.showSuggestions,N.suggestions.length]),r.useEffect((()=>{if(N.selectedSuggestionIndex>=0&&k.current){const e=k.current.querySelector(`[data-suggestion-index="${N.selectedSuggestionIndex}"]`);e&&e.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"})}}),[N.selectedSuggestionIndex]);const j=c&&N.value.length>0&&!a,b=N.isLoading;return n.jsxs("div",{className:v("ql-input-container",l),children:[n.jsxs("div",{className:"ql-input-wrapper",children:[u&&n.jsx("div",{className:"ql-input-icon ql-input-icon--search",children:n.jsx(x,{})}),n.jsx("input",{ref:r.useMemo((()=>e=>{"function"==typeof h?h(e):h&&(h.current=e),f.current=e}),[h]),type:"text",value:N.value,onChange:L,onKeyDown:E,onSelect:O,onFocus:()=>$(N.suggestions.length>0),onBlur:()=>{setTimeout((()=>$(!1)),150)},placeholder:o,disabled:a,className:v("ql-input",N.showSuggestions?"ql-input--suggestions":!N.query.valid&&N.value?"ql-input--invalid":N.query.valid&&N.value?"ql-input--valid":""),"data-testid":"ql-input",...d}),j&&n.jsx("button",{type:"button",onClick:V,className:"ql-input-icon ql-input-icon--clear","aria-label":"Clear input",children:n.jsx(m,{})}),b&&n.jsx("div",{className:"ql-input-icon ql-input-icon--loading",children:n.jsx(S,{})})]}),w&&N.suggestions.length>0&&n.jsx("div",{className:"ql-suggestions-popover",ref:k,children:n.jsx("div",{className:"ql-suggestions ql-fade-in",children:0===N.suggestions.length?n.jsx("div",{className:"ql-suggestions-empty",children:"No suggestions found."}):N.suggestions.map(((e,t)=>{const s=t===N.selectedSuggestionIndex;return n.jsx("div",{onClick:()=>C(e),className:v("ql-suggestion-item",s&&"ql-suggestion-item--selected"),"data-testid":"suggestion-item","data-suggestion-index":t,children:n.jsxs("div",{className:"ql-suggestion-item__content",children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem"},children:[n.jsx("span",{className:v("ql-suggestion-type",`ql-suggestion-type--${e.type}`),children:e.type}),n.jsx("span",{className:"ql-suggestion-item__label",children:e.displayValue||e.value})]}),e.description&&n.jsx("div",{className:"ql-suggestion-item__description",children:e.description})]})},`${e.category}-${t}`)}))})}),N.validationErrors.length>0&&n.jsx("div",{className:"ql-validation-error",children:N.validationErrors[0].message})]})}));k.displayName="QLInput",exports.CheckIcon=({className:e="",size:t=16})=>n.jsx("svg",{className:`ql-icon-check ${e}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:n.jsx("path",{d:"M20 6 9 17l-5-5"})}),exports.ChevronDownIcon=({className:e="",size:t=16})=>n.jsx("svg",{className:`ql-icon-chevron-down ${e}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:n.jsx("path",{d:"m6 9 6 6 6-6"})}),exports.LoaderIcon=S,exports.QLExpressionParser=o,exports.QLInput=k,exports.QLParser=c,exports.QLSuggestionEngine=f,exports.SearchIcon=x,exports.XIcon=m,exports.classNames=v,exports.countConditions=function e(t){return p(t)?1:g(t)?t.conditions.reduce(((t,n)=>t+e(n)),0):0},exports.getUsedFields=function e(t){return p(t)?[t.field]:g(t)?t.conditions.flatMap(e):[]},exports.isCondition=p,exports.isLogicalGroup=g,exports.printExpression=function e(t,n=0){const s=" ".repeat(n);if(p(t))return`${s}${t.field} ${t.operator} ${Array.isArray(t.value)?`[${t.value.join(", ")}]`:t.value}`;if(g(t)){const i=t.conditions.map((t=>e(t,n+1))).join("\n");return`${s}${t.operator}:\n${i}`}return""},exports.toMongooseQuery=d,exports.toSQLQuery=h,exports.useDebounce=function(e,t){const[n,i]=s.useState(e);return s.useEffect((()=>{const n=setTimeout((()=>{i(e)}),t);return()=>{clearTimeout(n)}}),[e,t]),n},exports.useQLInput=y; //# sourceMappingURL=index.js.map