elastic-input 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -16
- package/dist/autocomplete/AutocompleteEngine.d.ts +10 -0
- package/dist/components/AutocompleteDropdown.d.ts +7 -1
- package/dist/components/DateRangePicker.d.ts +3 -1
- package/dist/components/ElasticInput.d.ts +1 -1
- package/dist/components/HighlightedContent.d.ts +2 -0
- package/dist/components/ValidationSquiggles.d.ts +6 -1
- package/dist/elastic-input.es.js +3743 -2422
- package/dist/highlighting/rangeHighlight.d.ts +1 -1
- package/dist/highlighting/regexHighlight.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +64 -12
- package/dist/utils/cx.d.ts +2 -0
- package/dist/utils/domUtils.d.ts +6 -0
- package/dist/validation/Validator.d.ts +2 -1
- package/dist/validation/dateValidator.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A syntax-aware smart autocomplete input for building structured queries. Support
|
|
|
4
4
|
|
|
5
5
|
Built with React functional components and hooks (compatible with React 16.8+), zero runtime dependencies beyond React/ReactDOM, and fully inline-styled (no CSS imports required).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**[Live Demo](https://krtools.github.io/elastic-input/)**
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
@@ -19,6 +19,12 @@ Vibe-coded as a proof of concept with Claude Code
|
|
|
19
19
|
- **Fully configurable** — colors, structural styles, fonts, and layout are all customizable via props
|
|
20
20
|
- **Dark mode ready** — ships with `DARK_COLORS` and `DARK_STYLES` presets
|
|
21
21
|
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install elastic-input
|
|
26
|
+
```
|
|
27
|
+
|
|
22
28
|
## Quick Start
|
|
23
29
|
|
|
24
30
|
```tsx
|
|
@@ -30,8 +36,8 @@ const fields: FieldConfig[] = [
|
|
|
30
36
|
name: 'status',
|
|
31
37
|
label: 'Status',
|
|
32
38
|
type: 'string',
|
|
33
|
-
suggestions: ['active', 'inactive', 'pending'],
|
|
34
39
|
description: 'Account status',
|
|
40
|
+
placeholder: 'Search statuses...',
|
|
35
41
|
},
|
|
36
42
|
{
|
|
37
43
|
name: 'created',
|
|
@@ -103,33 +109,36 @@ Implicit AND is supported — `status:active level:ERROR` is equivalent to `stat
|
|
|
103
109
|
| `onValidationChange` | `(errors) => void` | — | Called when validation errors change |
|
|
104
110
|
| `value` | `string` | — | Controlled input value |
|
|
105
111
|
| `defaultValue` | `string` | — | Initial uncontrolled value |
|
|
106
|
-
| `savedSearches` | `SavedSearch[] \| () => Promise<SavedSearch[]>` | — | Saved search definitions (sync or async) |
|
|
107
|
-
| `searchHistory` | `HistoryEntry[] \| () => Promise<HistoryEntry[]>` | — | Search history entries (sync or async) |
|
|
108
|
-
| `fetchSuggestions` | `(field, partial) => Promise<SuggestionItem[]>` | — | Async suggestion provider for field values |
|
|
112
|
+
| `savedSearches` | `SavedSearch[] \| (partial) => Promise<SavedSearch[]>` | — | Saved search definitions (sync array or async callback with partial) |
|
|
113
|
+
| `searchHistory` | `HistoryEntry[] \| (partial) => Promise<HistoryEntry[]>` | — | Search history entries (sync array or async callback with partial) |
|
|
114
|
+
| `fetchSuggestions` | `(field, partial) => Promise<SuggestionItem[]>` | — | Async suggestion provider for field values (called for all non-boolean fields) |
|
|
109
115
|
| `colors` | `ColorConfig` | `DEFAULT_COLORS` | Syntax highlighting and UI colors |
|
|
110
116
|
| `styles` | `StyleConfig` | `DEFAULT_STYLES` | Structural/layout style overrides |
|
|
111
117
|
| `placeholder` | `string` | `"Search..."` | Placeholder text |
|
|
112
118
|
| `className` | `string` | — | CSS class for the outer container |
|
|
119
|
+
| `classNames` | `ClassNamesConfig` | — | Custom CSS classes for sub-elements (editor, dropdown, tokens, etc.) |
|
|
113
120
|
| `style` | `CSSProperties` | — | Inline styles for the outer container |
|
|
114
121
|
| `inputRef` | `(api) => void` | — | Receive an imperative API handle |
|
|
115
|
-
| `dropdown` | `DropdownConfig` | `{}` | Dropdown behavior and rendering (
|
|
122
|
+
| `dropdown` | `DropdownConfig` | `{}` | Dropdown behavior and rendering (open, triggers, renderers) |
|
|
116
123
|
| `features` | `FeaturesConfig` | `{}` | Feature toggles (multiline, smartSelectAll, expandSelection, wildcardWrap, savedSearches, historySearch) |
|
|
117
124
|
| `onKeyDown` | `(e) => void` | — | Called before internal keyboard handling |
|
|
118
125
|
| `onFocus` | `() => void` | — | Called when the input gains focus |
|
|
119
126
|
| `onBlur` | `() => void` | — | Called when the input loses focus |
|
|
120
127
|
| `onTab` | `(context) => TabActionResult` | — | Override Tab key behavior (accept/blur/submit) |
|
|
121
128
|
| `validateValue` | `(ctx) => ValidateReturn` | — | Custom validation for all value types |
|
|
129
|
+
| `parseDate` | `(value: string) => Date \| null` | — | Custom date parser for validation and date picker init |
|
|
122
130
|
|
|
123
131
|
## Field Configuration
|
|
124
132
|
|
|
125
133
|
```typescript
|
|
126
134
|
interface FieldConfig {
|
|
127
|
-
name: string;
|
|
128
|
-
label?: string;
|
|
129
|
-
type: FieldType;
|
|
130
|
-
|
|
131
|
-
operators?: string[];
|
|
132
|
-
description?: string;
|
|
135
|
+
name: string; // Field identifier used in queries
|
|
136
|
+
label?: string; // Display label (used in autocomplete)
|
|
137
|
+
type: FieldType; // 'string' | 'number' | 'date' | 'boolean' | 'ip'
|
|
138
|
+
aliases?: string[]; // Alternative names that resolve to this field
|
|
139
|
+
operators?: string[]; // Allowed operators (future use)
|
|
140
|
+
description?: string; // Shown in autocomplete dropdown
|
|
141
|
+
placeholder?: string | false; // Hint shown while typing a value (false to suppress)
|
|
133
142
|
}
|
|
134
143
|
```
|
|
135
144
|
|
|
@@ -233,12 +242,15 @@ const savedSearches = [
|
|
|
233
242
|
|
|
234
243
|
Type `#` in the input to see saved search suggestions. Selecting one replaces the `#token` with the saved query text.
|
|
235
244
|
|
|
236
|
-
Supports async loading:
|
|
245
|
+
Supports async loading with per-keystroke filtering:
|
|
237
246
|
|
|
238
247
|
```tsx
|
|
239
248
|
<ElasticInput
|
|
240
249
|
fields={fields}
|
|
241
|
-
savedSearches={
|
|
250
|
+
savedSearches={async (partial) => {
|
|
251
|
+
const res = await fetch(`/api/saved-searches?q=${partial}`);
|
|
252
|
+
return res.json();
|
|
253
|
+
}}
|
|
242
254
|
/>
|
|
243
255
|
```
|
|
244
256
|
|
|
@@ -260,9 +272,21 @@ const history = [
|
|
|
260
272
|
|
|
261
273
|
Type `!` to see history suggestions. Selecting one inserts the query (wrapped in parentheses if it contains boolean operators).
|
|
262
274
|
|
|
275
|
+
Supports async loading with per-keystroke filtering:
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<ElasticInput
|
|
279
|
+
fields={fields}
|
|
280
|
+
searchHistory={async (partial) => {
|
|
281
|
+
const res = await fetch(`/api/history?q=${partial}`);
|
|
282
|
+
return res.json();
|
|
283
|
+
}}
|
|
284
|
+
/>
|
|
285
|
+
```
|
|
286
|
+
|
|
263
287
|
## Async Suggestions
|
|
264
288
|
|
|
265
|
-
Provide dynamic suggestions for field values:
|
|
289
|
+
Provide dynamic suggestions for field values. Called for all non-boolean field value contexts when provided:
|
|
266
290
|
|
|
267
291
|
```tsx
|
|
268
292
|
<ElasticInput
|
|
@@ -395,7 +419,7 @@ const ast = parser.parse();
|
|
|
395
419
|
|
|
396
420
|
// Validate
|
|
397
421
|
const fields: FieldConfig[] = [
|
|
398
|
-
{ name: 'status', type: 'string'
|
|
422
|
+
{ name: 'status', type: 'string' },
|
|
399
423
|
{ name: 'price', type: 'number' },
|
|
400
424
|
];
|
|
401
425
|
const validator = new Validator(fields);
|
|
@@ -12,6 +12,10 @@ export interface AutocompleteResult {
|
|
|
12
12
|
export interface AutocompleteOptions {
|
|
13
13
|
showSavedSearchHint?: boolean;
|
|
14
14
|
showHistoryHint?: boolean;
|
|
15
|
+
/** Set to true when a savedSearches callback is provided (for hints even when no sync data). */
|
|
16
|
+
hasSavedSearchProvider?: boolean;
|
|
17
|
+
/** Set to true when a searchHistory callback is provided (for hints even when no sync data). */
|
|
18
|
+
hasHistoryProvider?: boolean;
|
|
15
19
|
}
|
|
16
20
|
export declare class AutocompleteEngine {
|
|
17
21
|
private fields;
|
|
@@ -33,4 +37,10 @@ export declare class AutocompleteEngine {
|
|
|
33
37
|
private getSpecialHints;
|
|
34
38
|
private getSavedSearchSuggestions;
|
|
35
39
|
private getHistorySuggestions;
|
|
40
|
+
/**
|
|
41
|
+
* Wraps a history query in parens if the top-level AST node is a BooleanExpr
|
|
42
|
+
* (explicit AND/OR or implicit adjacency). Already-grouped expressions
|
|
43
|
+
* like -(a AND b) or (a OR b)^2 don't need extra wrapping.
|
|
44
|
+
*/
|
|
45
|
+
static wrapHistoryQuery(query: string): string;
|
|
36
46
|
}
|
|
@@ -19,6 +19,12 @@ interface AutocompleteDropdownProps {
|
|
|
19
19
|
renderSavedSearchItem?: (search: SavedSearch, isSelected: boolean) => React.ReactNode | null | undefined;
|
|
20
20
|
renderDropdownHeader?: (context: CursorContext) => React.ReactNode | null | undefined;
|
|
21
21
|
cursorContext?: CursorContext | null;
|
|
22
|
+
/** Custom class names for dropdown elements. */
|
|
23
|
+
classNames?: {
|
|
24
|
+
dropdown?: string;
|
|
25
|
+
dropdownHeader?: string;
|
|
26
|
+
dropdownItem?: string;
|
|
27
|
+
};
|
|
22
28
|
}
|
|
23
|
-
export declare function AutocompleteDropdown({ suggestions, selectedIndex, onSelect, position, colors, styles, visible, fixedWidth, renderHistoryItem, renderSavedSearchItem, renderDropdownHeader, cursorContext, }: AutocompleteDropdownProps): React.ReactPortal | null;
|
|
29
|
+
export declare function AutocompleteDropdown({ suggestions, selectedIndex, onSelect, position, colors, styles, visible, fixedWidth, renderHistoryItem, renderSavedSearchItem, renderDropdownHeader, cursorContext, classNames, }: AutocompleteDropdownProps): React.ReactPortal | null;
|
|
24
30
|
export {};
|
|
@@ -11,6 +11,8 @@ interface DateRangePickerProps {
|
|
|
11
11
|
label: string;
|
|
12
12
|
value: string;
|
|
13
13
|
}[];
|
|
14
|
+
/** Custom class name for the date picker container. */
|
|
15
|
+
className?: string;
|
|
14
16
|
}
|
|
15
|
-
export declare function DateRangePicker({ onSelect, colors, styles: styleConfig, initialMode, initialStart, initialEnd, presets: presetsProp }: DateRangePickerProps): React.JSX.Element;
|
|
17
|
+
export declare function DateRangePicker({ onSelect, colors, styles: styleConfig, initialMode, initialStart, initialEnd, presets: presetsProp, className }: DateRangePickerProps): React.JSX.Element;
|
|
16
18
|
export {};
|
|
@@ -16,7 +16,7 @@ export declare function computeDatePickerInit(context: {
|
|
|
16
16
|
token?: {
|
|
17
17
|
value: string;
|
|
18
18
|
};
|
|
19
|
-
}): DatePickerInit | null;
|
|
19
|
+
}, parseDateFn?: (value: string) => Date | null): DatePickerInit | null;
|
|
20
20
|
/**
|
|
21
21
|
* Determine whether the date picker needs to be unmounted and remounted.
|
|
22
22
|
* This is necessary when initial state changes because DateRangePicker
|
|
@@ -3,5 +3,7 @@ import { ColorConfig } from '../types';
|
|
|
3
3
|
|
|
4
4
|
export interface HighlightOptions {
|
|
5
5
|
cursorOffset?: number;
|
|
6
|
+
/** Custom class name appended to every token span. */
|
|
7
|
+
tokenClassName?: string;
|
|
6
8
|
}
|
|
7
9
|
export declare function buildHighlightedHTML(tokens: Token[], colorConfig?: ColorConfig, options?: HighlightOptions): string;
|
|
@@ -8,6 +8,11 @@ interface ValidationSquigglesProps {
|
|
|
8
8
|
colors?: ColorConfig;
|
|
9
9
|
styles?: StyleConfig;
|
|
10
10
|
containerRef?: HTMLDivElement | null;
|
|
11
|
+
/** Custom class names for squiggly and tooltip elements. */
|
|
12
|
+
classNames?: {
|
|
13
|
+
squiggly?: string;
|
|
14
|
+
tooltip?: string;
|
|
15
|
+
};
|
|
11
16
|
}
|
|
12
|
-
export declare function ValidationSquiggles({ errors, editorRef, cursorOffset, colors, styles, containerRef }: ValidationSquigglesProps): React.JSX.Element | null;
|
|
17
|
+
export declare function ValidationSquiggles({ errors, editorRef, cursorOffset, colors, styles, containerRef, classNames }: ValidationSquigglesProps): React.JSX.Element | null;
|
|
13
18
|
export {};
|