@mohasinac/appkit 4.59.0 → 4.60.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 (531) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +62 -5
  3. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +2 -2
  4. package/dist/_internal/server/features/brands/actions.js +78 -4
  5. package/dist/_internal/server/features/checkout/actions.d.ts +36 -13
  6. package/dist/_internal/server/features/checkout/actions.js +668 -183
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +18 -1
  8. package/dist/_internal/server/features/gateway-events/index.d.ts +10 -0
  9. package/dist/_internal/server/features/gateway-events/index.js +10 -0
  10. package/dist/_internal/server/features/gateway-events/ingest.d.ts +127 -0
  11. package/dist/_internal/server/features/gateway-events/ingest.js +188 -0
  12. package/dist/_internal/server/features/gateway-events/redact.d.ts +66 -0
  13. package/dist/_internal/server/features/gateway-events/redact.js +151 -0
  14. package/dist/_internal/server/features/grievance/actions.d.ts +63 -0
  15. package/dist/_internal/server/features/grievance/actions.js +173 -0
  16. package/dist/_internal/server/features/grievance/index.d.ts +8 -0
  17. package/dist/_internal/server/features/grievance/index.js +8 -0
  18. package/dist/_internal/server/features/grouped/data.js +28 -3
  19. package/dist/_internal/server/features/lottery/actions.js +99 -4
  20. package/dist/_internal/server/features/order-completion/actions.d.ts +92 -0
  21. package/dist/_internal/server/features/order-completion/actions.js +336 -0
  22. package/dist/_internal/server/features/order-completion/index.d.ts +7 -0
  23. package/dist/_internal/server/features/order-completion/index.js +7 -0
  24. package/dist/_internal/server/features/orders/actions.d.ts +13 -0
  25. package/dist/_internal/server/features/orders/actions.js +56 -2
  26. package/dist/_internal/server/features/orders/adapters.js +26 -0
  27. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +116 -0
  28. package/dist/_internal/server/features/orders/cancellation-refund.js +466 -0
  29. package/dist/_internal/server/features/orders/index.d.ts +2 -1
  30. package/dist/_internal/server/features/orders/index.js +1 -1
  31. package/dist/_internal/server/features/orders/service.d.ts +60 -0
  32. package/dist/_internal/server/features/orders/service.js +74 -0
  33. package/dist/_internal/server/features/payment-cases/disputes.d.ts +76 -0
  34. package/dist/_internal/server/features/payment-cases/disputes.js +241 -0
  35. package/dist/_internal/server/features/payment-cases/index.d.ts +9 -0
  36. package/dist/_internal/server/features/payment-cases/index.js +9 -0
  37. package/dist/_internal/server/features/payouts/actions.d.ts +28 -3
  38. package/dist/_internal/server/features/payouts/actions.js +84 -10
  39. package/dist/_internal/server/features/points/adjust.d.ts +61 -0
  40. package/dist/_internal/server/features/points/adjust.js +121 -0
  41. package/dist/_internal/server/features/points/award.d.ts +65 -0
  42. package/dist/_internal/server/features/points/award.js +145 -0
  43. package/dist/_internal/server/features/price-index/market.d.ts +33 -0
  44. package/dist/_internal/server/features/price-index/market.js +54 -1
  45. package/dist/_internal/server/features/products/data.js +40 -22
  46. package/dist/_internal/server/features/protection-claims/actions.d.ts +72 -0
  47. package/dist/_internal/server/features/protection-claims/actions.js +228 -0
  48. package/dist/_internal/server/features/protection-claims/index.d.ts +8 -0
  49. package/dist/_internal/server/features/protection-claims/index.js +8 -0
  50. package/dist/_internal/server/features/refunds/actions.d.ts +20 -0
  51. package/dist/_internal/server/features/refunds/actions.js +259 -17
  52. package/dist/_internal/server/features/refunds/capacity.d.ts +29 -0
  53. package/dist/_internal/server/features/refunds/capacity.js +37 -0
  54. package/dist/_internal/server/features/reviews/actions.js +3 -2
  55. package/dist/_internal/server/features/search/index-build/sources.js +20 -1
  56. package/dist/_internal/server/features/shipping/reconcile.d.ts +10 -1
  57. package/dist/_internal/server/features/shipping/reconcile.js +34 -3
  58. package/dist/_internal/server/features/shipping/reimbursement.d.ts +117 -0
  59. package/dist/_internal/server/features/shipping/reimbursement.js +223 -0
  60. package/dist/_internal/server/features/stores/tabs.d.ts +19 -4
  61. package/dist/_internal/server/features/stores/tabs.js +24 -4
  62. package/dist/_internal/server/functions/https.d.ts +31 -1
  63. package/dist/_internal/server/functions/https.js +52 -1
  64. package/dist/_internal/server/functions/scheduled.d.ts +72 -1
  65. package/dist/_internal/server/functions/scheduled.js +124 -1
  66. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +62 -16
  67. package/dist/_internal/server/jobs/core/boxRollupReconcile.d.ts +46 -0
  68. package/dist/_internal/server/jobs/core/boxRollupReconcile.js +142 -0
  69. package/dist/_internal/server/jobs/core/dailyDataCleanup.js +149 -1
  70. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +14 -0
  71. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +79 -1
  72. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  73. package/dist/_internal/server/jobs/core/index.js +2 -0
  74. package/dist/_internal/server/jobs/core/marketPriceRollup.d.ts +64 -0
  75. package/dist/_internal/server/jobs/core/marketPriceRollup.js +153 -0
  76. package/dist/_internal/server/jobs/core/obligationSweep.d.ts +36 -0
  77. package/dist/_internal/server/jobs/core/obligationSweep.js +503 -0
  78. package/dist/_internal/server/jobs/core/paymentReconcile.d.ts +79 -0
  79. package/dist/_internal/server/jobs/core/paymentReconcile.js +614 -0
  80. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +34 -0
  81. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +35 -4
  82. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.d.ts +2 -0
  83. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.js +15 -0
  84. package/dist/_internal/server/jobs/handlers/countersReconcileNow.d.ts +65 -0
  85. package/dist/_internal/server/jobs/handlers/countersReconcileNow.js +89 -0
  86. package/dist/_internal/server/jobs/handlers/index.d.ts +5 -0
  87. package/dist/_internal/server/jobs/handlers/index.js +5 -0
  88. package/dist/_internal/server/jobs/handlers/marketPriceRollup.d.ts +2 -0
  89. package/dist/_internal/server/jobs/handlers/marketPriceRollup.js +2 -0
  90. package/dist/_internal/server/jobs/handlers/obligationSweep.d.ts +2 -0
  91. package/dist/_internal/server/jobs/handlers/obligationSweep.js +15 -0
  92. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +30 -1
  93. package/dist/_internal/server/jobs/handlers/paymentReconcile.d.ts +2 -0
  94. package/dist/_internal/server/jobs/handlers/paymentReconcile.js +6 -0
  95. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  96. package/dist/_internal/shared/actions/action-registry.js +71 -0
  97. package/dist/_internal/shared/checkout/coupon-discount.d.ts +73 -0
  98. package/dist/_internal/shared/checkout/coupon-discount.js +103 -0
  99. package/dist/_internal/shared/checkout/lanes.d.ts +42 -0
  100. package/dist/_internal/shared/checkout/lanes.js +46 -0
  101. package/dist/_internal/shared/checkout/order-math.d.ts +149 -1
  102. package/dist/_internal/shared/checkout/order-math.js +251 -3
  103. package/dist/_internal/shared/checkout/refundable-base.d.ts +116 -0
  104. package/dist/_internal/shared/checkout/refundable-base.js +122 -0
  105. package/dist/_internal/shared/features/auctions/config.d.ts +14 -1
  106. package/dist/_internal/shared/features/auctions/config.js +30 -1
  107. package/dist/_internal/shared/features/brands/schema.d.ts +42 -0
  108. package/dist/_internal/shared/features/brands/schema.js +18 -0
  109. package/dist/_internal/shared/features/orders/refund-copy.d.ts +22 -0
  110. package/dist/_internal/shared/features/orders/refund-copy.js +34 -0
  111. package/dist/_internal/shared/features/print/label-profiles.d.ts +198 -0
  112. package/dist/_internal/shared/features/print/label-profiles.js +350 -0
  113. package/dist/_internal/shared/features/products/to-product-item.js +33 -5
  114. package/dist/_internal/shared/fees/calculator.d.ts +31 -2
  115. package/dist/_internal/shared/fees/calculator.js +103 -5
  116. package/dist/_internal/shared/fees/india-states.d.ts +195 -0
  117. package/dist/_internal/shared/fees/india-states.js +190 -0
  118. package/dist/_internal/shared/fees/payout-hold.d.ts +80 -0
  119. package/dist/_internal/shared/fees/payout-hold.js +74 -0
  120. package/dist/_internal/shared/obligations/deadlines.d.ts +94 -0
  121. package/dist/_internal/shared/obligations/deadlines.js +155 -0
  122. package/dist/_internal/shared/shipping/quote.d.ts +96 -0
  123. package/dist/_internal/shared/shipping/quote.js +67 -0
  124. package/dist/_internal/shared/time/business-days.d.ts +91 -0
  125. package/dist/_internal/shared/time/business-days.js +185 -0
  126. package/dist/cli/index.js +0 -2
  127. package/dist/client.d.ts +9 -4
  128. package/dist/client.js +26 -3
  129. package/dist/configs/tailwind.d.ts +0 -12
  130. package/dist/configs/tailwind.js +28 -15
  131. package/dist/constants/api-endpoints.d.ts +51 -9
  132. package/dist/constants/api-endpoints.js +23 -7
  133. package/dist/constants/index.d.ts +1 -1
  134. package/dist/constants/index.js +1 -1
  135. package/dist/contracts/index.d.ts +1 -1
  136. package/dist/contracts/payment.d.ts +131 -0
  137. package/dist/features/about/components/AboutView.js +1 -1
  138. package/dist/features/about/components/DeveloperView.js +5 -2
  139. package/dist/features/about/components/FAQPageView.js +2 -1
  140. package/dist/features/about/components/FeesView.js +2 -1
  141. package/dist/features/about/components/HelpPageView.js +2 -1
  142. package/dist/features/about/components/HowAuctionsWorkView.js +2 -1
  143. package/dist/features/about/components/HowCheckoutWorksView.js +2 -1
  144. package/dist/features/about/components/HowEmiWorksView.js +2 -1
  145. package/dist/features/about/components/HowOffersWorkView.js +2 -1
  146. package/dist/features/about/components/HowOrdersWorkView.js +2 -1
  147. package/dist/features/about/components/HowPayoutsWorkView.js +2 -1
  148. package/dist/features/about/components/HowPreOrdersWorkView.js +2 -1
  149. package/dist/features/about/components/HowReviewsWorkView.js +2 -1
  150. package/dist/features/about/components/PolicyPageView.js +2 -1
  151. package/dist/features/about/components/ProseHero.d.ts +73 -0
  152. package/dist/features/about/components/ProseHero.js +18 -0
  153. package/dist/features/about/components/SecurityPrivacyView.js +2 -1
  154. package/dist/features/about/components/ShippingPolicyView.js +2 -1
  155. package/dist/features/about/components/TrackOrderView.js +2 -1
  156. package/dist/features/about/components/UnauthorizedView.js +1 -1
  157. package/dist/features/about/index.d.ts +2 -0
  158. package/dist/features/about/index.js +5 -0
  159. package/dist/features/account/actions/address-actions.d.ts +26 -2
  160. package/dist/features/account/actions/address-actions.js +25 -1
  161. package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
  162. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  163. package/dist/features/account/components/UserOrdersView.js +17 -0
  164. package/dist/features/account/components/UserSidebar.js +1 -1
  165. package/dist/features/account/hooks/useNotifications.js +29 -0
  166. package/dist/features/admin/actions/admin-coupon-actions.js +36 -0
  167. package/dist/features/admin/components/AdminBeysView.js +2 -2
  168. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  169. package/dist/features/admin/components/AdminBrandEditorView.js +32 -2
  170. package/dist/features/admin/components/AdminBundleEditorView.js +1 -1
  171. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  172. package/dist/features/admin/components/AdminCategoriesView.js +1 -1
  173. package/dist/features/admin/components/AdminCategoryEditorView.js +73 -17
  174. package/dist/features/admin/components/AdminContactEditorView.js +1 -1
  175. package/dist/features/admin/components/AdminCouponEditorView.js +26 -1
  176. package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
  177. package/dist/features/admin/components/AdminFaqsView.js +2 -2
  178. package/dist/features/admin/components/AdminGatewayEventsView.d.ts +54 -0
  179. package/dist/features/admin/components/AdminGatewayEventsView.js +209 -0
  180. package/dist/features/admin/components/AdminGuideHubView.js +1 -1
  181. package/dist/features/admin/components/AdminMoneyCasesView.d.ts +60 -0
  182. package/dist/features/admin/components/AdminMoneyCasesView.js +287 -0
  183. package/dist/features/admin/components/AdminPartsView.js +2 -2
  184. package/dist/features/admin/components/AdminProductsView.js +75 -4
  185. package/dist/features/admin/components/AdminSidebar.js +2 -2
  186. package/dist/features/admin/components/AdminSiteSettingsView.js +65 -7
  187. package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
  188. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  189. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
  190. package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
  191. package/dist/features/admin/components/AdminUsersView.js +72 -1
  192. package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
  193. package/dist/features/admin/components/AdminViewCards.js +4 -4
  194. package/dist/features/admin/components/DataListingView.d.ts +28 -0
  195. package/dist/features/admin/components/DataListingView.js +175 -14
  196. package/dist/features/admin/components/DataTable.d.ts +12 -1
  197. package/dist/features/admin/components/DataTable.js +3 -3
  198. package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
  199. package/dist/features/admin/components/OwnerQuickActions.js +60 -2
  200. package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +1 -1
  201. package/dist/features/admin/components/RecordOwnerQuickActions.js +61 -14
  202. package/dist/features/admin/components/analytics/AdminStatCard.d.ts +35 -1
  203. package/dist/features/admin/components/analytics/AdminStatCard.js +77 -2
  204. package/dist/features/admin/components/index.d.ts +4 -0
  205. package/dist/features/admin/components/index.js +6 -0
  206. package/dist/features/admin/constants/filter-tabs.d.ts +156 -0
  207. package/dist/features/admin/constants/filter-tabs.js +106 -0
  208. package/dist/features/admin/repository/site-settings.repository.d.ts +22 -0
  209. package/dist/features/admin/repository/site-settings.repository.js +82 -1
  210. package/dist/features/admin/schemas/admin-editor-forms.d.ts +21 -0
  211. package/dist/features/admin/schemas/admin-editor-forms.js +44 -0
  212. package/dist/features/admin/schemas/firestore.js +5 -1
  213. package/dist/features/admin/schemas/site-settings-form.js +30 -1
  214. package/dist/features/auctions/actions/bid-actions.js +13 -1
  215. package/dist/features/auctions/components/AuctionBottomActions.js +2 -2
  216. package/dist/features/auctions/components/AuctionDetailPageView.js +3 -1
  217. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -0
  218. package/dist/features/auctions/components/MarketplaceAuctionCard.js +5 -3
  219. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +8 -1
  220. package/dist/features/auctions/components/PlaceBidFormClient.js +2 -2
  221. package/dist/features/audit-log/schemas/firestore.d.ts +28 -0
  222. package/dist/features/audit-log/schemas/firestore.js +14 -0
  223. package/dist/features/auth/permissions/constants.d.ts +17 -1
  224. package/dist/features/auth/permissions/constants.js +18 -0
  225. package/dist/features/blog/components/BlogPostView.js +1 -1
  226. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
  227. package/dist/features/categories/api/[id]/description-template/route.js +107 -1
  228. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  229. package/dist/features/categories/components/BreadcrumbTrail.js +7 -1
  230. package/dist/features/categories/components/BundleDetailView.js +1 -1
  231. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  232. package/dist/features/categories/components/CategoryForm.js +12 -1
  233. package/dist/features/categories/components/CategoryTemplatePicker.js +38 -5
  234. package/dist/features/categories/repository/market-price-index.repository.d.ts +123 -0
  235. package/dist/features/categories/repository/market-price-index.repository.js +105 -0
  236. package/dist/features/categories/repository/price-observation.repository.d.ts +166 -0
  237. package/dist/features/categories/repository/price-observation.repository.js +132 -0
  238. package/dist/features/events/components/EventSaleBanner.js +1 -1
  239. package/dist/features/events/components/EventStatusBadge.js +1 -1
  240. package/dist/features/faq/components/FAQAccordion.js +2 -1
  241. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  242. package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
  243. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  244. package/dist/features/filters/FilterFacetSection.js +1 -1
  245. package/dist/features/filters/SwitchFilter.js +1 -1
  246. package/dist/features/gateway-events/repository/gateway-events.repository.d.ts +117 -0
  247. package/dist/features/gateway-events/repository/gateway-events.repository.js +274 -0
  248. package/dist/features/gateway-events/schemas/firestore.d.ts +217 -0
  249. package/dist/features/gateway-events/schemas/firestore.js +125 -0
  250. package/dist/features/gateway-events/schemas/index.d.ts +81 -0
  251. package/dist/features/gateway-events/schemas/index.js +79 -0
  252. package/dist/features/grouped/components/GroupedListingDetailView.js +1 -1
  253. package/dist/features/homepage/components/AnnouncementBar.js +37 -1
  254. package/dist/features/homepage/components/AnnouncementBar.style.css +30 -0
  255. package/dist/features/homepage/components/BrandsSection.js +1 -1
  256. package/dist/features/homepage/components/CTABannerSection.js +1 -1
  257. package/dist/features/homepage/components/FeaturedBundlesSection.js +14 -24
  258. package/dist/features/homepage/components/HeroCarousel.js +2 -2
  259. package/dist/features/homepage/components/SocialPostCard.js +1 -1
  260. package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +7 -0
  261. package/dist/features/inventory/components/AdminMoveLedgerView.js +157 -0
  262. package/dist/features/inventory/components/AdminStorageBoxesView.d.ts +11 -0
  263. package/dist/features/inventory/components/AdminStorageBoxesView.js +168 -0
  264. package/dist/features/inventory/components/ReceiveStationView.d.ts +39 -0
  265. package/dist/features/inventory/components/ReceiveStationView.js +413 -0
  266. package/dist/features/inventory/components/operator-message.d.ts +29 -0
  267. package/dist/features/inventory/components/operator-message.js +41 -0
  268. package/dist/features/inventory/index.d.ts +13 -0
  269. package/dist/features/inventory/index.js +28 -0
  270. package/dist/features/inventory/repository/inventory-movements.repository.d.ts +97 -0
  271. package/dist/features/inventory/repository/inventory-movements.repository.js +186 -0
  272. package/dist/features/inventory/repository/inventory-placements.repository.d.ts +179 -0
  273. package/dist/features/inventory/repository/inventory-placements.repository.js +345 -0
  274. package/dist/features/inventory/repository/storage-boxes.repository.d.ts +83 -0
  275. package/dist/features/inventory/repository/storage-boxes.repository.js +127 -0
  276. package/dist/features/inventory/schemas/firestore.d.ts +197 -0
  277. package/dist/features/inventory/schemas/firestore.js +159 -0
  278. package/dist/features/layout/AppLayoutShell.d.ts +12 -1
  279. package/dist/features/layout/AppLayoutShell.js +25 -12
  280. package/dist/features/layout/AutoBreadcrumbs.js +162 -3
  281. package/dist/features/layout/AutoBreadcrumbs.style.css +45 -0
  282. package/dist/features/layout/BottomNavbar.d.ts +1 -1
  283. package/dist/features/layout/BottomNavbar.js +2 -2
  284. package/dist/features/media/MediaAvatar.js +1 -1
  285. package/dist/features/media/MediaImage.d.ts +24 -4
  286. package/dist/features/media/MediaImage.js +44 -4
  287. package/dist/features/media/MediaLightbox.js +1 -1
  288. package/dist/features/media/modals/ImageCropModal.js +1 -1
  289. package/dist/features/media/modals/ImageEditor.js +1 -1
  290. package/dist/features/media/upload/MediaUploadField.js +91 -3
  291. package/dist/features/obligations/constants/policies.d.ts +92 -0
  292. package/dist/features/obligations/constants/policies.js +378 -0
  293. package/dist/features/obligations/repository/obligations.repository.d.ts +68 -0
  294. package/dist/features/obligations/repository/obligations.repository.js +158 -0
  295. package/dist/features/obligations/schemas/firestore.d.ts +160 -0
  296. package/dist/features/obligations/schemas/firestore.js +87 -0
  297. package/dist/features/orders/actions/order-actions.d.ts +43 -4
  298. package/dist/features/orders/actions/order-actions.js +60 -3
  299. package/dist/features/orders/actions/refund-actions.js +70 -10
  300. package/dist/features/orders/components/OrderCompletionPanel.d.ts +27 -0
  301. package/dist/features/orders/components/OrderCompletionPanel.js +192 -0
  302. package/dist/features/orders/components/OrdersList.js +2 -2
  303. package/dist/features/orders/components/RefundHistoryTable.js +3 -1
  304. package/dist/features/orders/components/index.d.ts +2 -0
  305. package/dist/features/orders/components/index.js +6 -0
  306. package/dist/features/orders/constants/transitions.d.ts +59 -0
  307. package/dist/features/orders/constants/transitions.js +104 -0
  308. package/dist/features/orders/repository/orders.repository.d.ts +109 -6
  309. package/dist/features/orders/repository/orders.repository.js +464 -21
  310. package/dist/features/orders/schemas/firestore.d.ts +270 -0
  311. package/dist/features/orders/schemas/firestore.js +24 -0
  312. package/dist/features/orders/schemas/index.d.ts +61 -0
  313. package/dist/features/orders/schemas/index.js +22 -0
  314. package/dist/features/orders/types/index.d.ts +79 -0
  315. package/dist/features/parts/components/PartsIndexPageView.js +8 -1
  316. package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +170 -0
  317. package/dist/features/payment-cases/repository/payment-cases.repository.js +342 -0
  318. package/dist/features/payment-cases/schemas/firestore.d.ts +229 -0
  319. package/dist/features/payment-cases/schemas/firestore.js +105 -0
  320. package/dist/features/payment-cases/schemas/resolve-form.d.ts +97 -0
  321. package/dist/features/payment-cases/schemas/resolve-form.js +114 -0
  322. package/dist/features/payments/repository/payout.repository.d.ts +0 -1
  323. package/dist/features/payments/repository/payout.repository.js +0 -1
  324. package/dist/features/points/repository/points.repository.d.ts +122 -0
  325. package/dist/features/points/repository/points.repository.js +304 -1
  326. package/dist/features/points/schemas/adjust-form.d.ts +58 -0
  327. package/dist/features/points/schemas/adjust-form.js +63 -0
  328. package/dist/features/points/schemas/firestore.d.ts +108 -1
  329. package/dist/features/points/schemas/firestore.js +84 -0
  330. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
  331. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  332. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
  333. package/dist/features/price-index/components/PriceIndexToolView.d.ts +23 -4
  334. package/dist/features/price-index/components/PriceIndexToolView.js +71 -6
  335. package/dist/features/price-index/market-stats.d.ts +82 -0
  336. package/dist/features/price-index/market-stats.js +230 -0
  337. package/dist/features/print/components/BoxLabelPrintView.d.ts +25 -0
  338. package/dist/features/print/components/BoxLabelPrintView.js +66 -0
  339. package/dist/features/print/components/LabelProfilePicker.d.ts +13 -0
  340. package/dist/features/print/components/LabelProfilePicker.js +38 -0
  341. package/dist/features/print/components/labels.d.ts +117 -0
  342. package/dist/features/print/components/labels.js +258 -0
  343. package/dist/features/print/components/labels.style.css +46 -0
  344. package/dist/features/print/index.d.ts +6 -0
  345. package/dist/features/print/index.js +16 -0
  346. package/dist/features/products/columns/productTableColumns.js +5 -4
  347. package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
  348. package/dist/features/products/components/MarketplacePrizeDrawCard.js +6 -6
  349. package/dist/features/products/components/PrizeDrawCollage.js +1 -1
  350. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  351. package/dist/features/products/components/PrizeRevealModal.js +2 -2
  352. package/dist/features/products/components/ProductDetailPageView.js +18 -4
  353. package/dist/features/products/components/ProductForm.js +34 -23
  354. package/dist/features/products/components/ProductGrid.js +86 -62
  355. package/dist/features/products/constants/card-badges.d.ts +97 -0
  356. package/dist/features/products/constants/card-badges.js +100 -0
  357. package/dist/features/products/repository/products.repository.js +34 -1
  358. package/dist/features/products/schemas/firestore.d.ts +46 -3
  359. package/dist/features/products/schemas/firestore.js +21 -0
  360. package/dist/features/promotions/components/PromotionsView.js +1 -1
  361. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +32 -0
  362. package/dist/features/promotions/repository/claimed-coupons.repository.js +58 -0
  363. package/dist/features/promotions/schemas/firestore.js +30 -3
  364. package/dist/features/promotions/schemas/index.d.ts +6 -6
  365. package/dist/features/protection-claims/repository/protection-claims.repository.d.ts +54 -0
  366. package/dist/features/protection-claims/repository/protection-claims.repository.js +174 -0
  367. package/dist/features/protection-claims/schemas/firestore.d.ts +168 -0
  368. package/dist/features/protection-claims/schemas/firestore.js +130 -0
  369. package/dist/features/reviews/actions/review-actions.js +3 -2
  370. package/dist/features/reviews/components/ReviewModal.js +1 -1
  371. package/dist/features/reviews/components/ReviewsList.js +1 -1
  372. package/dist/features/reviews/schemas/firestore.d.ts +20 -1
  373. package/dist/features/scams/constants/scam-types.d.ts +2 -0
  374. package/dist/features/scams/constants/scam-types.js +18 -0
  375. package/dist/features/scams/schemas/report-form.d.ts +3 -3
  376. package/dist/features/scams/schemas/report-form.js +26 -1
  377. package/dist/features/search/components/Search.js +9 -9
  378. package/dist/features/search/components/SearchResultsClient.js +18 -3
  379. package/dist/features/search/components/SearchResultsPageView.d.ts +1 -6
  380. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  381. package/dist/features/seller/actions/offer-actions.js +16 -1
  382. package/dist/features/seller/actions/seller-actions.js +14 -3
  383. package/dist/features/seller/components/CategoryInlineSelect.js +75 -11
  384. package/dist/features/seller/components/PrintCenterView.d.ts +5 -0
  385. package/dist/features/seller/components/PrintCenterView.js +41 -30
  386. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  387. package/dist/features/seller/components/SellerPayoutRequestView.js +16 -5
  388. package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
  389. package/dist/features/seller/components/SellerProductShell.d.ts +16 -0
  390. package/dist/features/seller/components/SellerProductShell.js +123 -13
  391. package/dist/features/seller/components/SellerReviewsView.js +4 -2
  392. package/dist/features/seller/components/SellerSidebar.js +1 -1
  393. package/dist/features/seller/schemas/coupon-form.d.ts +26 -0
  394. package/dist/features/seller/schemas/coupon-form.js +27 -0
  395. package/dist/features/seller/schemas/product-form.d.ts +3 -0
  396. package/dist/features/seller/schemas/product-form.js +5 -0
  397. package/dist/features/shell/FormShell.js +2 -2
  398. package/dist/features/shell/QuickFormDrawer.js +14 -0
  399. package/dist/features/shell/SectionForm.d.ts +19 -0
  400. package/dist/features/shell/SectionForm.js +133 -9
  401. package/dist/features/shell/SectionForm.style.css +54 -0
  402. package/dist/features/shipments/components/AdminShipmentsView.js +16 -1
  403. package/dist/features/shipments/repository/shipment-items.repository.d.ts +9 -0
  404. package/dist/features/shipments/repository/shipment-items.repository.js +14 -0
  405. package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
  406. package/dist/features/sticker-trace/components/StickerCommitPanel.js +1 -1
  407. package/dist/features/store-extensions/schemas/report-review-form.d.ts +8 -8
  408. package/dist/features/stores/components/StoreGuideHubView.js +1 -1
  409. package/dist/features/stores/components/StoreHeader.js +1 -1
  410. package/dist/features/support/schemas/firestore.d.ts +73 -2
  411. package/dist/features/support/schemas/firestore.js +59 -0
  412. package/dist/index.d.ts +16 -24
  413. package/dist/index.js +38 -47
  414. package/dist/next/ErrorBoundary.js +1 -1
  415. package/dist/next/routing/route-map.d.ts +24 -0
  416. package/dist/next/routing/route-map.js +40 -0
  417. package/dist/providers/payment-manual/index.d.ts +15 -1
  418. package/dist/providers/payment-manual/index.js +37 -0
  419. package/dist/providers/payment-phonepe/index.d.ts +14 -1
  420. package/dist/providers/payment-phonepe/index.js +36 -0
  421. package/dist/providers/payment-razorpay/index.d.ts +44 -1
  422. package/dist/providers/payment-razorpay/index.js +99 -0
  423. package/dist/providers/shipping-shiprocket/index.d.ts +18 -0
  424. package/dist/providers/shipping-shiprocket/index.js +18 -0
  425. package/dist/schemas/registry.d.ts +44 -11
  426. package/dist/server-entry.d.ts +2 -0
  427. package/dist/server-entry.js +27 -0
  428. package/dist/server.d.ts +42 -0
  429. package/dist/server.js +93 -0
  430. package/dist/styles.css +418 -149
  431. package/dist/tailwind-utilities.css +1 -1
  432. package/dist/tokens/themes/default-dark.js +15 -12
  433. package/dist/tokens/themes/default-light.js +14 -11
  434. package/dist/tokens/tokens.css +106 -23
  435. package/dist/ui/DataTable.style.css +4 -4
  436. package/dist/ui/columns/cell-renderers.d.ts +20 -0
  437. package/dist/ui/columns/cell-renderers.js +26 -1
  438. package/dist/ui/columns/index.d.ts +1 -1
  439. package/dist/ui/columns/index.js +4 -1
  440. package/dist/ui/components/Badge.style.css +1 -1
  441. package/dist/ui/components/Breadcrumb.js +19 -1
  442. package/dist/ui/components/BulkActionBar.style.css +4 -4
  443. package/dist/ui/components/Button.style.css +1 -1
  444. package/dist/ui/components/Checkbox.style.css +1 -1
  445. package/dist/ui/components/FallbackShell.js +1 -1
  446. package/dist/ui/components/Form.d.ts +14 -1
  447. package/dist/ui/components/Form.js +2 -2
  448. package/dist/ui/components/FormField.js +18 -4
  449. package/dist/ui/components/FormField.style.css +43 -3
  450. package/dist/ui/components/GatedPrice.style.css +1 -1
  451. package/dist/ui/components/IconButton.style.css +1 -1
  452. package/dist/ui/components/Input.js +22 -1
  453. package/dist/ui/components/Input.style.css +38 -22
  454. package/dist/ui/components/ListingFilterDrawer.js +1 -1
  455. package/dist/ui/components/ListingToolbar.js +1 -1
  456. package/dist/ui/components/PaginatedSelect.js +0 -0
  457. package/dist/ui/components/Radio.style.css +1 -1
  458. package/dist/ui/components/Repeater.d.ts +53 -0
  459. package/dist/ui/components/Repeater.js +7 -0
  460. package/dist/ui/components/RichTextEditor.d.ts +20 -1
  461. package/dist/ui/components/RichTextEditor.js +23 -2
  462. package/dist/ui/components/Select.style.css +7 -21
  463. package/dist/ui/components/Semantic.js +27 -3
  464. package/dist/ui/components/TagInput.style.css +4 -9
  465. package/dist/ui/components/Textarea.style.css +4 -18
  466. package/dist/ui/components/Toggle.style.css +1 -1
  467. package/dist/ui/components/Typography.d.ts +3 -3
  468. package/dist/ui/components/Typography.js +15 -15
  469. package/dist/ui/components/ViewToggle.style.css +4 -4
  470. package/dist/ui/forms/AddAnotherToggle.d.ts +16 -0
  471. package/dist/ui/forms/AddAnotherToggle.js +56 -0
  472. package/dist/ui/forms/ColorPickerField.js +15 -2
  473. package/dist/ui/forms/FieldCheckbox.js +15 -2
  474. package/dist/ui/forms/FieldInput.d.ts +22 -1
  475. package/dist/ui/forms/FieldInput.js +19 -5
  476. package/dist/ui/forms/FieldLabel.d.ts +35 -0
  477. package/dist/ui/forms/FieldLabel.js +70 -0
  478. package/dist/ui/forms/FieldSelect.d.ts +4 -1
  479. package/dist/ui/forms/FieldSelect.js +27 -5
  480. package/dist/ui/forms/FieldTextarea.d.ts +4 -1
  481. package/dist/ui/forms/FieldTextarea.js +22 -5
  482. package/dist/ui/forms/FormShell.d.ts +17 -1
  483. package/dist/ui/forms/FormShell.js +36 -2
  484. package/dist/ui/forms/FormShell.style.css +41 -33
  485. package/dist/ui/forms/index.d.ts +5 -1
  486. package/dist/ui/forms/index.js +2 -0
  487. package/dist/ui/icons/icon-registry.d.ts +1 -0
  488. package/dist/ui/icons/icon-registry.js +17 -1
  489. package/dist/utils/id-generators.d.ts +80 -0
  490. package/dist/utils/id-generators.js +93 -0
  491. package/dist/utils/search-txt-builders.d.ts +12 -0
  492. package/dist/utils/search-txt-builders.js +17 -0
  493. package/package.json +1 -1
  494. package/scripts/seed-cli.mjs +106 -5
  495. package/dist/features/loyalty/api/admin/loyalty/grant/route.d.ts +0 -12
  496. package/dist/features/loyalty/api/admin/loyalty/grant/route.js +0 -38
  497. package/dist/features/loyalty/api/balance/route.d.ts +0 -12
  498. package/dist/features/loyalty/api/balance/route.js +0 -41
  499. package/dist/features/loyalty/api/earn/route.d.ts +0 -12
  500. package/dist/features/loyalty/api/earn/route.js +0 -38
  501. package/dist/features/loyalty/api/history/route.d.ts +0 -12
  502. package/dist/features/loyalty/api/history/route.js +0 -58
  503. package/dist/features/loyalty/api/redeem/route.d.ts +0 -12
  504. package/dist/features/loyalty/api/redeem/route.js +0 -38
  505. package/dist/features/loyalty/columns/index.d.ts +0 -17
  506. package/dist/features/loyalty/columns/index.js +0 -40
  507. package/dist/features/loyalty/components/CoinsDisplay.d.ts +0 -12
  508. package/dist/features/loyalty/components/CoinsDisplay.js +0 -10
  509. package/dist/features/loyalty/components/index.d.ts +0 -1
  510. package/dist/features/loyalty/components/index.js +0 -1
  511. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +0 -4
  512. package/dist/features/loyalty/hooks/useLoyaltyBalance.js +0 -25
  513. package/dist/features/loyalty/index.d.ts +0 -6
  514. package/dist/features/loyalty/index.js +0 -6
  515. package/dist/features/loyalty/manifest.d.ts +0 -2
  516. package/dist/features/loyalty/manifest.js +0 -16
  517. package/dist/features/loyalty/messages/en.json +0 -19
  518. package/dist/features/loyalty/repository/loyalty.repository.d.ts +0 -8
  519. package/dist/features/loyalty/repository/loyalty.repository.js +0 -22
  520. package/dist/features/loyalty/schemas/index.d.ts +0 -85
  521. package/dist/features/loyalty/schemas/index.js +0 -40
  522. package/dist/features/loyalty/server.d.ts +0 -6
  523. package/dist/features/loyalty/server.js +0 -6
  524. package/dist/features/loyalty/types/index.d.ts +0 -31
  525. package/dist/features/loyalty/types/index.js +0 -1
  526. package/dist/features/loyalty/types/loyalty-config.d.ts +0 -7
  527. package/dist/features/loyalty/types/loyalty-config.js +0 -1
  528. package/dist/features/loyalty/types/loyalty-math.d.ts +0 -9
  529. package/dist/features/loyalty/types/loyalty-math.js +0 -27
  530. package/dist/features/products/components/ProductOwnerQuickActions.d.ts +0 -11
  531. package/dist/features/products/components/ProductOwnerQuickActions.js +0 -120
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * "Create & add another" — the toggle, and the submit label that follows it.
5
+ *
6
+ * Entering a batch of similar records is the one thing every create form in
7
+ * this app is bad at: save, land on a detail page, navigate back, re-pick the
8
+ * store, re-pick the category, re-pick the listing type. Four of those five
9
+ * steps are the same every time.
10
+ *
11
+ * 🛑 THE TOGGLE RENDERS NOTHING UNLESS THE FORM OPTED IN, and that is the
12
+ * point rather than a nicety. `FormShell` does not own the draft, so it cannot
13
+ * know what a fresh one looks like or which fields are sticky — only the
14
+ * caller's submit handler can keep this promise. A checkbox on all ~59 editors
15
+ * when one honours it is a control that does nothing on 58 of them, which is
16
+ * the defect shape this codebase keeps paying for: a declaration with no
17
+ * reader.
18
+ *
19
+ * So: `useFormShellState(schema, nav, { allowAddAnother: true })` offers it,
20
+ * the handler reads `addAnother`, and `audit-add-another-honoured` checks that
21
+ * whoever offers it also reads it.
22
+ */
23
+ import { useContext } from "react";
24
+ import { FormShellContext } from "./FormShell.js";
25
+ import { FieldCheckbox } from "./FieldCheckbox.js";
26
+ export function AddAnotherToggle({ noun, isCreate = true, }) {
27
+ const ctx = useContext(FormShellContext);
28
+ /*
29
+ * 🛑 `useContext` DIRECTLY, not `useFormShell()`, which throws without a
30
+ * provider. A toggle that crashes the form it is decorating is worse than
31
+ * one that renders nothing, and this is library code adjusting to its
32
+ * surroundings (Root Cause #20 — no provider must fail CLOSED, not loudly).
33
+ */
34
+ if (!ctx?.addAnotherEnabled)
35
+ return null;
36
+ /*
37
+ * 🛑 Hidden on EDIT. "Add another" after changing an existing record would
38
+ * have to mean "save this, then start a new one", which is a different and
39
+ * surprising action — and the sticky-field reasoning does not apply, because
40
+ * nobody edits a batch of records by starting from the last one they fixed.
41
+ */
42
+ if (!isCreate)
43
+ return null;
44
+ return (_jsx(FieldCheckbox, { name: "addAnother", label: noun ? `Create & add another ${noun}` : "Create & add another", hint: "Stay on this form after saving, keeping the store, category and type.", checked: ctx.addAnother, onChange: (next) => ctx.setAddAnother(next) }));
45
+ }
46
+ /**
47
+ * The submit button's label, given the toggle.
48
+ *
49
+ * 🛑 A SEPARATE HELPER BECAUSE THE LABEL MUST CHANGE. A button that says
50
+ * "Create listing" and then does not navigate has lied about what it did, and
51
+ * the user's next move is to press it again — which creates a duplicate. The
52
+ * label is the only thing telling them the destination changed.
53
+ */
54
+ export function addAnotherSubmitLabel(base, addAnother) {
55
+ return addAnother ? `${base} & add another` : base;
56
+ }
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useContext } from "react";
3
+ import { useContext, useId } from "react";
4
4
  import { FormShellContext } from "./FormShell.js";
5
5
  import { Label, Text, Span } from "../components/Typography.js";
6
6
  const SWATCH_WIDTH_MAP = {
@@ -23,7 +23,20 @@ export function ColorPickerField({ name, label, hint, required, swatchWidth = "f
23
23
  const error = errorProp ?? contextError;
24
24
  const touched = ctx?.touched[name];
25
25
  const showError = !!error && (touched != null ? touched : true);
26
- const inputId = `field-${name}`;
26
+ const reactId = useId();
27
+ /*
28
+ * 🛑 UNIQUE PER INSTANCE. This was `field-${name}`, so two fields sharing a
29
+ * name on one page produced two elements with the SAME id — `/auth/login`
30
+ * shipped two `id="field-email"` (the sign-in form and the footer
31
+ * newsletter).
32
+ *
33
+ * That is not cosmetic. `htmlFor` resolves to the FIRST element with the
34
+ * id, so the second field's label points at the first field's input: the
35
+ * label is present in the markup and the input has no accessible name, which
36
+ * is what an accessibility pass reports as an unlabelled field. Clicking the
37
+ * second label also focuses the first input.
38
+ */
39
+ const inputId = `field-${name}-${reactId}`;
27
40
  const errorId = `${inputId}-error`;
28
41
  function handleBlur(e) {
29
42
  ctx?.setFieldTouched(name);
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useContext } from "react";
3
+ import { useContext, useId } from "react";
4
4
  import { FormShellContext } from "./FormShell.js";
5
5
  import { Checkbox } from "../components/Checkbox.js";
6
6
  import { Text } from "../components/Typography.js";
@@ -10,7 +10,20 @@ export function FieldCheckbox({ name, label, hint, checked, onChange, onBlur, di
10
10
  const error = errorProp ?? contextError;
11
11
  const touched = ctx?.touched[name];
12
12
  const showError = !!error && (touched != null ? touched : true);
13
- const inputId = `field-${name}`;
13
+ const reactId = useId();
14
+ /*
15
+ * 🛑 UNIQUE PER INSTANCE. This was `field-${name}`, so two fields sharing a
16
+ * name on one page produced two elements with the SAME id — `/auth/login`
17
+ * shipped two `id="field-email"` (the sign-in form and the footer
18
+ * newsletter).
19
+ *
20
+ * That is not cosmetic. `htmlFor` resolves to the FIRST element with the
21
+ * id, so the second field's label points at the first field's input: the
22
+ * label is present in the markup and the input has no accessible name, which
23
+ * is what an accessibility pass reports as an unlabelled field. Clicking the
24
+ * second label also focuses the first input.
25
+ */
26
+ const inputId = `field-${name}-${reactId}`;
14
27
  const errorId = `${inputId}-error`;
15
28
  function handleChange(e) {
16
29
  onChange?.(e.target.checked);
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { type LabelPlacement } from "./FieldLabel";
2
3
  export interface FieldInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange"> {
3
4
  name: string;
4
5
  label?: string;
@@ -7,5 +8,25 @@ export interface FieldInputProps extends Omit<React.InputHTMLAttributes<HTMLInpu
7
8
  onChange?: (value: string) => void;
8
9
  /** Override error — falls back to FormShell context error for this field */
9
10
  error?: string;
11
+ /**
12
+ * A ref to the inner `<input>`, for the cases that need programmatic focus:
13
+ * a scan station that must re-focus after every scan, an error summary that
14
+ * jumps to the offending field, a drawer that focuses its first control.
15
+ *
16
+ * 🛑 NAMED `inputRef`, not a `forwardRef` on the component. This renders a
17
+ * wrapper `<div>`, a `<Label>`, the `<input>` and an error `<Text>` — so a
18
+ * bare "the ref" has no single obvious target, and the next reader could
19
+ * reasonably expect the wrapper. Being explicit about which element is the
20
+ * same lesson as `Select`'s `wrapperClassName` (Root Cause #29): when a
21
+ * primitive has an outer box and an inner control, a prop that does not say
22
+ * which one it means will eventually reach the wrong one.
23
+ */
24
+ inputRef?: React.Ref<HTMLInputElement>;
25
+ /**
26
+ * Override the section's label placement. Omit it — placement is a
27
+ * section-level decision (see `FieldLabel`), and a field that disagrees with
28
+ * its neighbours reads as broken rather than varied.
29
+ */
30
+ labelPlacement?: LabelPlacement;
10
31
  }
11
- export declare function FieldInput({ name, label, hint, required, onChange, error: errorProp, onBlur, className, ...inputProps }: FieldInputProps): React.JSX.Element;
32
+ export declare function FieldInput({ name, label, hint, required, onChange, error: errorProp, onBlur, className, inputRef, labelPlacement, ...inputProps }: FieldInputProps): React.JSX.Element;
@@ -1,16 +1,30 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useContext } from "react";
3
+ import { useContext, useId } from "react";
4
4
  import { FormShellContext } from "./FormShell.js";
5
5
  import { Input } from "../components/Input.js";
6
- import { Label, Text, Span } from "../components/Typography.js";
7
- export function FieldInput({ name, label, hint, required, onChange, error: errorProp, onBlur, className, ...inputProps }) {
6
+ import { Text } from "../components/Typography.js";
7
+ import { FieldLabel } from "./FieldLabel.js";
8
+ export function FieldInput({ name, label, hint, required, onChange, error: errorProp, onBlur, className, inputRef, labelPlacement, ...inputProps }) {
8
9
  const ctx = useContext(FormShellContext);
9
10
  const contextError = ctx?.errors[name];
10
11
  const error = errorProp ?? contextError;
11
12
  const touched = ctx?.touched[name];
12
13
  const showError = !!error && (touched != null ? touched : true);
13
- const inputId = `field-${name}`;
14
+ const reactId = useId();
15
+ /*
16
+ * 🛑 UNIQUE PER INSTANCE. This was `field-${name}`, so two fields sharing a
17
+ * name on one page produced two elements with the SAME id — `/auth/login`
18
+ * shipped two `id="field-email"` (the sign-in form and the footer
19
+ * newsletter).
20
+ *
21
+ * That is not cosmetic. `htmlFor` resolves to the FIRST element with the
22
+ * id, so the second field's label points at the first field's input: the
23
+ * label is present in the markup and the input has no accessible name, which
24
+ * is what an accessibility pass reports as an unlabelled field. Clicking the
25
+ * second label also focuses the first input.
26
+ */
27
+ const inputId = `field-${name}-${reactId}`;
14
28
  const errorId = `${inputId}-error`;
15
29
  function handleBlur(e) {
16
30
  ctx?.setFieldTouched(name);
@@ -21,5 +35,5 @@ export function FieldInput({ name, label, hint, required, onChange, error: error
21
35
  if (showError)
22
36
  ctx?.clearFieldError(name);
23
37
  }
24
- return (_jsxs("div", { className: ["appkit-form-field", className].filter(Boolean).join(" "), children: [label && (_jsxs(Label, { htmlFor: inputId, className: "appkit-form-field__label", children: [label, required && _jsx(Span, { className: "appkit-form-field__required", children: " *" })] })), _jsx(Input, { id: inputId, name: name, "aria-required": required || undefined, "aria-invalid": showError || undefined, "aria-describedby": showError ? errorId : undefined, onBlur: handleBlur, onChange: handleChange, ...inputProps }), !showError && hint && (_jsx(Text, { size: "sm", variant: "secondary", className: "appkit-form-field__hint", children: hint })), showError && (_jsx(Text, { id: errorId, size: "sm", variant: "error", className: "appkit-form-field__error", role: "alert", children: error }))] }));
38
+ return (_jsxs("div", { className: ["appkit-form-field", className].filter(Boolean).join(" "), children: [label && (_jsx(FieldLabel, { htmlFor: inputId, required: required, placement: labelPlacement, children: label })), _jsx(Input, { ref: inputRef, id: inputId, name: name, "aria-required": required || undefined, "aria-invalid": showError || undefined, "aria-describedby": showError ? errorId : undefined, onBlur: handleBlur, onChange: handleChange, ...inputProps }), !showError && hint && (_jsx(Text, { size: "sm", variant: "secondary", className: "appkit-form-field__hint", children: hint })), showError && (_jsx(Text, { id: errorId, size: "sm", variant: "error", className: "appkit-form-field__error", role: "alert", children: error }))] }));
25
39
  }
@@ -0,0 +1,35 @@
1
+ export type LabelPlacement = "above" | "inline" | "hidden";
2
+ /**
3
+ * Set by a section, read by every field inside it.
4
+ *
5
+ * Defaults to `"above"` — the current behaviour of all four owners — so
6
+ * introducing this changes no existing markup. The concept is new; the output
7
+ * is not.
8
+ */
9
+ export declare const LabelPlacementContext: import("react").Context<LabelPlacement>;
10
+ export declare function useLabelPlacement(override?: LabelPlacement): LabelPlacement;
11
+ export interface FieldLabelProps {
12
+ /**
13
+ * The `id` of the control this labels. The normal case.
14
+ *
15
+ * 🛑 OPTIONAL ONLY FOR THE `aria-labelledby` DIRECTION, and omitting it on a
16
+ * real input is how an unlabelled field is made. `htmlFor` associates with a
17
+ * LABELABLE element — `input`, `select`, `textarea`, `button`, `output`,
18
+ * `meter`, `progress` — and nothing else. A `contenteditable` div (the rich
19
+ * text editor) is not one, so there `htmlFor` points at nothing: the label
20
+ * looks correct to a human and the control has no accessible name.
21
+ *
22
+ * For those, give the LABEL an `id` and have the control carry
23
+ * `aria-labelledby` pointing back at it. Exactly one of `htmlFor` or `id`
24
+ * should be set.
25
+ */
26
+ htmlFor?: string;
27
+ /** This label's own id, for a control that points back via `aria-labelledby`. */
28
+ id?: string;
29
+ children: React.ReactNode;
30
+ required?: boolean;
31
+ /** Overrides the section's placement. Use only when this field differs. */
32
+ placement?: LabelPlacement;
33
+ className?: string;
34
+ }
35
+ export declare function FieldLabel({ htmlFor, id, children, required, placement, className, }: FieldLabelProps): import("react").JSX.Element;
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * The one owner of a form field's label.
5
+ *
6
+ * ── THE FOUR OWNERS THIS REPLACES ───────────────────────────────────────────
7
+ *
8
+ * `FieldInput`, `FieldSelect` and `FieldTextarea` each carried a BYTE-IDENTICAL
9
+ * copy of the same five lines, and `FormField` carried a fourth that had
10
+ * already drifted: its required marker is `>*<` where the other three are
11
+ * `> *<`, so the asterisk sits flush against the label text on ~40 screens and
12
+ * spaced on the rest. Nobody chose that. It is what four copies of five lines
13
+ * always become, and it is the smallest possible demonstration of why this
14
+ * file exists.
15
+ *
16
+ * A fifth family — `Input`, `Select`, `Textarea`, `Toggle`, `Radio`, `Slider`,
17
+ * `TagInput`, `DateInput`, `OtpInput` — each accept their own `label` prop and
18
+ * render it differently again. Those are NOT migrated here and should not be:
19
+ * see the note at the bottom on why a primitive keeps its own label.
20
+ *
21
+ * ── LABEL PLACEMENT ─────────────────────────────────────────────────────────
22
+ *
23
+ * 🛑 PLACEMENT IS A SECTION-LEVEL DECISION, NOT A PER-FIELD ONE. A form where
24
+ * one field labels above and its neighbour labels inline reads as broken
25
+ * rather than as varied, and the choice is about the density of a whole
26
+ * section — a 12-field address block wants inline, a 3-field settings panel
27
+ * wants above. So it comes from context, set once by `SectionDef`, and a field
28
+ * only overrides it when it genuinely differs from its neighbours.
29
+ *
30
+ * `"hidden"` is NOT "no label". It renders the label to assistive technology
31
+ * and hides it visually, which is the correct treatment for a field whose
32
+ * purpose is obvious from context (a search box with a magnifier, a quantity
33
+ * stepper in a table row). Passing no `label` at all is what produces an
34
+ * unlabelled field, and there are 392 of those — `"hidden"` is the fix for the
35
+ * subset that genuinely should not show one, not a way to silence the count.
36
+ */
37
+ import { createContext, useContext } from "react";
38
+ import { Label, Span } from "../components/Typography.js";
39
+ /**
40
+ * Set by a section, read by every field inside it.
41
+ *
42
+ * Defaults to `"above"` — the current behaviour of all four owners — so
43
+ * introducing this changes no existing markup. The concept is new; the output
44
+ * is not.
45
+ */
46
+ export const LabelPlacementContext = createContext("above");
47
+ export function useLabelPlacement(override) {
48
+ const fromSection = useContext(LabelPlacementContext);
49
+ return override ?? fromSection;
50
+ }
51
+ /**
52
+ * 🛑 `sr-only`, not `display: none`, for the hidden placement.
53
+ *
54
+ * A `display: none` label is removed from the accessibility tree, so hiding a
55
+ * label that way produces exactly the unlabelled field it was meant to avoid —
56
+ * the screen reader announces "edit text" and the visual user sees a box with
57
+ * a placeholder. `sr-only` keeps it announced and off-screen, which is the
58
+ * whole distinction between "visually hidden" and "absent".
59
+ */
60
+ const PLACEMENT_CLASS = {
61
+ above: "appkit-form-field__label",
62
+ inline: "appkit-form-field__label appkit-form-field__label--inline",
63
+ hidden: "sr-only",
64
+ };
65
+ export function FieldLabel({ htmlFor, id, children, required, placement, className = "", }) {
66
+ const resolved = useLabelPlacement(placement);
67
+ return (_jsxs(Label, { htmlFor: htmlFor, id: id, className: [PLACEMENT_CLASS[resolved], className]
68
+ .filter(Boolean)
69
+ .join(" "), children: [children, required && _jsx(Span, { className: "appkit-form-field__required", children: " *" })] }));
70
+ }
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { type SelectOption } from "../components/Select";
3
+ import { type LabelPlacement } from "./FieldLabel";
3
4
  export interface FieldSelectProps {
4
5
  name: string;
5
6
  label?: string;
@@ -14,5 +15,7 @@ export interface FieldSelectProps {
14
15
  /** Override error — falls back to FormShell context error for this field */
15
16
  error?: string;
16
17
  className?: string;
18
+ /** Override the section's label placement. Omit it — see `FieldLabel`. */
19
+ labelPlacement?: LabelPlacement;
17
20
  }
18
- export declare function FieldSelect({ name, label, hint, required, value, onChange, onBlur, options, disabled, placeholder, error: errorProp, className, }: FieldSelectProps): React.JSX.Element;
21
+ export declare function FieldSelect({ name, label, hint, required, value, onChange, onBlur, options, disabled, placeholder, error: errorProp, className, labelPlacement, }: FieldSelectProps): React.JSX.Element;
@@ -1,16 +1,38 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useContext } from "react";
3
+ import { useContext, useId } from "react";
4
4
  import { FormShellContext } from "./FormShell.js";
5
5
  import { Select } from "../components/Select.js";
6
- import { Label, Text, Span } from "../components/Typography.js";
7
- export function FieldSelect({ name, label, hint, required, value, onChange, onBlur, options, disabled, placeholder, error: errorProp, className, }) {
6
+ import { Text } from "../components/Typography.js";
7
+ import { FieldLabel } from "./FieldLabel.js";
8
+ export function FieldSelect({ name, label, hint, required, value, onChange, onBlur, options, disabled, placeholder, error: errorProp, className,
9
+ /*
10
+ * 🛑 Declared on `FieldSelectProps` and never destructured, so line 77 read
11
+ * a free variable that does not exist — `TS2304: Cannot find name
12
+ * 'labelPlacement'`. A prop that is typed but not unpacked is the exact
13
+ * shape of the `schema: _schema` defect `audit-dead-underscore-prop` exists
14
+ * for, except here it did not even compile.
15
+ */
16
+ labelPlacement, }) {
8
17
  const ctx = useContext(FormShellContext);
9
18
  const contextError = ctx?.errors[name];
10
19
  const error = errorProp ?? contextError;
11
20
  const touched = ctx?.touched[name];
12
21
  const showError = !!error && (touched != null ? touched : true);
13
- const inputId = `field-${name}`;
22
+ const reactId = useId();
23
+ /*
24
+ * 🛑 UNIQUE PER INSTANCE. This was `field-${name}`, so two fields sharing a
25
+ * name on one page produced two elements with the SAME id — `/auth/login`
26
+ * shipped two `id="field-email"` (the sign-in form and the footer
27
+ * newsletter).
28
+ *
29
+ * That is not cosmetic. `htmlFor` resolves to the FIRST element with the
30
+ * id, so the second field's label points at the first field's input: the
31
+ * label is present in the markup and the input has no accessible name, which
32
+ * is what an accessibility pass reports as an unlabelled field. Clicking the
33
+ * second label also focuses the first input.
34
+ */
35
+ const inputId = `field-${name}-${reactId}`;
14
36
  const errorId = `${inputId}-error`;
15
37
  function handleBlur() {
16
38
  ctx?.setFieldTouched(name);
@@ -21,5 +43,5 @@ export function FieldSelect({ name, label, hint, required, value, onChange, onBl
21
43
  if (showError)
22
44
  ctx?.clearFieldError(name);
23
45
  }
24
- return (_jsxs("div", { className: ["appkit-form-field", className].filter(Boolean).join(" "), children: [label && (_jsxs(Label, { htmlFor: inputId, className: "appkit-form-field__label", children: [label, required && _jsx(Span, { className: "appkit-form-field__required", children: " *" })] })), _jsx(Select, { id: inputId, name: name, value: value, onChange: handleChange, onBlur: handleBlur, options: options, disabled: disabled, placeholder: placeholder, "aria-required": required || undefined, "aria-invalid": showError || undefined, "aria-describedby": showError ? errorId : undefined }), !showError && hint && (_jsx(Text, { size: "sm", variant: "secondary", className: "appkit-form-field__hint", children: hint })), showError && (_jsx(Text, { id: errorId, size: "sm", variant: "error", className: "appkit-form-field__error", role: "alert", children: error }))] }));
46
+ return (_jsxs("div", { className: ["appkit-form-field", className].filter(Boolean).join(" "), children: [label && (_jsx(FieldLabel, { htmlFor: inputId, required: required, placement: labelPlacement, children: label })), _jsx(Select, { id: inputId, name: name, value: value, onChange: handleChange, onBlur: handleBlur, options: options, disabled: disabled, placeholder: placeholder, "aria-required": required || undefined, "aria-invalid": showError || undefined, "aria-describedby": showError ? errorId : undefined }), !showError && hint && (_jsx(Text, { size: "sm", variant: "secondary", className: "appkit-form-field__hint", children: hint })), showError && (_jsx(Text, { id: errorId, size: "sm", variant: "error", className: "appkit-form-field__error", role: "alert", children: error }))] }));
25
47
  }
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { type LabelPlacement } from "./FieldLabel";
2
3
  export interface FieldTextareaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange"> {
3
4
  name: string;
4
5
  label?: string;
@@ -9,5 +10,7 @@ export interface FieldTextareaProps extends Omit<React.TextareaHTMLAttributes<HT
9
10
  error?: string;
10
11
  /** Show a `{n}/{maxLength}` counter when maxLength is set */
11
12
  showCharCount?: boolean;
13
+ /** Override the section's label placement. Omit it — see `FieldLabel`. */
14
+ labelPlacement?: LabelPlacement;
12
15
  }
13
- export declare function FieldTextarea({ name, label, hint, required, onChange, error: errorProp, onBlur, className, showCharCount, ...textareaProps }: FieldTextareaProps): React.JSX.Element;
16
+ export declare function FieldTextarea({ name, label, hint, required, onChange, error: errorProp, onBlur, className, showCharCount, labelPlacement, ...textareaProps }: FieldTextareaProps): React.JSX.Element;
@@ -1,16 +1,30 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useContext } from "react";
3
+ import { useContext, useId } from "react";
4
4
  import { FormShellContext } from "./FormShell.js";
5
5
  import { Textarea } from "../components/Textarea.js";
6
- import { Label, Text, Span } from "../components/Typography.js";
7
- export function FieldTextarea({ name, label, hint, required, onChange, error: errorProp, onBlur, className, showCharCount, ...textareaProps }) {
6
+ import { Text } from "../components/Typography.js";
7
+ import { FieldLabel } from "./FieldLabel.js";
8
+ export function FieldTextarea({ name, label, hint, required, onChange, error: errorProp, onBlur, className, showCharCount, labelPlacement, ...textareaProps }) {
8
9
  const ctx = useContext(FormShellContext);
9
10
  const contextError = ctx?.errors[name];
10
11
  const error = errorProp ?? contextError;
11
12
  const touched = ctx?.touched[name];
12
13
  const showError = !!error && (touched != null ? touched : true);
13
- const fieldId = `field-${name}`;
14
+ const reactId = useId();
15
+ /*
16
+ * 🛑 UNIQUE PER INSTANCE. This was `field-${name}`, so two fields sharing a
17
+ * name on one page produced two elements with the SAME id — `/auth/login`
18
+ * shipped two `id="field-email"` (the sign-in form and the footer
19
+ * newsletter).
20
+ *
21
+ * That is not cosmetic. `htmlFor` resolves to the FIRST element with the
22
+ * id, so the second field's label points at the first field's input: the
23
+ * label is present in the markup and the input has no accessible name, which
24
+ * is what an accessibility pass reports as an unlabelled field. Clicking the
25
+ * second label also focuses the first input.
26
+ */
27
+ const fieldId = `field-${name}-${reactId}`;
14
28
  const errorId = `${fieldId}-error`;
15
29
  function handleBlur(e) {
16
30
  ctx?.setFieldTouched(name);
@@ -21,5 +35,8 @@ export function FieldTextarea({ name, label, hint, required, onChange, error: er
21
35
  if (showError)
22
36
  ctx?.clearFieldError(name);
23
37
  }
24
- return (_jsxs("div", { className: ["appkit-form-field", className].filter(Boolean).join(" "), children: [label && (_jsxs(Label, { htmlFor: fieldId, className: "appkit-form-field__label", children: [label, required && _jsx(Span, { className: "appkit-form-field__required", children: " *" })] })), _jsx(Textarea, { id: fieldId, name: name, "aria-required": required || undefined, "aria-invalid": showError || undefined, "aria-describedby": showError ? errorId : undefined, onBlur: handleBlur, onChange: handleChange, showCharCount: showCharCount, ...textareaProps }), !showError && hint && (_jsx(Text, { size: "sm", variant: "secondary", className: "appkit-form-field__hint", children: hint })), showError && (_jsx(Text, { id: errorId, size: "sm", variant: "error", className: "appkit-form-field__error", role: "alert", children: error }))] }));
38
+ return (_jsxs("div", { className: ["appkit-form-field", className].filter(Boolean).join(" "), children: [label && (
39
+ /* One label implementation — see FieldLabel's header on the four
40
+ byte-identical copies this replaced. */
41
+ _jsx(FieldLabel, { htmlFor: fieldId, required: required, placement: labelPlacement, children: label })), _jsx(Textarea, { id: fieldId, name: name, "aria-required": required || undefined, "aria-invalid": showError || undefined, "aria-describedby": showError ? errorId : undefined, onBlur: handleBlur, onChange: handleChange, showCharCount: showCharCount, ...textareaProps }), !showError && hint && (_jsx(Text, { size: "sm", variant: "secondary", className: "appkit-form-field__hint", children: hint })), showError && (_jsx(Text, { id: errorId, size: "sm", variant: "error", className: "appkit-form-field__error", role: "alert", children: error }))] }));
25
42
  }
@@ -69,9 +69,25 @@ export interface FormShellContextValue {
69
69
  submitAttemptCount: number;
70
70
  /** Call from a submit handler, before validating. */
71
71
  markSubmitAttempted: () => void;
72
+ addAnotherEnabled: boolean;
73
+ /** Ticked? Meaningless unless `addAnotherEnabled`. */
74
+ addAnother: boolean;
75
+ setAddAnother: (next: boolean) => void;
72
76
  }
73
77
  export declare const FormShellContext: React.Context<FormShellContextValue | null>;
74
78
  export declare function useFormShell(): FormShellContextValue;
79
+ export interface FormShellStateOptions {
80
+ /**
81
+ * Offer "Create & add another".
82
+ *
83
+ * 🛑 OPT-IN, and the caller is taking on an obligation by passing it: its
84
+ * submit handler MUST read `addAnother` and, when true, keep the user on the
85
+ * form with a fresh draft instead of navigating away. Passing this without
86
+ * honouring it ships a checkbox that does nothing — the defect shape this
87
+ * codebase has paid for most often. `audit-add-another-honoured` blocks it.
88
+ */
89
+ allowAddAnother?: boolean;
90
+ }
75
91
  export interface UseFormShellStateResult {
76
92
  shellCtx: FormShellContextValue;
77
93
  setFieldError: (name: string, error: string | null) => void;
@@ -105,7 +121,7 @@ export interface UseFormShellStateResult {
105
121
  * for single-segment forms; the summary renders a flat list, which is right
106
122
  * for them.
107
123
  */
108
- export declare function useFormShellState<TSchema extends import("zod").ZodTypeAny = import("zod").ZodTypeAny>(schema?: TSchema, nav?: FormShellNav): UseFormShellStateResult;
124
+ export declare function useFormShellState<TSchema extends import("zod").ZodTypeAny = import("zod").ZodTypeAny>(schema?: TSchema, nav?: FormShellNav, opts?: FormShellStateOptions): UseFormShellStateResult;
109
125
  export interface FormShellProviderProps {
110
126
  children: ReactNode;
111
127
  /** Called on debounced auto-save when isDirty changes */
@@ -24,9 +24,18 @@ export function useFormShell() {
24
24
  * for single-segment forms; the summary renders a flat list, which is right
25
25
  * for them.
26
26
  */
27
- export function useFormShellState(schema, nav) {
27
+ export function useFormShellState(schema, nav, opts) {
28
28
  const [errors, setErrors] = useState({});
29
29
  const [submitAttemptCount, setSubmitAttemptCount] = useState(0);
30
+ /*
31
+ * 🛑 DEFAULTS TO UNTICKED, even when offered. "Create & add another" changes
32
+ * what happens after a successful save, and a user who did not ask for a
33
+ * batch and is silently kept on the form reads it as "the save failed" —
34
+ * then saves again, and creates a duplicate. Defaulting a destination change
35
+ * is not a convenience.
36
+ */
37
+ const [addAnother, setAddAnother] = useState(false);
38
+ const addAnotherEnabled = opts?.allowAddAnother ?? false;
30
39
  const markSubmitAttempted = useCallback(() => setSubmitAttemptCount((n) => n + 1), []);
31
40
  const submitAttempted = submitAttemptCount > 0;
32
41
  const setFieldError = useCallback((name, error) => {
@@ -90,7 +99,14 @@ export function useFormShellState(schema, nav) {
90
99
  submitAttempted,
91
100
  submitAttemptCount,
92
101
  markSubmitAttempted,
93
- }), [errors, setFieldError, navSections, navGoTo, navFieldMap, submitAttempted, submitAttemptCount, markSubmitAttempted]);
102
+ addAnotherEnabled,
103
+ // 🛑 Forced to `false` when the feature is not offered, rather than passed
104
+ // through. Otherwise a caller that never opted in but reads `addAnother`
105
+ // (a copy-paste from one that did) could branch on a value no control can
106
+ // change — a dead branch that looks live.
107
+ addAnother: addAnotherEnabled && addAnother,
108
+ setAddAnother,
109
+ }), [errors, setFieldError, navSections, navGoTo, navFieldMap, submitAttempted, submitAttemptCount, markSubmitAttempted, addAnotherEnabled, addAnother]);
94
110
  return {
95
111
  shellCtx,
96
112
  setFieldError,
@@ -185,6 +201,24 @@ export function FormShellProvider({ children, onSaveDraft, isDirty = false, auto
185
201
  submitAttempted,
186
202
  submitAttemptCount,
187
203
  markSubmitAttempted,
204
+ /*
205
+ * 🛑 `FormShellProvider` DOES NOT OFFER "Create & add another", and this
206
+ * is a decision rather than an omission.
207
+ *
208
+ * This provider backs the multi-step WIZARD (`features/shell/FormShell` +
209
+ * `StepForm`) — auto-save, draft, publish. "Add another" means "stay here
210
+ * with a fresh draft", and in a wizard that would also have to mean "and
211
+ * go back to step one", silently discarding a publish flow the user had
212
+ * walked through. It also auto-saves drafts, so a half-cleared wizard
213
+ * would persist. If a batch-create wizard is ever wanted, it needs its own
214
+ * design; a checkbox here would be the control-that-lies shape.
215
+ *
216
+ * `addAnother` is hard `false`, so `<AddAnotherToggle>` inside a wizard
217
+ * renders nothing and any handler reading it takes the normal branch.
218
+ */
219
+ addAnotherEnabled: false,
220
+ addAnother: false,
221
+ setAddAnother: () => { },
188
222
  }), [errors, touched, setFieldError, setFieldTouched, clearFieldError, isDirty, onGoToStep, fieldToStepIndex, sections, submitAttempted, submitAttemptCount, markSubmitAttempted]);
189
223
  return _jsx(FormShellContext.Provider, { value: ctx, children: children });
190
224
  }