@wix/himalaya-cli 0.1311.0 → 0.1312.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 (183) hide show
  1. package/dist/cli.mjs +55 -34
  2. package/dist/preview-assets.generated.bin +0 -0
  3. package/guides/web-page-native-sdk.md +18 -8
  4. package/guides/webview-page-sdk.md +9 -3
  5. package/package.json +2 -2
  6. package/templates/beauty-salon/dev/index.ts +25 -25
  7. package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +10 -0
  8. package/templates/beauty-salon/tier5-src/_shared/collection-service.ts +3 -1
  9. package/templates/beauty-salon-owner/dev/index.ts +844 -510
  10. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +10 -0
  11. package/templates/beauty-salon-owner/tier5-src/_shared/collection-service.ts +3 -1
  12. package/templates/beauty-salon-owner/tier5-src/_shared/detail-facts.ts +26 -0
  13. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  14. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  15. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  16. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  17. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  18. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  19. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  20. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  21. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
  22. package/templates/branded-lite/dev/index.ts +120 -120
  23. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +10 -0
  24. package/templates/branded-lite/tier5-src/_shared/collection-service.ts +3 -1
  25. package/templates/community-club/dev/index.ts +20 -20
  26. package/templates/community-club/tier5-src/_shared/collection-contract.ts +10 -0
  27. package/templates/community-club/tier5-src/_shared/collection-service.ts +3 -1
  28. package/templates/community-club-owner/dev/index.ts +957 -595
  29. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +10 -0
  30. package/templates/community-club-owner/tier5-src/_shared/collection-service.ts +3 -1
  31. package/templates/community-club-owner/tier5-src/_shared/detail-facts.ts +26 -0
  32. package/templates/community-club-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  33. package/templates/community-club-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  34. package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  35. package/templates/community-club-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  36. package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  37. package/templates/community-club-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  38. package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  39. package/templates/community-club-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  40. package/templates/community-club-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  41. package/templates/events-meetups/dev/index.ts +15 -15
  42. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +10 -0
  43. package/templates/events-meetups/tier5-src/_shared/collection-service.ts +3 -1
  44. package/templates/events-meetups-owner/dev/index.ts +726 -433
  45. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +10 -0
  46. package/templates/events-meetups-owner/tier5-src/_shared/collection-service.ts +3 -1
  47. package/templates/events-meetups-owner/tier5-src/_shared/detail-facts.ts +26 -0
  48. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  49. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  50. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  51. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  52. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  53. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  54. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  55. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  56. package/templates/gym-fitness/dev/index.ts +30 -30
  57. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +10 -0
  58. package/templates/gym-fitness/tier5-src/_shared/collection-service.ts +3 -1
  59. package/templates/gym-fitness-owner/dev/index.ts +1041 -644
  60. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +10 -0
  61. package/templates/gym-fitness-owner/tier5-src/_shared/collection-service.ts +3 -1
  62. package/templates/gym-fitness-owner/tier5-src/_shared/detail-facts.ts +26 -0
  63. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  64. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  65. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  66. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  67. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  68. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  69. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  70. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  71. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  72. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
  73. package/templates/nonprofit-cause/dev/index.ts +20 -20
  74. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +10 -0
  75. package/templates/nonprofit-cause/tier5-src/_shared/collection-service.ts +3 -1
  76. package/templates/nonprofit-cause-owner/dev/index.ts +810 -482
  77. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +10 -0
  78. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-service.ts +3 -1
  79. package/templates/nonprofit-cause-owner/tier5-src/_shared/detail-facts.ts +26 -0
  80. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  81. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  82. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  83. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  84. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  85. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  86. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  87. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  88. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
  89. package/templates/owner-lite/dev/index.ts +1066 -648
  90. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +10 -0
  91. package/templates/owner-lite/tier5-src/_shared/collection-service.ts +3 -1
  92. package/templates/owner-lite/tier5-src/_shared/detail-facts.ts +26 -0
  93. package/templates/owner-lite/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  94. package/templates/owner-lite/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  95. package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +10 -0
  96. package/templates/owner-lite/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  97. package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +10 -0
  98. package/templates/owner-lite/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  99. package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +10 -0
  100. package/templates/owner-lite/tier5-src/himi-owner-lite-search/index.ts +6 -0
  101. package/templates/owner-lite/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  102. package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +10 -0
  103. package/templates/podcast-creator/dev/index.ts +20 -20
  104. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +10 -0
  105. package/templates/podcast-creator/tier5-src/_shared/collection-service.ts +3 -1
  106. package/templates/podcast-creator-owner/dev/index.ts +957 -595
  107. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +10 -0
  108. package/templates/podcast-creator-owner/tier5-src/_shared/collection-service.ts +3 -1
  109. package/templates/podcast-creator-owner/tier5-src/_shared/detail-facts.ts +26 -0
  110. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  111. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  112. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  113. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  114. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  115. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  116. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  117. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  118. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  119. package/templates/portfolio-creative/dev/index.ts +20 -20
  120. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +10 -0
  121. package/templates/portfolio-creative/tier5-src/_shared/collection-service.ts +3 -1
  122. package/templates/portfolio-creative-owner/dev/index.ts +844 -510
  123. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +10 -0
  124. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-service.ts +3 -1
  125. package/templates/portfolio-creative-owner/tier5-src/_shared/detail-facts.ts +26 -0
  126. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  127. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  128. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  129. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  130. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  131. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  132. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  133. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  134. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
  135. package/templates/restaurant/dev/index.ts +15 -15
  136. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +10 -0
  137. package/templates/restaurant/tier5-src/_shared/collection-service.ts +3 -1
  138. package/templates/restaurant-owner/dev/index.ts +1041 -644
  139. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +10 -0
  140. package/templates/restaurant-owner/tier5-src/_shared/collection-service.ts +3 -1
  141. package/templates/restaurant-owner/tier5-src/_shared/detail-facts.ts +26 -0
  142. package/templates/restaurant-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  143. package/templates/restaurant-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  144. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  145. package/templates/restaurant-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  146. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  147. package/templates/restaurant-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  148. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  149. package/templates/restaurant-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  150. package/templates/restaurant-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  151. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
  152. package/templates/retail-store/dev/index.ts +10 -10
  153. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +10 -0
  154. package/templates/retail-store/tier5-src/_shared/collection-service.ts +3 -1
  155. package/templates/retail-store-owner/dev/index.ts +760 -461
  156. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +10 -0
  157. package/templates/retail-store-owner/tier5-src/_shared/collection-service.ts +3 -1
  158. package/templates/retail-store-owner/tier5-src/_shared/detail-facts.ts +26 -0
  159. package/templates/retail-store-owner/tier5-src/_shared/offset-page.ts +10 -0
  160. package/templates/retail-store-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  161. package/templates/retail-store-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  162. package/templates/retail-store-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  163. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  164. package/templates/retail-store-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  165. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +10 -0
  166. package/templates/retail-store-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  167. package/templates/retail-store-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  168. package/templates/yoga-studio/dev/index.ts +30 -30
  169. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +10 -0
  170. package/templates/yoga-studio/tier5-src/_shared/collection-service.ts +3 -1
  171. package/templates/yoga-studio-owner/dev/index.ts +810 -482
  172. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +10 -0
  173. package/templates/yoga-studio-owner/tier5-src/_shared/collection-service.ts +3 -1
  174. package/templates/yoga-studio-owner/tier5-src/_shared/detail-facts.ts +26 -0
  175. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-ask/blocks.ts +7 -3
  176. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-ask/index.ts +2 -2
  177. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +10 -0
  178. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-manage/logic.ts +3 -0
  179. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +10 -0
  180. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-posts/index.ts +21 -2
  181. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-search/index.ts +6 -0
  182. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-search/vertical-sources.ts +178 -0
  183. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +10 -0
@@ -58,6 +58,13 @@ export interface CollectionConfig {
58
58
  /** At or below this many records, with no query/filter narrowing them and no further
59
59
  * page, the list/grid toggle, Refine, chips, search and count are noise. */
60
60
  export const COLLECTION_CHROME_MIN_ITEMS = 4;
61
+ /** The accessible name of a row's overflow menu: `template` with `{title}` filled, or the
62
+ * generic `fallback` for a record with no title. */
63
+ export function collectionActionsLabel(title: string, template: string, fallback: string): string {
64
+ const t = title.trim();
65
+ return t ? template.replace('{title}', () => t) : fallback;
66
+ }
67
+
61
68
  export const COLLECTIONS: Record<string, CollectionConfig> = {
62
69
  himiStoreShop: { rows: 'results', title: 'name', subtitle: 'subtitle', image: 'image', view: 'grid', backendQuery: true, countNoun: ['product', 'products'], favoriteToggle: true },
63
70
  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' } },
@@ -184,6 +191,9 @@ export function projectCollection(source: CollectionRow[], config: CollectionCon
184
191
  collectionSelectLabel: prefs.selectedIds.includes(collectionId(row)) ? 'Selected' : 'Select',
185
192
  // The save toggle names the action it WILL take (the service localizes it).
186
193
  collectionSaveLabel: prefs.savedIds.includes(collectionId(row)) ? 'Remove from saved' : 'Save',
194
+ // The row's overflow menu, named for its record: out of context (a rotor, a voice
195
+ // command) a list of identical "Item actions" cannot be told apart.
196
+ collectionActionsLabel: collectionActionsLabel(collectionTitle(row, config), 'Actions for {title}', 'Item actions'),
187
197
  collectionSubtitle: scalar(row[config.subtitle ?? '']) || scalar(row.subtitle) || scalar(row.description) || scalar(row.meta),
188
198
  collectionImage: scalar(row[config.image ?? '']), collectionNoImage: !scalar(row[config.image ?? '']), collectionHasImage: !!scalar(row[config.image ?? '']),
189
199
  collectionSaved: prefs.savedIds.includes(collectionId(row)), collectionNotSaved: !prefs.savedIds.includes(collectionId(row)), collectionSelected: prefs.selectedIds.includes(collectionId(row)),
@@ -1,5 +1,5 @@
1
1
  import { defineService as register, type ServiceDefinition } from '@himalaya/state';
2
- import { COLLECTIONS, COLLECTION_CHROME_MIN_ITEMS, initialCollection, normalizeCollection, projectCollection, collectionId, type CollectionRow } from './collection-contract.js';
2
+ import { COLLECTIONS, COLLECTION_CHROME_MIN_ITEMS, initialCollection, normalizeCollection, projectCollection, collectionId, collectionActionsLabel, type CollectionRow } from './collection-contract.js';
3
3
  import { localPreferences, type PreferenceRuntime } from './local-preferences.js';
4
4
  import { copyParam, stashCopy } from './himi-copy.js';
5
5
  import { createCollectionQuery, type CollectionQuerySource, type CollectionQueryState } from './collection-query.js';
@@ -130,6 +130,8 @@ export function decorateCollection(name: string, def: { state: State; actions?:
130
130
  // the save toggle names the action it WILL take for this row. The
131
131
  // old static "Save / unsave" made the owner work out the row's state.
132
132
  row.collectionSaveLabel = row.collectionSaved ? copyParam('collection.unsave', 'Remove from saved') : copyParam('collection.save', 'Save');
133
+ row.collectionActionsLabel = collectionActionsLabel(String(row.collectionTitle ?? ''),
134
+ copyParam('collection.itemActionsFor', 'Actions for {title}'), copyParam('collection.itemActions', 'Item actions'));
133
135
  });
134
136
  if (previewId && !rows.some(row => collectionId(row) === previewId)) previewId = '';
135
137
  const filterChoices = [{ id: 'all', label: copyParam('collection.all', 'All') }, { id: 'saved', label: copyParam('collection.saved', 'Saved') },
@@ -6423,7 +6423,7 @@ const SCREENS = runtimeSetting({
6423
6423
  "modifiers": {
6424
6424
  "width": 44,
6425
6425
  "height": 44,
6426
- "accessibilityLabel": "Item actions"
6426
+ "accessibilityLabel": "$item.collectionActionsLabel"
6427
6427
  }
6428
6428
  },
6429
6429
  "items": [
@@ -6831,7 +6831,7 @@ const SCREENS = runtimeSetting({
6831
6831
  "modifiers": {
6832
6832
  "width": 44,
6833
6833
  "height": 44,
6834
- "accessibilityLabel": "Item actions"
6834
+ "accessibilityLabel": "$item.collectionActionsLabel"
6835
6835
  }
6836
6836
  },
6837
6837
  "items": [
@@ -7191,7 +7191,7 @@ const SCREENS = runtimeSetting({
7191
7191
  "modifiers": {
7192
7192
  "width": 44,
7193
7193
  "height": 44,
7194
- "accessibilityLabel": "Item actions"
7194
+ "accessibilityLabel": "$item.collectionActionsLabel"
7195
7195
  }
7196
7196
  },
7197
7197
  "items": [
@@ -7599,7 +7599,7 @@ const SCREENS = runtimeSetting({
7599
7599
  "modifiers": {
7600
7600
  "width": 44,
7601
7601
  "height": 44,
7602
- "accessibilityLabel": "Item actions"
7602
+ "accessibilityLabel": "$item.collectionActionsLabel"
7603
7603
  }
7604
7604
  },
7605
7605
  "items": [
@@ -8346,7 +8346,7 @@ const SCREENS = runtimeSetting({
8346
8346
  "modifiers": {
8347
8347
  "width": 44,
8348
8348
  "height": 44,
8349
- "accessibilityLabel": "Item actions"
8349
+ "accessibilityLabel": "$item.collectionActionsLabel"
8350
8350
  }
8351
8351
  },
8352
8352
  "items": [
@@ -9896,7 +9896,7 @@ const SCREENS = runtimeSetting({
9896
9896
  "modifiers": {
9897
9897
  "width": 44,
9898
9898
  "height": 44,
9899
- "accessibilityLabel": "Item actions"
9899
+ "accessibilityLabel": "$item.collectionActionsLabel"
9900
9900
  }
9901
9901
  },
9902
9902
  "items": [
@@ -10243,7 +10243,7 @@ const SCREENS = runtimeSetting({
10243
10243
  "modifiers": {
10244
10244
  "width": 44,
10245
10245
  "height": 44,
10246
- "accessibilityLabel": "Item actions"
10246
+ "accessibilityLabel": "$item.collectionActionsLabel"
10247
10247
  }
10248
10248
  },
10249
10249
  "items": [
@@ -10533,7 +10533,7 @@ const SCREENS = runtimeSetting({
10533
10533
  "modifiers": {
10534
10534
  "width": 44,
10535
10535
  "height": 44,
10536
- "accessibilityLabel": "Item actions"
10536
+ "accessibilityLabel": "$item.collectionActionsLabel"
10537
10537
  }
10538
10538
  },
10539
10539
  "items": [
@@ -10880,7 +10880,7 @@ const SCREENS = runtimeSetting({
10880
10880
  "modifiers": {
10881
10881
  "width": 44,
10882
10882
  "height": 44,
10883
- "accessibilityLabel": "Item actions"
10883
+ "accessibilityLabel": "$item.collectionActionsLabel"
10884
10884
  }
10885
10885
  },
10886
10886
  "items": [
@@ -11521,7 +11521,7 @@ const SCREENS = runtimeSetting({
11521
11521
  "modifiers": {
11522
11522
  "width": 44,
11523
11523
  "height": 44,
11524
- "accessibilityLabel": "Item actions"
11524
+ "accessibilityLabel": "$item.collectionActionsLabel"
11525
11525
  }
11526
11526
  },
11527
11527
  "items": [
@@ -12956,7 +12956,7 @@ const SCREENS = runtimeSetting({
12956
12956
  "modifiers": {
12957
12957
  "width": 44,
12958
12958
  "height": 44,
12959
- "accessibilityLabel": "Item actions"
12959
+ "accessibilityLabel": "$item.collectionActionsLabel"
12960
12960
  }
12961
12961
  },
12962
12962
  "items": [
@@ -13293,7 +13293,7 @@ const SCREENS = runtimeSetting({
13293
13293
  "modifiers": {
13294
13294
  "width": 44,
13295
13295
  "height": 44,
13296
- "accessibilityLabel": "Item actions"
13296
+ "accessibilityLabel": "$item.collectionActionsLabel"
13297
13297
  }
13298
13298
  },
13299
13299
  "items": [
@@ -13567,7 +13567,7 @@ const SCREENS = runtimeSetting({
13567
13567
  "modifiers": {
13568
13568
  "width": 44,
13569
13569
  "height": 44,
13570
- "accessibilityLabel": "Item actions"
13570
+ "accessibilityLabel": "$item.collectionActionsLabel"
13571
13571
  }
13572
13572
  },
13573
13573
  "items": [
@@ -13904,7 +13904,7 @@ const SCREENS = runtimeSetting({
13904
13904
  "modifiers": {
13905
13905
  "width": 44,
13906
13906
  "height": 44,
13907
- "accessibilityLabel": "Item actions"
13907
+ "accessibilityLabel": "$item.collectionActionsLabel"
13908
13908
  }
13909
13909
  },
13910
13910
  "items": [
@@ -14528,7 +14528,7 @@ const SCREENS = runtimeSetting({
14528
14528
  "modifiers": {
14529
14529
  "width": 44,
14530
14530
  "height": 44,
14531
- "accessibilityLabel": "Item actions"
14531
+ "accessibilityLabel": "$item.collectionActionsLabel"
14532
14532
  }
14533
14533
  },
14534
14534
  "items": [
@@ -15441,7 +15441,7 @@ const SCREENS = runtimeSetting({
15441
15441
  "modifiers": {
15442
15442
  "width": 44,
15443
15443
  "height": 44,
15444
- "accessibilityLabel": "Item actions"
15444
+ "accessibilityLabel": "$item.collectionActionsLabel"
15445
15445
  }
15446
15446
  },
15447
15447
  "items": [
@@ -15711,7 +15711,7 @@ const SCREENS = runtimeSetting({
15711
15711
  "modifiers": {
15712
15712
  "width": 44,
15713
15713
  "height": 44,
15714
- "accessibilityLabel": "Item actions"
15714
+ "accessibilityLabel": "$item.collectionActionsLabel"
15715
15715
  }
15716
15716
  },
15717
15717
  "items": [
@@ -15985,7 +15985,7 @@ const SCREENS = runtimeSetting({
15985
15985
  "modifiers": {
15986
15986
  "width": 44,
15987
15987
  "height": 44,
15988
- "accessibilityLabel": "Item actions"
15988
+ "accessibilityLabel": "$item.collectionActionsLabel"
15989
15989
  }
15990
15990
  },
15991
15991
  "items": [
@@ -16255,7 +16255,7 @@ const SCREENS = runtimeSetting({
16255
16255
  "modifiers": {
16256
16256
  "width": 44,
16257
16257
  "height": 44,
16258
- "accessibilityLabel": "Item actions"
16258
+ "accessibilityLabel": "$item.collectionActionsLabel"
16259
16259
  }
16260
16260
  },
16261
16261
  "items": [
@@ -16812,7 +16812,7 @@ const SCREENS = runtimeSetting({
16812
16812
  "modifiers": {
16813
16813
  "width": 44,
16814
16814
  "height": 44,
16815
- "accessibilityLabel": "Item actions"
16815
+ "accessibilityLabel": "$item.collectionActionsLabel"
16816
16816
  }
16817
16817
  },
16818
16818
  "items": [
@@ -58,6 +58,13 @@ export interface CollectionConfig {
58
58
  /** At or below this many records, with no query/filter narrowing them and no further
59
59
  * page, the list/grid toggle, Refine, chips, search and count are noise. */
60
60
  export const COLLECTION_CHROME_MIN_ITEMS = 4;
61
+ /** The accessible name of a row's overflow menu: `template` with `{title}` filled, or the
62
+ * generic `fallback` for a record with no title. */
63
+ export function collectionActionsLabel(title: string, template: string, fallback: string): string {
64
+ const t = title.trim();
65
+ return t ? template.replace('{title}', () => t) : fallback;
66
+ }
67
+
61
68
  export const COLLECTIONS: Record<string, CollectionConfig> = {
62
69
  himiStoreShop: { rows: 'results', title: 'name', subtitle: 'subtitle', image: 'image', view: 'grid', backendQuery: true, countNoun: ['product', 'products'], favoriteToggle: true },
63
70
  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' } },
@@ -184,6 +191,9 @@ export function projectCollection(source: CollectionRow[], config: CollectionCon
184
191
  collectionSelectLabel: prefs.selectedIds.includes(collectionId(row)) ? 'Selected' : 'Select',
185
192
  // The save toggle names the action it WILL take (the service localizes it).
186
193
  collectionSaveLabel: prefs.savedIds.includes(collectionId(row)) ? 'Remove from saved' : 'Save',
194
+ // The row's overflow menu, named for its record: out of context (a rotor, a voice
195
+ // command) a list of identical "Item actions" cannot be told apart.
196
+ collectionActionsLabel: collectionActionsLabel(collectionTitle(row, config), 'Actions for {title}', 'Item actions'),
187
197
  collectionSubtitle: scalar(row[config.subtitle ?? '']) || scalar(row.subtitle) || scalar(row.description) || scalar(row.meta),
188
198
  collectionImage: scalar(row[config.image ?? '']), collectionNoImage: !scalar(row[config.image ?? '']), collectionHasImage: !!scalar(row[config.image ?? '']),
189
199
  collectionSaved: prefs.savedIds.includes(collectionId(row)), collectionNotSaved: !prefs.savedIds.includes(collectionId(row)), collectionSelected: prefs.selectedIds.includes(collectionId(row)),
@@ -1,5 +1,5 @@
1
1
  import { defineService as register, type ServiceDefinition } from '@himalaya/state';
2
- import { COLLECTIONS, COLLECTION_CHROME_MIN_ITEMS, initialCollection, normalizeCollection, projectCollection, collectionId, type CollectionRow } from './collection-contract.js';
2
+ import { COLLECTIONS, COLLECTION_CHROME_MIN_ITEMS, initialCollection, normalizeCollection, projectCollection, collectionId, collectionActionsLabel, type CollectionRow } from './collection-contract.js';
3
3
  import { localPreferences, type PreferenceRuntime } from './local-preferences.js';
4
4
  import { copyParam, stashCopy } from './himi-copy.js';
5
5
  import { createCollectionQuery, type CollectionQuerySource, type CollectionQueryState } from './collection-query.js';
@@ -130,6 +130,8 @@ export function decorateCollection(name: string, def: { state: State; actions?:
130
130
  // the save toggle names the action it WILL take for this row. The
131
131
  // old static "Save / unsave" made the owner work out the row's state.
132
132
  row.collectionSaveLabel = row.collectionSaved ? copyParam('collection.unsave', 'Remove from saved') : copyParam('collection.save', 'Save');
133
+ row.collectionActionsLabel = collectionActionsLabel(String(row.collectionTitle ?? ''),
134
+ copyParam('collection.itemActionsFor', 'Actions for {title}'), copyParam('collection.itemActions', 'Item actions'));
133
135
  });
134
136
  if (previewId && !rows.some(row => collectionId(row) === previewId)) previewId = '';
135
137
  const filterChoices = [{ id: 'all', label: copyParam('collection.all', 'All') }, { id: 'saved', label: copyParam('collection.saved', 'Saved') },