@shopify/ui-extensions 2026.10.0-rc.9 → 2026.10.1

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 (339) hide show
  1. package/build/cjs/surfaces/customer-account/preact/authenticated-account.js +1 -1
  2. package/build/cjs/surfaces/point-of-sale/events.js +39 -22
  3. package/build/cjs/surfaces/point-of-sale/pos-list-template.js +339 -0
  4. package/build/cjs/surfaces/point-of-sale.js +2 -0
  5. package/build/esm/surfaces/customer-account/preact/authenticated-account.mjs +1 -1
  6. package/build/esm/surfaces/point-of-sale/events.mjs +39 -22
  7. package/build/esm/surfaces/point-of-sale/pos-list-template.mjs +331 -0
  8. package/build/esm/surfaces/point-of-sale.mjs +1 -0
  9. package/build/esnext/surfaces/customer-account/preact/authenticated-account.esnext +1 -1
  10. package/build/esnext/surfaces/point-of-sale/events.esnext +39 -22
  11. package/build/esnext/surfaces/point-of-sale/pos-list-template.esnext +331 -0
  12. package/build/esnext/surfaces/point-of-sale.esnext +1 -0
  13. package/build/ts/shared.d.ts +6 -20
  14. package/build/ts/shared.d.ts.map +1 -1
  15. package/build/ts/surfaces/admin/api/picker/picker.d.ts +2 -2
  16. package/build/ts/surfaces/admin/api/picker/picker.d.ts.map +1 -1
  17. package/build/ts/surfaces/admin/components/AdminAction.d.ts +2 -2
  18. package/build/ts/surfaces/admin/components/AdminBlock.d.ts +3 -3
  19. package/build/ts/surfaces/admin/components/AdminPrintAction.d.ts +2 -2
  20. package/build/ts/surfaces/admin/components/AppNav.d.ts +1 -1
  21. package/build/ts/surfaces/admin/components/Avatar.d.ts +1 -1
  22. package/build/ts/surfaces/admin/components/Badge.d.ts +1 -1
  23. package/build/ts/surfaces/admin/components/Banner.d.ts +1 -1
  24. package/build/ts/surfaces/admin/components/Box.d.ts +1 -1
  25. package/build/ts/surfaces/admin/components/Button.d.ts +1 -1
  26. package/build/ts/surfaces/admin/components/ButtonGroup.d.ts +1 -1
  27. package/build/ts/surfaces/admin/components/Checkbox.d.ts +3 -3
  28. package/build/ts/surfaces/admin/components/Chip.d.ts +1 -1
  29. package/build/ts/surfaces/admin/components/Choice.d.ts +3 -3
  30. package/build/ts/surfaces/admin/components/ChoiceList.d.ts +3 -3
  31. package/build/ts/surfaces/admin/components/Clickable.d.ts +1 -1
  32. package/build/ts/surfaces/admin/components/ClickableChip.d.ts +1 -1
  33. package/build/ts/surfaces/admin/components/ColorField.d.ts +1 -1
  34. package/build/ts/surfaces/admin/components/ColorPicker.d.ts +1 -1
  35. package/build/ts/surfaces/admin/components/DateField.d.ts +1 -1
  36. package/build/ts/surfaces/admin/components/DatePicker.d.ts +1 -1
  37. package/build/ts/surfaces/admin/components/Divider.d.ts +1 -1
  38. package/build/ts/surfaces/admin/components/DropZone.d.ts +1 -1
  39. package/build/ts/surfaces/admin/components/EmailField.d.ts +1 -1
  40. package/build/ts/surfaces/admin/components/EmptyState.d.ts +1 -1
  41. package/build/ts/surfaces/admin/components/Form.d.ts +1 -1
  42. package/build/ts/surfaces/admin/components/FunctionSettings.d.ts +1 -1
  43. package/build/ts/surfaces/admin/components/Grid.d.ts +1 -1
  44. package/build/ts/surfaces/admin/components/GridItem.d.ts +1 -1
  45. package/build/ts/surfaces/admin/components/Heading.d.ts +1 -1
  46. package/build/ts/surfaces/admin/components/Icon.d.ts +1 -1
  47. package/build/ts/surfaces/admin/components/Image.d.ts +1 -1
  48. package/build/ts/surfaces/admin/components/Link.d.ts +1 -1
  49. package/build/ts/surfaces/admin/components/ListItem.d.ts +1 -1
  50. package/build/ts/surfaces/admin/components/Menu.d.ts +1 -1
  51. package/build/ts/surfaces/admin/components/Modal.d.ts +1 -1
  52. package/build/ts/surfaces/admin/components/MoneyField.d.ts +1 -1
  53. package/build/ts/surfaces/admin/components/Number.d.ts +1 -1
  54. package/build/ts/surfaces/admin/components/NumberField.d.ts +1 -1
  55. package/build/ts/surfaces/admin/components/Option.d.ts +3 -3
  56. package/build/ts/surfaces/admin/components/OptionGroup.d.ts +1 -1
  57. package/build/ts/surfaces/admin/components/OrderedList.d.ts +1 -1
  58. package/build/ts/surfaces/admin/components/Page.d.ts +1 -1
  59. package/build/ts/surfaces/admin/components/Paragraph.d.ts +1 -1
  60. package/build/ts/surfaces/admin/components/PasswordField.d.ts +1 -1
  61. package/build/ts/surfaces/admin/components/Popover.d.ts +1 -1
  62. package/build/ts/surfaces/admin/components/Progress.d.ts +155 -0
  63. package/build/ts/surfaces/admin/components/QueryContainer.d.ts +1 -1
  64. package/build/ts/surfaces/admin/components/SearchField.d.ts +1 -1
  65. package/build/ts/surfaces/admin/components/Section.d.ts +11 -3
  66. package/build/ts/surfaces/admin/components/Select.d.ts +1 -1
  67. package/build/ts/surfaces/admin/components/Spinner.d.ts +1 -1
  68. package/build/ts/surfaces/admin/components/Stack.d.ts +1 -1
  69. package/build/ts/surfaces/admin/components/StandardComponents.d.ts +1 -1
  70. package/build/ts/surfaces/admin/components/StandardComponents.d.ts.map +1 -1
  71. package/build/ts/surfaces/admin/components/Switch.d.ts +3 -3
  72. package/build/ts/surfaces/admin/components/Table.d.ts +1 -1
  73. package/build/ts/surfaces/admin/components/TableBody.d.ts +1 -1
  74. package/build/ts/surfaces/admin/components/TableCell.d.ts +1 -1
  75. package/build/ts/surfaces/admin/components/TableHeader.d.ts +1 -1
  76. package/build/ts/surfaces/admin/components/TableHeaderRow.d.ts +1 -1
  77. package/build/ts/surfaces/admin/components/TableRow.d.ts +1 -1
  78. package/build/ts/surfaces/admin/components/Text.d.ts +1 -1
  79. package/build/ts/surfaces/admin/components/TextArea.d.ts +1 -1
  80. package/build/ts/surfaces/admin/components/TextField.d.ts +1 -1
  81. package/build/ts/surfaces/admin/components/Thumbnail.d.ts +1 -1
  82. package/build/ts/surfaces/admin/components/Tooltip.d.ts +1 -1
  83. package/build/ts/surfaces/admin/components/URLField.d.ts +1 -1
  84. package/build/ts/surfaces/admin/components/UnorderedList.d.ts +1 -1
  85. package/build/ts/surfaces/admin/components/shared.d.ts +47 -7
  86. package/build/ts/surfaces/admin/targets/admin.abandoned-checkout-details.action.render.d.ts +3 -0
  87. package/build/ts/surfaces/admin/targets/admin.abandoned-checkout-details.block.render.d.ts +3 -0
  88. package/build/ts/surfaces/admin/targets/admin.abandoned-checkout-index.action.render.d.ts +3 -0
  89. package/build/ts/surfaces/admin/targets/admin.app.home.render.d.ts +3 -0
  90. package/build/ts/surfaces/admin/targets/admin.app.intent.render.d.ts +3 -0
  91. package/build/ts/surfaces/admin/targets/admin.catalog-details.action.render.d.ts +3 -0
  92. package/build/ts/surfaces/admin/targets/admin.catalog-details.block.render.d.ts +3 -0
  93. package/build/ts/surfaces/admin/targets/admin.collection-details.action.render.d.ts +3 -0
  94. package/build/ts/surfaces/admin/targets/admin.collection-details.block.render.d.ts +3 -0
  95. package/build/ts/surfaces/admin/targets/admin.collection-index.action.render.d.ts +3 -0
  96. package/build/ts/surfaces/admin/targets/admin.company-details.action.render.d.ts +3 -0
  97. package/build/ts/surfaces/admin/targets/admin.company-details.block.render.d.ts +3 -0
  98. package/build/ts/surfaces/admin/targets/admin.company-location-details.block.render.d.ts +3 -0
  99. package/build/ts/surfaces/admin/targets/admin.customer-details.action.render.d.ts +3 -0
  100. package/build/ts/surfaces/admin/targets/admin.customer-details.block.render.d.ts +3 -0
  101. package/build/ts/surfaces/admin/targets/admin.customer-index.action.render.d.ts +3 -0
  102. package/build/ts/surfaces/admin/targets/admin.customer-index.selection-action.render.d.ts +3 -0
  103. package/build/ts/surfaces/admin/targets/admin.customer-segment-details.action.render.d.ts +3 -0
  104. package/build/ts/surfaces/admin/targets/admin.discount-details.action.render.d.ts +3 -0
  105. package/build/ts/surfaces/admin/targets/admin.discount-details.function-settings.render.d.ts +3 -0
  106. package/build/ts/surfaces/admin/targets/admin.discount-index.action.render.d.ts +3 -0
  107. package/build/ts/surfaces/admin/targets/admin.discount-index.selection-action.render.d.ts +3 -0
  108. package/build/ts/surfaces/admin/targets/admin.draft-order-details.action.render.d.ts +3 -0
  109. package/build/ts/surfaces/admin/targets/admin.draft-order-details.block.render.d.ts +3 -0
  110. package/build/ts/surfaces/admin/targets/admin.draft-order-index.action.render.d.ts +3 -0
  111. package/build/ts/surfaces/admin/targets/admin.draft-order-index.selection-action.render.d.ts +3 -0
  112. package/build/ts/surfaces/admin/targets/admin.gift-card-details.action.render.d.ts +3 -0
  113. package/build/ts/surfaces/admin/targets/admin.gift-card-details.block.render.d.ts +3 -0
  114. package/build/ts/surfaces/admin/targets/admin.order-details.action.render.d.ts +3 -0
  115. package/build/ts/surfaces/admin/targets/admin.order-details.block.render.d.ts +3 -0
  116. package/build/ts/surfaces/admin/targets/admin.order-details.print-action.render.d.ts +3 -0
  117. package/build/ts/surfaces/admin/targets/admin.order-fulfilled-card.action.render.d.ts +3 -0
  118. package/build/ts/surfaces/admin/targets/admin.order-index.action.render.d.ts +3 -0
  119. package/build/ts/surfaces/admin/targets/admin.order-index.selection-action.render.d.ts +3 -0
  120. package/build/ts/surfaces/admin/targets/admin.order-index.selection-print-action.render.d.ts +3 -0
  121. package/build/ts/surfaces/admin/targets/admin.product-details.action.render.d.ts +3 -0
  122. package/build/ts/surfaces/admin/targets/admin.product-details.block.render.d.ts +3 -0
  123. package/build/ts/surfaces/admin/targets/admin.product-details.configuration.render.d.ts +3 -0
  124. package/build/ts/surfaces/admin/targets/admin.product-details.print-action.render.d.ts +3 -0
  125. package/build/ts/surfaces/admin/targets/admin.product-details.reorder.render.d.ts +3 -0
  126. package/build/ts/surfaces/admin/targets/admin.product-index.action.render.d.ts +3 -0
  127. package/build/ts/surfaces/admin/targets/admin.product-index.selection-action.render.d.ts +3 -0
  128. package/build/ts/surfaces/admin/targets/admin.product-index.selection-print-action.render.d.ts +3 -0
  129. package/build/ts/surfaces/admin/targets/admin.product-purchase-option.action.render.d.ts +3 -0
  130. package/build/ts/surfaces/admin/targets/admin.product-variant-details.action.render.d.ts +3 -0
  131. package/build/ts/surfaces/admin/targets/admin.product-variant-details.block.render.d.ts +3 -0
  132. package/build/ts/surfaces/admin/targets/admin.product-variant-details.configuration.render.d.ts +3 -0
  133. package/build/ts/surfaces/admin/targets/admin.product-variant-purchase-option.action.render.d.ts +3 -0
  134. package/build/ts/surfaces/admin/targets/admin.settings.internal-order-routing-rule.render.d.ts +3 -0
  135. package/build/ts/surfaces/admin/targets/admin.settings.order-routing-rule.render.d.ts +3 -0
  136. package/build/ts/surfaces/admin/targets/admin.settings.validation.render.d.ts +3 -0
  137. package/build/ts/surfaces/checkout/api/address-autocomplete/format-suggestion.d.ts +7 -0
  138. package/build/ts/surfaces/checkout/api/address-autocomplete/format-suggestion.d.ts.map +1 -1
  139. package/build/ts/surfaces/checkout/api/address-autocomplete/shared.d.ts +8 -1
  140. package/build/ts/surfaces/checkout/api/address-autocomplete/shared.d.ts.map +1 -1
  141. package/build/ts/surfaces/checkout/api/address-autocomplete/standard.d.ts +2 -2
  142. package/build/ts/surfaces/checkout/api/address-autocomplete/standard.d.ts.map +1 -1
  143. package/build/ts/surfaces/checkout/api/address-autocomplete/suggest.d.ts +7 -0
  144. package/build/ts/surfaces/checkout/api/address-autocomplete/suggest.d.ts.map +1 -1
  145. package/build/ts/surfaces/checkout/api/checkout/checkout.d.ts +15 -4
  146. package/build/ts/surfaces/checkout/api/checkout/checkout.d.ts.map +1 -1
  147. package/build/ts/surfaces/checkout/api/redeemable/redeemable.d.ts +1 -1
  148. package/build/ts/surfaces/checkout/api/shared.d.ts +108 -1
  149. package/build/ts/surfaces/checkout/api/shared.d.ts.map +1 -1
  150. package/build/ts/surfaces/checkout/api/standard/standard.d.ts +8 -4
  151. package/build/ts/surfaces/checkout/api/standard/standard.d.ts.map +1 -1
  152. package/build/ts/surfaces/checkout/components/MoneyField.d.ts +3 -1
  153. package/build/ts/surfaces/checkout/components/NumberField.d.ts +3 -1
  154. package/build/ts/surfaces/checkout/components/components-shared.d.ts +1 -1
  155. package/build/ts/surfaces/checkout/preact/country.d.ts +1 -1
  156. package/build/ts/surfaces/checkout/preact/country.d.ts.map +1 -1
  157. package/build/ts/surfaces/checkout.d.ts +2 -2
  158. package/build/ts/surfaces/checkout.d.ts.map +1 -1
  159. package/build/ts/surfaces/customer-account/api/order-status/order-status.d.ts +1 -1
  160. package/build/ts/surfaces/customer-account/api/shared.d.ts +26 -7
  161. package/build/ts/surfaces/customer-account/api/shared.d.ts.map +1 -1
  162. package/build/ts/surfaces/customer-account/api.d.ts +1 -1
  163. package/build/ts/surfaces/customer-account/api.d.ts.map +1 -1
  164. package/build/ts/surfaces/customer-account/components/MoneyField.d.ts +3 -1
  165. package/build/ts/surfaces/customer-account/components/NumberField.d.ts +3 -1
  166. package/build/ts/surfaces/customer-account/components/components-shared.d.ts +1 -1
  167. package/build/ts/surfaces/customer-account/preact/authenticated-account.d.ts +3 -3
  168. package/build/ts/surfaces/customer-account/preact/authenticated-account.d.ts.map +1 -1
  169. package/build/ts/surfaces/point-of-sale/api/cart-api/cart-api.d.ts +13 -0
  170. package/build/ts/surfaces/point-of-sale/api/cart-api/cart-api.d.ts.map +1 -1
  171. package/build/ts/surfaces/point-of-sale/api/device-api/device-api.d.ts +4 -0
  172. package/build/ts/surfaces/point-of-sale/api/device-api/device-api.d.ts.map +1 -1
  173. package/build/ts/surfaces/point-of-sale/api/docs.d.ts +7 -0
  174. package/build/ts/surfaces/point-of-sale/api/docs.d.ts.map +1 -1
  175. package/build/ts/surfaces/point-of-sale/api/extension-api/extension-api.d.ts +25 -5
  176. package/build/ts/surfaces/point-of-sale/api/extension-api/extension-api.d.ts.map +1 -1
  177. package/build/ts/surfaces/point-of-sale/api/navigation-api/navigation-api.d.ts +19 -7
  178. package/build/ts/surfaces/point-of-sale/api/navigation-api/navigation-api.d.ts.map +1 -1
  179. package/build/ts/surfaces/point-of-sale/api/resolution-api/resolution-api.d.ts +28 -3
  180. package/build/ts/surfaces/point-of-sale/api/resolution-api/resolution-api.d.ts.map +1 -1
  181. package/build/ts/surfaces/point-of-sale/api/session-api/session-api.d.ts +1 -1
  182. package/build/ts/surfaces/point-of-sale/api.d.ts +2 -2
  183. package/build/ts/surfaces/point-of-sale/api.d.ts.map +1 -1
  184. package/build/ts/surfaces/point-of-sale/components/POSList.d.ts +179 -0
  185. package/build/ts/surfaces/point-of-sale/components/targets/BlockExtensionComponents.d.ts +1 -1
  186. package/build/ts/surfaces/point-of-sale/components/targets/BlockExtensionComponents.d.ts.map +1 -1
  187. package/build/ts/surfaces/point-of-sale/components/targets/ResolutionComponents.d.ts +1 -1
  188. package/build/ts/surfaces/point-of-sale/components/targets/ResolutionComponents.d.ts.map +1 -1
  189. package/build/ts/surfaces/point-of-sale/components/targets/StandardComponents.d.ts +1 -1
  190. package/build/ts/surfaces/point-of-sale/components/targets/StandardComponents.d.ts.map +1 -1
  191. package/build/ts/surfaces/point-of-sale/event/data/BaseData.d.ts +12 -1
  192. package/build/ts/surfaces/point-of-sale/event/data/BaseData.d.ts.map +1 -1
  193. package/build/ts/surfaces/point-of-sale/event/data.d.ts +1 -1
  194. package/build/ts/surfaces/point-of-sale/event/data.d.ts.map +1 -1
  195. package/build/ts/surfaces/point-of-sale/events/scan-event.d.ts +34 -0
  196. package/build/ts/surfaces/point-of-sale/events/scan-event.d.ts.map +1 -0
  197. package/build/ts/surfaces/point-of-sale/events/transaction-complete-event.d.ts +8 -0
  198. package/build/ts/surfaces/point-of-sale/events/transaction-complete-event.d.ts.map +1 -1
  199. package/build/ts/surfaces/point-of-sale/events.d.ts +58 -28
  200. package/build/ts/surfaces/point-of-sale/events.d.ts.map +1 -1
  201. package/build/ts/surfaces/point-of-sale/extension-targets.d.ts +4 -4
  202. package/build/ts/surfaces/point-of-sale/extension-targets.d.ts.map +1 -1
  203. package/build/ts/surfaces/point-of-sale/globals.d.ts +0 -2
  204. package/build/ts/surfaces/point-of-sale/globals.d.ts.map +1 -1
  205. package/build/ts/surfaces/point-of-sale/pos-list-template.d.ts +36 -0
  206. package/build/ts/surfaces/point-of-sale/pos-list-template.d.ts.map +1 -0
  207. package/build/ts/surfaces/point-of-sale/targets/pos.cart.line-item-details.action.render.d.ts +1 -0
  208. package/build/ts/surfaces/point-of-sale/targets/pos.cart.validations.resolution.render.d.ts +1 -0
  209. package/build/ts/surfaces/point-of-sale/targets/pos.customer-details.action.render.d.ts +1 -0
  210. package/build/ts/surfaces/point-of-sale/targets/pos.draft-order-details.action.render.d.ts +1 -0
  211. package/build/ts/surfaces/point-of-sale/targets/pos.exchange.post.action.render.d.ts +1 -0
  212. package/build/ts/surfaces/point-of-sale/targets/pos.home.modal.render.d.ts +1 -0
  213. package/build/ts/surfaces/point-of-sale/targets/pos.order-details.action.render.d.ts +1 -0
  214. package/build/ts/surfaces/point-of-sale/targets/pos.payment.validations.resolution.render.d.ts +1 -0
  215. package/build/ts/surfaces/point-of-sale/targets/pos.product-details.action.render.d.ts +1 -0
  216. package/build/ts/surfaces/point-of-sale/targets/pos.purchase.post.action.render.d.ts +1 -0
  217. package/build/ts/surfaces/point-of-sale/targets/pos.register-details.action.render.d.ts +1 -0
  218. package/build/ts/surfaces/point-of-sale/targets/pos.return.post.action.render.d.ts +1 -0
  219. package/build/ts/surfaces/point-of-sale/types/base-transaction-complete.d.ts +8 -0
  220. package/build/ts/surfaces/point-of-sale/types/base-transaction-complete.d.ts.map +1 -1
  221. package/build/ts/surfaces/point-of-sale/types/session.d.ts +0 -6
  222. package/build/ts/surfaces/point-of-sale/types/session.d.ts.map +1 -1
  223. package/build/ts/surfaces/point-of-sale.d.ts +1 -0
  224. package/build/ts/surfaces/point-of-sale.d.ts.map +1 -1
  225. package/build/tsconfig.tsbuildinfo +1 -1
  226. package/package.json +2 -1
  227. package/src/shared.ts +22 -21
  228. package/src/surfaces/admin/api/picker/picker.ts +5 -2
  229. package/src/surfaces/admin/components/AdminAction.d.ts +2 -2
  230. package/src/surfaces/admin/components/AdminBlock.d.ts +3 -3
  231. package/src/surfaces/admin/components/AdminPrintAction.d.ts +2 -2
  232. package/src/surfaces/admin/components/AppNav.d.ts +1 -1
  233. package/src/surfaces/admin/components/Avatar.d.ts +1 -1
  234. package/src/surfaces/admin/components/Badge.d.ts +1 -1
  235. package/src/surfaces/admin/components/Banner.d.ts +1 -1
  236. package/src/surfaces/admin/components/Box.d.ts +1 -1
  237. package/src/surfaces/admin/components/Button.d.ts +1 -1
  238. package/src/surfaces/admin/components/ButtonGroup.d.ts +1 -1
  239. package/src/surfaces/admin/components/Checkbox.d.ts +3 -3
  240. package/src/surfaces/admin/components/Chip.d.ts +1 -1
  241. package/src/surfaces/admin/components/Choice.d.ts +3 -3
  242. package/src/surfaces/admin/components/ChoiceList.d.ts +3 -3
  243. package/src/surfaces/admin/components/Clickable.d.ts +1 -1
  244. package/src/surfaces/admin/components/ClickableChip.d.ts +1 -1
  245. package/src/surfaces/admin/components/ColorField.d.ts +1 -1
  246. package/src/surfaces/admin/components/ColorPicker.d.ts +1 -1
  247. package/src/surfaces/admin/components/DateField.d.ts +1 -1
  248. package/src/surfaces/admin/components/DatePicker.d.ts +1 -1
  249. package/src/surfaces/admin/components/Divider.d.ts +1 -1
  250. package/src/surfaces/admin/components/DropZone.d.ts +1 -1
  251. package/src/surfaces/admin/components/EmailField.d.ts +1 -1
  252. package/src/surfaces/admin/components/EmptyState.d.ts +1 -1
  253. package/src/surfaces/admin/components/Form.d.ts +1 -1
  254. package/src/surfaces/admin/components/FunctionSettings.d.ts +1 -1
  255. package/src/surfaces/admin/components/Grid.d.ts +1 -1
  256. package/src/surfaces/admin/components/GridItem.d.ts +1 -1
  257. package/src/surfaces/admin/components/Heading.d.ts +1 -1
  258. package/src/surfaces/admin/components/Icon.d.ts +1 -1
  259. package/src/surfaces/admin/components/Image.d.ts +1 -1
  260. package/src/surfaces/admin/components/Link.d.ts +1 -1
  261. package/src/surfaces/admin/components/ListItem.d.ts +1 -1
  262. package/src/surfaces/admin/components/Menu.d.ts +1 -1
  263. package/src/surfaces/admin/components/Modal.d.ts +1 -1
  264. package/src/surfaces/admin/components/MoneyField.d.ts +1 -1
  265. package/src/surfaces/admin/components/Number.d.ts +1 -1
  266. package/src/surfaces/admin/components/NumberField.d.ts +1 -1
  267. package/src/surfaces/admin/components/Option.d.ts +3 -3
  268. package/src/surfaces/admin/components/OptionGroup.d.ts +1 -1
  269. package/src/surfaces/admin/components/OrderedList.d.ts +1 -1
  270. package/src/surfaces/admin/components/Page.d.ts +1 -1
  271. package/src/surfaces/admin/components/Paragraph.d.ts +1 -1
  272. package/src/surfaces/admin/components/PasswordField.d.ts +1 -1
  273. package/src/surfaces/admin/components/Popover.d.ts +1 -1
  274. package/src/surfaces/admin/components/Progress.d.ts +155 -0
  275. package/src/surfaces/admin/components/QueryContainer.d.ts +1 -1
  276. package/src/surfaces/admin/components/SearchField.d.ts +1 -1
  277. package/src/surfaces/admin/components/Section.d.ts +11 -3
  278. package/src/surfaces/admin/components/Select.d.ts +1 -1
  279. package/src/surfaces/admin/components/Spinner.d.ts +1 -1
  280. package/src/surfaces/admin/components/Stack.d.ts +1 -1
  281. package/src/surfaces/admin/components/StandardComponents.ts +3 -0
  282. package/src/surfaces/admin/components/Switch.d.ts +3 -3
  283. package/src/surfaces/admin/components/Table.d.ts +1 -1
  284. package/src/surfaces/admin/components/TableBody.d.ts +1 -1
  285. package/src/surfaces/admin/components/TableCell.d.ts +1 -1
  286. package/src/surfaces/admin/components/TableHeader.d.ts +1 -1
  287. package/src/surfaces/admin/components/TableHeaderRow.d.ts +1 -1
  288. package/src/surfaces/admin/components/TableRow.d.ts +1 -1
  289. package/src/surfaces/admin/components/Text.d.ts +1 -1
  290. package/src/surfaces/admin/components/TextArea.d.ts +1 -1
  291. package/src/surfaces/admin/components/TextField.d.ts +1 -1
  292. package/src/surfaces/admin/components/Thumbnail.d.ts +1 -1
  293. package/src/surfaces/admin/components/Tooltip.d.ts +1 -1
  294. package/src/surfaces/admin/components/URLField.d.ts +1 -1
  295. package/src/surfaces/admin/components/UnorderedList.d.ts +1 -1
  296. package/src/surfaces/admin/components/shared.d.ts +47 -7
  297. package/src/surfaces/admin/components.d.ts +8216 -2635
  298. package/src/surfaces/checkout/api/address-autocomplete/format-suggestion.ts +9 -0
  299. package/src/surfaces/checkout/api/address-autocomplete/shared.ts +9 -0
  300. package/src/surfaces/checkout/api/address-autocomplete/standard.ts +1 -2
  301. package/src/surfaces/checkout/api/address-autocomplete/suggest.ts +8 -0
  302. package/src/surfaces/checkout/api/checkout/checkout.ts +19 -9
  303. package/src/surfaces/checkout/api/redeemable/redeemable.ts +1 -1
  304. package/src/surfaces/checkout/api/shared.ts +116 -1
  305. package/src/surfaces/checkout/api/standard/standard.ts +11 -3
  306. package/src/surfaces/checkout/components/MoneyField.d.ts +3 -1
  307. package/src/surfaces/checkout/components/NumberField.d.ts +3 -1
  308. package/src/surfaces/checkout/components/components-shared.d.ts +1 -1
  309. package/src/surfaces/checkout/preact/country.ts +1 -1
  310. package/src/surfaces/checkout.ts +3 -0
  311. package/src/surfaces/customer-account/api/order-status/order-status.ts +1 -1
  312. package/src/surfaces/customer-account/api/shared.ts +25 -7
  313. package/src/surfaces/customer-account/api.ts +1 -0
  314. package/src/surfaces/customer-account/preact/authenticated-account.ts +3 -3
  315. package/src/surfaces/point-of-sale/api/cart-api/cart-api.ts +14 -0
  316. package/src/surfaces/point-of-sale/api/device-api/device-api.ts +4 -0
  317. package/src/surfaces/point-of-sale/api/docs.ts +8 -0
  318. package/src/surfaces/point-of-sale/api/extension-api/extension-api.ts +25 -5
  319. package/src/surfaces/point-of-sale/api/navigation-api/navigation-api.ts +22 -7
  320. package/src/surfaces/point-of-sale/api/resolution-api/resolution-api.ts +30 -3
  321. package/src/surfaces/point-of-sale/api/session-api/session-api.ts +1 -1
  322. package/src/surfaces/point-of-sale/api.ts +2 -0
  323. package/src/surfaces/point-of-sale/components/POSList.d.ts +179 -0
  324. package/src/surfaces/point-of-sale/components/targets/BlockExtensionComponents.ts +0 -4
  325. package/src/surfaces/point-of-sale/components/targets/ResolutionComponents.ts +1 -1
  326. package/src/surfaces/point-of-sale/components/targets/StandardComponents.ts +1 -3
  327. package/src/surfaces/point-of-sale/components.d.ts +194 -0
  328. package/src/surfaces/point-of-sale/event/data/BaseData.ts +13 -1
  329. package/src/surfaces/point-of-sale/event/data.ts +1 -1
  330. package/src/surfaces/point-of-sale/events/scan-event.ts +34 -0
  331. package/src/surfaces/point-of-sale/events/transaction-complete-event.ts +8 -0
  332. package/src/surfaces/point-of-sale/events.ts +58 -27
  333. package/src/surfaces/point-of-sale/extension-targets.ts +4 -4
  334. package/src/surfaces/point-of-sale/globals.ts +0 -2
  335. package/src/surfaces/point-of-sale/pos-list-template.ts +351 -0
  336. package/src/surfaces/point-of-sale/tests/pos-list-template.test.ts +306 -0
  337. package/src/surfaces/point-of-sale/types/base-transaction-complete.ts +8 -0
  338. package/src/surfaces/point-of-sale/types/session.ts +0 -7
  339. package/src/surfaces/point-of-sale.ts +1 -0
@@ -3,6 +3,7 @@ import type {
3
3
  CashTrackingSessionStartEvent,
4
4
  CashTrackingSessionCompleteEvent,
5
5
  } from './events/cash-tracking-session-events';
6
+ import type {ScanEvent} from './events/scan-event';
6
7
  import type {Cart} from './types/cart';
7
8
  import type {MoneyV2} from './types/money';
8
9
 
@@ -16,6 +17,7 @@ export const POS_EVENT_NAMES = {
16
17
  TRANSACTION_COMPLETE: 'transactioncomplete',
17
18
  CASH_TRACKING_SESSION_START: 'cashtrackingsessionstart',
18
19
  CASH_TRACKING_SESSION_COMPLETE: 'cashtrackingsessioncomplete',
20
+ SCAN: 'scan',
19
21
  } as const;
20
22
 
21
23
  /**
@@ -47,6 +49,12 @@ export interface ShopifyEventMap {
47
49
  [POS_EVENT_NAMES.CASH_TRACKING_SESSION_START]: CashTrackingSessionStartEvent;
48
50
  /** Dispatched when a cash tracking session closes after reconciliation. */
49
51
  [POS_EVENT_NAMES.CASH_TRACKING_SESSION_COMPLETE]: CashTrackingSessionCompleteEvent;
52
+ /**
53
+ * Dispatched once for each successful scan captured by a camera, external,
54
+ * or embedded scanner, after POS has finished handling the scan itself.
55
+ * Every event carries decoded `data` and its `source`.
56
+ */
57
+ [POS_EVENT_NAMES.SCAN]: ScanEvent;
50
58
  }
51
59
 
52
60
  /**
@@ -54,7 +62,7 @@ export interface ShopifyEventMap {
54
62
  *
55
63
  * Used as the generic type parameter for `shopify.intercept`.
56
64
  *
57
- * @private
65
+ * @publicDocs
58
66
  */
59
67
  export interface ShopifyInterceptMap {
60
68
  [POS_INTERCEPT_NAMES.CART_VALIDATIONS]: CartValidationsEvent;
@@ -64,7 +72,7 @@ export interface ShopifyInterceptMap {
64
72
  /**
65
73
  * The data carried by a `cartvalidations` event.
66
74
  *
67
- * @private
75
+ * @publicDocs
68
76
  */
69
77
  export interface CartValidationsEventData {
70
78
  /** A snapshot of the POS cart taken when the event was produced. */
@@ -75,16 +83,17 @@ export interface CartValidationsEventData {
75
83
  * The event a `cartvalidations` interceptor receives. Carries a snapshot of
76
84
  * the POS cart taken when the event was produced.
77
85
  *
78
- * @private
86
+ * @publicDocs
79
87
  */
80
88
  export interface CartValidationsEvent extends CartValidationsEventData {
89
+ /** The event name, always `'cartvalidations'`. */
81
90
  readonly type: typeof POS_INTERCEPT_NAMES.CART_VALIDATIONS;
82
91
  }
83
92
 
84
93
  /**
85
94
  * The kind of payment method being attempted.
86
95
  *
87
- * @private
96
+ * @publicDocs
88
97
  */
89
98
  export type InterceptedPaymentMethodType = 'cash';
90
99
 
@@ -95,7 +104,7 @@ export type InterceptedPaymentMethodType = 'cash';
95
104
  * disambiguates method types a shop can have several of (for example custom
96
105
  * payment methods) as they become interceptable.
97
106
  *
98
- * @private
107
+ * @publicDocs
99
108
  */
100
109
  export interface InterceptedPaymentMethod {
101
110
  readonly type: InterceptedPaymentMethodType;
@@ -109,29 +118,30 @@ export interface InterceptedPaymentMethod {
109
118
  * attempt's payment method and amount; split payments produce one event per
110
119
  * tender, each with its own amount.
111
120
  *
112
- * @private
121
+ * @publicDocs
113
122
  */
114
123
  export interface PaymentValidationsEvent extends PaymentValidationsEventData {
124
+ /** The event name, always `'paymentvalidations'`. */
115
125
  readonly type: typeof POS_INTERCEPT_NAMES.PAYMENT_VALIDATIONS;
116
126
  }
117
127
 
118
128
  /**
119
129
  * The data carried by a `paymentvalidations` event.
120
130
  *
121
- * @private
131
+ * @publicDocs
122
132
  */
123
133
  export interface PaymentValidationsEventData {
124
134
  /** The payment method staff selected. */
125
135
  readonly paymentMethod: InterceptedPaymentMethod;
126
136
 
127
- /** The amount this tender would charge, in presentment currency. */
137
+ /** The cash amount received for this tender, in presentment currency. */
128
138
  readonly amount: MoneyV2;
129
139
  }
130
140
 
131
141
  /**
132
142
  * Targets the whole cart rather than a specific line item.
133
143
  *
134
- * @private
144
+ * @publicDocs
135
145
  */
136
146
  export type CartTarget = '$.cart';
137
147
 
@@ -139,38 +149,50 @@ export type CartTarget = '$.cart';
139
149
  * Targets one cart line item by its `uuid` from this event's `cart` snapshot,
140
150
  * for example `$.cart.lineItems['adfd6b06-4a24-4f5f-9f4b-ea21f4432dd4']`.
141
151
  *
142
- * @private
152
+ * @publicDocs
143
153
  */
144
154
  export type CartLineItemTarget = `$.cart.lineItems['${string}']`;
145
155
 
146
- /** @private */
156
+ /**
157
+ * A target that a `cartvalidations` interceptor can use: the whole cart or
158
+ * one cart line item.
159
+ *
160
+ * @publicDocs
161
+ */
147
162
  export type CartValidationTarget = CartTarget | CartLineItemTarget;
148
163
 
149
164
  /**
150
165
  * Targets the payment attempt being intercepted.
151
166
  *
152
- * @private
167
+ * @publicDocs
153
168
  */
154
169
  export type PaymentTarget = '$.payment';
155
170
 
156
- /** @private */
171
+ /**
172
+ * A target that a `paymentvalidations` interceptor can use. The only
173
+ * supported target is the payment attempt.
174
+ *
175
+ * @publicDocs
176
+ */
157
177
  export type PaymentValidationTarget = PaymentTarget;
158
178
 
159
179
  /**
160
180
  * Where a validation applies, as an enumerated token. Targets are matched
161
181
  * as exact strings, never evaluated as JSON paths.
162
182
  *
163
- * @private
183
+ * @publicDocs
164
184
  */
165
185
  export type ValidationTarget = CartValidationTarget | PaymentValidationTarget;
166
186
 
167
187
  /**
168
188
  * Maps POS interceptable workflow names to their valid validation targets.
169
189
  *
170
- * @private
190
+ * @publicDocs
171
191
  */
172
192
  interface ValidationTargetMap {
193
+ /** The targets that a `cartvalidations` interceptor can return. */
173
194
  [POS_INTERCEPT_NAMES.CART_VALIDATIONS]: CartValidationTarget;
195
+ /** The targets that a `paymentvalidations` interceptor can return. */
174
196
  [POS_INTERCEPT_NAMES.PAYMENT_VALIDATIONS]: PaymentValidationTarget;
175
197
  }
176
198
 
@@ -178,28 +200,30 @@ interface ValidationTargetMap {
178
200
  * The interceptor callback for a POS interceptable workflow, keyed by the
179
201
  * workflow name so the event and its valid validation targets stay paired.
180
202
  *
181
- * @private
203
+ * @publicDocs
182
204
  */
183
205
  export type ShopifyInterceptor<K extends keyof ShopifyInterceptMap> = (
184
206
  event: ShopifyInterceptMap[K],
185
207
  ) => InterceptResult<ValidationTargetMap[K]>;
186
208
 
187
209
  /**
188
- * The result an interceptor returns. An empty `operations` list allows the
189
- * workflow; an `ERROR` validation blocks it.
210
+ * The result an interceptor returns. An empty `operations` list adds no
211
+ * findings from this interceptor and doesn't remove or override findings from
212
+ * other interceptors.
190
213
  *
191
- * @private
214
+ * @publicDocs
192
215
  */
193
216
  export interface InterceptResult<
194
217
  TTarget extends ValidationTarget = ValidationTarget,
195
218
  > {
219
+ /** The operations to apply. Each operation can add one validation finding. */
196
220
  operations: Operation<TTarget>[];
197
221
  }
198
222
 
199
223
  /**
200
224
  * A single host operation produced by an interceptor.
201
225
  *
202
- * @private
226
+ * @publicDocs
203
227
  */
204
228
  export interface Operation<
205
229
  TTarget extends ValidationTarget = ValidationTarget,
@@ -207,31 +231,37 @@ export interface Operation<
207
231
  validationAdd?: ValidationAdd<TTarget>;
208
232
  }
209
233
 
210
- /** @private */
234
+ /**
235
+ * The severity of a validation. `ERROR` can block the workflow when blocking
236
+ * is declared and allowed by the store. `WARNING` never blocks.
237
+ *
238
+ * @publicDocs
239
+ */
211
240
  export type ValidationLevel = 'WARNING' | 'ERROR';
212
241
 
213
242
  /**
214
243
  * Adds a validation to the workflow being intercepted.
215
244
  *
216
- * @private
245
+ * @publicDocs
217
246
  */
218
247
  export interface ValidationAdd<
219
248
  TTarget extends ValidationTarget = ValidationTarget,
220
249
  > {
221
- /** `ERROR` blocks the workflow. `WARNING` does not. */
250
+ /** `ERROR` creates a finding labeled `Required` only when blocking is declared and allowed by the store. Otherwise, it creates a finding labeled `Recommended`. `WARNING` always creates a finding labeled `Recommended`. */
222
251
  level: ValidationLevel;
223
252
 
224
253
  /**
225
- * Stable identifier for this validation. Handles are namespaced per
226
- * extension and may repeat across targets: the same handle on two line
227
- * items is two validations.
254
+ * Stable identifier for this validation, namespaced per extension. Each
255
+ * handle must be unique within one `operations` array, even across
256
+ * different targets. A result that repeats a handle is rejected. To flag
257
+ * several line items, include the line item `uuid` in each handle.
228
258
  */
229
259
  handle: string;
230
260
 
231
261
  /**
232
262
  * Locates the data the validation applies to; the host decides where it
233
263
  * renders. Omitted or unrecognized targets fall back to the event's root
234
- * scope (`$.cart` / `$.payment`) — the validation still applies, rendered
264
+ * scope (`$.cart` / `$.payment`). The validation still applies, rendered
235
265
  * less specifically.
236
266
  *
237
267
  * Line item uuids are only valid within the event that delivered them:
@@ -246,4 +276,5 @@ export type {
246
276
  TransactionCompleteEvent,
247
277
  CashTrackingSessionStartEvent,
248
278
  CashTrackingSessionCompleteEvent,
279
+ ScanEvent,
249
280
  };
@@ -52,19 +52,19 @@ export interface RenderExtensionTargets {
52
52
  /**
53
53
  * Renders a single interactive tile component on the POS home screen's smart grid. The tile appears once during home screen initialization and remains persistent until navigation occurs. Use this target for high-frequency actions, status displays, or entry points to workflows that merchants need daily.
54
54
  *
55
- * Extensions at this target can dynamically update properties like enabled state and badge values in response to cart changes or device conditions. Tiles typically invoke `shopify.action.presentModal()` to launch the companion modal for complete workflows.
55
+ * Extensions at this target can dynamically update properties like enabled state and badge values in response to cart changes or device conditions. Tiles typically invoke `shopify.action.presentModal()` to launch the companion modal for complete workflows. Tiles can also open the connected cash drawer through the Cash Drawer API.
56
56
  */
57
57
  'pos.home.tile.render': RenderExtension<
58
- StandardApi<'pos.home.tile.render'> & ActionApi & CartApi,
58
+ StandardApi<'pos.home.tile.render'> & ActionApi & CartApi & CashDrawerApi,
59
59
  SmartGridComponents
60
60
  >;
61
61
  /**
62
62
  * Renders a full-screen modal interface launched from smart grid tiles. The modal appears when users tap a companion tile. Use this target for complete workflow experiences that require more space and functionality than the tile interface provides, such as multi-step processes, detailed information displays, or complex user interactions.
63
63
  *
64
- * Extensions at this target support full navigation hierarchies with multiple screens, scroll views, and interactive components to handle sophisticated workflows.
64
+ * Extensions at this target support full navigation hierarchies with multiple screens, scroll views, and interactive components to handle sophisticated workflows, and can open the connected cash drawer through the Cash Drawer API.
65
65
  */
66
66
  'pos.home.modal.render': RenderExtension<
67
- ActionTargetApi<'pos.home.modal.render'> & CartApi,
67
+ ActionTargetApi<'pos.home.modal.render'> & CartApi & CashDrawerApi,
68
68
  BasicComponents
69
69
  >;
70
70
  /**
@@ -44,8 +44,6 @@ export interface BackgroundShopifyGlobal extends ShopifyGlobal {
44
44
  /**
45
45
  * Register an interceptor for a POS host workflow that can be blocked.
46
46
  * Returns a function that unregisters the interceptor.
47
- *
48
- * @private
49
47
  */
50
48
  intercept<K extends keyof ShopifyInterceptMap>(
51
49
  type: K,
@@ -0,0 +1,351 @@
1
+ import htm from 'htm';
2
+
3
+ import type {
4
+ POSListItemTemplate,
5
+ POSListTemplateNode,
6
+ POSListTemplateProp,
7
+ POSListTemplateSegment,
8
+ POSListTemplates,
9
+ } from './components/POSList';
10
+
11
+ export type {
12
+ POSListItemTemplate,
13
+ POSListTemplateNode,
14
+ POSListTemplateProp,
15
+ POSListTemplateSegment,
16
+ POSListTemplates,
17
+ };
18
+
19
+ /**
20
+ * The tagged template that compiles `<s-pos-list-item>` markup into the
21
+ * `itemTemplates` value `<s-pos-list>` accepts. Templates are static: the
22
+ * result contains no functions. Compilation and validation happen when the
23
+ * helper executes, not during the extension build. Define templates at module
24
+ * scope to compile once per module execution.
25
+ * Invalid templates throw synchronously and return no partial collection.
26
+ * An uncaught module-scope exception aborts module evaluation; catch the helper
27
+ * invocation to recover explicitly. There is no automatic list-only fallback.
28
+ *
29
+ * @publicDocs
30
+ */
31
+ export type POSListTemplateTag = (
32
+ strings: TemplateStringsArray,
33
+ ...values: never[]
34
+ ) => POSListTemplates;
35
+
36
+ const ITEM_TAG = 's-pos-list-item';
37
+ const LIST_TAG = 's-pos-list';
38
+ const PATH_PATTERN = /^[\w.]+$/;
39
+ const EVENT_PROP_PATTERN = /^on/i;
40
+ const BIND_PREFIX = 'bind:';
41
+ /** `{{#if path}}`, `{{/if}}`, or `{{path}}`; anything else inside `{{ }}` is unsupported. */
42
+ const EXPRESSION_PATTERN = /\{\{\s*(?:#if\s+([\w.]+)|(\/if)|([\w.]+))\s*\}\}/g;
43
+ const ANY_EXPRESSION_PATTERN = /\{\{([\s\S]*?)\}\}/g;
44
+
45
+ interface RawElement {
46
+ tag: string;
47
+ props: Record<string, unknown>;
48
+ children: unknown[];
49
+ }
50
+
51
+ type Token =
52
+ | {kind: 'text'; value: string}
53
+ | {kind: 'path'; path: string}
54
+ | {kind: 'if'; path: string}
55
+ | {kind: 'endif'}
56
+ | {kind: 'element'; element: RawElement};
57
+
58
+ function fail(message: string): never {
59
+ throw new Error(`posListTemplate: ${message}`);
60
+ }
61
+
62
+ function isRawElement(value: unknown): value is RawElement {
63
+ return (
64
+ typeof value === 'object' &&
65
+ value !== null &&
66
+ 'tag' in value &&
67
+ 'props' in value &&
68
+ 'children' in value
69
+ );
70
+ }
71
+
72
+ function createRawElement(
73
+ type: unknown,
74
+ props: Record<string, unknown> | null,
75
+ ...children: unknown[]
76
+ ): RawElement {
77
+ if (typeof type !== 'string') {
78
+ fail('interpolated values are not supported; templates must be static');
79
+ }
80
+ return {tag: type, props: props ?? {}, children};
81
+ }
82
+
83
+ const parse = htm.bind<RawElement>(createRawElement);
84
+
85
+ /**
86
+ * Splits a string into literal and `{{path}}` segments. Used for attribute
87
+ * values, where block expressions have no meaning.
88
+ */
89
+ function parseSegments(value: string): POSListTemplateSegment[] {
90
+ const segments: POSListTemplateSegment[] = [];
91
+ let lastIndex = 0;
92
+ for (const match of value.matchAll(ANY_EXPRESSION_PATTERN)) {
93
+ const expression = match[1]!.trim();
94
+ if (!PATH_PATTERN.test(expression)) {
95
+ if (expression.startsWith('#if') || expression === '/if') {
96
+ fail(
97
+ `{{#if}} is not supported inside an attribute value: "${match[0]}"`,
98
+ );
99
+ }
100
+ fail(`unsupported template expression "${match[0]}"`);
101
+ }
102
+ const index = match.index ?? 0;
103
+ if (index > lastIndex) {
104
+ segments.push(value.slice(lastIndex, index));
105
+ }
106
+ segments.push({path: expression});
107
+ lastIndex = index + match[0].length;
108
+ }
109
+ if (lastIndex < value.length) {
110
+ segments.push(value.slice(lastIndex));
111
+ }
112
+ return segments;
113
+ }
114
+
115
+ function tokenizeText(value: string, tokens: Token[]): void {
116
+ let lastIndex = 0;
117
+ for (const match of value.matchAll(ANY_EXPRESSION_PATTERN)) {
118
+ const index = match.index ?? 0;
119
+ if (index > lastIndex) {
120
+ tokens.push({kind: 'text', value: value.slice(lastIndex, index)});
121
+ }
122
+ EXPRESSION_PATTERN.lastIndex = 0;
123
+ const expression = EXPRESSION_PATTERN.exec(match[0]);
124
+ if (expression === null || expression[0].length !== match[0].length) {
125
+ fail(`unsupported template expression "${match[0]}"`);
126
+ }
127
+ const [, ifPath, endIf, path] = expression;
128
+ if (ifPath !== undefined) {
129
+ tokens.push({kind: 'if', path: ifPath});
130
+ } else if (endIf !== undefined) {
131
+ tokens.push({kind: 'endif'});
132
+ } else if (path !== undefined) {
133
+ tokens.push({kind: 'path', path});
134
+ }
135
+ lastIndex = index + match[0].length;
136
+ }
137
+ if (lastIndex < value.length) {
138
+ tokens.push({kind: 'text', value: value.slice(lastIndex)});
139
+ }
140
+ }
141
+
142
+ function tokenize(rawChildren: unknown[]): Token[] {
143
+ const tokens: Token[] = [];
144
+ for (const child of rawChildren.flat()) {
145
+ if (typeof child === 'string') {
146
+ if (child.trim().length > 0) {
147
+ tokenizeText(child, tokens);
148
+ }
149
+ } else if (isRawElement(child)) {
150
+ tokens.push({kind: 'element', element: child});
151
+ } else if (child !== null && child !== undefined && child !== false) {
152
+ fail('interpolated values are not supported; templates must be static');
153
+ }
154
+ }
155
+ return tokens;
156
+ }
157
+
158
+ function compileProp(
159
+ name: string,
160
+ value: unknown,
161
+ props: Record<string, POSListTemplateProp>,
162
+ ): void {
163
+ const isBinding = name.startsWith(BIND_PREFIX);
164
+ const propName = isBinding ? name.slice(BIND_PREFIX.length) : name;
165
+ if (EVENT_PROP_PATTERN.test(propName)) {
166
+ fail(
167
+ `event handlers are not supported in templates; use onRowClick on <${LIST_TAG}>`,
168
+ );
169
+ }
170
+ if (isBinding) {
171
+ if (typeof value !== 'string' || !PATH_PATTERN.test(value)) {
172
+ fail(`${name} must name a row field path`);
173
+ }
174
+ if (propName in props) {
175
+ fail(`"${propName}" is set both as an attribute and through ${name}`);
176
+ }
177
+ props[propName] = {kind: 'field', path: value};
178
+ return;
179
+ }
180
+ if (typeof value === 'string') {
181
+ props[name] = value.includes('{{')
182
+ ? {kind: 'segments', segments: parseSegments(value)}
183
+ : {kind: 'literal', value};
184
+ return;
185
+ }
186
+ if (typeof value === 'boolean') {
187
+ props[name] = {kind: 'literal', value};
188
+ return;
189
+ }
190
+ fail('interpolated values are not supported; templates must be static');
191
+ }
192
+
193
+ function compileElement(
194
+ element: RawElement,
195
+ parentIfPath?: string,
196
+ ): POSListTemplateNode {
197
+ if (element.tag === ITEM_TAG || element.tag === LIST_TAG) {
198
+ fail(`<${element.tag}> can only appear as a template root`);
199
+ }
200
+ const props: Record<string, POSListTemplateProp> = {};
201
+ // Plain attributes first so `bind:` can detect a collision with one.
202
+ const entries = Object.entries(element.props);
203
+ for (const [name, value] of entries) {
204
+ if (!name.startsWith(BIND_PREFIX)) {
205
+ compileProp(name, value, props);
206
+ }
207
+ }
208
+ for (const [name, value] of entries) {
209
+ if (name.startsWith(BIND_PREFIX)) {
210
+ compileProp(name, value, props);
211
+ }
212
+ }
213
+ const node: POSListTemplateNode = {kind: 'element', tag: element.tag, props};
214
+ const children = compileChildren(element.children, false, parentIfPath);
215
+ if (children.length > 0) {
216
+ node.children = children;
217
+ }
218
+ return node;
219
+ }
220
+
221
+ function compileChildren(
222
+ rawChildren: unknown[],
223
+ atRoot: boolean,
224
+ parentIfPath?: string,
225
+ ): POSListTemplateNode[] {
226
+ const nodes: POSListTemplateNode[] = [];
227
+ let pendingText: POSListTemplateSegment[] = [];
228
+ let openIf: {path: string; children: POSListTemplateNode[]} | undefined;
229
+
230
+ const target = () => (openIf ? openIf.children : nodes);
231
+ const flushText = () => {
232
+ if (pendingText.length === 0) {
233
+ return;
234
+ }
235
+ if (atRoot) {
236
+ fail('text must be inside a component such as <s-text>');
237
+ }
238
+ target().push({kind: 'text', segments: pendingText});
239
+ pendingText = [];
240
+ };
241
+
242
+ for (const token of tokenize(rawChildren)) {
243
+ switch (token.kind) {
244
+ case 'text':
245
+ pendingText.push(token.value);
246
+ break;
247
+ case 'path':
248
+ pendingText.push({path: token.path});
249
+ break;
250
+ case 'if': {
251
+ flushText();
252
+ const enclosingIfPath = openIf?.path ?? parentIfPath;
253
+ if (enclosingIfPath !== undefined) {
254
+ fail(
255
+ `{{#if}} cannot be nested: {{#if ${token.path}}} inside {{#if ${enclosingIfPath}}}`,
256
+ );
257
+ }
258
+ openIf = {path: token.path, children: []};
259
+ break;
260
+ }
261
+ case 'endif':
262
+ flushText();
263
+ if (!openIf) {
264
+ fail('{{/if}} without a matching {{#if}}');
265
+ }
266
+ nodes.push({kind: 'if', path: openIf.path, children: openIf.children});
267
+ openIf = undefined;
268
+ break;
269
+ case 'element':
270
+ flushText();
271
+ target().push(
272
+ compileElement(token.element, openIf?.path ?? parentIfPath),
273
+ );
274
+ break;
275
+ }
276
+ }
277
+ flushText();
278
+ if (openIf) {
279
+ fail(`{{#if ${openIf.path}}} is missing its {{/if}}`);
280
+ }
281
+ return nodes;
282
+ }
283
+
284
+ function compileRoot(root: unknown, seen: Set<string>): POSListItemTemplate {
285
+ if (!isRawElement(root) || root.tag !== ITEM_TAG) {
286
+ fail(`every template root must be an <${ITEM_TAG} templateId="…"> element`);
287
+ }
288
+ let templateId: string | undefined;
289
+ let type: POSListItemTemplate['type'] = 'button';
290
+ for (const [name, value] of Object.entries(root.props)) {
291
+ if (name === 'templateId') {
292
+ if (typeof value !== 'string' || value.length === 0) {
293
+ fail(`<${ITEM_TAG}> requires a literal, non-empty templateId`);
294
+ }
295
+ templateId = value;
296
+ } else if (name === 'type') {
297
+ if (value !== 'button' && value !== 'text') {
298
+ fail(
299
+ `<${ITEM_TAG}> type must be "button" or "text", got ${JSON.stringify(
300
+ value,
301
+ )}`,
302
+ );
303
+ }
304
+ type = value;
305
+ } else {
306
+ fail(
307
+ `<${ITEM_TAG}> does not accept a "${name}" attribute; only templateId and type are allowed`,
308
+ );
309
+ }
310
+ }
311
+ if (templateId === undefined) {
312
+ fail(`<${ITEM_TAG}> requires a literal, non-empty templateId`);
313
+ }
314
+ if (seen.has(templateId)) {
315
+ fail(`duplicate templateId "${templateId}"`);
316
+ }
317
+ seen.add(templateId);
318
+ return {templateId, type, children: compileChildren(root.children, true)};
319
+ }
320
+
321
+ /**
322
+ * Compiles `<s-pos-list-item>` markup into the `itemTemplates` value for
323
+ * `<s-pos-list>`.
324
+ *
325
+ * Compilation and validation happen when this helper executes, not during the
326
+ * extension build. Define templates at module scope to compile once per module
327
+ * execution.
328
+ * Invalid templates throw synchronously and return no partial collection.
329
+ * An uncaught module-scope exception aborts module evaluation; catch the helper
330
+ * invocation to recover explicitly. There is no automatic list-only fallback.
331
+ *
332
+ * Inside a template, `{{path}}` interpolates a row field as text, `bind:prop="path"`
333
+ * passes a row field to a component prop with its own type, and
334
+ * `{{#if path}}…{{/if}}` renders its content only when the field is truthy.
335
+ * Event handlers, interpolated values, and any other `{{…}}` expression are
336
+ * rejected when the template is compiled.
337
+ *
338
+ * @publicDocs
339
+ */
340
+ export const posListTemplate: POSListTemplateTag = (strings, ...values) => {
341
+ if (values.length > 0) {
342
+ fail('interpolated values are not supported; templates must be static');
343
+ }
344
+ const parsed: unknown = parse(strings);
345
+ const roots = Array.isArray(parsed) ? parsed : [parsed];
346
+ const seen = new Set<string>();
347
+ const templates = roots
348
+ .filter((root) => !(typeof root === 'string' && root.trim().length === 0))
349
+ .map((root) => compileRoot(root, seen));
350
+ return {templates};
351
+ };