themelia-react-ui 2.0.3 → 2.0.4

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 (421) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +65 -28
  3. package/dist/{accordion-Cjb6sx0G.js → accordion-96o0pN62.js} +5 -5
  4. package/dist/{accordion-Cjb6sx0G.js.map → accordion-96o0pN62.js.map} +1 -1
  5. package/dist/action-menu-CHgs8vmj.js +281 -0
  6. package/dist/action-menu-CHgs8vmj.js.map +1 -0
  7. package/dist/{affordance-geometry.generated-tF36bREk.js → affordance-geometry.generated-B8yGOr8-.js} +7 -1
  8. package/dist/affordance-geometry.generated-B8yGOr8-.js.map +1 -0
  9. package/dist/{ai-artifact-DvTwDVyL.js → ai-artifact-BZUGwBq6.js} +277 -276
  10. package/dist/ai-artifact-BZUGwBq6.js.map +1 -0
  11. package/dist/{app-shell-C4FhvCqF.js → app-shell-D63ATkIK.js} +84 -83
  12. package/dist/app-shell-D63ATkIK.js.map +1 -0
  13. package/dist/{attachment-BxDfL2mw.js → attachment-DkoqHPPl.js} +7 -7
  14. package/dist/{attachment-BxDfL2mw.js.map → attachment-DkoqHPPl.js.map} +1 -1
  15. package/dist/{auth-BGua8ouh.js → auth-D2FVZ1MH.js} +10 -10
  16. package/dist/{auth-BGua8ouh.js.map → auth-D2FVZ1MH.js.map} +1 -1
  17. package/dist/{avatar-DAPlDvhJ.js → avatar-DWO_HHhB.js} +5 -5
  18. package/dist/{avatar-DAPlDvhJ.js.map → avatar-DWO_HHhB.js.map} +1 -1
  19. package/dist/{badge-HpFqoqSY.js → badge-DErMA7ul.js} +4 -4
  20. package/dist/{badge-HpFqoqSY.js.map → badge-DErMA7ul.js.map} +1 -1
  21. package/dist/base/accordion.js +1 -1
  22. package/dist/base/action-menu.js +1 -1
  23. package/dist/base/attachment.js +1 -1
  24. package/dist/base/avatar.js +1 -1
  25. package/dist/base/badge.js +1 -1
  26. package/dist/base/batch-action-bar.js +1 -1
  27. package/dist/base/buttons.js +1 -1
  28. package/dist/base/cards.js +2 -2
  29. package/dist/base/carousel.js +3 -3
  30. package/dist/base/cascader.js +13 -13
  31. package/dist/base/chart.js +1 -1
  32. package/dist/base/choice-inputs.js +2 -2
  33. package/dist/base/code-block.js +1 -1
  34. package/dist/base/combobox.js +1 -1
  35. package/dist/base/command.js +1 -1
  36. package/dist/base/copyable.js +1 -1
  37. package/dist/base/date-pickers.js +2 -2
  38. package/dist/base/display.js +6 -6
  39. package/dist/base/feedback.js +3 -3
  40. package/dist/base/forms-numeric.js +1 -1
  41. package/dist/base/forms.js +3 -3
  42. package/dist/base/inline-edit.js +10 -10
  43. package/dist/base/item.js +1 -1
  44. package/dist/base/media-gallery.js +1 -1
  45. package/dist/base/metadata-list.js +1 -1
  46. package/dist/base/navigation.js +6 -6
  47. package/dist/base/popover-menu.js +1 -1
  48. package/dist/base/popover.js +1 -1
  49. package/dist/base/qr-code.js +1 -1
  50. package/dist/base/repeaters.js +9 -9
  51. package/dist/base/sheet.js +1 -1
  52. package/dist/base/sidebar.js +1 -1
  53. package/dist/base/signature-pad.js +6 -6
  54. package/dist/base/skeleton.js +1 -1
  55. package/dist/base/spinner.js +4 -4
  56. package/dist/base/structure.js +1 -1
  57. package/dist/base/table.js +1 -1
  58. package/dist/base/text-inputs.js +2 -2
  59. package/dist/base/toaster.js +3 -3
  60. package/dist/base/tree.js +1 -1
  61. package/dist/base/upload-queue.js +1 -1
  62. package/dist/base/upload.js +3 -3
  63. package/dist/base/value-inputs.js +1 -1
  64. package/dist/{batch-action-bar-DnUJ21NQ.js → batch-action-bar-CdfIkCsV.js} +4 -4
  65. package/dist/{batch-action-bar-DnUJ21NQ.js.map → batch-action-bar-CdfIkCsV.js.map} +1 -1
  66. package/dist/blocks/admin.js +20 -20
  67. package/dist/blocks/admin.js.map +1 -1
  68. package/dist/blocks/ai.js +15 -15
  69. package/dist/blocks/analytics/usage-card.js +1 -1
  70. package/dist/blocks/analytics.js +17 -17
  71. package/dist/blocks/analytics.js.map +1 -1
  72. package/dist/blocks/collaboration.js +1 -1
  73. package/dist/blocks/commerce/receipt.js +1 -1
  74. package/dist/blocks/commerce.js +570 -567
  75. package/dist/blocks/commerce.js.map +1 -1
  76. package/dist/blocks/data-display.js +2 -2
  77. package/dist/blocks/onboarding.js +5 -5
  78. package/dist/blocks/planning.js +11 -11
  79. package/dist/blocks/timelines.js +1 -1
  80. package/dist/{breadcrumbs-C-oqs1sQ.js → breadcrumbs-B-WFKecD.js} +4 -4
  81. package/dist/{breadcrumbs-C-oqs1sQ.js.map → breadcrumbs-B-WFKecD.js.map} +1 -1
  82. package/dist/{button-DVzspB_G.js → button-DkmK-z8E.js} +2 -2
  83. package/dist/{button-DVzspB_G.js.map → button-DkmK-z8E.js.map} +1 -1
  84. package/dist/{buttons-DPZekJFu.js → buttons-BbfzgczK.js} +8 -8
  85. package/dist/{buttons-DPZekJFu.js.map → buttons-BbfzgczK.js.map} +1 -1
  86. package/dist/{cards-BaBZR-AU.js → cards-4JTWqvVe.js} +10 -10
  87. package/dist/cards-4JTWqvVe.js.map +1 -0
  88. package/dist/{chart-ZOYyK2xG.js → chart-C19flDQb.js} +4 -4
  89. package/dist/{chart-ZOYyK2xG.js.map → chart-C19flDQb.js.map} +1 -1
  90. package/dist/{checkbox-AWIhNhmo.js → checkbox-CzYUTPeJ.js} +9 -5
  91. package/dist/checkbox-CzYUTPeJ.js.map +1 -0
  92. package/dist/{choice-inputs-CNHvARCJ.js → choice-inputs-JLtij2y4.js} +182 -176
  93. package/dist/choice-inputs-JLtij2y4.js.map +1 -0
  94. package/dist/{code-block-DeneBJR_.js → code-block-CGNaUtAE.js} +7 -7
  95. package/dist/{code-block-DeneBJR_.js.map → code-block-CGNaUtAE.js.map} +1 -1
  96. package/dist/{collapsible-C-_l4hpy.js → collapsible-Do4G0zcC.js} +3 -3
  97. package/dist/{collapsible-C-_l4hpy.js.map → collapsible-Do4G0zcC.js.map} +1 -1
  98. package/dist/{collection-content-By56pLog.js → collection-content-C0e8SsTm.js} +3 -3
  99. package/dist/{collection-content-By56pLog.js.map → collection-content-C0e8SsTm.js.map} +1 -1
  100. package/dist/{combobox-Dxo2fAYQ.js → combobox-CBJDs6w_.js} +12 -12
  101. package/dist/{combobox-Dxo2fAYQ.js.map → combobox-CBJDs6w_.js.map} +1 -1
  102. package/dist/{combobox-DaHESuiL.js → combobox-hbhSS18O.js} +7 -7
  103. package/dist/{combobox-DaHESuiL.js.map → combobox-hbhSS18O.js.map} +1 -1
  104. package/dist/{command-C25VMRII.js → command-D8NrBj-b.js} +7 -7
  105. package/dist/{command-C25VMRII.js.map → command-D8NrBj-b.js.map} +1 -1
  106. package/dist/{comments-DD0DUPwJ.js → comments-Di4w0H_S.js} +383 -382
  107. package/dist/comments-Di4w0H_S.js.map +1 -0
  108. package/dist/components/base/action-menu/action-menu.d.ts +2 -0
  109. package/dist/components/base/cards/card.recipes.d.ts +12 -5
  110. package/dist/components/base/cards/smart-card.types.d.ts +12 -7
  111. package/dist/components/base/choice-inputs/checkbox.d.ts +7 -2
  112. package/dist/components/base/choice-inputs/switch-card.d.ts +7 -0
  113. package/dist/components/base/choice-inputs/toggle-field.d.ts +7 -0
  114. package/dist/components/base/date-pickers/datepicker.types.d.ts +7 -0
  115. package/dist/components/base/forms/controlled-form-field.d.ts +6 -6
  116. package/dist/components/base/forms/form-field.d.ts +5 -3
  117. package/dist/components/base/forms/index.d.ts +1 -0
  118. package/dist/components/base/forms/server-errors.d.ts +16 -0
  119. package/dist/components/base/forms/workflow.d.ts +5 -2
  120. package/dist/components/base/metadata-list/metadata-list.d.ts +3 -1
  121. package/dist/components/base/navigation/page-header/page-header.d.ts +4 -2
  122. package/dist/components/base/structure/composition.recipes.d.ts +17 -0
  123. package/dist/components/base/text-inputs/hooks/use-form-field-state.d.ts +7 -2
  124. package/dist/components/base/text-inputs/input.d.ts +4 -2
  125. package/dist/components/base/text-inputs/textarea.d.ts +4 -2
  126. package/dist/components/base/value-inputs/date-time-input.d.ts +2 -1
  127. package/dist/components/base/value-inputs/slider.d.ts +5 -1
  128. package/dist/components/base/value-inputs/tags-input.d.ts +5 -1
  129. package/dist/components/typography/text.styles.d.ts +26 -1
  130. package/dist/composition.recipes-COdiFhxB.js +19 -0
  131. package/dist/composition.recipes-COdiFhxB.js.map +1 -0
  132. package/dist/containers-CRmHf7GP.js +104 -0
  133. package/dist/containers-CRmHf7GP.js.map +1 -0
  134. package/dist/{copyable-ClBuk_UK.js → copyable-CnGCZdX4.js} +4 -4
  135. package/dist/{copyable-ClBuk_UK.js.map → copyable-CnGCZdX4.js.map} +1 -1
  136. package/dist/{data-display-DT_khPl_.js → data-display-D4oujtx0.js} +239 -238
  137. package/dist/data-display-D4oujtx0.js.map +1 -0
  138. package/dist/{date-DCrsDTZc.js → date-Q7jnXxpk.js} +5 -5
  139. package/dist/{date-DCrsDTZc.js.map → date-Q7jnXxpk.js.map} +1 -1
  140. package/dist/{date-picker-B2K3ucWn.js → date-picker-zOt1oNss.js} +102 -90
  141. package/dist/date-picker-zOt1oNss.js.map +1 -0
  142. package/dist/date-pickers-cj8IXbDC.js +179 -0
  143. package/dist/date-pickers-cj8IXbDC.js.map +1 -0
  144. package/dist/{display-hAc1HjpI.js → display-BB4BL_-K.js} +8 -8
  145. package/dist/{display-hAc1HjpI.js.map → display-BB4BL_-K.js.map} +1 -1
  146. package/dist/{dropdown-menu-Cl4X7L5S.js → dropdown-menu-CjY8Vt7W.js} +8 -8
  147. package/dist/{dropdown-menu-Cl4X7L5S.js.map → dropdown-menu-CjY8Vt7W.js.map} +1 -1
  148. package/dist/features/activities.js +11 -11
  149. package/dist/features/ai-chat.js +9 -9
  150. package/dist/features/appointment-calendar.js +222 -220
  151. package/dist/features/appointment-calendar.js.map +1 -1
  152. package/dist/features/async-preview.js +8 -8
  153. package/dist/features/combobox.js +1 -1
  154. package/dist/features/comments.js +1 -1
  155. package/dist/features/data-view.js +10 -10
  156. package/dist/features/email-composer.js +275 -274
  157. package/dist/features/email-composer.js.map +1 -1
  158. package/dist/features/event-calendar.js +199 -198
  159. package/dist/features/event-calendar.js.map +1 -1
  160. package/dist/features/filters.js +1 -1
  161. package/dist/features/global-search.js +12 -12
  162. package/dist/features/kanban.js +4 -4
  163. package/dist/features/map.js +7 -7
  164. package/dist/features/media-library.js +623 -622
  165. package/dist/features/media-library.js.map +1 -1
  166. package/dist/features/mentions.js +1 -1
  167. package/dist/features/overlays.js +1 -1
  168. package/dist/features/products.js +973 -969
  169. package/dist/features/products.js.map +1 -1
  170. package/dist/features/questionnaire.js +12 -12
  171. package/dist/features/resource-assignment.js +8 -8
  172. package/dist/features/resource.js +113 -112
  173. package/dist/features/resource.js.map +1 -1
  174. package/dist/features/rich-text-editor.js +2 -2
  175. package/dist/features/schema-form.js +254 -253
  176. package/dist/features/schema-form.js.map +1 -1
  177. package/dist/features/suggestions.js +3 -3
  178. package/dist/features/sync.js +3 -3
  179. package/dist/features/table.js +1 -1
  180. package/dist/features/theme-tweaker.js +19 -19
  181. package/dist/features/theme-tweaker.js.map +1 -1
  182. package/dist/{feedback-BYIhtitP.js → feedback-DZNL5Lg1.js} +9 -9
  183. package/dist/{feedback-BYIhtitP.js.map → feedback-DZNL5Lg1.js.map} +1 -1
  184. package/dist/{field-affordance-recipes-DZhnIL_Y.js → field-affordance-recipes-DjwGx8eM.js} +2 -2
  185. package/dist/{field-affordance-recipes-DZhnIL_Y.js.map → field-affordance-recipes-DjwGx8eM.js.map} +1 -1
  186. package/dist/{filters-DJVAveHA.js → filters-BcT-uoFy.js} +19 -19
  187. package/dist/{filters-DJVAveHA.js.map → filters-BcT-uoFy.js.map} +1 -1
  188. package/dist/{form-field-CwH9y77i.js → form-field-CsgRmdit.js} +14 -8
  189. package/dist/form-field-CsgRmdit.js.map +1 -0
  190. package/dist/{form-sizing-BdP_Mf5p.js → form-sizing-NXgjkmBG.js} +3 -3
  191. package/dist/{form-sizing-BdP_Mf5p.js.map → form-sizing-NXgjkmBG.js.map} +1 -1
  192. package/dist/{forms-B9G_xwzi.js → forms-BV5m5aQF.js} +83 -65
  193. package/dist/forms-BV5m5aQF.js.map +1 -0
  194. package/dist/{forms-numeric-B_jraJaQ.js → forms-numeric-Cd33AKbD.js} +288 -288
  195. package/dist/forms-numeric-Cd33AKbD.js.map +1 -0
  196. package/dist/{header-BSfIEWbI.js → header-BA697l4a.js} +14 -14
  197. package/dist/{header-BSfIEWbI.js.map → header-BA697l4a.js.map} +1 -1
  198. package/dist/hooks/useFormErrors.d.ts +1 -1
  199. package/dist/{hooks-ClH9thn4.js → hooks-BQ-L7Uu2.js} +2 -2
  200. package/dist/{hooks-ClH9thn4.js.map → hooks-BQ-L7Uu2.js.map} +1 -1
  201. package/dist/{icon-badge-DYKIwvOV.js → icon-badge-COWbCCWu.js} +3 -3
  202. package/dist/{icon-badge-DYKIwvOV.js.map → icon-badge-COWbCCWu.js.map} +1 -1
  203. package/dist/index.js +2 -2
  204. package/dist/input-Cdw4k0fb.js +289 -0
  205. package/dist/input-Cdw4k0fb.js.map +1 -0
  206. package/dist/{input-CZw8iU99.js → input-DOPL5_QE.js} +3 -3
  207. package/dist/{input-CZw8iU99.js.map → input-DOPL5_QE.js.map} +1 -1
  208. package/dist/item-BvZ2DR_x.js +277 -0
  209. package/dist/item-BvZ2DR_x.js.map +1 -0
  210. package/dist/layout/app-shell.js +1 -1
  211. package/dist/layout/auth.js +1 -1
  212. package/dist/layout/containers.js +1 -1
  213. package/dist/layout/header.js +1 -1
  214. package/dist/layout/hooks.js +1 -1
  215. package/dist/layout/navigation.js +1 -1
  216. package/dist/layout/page.js +1 -1
  217. package/dist/layout/settings.js +1 -1
  218. package/dist/layout/sidebar.js +2 -2
  219. package/dist/layout/workspace.js +1 -1
  220. package/dist/layout.js +10 -10
  221. package/dist/lib/affordance-geometry.generated.d.ts +6 -0
  222. package/dist/lib/ui-provider/types.d.ts +1 -1
  223. package/dist/lib/utils.js +1 -1
  224. package/dist/{media-gallery-3zIVLMWH.js → media-gallery-CSl5W1Fy.js} +6 -6
  225. package/dist/{media-gallery-3zIVLMWH.js.map → media-gallery-CSl5W1Fy.js.map} +1 -1
  226. package/dist/{mentions-CGlEJ15c.js → mentions-RKOQaaIB.js} +8 -8
  227. package/dist/{mentions-CGlEJ15c.js.map → mentions-RKOQaaIB.js.map} +1 -1
  228. package/dist/{message-DZ_ruyUV.js → message-INU2xsxu.js} +4 -4
  229. package/dist/{message-DZ_ruyUV.js.map → message-INU2xsxu.js.map} +1 -1
  230. package/dist/metadata-list-qVV7AVxa.js +443 -0
  231. package/dist/metadata-list-qVV7AVxa.js.map +1 -0
  232. package/dist/{navigation-BzhHI3lo.js → navigation-BQNcg1jT.js} +8 -8
  233. package/dist/{navigation-BzhHI3lo.js.map → navigation-BQNcg1jT.js.map} +1 -1
  234. package/dist/{navigation-Bnotn4AQ.js → navigation-DLF3E1IC.js} +7 -7
  235. package/dist/{navigation-Bnotn4AQ.js.map → navigation-DLF3E1IC.js.map} +1 -1
  236. package/dist/{navigation-row-recipes-BFLCk_Aq.js → navigation-row-recipes-WZEs-hYo.js} +2 -2
  237. package/dist/{navigation-row-recipes-BFLCk_Aq.js.map → navigation-row-recipes-WZEs-hYo.js.map} +1 -1
  238. package/dist/{number-DbV1Dija.js → number-E_OiIfJz.js} +5 -5
  239. package/dist/{number-DbV1Dija.js.map → number-E_OiIfJz.js.map} +1 -1
  240. package/dist/{overflow-tab-bar-CWY7Nogn.js → overflow-tab-bar-CrbqMteP.js} +107 -105
  241. package/dist/overflow-tab-bar-CrbqMteP.js.map +1 -0
  242. package/dist/{overlays-tMkF-VAN.js → overlays-BlKynmde.js} +228 -227
  243. package/dist/overlays-BlKynmde.js.map +1 -0
  244. package/dist/page-CIwNUtGr.js +227 -0
  245. package/dist/page-CIwNUtGr.js.map +1 -0
  246. package/dist/page-header-commands-DFMlNYzN.js +128 -0
  247. package/dist/page-header-commands-DFMlNYzN.js.map +1 -0
  248. package/dist/{pagination-BL25hu2s.js → pagination-Ch8X_47u.js} +5 -5
  249. package/dist/{pagination-BL25hu2s.js.map → pagination-Ch8X_47u.js.map} +1 -1
  250. package/dist/{popover-menu-Cn9rUkdc.js → popover-menu-BYaCdFhf.js} +6 -6
  251. package/dist/{popover-menu-Cn9rUkdc.js.map → popover-menu-BYaCdFhf.js.map} +1 -1
  252. package/dist/{popover-gnTOhbFM.js → popover-uwzX2vo7.js} +4 -4
  253. package/dist/{popover-gnTOhbFM.js.map → popover-uwzX2vo7.js.map} +1 -1
  254. package/dist/{primitives-BFK08r9M.js → primitives-Du64iDbb.js} +6 -6
  255. package/dist/{primitives-BFK08r9M.js.map → primitives-Du64iDbb.js.map} +1 -1
  256. package/dist/primitives.js +4 -4
  257. package/dist/{progress-B1VnCT0K.js → progress-BvF2oCdV.js} +5 -5
  258. package/dist/{progress-B1VnCT0K.js.map → progress-BvF2oCdV.js.map} +1 -1
  259. package/dist/{receipt-BVSOH3Xo.js → receipt-D789Jwyy.js} +6 -6
  260. package/dist/{receipt-BVSOH3Xo.js.map → receipt-D789Jwyy.js.map} +1 -1
  261. package/dist/{rich-text-GOUyKQ-s.js → rich-text-CLJEf76s.js} +4 -4
  262. package/dist/{rich-text-GOUyKQ-s.js.map → rich-text-CLJEf76s.js.map} +1 -1
  263. package/dist/{rich-text-editor-cRLC-eBK.js → rich-text-editor-Cm1dpUpQ.js} +10 -10
  264. package/dist/{rich-text-editor-cRLC-eBK.js.map → rich-text-editor-Cm1dpUpQ.js.map} +1 -1
  265. package/dist/{rich-text-editor-toolbar-DfXg0-VC.js → rich-text-editor-toolbar-L__e4x47.js} +4 -4
  266. package/dist/{rich-text-editor-toolbar-DfXg0-VC.js.map → rich-text-editor-toolbar-L__e4x47.js.map} +1 -1
  267. package/dist/{scroll-area-DcI-M1UT.js → scroll-area-La5RXsEk.js} +2 -2
  268. package/dist/{scroll-area-DcI-M1UT.js.map → scroll-area-La5RXsEk.js.map} +1 -1
  269. package/dist/{separator-Bom7NsGO.js → separator-DAEV0w65.js} +2 -2
  270. package/dist/{separator-Bom7NsGO.js.map → separator-DAEV0w65.js.map} +1 -1
  271. package/dist/{separator-BDV-Y648.js → separator-GNfPG-90.js} +3 -3
  272. package/dist/{separator-BDV-Y648.js.map → separator-GNfPG-90.js.map} +1 -1
  273. package/dist/services/actions.js +1 -1
  274. package/dist/settings-BA2iboic.js +174 -0
  275. package/dist/settings-BA2iboic.js.map +1 -0
  276. package/dist/{sheet-ijlsjq-n.js → sheet-DoAxTb2J.js} +7 -7
  277. package/dist/{sheet-ijlsjq-n.js.map → sheet-DoAxTb2J.js.map} +1 -1
  278. package/dist/{sidebar-DkTO4VTO.js → sidebar-ByqKR_W5.js} +13 -13
  279. package/dist/{sidebar-DkTO4VTO.js.map → sidebar-ByqKR_W5.js.map} +1 -1
  280. package/dist/{sidebar-Db6gkh3U.js → sidebar-D2iSnGJ7.js} +11 -11
  281. package/dist/{sidebar-Db6gkh3U.js.map → sidebar-D2iSnGJ7.js.map} +1 -1
  282. package/dist/{skeleton-Byjnt7qr.js → skeleton-CUj8O5Bd.js} +3 -3
  283. package/dist/{skeleton-Byjnt7qr.js.map → skeleton-CUj8O5Bd.js.map} +1 -1
  284. package/dist/smart-card-CqkzQsK-.js +614 -0
  285. package/dist/smart-card-CqkzQsK-.js.map +1 -0
  286. package/dist/{structure-BmisBK-3.js → structure-C0V0_Fyf.js} +3 -3
  287. package/dist/{structure-BmisBK-3.js.map → structure-C0V0_Fyf.js.map} +1 -1
  288. package/dist/{structure.recipes-EPz60cU8.js → structure.recipes-BB4-n58V.js} +2 -2
  289. package/dist/{structure.recipes-EPz60cU8.js.map → structure.recipes-BB4-n58V.js.map} +1 -1
  290. package/dist/style.css +1 -1
  291. package/dist/{table-DsfzoUia.js → table-CpvnzJn9.js} +3 -3
  292. package/dist/{table-DsfzoUia.js.map → table-CpvnzJn9.js.map} +1 -1
  293. package/dist/{table-BweFy_P9.js → table-DH7rozUv.js} +19 -19
  294. package/dist/{table-BweFy_P9.js.map → table-DH7rozUv.js.map} +1 -1
  295. package/dist/{tabs-CDocW5D1.js → tabs-eqVsJZWO.js} +7 -7
  296. package/dist/{tabs-CDocW5D1.js.map → tabs-eqVsJZWO.js.map} +1 -1
  297. package/dist/{text-inputs-f9Ia-aCi.js → text-inputs-DXItiR0O.js} +101 -98
  298. package/dist/text-inputs-DXItiR0O.js.map +1 -0
  299. package/dist/{text.styles-g4He6UIW.js → text.styles-B64My8RZ.js} +25 -10
  300. package/dist/text.styles-B64My8RZ.js.map +1 -0
  301. package/dist/theme.css +152 -112
  302. package/dist/{timelines-CwM_9IhD.js → timelines-DmtztAY_.js} +10 -10
  303. package/dist/{timelines-CwM_9IhD.js.map → timelines-DmtztAY_.js.map} +1 -1
  304. package/dist/{tooltip-yiRJUFjp.js → tooltip-B4hjKtoV.js} +3 -3
  305. package/dist/{tooltip-yiRJUFjp.js.map → tooltip-B4hjKtoV.js.map} +1 -1
  306. package/dist/{tree-WnKQzwbq.js → tree-CV11PURP.js} +8 -8
  307. package/dist/{tree-WnKQzwbq.js.map → tree-CV11PURP.js.map} +1 -1
  308. package/dist/typography/rich-text.js +1 -1
  309. package/dist/typography-CSyJrh28.js +117 -0
  310. package/dist/typography-CSyJrh28.js.map +1 -0
  311. package/dist/typography.js +1 -1
  312. package/dist/{ui-provider-C_U0Xma4.js → ui-provider-CQCuCBcy.js} +3 -3
  313. package/dist/ui-provider-CQCuCBcy.js.map +1 -0
  314. package/dist/ui-provider.js +1 -1
  315. package/dist/{upload-CXyxmQBP.js → upload-C9SA0X-8.js} +11 -11
  316. package/dist/{upload-CXyxmQBP.js.map → upload-C9SA0X-8.js.map} +1 -1
  317. package/dist/{upload-queue-Boscubn9.js → upload-queue-DhQJiSRc.js} +9 -9
  318. package/dist/{upload-queue-Boscubn9.js.map → upload-queue-DhQJiSRc.js.map} +1 -1
  319. package/dist/{usage-card-BhO5eqkX.js → usage-card-DVTRDmGz.js} +134 -133
  320. package/dist/usage-card-DVTRDmGz.js.map +1 -0
  321. package/dist/{utils-BRhFDwuU.js → utils-CF3c95Io.js} +68 -5
  322. package/dist/utils-CF3c95Io.js.map +1 -0
  323. package/dist/value-inputs-C0o70p-U.js +980 -0
  324. package/dist/value-inputs-C0o70p-U.js.map +1 -0
  325. package/dist/{value-typography-BP8OG6h5.js → value-typography-ClupF0Gz.js} +2 -2
  326. package/dist/{value-typography-BP8OG6h5.js.map → value-typography-ClupF0Gz.js.map} +1 -1
  327. package/dist/workspace-9EFVXUyk.js +410 -0
  328. package/dist/workspace-9EFVXUyk.js.map +1 -0
  329. package/docs/consumer-skill/SKILL.md +14 -129
  330. package/docs/consumer-skill/examples/app-layout.tsx +22 -12
  331. package/docs/consumer-skill/examples/authentication.tsx +77 -0
  332. package/docs/consumer-skill/examples/edit.tsx +30 -38
  333. package/docs/consumer-skill/examples/manifest.json +51 -1
  334. package/docs/consumer-skill/examples/rhf-bindings.tsx +86 -0
  335. package/docs/consumer-skill/examples/rhf-edit-page.tsx +141 -0
  336. package/docs/consumer-skill/examples/rhf-overlay-form.tsx +92 -0
  337. package/docs/consumer-skill/examples/rhf-transport.tsx +28 -0
  338. package/docs/consumer-skill/references/agents-md.md +17 -7
  339. package/docs/consumer-skill/references/authentication.md +42 -0
  340. package/docs/consumer-skill/references/component-contracts.json +319824 -0
  341. package/docs/consumer-skill/references/composition-mapping.md +92 -0
  342. package/docs/consumer-skill/references/composition.md +43 -19
  343. package/docs/consumer-skill/references/design-contract.md +32 -0
  344. package/docs/consumer-skill/references/discovery.md +84 -7
  345. package/docs/consumer-skill/references/installation.md +40 -36
  346. package/docs/consumer-skill/references/integration.md +6 -2
  347. package/docs/consumer-skill/references/public-api.json +1519 -65
  348. package/docs/consumer-skill/references/review.md +9 -4
  349. package/docs/consumer-skill/references/rhf-workflows.md +86 -0
  350. package/docs/consumer-skill/references/screen-archetypes.md +22 -0
  351. package/docs/consumer-skill/references/theming.md +8 -9
  352. package/docs/consumer-skill/references/tokens.json +12 -3
  353. package/docs/consumer-skill/references/workflows.md +2 -1
  354. package/docs/consumer-skill/scripts/composition-schema.d.mts +2 -0
  355. package/docs/consumer-skill/scripts/composition-schema.mjs +32 -0
  356. package/docs/consumer-skill/scripts/composition.mjs +198 -0
  357. package/docs/consumer-skill/scripts/discovery.mjs +42 -10
  358. package/docs/consumer-skill/scripts/inspect-component.mjs +11 -0
  359. package/docs/consumer-skill/scripts/inspect-tokens.mjs +11 -0
  360. package/docs/consumer-skill/scripts/inspection.mjs +138 -0
  361. package/docs/consumer-skill/scripts/map-composition.mjs +12 -0
  362. package/docs/consumer-skill/scripts/setup-skills.mjs +76 -0
  363. package/docs/consumer-skills/themelia-components/SKILL.md +30 -0
  364. package/docs/consumer-skills/themelia-composition/SKILL.md +35 -0
  365. package/docs/consumer-skills/themelia-forms/SKILL.md +12 -0
  366. package/docs/consumer-skills/themelia-foundation/SKILL.md +14 -0
  367. package/docs/consumer-skills/themelia-tokenization/SKILL.md +35 -0
  368. package/package.json +4 -2
  369. package/templates/README.md +39 -0
  370. package/templates/admin-shell-template.tsx +382 -0
  371. package/templates/analytics-operations-template.tsx +376 -0
  372. package/templates/customers-template.tsx +509 -0
  373. package/templates/index.ts +29 -0
  374. package/templates/orders-template.tsx +1102 -0
  375. package/templates/products-template.tsx +834 -0
  376. package/templates/user-permissions-template.tsx +450 -0
  377. package/dist/action-menu-CllU52Mm.js +0 -280
  378. package/dist/action-menu-CllU52Mm.js.map +0 -1
  379. package/dist/affordance-geometry.generated-tF36bREk.js.map +0 -1
  380. package/dist/ai-artifact-DvTwDVyL.js.map +0 -1
  381. package/dist/app-shell-C4FhvCqF.js.map +0 -1
  382. package/dist/cards-BaBZR-AU.js.map +0 -1
  383. package/dist/checkbox-AWIhNhmo.js.map +0 -1
  384. package/dist/choice-inputs-CNHvARCJ.js.map +0 -1
  385. package/dist/comments-DD0DUPwJ.js.map +0 -1
  386. package/dist/containers-Mu1LMGV1.js +0 -103
  387. package/dist/containers-Mu1LMGV1.js.map +0 -1
  388. package/dist/data-display-DT_khPl_.js.map +0 -1
  389. package/dist/date-picker-B2K3ucWn.js.map +0 -1
  390. package/dist/date-pickers-Ds8gLaoP.js +0 -175
  391. package/dist/date-pickers-Ds8gLaoP.js.map +0 -1
  392. package/dist/form-field-CwH9y77i.js.map +0 -1
  393. package/dist/forms-B9G_xwzi.js.map +0 -1
  394. package/dist/forms-numeric-B_jraJaQ.js.map +0 -1
  395. package/dist/input-DQdEd0YD.js +0 -263
  396. package/dist/input-DQdEd0YD.js.map +0 -1
  397. package/dist/item-K5_ghvze.js +0 -275
  398. package/dist/item-K5_ghvze.js.map +0 -1
  399. package/dist/metadata-list-8N16ZMW_.js +0 -405
  400. package/dist/metadata-list-8N16ZMW_.js.map +0 -1
  401. package/dist/overflow-tab-bar-CWY7Nogn.js.map +0 -1
  402. package/dist/overlays-tMkF-VAN.js.map +0 -1
  403. package/dist/page-CL9YeH_V.js +0 -224
  404. package/dist/page-CL9YeH_V.js.map +0 -1
  405. package/dist/page-header-commands-DOb6WsfD.js +0 -126
  406. package/dist/page-header-commands-DOb6WsfD.js.map +0 -1
  407. package/dist/settings-ybnjVwbd.js +0 -171
  408. package/dist/settings-ybnjVwbd.js.map +0 -1
  409. package/dist/smart-card-DiC5aac3.js +0 -604
  410. package/dist/smart-card-DiC5aac3.js.map +0 -1
  411. package/dist/text-inputs-f9Ia-aCi.js.map +0 -1
  412. package/dist/text.styles-g4He6UIW.js.map +0 -1
  413. package/dist/typography-UTnveOEy.js +0 -117
  414. package/dist/typography-UTnveOEy.js.map +0 -1
  415. package/dist/ui-provider-C_U0Xma4.js.map +0 -1
  416. package/dist/usage-card-BhO5eqkX.js.map +0 -1
  417. package/dist/utils-BRhFDwuU.js.map +0 -1
  418. package/dist/value-inputs-TaX4OjNk.js +0 -963
  419. package/dist/value-inputs-TaX4OjNk.js.map +0 -1
  420. package/dist/workspace-B-OEm3Kf.js +0 -408
  421. package/dist/workspace-B-OEm3Kf.js.map +0 -1
@@ -0,0 +1,1102 @@
1
+ import { useMemo, useState } from 'react';
2
+ import {
3
+ CheckCircle2,
4
+ Mail,
5
+ Package,
6
+ RotateCcw,
7
+ Truck,
8
+ XCircle,
9
+ } from 'lucide-react';
10
+
11
+ import { ActionMenu } from 'themelia-react-ui/base/action-menu';
12
+ import { Badge } from 'themelia-react-ui/base/badge';
13
+ import { Button } from 'themelia-react-ui/base/buttons';
14
+ import { Card } from 'themelia-react-ui/base/cards';
15
+ import { Select, ToggleField } from 'themelia-react-ui/base/choice-inputs';
16
+ import { FormField, FormSection } from 'themelia-react-ui/base/forms';
17
+ import { DecimalInput } from 'themelia-react-ui/base/forms-numeric';
18
+ import {
19
+ Item,
20
+ ItemActions,
21
+ ItemContent,
22
+ ItemDescription,
23
+ ItemGroup,
24
+ ItemTitle,
25
+ } from 'themelia-react-ui/base/item';
26
+ import { Stack } from 'themelia-react-ui/base/structure';
27
+ import { Input, Textarea } from 'themelia-react-ui/base/text-inputs';
28
+ import { AddressCard, PaymentMethod } from 'themelia-react-ui/blocks/commerce';
29
+ import { MetadataList } from 'themelia-react-ui/base/metadata-list';
30
+ import { ActivityLog, type ActivityLogEntry } from 'themelia-react-ui/features/activities';
31
+ import { ActionDialog, useOverlayVisibility } from 'themelia-react-ui/features/overlays';
32
+ import { TwoColumnLayout } from 'themelia-react-ui/layout/containers';
33
+ import { Page } from 'themelia-react-ui/layout/page';
34
+ import { Money, useMoneyFormatter } from 'themelia-react-ui/primitives';
35
+ import { Text } from 'themelia-react-ui/typography';
36
+
37
+ type OrderItemFulfillmentState = 'fulfilled' | 'unfulfilled' | 'digital';
38
+
39
+ interface OrderLineItemRecord {
40
+ id: string;
41
+ name: string;
42
+ variant: string;
43
+ sku: string;
44
+ weightLabel?: string;
45
+ fulfillmentState: OrderItemFulfillmentState;
46
+ unitPrice: number;
47
+ orderedQty: number;
48
+ refundedQty: number;
49
+ canceledQty: number;
50
+ refundReason?: string;
51
+ restockedLocation?: string;
52
+ }
53
+
54
+ const INITIAL_LINE_ITEMS: OrderLineItemRecord[] = [
55
+ {
56
+ id: 'item-sweater',
57
+ name: 'Merino Wool Crewneck Sweater',
58
+ variant: 'Heather Gray / Medium',
59
+ sku: 'MWC-GRY-M',
60
+ weightLabel: '0.42 kg',
61
+ fulfillmentState: 'fulfilled',
62
+ unitPrice: 145,
63
+ orderedQty: 1,
64
+ refundedQty: 0,
65
+ canceledQty: 0,
66
+ },
67
+ {
68
+ id: 'item-shirt',
69
+ name: 'Washed Linen Oxford Shirt',
70
+ variant: 'White / Medium',
71
+ sku: 'WLO-WHT-M',
72
+ weightLabel: '0.32 kg',
73
+ fulfillmentState: 'fulfilled',
74
+ unitPrice: 95,
75
+ orderedQty: 2,
76
+ refundedQty: 0,
77
+ canceledQty: 0,
78
+ },
79
+ {
80
+ id: 'item-scarf',
81
+ name: 'Cashmere Ribbed Scarf',
82
+ variant: 'Oatmeal / One Size',
83
+ sku: 'CRS-OAT-OS',
84
+ weightLabel: '0.24 kg',
85
+ fulfillmentState: 'unfulfilled',
86
+ unitPrice: 110,
87
+ orderedQty: 1,
88
+ refundedQty: 0,
89
+ canceledQty: 0,
90
+ },
91
+ {
92
+ id: 'item-giftcard',
93
+ name: 'Oak & Loom Digital Gift Card',
94
+ variant: '50.00 USD denomination · Recipient: ava.bennett@example.com',
95
+ sku: 'DGC-50-USD',
96
+ fulfillmentState: 'digital',
97
+ unitPrice: 50,
98
+ orderedQty: 1,
99
+ refundedQty: 0,
100
+ canceledQty: 0,
101
+ },
102
+ {
103
+ id: 'item-tote',
104
+ name: 'Everyday Canvas Tote',
105
+ variant: 'Natural / One Size',
106
+ sku: 'ECT-NAT-OS',
107
+ weightLabel: '0.28 kg',
108
+ fulfillmentState: 'fulfilled',
109
+ unitPrice: 45,
110
+ orderedQty: 1,
111
+ refundedQty: 1,
112
+ canceledQty: 0,
113
+ refundReason: 'Customer exchanged size/color',
114
+ restockedLocation: 'Brooklyn Warehouse',
115
+ },
116
+ {
117
+ id: 'item-beanie',
118
+ name: 'Ribbed Merino Beanie',
119
+ variant: 'Charcoal / One Size',
120
+ sku: 'RMB-CHR-OS',
121
+ weightLabel: '0.15 kg',
122
+ fulfillmentState: 'unfulfilled',
123
+ unitPrice: 38,
124
+ orderedQty: 1,
125
+ refundedQty: 0,
126
+ canceledQty: 1,
127
+ refundReason: 'Canceled before fulfillment',
128
+ restockedLocation: 'Brooklyn Warehouse',
129
+ },
130
+ ];
131
+
132
+ const REFUND_REASONS = [
133
+ { value: 'size_exchange', label: 'Size or fit exchange' },
134
+ { value: 'customer_changed_mind', label: 'Customer changed mind' },
135
+ { value: 'damaged_in_transit', label: 'Arrived damaged' },
136
+ { value: 'wrong_item_sent', label: 'Incorrect item shipped' },
137
+ ];
138
+
139
+ const CARRIER_OPTIONS = [
140
+ { value: 'UPS Ground', label: 'UPS Ground' },
141
+ { value: 'UPS 2nd Day Air', label: 'UPS 2nd Day Air' },
142
+ { value: 'FedEx Home Delivery', label: 'FedEx Home Delivery' },
143
+ { value: 'DHL Express', label: 'DHL Express' },
144
+ ];
145
+
146
+ const INITIAL_TIMELINE: ActivityLogEntry[] = [
147
+ {
148
+ id: 'evt-refund-tote',
149
+ kind: 'event',
150
+ label: 'Refund',
151
+ actor: { name: 'Maya Lin', initials: 'ML' },
152
+ action: 'refunded',
153
+ target: '45.00 USD',
154
+ description: '1 × Everyday Canvas Tote returned to Visa •••• 4242 · Restocked at Brooklyn Warehouse',
155
+ timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),
156
+ icon: RotateCcw,
157
+ tone: 'warning',
158
+ },
159
+ {
160
+ id: 'evt-shipped',
161
+ kind: 'event',
162
+ label: 'Fulfillment #1042-F1',
163
+ actor: { name: 'Brooklyn Warehouse', initials: 'BW' },
164
+ action: 'shipped 3 physical items via',
165
+ target: 'UPS Ground #1Z999AA10123456784',
166
+ timestamp: new Date(Date.now() - 18 * 60 * 60 * 1000).toISOString(),
167
+ icon: Truck,
168
+ tone: 'info',
169
+ },
170
+ {
171
+ id: 'evt-digital',
172
+ kind: 'event',
173
+ label: 'Digital #1042-D1',
174
+ actor: { name: 'Online Store', initials: 'OS' },
175
+ action: 'emailed a 50.00 USD digital gift card to',
176
+ target: 'ava.bennett@example.com',
177
+ timestamp: new Date(Date.now() - 23 * 60 * 60 * 1000).toISOString(),
178
+ icon: Mail,
179
+ tone: 'success',
180
+ },
181
+ {
182
+ id: 'evt-paid',
183
+ kind: 'event',
184
+ label: 'Payment',
185
+ actor: { name: 'Ava Bennett', initials: 'AB' },
186
+ action: 'authorized and captured',
187
+ target: '519.21 USD on Visa ending in 4242',
188
+ timestamp: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(),
189
+ icon: CheckCircle2,
190
+ tone: 'success',
191
+ },
192
+ ];
193
+
194
+ export function OrdersAdminTemplate() {
195
+ // Sample records are priced in USD; bind that once for every text amount.
196
+ const formatMoney = useMoneyFormatter({ currency: 'USD' });
197
+ const [lineItems, setLineItems] = useState<OrderLineItemRecord[]>(INITIAL_LINE_ITEMS);
198
+ const [timeline, setTimeline] = useState<ActivityLogEntry[]>(INITIAL_TIMELINE);
199
+ const [orderNote, setOrderNote] = useState(
200
+ 'Please leave package with the building doorman if I am not home.',
201
+ );
202
+
203
+ const [noteDraft, setNoteDraft] = useState(orderNote);
204
+ // Shipment tracking state
205
+ const [carrier, setCarrier] = useState('UPS Ground');
206
+ const [trackingNumber, setTrackingNumber] = useState('1Z999AA10123456784');
207
+ const [notifyTrackingCustomer, setNotifyTrackingCustomer] = useState(true);
208
+ const [trackingDraft, setTrackingDraft] = useState({ carrier, trackingNumber, notifyCustomer: notifyTrackingCustomer });
209
+
210
+ // Refund dialog state
211
+ const refundDialog = useOverlayVisibility();
212
+ const trackingDialog = useOverlayVisibility();
213
+ const noteDialog = useOverlayVisibility();
214
+
215
+ const [refundSelection, setRefundSelection] = useState<Record<string, number>>({
216
+ 'item-sweater': 0,
217
+ 'item-shirt': 1,
218
+ 'item-scarf': 0,
219
+ 'item-giftcard': 0,
220
+ });
221
+ const [refundReason, setRefundReason] = useState('size_exchange');
222
+ const [restockInventory, setRestockInventory] = useState(true);
223
+ const [notifyCustomer, setNotifyCustomer] = useState(true);
224
+ const [refundNote, setRefundNote] = useState('');
225
+
226
+ const fulfilledPhysicalItems = useMemo(
227
+ () =>
228
+ lineItems.filter(
229
+ (item) =>
230
+ item.fulfillmentState === 'fulfilled' &&
231
+ item.orderedQty - item.refundedQty - item.canceledQty > 0,
232
+ ),
233
+ [lineItems],
234
+ );
235
+
236
+ const unfulfilledPhysicalItems = useMemo(
237
+ () =>
238
+ lineItems.filter(
239
+ (item) =>
240
+ item.fulfillmentState === 'unfulfilled' &&
241
+ item.orderedQty - item.refundedQty - item.canceledQty > 0,
242
+ ),
243
+ [lineItems],
244
+ );
245
+
246
+ const fulfilledDigitalItems = useMemo(
247
+ () =>
248
+ lineItems.filter(
249
+ (item) =>
250
+ item.fulfillmentState === 'digital' &&
251
+ item.orderedQty - item.refundedQty - item.canceledQty > 0,
252
+ ),
253
+ [lineItems],
254
+ );
255
+
256
+ const removedItems = useMemo(
257
+ () => lineItems.filter((item) => item.refundedQty > 0 || item.canceledQty > 0),
258
+ [lineItems],
259
+ );
260
+
261
+ const activeSubtotal = useMemo(
262
+ () =>
263
+ lineItems.reduce((sum, item) => {
264
+ const activeUnits = item.orderedQty - item.canceledQty;
265
+ return sum + activeUnits * item.unitPrice;
266
+ }, 0),
267
+ [lineItems],
268
+ );
269
+
270
+ const totalRefundedAmount = useMemo(
271
+ () =>
272
+ lineItems.reduce((sum, item) => sum + item.refundedQty * item.unitPrice, 0),
273
+ [lineItems],
274
+ );
275
+
276
+ const discountAmount = 50.25;
277
+ const shippingAmount = 0;
278
+ const taxAmount = 29.46;
279
+ const originalCapturedTotal = INITIAL_LINE_ITEMS.reduce((sum, item) => sum + (item.orderedQty - item.canceledQty) * item.unitPrice, 0) - discountAmount + shippingAmount + taxAmount;
280
+ const netPayment = Math.max(0, originalCapturedTotal - totalRefundedAmount);
281
+
282
+ const draftRefundTotal = useMemo(
283
+ () =>
284
+ lineItems.reduce((sum, item) => {
285
+ const requested = refundSelection[item.id] ?? 0;
286
+ const selectedQty = Number.isFinite(requested) ? Math.min(Math.max(0, Math.floor(requested)), item.orderedQty - item.refundedQty - item.canceledQty) : 0;
287
+ return sum + selectedQty * item.unitPrice;
288
+ }, 0),
289
+ [lineItems, refundSelection],
290
+ );
291
+
292
+ const openRefundForSingleItem = (itemId: string) => {
293
+ setRefundSelection({
294
+ 'item-sweater': 0,
295
+ 'item-shirt': 0,
296
+ 'item-scarf': 0,
297
+ 'item-giftcard': 0,
298
+ [itemId]: 1,
299
+ });
300
+ refundDialog.show();
301
+ };
302
+
303
+ const handleFulfillItem = (itemId: string) => {
304
+ const targetItem = lineItems.find((item) => item.id === itemId);
305
+ if (!targetItem) return;
306
+
307
+ setLineItems((current) =>
308
+ current.map((item) =>
309
+ item.id === itemId ? { ...item, fulfillmentState: 'fulfilled' } : item,
310
+ ),
311
+ );
312
+
313
+ setTimeline((current) => [
314
+ {
315
+ id: `evt-fulfill-${Date.now()}`,
316
+ kind: 'event',
317
+ label: 'Fulfillment #1042-F1',
318
+ actor: { name: 'Maya Lin', initials: 'ML' },
319
+ action: 'fulfilled',
320
+ target: `${targetItem.orderedQty - targetItem.refundedQty - targetItem.canceledQty} × ${targetItem.name}`,
321
+ description: `Added to shipment ${carrier} #${trackingNumber}`,
322
+ timestamp: new Date().toISOString(),
323
+ icon: Package,
324
+ tone: 'success',
325
+ },
326
+ ...current,
327
+ ]);
328
+ };
329
+
330
+ const handleCancelUnfulfilledItem = (itemId: string) => {
331
+ const targetItem = lineItems.find((item) => item.id === itemId);
332
+ if (!targetItem) return;
333
+ const remainingQty =
334
+ targetItem.orderedQty - targetItem.refundedQty - targetItem.canceledQty;
335
+ if (remainingQty <= 0) return;
336
+
337
+ setLineItems((current) =>
338
+ current.map((item) =>
339
+ item.id === itemId
340
+ ? {
341
+ ...item,
342
+ canceledQty: item.canceledQty + remainingQty,
343
+ refundReason: 'Canceled before fulfillment',
344
+ restockedLocation: 'Brooklyn Warehouse',
345
+ }
346
+ : item,
347
+ ),
348
+ );
349
+
350
+ setTimeline((current) => [
351
+ {
352
+ id: `evt-cancel-${Date.now()}`,
353
+ kind: 'event',
354
+ label: 'Cancellation',
355
+ actor: { name: 'Maya Lin', initials: 'ML' },
356
+ action: 'canceled unfulfilled item',
357
+ target: `${remainingQty} × ${targetItem.name}`,
358
+ description: 'Inventory released at Brooklyn Warehouse',
359
+ timestamp: new Date().toISOString(),
360
+ icon: XCircle,
361
+ tone: 'destructive',
362
+ },
363
+ ...current,
364
+ ]);
365
+ };
366
+
367
+ const handleResendGiftCard = () => {
368
+ setTimeline((current) => [
369
+ {
370
+ id: `evt-resend-dgc-${Date.now()}`,
371
+ kind: 'event',
372
+ label: 'Digital #1042-D1',
373
+ actor: { name: 'Maya Lin', initials: 'ML' },
374
+ action: 'resent digital gift card email to',
375
+ target: 'ava.bennett@example.com',
376
+ timestamp: new Date().toISOString(),
377
+ icon: Mail,
378
+ tone: 'info',
379
+ },
380
+ ...current,
381
+ ]);
382
+ };
383
+
384
+ const handleConfirmRefund = () => {
385
+ if (draftRefundTotal <= 0) {
386
+ refundDialog.hide();
387
+ return;
388
+ }
389
+
390
+ const reasonLabel =
391
+ REFUND_REASONS.find((r) => r.value === refundReason)?.label ?? 'Customer return';
392
+ const refundedNames: string[] = [];
393
+
394
+ const nextLineItems = lineItems.map((item) => {
395
+ const requested = refundSelection[item.id] ?? 0;
396
+ const selectedQty = Number.isFinite(requested) ? Math.min(Math.max(0, Math.floor(requested)), item.orderedQty - item.refundedQty - item.canceledQty) : 0;
397
+ if (selectedQty <= 0) return item;
398
+ const maxRefundable = item.orderedQty - item.refundedQty - item.canceledQty;
399
+ const applied = Math.min(selectedQty, maxRefundable);
400
+ if (applied > 0) {
401
+ refundedNames.push(`${applied} × ${item.name}`);
402
+ }
403
+ return {
404
+ ...item,
405
+ refundedQty: item.refundedQty + applied,
406
+ refundReason: reasonLabel,
407
+ restockedLocation: restockInventory ? 'Brooklyn Warehouse' : undefined,
408
+ };
409
+ });
410
+ setLineItems(nextLineItems);
411
+
412
+ setTimeline((current) => [
413
+ {
414
+ id: `evt-refund-${Date.now()}`,
415
+ kind: 'event',
416
+ label: 'Refund',
417
+ actor: { name: 'Maya Lin', initials: 'ML' },
418
+ action: 'refunded',
419
+ target: formatMoney(draftRefundTotal),
420
+ description: `for ${refundedNames.join(', ')} (${reasonLabel}${restockInventory ? ' · Restocked at Brooklyn Warehouse' : ''})${refundNote.trim() ? ` · ${refundNote.trim()}` : ''}${notifyCustomer ? ' · Customer notification requested' : ''}`,
421
+ timestamp: new Date().toISOString(),
422
+ icon: RotateCcw,
423
+ tone: 'warning',
424
+ },
425
+ ...current,
426
+ ]);
427
+
428
+ setRefundSelection({});
429
+ setRefundNote('');
430
+ refundDialog.hide();
431
+ };
432
+
433
+ const unfulfilledUnitCount = unfulfilledPhysicalItems.reduce(
434
+ (sum, item) => sum + (item.orderedQty - item.refundedQty - item.canceledQty),
435
+ 0,
436
+ );
437
+
438
+ const handleFulfillRemaining = () =>
439
+ unfulfilledPhysicalItems.forEach((item) => handleFulfillItem(item.id));
440
+
441
+ return (
442
+ <Page
443
+ header={{
444
+ title: 'Order #1042',
445
+ description: 'October 14, 2026 at 2:14 pm · Online Store',
446
+ titleBadges: [
447
+ {
448
+ label: totalRefundedAmount > 0 ? 'Partially refunded' : 'Paid',
449
+ tone: totalRefundedAmount > 0 ? 'warning' : 'success',
450
+ },
451
+ {
452
+ label: unfulfilledUnitCount > 0 ? 'Partially fulfilled' : 'Fulfilled',
453
+ tone: unfulfilledUnitCount > 0 ? 'info' : 'success',
454
+ },
455
+ ],
456
+ // Fulfillment is the order's next step, so it is the route's one primary command
457
+ // while physical items remain unfulfilled.
458
+ primaryAction: {
459
+ label: `Fulfill ${unfulfilledUnitCount === 1 ? 'item' : 'items'}`,
460
+ visible: unfulfilledUnitCount > 0,
461
+ onClick: handleFulfillRemaining,
462
+ },
463
+ secondaryActions: [{ label: 'Refund items', onClick: refundDialog.show }],
464
+ }}
465
+ >
466
+ <TwoColumnLayout
467
+ stickyAside
468
+ main={
469
+ <Stack gap="2xl">
470
+ {/* Group 1: Fulfilled Physical Shipment */}
471
+ <Card
472
+ title="Fulfilled shipment · #1042-F1"
473
+ headerAction={
474
+ <Button
475
+ size="sm"
476
+ onClick={() => { setTrackingDraft({ carrier, trackingNumber, notifyCustomer: notifyTrackingCustomer }); trackingDialog.show(); }}
477
+ >
478
+ Edit tracking
479
+ </Button>
480
+ }
481
+ >
482
+ <Stack gap="2xl">
483
+ <MetadataList
484
+ columns={3}
485
+ items={[
486
+ {
487
+ id: 'carrier',
488
+ label: 'Carrier',
489
+ value: carrier,
490
+ },
491
+ {
492
+ id: 'tracking',
493
+ label: 'Tracking',
494
+ value: { kind: 'mono', value: trackingNumber },
495
+ },
496
+ {
497
+ id: 'origin',
498
+ label: 'Origin',
499
+ value: 'Brooklyn Warehouse',
500
+ },
501
+ ]}
502
+ />
503
+
504
+ <ItemGroup>
505
+ {fulfilledPhysicalItems.map((item) => {
506
+ const activeQty =
507
+ item.orderedQty - item.refundedQty - item.canceledQty;
508
+ return (
509
+ <Item key={item.id} size="md">
510
+ <ItemContent className="basis-48">
511
+ <ItemTitle>{item.name}</ItemTitle>
512
+ <ItemDescription>
513
+ {item.variant} · SKU {item.sku}
514
+ {item.weightLabel ? ` · ${item.weightLabel}` : ''}
515
+ </ItemDescription>
516
+ </ItemContent>
517
+ <ItemActions>
518
+ <Stack direction="horizontal" gap="md" align="center">
519
+ <Text size="sm" type="secondary">
520
+ {formatMoney(item.unitPrice)} × {activeQty}
521
+ </Text>
522
+ <Money
523
+ amount={item.unitPrice * activeQty}
524
+ currency="USD"
525
+ weight="semibold"
526
+ />
527
+ <ActionMenu
528
+ actions={[
529
+ {
530
+ id: `refund-${item.id}`,
531
+ label: 'Refund item',
532
+ icon: RotateCcw,
533
+ onClick: () => openRefundForSingleItem(item.id),
534
+ },
535
+ ]}
536
+ />
537
+ </Stack>
538
+ </ItemActions>
539
+ </Item>
540
+ );
541
+ })}
542
+ </ItemGroup>
543
+ </Stack>
544
+ </Card>
545
+
546
+ {/* Group 2: Unfulfilled Physical Items (if any remain unfulfilled) */}
547
+ {unfulfilledPhysicalItems.length > 0 && (
548
+ <Card title="Unfulfilled · #1042-U1">
549
+ <Stack gap="2xl">
550
+ <MetadataList
551
+ columns={3}
552
+ items={[
553
+ {
554
+ id: 'location',
555
+ label: 'Location',
556
+ value: 'Brooklyn Warehouse',
557
+ },
558
+ {
559
+ id: 'shipping-method',
560
+ label: 'Delivery method',
561
+ value: 'UPS Ground',
562
+ },
563
+ {
564
+ id: 'stock-status',
565
+ label: 'Stock',
566
+ value: {
567
+ kind: 'badge',
568
+ value: 'Ready to pack',
569
+ badgeTone: 'success',
570
+ },
571
+ },
572
+ ]}
573
+ />
574
+
575
+ <ItemGroup>
576
+ {unfulfilledPhysicalItems.map((item) => {
577
+ const activeQty =
578
+ item.orderedQty - item.refundedQty - item.canceledQty;
579
+ return (
580
+ <Item key={item.id} size="md">
581
+ <ItemContent className="basis-48">
582
+ <ItemTitle>{item.name}</ItemTitle>
583
+ <ItemDescription>
584
+ {item.variant} · SKU {item.sku}
585
+ {item.weightLabel ? ` · ${item.weightLabel}` : ''}
586
+ </ItemDescription>
587
+ </ItemContent>
588
+ <ItemActions>
589
+ <Stack direction="horizontal" gap="md" align="center">
590
+ <Text size="sm" type="secondary">
591
+ {formatMoney(item.unitPrice)} × {activeQty}
592
+ </Text>
593
+ <Money
594
+ amount={item.unitPrice * activeQty}
595
+ currency="USD"
596
+ weight="semibold"
597
+ />
598
+ <ActionMenu
599
+ actions={[
600
+ {
601
+ id: `fulfill-${item.id}`,
602
+ label: 'Mark as fulfilled',
603
+ icon: Package,
604
+ onClick: () => handleFulfillItem(item.id),
605
+ },
606
+ {
607
+ id: `cancel-${item.id}`,
608
+ label: 'Cancel item',
609
+ icon: XCircle,
610
+ tone: 'destructive',
611
+ onClick: () =>
612
+ handleCancelUnfulfilledItem(item.id),
613
+ },
614
+ ]}
615
+ />
616
+ </Stack>
617
+ </ItemActions>
618
+ </Item>
619
+ );
620
+ })}
621
+ </ItemGroup>
622
+ </Stack>
623
+ </Card>
624
+ )}
625
+
626
+ {/* Group 3: Digital Delivery */}
627
+ <Card
628
+ title="Digital delivery · #1042-D1"
629
+ headerAction={
630
+ <Button size="sm" onClick={handleResendGiftCard}>
631
+ Resend gift card
632
+ </Button>
633
+ }
634
+ >
635
+ <Stack gap="2xl">
636
+ <MetadataList
637
+ columns={3}
638
+ items={[
639
+ {
640
+ id: 'recipient',
641
+ label: 'Recipient',
642
+ value: { kind: 'email', value: 'ava.bennett@example.com' },
643
+ },
644
+ {
645
+ id: 'code',
646
+ label: 'Gift card code',
647
+ value: { kind: 'mono', value: '•••• •••• •••• 8F2A' },
648
+ },
649
+ {
650
+ id: 'status',
651
+ label: 'Status',
652
+ value: {
653
+ kind: 'badge',
654
+ value: 'Sent Oct 14',
655
+ badgeTone: 'success',
656
+ },
657
+ },
658
+ ]}
659
+ />
660
+
661
+ <ItemGroup>
662
+ {fulfilledDigitalItems.map((item) => {
663
+ const activeQty =
664
+ item.orderedQty - item.refundedQty - item.canceledQty;
665
+ return (
666
+ <Item key={item.id} size="md">
667
+ <ItemContent className="basis-48">
668
+ <ItemTitle>{item.name}</ItemTitle>
669
+ <ItemDescription>
670
+ {item.variant} · SKU {item.sku}
671
+ </ItemDescription>
672
+ </ItemContent>
673
+ <ItemActions>
674
+ <Stack direction="horizontal" gap="md" align="center">
675
+ <Text size="sm" type="secondary">
676
+ {formatMoney(item.unitPrice)} × {activeQty}
677
+ </Text>
678
+ <Money
679
+ amount={item.unitPrice * activeQty}
680
+ currency="USD"
681
+ weight="semibold"
682
+ />
683
+ <ActionMenu
684
+ actions={[
685
+ {
686
+ id: `resend-${item.id}`,
687
+ label: 'Resend email',
688
+ icon: Mail,
689
+ onClick: handleResendGiftCard,
690
+ },
691
+ {
692
+ id: `refund-${item.id}`,
693
+ label: 'Refund gift card',
694
+ icon: RotateCcw,
695
+ onClick: () => openRefundForSingleItem(item.id),
696
+ },
697
+ ]}
698
+ />
699
+ </Stack>
700
+ </ItemActions>
701
+ </Item>
702
+ );
703
+ })}
704
+ </ItemGroup>
705
+ </Stack>
706
+ </Card>
707
+
708
+ {/* Group 4: Refunded & Canceled Items */}
709
+ {removedItems.length > 0 && (
710
+ <Card
711
+ title="Refunded & canceled"
712
+ headerAction={
713
+ <Button size="sm" onClick={refundDialog.show}>
714
+ Refund more items
715
+ </Button>
716
+ }
717
+ >
718
+ <ItemGroup>
719
+ {removedItems.map((item) => {
720
+ const isCanceled = item.canceledQty > 0 && item.refundedQty === 0;
721
+ const qty = isCanceled ? item.canceledQty : item.refundedQty;
722
+ return (
723
+ <Item key={`removed-${item.id}`} size="md">
724
+ <ItemContent className="basis-48">
725
+ <ItemTitle>
726
+ <Stack direction="horizontal" gap="sm" align="center" wrap>
727
+ <Text tag="span" size="inherit" weight="semibold" lineHeight="tight">{item.name}</Text>
728
+ <Badge tone={isCanceled ? 'destructive' : 'warning'}>
729
+ {isCanceled ? 'Canceled' : 'Refunded'}
730
+ </Badge>
731
+ </Stack>
732
+ </ItemTitle>
733
+ <ItemDescription>
734
+ {item.variant} · SKU {item.sku}
735
+ {item.refundReason ? ` · ${item.refundReason}` : ''}
736
+ {item.restockedLocation
737
+ ? ` · Restocked at ${item.restockedLocation}`
738
+ : ''}
739
+ </ItemDescription>
740
+ </ItemContent>
741
+ <ItemActions>
742
+ <Stack direction="horizontal" gap="lg" align="center">
743
+ <Text size="sm" type="secondary">
744
+ {formatMoney(item.unitPrice)} × {qty}
745
+ </Text>
746
+ <Money
747
+ amount={isCanceled ? 0 : -(item.unitPrice * qty)}
748
+ currency="USD"
749
+ weight="semibold"
750
+ />
751
+ </Stack>
752
+ </ItemActions>
753
+ </Item>
754
+ );
755
+ })}
756
+ </ItemGroup>
757
+ </Card>
758
+ )}
759
+
760
+ {/* Payment Summary Card: the page header's badge states the payment status once. */}
761
+ <Card title="Payment">
762
+ <Stack gap="2xl">
763
+ <MetadataList
764
+ layout="rows"
765
+ density="compact"
766
+ valueAlign="end"
767
+ items={[
768
+ {
769
+ id: 'subtotal',
770
+ label: 'Subtotal (5 active items)',
771
+ value: { kind: 'money', value: activeSubtotal, currency: 'USD' },
772
+ },
773
+ {
774
+ id: 'discount',
775
+ label: 'Discount · AUTUMN15 (15% off apparel)',
776
+ value: { kind: 'money', value: -discountAmount, currency: 'USD' },
777
+ },
778
+ {
779
+ id: 'shipping',
780
+ label: `Shipping · ${carrier} (1.4 kg)`,
781
+ value: { kind: 'money', value: shippingAmount, currency: 'USD' },
782
+ },
783
+ {
784
+ id: 'taxes',
785
+ label: 'Taxes · NY State & NYC Local 8.875%',
786
+ value: { kind: 'money', value: taxAmount, currency: 'USD' },
787
+ },
788
+ {
789
+ id: 'total',
790
+ label: <Text weight="semibold">Total</Text>,
791
+ value: (
792
+ <Money
793
+ amount={originalCapturedTotal}
794
+ currency="USD"
795
+ weight="bold"
796
+ />
797
+ ),
798
+ },
799
+ ]}
800
+ />
801
+
802
+ <MetadataList
803
+ layout="rows"
804
+ density="compact"
805
+ valueAlign="end"
806
+ items={[
807
+ {
808
+ id: 'paid',
809
+ label: 'Paid by customer (Visa •••• 4242)',
810
+ value: {
811
+ kind: 'money' as const,
812
+ value: originalCapturedTotal,
813
+ currency: 'USD',
814
+ },
815
+ },
816
+ ...(totalRefundedAmount > 0
817
+ ? [
818
+ {
819
+ id: 'refunded',
820
+ label: 'Refunded to Visa •••• 4242',
821
+ value: {
822
+ kind: 'money' as const,
823
+ value: -totalRefundedAmount,
824
+ currency: 'USD',
825
+ },
826
+ },
827
+ ]
828
+ : []),
829
+ {
830
+ id: 'net',
831
+ label: <Text weight="semibold">Net payment</Text>,
832
+ value: <Money amount={netPayment} currency="USD" weight="bold" />,
833
+ },
834
+ ]}
835
+ />
836
+ </Stack>
837
+ </Card>
838
+
839
+ {/* Order Timeline */}
840
+ <Card title="Timeline">
841
+ <ActivityLog bare entries={timeline} itemSpacing="compact" />
842
+ </Card>
843
+ </Stack>
844
+ }
845
+ aside={
846
+ <Stack gap="2xl">
847
+ {/* Customer Metadata Card */}
848
+ <Card title="Customer">
849
+ <MetadataList
850
+ columns={1}
851
+ items={[
852
+ {
853
+ id: 'customer-name',
854
+ label: 'Name',
855
+ value: {
856
+ kind: 'text',
857
+ value: 'Ava Bennett',
858
+ },
859
+ },
860
+ {
861
+ id: 'customer-orders',
862
+ label: 'Orders',
863
+ value: `12 orders (${formatMoney(1840)} spent)`,
864
+ },
865
+ {
866
+ id: 'customer-email',
867
+ label: 'Email',
868
+ value: {
869
+ kind: 'email',
870
+ value: 'ava.bennett@example.com',
871
+ },
872
+ },
873
+ {
874
+ id: 'customer-phone',
875
+ label: 'Phone',
876
+ value: {
877
+ kind: 'phone',
878
+ value: '+12125550148',
879
+ display: '+1 (212) 555-0148',
880
+ },
881
+ },
882
+ ]}
883
+ />
884
+ </Card>
885
+
886
+ {/* Shipping Address Card */}
887
+ <AddressCard
888
+ surface="card"
889
+ kind="shipping"
890
+ default
891
+ name="Ava Bennett"
892
+ line1="214 Mercer Street"
893
+ line2="Apt 4B"
894
+ city="New York, NY"
895
+ postalCode="10012"
896
+ country="United States"
897
+ phone="+1 (212) 555-0148"
898
+ />
899
+
900
+ {/* Billing Address Card */}
901
+ <AddressCard
902
+ surface="card"
903
+ kind="billing"
904
+ name="Ava Bennett"
905
+ line1="214 Mercer Street"
906
+ line2="Apt 4B"
907
+ city="New York, NY"
908
+ postalCode="10012"
909
+ country="United States"
910
+ />
911
+
912
+ {/* Payment Method Card */}
913
+ <PaymentMethod
914
+ surface="card"
915
+ brand="visa"
916
+ last4="4242"
917
+ expiry="08/28"
918
+ holderName="Ava Bennett"
919
+ default
920
+ />
921
+
922
+ {/* Customer Delivery Note */}
923
+ <Card
924
+ title="Notes"
925
+ headerAction={
926
+ <Button
927
+ tone="secondary"
928
+ buttonStyle="ghost"
929
+ size="sm"
930
+ onClick={() => { setNoteDraft(orderNote); noteDialog.show(); }}
931
+ >
932
+ Edit
933
+ </Button>
934
+ }
935
+ >
936
+ <Text size="sm" type="secondary">
937
+ {orderNote}
938
+ </Text>
939
+ </Card>
940
+ </Stack>
941
+ }
942
+ />
943
+
944
+ {/* Edit Tracking Dialog */}
945
+ <ActionDialog
946
+ {...trackingDialog.overlayProps}
947
+ title="Edit tracking · Shipment #1042-F1"
948
+ description="Update carrier and tracking details for this fulfilled shipment."
949
+ strings={{
950
+ confirm: 'Save tracking',
951
+ cancel: 'Cancel',
952
+ }}
953
+ onConfirm={() => { setCarrier(trackingDraft.carrier); setTrackingNumber(trackingDraft.trackingNumber); setNotifyTrackingCustomer(trackingDraft.notifyCustomer); trackingDialog.hide(); }}
954
+ >
955
+ <FormSection title="Shipment tracking">
956
+ <FormField label="Shipping carrier" required>
957
+ <Select
958
+ aria-label="Shipping carrier"
959
+ options={CARRIER_OPTIONS}
960
+ value={trackingDraft.carrier}
961
+ onValueChange={(value) => setTrackingDraft((draft) => ({ ...draft, carrier: String(value) }))}
962
+ />
963
+ </FormField>
964
+ <FormField label="Tracking number" required>
965
+ <Input
966
+ aria-label="Tracking number"
967
+ value={trackingDraft.trackingNumber}
968
+ onChange={(event) => setTrackingDraft((draft) => ({ ...draft, trackingNumber: event.target.value }))}
969
+ />
970
+ </FormField>
971
+ <ToggleField
972
+ kind="checkbox"
973
+ value={trackingDraft.notifyCustomer}
974
+ onValueChange={(checked) => setTrackingDraft((draft) => ({ ...draft, notifyCustomer: Boolean(checked) }))}
975
+ label="Send tracking update email to customer"
976
+ />
977
+ </FormSection>
978
+ </ActionDialog>
979
+
980
+ {/* Edit Order Note Dialog */}
981
+ <ActionDialog
982
+ {...noteDialog.overlayProps}
983
+ title="Edit order note"
984
+ description="Update delivery instructions or internal notes for Order #1042."
985
+ strings={{
986
+ confirm: 'Save note',
987
+ cancel: 'Cancel',
988
+ }}
989
+ onConfirm={() => { setOrderNote(noteDraft); noteDialog.hide(); }}
990
+ >
991
+ <FormSection title="Order note">
992
+ <FormField label="Note">
993
+ <Textarea
994
+ aria-label="Order note"
995
+ rows={3}
996
+ value={noteDraft}
997
+ onChange={(event) => setNoteDraft(event.target.value)}
998
+ />
999
+ </FormField>
1000
+ </FormSection>
1001
+ </ActionDialog>
1002
+
1003
+ {/* Refund Items Dialog */}
1004
+ <ActionDialog
1005
+ {...refundDialog.overlayProps}
1006
+ title="Refund items · Order #1042"
1007
+ description="Select quantities to refund and return to inventory."
1008
+ strings={{
1009
+ confirm:
1010
+ draftRefundTotal > 0
1011
+ ? `Refund ${formatMoney(draftRefundTotal)}`
1012
+ : 'Select items to refund',
1013
+ cancel: 'Cancel',
1014
+ }}
1015
+ onConfirm={handleConfirmRefund}
1016
+ >
1017
+ <Stack gap="2xl">
1018
+ <FormSection title="Refundable line items">
1019
+ <Stack gap="md">
1020
+ {lineItems
1021
+ .filter((item) => item.orderedQty - item.refundedQty - item.canceledQty > 0)
1022
+ .map((item) => {
1023
+ const maxQty = item.orderedQty - item.refundedQty - item.canceledQty;
1024
+ const currentQty = refundSelection[item.id] ?? 0;
1025
+ return (
1026
+ <Stack
1027
+ key={item.id}
1028
+ direction="horizontal"
1029
+ justify="between"
1030
+ align="center"
1031
+ gap="md"
1032
+ >
1033
+ <Stack gap="xs">
1034
+ <Text weight="medium">{item.name}</Text>
1035
+ <Text size="xs" type="secondary">
1036
+ {item.variant} · {formatMoney(item.unitPrice)} × {maxQty} available
1037
+ </Text>
1038
+ </Stack>
1039
+ <DecimalInput
1040
+ aria-label={`Refund quantity for ${item.name}`}
1041
+ decimalPlaces={0}
1042
+ step={1}
1043
+ min={0}
1044
+ max={maxQty}
1045
+ value={String(currentQty)}
1046
+ onChange={(event) =>
1047
+ setRefundSelection((prev) => ({
1048
+ ...prev,
1049
+ [item.id]: Math.max(
1050
+ 0,
1051
+ Math.min(maxQty, Number(event.target.value || 0)),
1052
+ ),
1053
+ }))
1054
+ }
1055
+ />
1056
+ </Stack>
1057
+ );
1058
+ })}
1059
+ </Stack>
1060
+ </FormSection>
1061
+ <FormSection title="Refund details">
1062
+ <Stack gap="md">
1063
+ <FormField label="Reason for refund" required>
1064
+ <Select
1065
+ aria-label="Reason for refund"
1066
+ options={REFUND_REASONS}
1067
+ value={refundReason}
1068
+ onValueChange={(value) => setRefundReason(String(value))}
1069
+ />
1070
+ </FormField>
1071
+
1072
+ <FormField label="Staff note (optional)">
1073
+ <Textarea
1074
+ aria-label="Staff note"
1075
+ value={refundNote}
1076
+ onChange={(event) => setRefundNote(event.target.value)}
1077
+ placeholder="Reason for refund or inspection note..."
1078
+ rows={2}
1079
+ />
1080
+ </FormField>
1081
+
1082
+ <ToggleField
1083
+ kind="checkbox"
1084
+ value={restockInventory}
1085
+ onValueChange={(checked) => setRestockInventory(Boolean(checked))}
1086
+ label="Restock returned items at Brooklyn Warehouse"
1087
+ />
1088
+ <ToggleField
1089
+ kind="checkbox"
1090
+ value={notifyCustomer}
1091
+ onValueChange={(checked) => setNotifyCustomer(Boolean(checked))}
1092
+ label="Send refund notification email to customer"
1093
+ />
1094
+ </Stack>
1095
+ </FormSection>
1096
+ </Stack>
1097
+ </ActionDialog>
1098
+ </Page>
1099
+ );
1100
+ }
1101
+
1102
+ export default OrdersAdminTemplate;