@propeller-commerce/propeller-v2-react-ui 0.7.0 → 0.7.1

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
@@ -8,6 +8,30 @@ once it reaches 1.0. Until then (the `0.x` line) the public API may change
8
8
  between minor versions; breaking changes are called out below and in
9
9
  [MIGRATION.md](./MIGRATION.md).
10
10
 
11
+ ## [0.7.1] - 2026-07-28
12
+
13
+ ### Fixed
14
+
15
+ - **`cartUpdateAddress` rejected a blank email** — optional address fields were
16
+ sent as empty strings when left blank, and the API validates optional fields
17
+ whenever they are present, so a blank email failed with
18
+ `email must be an email` (400). This blocked the address step for a delivery
19
+ address, where the email legitimately lives on the contact / customer record
20
+ rather than the address. Optional fields are now omitted when blank, matching
21
+ how `useAddress` already built its payloads. Affects every optional field
22
+ (`email`, `phone`, `mobile`, `company`, `notes`, …), not just email.
23
+ - **`<AddressCard>` required an email on every address** — the edit and create
24
+ forms hardcoded `required` plus a `*` on the email input, contradicting the
25
+ field being optional on the address itself. Email is now optional in both
26
+ forms.
27
+ - **`<AddressCard>` accepted undeliverable emails** — `type="email"` alone
28
+ permits dotless domains such as `aa@gg` (valid per the HTML5 spec for
29
+ intranet hosts, but rejected by the API). Both email inputs now carry a
30
+ pattern requiring a dotted top-level domain, so invalid input is caught in
31
+ the form instead of surfacing as a failed mutation. Subdomains
32
+ (`user@sub.co.uk`) and tagged addresses (`user+tag@example.com`) remain
33
+ valid.
34
+
11
35
  ## [0.7.0] - 2026-07-27
12
36
 
13
37
  ### Added
package/dist/index.cjs CHANGED
@@ -888,6 +888,25 @@ function useCart(options) {
888
888
  }, [graphqlClient, language, configuration, user]);
889
889
  return { cart, cartId, loading, error, checkoutAllowed, resolveCart, addItem, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };
890
890
  }
891
+ function buildAddressInput(type, addr) {
892
+ return {
893
+ type,
894
+ firstName: addr.firstName || "",
895
+ lastName: addr.lastName || "",
896
+ street: addr.street || "",
897
+ postalCode: addr.postalCode || "",
898
+ city: addr.city || "",
899
+ ...addr.company && { company: addr.company },
900
+ ...addr.gender && { gender: addr.gender },
901
+ ...addr.middleName && { middleName: addr.middleName },
902
+ ...addr.number && { number: addr.number },
903
+ ...addr.numberExtension && { numberExtension: addr.numberExtension },
904
+ ...addr.country && { country: addr.country },
905
+ ...addr.email && { email: addr.email },
906
+ ...addr.mobile && { mobile: addr.mobile },
907
+ ...addr.phone && { phone: addr.phone }
908
+ };
909
+ }
891
910
  function useCheckout(options) {
892
911
  const { graphqlClient, user, companyId } = options;
893
912
  const language = options.language ?? "NL";
@@ -928,26 +947,9 @@ function useCheckout(options) {
928
947
  if (!hasInvoice) {
929
948
  const defaultInvoice = getUserDefaultAddress("invoice");
930
949
  if (defaultInvoice) {
931
- const input = {
932
- type: propellerSdkV2.CartAddressType.INVOICE,
933
- firstName: defaultInvoice.firstName || "",
934
- lastName: defaultInvoice.lastName || "",
935
- street: defaultInvoice.street || "",
936
- postalCode: defaultInvoice.postalCode || "",
937
- city: defaultInvoice.city || "",
938
- company: defaultInvoice.company,
939
- gender: defaultInvoice.gender,
940
- middleName: defaultInvoice.middleName,
941
- number: defaultInvoice.number,
942
- numberExtension: defaultInvoice.numberExtension,
943
- country: defaultInvoice.country,
944
- email: defaultInvoice.email,
945
- mobile: defaultInvoice.mobile,
946
- phone: defaultInvoice.phone
947
- };
948
950
  updatedCart = await cartService.updateCartAddress({
949
951
  id: updatedCart.cartId,
950
- input,
952
+ input: buildAddressInput(propellerSdkV2.CartAddressType.INVOICE, defaultInvoice),
951
953
  imageVariantFilters,
952
954
  imageSearchFilters,
953
955
  language
@@ -957,26 +959,9 @@ function useCheckout(options) {
957
959
  if (!hasDelivery) {
958
960
  const defaultDelivery = getUserDefaultAddress("delivery");
959
961
  if (defaultDelivery) {
960
- const input = {
961
- type: propellerSdkV2.CartAddressType.DELIVERY,
962
- firstName: defaultDelivery.firstName || "",
963
- lastName: defaultDelivery.lastName || "",
964
- street: defaultDelivery.street || "",
965
- postalCode: defaultDelivery.postalCode || "",
966
- city: defaultDelivery.city || "",
967
- company: defaultDelivery.company,
968
- gender: defaultDelivery.gender,
969
- middleName: defaultDelivery.middleName,
970
- number: defaultDelivery.number,
971
- numberExtension: defaultDelivery.numberExtension,
972
- country: defaultDelivery.country,
973
- email: defaultDelivery.email,
974
- mobile: defaultDelivery.mobile,
975
- phone: defaultDelivery.phone
976
- };
977
962
  updatedCart = await cartService.updateCartAddress({
978
963
  id: updatedCart.cartId,
979
- input,
964
+ input: buildAddressInput(propellerSdkV2.CartAddressType.DELIVERY, defaultDelivery),
980
965
  imageVariantFilters,
981
966
  imageSearchFilters,
982
967
  language
@@ -5065,6 +5050,7 @@ function AddToFavorite(rawProps) {
5065
5050
  ] }) }) : null });
5066
5051
  }
5067
5052
  var AddToFavorite_default = AddToFavorite;
5053
+ var EMAIL_PATTERN = "[^@\\s]+@[^@\\s.]+(?:\\.[^@\\s.]+)*\\.[A-Za-z]{2,}";
5068
5054
  var AddressCardContext = React6__namespace.createContext(null);
5069
5055
  function useAddressCardContext() {
5070
5056
  const ctx = React6__namespace.useContext(AddressCardContext);
@@ -5510,10 +5496,7 @@ function AddressCard(rawProps) {
5510
5496
  ] }),
5511
5497
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
5512
5498
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5513
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block text-sm font-medium mb-1", children: [
5514
- propellerV2CoreUi.getLabel(props.labels, "email", "Email"),
5515
- " *"
5516
- ] }),
5499
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: propellerV2CoreUi.getLabel(props.labels, "email", "Email") }),
5517
5500
  /* @__PURE__ */ jsxRuntime.jsx(
5518
5501
  "input",
5519
5502
  {
@@ -5523,7 +5506,7 @@ function AddressCard(rawProps) {
5523
5506
  onChange: (e) => {
5524
5507
  setEditEmail(e.target.value);
5525
5508
  },
5526
- required: true
5509
+ pattern: EMAIL_PATTERN
5527
5510
  }
5528
5511
  )
5529
5512
  ] }),
@@ -5803,10 +5786,7 @@ function AddressCard(rawProps) {
5803
5786
  ] }),
5804
5787
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
5805
5788
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5806
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block text-sm font-medium mb-1", children: [
5807
- propellerV2CoreUi.getLabel(props.labels, "email", "Email"),
5808
- " *"
5809
- ] }),
5789
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: propellerV2CoreUi.getLabel(props.labels, "email", "Email") }),
5810
5790
  /* @__PURE__ */ jsxRuntime.jsx(
5811
5791
  "input",
5812
5792
  {
@@ -5816,7 +5796,7 @@ function AddressCard(rawProps) {
5816
5796
  onChange: (e) => {
5817
5797
  setEditEmail(e.target.value);
5818
5798
  },
5819
- required: true
5799
+ pattern: EMAIL_PATTERN
5820
5800
  }
5821
5801
  )
5822
5802
  ] }),