@vectara/vectara-ui 9.10.0 → 9.11.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.
|
@@ -10,6 +10,7 @@ type Props = {
|
|
|
10
10
|
autoFocus?: boolean;
|
|
11
11
|
onSubmit?: FormEventHandler;
|
|
12
12
|
suggestions?: SearchSuggestion[];
|
|
13
|
+
isLoading?: boolean;
|
|
13
14
|
};
|
|
14
15
|
type ClearableProps = {
|
|
15
16
|
isClearable?: true;
|
|
@@ -18,5 +19,5 @@ type ClearableProps = {
|
|
|
18
19
|
isClearable?: false;
|
|
19
20
|
onClear?: never;
|
|
20
21
|
};
|
|
21
|
-
export declare const VuiSearchInput: ({ className, size, value, onChange, placeholder, autoFocus, onSubmit, isClearable, onClear, suggestions, ...rest }: Props & ClearableProps) => import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare const VuiSearchInput: ({ className, size, value, onChange, placeholder, autoFocus, onSubmit, isClearable, onClear, suggestions, isLoading, ...rest }: Props & ClearableProps) => import("react/jsx-runtime").JSX.Element;
|
|
22
23
|
export {};
|
|
@@ -13,13 +13,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
13
13
|
import { useRef, useState, useEffect, useMemo } from "react";
|
|
14
14
|
import classNames from "classnames";
|
|
15
15
|
import { VuiIconButton } from "../button/IconButton";
|
|
16
|
-
import { BiX } from "react-icons/bi";
|
|
16
|
+
import { BiSearch, BiX } from "react-icons/bi";
|
|
17
17
|
import { VuiIcon } from "../icon/Icon";
|
|
18
18
|
import { VuiSearchInputSuggestions } from "./SearchInputSuggestions";
|
|
19
19
|
import { createId } from "../../utils/createId";
|
|
20
|
+
import { VuiSpinner } from "../spinner/Spinner";
|
|
20
21
|
const SIZE = ["m", "l"];
|
|
21
22
|
export const VuiSearchInput = (_a) => {
|
|
22
|
-
var { className, size = "m", value, onChange, placeholder, autoFocus, onSubmit, isClearable, onClear, suggestions } = _a, rest = __rest(_a, ["className", "size", "value", "onChange", "placeholder", "autoFocus", "onSubmit", "isClearable", "onClear", "suggestions"]);
|
|
23
|
+
var { className, size = "m", value, onChange, placeholder, autoFocus, onSubmit, isClearable, onClear, suggestions, isLoading } = _a, rest = __rest(_a, ["className", "size", "value", "onChange", "placeholder", "autoFocus", "onSubmit", "isClearable", "onClear", "suggestions", "isLoading"]);
|
|
23
24
|
const classes = classNames("vuiSearchInput", `vuiSearchInput--${size}`, className);
|
|
24
25
|
const inputRef = useRef(null);
|
|
25
26
|
const containerRef = useRef(null);
|
|
@@ -129,7 +130,10 @@ export const VuiSearchInput = (_a) => {
|
|
|
129
130
|
}
|
|
130
131
|
const hasSuggestions = suggestions && suggestions.length > 0 && areSuggestionsVisible;
|
|
131
132
|
const controlsId = useMemo(() => `searchSuggestions-${createId()}`, []);
|
|
132
|
-
|
|
133
|
+
const inputClasses = classNames("vuiSearchInput__input", {
|
|
134
|
+
"vuiSearchInput__input--hasSuggestions": hasSuggestions
|
|
135
|
+
});
|
|
136
|
+
return (_jsx("form", Object.assign({ onSubmit: onSubmit }, { children: _jsxs("div", Object.assign({ ref: containerRef, className: classes, "aria-live": "polite", "aria-atomic": "true", "aria-busy": isLoading ? "true" : "false" }, { children: [_jsx("input", Object.assign({ ref: inputRef, className: inputClasses, type: "text", autoComplete: "off", autoCapitalize: "off", spellCheck: "false", autoFocus: autoFocus, placeholder: placeholder, value: value, onChange: onChange, onFocus: handleInputFocus, onKeyDown: handleInputKeyDown, "aria-autocomplete": "list", "aria-controls": hasSuggestions ? controlsId : undefined }, rest)), _jsx("div", Object.assign({ className: "vuiSearchInput__icon" }, { children: isLoading ? (_jsx(VuiSpinner, { size: size === "m" ? "s" : "m" })) : (_jsx(VuiIcon, Object.assign({ color: "subdued", size: size === "m" ? "s" : "m" }, { children: _jsx(BiSearch, {}) }))) })), isClearable && value && (_jsx(VuiIconButton, { "aria-label": "Clear input", className: "vuiSearchInput__clearButton", icon: _jsx(VuiIcon, { children: _jsx(BiX, {}) }), onClick: (e) => {
|
|
133
137
|
e.preventDefault();
|
|
134
138
|
onClear();
|
|
135
139
|
} })), hasSuggestions && (_jsx(VuiSearchInputSuggestions, { id: controlsId, suggestions: suggestions, onSuggestionKeyDown: handleSuggestionKeyDown, suggestionRefs: suggestionRefs }))] })) })));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
export const VuiSearchInputSuggestions = ({ id, suggestions, onSuggestionKeyDown, suggestionRefs }) => {
|
|
3
|
-
return (
|
|
3
|
+
return (_jsxs("div", Object.assign({ className: "vuiSearchInputSuggestionsContainer" }, { children: [_jsx("div", Object.assign({ className: "vuiSearchInputSuggestions" }, { children: _jsx("div", Object.assign({ id: id, className: "vuiSearchInputSuggestions__suggestionsList", role: "listbox" }, { children: suggestions.map((suggestion, index) => (_jsx("a", Object.assign({ href: suggestion.href, className: "vuiSearchInputSuggestions__suggestion", ref: (el) => (suggestionRefs.current[index] = el), onKeyDown: (e) => onSuggestionKeyDown(e, index), role: "option", "aria-selected": "false" }, { children: suggestion.label }), index))) })) })), _jsx("div", { className: "vuiSearchInputSuggestions__bottomSpacer" })] })));
|
|
4
4
|
};
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
align-items: center;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
.vuiSearchInput__icon {
|
|
8
|
+
position: absolute;
|
|
9
|
+
left: $sizeM;
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
7
13
|
.vuiSearchInput__input {
|
|
8
14
|
flex-grow: 1;
|
|
9
15
|
background-color: $colorEmptyShade;
|
|
@@ -22,6 +28,11 @@
|
|
|
22
28
|
}
|
|
23
29
|
}
|
|
24
30
|
|
|
31
|
+
.vuiSearchInput__input--hasSuggestions {
|
|
32
|
+
border-bottom-left-radius: 0;
|
|
33
|
+
border-bottom-right-radius: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
.vuiSearchInput__submitButton {
|
|
26
37
|
position: absolute;
|
|
27
38
|
right: $sizeS;
|
|
@@ -35,15 +46,23 @@
|
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
.vuiSearchInput--m {
|
|
49
|
+
.vuiSearchInput__icon {
|
|
50
|
+
top: $sizeXs + 1px;
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
.vuiSearchInput__input {
|
|
39
|
-
padding: $sizeXs $sizeM;
|
|
54
|
+
padding: $sizeXs $sizeM $sizeXs $sizeXl + $sizeXs;
|
|
40
55
|
font-size: $fontSizeStandard;
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
58
|
|
|
44
59
|
.vuiSearchInput--l {
|
|
60
|
+
.vuiSearchInput__icon {
|
|
61
|
+
top: $sizeS + 1px;
|
|
62
|
+
}
|
|
63
|
+
|
|
45
64
|
.vuiSearchInput__input {
|
|
46
|
-
padding: $sizeS $sizeM;
|
|
65
|
+
padding: $sizeS $sizeM $sizeS $sizeXl + $sizeS;
|
|
47
66
|
font-size: $fontSizeLarge;
|
|
48
67
|
}
|
|
49
68
|
}
|
|
@@ -61,32 +80,30 @@
|
|
|
61
80
|
color: $colorAccent;
|
|
62
81
|
}
|
|
63
82
|
}
|
|
64
|
-
|
|
65
|
-
.vuiSearchInputSuggestions {
|
|
83
|
+
.vuiSearchInputSuggestionsContainer {
|
|
66
84
|
position: absolute;
|
|
67
85
|
top: 100%;
|
|
68
86
|
left: 0;
|
|
69
87
|
right: 0;
|
|
70
88
|
z-index: 1;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// at the bottom so the user can see the menu completely.
|
|
74
|
-
&:after {
|
|
75
|
-
content: "";
|
|
76
|
-
position: absolute;
|
|
77
|
-
left: 0;
|
|
78
|
-
right: 0;
|
|
79
|
-
height: $sizeXl;
|
|
80
|
-
pointer-events: none;
|
|
81
|
-
}
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-direction: column;
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
.
|
|
93
|
+
.vuiSearchInputSuggestions {
|
|
94
|
+
// position: absolute;
|
|
95
|
+
// top: 100%;
|
|
96
|
+
// left: 0;
|
|
97
|
+
// right: 0;
|
|
98
|
+
overflow: hidden;
|
|
85
99
|
background-color: $colorEmptyShade;
|
|
86
100
|
border: 1px solid $colorMediumShade;
|
|
87
101
|
border-top: none;
|
|
88
|
-
border-radius: 0 0 $
|
|
102
|
+
border-radius: 0 0 $sizeXs $sizeXs;
|
|
89
103
|
box-shadow: $shadowLargeEnd;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.vuiSearchInputSuggestions__suggestionsList {
|
|
90
107
|
max-height: 220px;
|
|
91
108
|
overflow-y: auto;
|
|
92
109
|
}
|
|
@@ -110,3 +127,10 @@
|
|
|
110
127
|
outline: none;
|
|
111
128
|
}
|
|
112
129
|
}
|
|
130
|
+
|
|
131
|
+
// If at the bottom of the window, add some space
|
|
132
|
+
// so the user can comfortably see the complete suggestion list.
|
|
133
|
+
.vuiSearchInputSuggestions__bottomSpacer {
|
|
134
|
+
height: $sizeXl;
|
|
135
|
+
pointer-events: none;
|
|
136
|
+
}
|
package/lib/styles/index.css
CHANGED
|
@@ -3637,6 +3637,12 @@ h2.react-datepicker__current-month {
|
|
|
3637
3637
|
align-items: center;
|
|
3638
3638
|
}
|
|
3639
3639
|
|
|
3640
|
+
.vuiSearchInput__icon {
|
|
3641
|
+
position: absolute;
|
|
3642
|
+
left: 16px;
|
|
3643
|
+
pointer-events: none;
|
|
3644
|
+
}
|
|
3645
|
+
|
|
3640
3646
|
.vuiSearchInput__input {
|
|
3641
3647
|
flex-grow: 1;
|
|
3642
3648
|
background-color: #ffffff;
|
|
@@ -3654,6 +3660,11 @@ h2.react-datepicker__current-month {
|
|
|
3654
3660
|
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
|
|
3655
3661
|
}
|
|
3656
3662
|
|
|
3663
|
+
.vuiSearchInput__input--hasSuggestions {
|
|
3664
|
+
border-bottom-left-radius: 0;
|
|
3665
|
+
border-bottom-right-radius: 0;
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3657
3668
|
.vuiSearchInput__submitButton {
|
|
3658
3669
|
position: absolute;
|
|
3659
3670
|
right: 12px;
|
|
@@ -3665,13 +3676,19 @@ h2.react-datepicker__current-month {
|
|
|
3665
3676
|
color: #5f30c3;
|
|
3666
3677
|
}
|
|
3667
3678
|
|
|
3679
|
+
.vuiSearchInput--m .vuiSearchInput__icon {
|
|
3680
|
+
top: 9px;
|
|
3681
|
+
}
|
|
3668
3682
|
.vuiSearchInput--m .vuiSearchInput__input {
|
|
3669
|
-
padding: 8px 16px;
|
|
3683
|
+
padding: 8px 16px 8px 40px;
|
|
3670
3684
|
font-size: 14px;
|
|
3671
3685
|
}
|
|
3672
3686
|
|
|
3687
|
+
.vuiSearchInput--l .vuiSearchInput__icon {
|
|
3688
|
+
top: 13px;
|
|
3689
|
+
}
|
|
3673
3690
|
.vuiSearchInput--l .vuiSearchInput__input {
|
|
3674
|
-
padding: 12px 16px;
|
|
3691
|
+
padding: 12px 16px 12px 44px;
|
|
3675
3692
|
font-size: 18px;
|
|
3676
3693
|
}
|
|
3677
3694
|
|
|
@@ -3688,28 +3705,26 @@ h2.react-datepicker__current-month {
|
|
|
3688
3705
|
color: #5f30c3;
|
|
3689
3706
|
}
|
|
3690
3707
|
|
|
3691
|
-
.
|
|
3708
|
+
.vuiSearchInputSuggestionsContainer {
|
|
3692
3709
|
position: absolute;
|
|
3693
3710
|
top: 100%;
|
|
3694
3711
|
left: 0;
|
|
3695
3712
|
right: 0;
|
|
3696
3713
|
z-index: 1;
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
content: "";
|
|
3700
|
-
position: absolute;
|
|
3701
|
-
left: 0;
|
|
3702
|
-
right: 0;
|
|
3703
|
-
height: 32px;
|
|
3704
|
-
pointer-events: none;
|
|
3714
|
+
display: flex;
|
|
3715
|
+
flex-direction: column;
|
|
3705
3716
|
}
|
|
3706
3717
|
|
|
3707
|
-
.
|
|
3718
|
+
.vuiSearchInputSuggestions {
|
|
3719
|
+
overflow: hidden;
|
|
3708
3720
|
background-color: #ffffff;
|
|
3709
3721
|
border: 1px solid #cbd1de;
|
|
3710
3722
|
border-top: none;
|
|
3711
|
-
border-radius: 0 0
|
|
3723
|
+
border-radius: 0 0 8px 8px;
|
|
3712
3724
|
box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px;
|
|
3725
|
+
}
|
|
3726
|
+
|
|
3727
|
+
.vuiSearchInputSuggestions__suggestionsList {
|
|
3713
3728
|
max-height: 220px;
|
|
3714
3729
|
overflow-y: auto;
|
|
3715
3730
|
}
|
|
@@ -3731,6 +3746,11 @@ h2.react-datepicker__current-month {
|
|
|
3731
3746
|
outline: none;
|
|
3732
3747
|
}
|
|
3733
3748
|
|
|
3749
|
+
.vuiSearchInputSuggestions__bottomSpacer {
|
|
3750
|
+
height: 32px;
|
|
3751
|
+
pointer-events: none;
|
|
3752
|
+
}
|
|
3753
|
+
|
|
3734
3754
|
.vuiSearchResult {
|
|
3735
3755
|
position: relative;
|
|
3736
3756
|
}
|