@nuskin/shipping-address-form
v1.6.0
Published
React components for standalone address lookup and shipping address forms
Readme
@nuskin/shipping-address-form
React package that provides standalone address lookup and shipping address form components.
The component:
- exports
AddressLookupfor standalone address entry and validation - exports
ShippingAddressForm, which adds shipping-specific fields, actions, and Contentstack-driven form configuration aroundAddressLookup - loads a shipping form definition from Contentstack based on the logged-in country and form type
- renders pre-address and post-address shipping fields in the order defined by content
- loads localized strings once and passes the derived
formStringssubset intoAddressLookup - emits a single
onActioncallback forsaveandcancel
Installation
yarn add @nuskin/shipping-address-formPeer dependencies:
reactreact-domaxios
Direct dependencies used by this package:
@nuskin/contentstack-lib@nuskin/foundation-ui-componentsreact-phone-number-input
Usage
import ShippingAddressForm from '@nuskin/shipping-address-form'
export default function Example() {
const handleAction = (payload) => {
if (payload.type === 'cancel') {
return
}
if (payload.type === 'save') {
console.log(payload.data)
console.log(payload.validationStatus)
}
}
return (
<ShippingAddressForm
country='US'
type='shipping'
language='en'
showSaveCheckbox={true}
showDefaultCheckbox={true}
showCancelButton={true}
showContinueButton={false}
readOnlyView={false}
address={{
givenName: 'Jane',
surname: 'Doe',
mobilePhone: '+18015551212',
address1: '123 Main St',
city: 'Provo',
region: 'UT',
postalCode: '84604',
email: '[email protected]'
}}
onAction={handleAction}
/>
)
}Standalone AddressLookup
AddressLookup is available when an application needs address autocomplete and validation without
the shipping-specific fields and actions.
import {
AddressLookup,
normalizeAddressForm,
DEFAULT_ADDRESS_FORM,
SUPPORTED_COUNTRIES
} from '@nuskin/shipping-address-form'AddressLookup accepts onAddressSelect, country, language, address, requireValidation,
readOnlyView, showManualValidateButton, validationRequestId, strings, formDefinition, and
deferFormLookup. It supports Smarty autocomplete and validation for US and international
addresses. normalizeAddressForm, DEFAULT_ADDRESS_FORM, and SUPPORTED_COUNTRIES are exported
for consumers that need to provide or reuse address form definitions.
ShippingAddressForm Props
country
- Type:
string - Default:
'US'
Two-character country code for the logged-in market. This is used to:
- load the shipping form definition from Contentstack with the current
type - load localized strings
- choose the default phone country
If the returned shipping form includes a countries list, the component shows a destination-country selector. In that case:
- the selector defaults to the logged-in country when present in the returned list
- otherwise it falls back to the first available destination country
- the selected destination country is passed into
AddressLookup
When the selected destination country matches the logged-in country, the wrapper passes the loaded
shipping form's addressForm to AddressLookup as formDefinition. When the user selects a different
destination country, the wrapper lets AddressLookup load that country's address form directly.
This destination-country list is separate from the phone country selector. The phone field uses the package's SUPPORTED_COUNTRIES export.
type
- Type:
string - Default:
'shipping'
Form type used when loading the Contentstack shipping address form. By default, ShippingAddressForm loads the shipping form type.
The lookup uses:
stack.getMultiEntryByFields('shipping_address_form', { country, type }, true)language
- Type:
string | undefined
Language code used to load localized strings for this component and the derived formStrings passed to AddressLookup.
address
- Type:
object | null - Default:
null
Initial form values. Supported keys depend on the current Contentstack shipping form definition.
The address prop is used in two places:
- to initialize the shipping fields managed by
ShippingAddressForm - to pass address values and optional verification metadata through to the built-in
AddressLookup
Common examples include:
givenNamesurnamemobilePhonemobilePhoneCountryinstructionssaveToAccountsaveAsDefault
Address fields used by AddressLookup can also be provided and are passed through as address.
The incoming address object may also include AddressLookup verification metadata, for example:
{
verification: {
status: 'verified', // or 'autocomplete' | 'unverified'
source: 'smarty-us', // or 'smarty-intl'
verifiedAt: '2026-05-01T15:01:07.905Z'
}
}If an incoming mobilePhone value is in a legacy/local format, the wrapper attempts to normalize it using mobilePhoneCountry. When mobilePhoneCountry is missing, it falls back to the current address-form country. If parsing fails, the original value is preserved.
showSaveCheckbox
- Type:
boolean - Default:
true
Controls whether the "save to account" checkbox is rendered.
showDefaultCheckbox
- Type:
boolean - Default:
true
Controls whether the "set as default" checkbox is rendered.
showCancelButton
- Type:
boolean - Default:
true
Controls whether the Cancel button is rendered.
showContinueButton
- Type:
boolean - Default:
false
When true, the primary action keeps the same save behavior but uses the localized Continue label instead of the Save label.
readOnlyView
- Type:
boolean - Default:
false
When true, the wrapper renders in display-only mode:
- passes
readOnlyViewthrough toAddressLookup - renders shipping fields as read-only
- disables the destination country selector and save/default checkboxes
- hides the Save/Continue and Cancel actions
- suppresses wrapper save and cancel callbacks
Readonly mode is intended for displaying an existing address without allowing edits or validation actions.
onAction
- Type:
(payload) => void
Single callback for form actions.
Cancel payload
{ type: 'cancel' }Save payload
Only emitted after:
AddressLookupvalidation is triggeredAddressLookupreportsstatus.completeness === 'complete'- required shipping fields are complete
- any
allowedCharactersregex rules defined for shipping fields pass
{
type: 'save',
data: {
givenName: 'Jane',
surname: 'Doe',
mobilePhone: '+18015551212',
mobilePhoneCountry: 'US',
address1: '123 Main St',
city: 'Provo',
region: 'UT',
postalCode: '84604',
email: '[email protected]',
country: 'US',
saveToAccount: true,
saveAsDefault: false
},
validationStatus: {
verification: 'verified',
completeness: 'complete',
missingFields: [],
mode: 'manual',
phone: {
valid: true
}
}
}The exact shipping-field keys in data depend on the current form definition.
Form Definition
Shipping form layout is loaded from Contentstack content type:
shipping_address_form
The entry is resolved by:
countrytype
The normalized shipping form includes:
countriespreAddressFieldsaddressFormpostAddressFields
Rendering order is content-driven:
- optional destination-country selector
preAddressFieldsAddressLookuppostAddressFields
Field normalization currently supports:
fieldwidtheditablemaxLengthrequiredallowedCharacters
Width handling:
halfrenders half widthfullrenders full width- any other value defaults to
full
mobilePhone is rendered with react-phone-number-input. Other text-like shipping fields are rendered with NsInputField from @nuskin/foundation-ui-components.
Validation Behavior
Address fields
Address validation is delegated to the built-in AddressLookup component.
When the Save button is clicked:
ShippingAddressFormincrementsvalidationRequestIdAddressLookupvalidates its fields- if the returned callback payload is a complete
validation-request,ShippingAddressFormmay emitonAction({ type: 'save', ... })
Shipping fields
Shipping field validation is handled locally.
- Required field errors show on blur and on save attempt.
- If an
emailfield is part of the shipping form, save-time validation also calls the email-verifyGET /emailInfoendpoint. - Save is blocked only when email-verify explicitly reports invalid format or invalid domain.
- Email-verify service failures do not block save.
- The email-verify base URL resolves to
apis.test.nuskin.comfor local/test-like hosts andapis.nuskin.comotherwise. - Phone validation uses
isPossiblePhoneNumber()fromreact-phone-number-input. - Invalid phone numbers show an error message and red field styling.
- Invalid phone format is currently non-blocking for save.
- When a non-empty phone value is present,
validationStatus.phoneis included in the save callback. - If the phone format is invalid, the save callback includes
validationStatus.phone = { valid: false, reason: 'invalid_format' }. - Missing required shipping fields block save.
- If a field definition includes
allowedCharacters, that regex is used for validation.
Localization
Strings are loaded from Contentstack content type:
shipping_component
This component uses shipping-level labels such as:
countryLabelgivenNameLabelsurnameLabelmobilePhoneLabelinstructionsLabelagreeToSaveAddresssetDefaultcontinueTextsaveAddresscancelinvalidPhonefieldRequired
The wrapper also derives labels.formStrings from root-level content fields and passes that object into AddressLookup.
That derived object includes the common address strings expected by AddressLookup, along with its US and international verification strings.
When the phone country is changed, the phone label is reloaded for that selected phone country and cached for reuse.
Styling
This package imports:
react-phone-number-input/style.csssrc/shippingAddressForm/styles/shippingAddressForm.cssin the built package
The component uses namespaced CSS classes starting with:
.ns-shipping-address-form
Examples:
.ns-shipping-address-form__input.ns-shipping-address-form__input--invalid.ns-shipping-address-form__phone.ns-shipping-address-form__phone-input.ns-shipping-address-form__error-text.ns-shipping-address-form__button
The stylesheet also exposes CSS variables for common overrides:
--nssf-border-color--nssf-disabled-surface-color--nssf-error-color--nssf-primary-color--nssf-surface-color--nssf-radius--nssf-label-font-size--nssf-input-font-size
Standard shipping fields use NsInputField. The phone field uses react-phone-number-input with local wrapper styles, so it may need its own CSS adjustments if your application theme changes.
Development
Run the local test app:
yarn devThe local test app supports readonly mode through query params:
?country=US&language=en&type=shipping&readOnlyView=trueBuild the package:
yarn build