@gomusdev/web-components 3.0.0-next.3 → 3.1.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.
package/README.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.0 (2026-05-26)
4
+
5
+ ### Features
6
+
7
+ * **coupon:** ensure coupon codes are stored in uppercase and update tests/documentation
8
+
9
+ ### Bug Fixes
10
+
11
+ * **auth:** replace 1s localStorage poll with storage event
12
+
13
+ ## 3.0.0 (2026-05-26)
14
+
15
+ ### ⚠ BREAKING CHANGES
16
+
17
+ * **cart:** <go-cart> is now a composable shell. The old self-rendering
18
+ <go-cart></go-cart> markup no longer renders the standard layout — integrators
19
+ must migrate to the new subcomponents (<go-cart-items>, <go-cart-coupons>,
20
+ <go-cart-subtotal-amount>, <go-cart-discounted-amount>, <go-cart-total-amount>)
21
+ or use the `default` attribute as a drop-in. Coupon row classes are renamed
22
+ (.go-cart-coupon, .go-cart-coupon-code, .go-cart-coupon-remove). The remove
23
+ button uses the shared .go-cart-remove class. <go-if> now exposes the cart
24
+ projection as data.cartView. See README.md and the cart documentation for
25
+ the full migration.
26
+
27
+ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
28
+
29
+ ### Features
30
+
31
+ * **cart, if:** expose cart projection to go-if and document coupon scenarios
32
+ * **cart:** enhance layout & UX with new coupon redemption and styling updates
33
+ * **cart:** modularize cart components and add customizable subcomponents
34
+
35
+ ### Bug Fixes
36
+
37
+ * flush unsubmitted coupon token before checkout
38
+ * include 2.1.1 patches from master
39
+ * **shop:** remove dangerous clearCache() that wiped auth and cart, closes [this.#data](https://gitlab.giantmonkey.de/gomus/this./issues/data) [gomus/frontend#24](https://gitlab.giantmonkey.de/gomus/frontend/issues/24)
40
+ * validate coupon on go-after-validation, not just submit
41
+
42
+ ### Documentation
43
+
44
+ * **cart:** announce 3.0.0 breaking change for cart composable rewrite
45
+
3
46
  ## 3.0.0-next.3 (2026-05-21)
4
47
 
5
48
  ### Bug Fixes
@@ -5684,7 +5684,11 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
5684
5684
  };
5685
5685
  constructor() {
5686
5686
  this.load();
5687
- setInterval(() => this.load(), 1e3);
5687
+ if (typeof window !== "undefined") {
5688
+ window.addEventListener("storage", (e) => {
5689
+ if (e.key === "go-auth") this.load();
5690
+ });
5691
+ }
5688
5692
  }
5689
5693
  customerLevel() {
5690
5694
  if (this.isGuest()) return 10;
@@ -5726,9 +5730,11 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
5726
5730
  return JSON.stringify(this.#data);
5727
5731
  }
5728
5732
  save() {
5733
+ if (typeof localStorage === "undefined") return;
5729
5734
  localStorage.setItem("go-auth", this.toString());
5730
5735
  }
5731
5736
  load() {
5737
+ if (typeof localStorage === "undefined") return;
5732
5738
  const str = localStorage.getItem("go-auth");
5733
5739
  if (!str) {
5734
5740
  this.signOut();
@@ -17530,6 +17536,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17530
17536
  shop.cart.coupons.join("|");
17531
17537
  untrack(() => details.calculateDisplayCart());
17532
17538
  });
17539
+ async function flushCoupons() {
17540
+ const els = $$props.$$host.querySelectorAll("go-coupon-redemption");
17541
+ let ok2 = true;
17542
+ for (const el of els) {
17543
+ const result = await el.flush?.();
17544
+ if (result && !result.success) ok2 = false;
17545
+ }
17546
+ return ok2;
17547
+ }
17548
+ $$props.$$host.addEventListener("click", async (e) => {
17549
+ const submit = e.target.closest("go-submit");
17550
+ if (!submit) return;
17551
+ const innerForm = submit.closest("go-form");
17552
+ if (innerForm && $$props.$$host.contains(innerForm)) return;
17553
+ const ok2 = await flushCoupons();
17554
+ $$props.$$host.dispatchEvent(new CustomEvent("go-submit", { detail: { ok: ok2 }, bubbles: true, composed: true }));
17555
+ });
17533
17556
  var $$exports = {
17534
17557
  get preview() {
17535
17558
  return preview();
@@ -17628,20 +17651,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17628
17651
  ]
17629
17652
  });
17630
17653
  wrapInElement($$props.$$host, "go-form", { "form-id": "checkoutGuest", custom: custom2() });
17631
- async function flushCoupons() {
17632
- const couponEls = document.querySelectorAll("go-coupon-redemption");
17633
- let allOk = true;
17634
- for (const el of couponEls) {
17635
- const result = await el.flush?.();
17636
- if (result && !result.success) allOk = false;
17637
- }
17638
- return allOk;
17639
- }
17640
- $$props.$$host.addEventListener("go-after-validation", flushCoupons);
17641
17654
  $$props.$$host.addEventListener("submit", async (e) => {
17642
17655
  const form = e.target;
17643
17656
  if (!get$2(cart)) return;
17644
- if (!await flushCoupons()) return;
17645
17657
  const auth = await shop.signUp(form.details.formData, true);
17646
17658
  if (auth.error) {
17647
17659
  form.details.apiErrors = auth.error.errors;
@@ -17720,7 +17732,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17720
17732
  });
17721
17733
  async function runRedeem(form) {
17722
17734
  const field = form.details.fields.find((f) => f.key === "token");
17723
- const token = (form.details.fieldValue("token") ?? "").trim();
17735
+ const token = (form.details.fieldValue("token") ?? "").trim().toUpperCase();
17724
17736
  if (!token) return { success: true };
17725
17737
  const result = await redeem(token);
17726
17738
  if (!result.success) {
@@ -5684,7 +5684,11 @@ class Auth {
5684
5684
  };
5685
5685
  constructor() {
5686
5686
  this.load();
5687
- setInterval(() => this.load(), 1e3);
5687
+ if (typeof window !== "undefined") {
5688
+ window.addEventListener("storage", (e) => {
5689
+ if (e.key === "go-auth") this.load();
5690
+ });
5691
+ }
5688
5692
  }
5689
5693
  customerLevel() {
5690
5694
  if (this.isGuest()) return 10;
@@ -5726,9 +5730,11 @@ class Auth {
5726
5730
  return JSON.stringify(this.#data);
5727
5731
  }
5728
5732
  save() {
5733
+ if (typeof localStorage === "undefined") return;
5729
5734
  localStorage.setItem("go-auth", this.toString());
5730
5735
  }
5731
5736
  load() {
5737
+ if (typeof localStorage === "undefined") return;
5732
5738
  const str = localStorage.getItem("go-auth");
5733
5739
  if (!str) {
5734
5740
  this.signOut();
@@ -17530,6 +17536,23 @@ function Cart($$anchor, $$props) {
17530
17536
  shop.cart.coupons.join("|");
17531
17537
  untrack(() => details.calculateDisplayCart());
17532
17538
  });
17539
+ async function flushCoupons() {
17540
+ const els = $$props.$$host.querySelectorAll("go-coupon-redemption");
17541
+ let ok2 = true;
17542
+ for (const el of els) {
17543
+ const result = await el.flush?.();
17544
+ if (result && !result.success) ok2 = false;
17545
+ }
17546
+ return ok2;
17547
+ }
17548
+ $$props.$$host.addEventListener("click", async (e) => {
17549
+ const submit = e.target.closest("go-submit");
17550
+ if (!submit) return;
17551
+ const innerForm = submit.closest("go-form");
17552
+ if (innerForm && $$props.$$host.contains(innerForm)) return;
17553
+ const ok2 = await flushCoupons();
17554
+ $$props.$$host.dispatchEvent(new CustomEvent("go-submit", { detail: { ok: ok2 }, bubbles: true, composed: true }));
17555
+ });
17533
17556
  var $$exports = {
17534
17557
  get preview() {
17535
17558
  return preview();
@@ -17628,20 +17651,9 @@ function CheckoutForm($$anchor, $$props) {
17628
17651
  ]
17629
17652
  });
17630
17653
  wrapInElement($$props.$$host, "go-form", { "form-id": "checkoutGuest", custom: custom2() });
17631
- async function flushCoupons() {
17632
- const couponEls = document.querySelectorAll("go-coupon-redemption");
17633
- let allOk = true;
17634
- for (const el of couponEls) {
17635
- const result = await el.flush?.();
17636
- if (result && !result.success) allOk = false;
17637
- }
17638
- return allOk;
17639
- }
17640
- $$props.$$host.addEventListener("go-after-validation", flushCoupons);
17641
17654
  $$props.$$host.addEventListener("submit", async (e) => {
17642
17655
  const form = e.target;
17643
17656
  if (!get$2(cart)) return;
17644
- if (!await flushCoupons()) return;
17645
17657
  const auth = await shop.signUp(form.details.formData, true);
17646
17658
  if (auth.error) {
17647
17659
  form.details.apiErrors = auth.error.errors;
@@ -17720,7 +17732,7 @@ function CouponRedemption($$anchor, $$props) {
17720
17732
  });
17721
17733
  async function runRedeem(form) {
17722
17734
  const field = form.details.fields.find((f) => f.key === "token");
17723
- const token = (form.details.fieldValue("token") ?? "").trim();
17735
+ const token = (form.details.fieldValue("token") ?? "").trim().toUpperCase();
17724
17736
  if (!token) return { success: true };
17725
17737
  const result = await redeem(token);
17726
17738
  if (!result.success) {