@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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerebruminc/cerebellum",
3
- "version": "20.0.4",
3
+ "version": "20.0.5",
4
4
  "description": "Cerebrum's React Component Library",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -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 { cityFieldName, countryFieldName, helperText, onInputBlur, onChange, stateAbbrFieldName, stateFieldName, zipFieldName } = options;
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: "Suite/Apt/etc",
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;