@jobber/components-native 0.27.0 → 0.28.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/dist/src/InputSearch/InputSearch.js +28 -0
- package/dist/src/InputSearch/InputSearch.style.js +8 -0
- package/dist/src/InputSearch/components/FilterButton.js +9 -0
- package/dist/src/InputSearch/index.js +2 -0
- package/dist/src/index.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/src/InputSearch/InputSearch.d.ts +24 -0
- package/dist/types/src/InputSearch/InputSearch.style.d.ts +6 -0
- package/dist/types/src/InputSearch/components/FilterButton.d.ts +7 -0
- package/dist/types/src/InputSearch/index.d.ts +3 -0
- package/dist/types/src/index.d.ts +1 -0
- package/package.json +4 -2
- package/src/InputSearch/InputSearch.style.ts +9 -0
- package/src/InputSearch/InputSearch.test.tsx +77 -0
- package/src/InputSearch/InputSearch.tsx +71 -0
- package/src/InputSearch/components/FilterButton.tsx +24 -0
- package/src/InputSearch/index.ts +3 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { InputTextProps, InputTextRef } from "../InputText";
|
|
3
|
+
export declare const InputSearch: React.ForwardRefExoticComponent<InputSearchProps & React.RefAttributes<InputTextRef>>;
|
|
4
|
+
export interface InputSearchProps extends Pick<InputTextProps, "accessibilityHint" | "accessibilityLabel" | "autoFocus" | "placeholder" | "prefix"> {
|
|
5
|
+
/**
|
|
6
|
+
* A callback function that handles the update of the new value of the property value.
|
|
7
|
+
*/
|
|
8
|
+
readonly onChange: (newValue: string) => void;
|
|
9
|
+
/**
|
|
10
|
+
* A callback function that handles the API call to search the value. This is where the
|
|
11
|
+
* wait value is applied to the debounce function to give a delay in each input and API request.
|
|
12
|
+
*/
|
|
13
|
+
readonly onDebouncedChange: (searchValue: string) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Set the component to a given value
|
|
16
|
+
*/
|
|
17
|
+
readonly value: string;
|
|
18
|
+
/**
|
|
19
|
+
* A numeric value to represents the milliseconds in delaying the function to populate
|
|
20
|
+
* the data source when the 'value' changed.
|
|
21
|
+
* @default 300
|
|
22
|
+
*/
|
|
23
|
+
readonly wait?: number;
|
|
24
|
+
}
|
|
@@ -17,6 +17,7 @@ export * from "./Icon";
|
|
|
17
17
|
export * from "./IconButton";
|
|
18
18
|
export * from "./InputFieldWrapper";
|
|
19
19
|
export * from "./InputPressable";
|
|
20
|
+
export * from "./InputSearch";
|
|
20
21
|
export * from "./InputText";
|
|
21
22
|
export * from "./TextList";
|
|
22
23
|
export * from "./ProgressBar";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"module": "dist/src/index.js",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@jobber/design": "^0.41.3",
|
|
25
25
|
"lodash.chunk": "^4.2.0",
|
|
26
|
+
"lodash.debounce": "^4.0.8",
|
|
26
27
|
"lodash.identity": "^3.0.0",
|
|
27
28
|
"react-hook-form": "^7.30.0",
|
|
28
29
|
"react-intl": "^6.4.2",
|
|
@@ -42,6 +43,7 @@
|
|
|
42
43
|
"@testing-library/react-hooks": "^7.0.2",
|
|
43
44
|
"@testing-library/react-native": "^12.0.1",
|
|
44
45
|
"@types/lodash.chunk": "^4.2.7",
|
|
46
|
+
"@types/lodash.debounce": "^4.0.7",
|
|
45
47
|
"@types/lodash.identity": "^3.0.7",
|
|
46
48
|
"@types/react": "^18.0.28",
|
|
47
49
|
"@types/react-native": "^0.71.6",
|
|
@@ -55,5 +57,5 @@
|
|
|
55
57
|
"react": "^18",
|
|
56
58
|
"react-native": ">=0.69.2"
|
|
57
59
|
},
|
|
58
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "dcb391abbe27fca411efd97be1c7128cde9d749f"
|
|
59
61
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
cleanup,
|
|
4
|
+
fireEvent,
|
|
5
|
+
render,
|
|
6
|
+
waitFor,
|
|
7
|
+
} from "@testing-library/react-native";
|
|
8
|
+
import { useIntl } from "react-intl";
|
|
9
|
+
import { InputSearch } from "./InputSearch";
|
|
10
|
+
import { messages as clearMessages } from "../InputFieldWrapper/components/ClearAction";
|
|
11
|
+
|
|
12
|
+
const accessibilityLabelSearch = "Search";
|
|
13
|
+
const accessibilityHint = "Search clients, properties, quotes, etc.";
|
|
14
|
+
const mockOnChange = jest.fn();
|
|
15
|
+
const mockOnDebouncedChange = jest.fn();
|
|
16
|
+
let searchValue: string;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
mockOnChange.mockReset();
|
|
20
|
+
mockOnDebouncedChange.mockReset();
|
|
21
|
+
searchValue = "";
|
|
22
|
+
});
|
|
23
|
+
afterEach(cleanup);
|
|
24
|
+
|
|
25
|
+
function setup() {
|
|
26
|
+
return render(
|
|
27
|
+
<InputSearch
|
|
28
|
+
accessibilityHint={accessibilityHint}
|
|
29
|
+
accessibilityLabel={accessibilityLabelSearch}
|
|
30
|
+
placeholder={accessibilityHint}
|
|
31
|
+
value={searchValue}
|
|
32
|
+
onChange={mockOnChange}
|
|
33
|
+
onDebouncedChange={mockOnDebouncedChange}
|
|
34
|
+
/>,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe("InputSearch", () => {
|
|
39
|
+
it("renders the search input text", () => {
|
|
40
|
+
const { getByHintText, getByLabelText } = setup();
|
|
41
|
+
|
|
42
|
+
expect(getByLabelText(accessibilityLabelSearch)).toBeDefined();
|
|
43
|
+
expect(getByHintText(accessibilityHint)).toBeDefined();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("passes the correct search value to onChange when the value changed", () => {
|
|
47
|
+
const { getByLabelText } = setup();
|
|
48
|
+
const inputSearch = getByLabelText(accessibilityLabelSearch);
|
|
49
|
+
|
|
50
|
+
fireEvent.changeText(inputSearch, "Apollo Client");
|
|
51
|
+
expect(mockOnChange).toHaveBeenCalledWith("Apollo Client");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("passes the correcet search value to onDebouncedChange when the value changed", async () => {
|
|
55
|
+
const { getByLabelText } = setup();
|
|
56
|
+
const inputSearch = getByLabelText(accessibilityLabelSearch);
|
|
57
|
+
|
|
58
|
+
await waitFor(() => {
|
|
59
|
+
fireEvent.changeText(inputSearch, "Update Apollo Client");
|
|
60
|
+
expect(mockOnDebouncedChange).toHaveBeenCalled();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("clears the search value when the clear button is pressed", () => {
|
|
65
|
+
searchValue = "test search value";
|
|
66
|
+
const { formatMessage } = useIntl();
|
|
67
|
+
const { getByLabelText } = setup();
|
|
68
|
+
|
|
69
|
+
fireEvent(getByLabelText(accessibilityLabelSearch), "focus");
|
|
70
|
+
|
|
71
|
+
const inputSearchClearButton = getByLabelText(
|
|
72
|
+
formatMessage(clearMessages.clearTextLabel),
|
|
73
|
+
);
|
|
74
|
+
fireEvent.press(inputSearchClearButton);
|
|
75
|
+
expect(mockOnChange).toHaveBeenCalledWith("");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React, { Ref, forwardRef, useEffect } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import debounce from "lodash.debounce";
|
|
4
|
+
import { styles } from "./InputSearch.style";
|
|
5
|
+
import { InputText, InputTextProps, InputTextRef } from "../InputText";
|
|
6
|
+
|
|
7
|
+
export const InputSearch = forwardRef(SearchInputInternal);
|
|
8
|
+
|
|
9
|
+
export interface InputSearchProps
|
|
10
|
+
extends Pick<
|
|
11
|
+
InputTextProps,
|
|
12
|
+
| "accessibilityHint"
|
|
13
|
+
| "accessibilityLabel"
|
|
14
|
+
| "autoFocus"
|
|
15
|
+
| "placeholder"
|
|
16
|
+
| "prefix"
|
|
17
|
+
> {
|
|
18
|
+
/**
|
|
19
|
+
* A callback function that handles the update of the new value of the property value.
|
|
20
|
+
*/
|
|
21
|
+
readonly onChange: (newValue: string) => void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A callback function that handles the API call to search the value. This is where the
|
|
25
|
+
* wait value is applied to the debounce function to give a delay in each input and API request.
|
|
26
|
+
*/
|
|
27
|
+
readonly onDebouncedChange: (searchValue: string) => void;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Set the component to a given value
|
|
31
|
+
*/
|
|
32
|
+
readonly value: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A numeric value to represents the milliseconds in delaying the function to populate
|
|
36
|
+
* the data source when the 'value' changed.
|
|
37
|
+
* @default 300
|
|
38
|
+
*/
|
|
39
|
+
readonly wait?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function SearchInputInternal(
|
|
43
|
+
{
|
|
44
|
+
onChange,
|
|
45
|
+
onDebouncedChange,
|
|
46
|
+
wait = 300,
|
|
47
|
+
value,
|
|
48
|
+
...inputTextProps
|
|
49
|
+
}: InputSearchProps,
|
|
50
|
+
ref: Ref<InputTextRef>,
|
|
51
|
+
) {
|
|
52
|
+
const delayedSearch = debounce(onDebouncedChange, wait);
|
|
53
|
+
const handleChange = (newValue = "") => onChange(newValue);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
delayedSearch(value);
|
|
57
|
+
return delayedSearch.cancel;
|
|
58
|
+
}, [value, delayedSearch]);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<View style={styles.container}>
|
|
62
|
+
<InputText
|
|
63
|
+
{...inputTextProps}
|
|
64
|
+
autoCorrect={false}
|
|
65
|
+
onChangeText={handleChange}
|
|
66
|
+
ref={ref}
|
|
67
|
+
value={value}
|
|
68
|
+
/>
|
|
69
|
+
</View>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Keyboard } from "react-native";
|
|
3
|
+
import { IconButton } from "../../IconButton";
|
|
4
|
+
|
|
5
|
+
interface FilterButtonProps {
|
|
6
|
+
readonly accessibilityLabel: string;
|
|
7
|
+
readonly onClick: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function FilterButton({
|
|
11
|
+
accessibilityLabel,
|
|
12
|
+
onClick,
|
|
13
|
+
}: FilterButtonProps): JSX.Element {
|
|
14
|
+
return (
|
|
15
|
+
<IconButton
|
|
16
|
+
onPress={() => {
|
|
17
|
+
onClick();
|
|
18
|
+
Keyboard.dismiss();
|
|
19
|
+
}}
|
|
20
|
+
name="filter"
|
|
21
|
+
accessibilityLabel={accessibilityLabel}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from "./Icon";
|
|
|
17
17
|
export * from "./IconButton";
|
|
18
18
|
export * from "./InputFieldWrapper";
|
|
19
19
|
export * from "./InputPressable";
|
|
20
|
+
export * from "./InputSearch";
|
|
20
21
|
export * from "./InputText";
|
|
21
22
|
export * from "./TextList";
|
|
22
23
|
export * from "./ProgressBar";
|