elastic-input 0.3.1 → 0.3.2
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/dist/elastic-input.es.js
CHANGED
|
@@ -1180,7 +1180,8 @@ const DEFAULT_COLORS = {
|
|
|
1180
1180
|
regexAlternation: "#8250df",
|
|
1181
1181
|
regexText: "#0a3069",
|
|
1182
1182
|
matchedParenBg: "#fff3cd",
|
|
1183
|
-
warning: "#d4a72c"
|
|
1183
|
+
warning: "#d4a72c",
|
|
1184
|
+
historyDescription: "#656d76"
|
|
1184
1185
|
};
|
|
1185
1186
|
const DARK_COLORS = {
|
|
1186
1187
|
fieldName: "#79c0ff",
|
|
@@ -1208,7 +1209,8 @@ const DARK_COLORS = {
|
|
|
1208
1209
|
regexAlternation: "#d2a8ff",
|
|
1209
1210
|
regexText: "#a5d6ff",
|
|
1210
1211
|
matchedParenBg: "#3d3222",
|
|
1211
|
-
warning: "#e3b341"
|
|
1212
|
+
warning: "#e3b341",
|
|
1213
|
+
historyDescription: "#484f58"
|
|
1212
1214
|
};
|
|
1213
1215
|
const DEFAULT_STYLES = {
|
|
1214
1216
|
fontFamily: "'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace",
|
|
@@ -1530,7 +1532,7 @@ class AutocompleteEngine {
|
|
|
1530
1532
|
return this.searchHistory.slice(0, this.maxSuggestions).map((h) => ({
|
|
1531
1533
|
text: AutocompleteEngine.wrapHistoryQuery(h.query),
|
|
1532
1534
|
label: h.label || h.query,
|
|
1533
|
-
description: h.
|
|
1535
|
+
description: h.description,
|
|
1534
1536
|
type: "history",
|
|
1535
1537
|
replaceStart: start,
|
|
1536
1538
|
replaceEnd: end,
|
|
@@ -2799,7 +2801,7 @@ function AutocompleteDropdown({
|
|
|
2799
2801
|
whiteSpace: "normal",
|
|
2800
2802
|
wordBreak: "break-all",
|
|
2801
2803
|
width: "100%"
|
|
2802
|
-
} }, highlightMatch(suggestion.label, suggestion.matchPartial, isSelected)), /* @__PURE__ */ React.createElement("span", { style: { display: "flex", alignItems: "center", gap: "8px", width: "100%" } }, suggestion.description && /* @__PURE__ */ React.createElement("span", { className: "ei-dropdown-item-desc", style: { ...getDropdownItemDescStyle(), flex: 1 } }, suggestion.description), /* @__PURE__ */ React.createElement("span", { className: "ei-dropdown-item-type", style: { ...getDropdownItemTypeStyle(isSelected, mergedStyles), marginLeft: "auto" } }, "history")))
|
|
2804
|
+
} }, highlightMatch(suggestion.label, suggestion.matchPartial, isSelected)), /* @__PURE__ */ React.createElement("span", { style: { display: "flex", alignItems: "center", gap: "8px", width: "100%" } }, suggestion.description != null && /* @__PURE__ */ React.createElement("span", { className: "ei-dropdown-item-desc", style: { ...getDropdownItemDescStyle(), flex: 1, color: mergedColors.historyDescription, opacity: 1 } }, suggestion.description), /* @__PURE__ */ React.createElement("span", { className: "ei-dropdown-item-type", style: { ...getDropdownItemTypeStyle(isSelected, mergedStyles), marginLeft: "auto" } }, "history")))
|
|
2803
2805
|
);
|
|
2804
2806
|
}
|
|
2805
2807
|
if (suggestion.type === "savedSearch" && renderSavedSearchItem && suggestion.sourceData) {
|
|
@@ -3735,13 +3737,14 @@ function ElasticInput(props) {
|
|
|
3735
3737
|
const effectiveMaxSuggestions = maxSuggestions || DEFAULT_MAX_SUGGESTIONS;
|
|
3736
3738
|
const suggestDebounceMs = dropdownConfig == null ? void 0 : dropdownConfig.suggestDebounceMs;
|
|
3737
3739
|
const dropdownMaxHeightPx = parseInt((stylesProp == null ? void 0 : stylesProp.dropdownMaxHeight) || "300", 10) || 300;
|
|
3738
|
-
const enableSavedSearches = (featuresConfig == null ? void 0 : featuresConfig.savedSearches) ??
|
|
3739
|
-
const enableHistorySearch = (featuresConfig == null ? void 0 : featuresConfig.historySearch) ??
|
|
3740
|
+
const enableSavedSearches = (featuresConfig == null ? void 0 : featuresConfig.savedSearches) ?? !!savedSearches;
|
|
3741
|
+
const enableHistorySearch = (featuresConfig == null ? void 0 : featuresConfig.historySearch) ?? !!searchHistory;
|
|
3740
3742
|
const showSavedSearchHint = (dropdownConfig == null ? void 0 : dropdownConfig.showSavedSearchHint) ?? enableSavedSearches;
|
|
3741
3743
|
const showHistoryHint = (dropdownConfig == null ? void 0 : dropdownConfig.showHistoryHint) ?? enableHistorySearch;
|
|
3742
3744
|
const showOperators = (dropdownConfig == null ? void 0 : dropdownConfig.showOperators) !== false;
|
|
3743
3745
|
const triggerOnNavigation = (dropdownOpenIsCallback || dropdownMode !== "input") && (dropdownConfig == null ? void 0 : dropdownConfig.onNavigation) !== false;
|
|
3744
3746
|
const navigationDelay = (dropdownConfig == null ? void 0 : dropdownConfig.navigationDelay) ?? 0;
|
|
3747
|
+
const loadingDelay = (dropdownConfig == null ? void 0 : dropdownConfig.loadingDelay) ?? 0;
|
|
3745
3748
|
const renderFieldHint = dropdownConfig == null ? void 0 : dropdownConfig.renderFieldHint;
|
|
3746
3749
|
const renderHistoryItem = dropdownConfig == null ? void 0 : dropdownConfig.renderHistoryItem;
|
|
3747
3750
|
const renderSavedSearchItem = dropdownConfig == null ? void 0 : dropdownConfig.renderSavedSearchItem;
|
|
@@ -3786,6 +3789,7 @@ function ElasticInput(props) {
|
|
|
3786
3789
|
const abortControllerRef = React.useRef(null);
|
|
3787
3790
|
const highlightTimerRef = React.useRef(null);
|
|
3788
3791
|
const navDelayTimerRef = React.useRef(null);
|
|
3792
|
+
const loadingDelayTimerRef = React.useRef(null);
|
|
3789
3793
|
const asyncActiveRef = React.useRef(false);
|
|
3790
3794
|
const datePickerInitRef = React.useRef(null);
|
|
3791
3795
|
const datePickerReplaceRef = React.useRef(null);
|
|
@@ -3993,6 +3997,10 @@ function ElasticInput(props) {
|
|
|
3993
3997
|
asyncActiveRef.current = false;
|
|
3994
3998
|
(_a = abortControllerRef.current) == null ? void 0 : _a.abort();
|
|
3995
3999
|
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
4000
|
+
if (loadingDelayTimerRef.current) {
|
|
4001
|
+
clearTimeout(loadingDelayTimerRef.current);
|
|
4002
|
+
loadingDelayTimerRef.current = null;
|
|
4003
|
+
}
|
|
3996
4004
|
const init = computeDatePickerInit(result.context, parseDateProp);
|
|
3997
4005
|
const prevInit = datePickerInitRef.current;
|
|
3998
4006
|
datePickerInitRef.current = init;
|
|
@@ -4020,6 +4028,10 @@ function ElasticInput(props) {
|
|
|
4020
4028
|
asyncActiveRef.current = false;
|
|
4021
4029
|
(_b = abortControllerRef.current) == null ? void 0 : _b.abort();
|
|
4022
4030
|
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
4031
|
+
if (loadingDelayTimerRef.current) {
|
|
4032
|
+
clearTimeout(loadingDelayTimerRef.current);
|
|
4033
|
+
loadingDelayTimerRef.current = null;
|
|
4034
|
+
}
|
|
4023
4035
|
const newSuggestions = applyFieldHint(result.suggestions, result.context);
|
|
4024
4036
|
if (newSuggestions.length > 0) {
|
|
4025
4037
|
setSuggestions(newSuggestions);
|
|
@@ -4038,20 +4050,28 @@ function ElasticInput(props) {
|
|
|
4038
4050
|
const token = result.context.token;
|
|
4039
4051
|
const start = token ? token.start : offset;
|
|
4040
4052
|
const end = token ? token.end : offset;
|
|
4041
|
-
const
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4053
|
+
const showSpinner = () => {
|
|
4054
|
+
loadingDelayTimerRef.current = null;
|
|
4055
|
+
const loadingSuggestion = {
|
|
4056
|
+
text: "",
|
|
4057
|
+
label: "Searching...",
|
|
4058
|
+
type: "loading",
|
|
4059
|
+
replaceStart: start,
|
|
4060
|
+
replaceEnd: end
|
|
4061
|
+
};
|
|
4062
|
+
setSuggestions([loadingSuggestion]);
|
|
4063
|
+
if (!dropdownAlignToInput) setShowDropdown(false);
|
|
4064
|
+
setShowDatePicker(false);
|
|
4065
|
+
setSelectedSuggestionIndex(-1);
|
|
4066
|
+
showDropdownAtPosition(32, 300);
|
|
4048
4067
|
};
|
|
4049
|
-
|
|
4050
|
-
if (
|
|
4051
|
-
|
|
4052
|
-
|
|
4068
|
+
if (loadingDelayTimerRef.current) clearTimeout(loadingDelayTimerRef.current);
|
|
4069
|
+
if (loadingDelay > 0) {
|
|
4070
|
+
loadingDelayTimerRef.current = setTimeout(showSpinner, loadingDelay);
|
|
4071
|
+
} else {
|
|
4072
|
+
showSpinner();
|
|
4073
|
+
}
|
|
4053
4074
|
setAutocompleteContext(contextType);
|
|
4054
|
-
showDropdownAtPosition(32, 300);
|
|
4055
4075
|
}
|
|
4056
4076
|
if (willFetchAsync) {
|
|
4057
4077
|
const partial = result.context.partial;
|
|
@@ -4086,7 +4106,7 @@ function ElasticInput(props) {
|
|
|
4086
4106
|
mapped = fetched.map((h) => ({
|
|
4087
4107
|
text: AutocompleteEngine.wrapHistoryQuery(h.query),
|
|
4088
4108
|
label: h.label || h.query,
|
|
4089
|
-
description: h.
|
|
4109
|
+
description: h.description,
|
|
4090
4110
|
type: "history",
|
|
4091
4111
|
replaceStart: start,
|
|
4092
4112
|
replaceEnd: end,
|
|
@@ -4109,6 +4129,10 @@ function ElasticInput(props) {
|
|
|
4109
4129
|
matchPartial: partial
|
|
4110
4130
|
}));
|
|
4111
4131
|
}
|
|
4132
|
+
if (loadingDelayTimerRef.current) {
|
|
4133
|
+
clearTimeout(loadingDelayTimerRef.current);
|
|
4134
|
+
loadingDelayTimerRef.current = null;
|
|
4135
|
+
}
|
|
4112
4136
|
mapped = mapped.slice(0, effectiveMaxSuggestions);
|
|
4113
4137
|
if (mapped.length > 0) {
|
|
4114
4138
|
setSuggestions(mapped);
|
|
@@ -4130,6 +4154,10 @@ function ElasticInput(props) {
|
|
|
4130
4154
|
}
|
|
4131
4155
|
}
|
|
4132
4156
|
} catch (e) {
|
|
4157
|
+
if (loadingDelayTimerRef.current) {
|
|
4158
|
+
clearTimeout(loadingDelayTimerRef.current);
|
|
4159
|
+
loadingDelayTimerRef.current = null;
|
|
4160
|
+
}
|
|
4133
4161
|
if (!controller.signal.aborted) {
|
|
4134
4162
|
const errorMsg = e instanceof Error ? e.message : "Error loading suggestions";
|
|
4135
4163
|
const errorSuggestion = {
|
|
@@ -4147,7 +4175,7 @@ function ElasticInput(props) {
|
|
|
4147
4175
|
}
|
|
4148
4176
|
}, debounceMs);
|
|
4149
4177
|
}
|
|
4150
|
-
}, [fetchSuggestionsProp, savedSearches, searchHistory, suggestDebounceMs, applyFieldHint, computeDropdownPosition, showDropdownAtPosition, dropdownAlignToInput, dropdownOpen, dropdownOpenIsCallback, dropdownMode, showOperators, effectiveMaxSuggestions]);
|
|
4178
|
+
}, [fetchSuggestionsProp, savedSearches, searchHistory, suggestDebounceMs, applyFieldHint, computeDropdownPosition, showDropdownAtPosition, dropdownAlignToInput, dropdownOpen, dropdownOpenIsCallback, dropdownMode, showOperators, effectiveMaxSuggestions, loadingDelay]);
|
|
4151
4179
|
updateSuggestionsRef.current = updateSuggestionsFromTokens;
|
|
4152
4180
|
const closeDropdown = React.useCallback(() => {
|
|
4153
4181
|
var _a;
|
|
@@ -4348,6 +4376,7 @@ function ElasticInput(props) {
|
|
|
4348
4376
|
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
4349
4377
|
if (highlightTimerRef.current) clearTimeout(highlightTimerRef.current);
|
|
4350
4378
|
if (navDelayTimerRef.current) clearTimeout(navDelayTimerRef.current);
|
|
4379
|
+
if (loadingDelayTimerRef.current) clearTimeout(loadingDelayTimerRef.current);
|
|
4351
4380
|
(_a = abortControllerRef.current) == null ? void 0 : _a.abort();
|
|
4352
4381
|
};
|
|
4353
4382
|
}, []);
|
package/dist/types.d.ts
CHANGED
|
@@ -67,10 +67,10 @@ export interface SavedSearch {
|
|
|
67
67
|
export interface HistoryEntry {
|
|
68
68
|
/** The query string from the history entry. */
|
|
69
69
|
query: string;
|
|
70
|
-
/** Unix timestamp (ms) of when the query was executed. Used for ordering. */
|
|
71
|
-
timestamp?: number;
|
|
72
70
|
/** Optional label for display in the autocomplete dropdown. Falls back to `query`. */
|
|
73
71
|
label?: string;
|
|
72
|
+
/** Optional description shown below the label (e.g. date, category). Rendered as-is. */
|
|
73
|
+
description?: React.ReactNode;
|
|
74
74
|
}
|
|
75
75
|
/** An item returned by the async `fetchSuggestions` callback for field value autocomplete. */
|
|
76
76
|
export interface SuggestionItem {
|
|
@@ -140,6 +140,8 @@ export interface ColorConfig {
|
|
|
140
140
|
matchedParenBg?: string;
|
|
141
141
|
/** Warning-severity squiggly underlines (e.g. ambiguous precedence). */
|
|
142
142
|
warning?: string;
|
|
143
|
+
/** Color for history item descriptions. Set to `'transparent'` to hide. */
|
|
144
|
+
historyDescription?: string;
|
|
143
145
|
}
|
|
144
146
|
/**
|
|
145
147
|
* Structural and layout style overrides for the input and dropdown.
|
|
@@ -241,6 +243,10 @@ export interface DropdownConfig {
|
|
|
241
243
|
* immediate. If the user types before the delay elapses, the timer is cancelled.
|
|
242
244
|
* Ignored when `onNavigation` is false. @default 0 */
|
|
243
245
|
navigationDelay?: number;
|
|
246
|
+
/** Delay in ms before showing the "Searching..." spinner on first entry into an
|
|
247
|
+
* async field. If the fetch resolves before the delay, the spinner never appears.
|
|
248
|
+
* Subsequent keystrokes preserve previous results regardless of this setting. @default 0 */
|
|
249
|
+
loadingDelay?: number;
|
|
244
250
|
/** Custom renderer for field value hints. Return a React element for rich content,
|
|
245
251
|
* or null/undefined for the default hint. */
|
|
246
252
|
renderFieldHint?: (field: FieldConfig, partial: string) => React.ReactNode | null | undefined;
|