@wix/himalaya-cli 0.1593.0 → 0.1594.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.
Files changed (24) hide show
  1. package/dist/cli.mjs +1 -0
  2. package/guides/one-app-to-himi-app.md +12 -0
  3. package/package.json +2 -2
  4. package/templates/beauty-salon/dev/index.ts +216 -8
  5. package/templates/beauty-salon/tier5-src/_shared/himi-store-facets.ts +26 -2
  6. package/templates/beauty-salon/tier5-src/himi-branded-lite-category/index.ts +3 -3
  7. package/templates/beauty-salon/tier5-src/himi-branded-lite-shop/index.ts +4 -4
  8. package/templates/branded-lite/dev/index.ts +216 -8
  9. package/templates/branded-lite/tier5-src/_shared/business-chat-transport.ts +9 -0
  10. package/templates/branded-lite/tier5-src/_shared/himi-store-facets.ts +26 -2
  11. package/templates/branded-lite/tier5-src/himi-branded-lite-category/index.ts +3 -3
  12. package/templates/branded-lite/tier5-src/himi-branded-lite-shop/index.ts +3 -3
  13. package/templates/gym-fitness/dev/index.ts +216 -8
  14. package/templates/gym-fitness/tier5-src/_shared/himi-store-facets.ts +26 -2
  15. package/templates/gym-fitness/tier5-src/himi-branded-lite-category/index.ts +3 -3
  16. package/templates/gym-fitness/tier5-src/himi-branded-lite-shop/index.ts +4 -4
  17. package/templates/portfolio-creative/dev/index.ts +216 -8
  18. package/templates/portfolio-creative/tier5-src/_shared/himi-store-facets.ts +26 -2
  19. package/templates/portfolio-creative/tier5-src/himi-branded-lite-category/index.ts +3 -3
  20. package/templates/portfolio-creative/tier5-src/himi-branded-lite-shop/index.ts +4 -4
  21. package/templates/retail-store/dev/index.ts +216 -8
  22. package/templates/retail-store/tier5-src/_shared/himi-store-facets.ts +26 -2
  23. package/templates/retail-store/tier5-src/himi-branded-lite-category/index.ts +3 -3
  24. package/templates/retail-store/tier5-src/himi-branded-lite-shop/index.ts +3 -3
@@ -8465,7 +8465,33 @@ const SCREENS = runtimeSetting({
8465
8465
  "top": 2,
8466
8466
  "bottom": 2
8467
8467
  },
8468
- "hiddenPath": "$item.notOnSale"
8468
+ "hiddenPath": "$item.saleTagHidden"
8469
+ }
8470
+ },
8471
+ {
8472
+ "id": "",
8473
+ "body": {
8474
+ "package": "himalaya",
8475
+ "type": "Text",
8476
+ "props": {
8477
+ "text": "$item.ribbon",
8478
+ "style": "caption",
8479
+ "color": "accentPrimary",
8480
+ "maxLines": 1
8481
+ }
8482
+ },
8483
+ "modifiers": {
8484
+ "background": {
8485
+ "token": "accentSurface"
8486
+ },
8487
+ "cornerRadius": 6,
8488
+ "padding": {
8489
+ "leading": 6,
8490
+ "trailing": 6,
8491
+ "top": 2,
8492
+ "bottom": 2
8493
+ },
8494
+ "hiddenPath": "$item.noRibbon"
8469
8495
  }
8470
8496
  },
8471
8497
  {
@@ -8908,7 +8934,33 @@ const SCREENS = runtimeSetting({
8908
8934
  "top": 2,
8909
8935
  "bottom": 2
8910
8936
  },
8911
- "hiddenPath": "$item.notOnSale"
8937
+ "hiddenPath": "$item.saleTagHidden"
8938
+ }
8939
+ },
8940
+ {
8941
+ "id": "",
8942
+ "body": {
8943
+ "package": "himalaya",
8944
+ "type": "Text",
8945
+ "props": {
8946
+ "text": "$item.ribbon",
8947
+ "style": "caption",
8948
+ "color": "accentPrimary",
8949
+ "maxLines": 1
8950
+ }
8951
+ },
8952
+ "modifiers": {
8953
+ "background": {
8954
+ "token": "accentSurface"
8955
+ },
8956
+ "cornerRadius": 6,
8957
+ "padding": {
8958
+ "leading": 6,
8959
+ "trailing": 6,
8960
+ "top": 2,
8961
+ "bottom": 2
8962
+ },
8963
+ "hiddenPath": "$item.noRibbon"
8912
8964
  }
8913
8965
  },
8914
8966
  {
@@ -9383,7 +9435,33 @@ const SCREENS = runtimeSetting({
9383
9435
  "top": 2,
9384
9436
  "bottom": 2
9385
9437
  },
9386
- "hiddenPath": "$item.notOnSale"
9438
+ "hiddenPath": "$item.saleTagHidden"
9439
+ }
9440
+ },
9441
+ {
9442
+ "id": "",
9443
+ "body": {
9444
+ "package": "himalaya",
9445
+ "type": "Text",
9446
+ "props": {
9447
+ "text": "$item.ribbon",
9448
+ "style": "caption",
9449
+ "color": "accentPrimary",
9450
+ "maxLines": 1
9451
+ }
9452
+ },
9453
+ "modifiers": {
9454
+ "background": {
9455
+ "token": "accentSurface"
9456
+ },
9457
+ "cornerRadius": 6,
9458
+ "padding": {
9459
+ "leading": 6,
9460
+ "trailing": 6,
9461
+ "top": 2,
9462
+ "bottom": 2
9463
+ },
9464
+ "hiddenPath": "$item.noRibbon"
9387
9465
  }
9388
9466
  },
9389
9467
  {
@@ -9834,7 +9912,33 @@ const SCREENS = runtimeSetting({
9834
9912
  "top": 2,
9835
9913
  "bottom": 2
9836
9914
  },
9837
- "hiddenPath": "$item.notOnSale"
9915
+ "hiddenPath": "$item.saleTagHidden"
9916
+ }
9917
+ },
9918
+ {
9919
+ "id": "",
9920
+ "body": {
9921
+ "package": "himalaya",
9922
+ "type": "Text",
9923
+ "props": {
9924
+ "text": "$item.ribbon",
9925
+ "style": "caption",
9926
+ "color": "accentPrimary",
9927
+ "maxLines": 1
9928
+ }
9929
+ },
9930
+ "modifiers": {
9931
+ "background": {
9932
+ "token": "accentSurface"
9933
+ },
9934
+ "cornerRadius": 6,
9935
+ "padding": {
9936
+ "leading": 6,
9937
+ "trailing": 6,
9938
+ "top": 2,
9939
+ "bottom": 2
9940
+ },
9941
+ "hiddenPath": "$item.noRibbon"
9838
9942
  }
9839
9943
  },
9840
9944
  {
@@ -12464,7 +12568,33 @@ const SCREENS = runtimeSetting({
12464
12568
  "top": 2,
12465
12569
  "bottom": 2
12466
12570
  },
12467
- "hiddenPath": "$item.notOnSale"
12571
+ "hiddenPath": "$item.saleTagHidden"
12572
+ }
12573
+ },
12574
+ {
12575
+ "id": "",
12576
+ "body": {
12577
+ "package": "himalaya",
12578
+ "type": "Text",
12579
+ "props": {
12580
+ "text": "$item.ribbon",
12581
+ "style": "caption",
12582
+ "color": "accentPrimary",
12583
+ "maxLines": 1
12584
+ }
12585
+ },
12586
+ "modifiers": {
12587
+ "background": {
12588
+ "token": "accentSurface"
12589
+ },
12590
+ "cornerRadius": 6,
12591
+ "padding": {
12592
+ "leading": 6,
12593
+ "trailing": 6,
12594
+ "top": 2,
12595
+ "bottom": 2
12596
+ },
12597
+ "hiddenPath": "$item.noRibbon"
12468
12598
  }
12469
12599
  },
12470
12600
  {
@@ -12920,7 +13050,33 @@ const SCREENS = runtimeSetting({
12920
13050
  "top": 2,
12921
13051
  "bottom": 2
12922
13052
  },
12923
- "hiddenPath": "$item.notOnSale"
13053
+ "hiddenPath": "$item.saleTagHidden"
13054
+ }
13055
+ },
13056
+ {
13057
+ "id": "",
13058
+ "body": {
13059
+ "package": "himalaya",
13060
+ "type": "Text",
13061
+ "props": {
13062
+ "text": "$item.ribbon",
13063
+ "style": "caption",
13064
+ "color": "accentPrimary",
13065
+ "maxLines": 1
13066
+ }
13067
+ },
13068
+ "modifiers": {
13069
+ "background": {
13070
+ "token": "accentSurface"
13071
+ },
13072
+ "cornerRadius": 6,
13073
+ "padding": {
13074
+ "leading": 6,
13075
+ "trailing": 6,
13076
+ "top": 2,
13077
+ "bottom": 2
13078
+ },
13079
+ "hiddenPath": "$item.noRibbon"
12924
13080
  }
12925
13081
  },
12926
13082
  {
@@ -13408,7 +13564,33 @@ const SCREENS = runtimeSetting({
13408
13564
  "top": 2,
13409
13565
  "bottom": 2
13410
13566
  },
13411
- "hiddenPath": "$item.notOnSale"
13567
+ "hiddenPath": "$item.saleTagHidden"
13568
+ }
13569
+ },
13570
+ {
13571
+ "id": "",
13572
+ "body": {
13573
+ "package": "himalaya",
13574
+ "type": "Text",
13575
+ "props": {
13576
+ "text": "$item.ribbon",
13577
+ "style": "caption",
13578
+ "color": "accentPrimary",
13579
+ "maxLines": 1
13580
+ }
13581
+ },
13582
+ "modifiers": {
13583
+ "background": {
13584
+ "token": "accentSurface"
13585
+ },
13586
+ "cornerRadius": 6,
13587
+ "padding": {
13588
+ "leading": 6,
13589
+ "trailing": 6,
13590
+ "top": 2,
13591
+ "bottom": 2
13592
+ },
13593
+ "hiddenPath": "$item.noRibbon"
13412
13594
  }
13413
13595
  },
13414
13596
  {
@@ -13872,7 +14054,33 @@ const SCREENS = runtimeSetting({
13872
14054
  "top": 2,
13873
14055
  "bottom": 2
13874
14056
  },
13875
- "hiddenPath": "$item.notOnSale"
14057
+ "hiddenPath": "$item.saleTagHidden"
14058
+ }
14059
+ },
14060
+ {
14061
+ "id": "",
14062
+ "body": {
14063
+ "package": "himalaya",
14064
+ "type": "Text",
14065
+ "props": {
14066
+ "text": "$item.ribbon",
14067
+ "style": "caption",
14068
+ "color": "accentPrimary",
14069
+ "maxLines": 1
14070
+ }
14071
+ },
14072
+ "modifiers": {
14073
+ "background": {
14074
+ "token": "accentSurface"
14075
+ },
14076
+ "cornerRadius": 6,
14077
+ "padding": {
14078
+ "leading": 6,
14079
+ "trailing": 6,
14080
+ "top": 2,
14081
+ "bottom": 2
14082
+ },
14083
+ "hiddenPath": "$item.noRibbon"
13876
14084
  }
13877
14085
  },
13878
14086
  {
@@ -58,8 +58,14 @@ export interface ProductCard {
58
58
  swatch1: string; swatch2: string; swatch3: string; swatch4: string; swatch5: string;
59
59
  swatch1Hidden: boolean; swatch2Hidden: boolean; swatch3Hidden: boolean; swatch4Hidden: boolean; swatch5Hidden: boolean;
60
60
  noSwatches: boolean;
61
- /** Hides the Sale tag / swatch row when it has nothing to show. */
61
+ /** Hides the tag row (Sale tag, ribbon, swatches) when it has nothing to show. */
62
62
  noTagRow: boolean;
63
+ /** The merchant's ribbon text ("New", "Best Seller"…), "" when the product has none. The ribbon replaces
64
+ * the price-derived Sale tag, so a product never carries two tags. */
65
+ ribbon: string;
66
+ noRibbon: boolean;
67
+ /** Hides the price-derived Sale tag: the product is not on sale, or its ribbon takes the tag's place. */
68
+ saleTagHidden: boolean;
63
69
  /** The Wix price before any App Store presentation rewrites `price`. */
64
70
  commercePrice: string;
65
71
  /** Original Wix sale metadata retained when App Store presentation hides it. */
@@ -179,6 +185,21 @@ function swatchFields(hexes: string[], onSale: boolean) {
179
185
  };
180
186
  }
181
187
 
188
+ /** The ribbon the merchant set, whichever catalog answered: V3 `{ id, name }`, V1 a plain string. Read through a
189
+ * local type, not a `StoreProduct` member: other workers already extend that type with their own `ribbon`. */
190
+ export function ribbonText(p: StoreProduct): string {
191
+ const ribbon = (p as { ribbon?: unknown }).ribbon;
192
+ const name = typeof ribbon === "string" ? ribbon : typeof (ribbon as { name?: unknown } | null | undefined)?.name === "string" ? (ribbon as { name: string }).name : "";
193
+ return name.trim();
194
+ }
195
+
196
+ /** What the tag row (Sale tag, ribbon, swatches) shows. One rule for every screen that rebuilds it, including
197
+ * after the App Store presentation changes `onSale`: the ribbon wins over the Sale tag, so a product never
198
+ * carries two, and the row hides when it has nothing to show. */
199
+ export function tagFields(onSale: boolean, noSwatches: boolean, ribbon: string | undefined) {
200
+ return { ribbon: ribbon ?? "", noRibbon: !ribbon, saleTagHidden: !onSale || !!ribbon, noTagRow: !onSale && noSwatches && !ribbon };
201
+ }
202
+
182
203
  export function productCard(p: StoreProduct, saved: Set<string> = savedIds()): ProductCard {
183
204
  const { now, was } = prices(p);
184
205
  const groups = productOptions(p);
@@ -187,11 +208,14 @@ export function productCard(p: StoreProduct, saved: Set<string> = savedIds()): P
187
208
  const image = productImage(p);
188
209
  const id = p.id ?? "";
189
210
  const onSale = !!was;
211
+ const ribbon = ribbonText(p);
212
+ const swatches = swatchFields((color?.choices ?? []).map((c) => c.colorCode ?? ""), onSale);
190
213
  return {
191
214
  id, name, image, hasImage: !!image, noImage: !image, initial: initials(name),
192
215
  price: now, wasPrice: was, onSale, notOnSale: !onSale,
193
216
  saved: saved.has(id), notSaved: !saved.has(id),
194
- ...swatchFields((color?.choices ?? []).map((c) => c.colorCode ?? ""), onSale),
217
+ ...swatches,
218
+ ...tagFields(onSale, swatches.noSwatches, ribbon),
195
219
  commercePrice: now,
196
220
  detailScreenId: "himi_product",
197
221
  };
@@ -7,7 +7,7 @@ import { searchStoreProducts, type StoreProduct } from "../_shared/himi-store.js
7
7
  import { createCollectionQuery } from "../_shared/collection-query.js";
8
8
  import { detailInputId, presence, presenceAfterError, type PresenceFlags } from "../_shared/detail-presence.js";
9
9
  import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
10
- import { FACETS_BOOT, PAGE_SIZE, applyFacets, currencyOf, facetActions, idOf, readViewPrefs, toRows, toggleSaved, type FacetState } from "../_shared/himi-store-facets.js";
10
+ import { FACETS_BOOT, PAGE_SIZE, applyFacets, currencyOf, facetActions, idOf, readViewPrefs, tagFields, toRows, toggleSaved, type FacetState } from "../_shared/himi-store-facets.js";
11
11
  import { withIapPresentation } from "../_shared/iap-presentation.js";
12
12
 
13
13
  interface State extends FacetState, PresenceFlags {
@@ -187,8 +187,8 @@ const register = withIapPresentation<State>({
187
187
  const onSale = stored.commerceOnSale ?? row.onSale;
188
188
  return { ...row, price: price(row.id, row.commercePrice) || row.price,
189
189
  commerceWasPrice: wasPrice, commerceOnSale: onSale,
190
- ...(apple(row.id) ? { wasPrice: "", onSale: false, notOnSale: true, noTagRow: row.noSwatches }
191
- : { wasPrice, onSale, notOnSale: !onSale, noTagRow: !onSale && row.noSwatches }),
190
+ ...(apple(row.id) ? { wasPrice: "", onSale: false, notOnSale: true, ...tagFields(false, row.noSwatches, row.ribbon) }
191
+ : { wasPrice, onSale, notOnSale: !onSale, ...tagFields(onSale, row.noSwatches, row.ribbon) }),
192
192
  };
193
193
  }) }),
194
194
  });
@@ -16,7 +16,7 @@ import { withIapPresentation } from "../_shared/iap-presentation.js";
16
16
  import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
17
17
  import { loadStoreCategories, type StoreCategoryCard } from "../_shared/himi-store-categories.js";
18
18
  import {
19
- FACETS_BOOT, PAGE_SIZE, applyFacets, countText, currencyOf, facetActions, idOf, option, readViewPrefs, selected, toRows, toggleSaved,
19
+ FACETS_BOOT, PAGE_SIZE, applyFacets, countText, currencyOf, facetActions, idOf, option, readViewPrefs, selected, tagFields, toRows, toggleSaved,
20
20
  type FacetState, type Option, type ProductCard, type Row,
21
21
  } from "../_shared/himi-store-facets.js";
22
22
 
@@ -187,7 +187,7 @@ function cachedCard(value: unknown): CachedCard | undefined {
187
187
  price, wasPrice: "", onSale: false, notOnSale: true, saved: false, notSaved: true,
188
188
  swatch1: "", swatch2: "", swatch3: "", swatch4: "", swatch5: "",
189
189
  swatch1Hidden: true, swatch2Hidden: true, swatch3Hidden: true, swatch4Hidden: true, swatch5Hidden: true,
190
- noSwatches: true, noTagRow: true, commercePrice: raw.commercePrice ?? price,
190
+ noSwatches: true, ...tagFields(false, true, ""), commercePrice: raw.commercePrice ?? price,
191
191
  detailScreenId: raw.detailScreenId || "himi_product", legacyCache: true,
192
192
  };
193
193
  }
@@ -616,7 +616,7 @@ const register = withIapPresentation<S>({
616
616
  wasPrice: "",
617
617
  onSale: false,
618
618
  notOnSale: true,
619
- noTagRow: row.noSwatches,
619
+ ...tagFields(false, row.noSwatches, row.ribbon),
620
620
  };
621
621
  return {
622
622
  ...row,
@@ -624,7 +624,7 @@ const register = withIapPresentation<S>({
624
624
  wasPrice,
625
625
  onSale,
626
626
  notOnSale: !onSale,
627
- noTagRow: !onSale && row.noSwatches,
627
+ ...tagFields(onSale, row.noSwatches, row.ribbon),
628
628
  };
629
629
  }) }),
630
630
  });