@wix/himalaya-cli 0.1035.0 → 0.1036.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 (234) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +7 -1
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/display.d.ts +13 -1
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +28 -6
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores-collections.mjs +1 -1
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +7 -1
  6. package/dist/cli.mjs +23 -21
  7. package/dist/preview-assets.generated.bin +0 -0
  8. package/guides/sdk-reference.json +16 -4
  9. package/package.json +2 -2
  10. package/templates/beauty-salon/dev/index.ts +72 -175
  11. package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +16 -9
  12. package/templates/beauty-salon/tier5-src/_shared/collection-service.ts +19 -5
  13. package/templates/beauty-salon/tier5-src/_shared/engine-intl.ts +51 -0
  14. package/templates/beauty-salon/tier5-src/_shared/himi-restaurants.ts +4 -4
  15. package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +49 -0
  16. package/templates/beauty-salon/tier5-src/_shared/wix-service-price.ts +1 -1
  17. package/templates/beauty-salon/tier5-src/himi-branded-lite-info/index.ts +5 -2
  18. package/templates/beauty-salon/tier5-src/himi-branded-lite-plans/index.ts +1 -1
  19. package/templates/beauty-salon/tier5-src/wix-spaces-collections/index.ts +1 -1
  20. package/templates/beauty-salon/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  21. package/templates/beauty-salon-owner/dev/index.ts +84 -599
  22. package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +22 -6
  23. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +16 -9
  24. package/templates/beauty-salon-owner/tier5-src/_shared/collection-service.ts +19 -5
  25. package/templates/beauty-salon-owner/tier5-src/_shared/engine-intl.ts +51 -0
  26. package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  27. package/templates/branded-lite/dev/index.ts +178 -264
  28. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +16 -9
  29. package/templates/branded-lite/tier5-src/_shared/collection-service.ts +19 -5
  30. package/templates/branded-lite/tier5-src/_shared/engine-intl.ts +51 -0
  31. package/templates/branded-lite/tier5-src/_shared/himi-restaurants.ts +4 -4
  32. package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +49 -0
  33. package/templates/branded-lite/tier5-src/_shared/wix-service-price.ts +1 -1
  34. package/templates/branded-lite/tier5-src/himi-branded-lite-cms/index.ts +5 -5
  35. package/templates/branded-lite/tier5-src/himi-branded-lite-coupons/index.ts +33 -7
  36. package/templates/branded-lite/tier5-src/himi-branded-lite-donations/index.ts +3 -3
  37. package/templates/branded-lite/tier5-src/himi-branded-lite-forms/index.ts +11 -10
  38. package/templates/branded-lite/tier5-src/himi-branded-lite-giftcards/index.ts +3 -3
  39. package/templates/branded-lite/tier5-src/himi-branded-lite-info/index.ts +5 -2
  40. package/templates/branded-lite/tier5-src/himi-branded-lite-invoices/index.ts +3 -3
  41. package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +1 -1
  42. package/templates/branded-lite/tier5-src/himi-branded-lite-plans/index.ts +1 -1
  43. package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +1 -1
  44. package/templates/branded-lite/tier5-src/himi-branded-lite-reserve/index.ts +5 -3
  45. package/templates/branded-lite/tier5-src/himi-events-detail/index.ts +1 -1
  46. package/templates/branded-lite/tier5-src/himi-events-list/index.ts +20 -4
  47. package/templates/branded-lite/tier5-src/himi-events-my-events/index.ts +2 -2
  48. package/templates/branded-lite/tier5-src/wix-spaces-collections/index.ts +1 -1
  49. package/templates/branded-lite/tier5-src/wix-spaces-forum/index.ts +7 -1
  50. package/templates/branded-lite/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  51. package/templates/community-club/dev/index.ts +62 -81
  52. package/templates/community-club/tier5-src/_shared/collection-contract.ts +16 -9
  53. package/templates/community-club/tier5-src/_shared/collection-service.ts +19 -5
  54. package/templates/community-club/tier5-src/_shared/engine-intl.ts +51 -0
  55. package/templates/community-club/tier5-src/_shared/himi-restaurants.ts +4 -4
  56. package/templates/community-club/tier5-src/_shared/owner-load-error.ts +49 -0
  57. package/templates/community-club/tier5-src/_shared/wix-service-price.ts +1 -1
  58. package/templates/community-club/tier5-src/himi-branded-lite-cms/index.ts +5 -5
  59. package/templates/community-club/tier5-src/himi-branded-lite-info/index.ts +5 -2
  60. package/templates/community-club/tier5-src/himi-events-detail/index.ts +1 -1
  61. package/templates/community-club/tier5-src/himi-events-list/index.ts +20 -4
  62. package/templates/community-club/tier5-src/himi-events-my-events/index.ts +2 -2
  63. package/templates/community-club/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  64. package/templates/community-club-owner/dev/index.ts +84 -599
  65. package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +22 -6
  66. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +16 -9
  67. package/templates/community-club-owner/tier5-src/_shared/collection-service.ts +19 -5
  68. package/templates/community-club-owner/tier5-src/_shared/engine-intl.ts +51 -0
  69. package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  70. package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
  71. package/templates/events-meetups/dev/index.ts +60 -79
  72. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +16 -9
  73. package/templates/events-meetups/tier5-src/_shared/collection-service.ts +19 -5
  74. package/templates/events-meetups/tier5-src/_shared/engine-intl.ts +51 -0
  75. package/templates/events-meetups/tier5-src/_shared/himi-restaurants.ts +4 -4
  76. package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +49 -0
  77. package/templates/events-meetups/tier5-src/_shared/wix-service-price.ts +1 -1
  78. package/templates/events-meetups/tier5-src/himi-branded-lite-info/index.ts +5 -2
  79. package/templates/events-meetups/tier5-src/himi-events-detail/index.ts +1 -1
  80. package/templates/events-meetups/tier5-src/himi-events-list/index.ts +20 -4
  81. package/templates/events-meetups/tier5-src/himi-events-my-events/index.ts +2 -2
  82. package/templates/events-meetups/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  83. package/templates/events-meetups-owner/dev/index.ts +84 -543
  84. package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +22 -6
  85. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +16 -9
  86. package/templates/events-meetups-owner/tier5-src/_shared/collection-service.ts +19 -5
  87. package/templates/events-meetups-owner/tier5-src/_shared/engine-intl.ts +51 -0
  88. package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  89. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
  90. package/templates/gym-fitness/dev/index.ts +73 -204
  91. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +16 -9
  92. package/templates/gym-fitness/tier5-src/_shared/collection-service.ts +19 -5
  93. package/templates/gym-fitness/tier5-src/_shared/engine-intl.ts +51 -0
  94. package/templates/gym-fitness/tier5-src/_shared/himi-restaurants.ts +4 -4
  95. package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +49 -0
  96. package/templates/gym-fitness/tier5-src/_shared/wix-service-price.ts +1 -1
  97. package/templates/gym-fitness/tier5-src/himi-branded-lite-info/index.ts +5 -2
  98. package/templates/gym-fitness/tier5-src/himi-branded-lite-plans/index.ts +1 -1
  99. package/templates/gym-fitness/tier5-src/himi-events-detail/index.ts +1 -1
  100. package/templates/gym-fitness/tier5-src/himi-events-list/index.ts +20 -4
  101. package/templates/gym-fitness/tier5-src/himi-events-my-events/index.ts +2 -2
  102. package/templates/gym-fitness/tier5-src/wix-spaces-collections/index.ts +1 -1
  103. package/templates/gym-fitness/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  104. package/templates/gym-fitness-owner/dev/index.ts +84 -627
  105. package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +22 -6
  106. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +16 -9
  107. package/templates/gym-fitness-owner/tier5-src/_shared/collection-service.ts +19 -5
  108. package/templates/gym-fitness-owner/tier5-src/_shared/engine-intl.ts +51 -0
  109. package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  110. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
  111. package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +49 -0
  112. package/templates/nonprofit-cause/dev/index.ts +71 -90
  113. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +16 -9
  114. package/templates/nonprofit-cause/tier5-src/_shared/collection-service.ts +19 -5
  115. package/templates/nonprofit-cause/tier5-src/_shared/engine-intl.ts +51 -0
  116. package/templates/nonprofit-cause/tier5-src/_shared/himi-restaurants.ts +4 -4
  117. package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +49 -0
  118. package/templates/nonprofit-cause/tier5-src/_shared/wix-service-price.ts +1 -1
  119. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-info/index.ts +5 -2
  120. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-plans/index.ts +1 -1
  121. package/templates/nonprofit-cause/tier5-src/himi-events-detail/index.ts +1 -1
  122. package/templates/nonprofit-cause/tier5-src/himi-events-list/index.ts +20 -4
  123. package/templates/nonprofit-cause/tier5-src/himi-events-my-events/index.ts +2 -2
  124. package/templates/nonprofit-cause/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  125. package/templates/nonprofit-cause-owner/dev/index.ts +84 -571
  126. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +22 -6
  127. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +16 -9
  128. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-service.ts +19 -5
  129. package/templates/nonprofit-cause-owner/tier5-src/_shared/engine-intl.ts +51 -0
  130. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  131. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
  132. package/templates/owner-lite/dev/index.ts +84 -627
  133. package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +22 -6
  134. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +16 -9
  135. package/templates/owner-lite/tier5-src/_shared/collection-service.ts +19 -5
  136. package/templates/owner-lite/tier5-src/_shared/engine-intl.ts +51 -0
  137. package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +49 -0
  138. package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +1 -0
  139. package/templates/podcast-creator/dev/index.ts +71 -90
  140. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +16 -9
  141. package/templates/podcast-creator/tier5-src/_shared/collection-service.ts +19 -5
  142. package/templates/podcast-creator/tier5-src/_shared/engine-intl.ts +51 -0
  143. package/templates/podcast-creator/tier5-src/_shared/himi-restaurants.ts +4 -4
  144. package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +49 -0
  145. package/templates/podcast-creator/tier5-src/_shared/wix-service-price.ts +1 -1
  146. package/templates/podcast-creator/tier5-src/himi-branded-lite-info/index.ts +5 -2
  147. package/templates/podcast-creator/tier5-src/himi-branded-lite-plans/index.ts +1 -1
  148. package/templates/podcast-creator/tier5-src/himi-events-detail/index.ts +1 -1
  149. package/templates/podcast-creator/tier5-src/himi-events-list/index.ts +20 -4
  150. package/templates/podcast-creator/tier5-src/himi-events-my-events/index.ts +2 -2
  151. package/templates/podcast-creator/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  152. package/templates/podcast-creator-owner/dev/index.ts +84 -599
  153. package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +22 -6
  154. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +16 -9
  155. package/templates/podcast-creator-owner/tier5-src/_shared/collection-service.ts +19 -5
  156. package/templates/podcast-creator-owner/tier5-src/_shared/engine-intl.ts +51 -0
  157. package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  158. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
  159. package/templates/portfolio-creative/dev/index.ts +62 -137
  160. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +16 -9
  161. package/templates/portfolio-creative/tier5-src/_shared/collection-service.ts +19 -5
  162. package/templates/portfolio-creative/tier5-src/_shared/engine-intl.ts +51 -0
  163. package/templates/portfolio-creative/tier5-src/_shared/himi-restaurants.ts +4 -4
  164. package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +49 -0
  165. package/templates/portfolio-creative/tier5-src/_shared/wix-service-price.ts +1 -1
  166. package/templates/portfolio-creative/tier5-src/himi-branded-lite-info/index.ts +5 -2
  167. package/templates/portfolio-creative/tier5-src/himi-events-detail/index.ts +1 -1
  168. package/templates/portfolio-creative/tier5-src/himi-events-list/index.ts +20 -4
  169. package/templates/portfolio-creative/tier5-src/himi-events-my-events/index.ts +2 -2
  170. package/templates/portfolio-creative/tier5-src/wix-spaces-collections/index.ts +1 -1
  171. package/templates/portfolio-creative/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  172. package/templates/portfolio-creative-owner/dev/index.ts +84 -599
  173. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +22 -6
  174. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +16 -9
  175. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-service.ts +19 -5
  176. package/templates/portfolio-creative-owner/tier5-src/_shared/engine-intl.ts +51 -0
  177. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  178. package/templates/restaurant/dev/index.ts +124 -101
  179. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +16 -9
  180. package/templates/restaurant/tier5-src/_shared/collection-service.ts +19 -5
  181. package/templates/restaurant/tier5-src/_shared/engine-intl.ts +51 -0
  182. package/templates/restaurant/tier5-src/_shared/himi-restaurants.ts +4 -4
  183. package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +49 -0
  184. package/templates/restaurant/tier5-src/_shared/wix-service-price.ts +1 -1
  185. package/templates/restaurant/tier5-src/himi-branded-lite-info/index.ts +5 -2
  186. package/templates/restaurant/tier5-src/himi-branded-lite-reserve/index.ts +5 -3
  187. package/templates/restaurant/tier5-src/himi-events-detail/index.ts +1 -1
  188. package/templates/restaurant/tier5-src/himi-events-list/index.ts +20 -4
  189. package/templates/restaurant/tier5-src/himi-events-my-events/index.ts +2 -2
  190. package/templates/restaurant/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  191. package/templates/restaurant-owner/dev/index.ts +84 -627
  192. package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +22 -6
  193. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +16 -9
  194. package/templates/restaurant-owner/tier5-src/_shared/collection-service.ts +19 -5
  195. package/templates/restaurant-owner/tier5-src/_shared/engine-intl.ts +51 -0
  196. package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  197. package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
  198. package/templates/retail-store/dev/index.ts +59 -106
  199. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +16 -9
  200. package/templates/retail-store/tier5-src/_shared/collection-service.ts +19 -5
  201. package/templates/retail-store/tier5-src/_shared/engine-intl.ts +51 -0
  202. package/templates/retail-store/tier5-src/_shared/himi-restaurants.ts +4 -4
  203. package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +49 -0
  204. package/templates/retail-store/tier5-src/_shared/wix-service-price.ts +1 -1
  205. package/templates/retail-store/tier5-src/himi-branded-lite-info/index.ts +5 -2
  206. package/templates/retail-store/tier5-src/wix-spaces-collections/index.ts +1 -1
  207. package/templates/retail-store/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  208. package/templates/retail-store-owner/dev/index.ts +84 -571
  209. package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +22 -6
  210. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +16 -9
  211. package/templates/retail-store-owner/tier5-src/_shared/collection-service.ts +19 -5
  212. package/templates/retail-store-owner/tier5-src/_shared/engine-intl.ts +51 -0
  213. package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  214. package/templates/yoga-studio/dev/index.ts +73 -148
  215. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +16 -9
  216. package/templates/yoga-studio/tier5-src/_shared/collection-service.ts +19 -5
  217. package/templates/yoga-studio/tier5-src/_shared/engine-intl.ts +51 -0
  218. package/templates/yoga-studio/tier5-src/_shared/himi-restaurants.ts +4 -4
  219. package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +49 -0
  220. package/templates/yoga-studio/tier5-src/_shared/wix-service-price.ts +1 -1
  221. package/templates/yoga-studio/tier5-src/himi-branded-lite-info/index.ts +5 -2
  222. package/templates/yoga-studio/tier5-src/himi-branded-lite-plans/index.ts +1 -1
  223. package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +1 -1
  224. package/templates/yoga-studio/tier5-src/himi-events-detail/index.ts +1 -1
  225. package/templates/yoga-studio/tier5-src/himi-events-list/index.ts +20 -4
  226. package/templates/yoga-studio/tier5-src/himi-events-my-events/index.ts +2 -2
  227. package/templates/yoga-studio/tier5-src/wix-spaces-whats-new/index.ts +4 -4
  228. package/templates/yoga-studio-owner/dev/index.ts +84 -571
  229. package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +22 -6
  230. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +16 -9
  231. package/templates/yoga-studio-owner/tier5-src/_shared/collection-service.ts +19 -5
  232. package/templates/yoga-studio-owner/tier5-src/_shared/engine-intl.ts +51 -0
  233. package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +49 -0
  234. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +1 -0
@@ -3954,17 +3954,6 @@ const SCREENS = runtimeSetting({
3954
3954
  }
3955
3955
  }
3956
3956
  },
3957
- {
3958
- "id": "",
3959
- "body": {
3960
- "package": "himalaya",
3961
- "type": "Text",
3962
- "props": {
3963
- "text": "__HIMI_APP_NAME__",
3964
- "style": "bodyEmphasis"
3965
- }
3966
- }
3967
- },
3968
3957
  {
3969
3958
  "id": "",
3970
3959
  "body": {
@@ -5598,16 +5587,64 @@ const SCREENS = runtimeSetting({
5598
5587
  }
5599
5588
  },
5600
5589
  {
5601
- "id": "",
5590
+ "id": "himi_whats_new.empty",
5602
5591
  "body": {
5603
5592
  "package": "himalaya",
5604
- "type": "Text",
5593
+ "type": "VStack",
5605
5594
  "props": {
5606
- "text": "$service:spacesWhatsNew.emptyText",
5607
- "style": "body",
5608
- "color": "textSecondary",
5609
- "collapseWhenEmpty": true
5595
+ "spacing": 8,
5596
+ "alignment": "leading",
5597
+ "children": [
5598
+ {
5599
+ "id": "",
5600
+ "body": {
5601
+ "package": "himalaya",
5602
+ "type": "Icon",
5603
+ "props": {
5604
+ "name": "newspaper",
5605
+ "size": 28,
5606
+ "tint": "textTertiary"
5607
+ }
5608
+ },
5609
+ "modifiers": {
5610
+ "accessibilityRole": "decorative"
5611
+ }
5612
+ },
5613
+ {
5614
+ "id": "",
5615
+ "body": {
5616
+ "package": "himalaya",
5617
+ "type": "Text",
5618
+ "props": {
5619
+ "text": "$service:spacesWhatsNew.emptyText",
5620
+ "style": "body",
5621
+ "color": "textSecondary",
5622
+ "collapseWhenEmpty": true
5623
+ }
5624
+ }
5625
+ }
5626
+ ]
5610
5627
  }
5628
+ },
5629
+ "modifiers": {
5630
+ "background": {
5631
+ "token": "surfaceElevated"
5632
+ },
5633
+ "border": {
5634
+ "width": 1,
5635
+ "color": {
5636
+ "token": "border"
5637
+ }
5638
+ },
5639
+ "cornerRadius": 16,
5640
+ "padding": {
5641
+ "leading": 16,
5642
+ "trailing": 16,
5643
+ "top": 16,
5644
+ "bottom": 16
5645
+ },
5646
+ "fillMaxWidth": true,
5647
+ "hiddenPath": "$service:spacesWhatsNew.noEmpty"
5611
5648
  }
5612
5649
  }
5613
5650
  ]
@@ -6919,20 +6956,6 @@ const SCREENS = runtimeSetting({
6919
6956
  }
6920
6957
  }
6921
6958
  },
6922
- {
6923
- "id": "btn_tier5_himistoreshop_load",
6924
- "body": {
6925
- "package": "himalaya",
6926
- "type": "Button",
6927
- "props": {
6928
- "title": "Refresh",
6929
- "style": "plain",
6930
- "action": {
6931
- "actionId": "tier5.himiStoreShop.load"
6932
- }
6933
- }
6934
- }
6935
- },
6936
6959
  {
6937
6960
  "id": "himi_shop.list.collection.more",
6938
6961
  "body": {
@@ -7570,20 +7593,6 @@ const SCREENS = runtimeSetting({
7570
7593
  }
7571
7594
  }
7572
7595
  },
7573
- {
7574
- "id": "btn_tier5_himistoreshop_load",
7575
- "body": {
7576
- "package": "himalaya",
7577
- "type": "Button",
7578
- "props": {
7579
- "title": "Refresh",
7580
- "style": "plain",
7581
- "action": {
7582
- "actionId": "tier5.himiStoreShop.load"
7583
- }
7584
- }
7585
- }
7586
- },
7587
7596
  {
7588
7597
  "id": "himi_shop.list.collection.compact-more",
7589
7598
  "body": {
@@ -9297,7 +9306,7 @@ const SCREENS = runtimeSetting({
9297
9306
  "package": "himalaya",
9298
9307
  "type": "Text",
9299
9308
  "props": {
9300
- "text": "Review your items, then Checkout opens secure hosted checkout in the browser.",
9309
+ "text": "Review your items before you check out.",
9301
9310
  "style": "body",
9302
9311
  "color": "textSecondary"
9303
9312
  }
@@ -10042,7 +10051,7 @@ const SCREENS = runtimeSetting({
10042
10051
  "package": "himalaya",
10043
10052
  "type": "SearchField",
10044
10053
  "props": {
10045
- "placeholder": "Exact order number",
10054
+ "placeholder": "Search by order number",
10046
10055
  "value": "$service:himiBrandedOrders.collection.query",
10047
10056
  "debounceMs": 200,
10048
10057
  "onChange": {
@@ -10915,20 +10924,6 @@ const SCREENS = runtimeSetting({
10915
10924
  }
10916
10925
  }
10917
10926
  },
10918
- {
10919
- "id": "btn_tier5_himibrandedorders_refresh",
10920
- "body": {
10921
- "package": "himalaya",
10922
- "type": "Button",
10923
- "props": {
10924
- "title": "Refresh",
10925
- "style": "plain",
10926
- "action": {
10927
- "actionId": "tier5.himiBrandedOrders.refresh"
10928
- }
10929
- }
10930
- }
10931
- },
10932
10927
  {
10933
10928
  "id": "himi_orders.list.collection.more",
10934
10929
  "body": {
@@ -11499,20 +11494,6 @@ const SCREENS = runtimeSetting({
11499
11494
  }
11500
11495
  }
11501
11496
  },
11502
- {
11503
- "id": "btn_tier5_himibrandedorders_refresh",
11504
- "body": {
11505
- "package": "himalaya",
11506
- "type": "Button",
11507
- "props": {
11508
- "title": "Refresh",
11509
- "style": "plain",
11510
- "action": {
11511
- "actionId": "tier5.himiBrandedOrders.refresh"
11512
- }
11513
- }
11514
- }
11515
- },
11516
11497
  {
11517
11498
  "id": "himi_orders.list.collection.compact-more",
11518
11499
  "body": {
@@ -12394,7 +12375,7 @@ const SCREENS = runtimeSetting({
12394
12375
  "package": "himalaya",
12395
12376
  "type": "SearchField",
12396
12377
  "props": {
12397
- "placeholder": "Service name starts with…",
12378
+ "placeholder": "Search services",
12398
12379
  "debounceMs": 200,
12399
12380
  "onChange": {
12400
12381
  "actionId": "tier5.himiBookingServices.collectionSearch"
@@ -13586,20 +13567,6 @@ const SCREENS = runtimeSetting({
13586
13567
  }
13587
13568
  }
13588
13569
  },
13589
- {
13590
- "id": "btn_tier5_himibookingservices_refresh",
13591
- "body": {
13592
- "package": "himalaya",
13593
- "type": "Button",
13594
- "props": {
13595
- "title": "Refresh",
13596
- "style": "plain",
13597
- "action": {
13598
- "actionId": "tier5.himiBookingServices.refresh"
13599
- }
13600
- }
13601
- }
13602
- },
13603
13570
  {
13604
13571
  "id": "himi_services.list.collection.more",
13605
13572
  "body": {
@@ -14275,20 +14242,6 @@ const SCREENS = runtimeSetting({
14275
14242
  }
14276
14243
  }
14277
14244
  },
14278
- {
14279
- "id": "btn_tier5_himibookingservices_refresh",
14280
- "body": {
14281
- "package": "himalaya",
14282
- "type": "Button",
14283
- "props": {
14284
- "title": "Refresh",
14285
- "style": "plain",
14286
- "action": {
14287
- "actionId": "tier5.himiBookingServices.refresh"
14288
- }
14289
- }
14290
- }
14291
- },
14292
14245
  {
14293
14246
  "id": "himi_services.list.collection.compact-more",
14294
14247
  "body": {
@@ -15573,7 +15526,7 @@ const SCREENS = runtimeSetting({
15573
15526
  "package": "himalaya",
15574
15527
  "type": "SearchField",
15575
15528
  "props": {
15576
- "placeholder": "Exact booking ID",
15529
+ "placeholder": "Search by booking ID",
15577
15530
  "value": "$service:himiBookingBookings.collection.query",
15578
15531
  "debounceMs": 200,
15579
15532
  "onChange": {
@@ -16488,20 +16441,6 @@ const SCREENS = runtimeSetting({
16488
16441
  }
16489
16442
  }
16490
16443
  },
16491
- {
16492
- "id": "btn_tier5_himibookingbookings_refresh",
16493
- "body": {
16494
- "package": "himalaya",
16495
- "type": "Button",
16496
- "props": {
16497
- "title": "Refresh",
16498
- "style": "plain",
16499
- "action": {
16500
- "actionId": "tier5.himiBookingBookings.refresh"
16501
- }
16502
- }
16503
- }
16504
- },
16505
16444
  {
16506
16445
  "id": "himi_bookings.list.collection.more",
16507
16446
  "body": {
@@ -17114,20 +17053,6 @@ const SCREENS = runtimeSetting({
17114
17053
  }
17115
17054
  }
17116
17055
  },
17117
- {
17118
- "id": "btn_tier5_himibookingbookings_refresh",
17119
- "body": {
17120
- "package": "himalaya",
17121
- "type": "Button",
17122
- "props": {
17123
- "title": "Refresh",
17124
- "style": "plain",
17125
- "action": {
17126
- "actionId": "tier5.himiBookingBookings.refresh"
17127
- }
17128
- }
17129
- }
17130
- },
17131
17056
  {
17132
17057
  "id": "himi_bookings.list.collection.compact-more",
17133
17058
  "body": {
@@ -18436,7 +18361,7 @@ const SCREENS = runtimeSetting({
18436
18361
  "package": "himalaya",
18437
18362
  "type": "SearchField",
18438
18363
  "props": {
18439
- "placeholder": "Search loaded items",
18364
+ "placeholder": "Search",
18440
18365
  "value": "$service:himiBrandedPlans.collection.query",
18441
18366
  "debounceMs": 200,
18442
18367
  "onChange": {
@@ -18826,7 +18751,7 @@ const SCREENS = runtimeSetting({
18826
18751
  "text": "$item.collectionMeta",
18827
18752
  "style": "caption",
18828
18753
  "color": "textSecondary",
18829
- "maxLines": 2,
18754
+ "maxLines": 8,
18830
18755
  "collapseWhenEmpty": true
18831
18756
  }
18832
18757
  }
@@ -19074,9 +18999,9 @@ const SCREENS = runtimeSetting({
19074
18999
  "package": "himalaya",
19075
19000
  "type": "Grid",
19076
19001
  "props": {
19077
- "columns": 2,
19078
- "columnsMedium": 3,
19079
- "columnsExpanded": 4,
19002
+ "columns": 1,
19003
+ "columnsMedium": 2,
19004
+ "columnsExpanded": 3,
19080
19005
  "spacing": 12,
19081
19006
  "itemsPath": "$service:himiBrandedPlans.collection.items",
19082
19007
  "items": [
@@ -19133,7 +19058,7 @@ const SCREENS = runtimeSetting({
19133
19058
  "text": "$item.collectionMeta",
19134
19059
  "style": "caption",
19135
19060
  "color": "textSecondary",
19136
- "maxLines": 2,
19061
+ "maxLines": 8,
19137
19062
  "collapseWhenEmpty": true
19138
19063
  }
19139
19064
  }
@@ -19702,9 +19627,9 @@ const SCREENS = runtimeSetting({
19702
19627
  "package": "himalaya",
19703
19628
  "type": "Grid",
19704
19629
  "props": {
19705
- "columns": 2,
19706
- "columnsMedium": 3,
19707
- "columnsExpanded": 4,
19630
+ "columns": 1,
19631
+ "columnsMedium": 2,
19632
+ "columnsExpanded": 3,
19708
19633
  "spacing": 8,
19709
19634
  "itemsPath": "$service:himiBrandedPlans.collection.items",
19710
19635
  "items": [
@@ -20078,7 +20003,7 @@ const SCREENS = runtimeSetting({
20078
20003
  "package": "himalaya",
20079
20004
  "type": "Text",
20080
20005
  "props": {
20081
- "text": "Sort loaded items",
20006
+ "text": "Sort",
20082
20007
  "style": "bodyEmphasis"
20083
20008
  }
20084
20009
  }
@@ -20360,7 +20285,7 @@ const SCREENS = runtimeSetting({
20360
20285
  "text": "$item.collectionMeta",
20361
20286
  "style": "caption",
20362
20287
  "color": "textSecondary",
20363
- "maxLines": 2,
20288
+ "maxLines": 8,
20364
20289
  "collapseWhenEmpty": true
20365
20290
  }
20366
20291
  }
@@ -21691,7 +21616,7 @@ const SCREENS = runtimeSetting({
21691
21616
  "package": "himalaya",
21692
21617
  "type": "SearchField",
21693
21618
  "props": {
21694
- "placeholder": "Search loaded items",
21619
+ "placeholder": "Search",
21695
21620
  "debounceMs": 200,
21696
21621
  "onChange": {
21697
21622
  "actionId": "tier5.himiBlogFeed.collectionSearch"
@@ -22803,20 +22728,6 @@ const SCREENS = runtimeSetting({
22803
22728
  }
22804
22729
  }
22805
22730
  },
22806
- {
22807
- "id": "btn_tier5_himiblogfeed_retry",
22808
- "body": {
22809
- "package": "himalaya",
22810
- "type": "Button",
22811
- "props": {
22812
- "title": "Refresh",
22813
- "style": "plain",
22814
- "action": {
22815
- "actionId": "tier5.himiBlogFeed.retry"
22816
- }
22817
- }
22818
- }
22819
- },
22820
22731
  {
22821
22732
  "id": "himi_blog.list.collection.more",
22822
22733
  "body": {
@@ -23454,20 +23365,6 @@ const SCREENS = runtimeSetting({
23454
23365
  }
23455
23366
  }
23456
23367
  },
23457
- {
23458
- "id": "btn_tier5_himiblogfeed_retry",
23459
- "body": {
23460
- "package": "himalaya",
23461
- "type": "Button",
23462
- "props": {
23463
- "title": "Refresh",
23464
- "style": "plain",
23465
- "action": {
23466
- "actionId": "tier5.himiBlogFeed.retry"
23467
- }
23468
- }
23469
- }
23470
- },
23471
23368
  {
23472
23369
  "id": "himi_blog.list.collection.compact-more",
23473
23370
  "body": {
@@ -23594,7 +23491,7 @@ const SCREENS = runtimeSetting({
23594
23491
  "package": "himalaya",
23595
23492
  "type": "Text",
23596
23493
  "props": {
23597
- "text": "Sort loaded items",
23494
+ "text": "Sort",
23598
23495
  "style": "bodyEmphasis"
23599
23496
  }
23600
23497
  }
@@ -24298,7 +24195,7 @@ const SCREENS = runtimeSetting({
24298
24195
  "package": "himalaya",
24299
24196
  "type": "Text",
24300
24197
  "props": {
24301
- "text": "Posts saved on this member device.",
24198
+ "text": "Posts you have saved to read later.",
24302
24199
  "style": "body",
24303
24200
  "color": "textSecondary"
24304
24201
  }
@@ -26,6 +26,13 @@ export interface CollectionConfig {
26
26
  reviewSelectedAction?: string;
27
27
  /** Optional comfortable grid media height for immersive visual catalogs. */
28
28
  gridImageHeight?: number;
29
+ /** What the count summary counts — ["dish", "dishes"] reads "12 dishes". Default "item(s)". */
30
+ countNoun?: [string, string];
31
+ /** Phone grid columns (default 2). A card carrying a paragraph of benefits and a CTA — a
32
+ * pricing plan — is unreadable at half width, so it opts into one. */
33
+ gridColumns?: number;
34
+ /** Lines of the meta caption a comfortable row may use (default 2). */
35
+ metaMaxLines?: number;
29
36
  /** The card's primary verb, shown as a visible button beside the overflow.
30
37
  * `screenId` opens that screen with the row id; without it the verb reuses the
31
38
  * row's own tap action (the detail screen that owns the verb). */
@@ -38,28 +45,28 @@ export interface CollectionConfig {
38
45
  * page, the list/grid toggle, Refine, chips, search and count are noise. */
39
46
  export const COLLECTION_CHROME_MIN_ITEMS = 4;
40
47
  export const COLLECTIONS: Record<string, CollectionConfig> = {
41
- himiStoreShop: { rows: 'results', title: 'name', subtitle: 'subtitle', image: 'image', view: 'grid', backendQuery: true },
42
- himiBookingServices: { rows: 'results', title: 'name', subtitle: 'subtitle', image: 'image', filter: 'category', view: 'grid', backendQuery: true, searchPlaceholder: 'Service name starts with…', primaryVerb: { label: 'Book', screenId: 'himi_time' } },
48
+ himiStoreShop: { rows: 'results', title: 'name', subtitle: 'subtitle', image: 'image', view: 'grid', backendQuery: true, countNoun: ['product', 'products'] },
49
+ himiBookingServices: { rows: 'results', title: 'name', subtitle: 'subtitle', image: 'image', filter: 'category', view: 'grid', backendQuery: true, searchPlaceholder: 'Search services', countNoun: ['service', 'services'], primaryVerb: { label: 'Book', screenId: 'himi_time' } },
43
50
  himiBookingBookings: { rows: 'rows', title: 'title', subtitle: 'subtitle', metadata: ['status'], view: 'list', backendQuery: true,
44
- defaultFilter: 'value:Upcoming', searchPlaceholder: 'Exact booking ID', filterValues: ['Upcoming', 'Past', 'Cancelled'],
51
+ defaultFilter: 'value:Upcoming', searchPlaceholder: 'Search by booking ID', countNoun: ['booking', 'bookings'], filterValues: ['Upcoming', 'Past', 'Cancelled'],
45
52
  sortLabels: { default: 'Soonest', az: 'Oldest', za: 'Latest' } },
46
- himiEvents: { rows: 'results', title: 'title', subtitle: 'dateLine', image: 'image', view: 'grid', backendQuery: true, searchPlaceholder: 'Exact event title', filterValues: ['Upcoming', 'Past'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' }, primaryVerb: { label: 'Register' } },
53
+ himiEvents: { rows: 'results', title: 'title', subtitle: 'dateLine', image: 'image', view: 'grid', backendQuery: true, defaultFilter: 'value:Upcoming', searchPlaceholder: 'Search events', countNoun: ['event', 'events'], filterValues: ['Upcoming', 'Past'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' }, primaryVerb: { label: 'Register' } },
47
54
  himiBlogFeed: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', filter: 'category', filterValuesFrom: 'categories', view: 'grid', narrowedBy: 'selectedCategoryId' },
48
- himiOwnerLiteProducts: { rows: 'products', title: 'name', subtitle: 'price', image: 'image', view: 'grid', backendQuery: true },
55
+ himiOwnerLiteProducts: { rows: 'products', title: 'name', subtitle: 'price', image: 'image', view: 'grid', backendQuery: true, countNoun: ['product', 'products'] },
49
56
  himiOwnerModules: { instanceInput: 'module', rows: 'rows', title: 'title', subtitle: 'subtitle', image: 'image', filter: 'statusLabel', view: 'list', paged: true, reviewAction: 'prepareRecord', reviewSelectedAction: 'prepareSelected' },
50
57
  himiOwnerLiteServices: { rows: 'services', title: 'name', subtitle: 'subtitle', view: 'list', backendQuery: true, searchPlaceholder: 'Service name starts with…' },
51
58
  himiOwnerLiteEvents: { rows: 'events', title: 'title', subtitle: 'dateLine', view: 'grid', backendQuery: true, searchPlaceholder: 'Exact event title', filterValues: ['Upcoming'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' } },
52
59
  himiOwnerLitePosts: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', view: 'grid' },
53
- himiOwnerLiteOrders: { rows: 'orders', title: 'buyer', subtitle: 'meta', filter: 'statusLabel', view: 'list', backendQuery: true,
60
+ himiOwnerLiteOrders: { rows: 'orders', title: 'buyer', subtitle: 'meta', filter: 'statusLabel', view: 'list', backendQuery: true, countNoun: ['order', 'orders'],
54
61
  searchPlaceholder: 'Customer name, email or order #', sortLabels: { default: 'Newest', az: 'Customer A–Z', za: 'Customer Z–A' },
55
62
  filterValues: ['Recent 7 days', 'Paid', 'Unpaid', 'Partially paid', 'Pending', 'Refunded', 'Partly refunded'] },
56
63
  himiBrandedGroups: { rows: 'rows', title: 'name', subtitle: 'description', image: 'image', view: 'grid' },
57
64
  himiBrandedCms: { rows: 'rows', title: 'name', subtitle: 'subtitle', view: 'grid' },
58
65
  himiBrandedCmsCollection: { instanceInput: 'collection', rows: 'rows', title: 'title', subtitle: 'subtitle', view: 'list' },
59
66
  himiBrandedOrders: { rows: 'rows', title: 'title', subtitle: 'subtitle', view: 'list', backendQuery: true,
60
- searchPlaceholder: 'Exact order number', filterValues: ['Not fulfilled', 'Partially fulfilled', 'Fulfilled'],
67
+ searchPlaceholder: 'Search by order number', countNoun: ['order', 'orders'], filterValues: ['Not fulfilled', 'Partially fulfilled', 'Fulfilled'],
61
68
  sortLabels: { default: 'Newest', az: 'Oldest', za: 'Order # ↓' } },
62
- himiBrandedPlans: { rows: 'rows', title: 'name', subtitle: 'description', metadata: ['priceLine', 'periodLine', 'trialBadge', 'perk1', 'perk2', 'perk3'], view: 'grid' },
69
+ himiBrandedPlans: { rows: 'rows', title: 'name', subtitle: 'description', metadata: ['badge', 'priceLine', 'periodLine', 'trialBadge', 'perk1', 'perk2', 'perk3'], view: 'grid', gridColumns: 1, metaMaxLines: 8, countNoun: ['plan', 'plans'] },
63
70
  himiBrandedPrograms: { rows: 'rows', title: 'name', subtitle: 'description', image: 'image', view: 'grid' },
64
71
  himiBrandedCoupons: { rows: 'coupons', title: 'name', subtitle: 'subtitle', view: 'list', primaryVerb: { label: 'Get code' } },
65
72
  himiBrandedNotifications: { rows: 'items', title: 'name', subtitle: 'subtitle', image: 'photo', metadata: ['unreadDot'], view: 'list' },
@@ -75,7 +82,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
75
82
  himiBrandedForms: { rows: 'forms', title: 'name', subtitle: 'description', view: 'list' },
76
83
  himiBrandedGalleries: { rows: 'galleries', title: 'name', subtitle: 'description', image: 'image', view: 'grid' },
77
84
  himiBrandedInbox: { rows: 'conversations', title: 'title', subtitle: 'preview', view: 'list' },
78
- himiBrandedMenus: { rows: 'rows', title: 'name', subtitle: 'description', image: 'image', sectioned: true, filter: 'collectionCategory', metadata: ['collectionCategory', 'priceLine', 'label1', 'label2', 'label3'], view: 'grid' },
85
+ himiBrandedMenus: { rows: 'rows', title: 'name', subtitle: 'description', image: 'image', sectioned: true, filter: 'collectionCategory', metadata: ['collectionCategory', 'priceLine', 'label1', 'label2', 'label3'], view: 'grid', searchPlaceholder: 'Search the menu', countNoun: ['dish', 'dishes'] },
79
86
  };
80
87
  export interface CollectionPreferences {
81
88
  view: 'list' | 'grid';
@@ -18,6 +18,20 @@ type Reducer = (s: State, ...args: unknown[]) => State | undefined | Promise<Sta
18
18
  const object = (x: unknown): State => x && typeof x === 'object' && !Array.isArray(x) ? x as State : {};
19
19
  const str = (arg: unknown, key: string): string => typeof arg === 'string' ? arg : String(object(arg)[key] ?? '');
20
20
 
21
+ /** The toolbar count line — "12 dishes", or "3 of 12 dishes" while a filter narrows the list.
22
+ *
23
+ * It used to read "12 / 12 loaded" and "2 / 2 results" ([branded-lite-qa] #3002): the numbers
24
+ * described the implementation (a client-side filter over a fetched page) rather than what the
25
+ * customer is looking at, and the slash-and-suffix wrapped onto two lines on web. When the
26
+ * backend total is unknown the count shown is simply what is shown; the "Load more" button is
27
+ * what says there is more. */
28
+ export function collectionSummary(o: { shown: number; loaded: number; total?: number; backend?: boolean; noun?: [string, string] }): string {
29
+ const [one, many] = o.noun ?? [copyParam('collection.itemOne', 'item'), copyParam('collection.itemMany', 'items')];
30
+ const whole = o.backend ? (typeof o.total === 'number' ? o.total : o.shown) : o.loaded;
31
+ const noun = (whole === 1 ? one : many);
32
+ return o.shown < whole ? `${o.shown} ${copyParam('collection.of', 'of')} ${whole} ${noun}` : `${o.shown} ${o.shown === 1 ? one : many}`;
33
+ }
34
+
21
35
  /** Opt-in decorator. Domain reducers remain authoritative; collection preferences
22
36
  * survive reducers which replace their entire state, including async refreshes. */
23
37
  export function decorateCollection(name: string, def: { state: State; actions?: Record<string, Reducer> }, saving?: CollectionSaving, backend?: BackendCollection) {
@@ -179,11 +193,11 @@ export function decorateCollection(name: string, def: { state: State; actions?:
179
193
  filtersPresented, previewPresented: !!previewId, preview: projected.items.filter(row => row.collectionId === previewId),
180
194
  persistenceLabel: persisted.available ? copyParam('collection.onDevice', 'Saved on this device') : copyParam('collection.sessionOnly', 'Choices last for this session'),
181
195
  noEmpty: loading || errored || sourceEmpty || domainNarrowed || projected.items.length > 0,
182
- summary: backend && config.backendQuery
183
- ? (s.fromCache ? copyParam('collection.cached', 'Saved offline · may be outdated')
184
- : typeof s.total === 'number' ? `${projected.items.length} / ${s.total} ${copyParam('collection.results', 'results')}`
185
- : `${projected.items.length} ${s.complete ? copyParam('collection.results', 'results') : copyParam('collection.loaded', 'loaded')}`)
186
- : `${projected.items.length} / ${projected.loaded} ${copyParam('collection.loaded', 'loaded')}`,
196
+ summary: backend && config.backendQuery && s.fromCache
197
+ ? copyParam('collection.cached', 'Saved offline · may be outdated')
198
+ : collectionSummary({ shown: projected.items.length, loaded: projected.loaded, backend: !!(backend && config.backendQuery),
199
+ total: typeof s.total === 'number' ? s.total : undefined, noun: config.countNoun
200
+ ? [copyParam(`collection.${name}.countOne`, config.countNoun[0]), copyParam(`collection.${name}.countMany`, config.countNoun[1])] : undefined }),
187
201
  selectedSummary: `${prefs.selectedIds.length} ${copyParam('collection.selected', 'selected')}`,
188
202
  filterChoices,
189
203
  chips: config.filterValues ? filterChoices.filter(choice => ['all', 'saved', prefs.filter].includes(choice.id)) : filterChoices,
@@ -352,3 +352,54 @@ export function compareDateDesc(a: string, b: string): number {
352
352
  if (bBad) return -1;
353
353
  return tb - ta;
354
354
  }
355
+
356
+ // --- [branded-lite-qa] #3079: one pattern per fact ---------------------------------------
357
+ //
358
+ // Before these existed, four screens formatted the same money four ways — Shop "69.00 ₪" (Wix's
359
+ // pre-formatted string), Services "₪70" (0 decimals), Menu "₪32.00", Plans "$24" — and two
360
+ // screens formatted the same clock two ways (Events "9:00 PM-11:00 PM", Reserve "20:00").
361
+ // Customers read that as sloppiness, and a whole "₪70" beside "₪69.50" reads as a different
362
+ // kind of number. So: one money pattern, one clock, one range.
363
+
364
+ // Money uses `formatCurrency(amount, currency, "en")` — the currency's NATURAL decimals
365
+ // ("₪70.00", "¥500"). Passing 0 fraction digits for whole amounts is what made a list read
366
+ // "₪70 · ₪69.50".
367
+
368
+ const KNOWN_SYMBOLS = new Set(Object.values(CURRENCY_SYMBOL));
369
+
370
+ /** Wix hands some prices over PRE-formatted in the site's regional style — "69.00 ₪" with the
371
+ * symbol trailing, often wrapped in bidi marks. Reorder those to the house pattern ("₪69.00") so
372
+ * they match every price we format ourselves. Only an en-shaped number ("69.00", "1,234.50") with
373
+ * a known trailing symbol is reordered: a comma-decimal or space-grouped string ("69,00 €",
374
+ * "1 234,56 €") is kept as Wix wrote it, because half-converting it would be worse. Anything else
375
+ * ("Market price") is returned trimmed. The store SDK's product price applies the same rule. */
376
+ export function normalizeFormattedPrice(formatted: string): string {
377
+ const raw = (formatted || "").replace(/[‎‏]/g, "").trim();
378
+ const m = /^(-?)(\d{1,3}(?:,\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?)[\s  ]*(\S+)$/.exec(raw);
379
+ if (!m || !KNOWN_SYMBOLS.has(m[3])) return raw;
380
+ return `${m[1]}${m[3]}${m[2]}`;
381
+ }
382
+
383
+ function clockParts(d: Date, locale: string): { time: string; meridiem: string } {
384
+ const full = hasIntl()
385
+ ? new Intl.DateTimeFormat(locale, { hour: "numeric", minute: "2-digit", hour12: true }).format(d)
386
+ : clock12(d);
387
+ // ICU puts a narrow no-break space before the meridiem; normalize so callers can split on it.
388
+ const clean = full.replace(/[  ]/g, " ");
389
+ const m = /^(.*?)\s*([AP]\.?M\.?)$/i.exec(clean);
390
+ return m ? { time: m[1], meridiem: m[2] } : { time: clean, meridiem: "" };
391
+ }
392
+
393
+ /** "8:00 PM" — the one clock every customer screen uses (12-hour, en-US shape). */
394
+ export function formatClock(date: Date, locale = "en-US"): string {
395
+ const { time, meridiem } = clockParts(date, locale);
396
+ return meridiem ? `${time} ${meridiem}` : time;
397
+ }
398
+
399
+ /** Is this ISO instant before `now`? A missing or unparseable value is NOT past — "no expiry"
400
+ * must never classify an offer as expired. */
401
+ export function isPastDate(iso: string | undefined | null, now: number = Date.now()): boolean {
402
+ if (!iso) return false;
403
+ const t = Date.parse(iso);
404
+ return !Number.isNaN(t) && t < now;
405
+ }
@@ -11,7 +11,7 @@ import { wixMediaUrl, type WixImageSize } from "@himalaya/wix-media";
11
11
  // copier recognizes + carries the dependency; resolves to the same file here
12
12
  // and in the scaffolded tier5-src/_shared/ layout.
13
13
  import { cleanTitle, initials } from "../_shared/himi-text.js";
14
- import { formatCurrency } from "../_shared/engine-intl.js";
14
+ import { formatCurrency, normalizeFormattedPrice } from "../_shared/engine-intl.js";
15
15
 
16
16
  /** One dish tile/row: the media-XOR-initials card contract every himi list
17
17
  * uses, plus a formatted price line and the templated detail screen id. */
@@ -97,13 +97,13 @@ export function itemPriceLine(item: WixItem): string {
97
97
  | { price?: unknown; currency?: unknown; formattedPrice?: unknown }
98
98
  | undefined;
99
99
  const formatted = typeof info?.formattedPrice === "string" ? info.formattedPrice.trim() : "";
100
- if (formatted) return formatted;
100
+ if (formatted) return normalizeFormattedPrice(formatted);
101
101
  const price = info?.price;
102
102
  if (price == null || price === "" || Number.isNaN(Number(price))) return "";
103
103
  const currency = typeof info?.currency === "string" ? info.currency : "";
104
104
  if (!currency) return `${price}`;
105
105
  try {
106
- return formatCurrency(Number(price), currency, "en", Number(price) % 1 === 0 ? 0 : 2);
106
+ return formatCurrency(Number(price), currency, "en");
107
107
  } catch {
108
108
  return `${price}`;
109
109
  }
@@ -149,7 +149,7 @@ export function itemPriceVariants(item: WixItem): Array<{ id: string; name: stri
149
149
  let priceLine = `${price}`;
150
150
  if (currency) {
151
151
  try {
152
- priceLine = formatCurrency(Number(price), currency, "en", Number(price) % 1 === 0 ? 0 : 2);
152
+ priceLine = formatCurrency(Number(price), currency, "en");
153
153
  } catch { /* keep the bare amount */ }
154
154
  }
155
155
  rows.push({ id: typeof node.id === "string" && node.id ? node.id : `variant-${index}`, name: name || "Option", priceLine });