codexly-ui 0.10.67 → 0.10.68
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/fesm2022/codexly-ui.mjs +34 -3
- package/fesm2022/codexly-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/codexly-ui.d.ts +14 -0
package/fesm2022/codexly-ui.mjs
CHANGED
|
@@ -14444,7 +14444,11 @@ class ClxProductDetailComponent {
|
|
|
14444
14444
|
_carousel = viewChild(ClxCarouselComponent, ...(ngDevMode ? [{ debugName: "_carousel" }] : /* istanbul ignore next */ []));
|
|
14445
14445
|
quantity = signal(1, ...(ngDevMode ? [{ debugName: "quantity" }] : /* istanbul ignore next */ []));
|
|
14446
14446
|
activeTab = signal('general', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
14447
|
+
/** Only holds specs the visitor has explicitly clicked — starts empty, not pre-filled with the
|
|
14448
|
+
* initial variation's specs, so a spec option can be toggled off (click again to deselect)
|
|
14449
|
+
* without fighting a "fully selected" starting state that never lets go of its last value. */
|
|
14447
14450
|
selectedSpecs = signal({}, ...(ngDevMode ? [{ debugName: "selectedSpecs" }] : /* istanbul ignore next */ []));
|
|
14451
|
+
_initialVariation = signal(null, ...(ngDevMode ? [{ debugName: "_initialVariation" }] : /* istanbul ignore next */ []));
|
|
14448
14452
|
/** Same card treatment as clx-product (bg-clx-surface + shadow-sm) — keeps the gallery/info
|
|
14449
14453
|
* panels visually consistent with the rest of the e-commerce card set. */
|
|
14450
14454
|
_panelClass = 'bg-clx-surface rounded-2xl shadow-sm p-4';
|
|
@@ -14460,7 +14464,13 @@ class ClxProductDetailComponent {
|
|
|
14460
14464
|
return;
|
|
14461
14465
|
const initialId = this.initialVariationId();
|
|
14462
14466
|
const initial = (initialId && p.variations.find(v => v.id === initialId)) || p.variations[0];
|
|
14463
|
-
this.
|
|
14467
|
+
this._initialVariation.set(initial);
|
|
14468
|
+
// Pre-select the full spec combination only when the landing variation has stock — every
|
|
14469
|
+
// other combination stays reachable by changing any one spec. When it's sold out, starting
|
|
14470
|
+
// fully selected would fix both Color and Talla to a combination that can never resolve to
|
|
14471
|
+
// an in-stock variation, hiding every other option (see isOptionAvailable's fallback) with
|
|
14472
|
+
// no selected value left to toggle off — so start empty and let the visitor pick from scratch.
|
|
14473
|
+
this.selectedSpecs.set(initial.in_stock ? { ...initial.specs } : {});
|
|
14464
14474
|
});
|
|
14465
14475
|
effect(() => {
|
|
14466
14476
|
const v = this.activeVariation();
|
|
@@ -14468,12 +14478,22 @@ class ClxProductDetailComponent {
|
|
|
14468
14478
|
this.variationChange.emit(v);
|
|
14469
14479
|
});
|
|
14470
14480
|
}
|
|
14481
|
+
/** With no specs selected (fresh load, or every spec toggled back off) this is the variation
|
|
14482
|
+
* the visitor originally landed on. Otherwise, resolves the variation matching every currently
|
|
14483
|
+
* selected spec — with a partial selection (some spec types still untouched), any variation
|
|
14484
|
+
* whose specs are a superset of the selection counts as a match, since the visitor hasn't
|
|
14485
|
+
* narrowed those other spec types down to one value yet. */
|
|
14471
14486
|
activeVariation = computed(() => {
|
|
14472
14487
|
const p = this.product();
|
|
14473
14488
|
if (!p?.variations?.length)
|
|
14474
14489
|
return null;
|
|
14475
14490
|
const sel = this.selectedSpecs();
|
|
14476
|
-
|
|
14491
|
+
if (Object.keys(sel).length === 0)
|
|
14492
|
+
return this._initialVariation() ?? p.variations[0];
|
|
14493
|
+
const matches = p.variations.filter(v => Object.entries(sel).every(([typeId, optId]) => v.specs[typeId] === optId));
|
|
14494
|
+
// With a partial selection, several variations can match (e.g. only Color chosen) — prefer
|
|
14495
|
+
// one with stock so the price/gallery/CTA reflect a purchasable option by default.
|
|
14496
|
+
return matches.find(v => v.in_stock) ?? matches[0] ?? this._initialVariation() ?? p.variations[0];
|
|
14477
14497
|
}, ...(ngDevMode ? [{ debugName: "activeVariation" }] : /* istanbul ignore next */ []));
|
|
14478
14498
|
finalPrice = computed(() => {
|
|
14479
14499
|
const v = this.activeVariation();
|
|
@@ -14512,8 +14532,19 @@ class ClxProductDetailComponent {
|
|
|
14512
14532
|
}
|
|
14513
14533
|
return variations.some(v => v.specs[specTypeId] === specOptionId && v.in_stock && matchesCrossSelection(v));
|
|
14514
14534
|
}
|
|
14535
|
+
/** Clicking an already-selected option deselects it (toggle) instead of being a no-op — the only
|
|
14536
|
+
* way to escape a narrowed-down selection and see all options again, per the "hide unavailable
|
|
14537
|
+
* options" design: there's no separate disabled state to click through, so toggling off is the
|
|
14538
|
+
* sole path back. Once every spec is toggled off, activeVariation() falls back to the variation
|
|
14539
|
+
* the visitor originally landed on (see _initialVariation). */
|
|
14515
14540
|
selectSpec(specTypeId, specOptionId) {
|
|
14516
|
-
this.selectedSpecs.update(s =>
|
|
14541
|
+
this.selectedSpecs.update(s => {
|
|
14542
|
+
if (s[specTypeId] === specOptionId) {
|
|
14543
|
+
const { [specTypeId]: _removed, ...rest } = s;
|
|
14544
|
+
return rest;
|
|
14545
|
+
}
|
|
14546
|
+
return { ...s, [specTypeId]: specOptionId };
|
|
14547
|
+
});
|
|
14517
14548
|
this._carousel()?.goTo(0);
|
|
14518
14549
|
}
|
|
14519
14550
|
isSpecSelected(specTypeId, specOptionId) {
|