@cerebruminc/cerebellum 20.0.4 → 20.0.5
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/components/Form/fields/AddressField/AddressField.mdx +7 -0
- package/src/components/Form/fields/AddressField/AddressField.test.tsx +94 -1
- package/src/components/Form/fields/AddressField/AddressField.tsx +17 -1
- package/src/components/Form/mocks/fields.tsx +2 -1
- package/src/components/Form/types.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# react-component-lib-boilerplate
|
|
2
2
|
|
|
3
|
+
## [20.0.5](https://github.com/cerebruminc/cerebellum/compare/v20.0.4...v20.0.5) (2026-08-14)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* automatically map secondary address fields ([40b046b](https://github.com/cerebruminc/cerebellum/commit/40b046b082855cf4be00d97940a6166f74722a6b))
|
|
9
|
+
|
|
3
10
|
## [20.0.4](https://github.com/cerebruminc/cerebellum/compare/v20.0.3...v20.0.4) (2026-08-12)
|
|
4
11
|
|
|
5
12
|
|
package/package.json
CHANGED
|
@@ -58,6 +58,7 @@ const Example = ({ submit }) => {
|
|
|
58
58
|
| onChange | function | Called when the value is changed & returns the event | -- |
|
|
59
59
|
| placeholder | string | Placeholder text. Make it descriptive | -- |
|
|
60
60
|
| restrictToCountry | string | The country code to restrict the search to. You can allow all international addresses by passing, `""` | "USA" |
|
|
61
|
+
| secondaryAddressFieldName | string | `name` for a linked field. When an address is selected, it updates the field with Google's apartment, unit, or suite value. | -- |
|
|
61
62
|
| stateAbbrFieldName | string | `name` for a linked field. When and address is selected, it will update the associated field with the state abbreviation. | -- |
|
|
62
63
|
| stateFieldName | string | `name` for a linked field. When and address is selected, it will update the associated field with the state. | -- |
|
|
63
64
|
| streetAddressOnly | boolean | Only shows the street address. `false` shows city, state, and country. Recommend `true` if using separate state, city, or other fields. | false |
|
|
@@ -80,11 +81,17 @@ const Example = ({ submit }) => {
|
|
|
80
81
|
type: FormFieldTypeEnum.Address,
|
|
81
82
|
options: {
|
|
82
83
|
cityFieldName: "city",
|
|
84
|
+
secondaryAddressFieldName: "addressLineTwo",
|
|
83
85
|
stateAbbrFieldName: "state",
|
|
84
86
|
streetAddressOnly: true,
|
|
85
87
|
zipFieldName: "zip",
|
|
86
88
|
},
|
|
87
89
|
},
|
|
90
|
+
{
|
|
91
|
+
fieldLabel: "Suite/Apt/etc",
|
|
92
|
+
name: "addressLineTwo",
|
|
93
|
+
type: FormFieldTypeEnum.Text,
|
|
94
|
+
},
|
|
88
95
|
{
|
|
89
96
|
fieldLabel: "City",
|
|
90
97
|
name: "city",
|
|
@@ -1,8 +1,54 @@
|
|
|
1
|
-
import { render, screen } from "@testing-library/react";
|
|
1
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
2
2
|
import { Form } from "../..";
|
|
3
3
|
import { withTheme } from "../../../../hocs/withTheme";
|
|
4
4
|
import { FormFieldTypeEnum } from "../../types";
|
|
5
5
|
|
|
6
|
+
jest.mock("../../../AddressInput", () => {
|
|
7
|
+
const React = require("react");
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
AddressInput: ({ inputLabel, onChange, placeholder }: any) => (
|
|
11
|
+
<label>
|
|
12
|
+
{inputLabel}
|
|
13
|
+
<input placeholder={placeholder} />
|
|
14
|
+
<button
|
|
15
|
+
onClick={() =>
|
|
16
|
+
onChange(
|
|
17
|
+
{ target: { value: "415 East Irving Park Road", name: "addressLineOne" } },
|
|
18
|
+
{
|
|
19
|
+
city: "Chicago",
|
|
20
|
+
postalCode: "60613",
|
|
21
|
+
rawAddressObject: {},
|
|
22
|
+
secondaryAddress: "APT 2N",
|
|
23
|
+
stateAbbreviation: "IL",
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
type="button"
|
|
28
|
+
>
|
|
29
|
+
Select address
|
|
30
|
+
</button>
|
|
31
|
+
<button
|
|
32
|
+
onClick={() =>
|
|
33
|
+
onChange(
|
|
34
|
+
{ target: { value: "415 East Irving Park Road", name: "addressLineOne" } },
|
|
35
|
+
{
|
|
36
|
+
city: "Chicago",
|
|
37
|
+
postalCode: "60613",
|
|
38
|
+
rawAddressObject: {},
|
|
39
|
+
stateAbbreviation: "IL",
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
type="button"
|
|
44
|
+
>
|
|
45
|
+
Select address without unit
|
|
46
|
+
</button>
|
|
47
|
+
</label>
|
|
48
|
+
),
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
6
52
|
const ThemedForm = withTheme(Form);
|
|
7
53
|
|
|
8
54
|
const addressOnly = [
|
|
@@ -28,4 +74,51 @@ describe("AddressField", () => {
|
|
|
28
74
|
const label = screen.getByPlaceholderText(addressOnly[0].options.placeholder);
|
|
29
75
|
expect(label).toBeInTheDocument();
|
|
30
76
|
});
|
|
77
|
+
|
|
78
|
+
test("maps the Google secondary address to the configured form field", async () => {
|
|
79
|
+
const fields = [
|
|
80
|
+
{
|
|
81
|
+
fieldLabel: "Address",
|
|
82
|
+
name: "addressLineOne",
|
|
83
|
+
type: FormFieldTypeEnum.Address,
|
|
84
|
+
options: {
|
|
85
|
+
secondaryAddressFieldName: "addressLineTwo",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
fieldLabel: "Suite/Apt/etc",
|
|
90
|
+
name: "addressLineTwo",
|
|
91
|
+
type: FormFieldTypeEnum.Text,
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
render(<ThemedForm fields={fields} submit={() => {}} />);
|
|
96
|
+
fireEvent.click(screen.getByRole("button", { name: "Select address" }));
|
|
97
|
+
|
|
98
|
+
expect(await screen.findByDisplayValue("APT 2N")).toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("preserves the configured form field when Google does not return a secondary address", () => {
|
|
102
|
+
const fields = [
|
|
103
|
+
{
|
|
104
|
+
fieldLabel: "Address",
|
|
105
|
+
name: "addressLineOne",
|
|
106
|
+
type: FormFieldTypeEnum.Address,
|
|
107
|
+
options: {
|
|
108
|
+
secondaryAddressFieldName: "addressLineTwo",
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
fieldLabel: "Suite/Apt/etc",
|
|
113
|
+
initialValue: "Unit 4",
|
|
114
|
+
name: "addressLineTwo",
|
|
115
|
+
type: FormFieldTypeEnum.Text,
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
render(<ThemedForm fields={fields} submit={() => {}} />);
|
|
120
|
+
fireEvent.click(screen.getByRole("button", { name: "Select address without unit" }));
|
|
121
|
+
|
|
122
|
+
expect(screen.getByDisplayValue("Unit 4")).toBeInTheDocument();
|
|
123
|
+
});
|
|
31
124
|
});
|
|
@@ -24,7 +24,17 @@ export const AddressField: FC<AddressFieldProps> = ({
|
|
|
24
24
|
|
|
25
25
|
const { setFieldError } = useFormikContext();
|
|
26
26
|
|
|
27
|
-
const {
|
|
27
|
+
const {
|
|
28
|
+
cityFieldName,
|
|
29
|
+
countryFieldName,
|
|
30
|
+
helperText,
|
|
31
|
+
onInputBlur,
|
|
32
|
+
onChange,
|
|
33
|
+
secondaryAddressFieldName,
|
|
34
|
+
stateAbbrFieldName,
|
|
35
|
+
stateFieldName,
|
|
36
|
+
zipFieldName,
|
|
37
|
+
} = options;
|
|
28
38
|
const showValidationMessage = (touched[name] || submitAttempt) && !!errors[name];
|
|
29
39
|
const validationMessage = errors[name];
|
|
30
40
|
const InputWrap = leftLabels ? InputBox : Fragment;
|
|
@@ -66,6 +76,12 @@ export const AddressField: FC<AddressFieldProps> = ({
|
|
|
66
76
|
handleChange({ target: { value: addressObject.country, name: countryFieldName } });
|
|
67
77
|
setTimeout(() => setFieldError(countryFieldName, undefined), 1);
|
|
68
78
|
}
|
|
79
|
+
if (secondaryAddressFieldName && addressObject.secondaryAddress) {
|
|
80
|
+
handleChange({
|
|
81
|
+
target: { value: addressObject.secondaryAddress, name: secondaryAddressFieldName },
|
|
82
|
+
});
|
|
83
|
+
setTimeout(() => setFieldError(secondaryAddressFieldName, undefined), 1);
|
|
84
|
+
}
|
|
69
85
|
if (stateAbbrFieldName) {
|
|
70
86
|
handleChange({ target: { value: addressObject.stateAbbreviation, name: stateAbbrFieldName } });
|
|
71
87
|
setTimeout(() => setFieldError(stateAbbrFieldName, undefined), 1);
|
|
@@ -39,6 +39,7 @@ export const addressFields = [
|
|
|
39
39
|
required: true,
|
|
40
40
|
options: {
|
|
41
41
|
cityFieldName: "city",
|
|
42
|
+
secondaryAddressFieldName: "suiteAptEtc",
|
|
42
43
|
stateAbbrFieldName: "state",
|
|
43
44
|
stateFieldName: "fullState",
|
|
44
45
|
streetAddressOnly: true,
|
|
@@ -47,7 +48,7 @@ export const addressFields = [
|
|
|
47
48
|
},
|
|
48
49
|
{
|
|
49
50
|
fieldLabel: "Suite/Apt/etc",
|
|
50
|
-
name: "
|
|
51
|
+
name: "suiteAptEtc",
|
|
51
52
|
initialValue: "",
|
|
52
53
|
type: FormFieldTypeEnum.Text,
|
|
53
54
|
},
|
|
@@ -226,6 +226,7 @@ export interface AddressOptionsType {
|
|
|
226
226
|
onChange?: (event: { target: { value: string; name?: string } }, addressObject?: AddressDetailsType) => void;
|
|
227
227
|
placeholder?: string;
|
|
228
228
|
restrictToCountry?: string;
|
|
229
|
+
secondaryAddressFieldName?: string;
|
|
229
230
|
stateAbbrFieldName?: string;
|
|
230
231
|
stateFieldName?: string;
|
|
231
232
|
streetAddressOnly?: boolean;
|