@nuskin/shipping-address-form 1.5.0 → 1.6.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.
Files changed (96) hide show
  1. package/README.md +30 -10
  2. package/dist/addressLookup/AddressLookup.js +70 -0
  3. package/dist/addressLookup/AddressLookup.js.map +1 -0
  4. package/dist/addressLookup/components/LocationPinIcon.js +33 -0
  5. package/dist/addressLookup/components/LocationPinIcon.js.map +1 -0
  6. package/dist/addressLookup/components/SmartyIntlResults.js +999 -0
  7. package/dist/addressLookup/components/SmartyIntlResults.js.map +1 -0
  8. package/dist/addressLookup/components/SmartyUSResults.js +980 -0
  9. package/dist/addressLookup/components/SmartyUSResults.js.map +1 -0
  10. package/dist/addressLookup/config/address/countries.js +61 -0
  11. package/dist/addressLookup/config/address/countries.js.map +1 -0
  12. package/dist/addressLookup/config/address/index.js +19 -0
  13. package/dist/addressLookup/config/address/index.js.map +1 -0
  14. package/dist/addressLookup/config/googleMaps.js +12 -0
  15. package/dist/addressLookup/config/googleMaps.js.map +1 -0
  16. package/dist/addressLookup/countries.js +19 -0
  17. package/dist/addressLookup/countries.js.map +1 -0
  18. package/dist/addressLookup/hooks/useAddressFieldLabels.js +41 -0
  19. package/dist/addressLookup/hooks/useAddressFieldLabels.js.map +1 -0
  20. package/dist/addressLookup/hooks/useAddressForm.js +36 -0
  21. package/dist/addressLookup/hooks/useAddressForm.js.map +1 -0
  22. package/dist/addressLookup/hooks/useAddressMapModal.js +136 -0
  23. package/dist/addressLookup/hooks/useAddressMapModal.js.map +1 -0
  24. package/dist/addressLookup/hooks/useAddressValidationBase.js +143 -0
  25. package/dist/addressLookup/hooks/useAddressValidationBase.js.map +1 -0
  26. package/dist/addressLookup/hooks/useInitialAddressVerification.js +57 -0
  27. package/dist/addressLookup/hooks/useInitialAddressVerification.js.map +1 -0
  28. package/dist/addressLookup/hooks/useIntlAddressValidation.js +122 -0
  29. package/dist/addressLookup/hooks/useIntlAddressValidation.js.map +1 -0
  30. package/dist/addressLookup/hooks/useSmartyInternationalLookup.js +74 -0
  31. package/dist/addressLookup/hooks/useSmartyInternationalLookup.js.map +1 -0
  32. package/dist/addressLookup/hooks/useSmartyLookupBase.js +152 -0
  33. package/dist/addressLookup/hooks/useSmartyLookupBase.js.map +1 -0
  34. package/dist/addressLookup/hooks/useSmartyUSLookup.js +79 -0
  35. package/dist/addressLookup/hooks/useSmartyUSLookup.js.map +1 -0
  36. package/dist/addressLookup/hooks/useUSAddressValidation.js +166 -0
  37. package/dist/addressLookup/hooks/useUSAddressValidation.js.map +1 -0
  38. package/dist/addressLookup/index.js +41 -0
  39. package/dist/addressLookup/index.js.map +1 -0
  40. package/dist/addressLookup/styles/addressLookup.css +374 -0
  41. package/dist/addressLookup/utils/addressForm.js +150 -0
  42. package/dist/addressLookup/utils/addressForm.js.map +1 -0
  43. package/dist/addressLookup/utils/addressMapping.js +190 -0
  44. package/dist/addressLookup/utils/addressMapping.js.map +1 -0
  45. package/dist/addressLookup/utils/addressStatus.js +173 -0
  46. package/dist/addressLookup/utils/addressStatus.js.map +1 -0
  47. package/dist/addressLookup/utils/addressStrings.js +159 -0
  48. package/dist/addressLookup/utils/addressStrings.js.map +1 -0
  49. package/dist/addressLookup/utils/addressVerification.js +66 -0
  50. package/dist/addressLookup/utils/addressVerification.js.map +1 -0
  51. package/dist/addressLookup/utils/addressWrapper.js +40 -0
  52. package/dist/addressLookup/utils/addressWrapper.js.map +1 -0
  53. package/dist/addressLookup/utils/componentPropTypes.js +118 -0
  54. package/dist/addressLookup/utils/componentPropTypes.js.map +1 -0
  55. package/dist/addressLookup/utils/googleMapsLoader.js +68 -0
  56. package/dist/addressLookup/utils/googleMapsLoader.js.map +1 -0
  57. package/dist/addressLookup/utils/inFlightRequests.js +50 -0
  58. package/dist/addressLookup/utils/inFlightRequests.js.map +1 -0
  59. package/dist/addressLookup/utils/intlAutocompleteBusinessRules.js +62 -0
  60. package/dist/addressLookup/utils/intlAutocompleteBusinessRules.js.map +1 -0
  61. package/dist/addressLookup/utils/requestCache.js +44 -0
  62. package/dist/addressLookup/utils/requestCache.js.map +1 -0
  63. package/dist/addressLookup/utils/requestRateLimiter.js +53 -0
  64. package/dist/addressLookup/utils/requestRateLimiter.js.map +1 -0
  65. package/dist/addressLookup/utils/smartyConfig.js +11 -0
  66. package/dist/addressLookup/utils/smartyConfig.js.map +1 -0
  67. package/dist/addressLookup/utils/validators.js +45 -0
  68. package/dist/addressLookup/utils/validators.js.map +1 -0
  69. package/dist/index.js +28 -1
  70. package/dist/index.js.map +1 -1
  71. package/dist/{ShippingAddressForm.js → shippingAddressForm/ShippingAddressForm.js} +2 -2
  72. package/dist/shippingAddressForm/ShippingAddressForm.js.map +1 -0
  73. package/dist/{components → shippingAddressForm/components}/ShippingField.js +32 -22
  74. package/dist/shippingAddressForm/components/ShippingField.js.map +1 -0
  75. package/dist/shippingAddressForm/hooks/useAddressFieldLabels.js.map +1 -0
  76. package/dist/shippingAddressForm/hooks/useShippingAddressForm.js.map +1 -0
  77. package/dist/{hooks → shippingAddressForm/hooks}/useShippingFormState.js +5 -0
  78. package/dist/shippingAddressForm/hooks/useShippingFormState.js.map +1 -0
  79. package/dist/shippingAddressForm/utils/emailVerify.js.map +1 -0
  80. package/dist/{utils → shippingAddressForm/utils}/shippingAddressForm.js +3 -3
  81. package/dist/shippingAddressForm/utils/shippingAddressForm.js.map +1 -0
  82. package/dist/shippingAddressForm/utils/shippingStrings.js.map +1 -0
  83. package/package.json +2 -3
  84. package/dist/ShippingAddressForm.js.map +0 -1
  85. package/dist/components/ShippingField.js.map +0 -1
  86. package/dist/hooks/useAddressFieldLabels.js.map +0 -1
  87. package/dist/hooks/useShippingAddressForm.js.map +0 -1
  88. package/dist/hooks/useShippingFormState.js.map +0 -1
  89. package/dist/utils/emailVerify.js.map +0 -1
  90. package/dist/utils/shippingAddressForm.js.map +0 -1
  91. package/dist/utils/shippingStrings.js.map +0 -1
  92. /package/dist/{hooks → shippingAddressForm/hooks}/useAddressFieldLabels.js +0 -0
  93. /package/dist/{hooks → shippingAddressForm/hooks}/useShippingAddressForm.js +0 -0
  94. /package/dist/{styles → shippingAddressForm/styles}/shippingAddressForm.css +0 -0
  95. /package/dist/{utils → shippingAddressForm/utils}/emailVerify.js +0 -0
  96. /package/dist/{utils → shippingAddressForm/utils}/shippingStrings.js +0 -0
@@ -0,0 +1,980 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _propTypes = _interopRequireDefault(require("prop-types"));
8
+ var _react = require("react");
9
+ var _useSmartyUSLookup = _interopRequireDefault(require("../hooks/useSmartyUSLookup"));
10
+ var _useUSAddressValidation = _interopRequireDefault(require("../hooks/useUSAddressValidation"));
11
+ var _useAddressFieldLabels = _interopRequireDefault(require("../hooks/useAddressFieldLabels"));
12
+ var _useAddressForm = _interopRequireDefault(require("../hooks/useAddressForm"));
13
+ var _useInitialAddressVerification = _interopRequireDefault(require("../hooks/useInitialAddressVerification"));
14
+ var _useAddressMapModal = _interopRequireDefault(require("../hooks/useAddressMapModal"));
15
+ var _addressMapping = require("../utils/addressMapping");
16
+ var _addressWrapper = require("../utils/addressWrapper");
17
+ var _addressStatus = require("../utils/addressStatus");
18
+ var _addressVerification = require("../utils/addressVerification");
19
+ var _validators = require("../utils/validators");
20
+ var _componentPropTypes = require("../utils/componentPropTypes");
21
+ var _LocationPinIcon = _interopRequireDefault(require("./LocationPinIcon"));
22
+ var _foundationUiComponents = require("@nuskin/foundation-ui-components");
23
+ var _jsxRuntime = require("react/jsx-runtime");
24
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
25
+ const stripGeocode = (address = {}) => {
26
+ const nextAddress = {
27
+ ...address
28
+ };
29
+ delete nextAddress.latitude;
30
+ delete nextAddress.longitude;
31
+ return nextAddress;
32
+ };
33
+ const FIELD_TEST_IDS = {
34
+ address1: 'qa-address-1',
35
+ address2: 'qa-address-2',
36
+ district: 'qa-address-district',
37
+ region: 'qa-address-region',
38
+ city: 'qa-address-city',
39
+ postalCode: 'qa-address-postal-code'
40
+ };
41
+ const FIELD_IDS = {
42
+ address1: 'address-line-1',
43
+ address2: 'address-line-2',
44
+ district: 'address-district',
45
+ region: 'address-region',
46
+ city: 'address-city',
47
+ postalCode: 'address-postal-code'
48
+ };
49
+ const getFieldTestId = field => FIELD_TEST_IDS[field] || `qa-address-${field}`;
50
+ const getFieldId = field => FIELD_IDS[field] || `address-${field}`;
51
+ const LOOKUP_LIST_BUTTON_SELECTOR = '.ns-address-lookup__list-button';
52
+ const SmartyUSResults = ({
53
+ onSelect,
54
+ initialAddress = null,
55
+ requireValidation = true,
56
+ readOnlyView = false,
57
+ showManualValidateButton = false,
58
+ validationRequestId = 0,
59
+ language = 'en',
60
+ strings = null,
61
+ formDefinition = null,
62
+ deferFormLookup = false
63
+ }) => {
64
+ var _formDefinition$addre;
65
+ const [mode, setMode] = (0, _react.useState)('autocomplete');
66
+ const [query, setQuery] = (0, _react.useState)('');
67
+ const [selectedAddress, setSelectedAddress] = (0, _react.useState)(null);
68
+ const [selectedUSAddress, setSelectedUSAddress] = (0, _react.useState)(null);
69
+ const [formData, setFormData] = (0, _react.useState)(initialAddress || {});
70
+ const [verificationStatus, setVerificationStatus] = (0, _react.useState)((0, _addressVerification.getIncomingVerificationStatus)(initialAddress));
71
+ const [validationTrigger, setValidationTrigger] = (0, _react.useState)(0);
72
+ const [validationTriggerSource, setValidationTriggerSource] = (0, _react.useState)(null);
73
+ const [showValidationSuggestions, setShowValidationSuggestions] = (0, _react.useState)(false);
74
+ const [mapAddressLines, setMapAddressLines] = (0, _react.useState)([]);
75
+ const [hasPendingLookupDraft, setHasPendingLookupDraft] = (0, _react.useState)(false);
76
+ const [touchedFields, setTouchedFields] = (0, _react.useState)({});
77
+ const [showAllRequiredErrors, setShowAllRequiredErrors] = (0, _react.useState)(false);
78
+ const [lookupServiceError, setLookupServiceError] = (0, _react.useState)(null);
79
+ const [validationServiceError, setValidationServiceError] = (0, _react.useState)(null);
80
+ const shouldSearchRef = (0, _react.useRef)(true);
81
+ const fieldTimerRef = (0, _react.useRef)(null);
82
+ const componentRef = (0, _react.useRef)(null);
83
+ const suggestionsListRef = (0, _react.useRef)(null);
84
+ const lastCommittedAddressRef = (0, _react.useRef)(initialAddress || {});
85
+ const lookupDraftOriginalRef = (0, _react.useRef)(initialAddress || {});
86
+ const appliedSelectionKeyRef = (0, _react.useRef)(null);
87
+ const mapValidationStartedRef = (0, _react.useRef)(false);
88
+ const autoApplyValidationStartedRef = (0, _react.useRef)(false);
89
+ const hasInitializedAddressRef = (0, _react.useRef)(false);
90
+ (0, _react.useEffect)(() => {
91
+ if (!initialAddress || hasInitializedAddressRef.current) {
92
+ return;
93
+ }
94
+ hasInitializedAddressRef.current = true;
95
+ setFormData(initialAddress);
96
+ setVerificationStatus((0, _addressVerification.getIncomingVerificationStatus)(initialAddress));
97
+ shouldSearchRef.current = false;
98
+ lastCommittedAddressRef.current = initialAddress;
99
+ lookupDraftOriginalRef.current = initialAddress;
100
+ setTouchedFields({});
101
+ setShowAllRequiredErrors(false);
102
+ setLookupServiceError(null);
103
+ setValidationServiceError(null);
104
+ setMapAddressLines([]);
105
+ }, [initialAddress]);
106
+ (0, _react.useEffect)(() => {
107
+ return () => {
108
+ if (fieldTimerRef.current) {
109
+ clearTimeout(fieldTimerRef.current);
110
+ }
111
+ };
112
+ }, []);
113
+ const isAutocompleteMode = mode === 'autocomplete';
114
+ const {
115
+ labels: fieldLabels,
116
+ isLoading: areLabelsLoading
117
+ } = (0, _useAddressFieldLabels.default)('US', language, strings);
118
+ const shouldLoadAddressForm = !formDefinition && !deferFormLookup;
119
+ const {
120
+ addressForm: loadedAddressForm,
121
+ isLoading: isFormLoading
122
+ } = (0, _useAddressForm.default)('US', shouldLoadAddressForm);
123
+ const providedAddressForm = formDefinition !== null && formDefinition !== void 0 && (_formDefinition$addre = formDefinition.addressElements) !== null && _formDefinition$addre !== void 0 && _formDefinition$addre.length ? formDefinition : null;
124
+ const resolvedAddressForm = providedAddressForm || loadedAddressForm;
125
+ const allowValidation = requireValidation && !readOnlyView;
126
+ const lookupField = (resolvedAddressForm === null || resolvedAddressForm === void 0 ? void 0 : resolvedAddressForm.lookupField) || 'address1';
127
+ const requiredFields = (0, _addressStatus.getRequiredFieldsFromAddressForm)(resolvedAddressForm);
128
+ const hasEmailField = ((resolvedAddressForm === null || resolvedAddressForm === void 0 ? void 0 : resolvedAddressForm.addressElements) || []).some(field => field.field === 'email');
129
+ const hasMapCoordinates = (formData === null || formData === void 0 ? void 0 : formData.latitude) !== undefined && (formData === null || formData === void 0 ? void 0 : formData.longitude) !== undefined;
130
+ const hasLookupValue = Boolean(String((formData === null || formData === void 0 ? void 0 : formData[lookupField]) || '').trim());
131
+ const canAttemptMap = Boolean(!isAutocompleteMode && hasLookupValue || isAutocompleteMode && ['autocomplete', 'verified'].includes(verificationStatus) && hasLookupValue);
132
+ const showMapAction = !readOnlyView && (hasMapCoordinates || canAttemptMap);
133
+ const mapInfoLines = (mapAddressLines.length ? mapAddressLines : [formData.address1, formData.address2, [formData.city, formData.region, formData.postalCode].filter(Boolean).join(' ')]).filter(Boolean);
134
+ const {
135
+ mapContainerRef,
136
+ pendingMapOpen,
137
+ setPendingMapOpen,
138
+ setShowMapModal,
139
+ showMapModal
140
+ } = (0, _useAddressMapModal.default)({
141
+ formData,
142
+ infoLines: mapInfoLines,
143
+ hasMapCoordinates,
144
+ openInMapsLabel: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.openInMaps,
145
+ shouldPrepareMap: showMapAction
146
+ });
147
+ const {
148
+ suggestions,
149
+ loading,
150
+ error,
151
+ rateLimited
152
+ } = (0, _useSmartyUSLookup.default)(!readOnlyView && shouldSearchRef.current && isAutocompleteMode ? query : '', selectedUSAddress, 500);
153
+ const {
154
+ suggestions: validationSuggestions,
155
+ loading: validationLoading,
156
+ error: validationError,
157
+ rateLimited: validationRateLimited
158
+ } = (0, _useUSAddressValidation.default)(formData, allowValidation ? validationTrigger : 0);
159
+ const lookupValue = formData[lookupField];
160
+ const lookupErrorMessage = lookupServiceError !== null && lookupServiceError !== void 0 && lookupServiceError.rateLimited ? (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.rateLimited) || 'Too many requests. Please wait a moment and try again.' : (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.lookupError) || 'We could not look up that address right now.';
161
+ const validationErrorMessage = validationServiceError !== null && validationServiceError !== void 0 && validationServiceError.rateLimited ? (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.rateLimited) || 'Too many requests. Please wait a moment and try again.' : (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.validationError) || 'We could not validate that address right now.';
162
+ (0, _react.useEffect)(() => {
163
+ if (!validationRequestId) {
164
+ return;
165
+ }
166
+ setShowAllRequiredErrors(true);
167
+ onSelect === null || onSelect === void 0 || onSelect({
168
+ type: 'validation-request',
169
+ address: formData,
170
+ status: (0, _addressStatus.buildAddressStatus)({
171
+ countryCode: 'US',
172
+ addressForm: resolvedAddressForm,
173
+ formData,
174
+ verificationStatus,
175
+ mode,
176
+ requireValidation: allowValidation
177
+ })
178
+ });
179
+ }, [allowValidation, validationRequestId]);
180
+ (0, _react.useEffect)(() => {
181
+ if (!error) {
182
+ setLookupServiceError(null);
183
+ return;
184
+ }
185
+ setLookupServiceError({
186
+ rateLimited,
187
+ rawMessage: error
188
+ });
189
+ }, [error, rateLimited]);
190
+ (0, _react.useEffect)(() => {
191
+ if (!validationError) {
192
+ setValidationServiceError(null);
193
+ return;
194
+ }
195
+ setValidationServiceError({
196
+ rateLimited: validationRateLimited,
197
+ rawMessage: validationError
198
+ });
199
+ setPendingMapOpen(false);
200
+ mapValidationStartedRef.current = false;
201
+ }, [validationError, validationRateLimited]);
202
+ (0, _react.useEffect)(() => {
203
+ if (!lookupServiceError) {
204
+ return;
205
+ }
206
+ onSelect === null || onSelect === void 0 || onSelect({
207
+ type: 'lookup-error',
208
+ address: formData,
209
+ status: (0, _addressStatus.buildAddressStatus)({
210
+ countryCode: 'US',
211
+ addressForm: resolvedAddressForm,
212
+ formData,
213
+ verificationStatus,
214
+ mode,
215
+ requireValidation: allowValidation
216
+ }),
217
+ error: {
218
+ kind: lookupServiceError.rateLimited ? 'rate-limited' : 'api',
219
+ source: 'autocomplete',
220
+ message: lookupErrorMessage
221
+ }
222
+ });
223
+ }, [lookupServiceError]);
224
+ (0, _react.useEffect)(() => {
225
+ if (!validationServiceError) {
226
+ return;
227
+ }
228
+ onSelect === null || onSelect === void 0 || onSelect({
229
+ type: 'validation-error',
230
+ address: formData,
231
+ status: (0, _addressStatus.buildAddressStatus)({
232
+ countryCode: 'US',
233
+ addressForm: resolvedAddressForm,
234
+ formData,
235
+ verificationStatus,
236
+ mode,
237
+ requireValidation: allowValidation
238
+ }),
239
+ error: {
240
+ kind: validationServiceError.rateLimited ? 'rate-limited' : 'api',
241
+ source: 'validation',
242
+ message: validationErrorMessage
243
+ }
244
+ });
245
+ }, [validationServiceError]);
246
+ const clearServiceErrors = ({
247
+ lookup = true,
248
+ validation = true
249
+ } = {}) => {
250
+ if (lookup) {
251
+ setLookupServiceError(null);
252
+ }
253
+ if (validation) {
254
+ setValidationServiceError(null);
255
+ }
256
+ };
257
+ const stripUnusedEmail = (address = {}) => {
258
+ if (hasEmailField) {
259
+ return address;
260
+ }
261
+ const nextAddress = {
262
+ ...address
263
+ };
264
+ delete nextAddress.email;
265
+ return nextAddress;
266
+ };
267
+ const buildTrackedAddress = (address = {}, status = 'unverified', source = null) => stripUnusedEmail((0, _addressVerification.withAddressVerification)(address, status, source));
268
+ const isAcceptableInitialValidationResult = validatedAddress => Boolean(validatedAddress === null || validatedAddress === void 0 ? void 0 : validatedAddress.isDeliverable);
269
+ const getBestInitialValidationResult = (suggestions = []) => suggestions.find(isAcceptableInitialValidationResult) || null;
270
+ (0, _useInitialAddressVerification.default)({
271
+ initialAddress,
272
+ countryCode: 'US',
273
+ lookupField,
274
+ requireValidation: allowValidation,
275
+ resolvedAddressForm,
276
+ setValidationServiceError,
277
+ setShowValidationSuggestions,
278
+ setValidationTriggerSource,
279
+ setValidationTrigger
280
+ });
281
+ (0, _react.useEffect)(() => {
282
+ if (validationTrigger > 0 && ['autocomplete', 'map', 'initial'].includes(validationTriggerSource)) {
283
+ autoApplyValidationStartedRef.current = false;
284
+ }
285
+ }, [validationTrigger, validationTriggerSource]);
286
+ (0, _react.useEffect)(() => {
287
+ if (validationLoading && validationTriggerSource === 'map') {
288
+ mapValidationStartedRef.current = true;
289
+ }
290
+ if (validationLoading && ['autocomplete', 'map', 'initial'].includes(validationTriggerSource)) {
291
+ autoApplyValidationStartedRef.current = true;
292
+ }
293
+ }, [validationLoading, validationTriggerSource]);
294
+ (0, _react.useEffect)(() => {
295
+ if (validationTriggerSource === 'map' && showValidationSuggestions && !validationLoading && validationSuggestions.length === 0 && !validationServiceError && mapValidationStartedRef.current) {
296
+ setPendingMapOpen(false);
297
+ mapValidationStartedRef.current = false;
298
+ }
299
+ }, [validationLoading, validationSuggestions, validationTriggerSource, showValidationSuggestions, validationServiceError]);
300
+ (0, _react.useEffect)(() => {
301
+ if (lookupValue !== undefined && shouldSearchRef.current && !selectedAddress) {
302
+ setQuery(lookupValue);
303
+ }
304
+ }, [lookupValue, selectedAddress]);
305
+ (0, _react.useEffect)(() => {
306
+ var _suggestionButtons$;
307
+ const shouldShowValidationResults = allowValidation && showValidationSuggestions && validationSuggestions.length > 0 && !validationLoading && (!isAutocompleteMode || validationTriggerSource === 'map');
308
+ if (!shouldShowValidationResults) {
309
+ return;
310
+ }
311
+ const suggestionButtons = getVisibleSuggestionButtons();
312
+ if (suggestionButtons.length === 0 || suggestionButtons.includes(document.activeElement)) {
313
+ return;
314
+ }
315
+ (_suggestionButtons$ = suggestionButtons[0]) === null || _suggestionButtons$ === void 0 || _suggestionButtons$.focus();
316
+ }, [isAutocompleteMode, allowValidation, showValidationSuggestions, validationLoading, validationSuggestions, validationTriggerSource]);
317
+ (0, _react.useEffect)(() => {
318
+ var _getLookupInputElemen;
319
+ const shouldRefocusLookupField = isAutocompleteMode && selectedUSAddress && suggestions.length > 0 && !selectedAddress && !loading;
320
+ if (!shouldRefocusLookupField) {
321
+ return;
322
+ }
323
+ (_getLookupInputElemen = getLookupInputElement()) === null || _getLookupInputElemen === void 0 || _getLookupInputElemen.focus();
324
+ }, [isAutocompleteMode, selectedUSAddress, suggestions, selectedAddress, loading]);
325
+ (0, _react.useEffect)(() => {
326
+ if (!hasPendingLookupDraft || suggestions.length === 0) {
327
+ return undefined;
328
+ }
329
+ const handleDocumentMouseDown = event => {
330
+ const component = componentRef.current;
331
+ if (component !== null && component !== void 0 && component.contains(event.target)) {
332
+ return;
333
+ }
334
+ const suggestionsList = suggestionsListRef.current;
335
+ if ((suggestionsList === null || suggestionsList === void 0 ? void 0 : suggestionsList.contains(event.target)) === false) {
336
+ shouldSearchRef.current = false;
337
+ setQuery('');
338
+ setSelectedAddress(null);
339
+ setSelectedUSAddress(null);
340
+ setShowValidationSuggestions(false);
341
+ setShowMapModal(false);
342
+ setPendingMapOpen(false);
343
+ mapValidationStartedRef.current = false;
344
+ clearServiceErrors();
345
+ setFormData(lookupDraftOriginalRef.current);
346
+ setMapAddressLines([]);
347
+ setHasPendingLookupDraft(false);
348
+ }
349
+ };
350
+ document.addEventListener('pointerdown', handleDocumentMouseDown);
351
+ return () => {
352
+ document.removeEventListener('pointerdown', handleDocumentMouseDown);
353
+ };
354
+ }, [hasPendingLookupDraft, suggestions]);
355
+ (0, _react.useEffect)(() => {
356
+ if (selectedAddress) {
357
+ const selectionKey = selectedAddress.street_line ? `${selectedAddress.street_line}|${selectedAddress.secondary || ''}|${selectedAddress.zipcode || ''}` : JSON.stringify(selectedAddress);
358
+ if (appliedSelectionKeyRef.current === selectionKey) {
359
+ return;
360
+ }
361
+ appliedSelectionKeyRef.current = selectionKey;
362
+ const config = resolvedAddressForm.addressElements || [];
363
+ let mapped = {
364
+ address1: selectedAddress.street_line,
365
+ address2: selectedAddress.secondary || '',
366
+ city: selectedAddress.city,
367
+ region: selectedAddress.state,
368
+ postalCode: selectedAddress.zipcode
369
+ };
370
+
371
+ // Apply address wrapping if enabled
372
+ if (resolvedAddressForm.wrapAddress1ToAddress2) {
373
+ const address1Field = config.find(f => f.field === 'address1');
374
+ if (address1Field !== null && address1Field !== void 0 && address1Field.maxLength) {
375
+ const wrapped = (0, _addressWrapper.wrapAddress1ToAddress2)(mapped.address1, mapped.address2, address1Field.maxLength);
376
+ mapped.address1 = wrapped.address1;
377
+ mapped.address2 = wrapped.address2;
378
+ }
379
+ }
380
+ const updatedFormData = {
381
+ ...stripGeocode(formData),
382
+ ...mapped,
383
+ email: formData.email
384
+ };
385
+ const normalizedFormData = buildTrackedAddress(updatedFormData, 'autocomplete', 'smarty-us');
386
+ setFormData(normalizedFormData);
387
+ setMapAddressLines([]);
388
+ lastCommittedAddressRef.current = normalizedFormData;
389
+ lookupDraftOriginalRef.current = normalizedFormData;
390
+ setHasPendingLookupDraft(false);
391
+ clearServiceErrors();
392
+ const currentVerificationStatus = 'autocomplete';
393
+ setVerificationStatus(currentVerificationStatus);
394
+ onSelect === null || onSelect === void 0 || onSelect({
395
+ type: 'autocomplete',
396
+ address: normalizedFormData,
397
+ status: (0, _addressStatus.buildAddressStatus)({
398
+ countryCode: 'US',
399
+ addressForm: resolvedAddressForm,
400
+ formData: normalizedFormData,
401
+ verificationStatus: currentVerificationStatus,
402
+ mode,
403
+ requireValidation: allowValidation
404
+ })
405
+ });
406
+ }
407
+ }, [selectedAddress]);
408
+ const handleInputChange = e => {
409
+ const value = (0, _validators.normalizeAddressFieldValue)(lookupField, e.target.value);
410
+ shouldSearchRef.current = true;
411
+ appliedSelectionKeyRef.current = null;
412
+ setSelectedAddress(null);
413
+ setSelectedUSAddress(null);
414
+ setShowValidationSuggestions(false);
415
+ setShowMapModal(false);
416
+ setPendingMapOpen(false);
417
+ mapValidationStartedRef.current = false;
418
+ setMapAddressLines([]);
419
+ setValidationTriggerSource(null);
420
+ clearServiceErrors();
421
+ if (!hasPendingLookupDraft) {
422
+ lookupDraftOriginalRef.current = formData;
423
+ setHasPendingLookupDraft(true);
424
+ }
425
+ const updatedLookupData = stripUnusedEmail({
426
+ ...stripGeocode(formData),
427
+ [lookupField]: value
428
+ });
429
+ setFormData(buildTrackedAddress(updatedLookupData, 'unverified'));
430
+ setVerificationStatus('unverified');
431
+ };
432
+ const isFieldRequired = field => requiredFields.includes(field);
433
+ const isFieldBlank = field => String(formData[field] || '').trim() === '';
434
+ const hasInvalidPostalCodeFormat = field => {
435
+ if (field !== 'postalCode') {
436
+ return false;
437
+ }
438
+ const value = String(formData.postalCode || '').trim();
439
+ if (!value || !resolvedAddressForm.postalCodeRegex) {
440
+ return false;
441
+ }
442
+ return !resolvedAddressForm.postalCodeRegex.test((0, _validators.normalizePostalCodeValue)(value));
443
+ };
444
+ const hasInvalidEmailFormat = field => {
445
+ if (field !== 'email') {
446
+ return false;
447
+ }
448
+ const value = String(formData.email || '').trim();
449
+ if (!value) {
450
+ return false;
451
+ }
452
+ return !(0, _validators.isValidEmail)(value);
453
+ };
454
+ const shouldShowFieldError = field => {
455
+ const shouldShowValidation = Boolean(showAllRequiredErrors || touchedFields[field]);
456
+ if (!shouldShowValidation) {
457
+ return false;
458
+ }
459
+ const requiredError = isFieldRequired(field) && isFieldBlank(field);
460
+ return requiredError || hasInvalidPostalCodeFormat(field) || hasInvalidEmailFormat(field);
461
+ };
462
+ const handleFieldBlur = field => {
463
+ if (!isFieldRequired(field) && field !== 'email' && field !== 'postalCode') {
464
+ return;
465
+ }
466
+ setTouchedFields(prev => ({
467
+ ...prev,
468
+ [field]: true
469
+ }));
470
+ };
471
+ const getFieldErrorMessage = field => {
472
+ if (!shouldShowFieldError(field)) {
473
+ return '';
474
+ }
475
+ if (isFieldRequired(field) && isFieldBlank(field)) {
476
+ return areLabelsLoading ? '' : fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.fieldRequired;
477
+ }
478
+ if (hasInvalidPostalCodeFormat(field)) {
479
+ return areLabelsLoading ? '' : fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.invalidPostalCode;
480
+ }
481
+ if (hasInvalidEmailFormat(field)) {
482
+ return areLabelsLoading ? '' : fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.invalidEmail;
483
+ }
484
+ return '';
485
+ };
486
+ const hasVisibleFieldError = field => shouldShowFieldError(field);
487
+ const handleEditableFieldChange = (field, value) => {
488
+ const normalizedValue = (0, _validators.normalizeAddressFieldValue)(field, value);
489
+ if (field === lookupField) {
490
+ setShowValidationSuggestions(false);
491
+ }
492
+ clearServiceErrors();
493
+ setShowMapModal(false);
494
+ setPendingMapOpen(false);
495
+ mapValidationStartedRef.current = false;
496
+ setMapAddressLines([]);
497
+ const requiredFieldsForVerification = (resolvedAddressForm === null || resolvedAddressForm === void 0 ? void 0 : resolvedAddressForm.requiredFields) || requiredFields;
498
+ const nextVerificationStatus = (0, _addressVerification.getManualEditVerificationStatus)(verificationStatus, field, lookupField, requiredFieldsForVerification);
499
+ const updatedFormData = (0, _addressVerification.withManualAddressVerificationEdit)(stripUnusedEmail({
500
+ ...stripGeocode(formData),
501
+ [field]: normalizedValue
502
+ }), field, nextVerificationStatus);
503
+ setFormData(updatedFormData);
504
+ setVerificationStatus(nextVerificationStatus);
505
+ if (fieldTimerRef.current) {
506
+ clearTimeout(fieldTimerRef.current);
507
+ }
508
+ fieldTimerRef.current = setTimeout(() => {
509
+ const payload = {
510
+ type: 'field-change',
511
+ field,
512
+ value: normalizedValue,
513
+ address: updatedFormData,
514
+ status: (0, _addressStatus.buildAddressStatus)({
515
+ countryCode: 'US',
516
+ addressForm: resolvedAddressForm,
517
+ formData: updatedFormData,
518
+ verificationStatus: nextVerificationStatus,
519
+ mode,
520
+ requireValidation: allowValidation
521
+ })
522
+ };
523
+ if (hasEmailField && field === 'email' && value) {
524
+ payload.isValidEmail = (0, _validators.isValidEmail)(normalizedValue);
525
+ }
526
+ onSelect === null || onSelect === void 0 || onSelect(payload);
527
+ }, 500);
528
+ };
529
+ const handleSelect = address => {
530
+ clearServiceErrors({
531
+ lookup: true,
532
+ validation: false
533
+ });
534
+ if (address.entries > 1) {
535
+ shouldSearchRef.current = true;
536
+ appliedSelectionKeyRef.current = null;
537
+ setSelectedUSAddress(address);
538
+ const baseAddress = `${address.street_line} ${address.secondary}`.trim();
539
+ setQuery(baseAddress);
540
+ } else {
541
+ shouldSearchRef.current = false;
542
+ appliedSelectionKeyRef.current = null;
543
+ setSelectedUSAddress(null);
544
+ setSelectedAddress(address);
545
+ setQuery('');
546
+ }
547
+ };
548
+ const handleValidationSelect = validatedAddress => {
549
+ var _validatedAddress$met, _validatedAddress$met2;
550
+ clearServiceErrors({
551
+ lookup: false,
552
+ validation: true
553
+ });
554
+ const config = resolvedAddressForm.addressElements || [];
555
+ const {
556
+ mapped: verifiedMapped,
557
+ mapAddressLines: nextMapAddressLines
558
+ } = (0, _addressMapping.buildUSVerifiedAddressMapping)(validatedAddress);
559
+ let mapped = {
560
+ ...verifiedMapped
561
+ };
562
+ if (resolvedAddressForm.wrapAddress1ToAddress2) {
563
+ const address1Field = config.find(f => f.field === 'address1');
564
+ if (address1Field !== null && address1Field !== void 0 && address1Field.maxLength) {
565
+ const wrapped = (0, _addressWrapper.wrapAddress1ToAddress2)(mapped.address1, mapped.address2, address1Field.maxLength);
566
+ mapped.address1 = wrapped.address1;
567
+ mapped.address2 = wrapped.address2;
568
+ }
569
+ }
570
+ const updatedFormData = {
571
+ ...stripGeocode(formData),
572
+ ...mapped,
573
+ email: formData.email,
574
+ latitude: (_validatedAddress$met = validatedAddress.metadata) === null || _validatedAddress$met === void 0 ? void 0 : _validatedAddress$met.latitude,
575
+ longitude: (_validatedAddress$met2 = validatedAddress.metadata) === null || _validatedAddress$met2 === void 0 ? void 0 : _validatedAddress$met2.longitude
576
+ };
577
+ const normalizedFormData = buildTrackedAddress(updatedFormData, 'verified', 'smarty-us');
578
+ setShowValidationSuggestions(false);
579
+ setValidationTriggerSource(null);
580
+ setMapAddressLines(nextMapAddressLines);
581
+ setFormData(normalizedFormData);
582
+ lastCommittedAddressRef.current = normalizedFormData;
583
+ lookupDraftOriginalRef.current = normalizedFormData;
584
+ setHasPendingLookupDraft(false);
585
+ const currentVerificationStatus = 'verified';
586
+ setVerificationStatus(currentVerificationStatus);
587
+ autoApplyValidationStartedRef.current = false;
588
+ if (pendingMapOpen) {
589
+ setPendingMapOpen(false);
590
+ mapValidationStartedRef.current = false;
591
+ setShowMapModal(true);
592
+ }
593
+ onSelect === null || onSelect === void 0 || onSelect({
594
+ type: 'validation',
595
+ address: normalizedFormData,
596
+ verification: validatedAddress.analysis,
597
+ isDeliverable: validatedAddress.isDeliverable,
598
+ status: (0, _addressStatus.buildAddressStatus)({
599
+ countryCode: 'US',
600
+ addressForm: resolvedAddressForm,
601
+ formData: normalizedFormData,
602
+ verificationStatus: currentVerificationStatus,
603
+ mode,
604
+ requireValidation: allowValidation
605
+ })
606
+ });
607
+ };
608
+ const handleValidate = () => {
609
+ if (!allowValidation) {
610
+ return;
611
+ }
612
+ clearServiceErrors({
613
+ lookup: false,
614
+ validation: true
615
+ });
616
+ setShowValidationSuggestions(true);
617
+ setValidationTriggerSource('manual');
618
+ setValidationTrigger(prev => prev + 1);
619
+ };
620
+ const handleOpenMap = () => {
621
+ if (hasMapCoordinates) {
622
+ setShowMapModal(true);
623
+ return;
624
+ }
625
+ if (!canAttemptMap || validationLoading) {
626
+ return;
627
+ }
628
+ clearServiceErrors({
629
+ lookup: false,
630
+ validation: true
631
+ });
632
+ mapValidationStartedRef.current = false;
633
+ setPendingMapOpen(true);
634
+ setShowValidationSuggestions(true);
635
+ setValidationTriggerSource('map');
636
+ setValidationTrigger(prev => prev + 1);
637
+ };
638
+ const getFieldKey = fieldConfig => fieldConfig.field;
639
+ const getSuggestionKey = suggestion => [suggestion.street_line, suggestion.secondary, suggestion.city, suggestion.state, suggestion.zipcode, suggestion.entries].filter(value => value !== undefined && value !== null).join('|');
640
+ const getValidationSuggestionKey = suggestion => [suggestion.delivery_line_1, suggestion.delivery_line_2, suggestion.last_line, suggestion.dpvMatchCode].filter(value => value !== undefined && value !== null).join('|');
641
+ const getValidationSummaryTitle = suggestion => {
642
+ var _suggestion$validatio, _suggestion$validatio2, _suggestion$validatio3, _suggestion$validatio4, _suggestion$validatio5, _suggestion$validatio6, _suggestion$validatio7, _suggestion$validatio8, _suggestion$validatio9;
643
+ const code = (_suggestion$validatio = suggestion.validationSummary) === null || _suggestion$validatio === void 0 ? void 0 : _suggestion$validatio.code;
644
+ switch (code) {
645
+ case 'verified':
646
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usVerified) || ((_suggestion$validatio2 = suggestion.validationSummary) === null || _suggestion$validatio2 === void 0 ? void 0 : _suggestion$validatio2.title) || 'Verified';
647
+ case 'missing-secondary':
648
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usMissingSecondaryTitle) || ((_suggestion$validatio3 = suggestion.validationSummary) === null || _suggestion$validatio3 === void 0 ? void 0 : _suggestion$validatio3.title) || 'Apartment or suite needed';
649
+ case 'invalid-secondary-required':
650
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usInvalidSecondaryRequiredTitle) || ((_suggestion$validatio4 = suggestion.validationSummary) === null || _suggestion$validatio4 === void 0 ? void 0 : _suggestion$validatio4.title) || 'Apartment or suite not recognized';
651
+ case 'invalid-secondary-optional':
652
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usInvalidSecondaryOptionalTitle) || ((_suggestion$validatio5 = suggestion.validationSummary) === null || _suggestion$validatio5 === void 0 ? void 0 : _suggestion$validatio5.title) || 'Unit not recognized';
653
+ case 'vacant':
654
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usVacantTitle) || ((_suggestion$validatio6 = suggestion.validationSummary) === null || _suggestion$validatio6 === void 0 ? void 0 : _suggestion$validatio6.title) || 'Verified, but marked vacant';
655
+ case 'no-stat':
656
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usNoStatTitle) || ((_suggestion$validatio7 = suggestion.validationSummary) === null || _suggestion$validatio7 === void 0 ? void 0 : _suggestion$validatio7.title) || 'Verified with caution';
657
+ case 'not-confirmed':
658
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usNotConfirmedTitle) || ((_suggestion$validatio8 = suggestion.validationSummary) === null || _suggestion$validatio8 === void 0 ? void 0 : _suggestion$validatio8.title) || 'Not verified';
659
+ default:
660
+ return ((_suggestion$validatio9 = suggestion.validationSummary) === null || _suggestion$validatio9 === void 0 ? void 0 : _suggestion$validatio9.title) || 'Candidate';
661
+ }
662
+ };
663
+ const getValidationSummaryMessage = suggestion => {
664
+ var _suggestion$validatio0, _suggestion$validatio1, _suggestion$validatio10, _suggestion$validatio11, _suggestion$validatio12, _suggestion$validatio13, _suggestion$validatio14, _suggestion$validatio15, _suggestion$validatio16;
665
+ const code = (_suggestion$validatio0 = suggestion.validationSummary) === null || _suggestion$validatio0 === void 0 ? void 0 : _suggestion$validatio0.code;
666
+ switch (code) {
667
+ case 'missing-secondary':
668
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usMissingSecondaryMessage) || ((_suggestion$validatio1 = suggestion.validationSummary) === null || _suggestion$validatio1 === void 0 ? void 0 : _suggestion$validatio1.message) || '';
669
+ case 'invalid-secondary-required':
670
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usInvalidSecondaryRequiredMessage) || ((_suggestion$validatio10 = suggestion.validationSummary) === null || _suggestion$validatio10 === void 0 ? void 0 : _suggestion$validatio10.message) || '';
671
+ case 'invalid-secondary-optional':
672
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usInvalidSecondaryOptionalMessage) || ((_suggestion$validatio11 = suggestion.validationSummary) === null || _suggestion$validatio11 === void 0 ? void 0 : _suggestion$validatio11.message) || '';
673
+ case 'vacant':
674
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usVacantMessage) || ((_suggestion$validatio12 = suggestion.validationSummary) === null || _suggestion$validatio12 === void 0 ? void 0 : _suggestion$validatio12.message) || '';
675
+ case 'no-stat':
676
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usNoStatMessage) || ((_suggestion$validatio13 = suggestion.validationSummary) === null || _suggestion$validatio13 === void 0 ? void 0 : _suggestion$validatio13.message) || '';
677
+ case 'not-confirmed':
678
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usNotConfirmedMessage) || ((_suggestion$validatio14 = suggestion.validationSummary) === null || _suggestion$validatio14 === void 0 ? void 0 : _suggestion$validatio14.message) || '';
679
+ case 'verified':
680
+ return (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usVerifiedMessage) || ((_suggestion$validatio15 = suggestion.validationSummary) === null || _suggestion$validatio15 === void 0 ? void 0 : _suggestion$validatio15.message) || '';
681
+ default:
682
+ return ((_suggestion$validatio16 = suggestion.validationSummary) === null || _suggestion$validatio16 === void 0 ? void 0 : _suggestion$validatio16.message) || '';
683
+ }
684
+ };
685
+ const renderLookupActions = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
686
+ className: "ns-address-lookup__actions",
687
+ children: [showMapAction && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
688
+ type: "button",
689
+ onClick: handleOpenMap,
690
+ className: "ns-address-lookup__toggle ns-address-lookup__toggle--icon",
691
+ title: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.openInMaps,
692
+ "aria-label": fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.openInMaps,
693
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_LocationPinIcon.default, {
694
+ className: "ns-address-lookup__icon"
695
+ })
696
+ }), !isAutocompleteMode && allowValidation && showManualValidateButton && /*#__PURE__*/(0, _jsxRuntime.jsx)(_foundationUiComponents.NsButton, {
697
+ type: "button",
698
+ onClick: handleValidate,
699
+ disabled: validationLoading || !String(formData[lookupField] || '').trim(),
700
+ variant: "contained",
701
+ color: "primary",
702
+ size: "small",
703
+ children: validationLoading ? 'Validating...' : 'Validate Address'
704
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
705
+ type: "button",
706
+ onClick: () => {
707
+ setShowValidationSuggestions(false);
708
+ setShowMapModal(false);
709
+ setPendingMapOpen(false);
710
+ mapValidationStartedRef.current = false;
711
+ setValidationTriggerSource(null);
712
+ clearServiceErrors();
713
+ setMode(mode === 'autocomplete' ? 'manual' : 'autocomplete');
714
+ },
715
+ className: "ns-address-lookup__toggle",
716
+ children: mode === 'autocomplete' ? fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.switchToManualEntry : fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.switchToAutocomplete
717
+ })]
718
+ });
719
+ const getLookupInputElement = () => typeof document !== 'undefined' ? document.getElementById(getFieldId(lookupField)) : null;
720
+ const getVisibleSuggestionButtons = () => {
721
+ var _componentRef$current;
722
+ return Array.from(((_componentRef$current = componentRef.current) === null || _componentRef$current === void 0 ? void 0 : _componentRef$current.querySelectorAll(LOOKUP_LIST_BUTTON_SELECTOR)) || []);
723
+ };
724
+ const handleLookupInputKeyDown = event => {
725
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') {
726
+ return;
727
+ }
728
+ const suggestionButtons = getVisibleSuggestionButtons();
729
+ if (suggestionButtons.length === 0) {
730
+ return;
731
+ }
732
+ event.preventDefault();
733
+ const targetButton = event.key === 'ArrowUp' ? suggestionButtons[suggestionButtons.length - 1] : suggestionButtons[0];
734
+ targetButton === null || targetButton === void 0 || targetButton.focus();
735
+ };
736
+ const handleSuggestionButtonKeyDown = (event, index) => {
737
+ const suggestionButtons = getVisibleSuggestionButtons();
738
+ if (suggestionButtons.length === 0) {
739
+ return;
740
+ }
741
+ if (event.key === 'ArrowDown') {
742
+ var _suggestionButtons;
743
+ event.preventDefault();
744
+ if (index === suggestionButtons.length - 1) {
745
+ var _getLookupInputElemen2;
746
+ (_getLookupInputElemen2 = getLookupInputElement()) === null || _getLookupInputElemen2 === void 0 || _getLookupInputElemen2.focus();
747
+ return;
748
+ }
749
+ (_suggestionButtons = suggestionButtons[index + 1]) === null || _suggestionButtons === void 0 || _suggestionButtons.focus();
750
+ return;
751
+ }
752
+ if (event.key === 'ArrowUp') {
753
+ var _suggestionButtons2;
754
+ event.preventDefault();
755
+ if (index === 0) {
756
+ var _getLookupInputElemen3;
757
+ (_getLookupInputElemen3 = getLookupInputElement()) === null || _getLookupInputElemen3 === void 0 || _getLookupInputElemen3.focus();
758
+ return;
759
+ }
760
+ (_suggestionButtons2 = suggestionButtons[index - 1]) === null || _suggestionButtons2 === void 0 || _suggestionButtons2.focus();
761
+ return;
762
+ }
763
+ if (event.key === 'Escape') {
764
+ var _getLookupInputElemen4;
765
+ event.preventDefault();
766
+ (_getLookupInputElemen4 = getLookupInputElement()) === null || _getLookupInputElemen4 === void 0 || _getLookupInputElemen4.focus();
767
+ }
768
+ };
769
+ const renderLookupLists = isLookupField => {
770
+ if (readOnlyView) {
771
+ return null;
772
+ }
773
+ const shouldShowValidationResults = allowValidation && showValidationSuggestions && (!isAutocompleteMode || validationTriggerSource === 'map');
774
+ const shouldShowNoResults = shouldShowValidationResults && !validationLoading && validationSuggestions.length === 0 && !validationServiceError && (validationTriggerSource !== 'map' || mapValidationStartedRef.current);
775
+ if (!isLookupField) {
776
+ return null;
777
+ }
778
+ if (loading && isAutocompleteMode) {
779
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
780
+ className: "ns-address-lookup__spinner"
781
+ });
782
+ }
783
+ if (suggestions.length > 0 && !selectedAddress && isAutocompleteMode) {
784
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("ul", {
785
+ ref: suggestionsListRef,
786
+ className: "ns-address-lookup__list ns-address-lookup__list--suggestions",
787
+ children: suggestions.map((suggestion, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
788
+ className: ['ns-address-lookup__list-item', index < suggestions.length - 1 ? 'ns-address-lookup__list-item--divided' : ''].filter(Boolean).join(' '),
789
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
790
+ type: "button",
791
+ onClick: () => handleSelect(suggestion),
792
+ onKeyDown: event => handleSuggestionButtonKeyDown(event, index),
793
+ className: "ns-address-lookup__list-button",
794
+ children: suggestion.displayText
795
+ })
796
+ }, getSuggestionKey(suggestion)))
797
+ });
798
+ }
799
+ if (shouldShowValidationResults && validationSuggestions.length > 0) {
800
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("ul", {
801
+ className: "ns-address-lookup__list ns-address-lookup__list--validation-inline",
802
+ children: validationSuggestions.map((suggestion, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
803
+ className: ['ns-address-lookup__list-item', index < validationSuggestions.length - 1 ? 'ns-address-lookup__list-item--divided' : ''].filter(Boolean).join(' '),
804
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
805
+ type: "button",
806
+ onClick: () => handleValidationSelect(suggestion),
807
+ onKeyDown: event => handleSuggestionButtonKeyDown(event, index),
808
+ className: "ns-address-lookup__list-button",
809
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
810
+ className: "ns-address-lookup__list-title",
811
+ children: getValidationSummaryTitle(suggestion)
812
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
813
+ className: "ns-address-lookup__list-subtitle",
814
+ children: suggestion.displayText
815
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
816
+ className: "ns-address-lookup__list-subtitle",
817
+ children: getValidationSummaryMessage(suggestion)
818
+ })]
819
+ })
820
+ }, getValidationSuggestionKey(suggestion)))
821
+ });
822
+ }
823
+ if (shouldShowNoResults) {
824
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
825
+ className: "ns-address-lookup__message",
826
+ children: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.usNoResults
827
+ });
828
+ }
829
+ return null;
830
+ };
831
+ (0, _react.useEffect)(() => {
832
+ if (['autocomplete', 'map'].includes(validationTriggerSource) && validationSuggestions.length === 1 && autoApplyValidationStartedRef.current) {
833
+ handleValidationSelect(validationSuggestions[0]);
834
+ }
835
+ if (validationTriggerSource === 'initial' && autoApplyValidationStartedRef.current && !validationLoading) {
836
+ const bestSuggestion = getBestInitialValidationResult(validationSuggestions);
837
+ if (bestSuggestion) {
838
+ handleValidationSelect(bestSuggestion);
839
+ return;
840
+ }
841
+ autoApplyValidationStartedRef.current = false;
842
+ setShowValidationSuggestions(false);
843
+ setValidationTriggerSource(null);
844
+ }
845
+ }, [validationLoading, validationSuggestions, validationTriggerSource]);
846
+ const renderField = fieldConfig => {
847
+ const isLookupField = fieldConfig.field === lookupField;
848
+ const fieldId = getFieldId(fieldConfig.field);
849
+ const fieldLabel = areLabelsLoading ? '' : (fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels[fieldConfig.field]) || fieldConfig.label;
850
+ const fieldError = getFieldErrorMessage(fieldConfig.field);
851
+ const isInvalid = hasVisibleFieldError(fieldConfig.field);
852
+ const isReadOnly = readOnlyView || !fieldConfig.editable && !isLookupField && isAutocompleteMode;
853
+ const fieldWidth = fieldConfig.width === 'full' ? '100%' : fieldConfig.width === 'third' ? '33.333333%' : '50%';
854
+ const inputClassName = ['ns-address-lookup__input', isReadOnly ? 'ns-address-lookup__input--readonly' : '', isLookupField && loading ? 'ns-address-lookup__input--loading' : ''].filter(Boolean).join(' ');
855
+ const labelRowClassName = ['ns-address-lookup__label-row', isLookupField ? '' : 'ns-address-lookup__label-row--field'].filter(Boolean).join(' ');
856
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
857
+ className: "ns-address-lookup__field",
858
+ style: {
859
+ width: fieldWidth
860
+ },
861
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
862
+ className: labelRowClassName,
863
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("label", {
864
+ htmlFor: fieldId,
865
+ className: "MuiFormLabel-root MuiFormLabel-colorPrimary css-1ef1ceb-MuiFormLabel-root",
866
+ children: [fieldLabel, fieldConfig.required && !areLabelsLoading && /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
867
+ "aria-hidden": "true",
868
+ className: "MuiFormLabel-asterisk",
869
+ children: ' *'
870
+ })]
871
+ }), isLookupField && !readOnlyView && renderLookupActions()]
872
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_foundationUiComponents.NsInputField, {
873
+ id: fieldId,
874
+ type: "text",
875
+ value: formData[fieldConfig.field] || '',
876
+ "aria-invalid": shouldShowFieldError(fieldConfig.field) ? 'true' : undefined,
877
+ fieldState: isInvalid ? 'error' : undefined,
878
+ helperText: fieldError || undefined,
879
+ required: fieldConfig.required,
880
+ onBlur: () => handleFieldBlur(fieldConfig.field),
881
+ onKeyDown: isLookupField && !readOnlyView ? handleLookupInputKeyDown : undefined,
882
+ onChange: e => {
883
+ const filtered = (0, _validators.filterAllowedCharacters)(e.target.value, fieldConfig.allowedCharacters);
884
+ if (readOnlyView) {
885
+ return;
886
+ }
887
+ if (isLookupField && isAutocompleteMode) {
888
+ handleInputChange({
889
+ ...e,
890
+ target: {
891
+ ...e.target,
892
+ value: filtered
893
+ }
894
+ });
895
+ } else {
896
+ handleEditableFieldChange(fieldConfig.field, filtered);
897
+ }
898
+ },
899
+ InputProps: {
900
+ readOnly: isReadOnly
901
+ },
902
+ inputProps: {
903
+ maxLength: fieldConfig.maxLength,
904
+ 'data-testid': getFieldTestId(fieldConfig.field)
905
+ },
906
+ className: inputClassName
907
+ }), renderLookupLists(isLookupField)]
908
+ }, getFieldKey(fieldConfig));
909
+ };
910
+ const renderAddressForm = () => {
911
+ const config = resolvedAddressForm === null || resolvedAddressForm === void 0 ? void 0 : resolvedAddressForm.addressElements;
912
+ if (!(config !== null && config !== void 0 && config.length)) {
913
+ if (isFormLoading) {
914
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
915
+ children: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.loadingAddressForm
916
+ });
917
+ }
918
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
919
+ children: "No form available for this country: US"
920
+ });
921
+ }
922
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
923
+ children: config.map(renderField)
924
+ });
925
+ };
926
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
927
+ ref: componentRef,
928
+ className: "ns-address-lookup__panel",
929
+ children: [lookupServiceError && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
930
+ className: "ns-address-lookup__message",
931
+ children: lookupErrorMessage
932
+ }), allowValidation && validationServiceError && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
933
+ className: "ns-address-lookup__message",
934
+ children: validationErrorMessage
935
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
936
+ className: "ns-address-lookup__form",
937
+ children: renderAddressForm()
938
+ }), showMapModal && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
939
+ className: "ns-address-lookup__modal-backdrop",
940
+ onClick: () => setShowMapModal(false),
941
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
942
+ className: "ns-address-lookup__modal",
943
+ role: "dialog",
944
+ "aria-modal": "true",
945
+ "aria-label": fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.addressLocation,
946
+ onClick: event => event.stopPropagation(),
947
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
948
+ className: "ns-address-lookup__modal-header",
949
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
950
+ className: "ns-address-lookup__modal-title",
951
+ children: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.addressLocation
952
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
953
+ type: "button",
954
+ className: "ns-address-lookup__toggle",
955
+ "aria-label": "Close",
956
+ onClick: () => setShowMapModal(false),
957
+ children: "X"
958
+ })]
959
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
960
+ ref: mapContainerRef,
961
+ className: "ns-address-lookup__map"
962
+ })]
963
+ })
964
+ })]
965
+ });
966
+ };
967
+ SmartyUSResults.propTypes = {
968
+ onSelect: _propTypes.default.func,
969
+ initialAddress: _componentPropTypes.addressPropType,
970
+ requireValidation: _propTypes.default.bool,
971
+ readOnlyView: _propTypes.default.bool,
972
+ showManualValidateButton: _propTypes.default.bool,
973
+ validationRequestId: _propTypes.default.number,
974
+ language: _propTypes.default.string,
975
+ strings: _componentPropTypes.labelStringsPropType,
976
+ formDefinition: _componentPropTypes.formDefinitionPropType,
977
+ deferFormLookup: _propTypes.default.bool
978
+ };
979
+ var _default = exports.default = SmartyUSResults;
980
+ //# sourceMappingURL=SmartyUSResults.js.map