@ikas/code-components-mcp 1.4.0-beta.23 → 1.4.0-beta.231

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 (94) hide show
  1. package/data/framework.json +191 -78
  2. package/data/migration.json +10 -4
  3. package/data/section-templates/account-info-section/children/AccountFavorites/ikas-config-snippet.json +13 -0
  4. package/data/section-templates/account-info-section/children/AccountOrders/index.tsx +1 -1
  5. package/data/section-templates/account-info-section/ikas-config-snippet.json +19 -0
  6. package/data/section-templates/add-to-cart/ikas-config-snippet.json +17 -0
  7. package/data/section-templates/add-to-cart/index.tsx +16 -2
  8. package/data/section-templates/add-to-cart/sub-components/QuantitySelector/index.tsx +11 -3
  9. package/data/section-templates/add-to-cart/utils/cartLimits.ts +24 -0
  10. package/data/section-templates/blog-home-section/ikas-config-snippet.json +2 -0
  11. package/data/section-templates/blog-home-section/index.tsx +2 -1
  12. package/data/section-templates/blog-post-section/ikas-config-snippet.json +2 -0
  13. package/data/section-templates/blog-post-section/index.tsx +3 -2
  14. package/data/section-templates/bundle-products/hooks/useBundleProducts.ts +7 -6
  15. package/data/section-templates/bundle-products/ikas-config-snippet.json +20 -0
  16. package/data/section-templates/cart-section/components/EmptyState/index.tsx +1 -1
  17. package/data/section-templates/cart-section/sub-components/CartItem/index.tsx +66 -24
  18. package/data/section-templates/cart-section/sub-components/CartItem/styles.css +14 -0
  19. package/data/section-templates/cart-section/sub-components/QuantitySelector/index.tsx +11 -3
  20. package/data/section-templates/cart-section/utils/cartLimits.ts +24 -0
  21. package/data/section-templates/cart-section/utils/cartLineLimits.ts +100 -0
  22. package/data/section-templates/category-images-section/children/CategoryImageItem/ikas-config-snippet.json +4 -0
  23. package/data/section-templates/category-images-section/ikas-config-snippet.json +15 -0
  24. package/data/section-templates/category-list-section/children/CardProductName/ikas-config-snippet.json +2 -1
  25. package/data/section-templates/category-list-section/ikas-config-snippet.json +21 -0
  26. package/data/section-templates/category-list-section/index.tsx +2 -1
  27. package/data/section-templates/component-renderer/additional/ProductDetail/index.tsx +5 -1
  28. package/data/section-templates/component-renderer/ikas-config-snippet.json +13 -0
  29. package/data/section-templates/favorites/ikas-config-snippet.json +18 -1
  30. package/data/section-templates/features-section/ikas-config-snippet.json +13 -0
  31. package/data/section-templates/footer-section/ikas-config-snippet.json +15 -0
  32. package/data/section-templates/forgot-password-section/components/ForgotPasswordForm/index.tsx +1 -1
  33. package/data/section-templates/header-section/children/Announcements/ikas-config-snippet.json +7 -0
  34. package/data/section-templates/header-section/children/CookieBar/ikas-config-snippet.json +3 -0
  35. package/data/section-templates/header-section/children/Navbar/components/CartSidebar/index.tsx +2 -1
  36. package/data/section-templates/header-section/children/Navbar/components/SearchModal/index.tsx +2 -1
  37. package/data/section-templates/header-section/children/Navbar/ikas-config-snippet.json +27 -0
  38. package/data/section-templates/header-section/children/Navbar/index.tsx +6 -5
  39. package/data/section-templates/header-section/ikas-config-snippet.json +13 -0
  40. package/data/section-templates/header-section/sub-components/CartItem/index.tsx +66 -24
  41. package/data/section-templates/header-section/sub-components/CartItem/styles.css +14 -0
  42. package/data/section-templates/header-section/sub-components/QuantitySelector/index.tsx +11 -3
  43. package/data/section-templates/header-section/utils/cartLimits.ts +24 -0
  44. package/data/section-templates/header-section/utils/cartLineLimits.ts +100 -0
  45. package/data/section-templates/hero-slider-section/children/HeroSliderItem/ikas-config-snippet.json +18 -0
  46. package/data/section-templates/hero-slider-section/children/HeroSliderItem/index.tsx +12 -7
  47. package/data/section-templates/hero-slider-section/ikas-config-snippet.json +13 -0
  48. package/data/section-templates/image-handling/ikas-config-snippet.json +53 -0
  49. package/data/section-templates/image-handling/index.tsx +5 -1
  50. package/data/section-templates/login-section/ikas-config-snippet.json +2 -0
  51. package/data/section-templates/navigation/components/CartSidebar/index.tsx +2 -1
  52. package/data/section-templates/navigation/components/SearchModal/index.tsx +2 -1
  53. package/data/section-templates/navigation/ikas-config-snippet.json +27 -0
  54. package/data/section-templates/navigation/index.tsx +6 -5
  55. package/data/section-templates/navigation/sub-components/CartItem/index.tsx +66 -24
  56. package/data/section-templates/navigation/sub-components/CartItem/styles.css +14 -0
  57. package/data/section-templates/navigation/sub-components/QuantitySelector/index.tsx +11 -3
  58. package/data/section-templates/navigation/utils/cartLimits.ts +24 -0
  59. package/data/section-templates/navigation/utils/cartLineLimits.ts +100 -0
  60. package/data/section-templates/product-detail-section/children/ProductDetailAddToCart/ikas-config-snippet.json +17 -0
  61. package/data/section-templates/product-detail-section/children/ProductDetailAddToCart/index.tsx +16 -2
  62. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/components/BackInStockForm/index.tsx +92 -0
  63. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/ikas-config-snippet.json +175 -0
  64. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/index.tsx +141 -0
  65. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/styles.css +47 -0
  66. package/data/section-templates/product-detail-section/children/ProductDetailBackInStock/types.ts +25 -0
  67. package/data/section-templates/product-detail-section/children/ProductDetailBundleFurniture/ikas-config-snippet.json +18 -0
  68. package/data/section-templates/product-detail-section/children/ProductDetailBundleProduct/ikas-config-snippet.json +20 -0
  69. package/data/section-templates/product-detail-section/children/ProductDetailDescription/ikas-config-snippet.json +27 -0
  70. package/data/section-templates/product-detail-section/children/ProductDetailFeatures/ikas-config-snippet.json +29 -0
  71. package/data/section-templates/product-detail-section/children/ProductDetailNameFavorite/ikas-config-snippet.json +18 -1
  72. package/data/section-templates/product-detail-section/children/ProductDetailOffer/ikas-config-snippet.json +20 -0
  73. package/data/section-templates/product-detail-section/children/ProductDetailOptionSet/ikas-config-snippet.json +16 -0
  74. package/data/section-templates/product-detail-section/children/ProductDetailPrices/ikas-config-snippet.json +16 -0
  75. package/data/section-templates/product-detail-section/children/ProductDetailProductGroup/ikas-config-snippet.json +16 -0
  76. package/data/section-templates/product-detail-section/children/ProductDetailSku/ikas-config-snippet.json +16 -0
  77. package/data/section-templates/product-detail-section/children/ProductDetailVariant/ikas-config-snippet.json +17 -0
  78. package/data/section-templates/product-detail-section/hooks/useBundleProducts.ts +7 -6
  79. package/data/section-templates/product-detail-section/ikas-config-snippet.json +53 -0
  80. package/data/section-templates/product-detail-section/index.tsx +5 -1
  81. package/data/section-templates/product-detail-section/sub-components/Modal/index.tsx +120 -0
  82. package/data/section-templates/product-detail-section/sub-components/Modal/styles.css +70 -0
  83. package/data/section-templates/product-detail-section/sub-components/QuantitySelector/index.tsx +11 -3
  84. package/data/section-templates/product-detail-section/utils/cartLimits.ts +24 -0
  85. package/data/section-templates/product-pricing/ikas-config-snippet.json +16 -0
  86. package/data/section-templates/product-slider-section/children/CardProductName/ikas-config-snippet.json +2 -1
  87. package/data/section-templates/product-slider-section/ikas-config-snippet.json +17 -0
  88. package/data/section-templates/register-section/ikas-config-snippet.json +2 -0
  89. package/data/section-templates/variant-selection/ikas-config-snippet.json +17 -0
  90. package/data/storefront-api.json +1046 -80
  91. package/data/storefront-types.json +9868 -6037
  92. package/dist/index.js +2578 -257
  93. package/dist/index.js.map +1 -1
  94. package/package.json +1 -1
@@ -14,9 +14,12 @@ import {
14
14
  getOrderLineItemFormattedOverridenPriceWithQuantity,
15
15
  hasOrderLineItemDiscount,
16
16
  getOrderLineItemOverridenPriceWithQuantity,
17
+ cartStore,
18
+ isOrderLineItemAutoCreated,
17
19
  } from "@ikas/bp-storefront";
18
20
  import { resolveAspectRatio, resolveObjectFit } from "../../utils/media";
19
21
  import { cx } from "../../utils/cx";
22
+ import { useCartLineLimits } from "../../utils/cartLineLimits";
20
23
  import type { AspectRatio, ObjectFit } from "../../global-types";
21
24
 
22
25
  interface CartItemProps {
@@ -25,6 +28,7 @@ interface CartItemProps {
25
28
  variant?: "sidebar" | "page";
26
29
  aspectRatio?: AspectRatio;
27
30
  objectFit?: ObjectFit;
31
+ giftLabel?: string;
28
32
  }
29
33
 
30
34
  const CartItem = observer(function CartItem({
@@ -33,9 +37,29 @@ const CartItem = observer(function CartItem({
33
37
  variant = "sidebar",
34
38
  aspectRatio,
35
39
  objectFit,
40
+ giftLabel = "Gift",
36
41
  }: CartItemProps) {
37
42
  const isPage = variant === "page";
38
43
 
44
+ // The line's IkasOrderLineVariant carries no salesChannels, so the per-cart
45
+ // quantity limits come from a batched product fetch shared across all lines.
46
+ const limits = useCartLineLimits(item.variant?.productId);
47
+
48
+ // Lines a campaign added automatically (e.g. a "buy 1 get 1" gift) cannot be
49
+ // edited or removed on their own, so render them read-only with a badge.
50
+ const isAutoCreated =
51
+ !!cartStore.cart && isOrderLineItemAutoCreated(cartStore.cart, item);
52
+ const giftBadge = isAutoCreated ? (
53
+ <span className="kombos-cart-item__gift-badge text-xs-medium">
54
+ {giftLabel}
55
+ </span>
56
+ ) : null;
57
+ const staticQuantity = (
58
+ <span className="kombos-cart-item__qty-static text-sm-medium">
59
+ ×{item.quantity}
60
+ </span>
61
+ );
62
+
39
63
  const mediaStyle: Record<string, string> = {
40
64
  aspectRatio: resolveAspectRatio(aspectRatio),
41
65
  objectFit: resolveObjectFit(objectFit),
@@ -103,6 +127,7 @@ const CartItem = observer(function CartItem({
103
127
  <a href={href} className={nameClass}>
104
128
  {item.variant?.name}
105
129
  </a>
130
+ {giftBadge}
106
131
  {variantValues.length > 0 && (
107
132
  <p className="kombos-cart-item__variant-text text-sm-regular">
108
133
  {variantValues
@@ -113,19 +138,22 @@ const CartItem = observer(function CartItem({
113
138
  </p>
114
139
  )}
115
140
  </div>
116
- <button
117
- className="kombos-cart-item__remove"
118
- onClick={() => onRemove(item)}
119
- aria-label="Remove"
120
- >
121
- <TrashSVG />
122
- </button>
141
+ {!isAutoCreated && (
142
+ <button
143
+ className="kombos-cart-item__remove"
144
+ onClick={() => onRemove(item)}
145
+ aria-label="Remove"
146
+ >
147
+ <TrashSVG />
148
+ </button>
149
+ )}
123
150
  </div>
124
151
  ) : (
125
152
  <>
126
153
  <a href={href} className={nameClass}>
127
154
  {item.variant?.name}
128
155
  </a>
156
+ {giftBadge}
129
157
 
130
158
  {variantValues.length > 0 && (
131
159
  <div className="kombos-cart-item__variants">
@@ -151,11 +179,17 @@ const CartItem = observer(function CartItem({
151
179
 
152
180
  {isPage ? (
153
181
  <div className="kombos-cart-item__bottom">
154
- <QuantitySelector
155
- size="sm"
156
- value={item.quantity}
157
- onChange={(qty) => changeItemQuantity(item, qty)}
158
- />
182
+ {isAutoCreated ? (
183
+ staticQuantity
184
+ ) : (
185
+ <QuantitySelector
186
+ size="sm"
187
+ value={item.quantity}
188
+ min={limits?.min ?? 1}
189
+ max={limits?.max}
190
+ onChange={(qty) => changeItemQuantity(item, qty)}
191
+ />
192
+ )}
159
193
  <div className="kombos-cart-item__prices">
160
194
  {hasDiscount && (
161
195
  <span className="kombos-cart-item__original-price text-sm-regular-strike">
@@ -193,18 +227,26 @@ const CartItem = observer(function CartItem({
193
227
  </div>
194
228
 
195
229
  <div className="kombos-cart-item__actions">
196
- <QuantitySelector
197
- size="sm"
198
- value={item.quantity}
199
- onChange={(qty) => changeItemQuantity(item, qty)}
200
- />
201
- <button
202
- className="kombos-cart-item__remove"
203
- onClick={() => onRemove(item)}
204
- aria-label="Remove"
205
- >
206
- <TrashSVG />
207
- </button>
230
+ {isAutoCreated ? (
231
+ staticQuantity
232
+ ) : (
233
+ <>
234
+ <QuantitySelector
235
+ size="sm"
236
+ value={item.quantity}
237
+ min={limits?.min ?? 1}
238
+ max={limits?.max}
239
+ onChange={(qty) => changeItemQuantity(item, qty)}
240
+ />
241
+ <button
242
+ className="kombos-cart-item__remove"
243
+ onClick={() => onRemove(item)}
244
+ aria-label="Remove"
245
+ >
246
+ <TrashSVG />
247
+ </button>
248
+ </>
249
+ )}
208
250
  </div>
209
251
  </>
210
252
  )}
@@ -168,3 +168,17 @@
168
168
  flex-shrink: 0;
169
169
  }
170
170
 
171
+ /* Auto-created (campaign gift) line: badge + read-only quantity */
172
+ .kombos-cart-item__gift-badge {
173
+ display: inline-flex;
174
+ align-self: flex-start;
175
+ padding: 0.125rem 0.5rem;
176
+ border-radius: 999px;
177
+ background: var(--kombos-gray-100);
178
+ color: var(--kombos-gray-500);
179
+ }
180
+
181
+ .kombos-cart-item__qty-static {
182
+ color: var(--kombos-gray-500);
183
+ }
184
+
@@ -5,20 +5,27 @@ interface Props {
5
5
  value: number;
6
6
  onChange: (value: number) => void;
7
7
  size?: "default" | "sm";
8
+ min?: number;
9
+ max?: number;
8
10
  }
9
11
 
10
12
  export default function QuantitySelector({
11
13
  value,
12
14
  onChange,
13
15
  size = "default",
16
+ min = 1,
17
+ max,
14
18
  }: Props) {
19
+ const canDecrease = value > min;
20
+ const canIncrease = max == null || value < max;
21
+
15
22
  return (
16
23
  <div className={cx("kombos-pd__qty", size === "sm" && "kombos-pd__qty--sm")}>
17
24
  <button
18
25
  type="button"
19
26
  className="kombos-pd__qty-btn"
20
- onClick={() => onChange(Math.max(1, value - 1))}
21
- disabled={value <= 1}
27
+ onClick={() => onChange(Math.max(min, value - 1))}
28
+ disabled={!canDecrease}
22
29
  aria-label="Decrease quantity"
23
30
  >
24
31
  <MinusSVG />
@@ -31,7 +38,8 @@ export default function QuantitySelector({
31
38
  <button
32
39
  type="button"
33
40
  className="kombos-pd__qty-btn"
34
- onClick={() => onChange(value + 1)}
41
+ onClick={() => onChange(max == null ? value + 1 : Math.min(max, value + 1))}
42
+ disabled={!canIncrease}
35
43
  aria-label="Increase quantity"
36
44
  >
37
45
  <PlusSVG />
@@ -0,0 +1,24 @@
1
+ import { IkasProduct, IkasStorefrontConfig } from "@ikas/bp-storefront";
2
+
3
+ export interface CartQuantityLimits {
4
+ min: number;
5
+ max?: number;
6
+ }
7
+
8
+ /**
9
+ * Resolve the per-cart quantity limits for a product from its active sales
10
+ * channel. Falls back to a minimum of 1 and no maximum when the channel or its
11
+ * limits are not set. `addItemToCart` clamps to the same limits internally only
12
+ * when it creates a NEW cart line — incrementing an existing line goes through
13
+ * `changeItemQuantity`, which never clamps — so enforcing these in the stepper
14
+ * is the only guard that covers both paths.
15
+ */
16
+ export function getProductCartLimits(product: IkasProduct): CartQuantityLimits {
17
+ const channel = product.salesChannels?.find(
18
+ (sc) => sc.id === IkasStorefrontConfig.salesChannelId,
19
+ );
20
+ return {
21
+ min: channel?.minQuantityPerCart ?? 1,
22
+ max: channel?.maxQuantityPerCart ?? undefined,
23
+ };
24
+ }
@@ -0,0 +1,100 @@
1
+ import { useEffect, useState } from "preact/hooks";
2
+ import { baseStore, bs_searchProductsById } from "@ikas/bp-storefront";
3
+ import { CartQuantityLimits, getProductCartLimits } from "./cartLimits";
4
+
5
+ /**
6
+ * Per-cart quantity limits for cart lines.
7
+ *
8
+ * A cart line's `IkasOrderLineVariant` carries no `salesChannels`, so the
9
+ * min/max per-cart limits can only be read from the full `IkasProduct`. This
10
+ * store batch-fetches the line products with `bs_searchProductsById` (lines
11
+ * register their productId one by one; the ids are flushed as ONE request on
12
+ * the next tick) and maps the resolved limits by product id for the cart
13
+ * steppers to read. Each product is fetched at most once; results stay cached
14
+ * for the session.
15
+ */
16
+
17
+ const limitsByProductId = new Map<string, CartQuantityLimits>();
18
+ const requestedProductIds = new Set<string>();
19
+ const listeners = new Set<() => void>();
20
+
21
+ let pendingProductIds: string[] = [];
22
+ let flushTimer: ReturnType<typeof setTimeout> | null = null;
23
+
24
+ function emit() {
25
+ for (const listener of listeners) listener();
26
+ }
27
+
28
+ async function flush() {
29
+ flushTimer = null;
30
+ const batch = pendingProductIds;
31
+ pendingProductIds = [];
32
+
33
+ // bs_searchProductsById never throws — API/network failures resolve with
34
+ // isSuccess: false — so the retry unmark must live on the result check.
35
+ const result = await bs_searchProductsById(baseStore, { productIds: batch }).catch(
36
+ () => null,
37
+ );
38
+ if (!result?.isSuccess || !result.products) {
39
+ // Limits stay unenforced for now; unmark the batch so a later
40
+ // ensureCartLineLimits call (e.g. the next cart open) can retry.
41
+ for (const id of batch) requestedProductIds.delete(id);
42
+ return;
43
+ }
44
+
45
+ for (const product of result.products) {
46
+ limitsByProductId.set(product.id, getProductCartLimits(product));
47
+ }
48
+ emit();
49
+ }
50
+
51
+ /**
52
+ * Register a cart line's productId for limit resolution. Ids already requested
53
+ * are skipped; new ids are collected and fetched in a single batched request
54
+ * on the next tick, so per-line calls do not fan out into per-line requests.
55
+ */
56
+ export function ensureCartLineLimits(productId: string) {
57
+ if (requestedProductIds.has(productId)) return;
58
+ requestedProductIds.add(productId);
59
+ pendingProductIds.push(productId);
60
+ if (!flushTimer) flushTimer = setTimeout(flush, 0);
61
+ }
62
+
63
+ /** Resolved limits for a product — undefined until the batch fetch lands. */
64
+ export function getCartLineLimits(
65
+ productId: string | null | undefined,
66
+ ): CartQuantityLimits | undefined {
67
+ return productId ? limitsByProductId.get(productId) : undefined;
68
+ }
69
+
70
+ /** Subscribe to limit resolutions; returns the unsubscribe function. */
71
+ export function subscribeCartLineLimits(listener: () => void) {
72
+ listeners.add(listener);
73
+ return () => {
74
+ listeners.delete(listener);
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Hook: resolved limits for one cart line's product — undefined until the
80
+ * batched fetch lands. Encapsulates the subscription protocol so components
81
+ * cannot get the ordering wrong.
82
+ */
83
+ export function useCartLineLimits(
84
+ productId: string | null | undefined,
85
+ ): CartQuantityLimits | undefined {
86
+ const [, setVersion] = useState(0);
87
+ const limits = getCartLineLimits(productId);
88
+ useEffect(() => {
89
+ if (!productId) return;
90
+ // Subscribe BEFORE registering the id: a batch already in flight can
91
+ // resolve between render and this effect, and its emit must not be missed.
92
+ const unsubscribe = subscribeCartLineLimits(() => setVersion((v) => v + 1));
93
+ ensureCartLineLimits(productId);
94
+ // Re-check once for a result that landed before the subscription armed —
95
+ // skipped when the arming render already saw it (no redundant re-render).
96
+ if (!limits && getCartLineLimits(productId)) setVersion((v) => v + 1);
97
+ return unsubscribe;
98
+ }, [productId]);
99
+ return limits;
100
+ }
@@ -24,6 +24,7 @@
24
24
  "displayName": "Dark Overlay",
25
25
  "type": "BOOLEAN",
26
26
  "required": false,
27
+ "defaultValue": false,
27
28
  "groupId": "desktop"
28
29
  },
29
30
  {
@@ -39,6 +40,7 @@
39
40
  "displayName": "Image Fit",
40
41
  "type": "ENUM",
41
42
  "required": false,
43
+ "defaultValue": "Cover",
42
44
  "groupId": "desktop",
43
45
  "enumTypeId": "{{ENUM_ID:ObjectFit}}"
44
46
  },
@@ -61,6 +63,7 @@
61
63
  "displayName": "Dark Overlay",
62
64
  "type": "BOOLEAN",
63
65
  "required": false,
66
+ "defaultValue": false,
64
67
  "groupId": "mobile"
65
68
  },
66
69
  {
@@ -76,6 +79,7 @@
76
79
  "displayName": "Image Fit",
77
80
  "type": "ENUM",
78
81
  "required": false,
82
+ "defaultValue": "Cover",
79
83
  "groupId": "mobile",
80
84
  "enumTypeId": "{{ENUM_ID:ObjectFit}}"
81
85
  }
@@ -18,6 +18,7 @@
18
18
  "displayName": "Title Color",
19
19
  "type": "COLOR",
20
20
  "required": false,
21
+ "defaultValue": "#14141a",
21
22
  "groupId": "content"
22
23
  },
23
24
  {
@@ -41,6 +42,7 @@
41
42
  "displayName": "Mobile Column Count",
42
43
  "type": "ENUM",
43
44
  "required": false,
45
+ "defaultValue": "One",
44
46
  "groupId": "appearance",
45
47
  "enumTypeId": "{{ENUM_ID:NumberOfColumns}}"
46
48
  },
@@ -49,6 +51,19 @@
49
51
  "displayName": "Categories",
50
52
  "type": "COMPONENT_LIST",
51
53
  "required": false,
54
+ "defaultValue": {
55
+ "components": [
56
+ {
57
+ "codeComponentId": "nb34u3yu-category-image-item"
58
+ },
59
+ {
60
+ "codeComponentId": "nb34u3yu-category-image-item"
61
+ },
62
+ {
63
+ "codeComponentId": "nb34u3yu-category-image-item"
64
+ }
65
+ ]
66
+ },
52
67
  "filteredComponentIds": [
53
68
  "<id-of-CategoryImageItem>"
54
69
  ]
@@ -15,7 +15,8 @@
15
15
  "name": "singleLineName",
16
16
  "displayName": "Single Row First Name",
17
17
  "type": "BOOLEAN",
18
- "required": false
18
+ "required": false,
19
+ "defaultValue": false
19
20
  }
20
21
  ]
21
22
  }
@@ -111,6 +111,7 @@
111
111
  "displayName": "Show Filters",
112
112
  "type": "BOOLEAN",
113
113
  "required": false,
114
+ "defaultValue": false,
114
115
  "groupId": "filters"
115
116
  },
116
117
  {
@@ -118,6 +119,7 @@
118
119
  "displayName": "Show Search",
119
120
  "type": "BOOLEAN",
120
121
  "required": false,
122
+ "defaultValue": false,
121
123
  "groupId": "filters"
122
124
  },
123
125
  {
@@ -125,6 +127,7 @@
125
127
  "displayName": "Image Aspect Ratio",
126
128
  "type": "ENUM",
127
129
  "required": false,
130
+ "defaultValue": "Square",
128
131
  "groupId": "image-settings",
129
132
  "enumTypeId": "{{ENUM_ID:AspectRatio}}"
130
133
  },
@@ -133,6 +136,7 @@
133
136
  "displayName": "Image Fit",
134
137
  "type": "ENUM",
135
138
  "required": false,
139
+ "defaultValue": "Cover",
136
140
  "groupId": "image-settings",
137
141
  "enumTypeId": "{{ENUM_ID:ObjectFit}}"
138
142
  },
@@ -141,6 +145,7 @@
141
145
  "displayName": "Infinite Scroll",
142
146
  "type": "BOOLEAN",
143
147
  "required": false,
148
+ "defaultValue": false,
144
149
  "groupId": "pagination"
145
150
  },
146
151
  {
@@ -164,6 +169,7 @@
164
169
  "displayName": "Hide Add to Cart Button",
165
170
  "type": "BOOLEAN",
166
171
  "required": false,
172
+ "defaultValue": false,
167
173
  "groupId": "card-settings"
168
174
  },
169
175
  {
@@ -171,6 +177,19 @@
171
177
  "displayName": "Components",
172
178
  "type": "COMPONENT_LIST",
173
179
  "required": false,
180
+ "defaultValue": {
181
+ "components": [
182
+ {
183
+ "codeComponentId": "nb34u3yu-card-product-name"
184
+ },
185
+ {
186
+ "codeComponentId": "nb34u3yu-card-product-variants"
187
+ },
188
+ {
189
+ "codeComponentId": "nb34u3yu-card-product-price"
190
+ }
191
+ ]
192
+ },
174
193
  "privateVarMap": {
175
194
  "product": {
176
195
  "id": "pvm_1772808304776_3",
@@ -188,6 +207,7 @@
188
207
  "displayName": "Hide Breadcrumb",
189
208
  "type": "BOOLEAN",
190
209
  "required": false,
210
+ "defaultValue": false,
191
211
  "groupId": "appearance"
192
212
  },
193
213
  {
@@ -195,6 +215,7 @@
195
215
  "displayName": "Is This a Brand Page?",
196
216
  "type": "BOOLEAN",
197
217
  "required": false,
218
+ "defaultValue": false,
198
219
  "groupId": "data"
199
220
  },
200
221
  {
@@ -21,6 +21,7 @@ import {
21
21
  searchProductList,
22
22
  getProductOptionSet,
23
23
  IkasComponentRenderer,
24
+ withRoutePrefix,
24
25
  } from "@ikas/bp-storefront";
25
26
  import { Props } from "./types";
26
27
  import ProductCard from "../../sub-components/ProductCard";
@@ -170,7 +171,7 @@ export function CategoryList(props: Props) {
170
171
  const path = getCategoryPath(category);
171
172
  if (path.length === 0) return [];
172
173
  return [
173
- { label: homepageText, href: "/" } as BreadcrumbItem,
174
+ { label: homepageText, href: withRoutePrefix("/") } as BreadcrumbItem,
174
175
  ...path.map(
175
176
  (cat: any) =>
176
177
  ({
@@ -6,6 +6,7 @@ import {
6
6
  IkasImage,
7
7
  isNotEmpty,
8
8
  IkasComponentRenderer,
9
+ withRoutePrefix,
9
10
  } from "@ikas/bp-storefront";
10
11
  import { Props } from "./types";
11
12
  import Breadcrumb from "../../sub-components/Breadcrumb";
@@ -42,7 +43,10 @@ export function ProductDetail(props: Props) {
42
43
  <div className="kombos-container kombos-pd__container">
43
44
  <Breadcrumb
44
45
  items={[
45
- { label: homepageText, href: "/" } as BreadcrumbItem,
46
+ {
47
+ label: homepageText,
48
+ href: withRoutePrefix("/"),
49
+ } as BreadcrumbItem,
46
50
  ...(isNotEmpty(categoryPath)
47
51
  ? categoryPath.map(
48
52
  (pathItem: any) =>
@@ -10,6 +10,19 @@
10
10
  "displayName": "Components",
11
11
  "type": "COMPONENT_LIST",
12
12
  "required": false,
13
+ "defaultValue": {
14
+ "components": [
15
+ {
16
+ "codeComponentId": "nb34u3yu-announcements"
17
+ },
18
+ {
19
+ "codeComponentId": "nb34u3yu-navbar"
20
+ },
21
+ {
22
+ "codeComponentId": "nb34u3yu-cookie-bar"
23
+ }
24
+ ]
25
+ },
13
26
  "filteredComponentIds": [
14
27
  "<id-of-Navbar>",
15
28
  "<id-of-Announcements>",
@@ -16,6 +16,10 @@
16
16
  "displayName": "Top Spacing",
17
17
  "type": "TYPE",
18
18
  "required": false,
19
+ "defaultValue": {
20
+ "value": 0,
21
+ "unit": "px"
22
+ },
19
23
  "groupId": "mobile",
20
24
  "typeId": "@ikas/bp-storefront-models-MarginTopStyleType"
21
25
  },
@@ -24,6 +28,10 @@
24
28
  "displayName": "Bottom Spacing",
25
29
  "type": "TYPE",
26
30
  "required": false,
31
+ "defaultValue": {
32
+ "value": 0,
33
+ "unit": "px"
34
+ },
27
35
  "groupId": "mobile",
28
36
  "typeId": "@ikas/bp-storefront-models-MarginBottomStyleType"
29
37
  },
@@ -32,6 +40,10 @@
32
40
  "displayName": "Top Spacing",
33
41
  "type": "TYPE",
34
42
  "required": false,
43
+ "defaultValue": {
44
+ "value": 0,
45
+ "unit": "px"
46
+ },
35
47
  "groupId": "desktop",
36
48
  "typeId": "@ikas/bp-storefront-models-MarginTopStyleType"
37
49
  },
@@ -40,6 +52,10 @@
40
52
  "displayName": "Bottom Spacing",
41
53
  "type": "TYPE",
42
54
  "required": false,
55
+ "defaultValue": {
56
+ "value": 0,
57
+ "unit": "px"
58
+ },
43
59
  "groupId": "desktop",
44
60
  "typeId": "@ikas/bp-storefront-models-MarginBottomStyleType"
45
61
  },
@@ -47,7 +63,8 @@
47
63
  "name": "hideFavoriteButton",
48
64
  "displayName": "Hide Favorite Button",
49
65
  "type": "BOOLEAN",
50
- "required": false
66
+ "required": false,
67
+ "defaultValue": false
51
68
  }
52
69
  ],
53
70
  "propGroups": [
@@ -17,6 +17,19 @@
17
17
  "displayName": "Specifications",
18
18
  "type": "COMPONENT_LIST",
19
19
  "required": false,
20
+ "defaultValue": {
21
+ "components": [
22
+ {
23
+ "codeComponentId": "nb34u3yu-feature-item"
24
+ },
25
+ {
26
+ "codeComponentId": "nb34u3yu-feature-item"
27
+ },
28
+ {
29
+ "codeComponentId": "nb34u3yu-feature-item"
30
+ }
31
+ ]
32
+ },
20
33
  "filteredComponentIds": [
21
34
  "<id-of-FeatureItem>"
22
35
  ]
@@ -39,6 +39,7 @@
39
39
  "displayName": "Link Color",
40
40
  "type": "COLOR",
41
41
  "required": false,
42
+ "defaultValue": "#2e2e33",
42
43
  "groupId": "appearance"
43
44
  },
44
45
  {
@@ -46,6 +47,7 @@
46
47
  "displayName": "Link Hover Color",
47
48
  "type": "COLOR",
48
49
  "required": false,
50
+ "defaultValue": "#14141a",
49
51
  "groupId": "appearance"
50
52
  },
51
53
  {
@@ -75,6 +77,19 @@
75
77
  "displayName": "Social Media Icons",
76
78
  "type": "COMPONENT_LIST",
77
79
  "required": false,
80
+ "defaultValue": {
81
+ "components": [
82
+ {
83
+ "codeComponentId": "nb34u3yu-social-media-icon"
84
+ },
85
+ {
86
+ "codeComponentId": "nb34u3yu-social-media-icon"
87
+ },
88
+ {
89
+ "codeComponentId": "nb34u3yu-social-media-icon"
90
+ }
91
+ ]
92
+ },
78
93
  "filteredComponentIds": [
79
94
  "<id-of-SocialMediaIcon>"
80
95
  ]
@@ -49,7 +49,7 @@ const ForgotPasswordForm = observer(function ForgotPasswordForm({
49
49
  variant="primary"
50
50
  size="s"
51
51
  className="forgot-password__submit-btn"
52
- onClick={() => Router.navigate("/")}
52
+ onClick={() => Router.navigateToPage("INDEX")}
53
53
  >
54
54
  {successButtonText}
55
55
  </Button>