@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
- return (_jsx("form", Object.assign({ onSubmit: onSubmit }, { children: _jsxs("div", Object.assign({ ref: containerRef, className: classes }, { children: [_jsx("input", Object.assign({ ref: inputRef, className: "vuiSearchInput__input", 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)), isClearable && value && (_jsx(VuiIconButton, { "aria-label": "Clear input", className: "vuiSearchInput__clearButton", icon: _jsx(VuiIcon, { children: _jsx(BiX, {}) }), onClick: (e) => {
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 (_jsx("div", Object.assign({ id: id, className: "vuiSearchInputSuggestions", role: "listbox" }, { children: _jsx("div", Object.assign({ className: "vuiSearchInputSuggestions__suggestionsList" }, { 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))) })) })));
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
- // If this is at the bottom of the page we need to add some space
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
- .vuiSearchInputSuggestions__suggestionsList {
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 $sizeM $sizeM;
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
+ }
@@ -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
- .vuiSearchInputSuggestions {
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
- .vuiSearchInputSuggestions:after {
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
- .vuiSearchInputSuggestions__suggestionsList {
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 16px 16px;
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectara/vectara-ui",
3
- "version": "9.10.0",
3
+ "version": "9.11.0",
4
4
  "homepage": "./",
5
5
  "description": "Vectara's design system, codified as a React and Sass component library",
6
6
  "author": "Vectara",