Skip to content

Commit a3b278c

Browse files
authored
Merge pull request #14 from AmyShackles/v3.1.0
V3.1.0
2 parents ca052e7 + 8a9ad61 commit a3b278c

File tree

7 files changed

+120
-10
lines changed

7 files changed

+120
-10
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ const ExampleClient = () => {
5454
5555
}
5656
57-
5857
```
5958

6059
## AutoSuggest props:
@@ -68,6 +67,7 @@ const ExampleClient = () => {
6867
| **options** | The array of options if the autosuggest is created using a list of items already in the application |
6968
| **handleChange** | Array for updating the text in the autosuggest field |
7069
| **value** | The value of the autosuggest field |
70+
| **caseInsensitive** | Setting for Client version of AutoSuggest, whether to perform case-insensitive matches against the options array |
7171

7272

7373
## AutoSuggest Default Props
@@ -78,7 +78,12 @@ const ExampleClient = () => {
7878
| **url** | string | "" |
7979
| **debounceTime** | number | 200 |
8080
| **styles** | object | <pre> {<br> announcement: {<br> position: "absolute",<br> clip: "rect(0 0 0 0)",<br> clipPath: "inset(50%)",<br> height: "1px",<br> width: "1px",<br> overflow: "hidden",<br> },<br> combobox: {<br> display: "inline-block",<br> },<br> searchField: {<br> padding: ".5rem",<br> border: "2px solid #c8c8c8",<br> backgroundColor: "#fff",<br> borderRadius: "6px",<br> color: "#000",<br> fontWeight: "normal",<br> fontSize: "1.35rem",<br> margin: "0 auto",<br> width: "19rem",<br> focus: {<br> color: "#000",<br> border: "2px solid #005499",<br> outline: "none",<br> },<br> },<br> searchLabel: {<br> display: "block",<br> fontSize: "1.35rem",<br> },<br> suggestionsContainer: {<br> display: "block",<br> position: "absolute",<br> border: "1px solid #999",<br> background: "#fff",<br> width: "20rem",<br> },<br> suggestionOptions: {<br> margin: "0",<br> padding: "0",<br> listStyle: "none",<br> },<br> suggestionOption: {<br> margin: "0",<br> padding: ".5rem",<br> fontSize: "1.35rem",<br> whiteSpace: "nowrap",<br> overflow: "hidden",<br> cursor: "default",<br> },<br> } </pre> |
81-
| options | array | [] |
81+
| **options** | array | [] |
82+
| **handleChange** | function | No default. Required prop |
83+
| **value** | string | No default. Required prop |
84+
| **caseInsensitive** | boolean | true |
85+
86+
<hr>
8287

8388
## Options argument
8489

dist/AutoSuggest.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-autosuggestions",
3-
"version": "3.0.2",
3+
"version": "3.1.0",
44
"keywords": [
55
"React",
66
"auto-suggest",

src/components/AutoSuggest.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export const AutoSuggest = ({
1313
options = [],
1414
handleChange,
1515
disabled = false,
16-
value
16+
value,
17+
caseInsensitive = true
1718
}) => {
1819
const combinedStyles = {
1920
announcement: {
@@ -97,6 +98,7 @@ export const AutoSuggest = ({
9798
handleChange={handleChange}
9899
disabled={disabled}
99100
value={value}
101+
caseInsensitive={caseInsensitive}
100102
/>
101103
);
102104
};

src/components/AutoSuggestClient.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { AutoSuggestContainer } from "./AutoSuggestContainer.js";
33
import { alphanumericSort } from "../utils/alphanumericSort.js";
44

55
export const AutoSuggestClient = React.forwardRef(
6-
({ name, options, styles, type, isOpen, setIsOpen, handleChange, disabled, value }, ref) => {
6+
(
7+
{ name, options, styles, type, isOpen, setIsOpen, handleChange, disabled, value, caseInsensitive },
8+
ref
9+
) => {
710
const [sortedOptions, optionType] = alphanumericSort(options);
811
const [results, setResults] = React.useState(sortedOptions);
912
const [noResult, setNoResult] = React.useState(false);
@@ -13,10 +16,18 @@ export const AutoSuggestClient = React.forwardRef(
1316
if (isOpen && value) {
1417
let res;
1518
if (optionType === "string") {
16-
res = options.filter((opt) => opt.startsWith(value));
19+
if (caseInsensitive) {
20+
res = options.filter((opt) => opt.toUpperCase().startsWith(value.toUpperCase()));
21+
} else {
22+
res = options.filter((opt) => opt.startsWith(value));
23+
}
1724
}
1825
if (optionType === "object") {
19-
res = options.filter((opt) => opt.value.startsWith(value));
26+
if (caseInsensitive) {
27+
res = options.filter((opt) => opt.value.toUpperCase().startsWith(value.toUpperCase()));
28+
} else {
29+
res = options.filter((opt) => opt.value.startsWith(value));
30+
}
2031
}
2132
setResults(res);
2233
res.length >= 1 && setIsOpen(true);

tests/AutoSuggest.test.js

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,17 @@ beforeAll(() => server.listen());
2424
afterEach(() => server.resetHandlers());
2525
afterAll(() => server.close());
2626

27-
const Form = ({ name = "", url = "", options = [], type = "", styles, handleChange, disabled, value }) => {
27+
const Form = ({
28+
name = "",
29+
url = "",
30+
options = [],
31+
type = "",
32+
styles,
33+
handleChange,
34+
disabled,
35+
value,
36+
caseInsensitive
37+
}) => {
2838
const [make, setMake] = React.useState();
2939
const [formData, setFormData] = React.useState();
3040
const handleSubmit = (e) => {
@@ -43,6 +53,7 @@ const Form = ({ name = "", url = "", options = [], type = "", styles, handleChan
4353
options={options}
4454
styles={styles}
4555
disabled={disabled ? true : false}
56+
caseInsensitive={caseInsensitive}
4657
/>
4758
<button>Submit</button>
4859
</form>
@@ -767,4 +778,85 @@ test("Input value should update if changed -- client", async () => {
767778
expect(countryAnnouncement).not.toHaveTextContent(
768779
"3 suggestions displayed. To navigate, use up and down arrow keys."
769780
);
781+
});
782+
describe("Client version should perform case-insensitive matche if caseInsensitive is true", async () => {
783+
test("when options are strings", () => {
784+
const options = ["abba", "ABB", "aBbott", "Abberette"];
785+
render(<Form options={options} name="Name" caseInsensitive={true} />);
786+
const input = screen.getByRole("textbox", { name: "Name" });
787+
fireEvent.change(input, { target: { value: "Abb" } });
788+
expect(screen.getByRole("option", { name: "abba" }));
789+
expect(screen.getByRole("option", { name: "ABB" }));
790+
expect(screen.getByRole("option", { name: "aBbott" }));
791+
expect(screen.getByRole("option", { name: "Abberette" }));
792+
});
793+
test("when options are objects", () => {
794+
const options = [
795+
{ name: "abba", value: "abba" },
796+
{ name: "ABB", value: "ABB" },
797+
{ name: "aBbott", value: "aBbott" },
798+
{ name: "Abberette", value: "Abberette" }
799+
];
800+
render(<Form options={options} name="Name" caseInsensitive={true} />);
801+
const input = screen.getByRole("textbox", { name: "Name" });
802+
fireEvent.change(input, { target: { value: "Abb" } });
803+
expect(screen.getByRole("option", { name: "abba" }));
804+
expect(screen.getByRole("option", { name: "ABB" }));
805+
expect(screen.getByRole("option", { name: "aBbott" }));
806+
expect(screen.getByRole("option", { name: "Abberette" }));
807+
});
808+
});
809+
describe("Client version should perform case-insensitive match by default", async () => {
810+
test("when options are strings", () => {
811+
const options = ["abba", "ABB", "aBbott", "Abberette"];
812+
render(<Form options={options} name="Name" />);
813+
const input = screen.getByRole("textbox", { name: "Name" });
814+
fireEvent.change(input, { target: { value: "Abb" } });
815+
expect(screen.getByRole("option", { name: "abba" }));
816+
expect(screen.getByRole("option", { name: "ABB" }));
817+
expect(screen.getByRole("option", { name: "aBbott" }));
818+
expect(screen.getByRole("option", { name: "Abberette" }));
819+
});
820+
test("when options are objects", () => {
821+
const options = [
822+
{ name: "abba", value: "abba" },
823+
{ name: "ABB", value: "ABB" },
824+
{ name: "aBbott", value: "aBbott" },
825+
{ name: "Abberette", value: "Abberette" }
826+
];
827+
render(<Form options={options} name="Name" />);
828+
const input = screen.getByRole("textbox", { name: "Name" });
829+
fireEvent.change(input, { target: { value: "Abb" } });
830+
expect(screen.getByRole("option", { name: "abba" }));
831+
expect(screen.getByRole("option", { name: "ABB" }));
832+
expect(screen.getByRole("option", { name: "aBbott" }));
833+
expect(screen.getByRole("option", { name: "Abberette" }));
834+
});
835+
});
836+
describe("Client version should not perform case-insensitive matches if caseInsensitive is false", async () => {
837+
test("when options are strings", () => {
838+
const options = ["abba", "ABB", "aBbott", "Abberette"];
839+
render(<Form options={options} name="Name" caseInsensitive={false} />);
840+
const input = screen.getByRole("textbox", { name: "Name" });
841+
fireEvent.change(input, { target: { value: "a" } });
842+
expect(screen.getByRole("option", { name: "abba" }));
843+
expect(screen.getByRole("option", { name: "aBbott" }));
844+
expect(screen.queryByRole("option", { name: "ABB" })).toBeNull();
845+
expect(screen.queryByRole("option", { name: "Abberette" })).toBeNull();
846+
});
847+
test("when options are objects", () => {
848+
const options = [
849+
{ name: "abba", value: "abba" },
850+
{ name: "ABB", value: "ABB" },
851+
{ name: "aBbott", value: "aBbott" },
852+
{ name: "Abberette", value: "Abberette" }
853+
];
854+
render(<Form options={options} name="Name" caseInsensitive={false} />);
855+
const input = screen.getByRole("textbox", { name: "Name" });
856+
fireEvent.change(input, { target: { value: "a" } });
857+
expect(screen.getByRole("option", { name: "abba" }));
858+
expect(screen.getByRole("option", { name: "aBbott" }));
859+
expect(screen.queryByRole("option", { name: "ABB" })).toBeNull();
860+
expect(screen.queryByRole("option", { name: "Abberette" })).toBeNull();
861+
});
770862
});

0 commit comments

Comments
 (0)