UNPKG

@abaktiar/ql-input

Version:

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

342 lines (299 loc) 9.53 kB
import { FC } from 'react'; import * as React_2 from 'react'; export declare const CheckIcon: FC<IconProps>; export declare const ChevronDownIcon: FC<IconProps>; /** * Simple class name combiner - framework independent */ export declare function classNames(...classes: (string | undefined | null | false)[]): string; /** * Count total conditions in an expression */ export declare function countConditions(expr: QLExpression): number; export declare type FieldType = 'text' | 'number' | 'date' | 'datetime' | 'boolean' | 'option' | 'multiselect' | 'user'; /** * Get all field names used in an expression */ export declare function getUsedFields(expr: QLExpression): string[]; declare interface IconProps { className?: string; size?: number; } /** * Helper functions to work with QL expressions and convert them to database queries */ export declare function isCondition(expr: QLExpression): expr is QLCondition; export declare function isLogicalGroup(expr: QLExpression): expr is QLLogicalGroup; export declare const LoaderIcon: FC<IconProps>; export declare type LogicalOperatorType = 'AND' | 'OR' | 'NOT'; export declare type OperatorType = '=' | '!=' | '>' | '<' | '>=' | '<=' | '~' | '!~' | 'IN' | 'NOT IN' | 'IS EMPTY' | 'IS NOT EMPTY' | 'WAS' | 'WAS IN' | 'WAS NOT IN' | 'CHANGED'; export declare interface ParseContext { input: string; position: number; tokens: QLToken[]; currentToken?: QLToken; expectingField: boolean; expectingOperator: boolean; expectingValue: boolean; expectingLogical: boolean; parenthesesLevel: number; inOrderBy: boolean; lastField?: string; } /** * Pretty print expression for debugging */ export declare function printExpression(expr: QLExpression, indent?: number): string; export declare interface QLCondition { field: string; operator: OperatorType; value?: string | string[]; not?: boolean; } export declare type QLExpression = QLCondition | QLLogicalGroup; /** * Enhanced QL Expression Parser * Builds hierarchical expression trees that properly represent logical grouping */ export declare class QLExpressionParser { private tokens; private position; parse(tokens: QLToken[]): QLExpression | null; private parseExpression; private parseOrExpression; private parseAndExpression; private parsePrimaryExpression; private parseCondition; private parseValue; private parseFunctionCall; private parseInList; private operatorRequiresValue; private current; private advance; private isLogicalGroup; } export declare interface QLField { name: string; displayName: string; type: FieldType; operators: OperatorType[]; sortable?: boolean; description?: string; options?: QLValue[]; asyncValueSuggestions?: boolean; } export declare interface QLFunction { name: string; displayName: string; description?: string; parameters?: { name: string; type: FieldType; required: boolean; description?: string; }[]; } export declare const QLInput: React_2.ForwardRefExoticComponent<QLInputProps & React_2.RefAttributes<HTMLInputElement>>; export declare interface QLInputConfig { fields: QLField[]; functions?: QLFunction[]; operators?: OperatorType[]; logicalOperators?: LogicalOperatorType[]; keywords?: string[]; maxSuggestions?: number; debounceMs?: number; caseSensitive?: boolean; allowParentheses?: boolean; allowOrderBy?: boolean; allowFunctions?: boolean; } export declare interface QLInputProps { value?: string; onChange?: (value: string, query: QLQuery) => void; onExecute?: (query: QLQuery) => void; config: QLInputConfig; placeholder?: string; disabled?: boolean; className?: string; showSearchIcon?: boolean; showClearIcon?: boolean; getAsyncValueSuggestions?: (field: string, typedValue: string) => Promise<QLValue[]>; getPredefinedValueSuggestions?: (field: string) => QLValue[]; } export declare interface QLInputState { value: string; tokens: QLToken[]; suggestions: QLSuggestion[]; showSuggestions: boolean; selectedSuggestionIndex: number; cursorPosition: number; query: QLQuery; validationErrors: ValidationError[]; isLoading: boolean; justSelectedSuggestion: boolean; } export declare interface QLLogicalGroup { operator: LogicalOperatorType; conditions: (QLCondition | QLLogicalGroup)[]; not?: boolean; } export declare interface QLOrderBy { field: string; direction: SortDirection; } export declare class QLParser { constructor(_config: QLInputConfig); /** * Tokenize the input string into QL tokens */ tokenize(input: string): QLToken[]; /** * Classify unknown tokens based on context */ private classifyTokens; /** * Parse tokens into a QL query object */ parse(input: string): QLQuery; private splitQuery; private parseOrderBy; } export declare interface QLQuery { where?: QLExpression; orderBy?: QLOrderBy[]; raw: string; valid: boolean; errors: string[]; } export declare interface QLSuggestion { type: 'field' | 'operator' | 'value' | 'logical' | 'keyword' | 'function' | 'parenthesis' | 'comma'; value: string; displayValue?: string; description?: string; insertText?: string; category?: string; } export declare class QLSuggestionEngine { private config; constructor(config: QLInputConfig); /** * Get suggestions based on current context */ getSuggestions(context: SuggestionContext): QLSuggestion[]; /** * Get field suggestions */ private getFieldSuggestions; /** * Get operator suggestions for a specific field */ private getOperatorSuggestions; /** * Get value suggestions for a specific field */ private getValueSuggestions; /** * Get operator description */ private getOperatorDescription; /** * Get logical operator suggestions */ private getLogicalOperatorSuggestions; /** * Get sortable field suggestions for ORDER BY */ private getSortableFieldSuggestions; /** * Get sort direction suggestions */ private getSortDirectionSuggestions; /** * Get function suggestions */ private getFunctionSuggestions; /** * Get value suggestions for IN lists (inside parentheses) */ private getInListValueSuggestions; /** * Get logical operator description */ private getLogicalOperatorDescription; /** * Filter suggestions based on partial input */ private filterSuggestions; /** * Get suggestion context from input and cursor position */ getSuggestionContext(input: string, cursorPosition: number, tokens: QLToken[]): SuggestionContext; } export declare interface QLToken { type: 'field' | 'operator' | 'value' | 'logical' | 'keyword' | 'function' | 'parenthesis' | 'comma' | 'whitespace' | 'unknown'; value: string; start: number; end: number; valid?: boolean; error?: string; } export declare interface QLValue { value: string; displayValue?: string; description?: string; } export declare const SearchIcon: FC<IconProps>; export declare type SortDirection = 'ASC' | 'DESC'; export declare interface SuggestionContext { input: string; cursorPosition: number; tokens: QLToken[]; currentToken?: QLToken; previousToken?: QLToken; nextToken?: QLToken; expectingField: boolean; expectingOperator: boolean; expectingValue: boolean; expectingLogical: boolean; inOrderBy: boolean; parenthesesLevel: number; inInList: boolean; lastField?: string; lastOperator?: string; partialInput?: string; } /** * Convert QL expression to Mongoose query */ export declare function toMongooseQuery(expr: QLExpression): any; /** * Convert QL expression to SQL WHERE clause */ export declare function toSQLQuery(expr: QLExpression): string; /** * Custom hook for debouncing values */ export declare function useDebounce<T>(value: T, delay: number): T; export declare function useQLInput({ config, initialValue, onChange, onExecute, getAsyncValueSuggestions, getPredefinedValueSuggestions, }: UseQLInputProps): { state: QLInputState; handleInputChange: (value: string, cursorPosition: number) => void; handleKeyDown: (event: React.KeyboardEvent) => void; selectSuggestion: (suggestion: QLSuggestion) => void; hideSuggestions: () => void; }; declare interface UseQLInputProps { config: QLInputConfig; initialValue?: string; onChange?: (value: string, query: QLQuery) => void; onExecute?: (query: QLQuery) => void; getAsyncValueSuggestions?: (field: string, typedValue: string) => Promise<QLValue[]>; getPredefinedValueSuggestions?: (field: string) => QLValue[]; } export declare interface ValidationError { message: string; start: number; end: number; severity: 'error' | 'warning'; } export declare const XIcon: FC<IconProps>; export { }