@stackcraftmx/calcita 0.47.0 → 0.52.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 (501) hide show
  1. package/README.md +192 -13
  2. package/cli/calcita.js +17 -0
  3. package/cli/checkTexts.js +266 -0
  4. package/cli/packageVersions.js +6 -1
  5. package/cli/projectFiles.js +4 -2
  6. package/cli/templates/project/README.md.tpl +21 -1
  7. package/cli/templates/project/eslint.config.js.tpl +27 -0
  8. package/cli/templates/project/src/app/appTexts.js.tpl +2 -1
  9. package/cli/templates/project/src/core/publicPaths.js.tpl +10 -2
  10. package/cli/templates/project/vite.config.js.tpl +8 -1
  11. package/dist/DataTable/AuditTrailDialog.js +3 -2
  12. package/dist/DataTable/AuditTrailDialog.js.map +1 -1
  13. package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js +3 -2
  14. package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js.map +1 -1
  15. package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +3 -2
  16. package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -1
  17. package/dist/DataTable/ColumnFilters/SortableFilterHeader.js +3 -2
  18. package/dist/DataTable/ColumnFilters/SortableFilterHeader.js.map +1 -1
  19. package/dist/DataTable/EmptyState.js +3 -2
  20. package/dist/DataTable/EmptyState.js.map +1 -1
  21. package/dist/DataTable/FilterChips.js +3 -2
  22. package/dist/DataTable/FilterChips.js.map +1 -1
  23. package/dist/DataTable/GoToPage.js +3 -2
  24. package/dist/DataTable/GoToPage.js.map +1 -1
  25. package/dist/DataTable/ServerTable.js +95 -28
  26. package/dist/DataTable/ServerTable.js.map +1 -1
  27. package/dist/DataTable/ServerTableFilterDrawer.js +8 -3
  28. package/dist/DataTable/ServerTableFilterDrawer.js.map +1 -1
  29. package/dist/DataTable/StackedCell.js +60 -0
  30. package/dist/DataTable/StackedCell.js.map +1 -0
  31. package/dist/DataTable/TableCardsView.js +88 -0
  32. package/dist/DataTable/TableCardsView.js.map +1 -0
  33. package/dist/DataTable/columnWidths.js +30 -0
  34. package/dist/DataTable/columnWidths.js.map +1 -0
  35. package/dist/DataTable/columns.js +47 -1
  36. package/dist/DataTable/columns.js.map +1 -1
  37. package/dist/DataTable/fixedColumns.js +24 -0
  38. package/dist/DataTable/fixedColumns.js.map +1 -0
  39. package/dist/DataTable/useTableView.js +29 -0
  40. package/dist/DataTable/useTableView.js.map +1 -0
  41. package/dist/access/PermissionMatrix.js +3 -2
  42. package/dist/access/PermissionMatrix.js.map +1 -1
  43. package/dist/account/AccountProvider.js +1 -1
  44. package/dist/account/AccountSecuritySection.js +3 -2
  45. package/dist/account/AccountSecuritySection.js.map +1 -1
  46. package/dist/account/DemoTotpCodeButton.js +3 -2
  47. package/dist/account/DemoTotpCodeButton.js.map +1 -1
  48. package/dist/account/ProfileScreen.js +3 -2
  49. package/dist/account/ProfileScreen.js.map +1 -1
  50. package/dist/account/SignInScreen.js +3 -2
  51. package/dist/account/SignInScreen.js.map +1 -1
  52. package/dist/appShell/AccountMenu.js +3 -2
  53. package/dist/appShell/AccountMenu.js.map +1 -1
  54. package/dist/appShell/AppLayout.js +3 -2
  55. package/dist/appShell/AppLayout.js.map +1 -1
  56. package/dist/appShell/AppearanceSettings.js +3 -2
  57. package/dist/appShell/AppearanceSettings.js.map +1 -1
  58. package/dist/appShell/AuthLayout.js +3 -2
  59. package/dist/appShell/AuthLayout.js.map +1 -1
  60. package/dist/appShell/BarActionButton.js +11 -4
  61. package/dist/appShell/BarActionButton.js.map +1 -1
  62. package/dist/appShell/BarActions.js +3 -2
  63. package/dist/appShell/BarActions.js.map +1 -1
  64. package/dist/appShell/BarCapsule.js +3 -2
  65. package/dist/appShell/BarCapsule.js.map +1 -1
  66. package/dist/appShell/BarSearch.js +3 -2
  67. package/dist/appShell/BarSearch.js.map +1 -1
  68. package/dist/appShell/HeaderTools.js +3 -2
  69. package/dist/appShell/HeaderTools.js.map +1 -1
  70. package/dist/appShell/MobileTabBar.js +3 -2
  71. package/dist/appShell/MobileTabBar.js.map +1 -1
  72. package/dist/appShell/SettingsMenu.js +3 -2
  73. package/dist/appShell/SettingsMenu.js.map +1 -1
  74. package/dist/appShell/SideMenu.js +3 -2
  75. package/dist/appShell/SideMenu.js.map +1 -1
  76. package/dist/appShell/SideMenuEntry.js +3 -2
  77. package/dist/appShell/SideMenuEntry.js.map +1 -1
  78. package/dist/appShell/SubmenuActionsMenu.js +3 -2
  79. package/dist/appShell/SubmenuActionsMenu.js.map +1 -1
  80. package/dist/appShell/TabBarEditor.js +3 -2
  81. package/dist/appShell/TabBarEditor.js.map +1 -1
  82. package/dist/appShell/TopMenu.js +3 -2
  83. package/dist/appShell/TopMenu.js.map +1 -1
  84. package/dist/appShell/Wordmark.js +3 -2
  85. package/dist/appShell/Wordmark.js.map +1 -1
  86. package/dist/auth/PasswordChecklist.js +3 -2
  87. package/dist/auth/PasswordChecklist.js.map +1 -1
  88. package/dist/calendar/EventCalendar.js +3 -2
  89. package/dist/calendar/EventCalendar.js.map +1 -1
  90. package/dist/calendar/EventDetails.js +3 -2
  91. package/dist/calendar/EventDetails.js.map +1 -1
  92. package/dist/datePickers/DateInput.js +28 -22
  93. package/dist/datePickers/DateInput.js.map +1 -1
  94. package/dist/datePickers/DateTimeInput.js +33 -27
  95. package/dist/datePickers/DateTimeInput.js.map +1 -1
  96. package/dist/datePickers/MonthInput.js +27 -21
  97. package/dist/datePickers/MonthInput.js.map +1 -1
  98. package/dist/datePickers/TimeInput.js +26 -20
  99. package/dist/datePickers/TimeInput.js.map +1 -1
  100. package/dist/datePickers/usePickerField.js +5 -4
  101. package/dist/datePickers/usePickerField.js.map +1 -1
  102. package/dist/downloads/DownloadManager.js +3 -2
  103. package/dist/downloads/DownloadManager.js.map +1 -1
  104. package/dist/feedback/ConfirmDialog.js +3 -2
  105. package/dist/feedback/ConfirmDialog.js.map +1 -1
  106. package/dist/feedback/ModalWaiting.js +3 -2
  107. package/dist/feedback/ModalWaiting.js.map +1 -1
  108. package/dist/feedback/NewBuildNotice.js +3 -2
  109. package/dist/feedback/NewBuildNotice.js.map +1 -1
  110. package/dist/filepond/FileDropzone.js +3 -2
  111. package/dist/filepond/FileDropzone.js.map +1 -1
  112. package/dist/forms/FormProblemAlert.js +3 -2
  113. package/dist/forms/FormProblemAlert.js.map +1 -1
  114. package/dist/forms/FormWizard.js +21 -6
  115. package/dist/forms/FormWizard.js.map +1 -1
  116. package/dist/forms/SubmitButton.js +7 -2
  117. package/dist/forms/SubmitButton.js.map +1 -1
  118. package/dist/forms/auth/SignInForm.js +3 -2
  119. package/dist/forms/auth/SignInForm.js.map +1 -1
  120. package/dist/forms/fieldRules.js +30 -0
  121. package/dist/forms/fieldRules.js.map +1 -0
  122. package/dist/forms/security/SecondStepForm.js +3 -2
  123. package/dist/forms/security/SecondStepForm.js.map +1 -1
  124. package/dist/forms/security/TwoStepVerificationCard.js +3 -2
  125. package/dist/forms/security/TwoStepVerificationCard.js.map +1 -1
  126. package/dist/forms/useValidationText.js +18 -0
  127. package/dist/forms/useValidationText.js.map +1 -0
  128. package/dist/forms/validation.js +35 -31
  129. package/dist/forms/validation.js.map +1 -1
  130. package/dist/forms/validationMessages.js +64 -7
  131. package/dist/forms/validationMessages.js.map +1 -1
  132. package/dist/forms.js +3 -0
  133. package/dist/forms.js.map +1 -1
  134. package/dist/hookForm/FormProblemAlert.js +3 -2
  135. package/dist/hookForm/FormProblemAlert.js.map +1 -1
  136. package/dist/hookForm/FormWizard.js +19 -5
  137. package/dist/hookForm/FormWizard.js.map +1 -1
  138. package/dist/hookForm/SubmitButton.js +7 -2
  139. package/dist/hookForm/SubmitButton.js.map +1 -1
  140. package/dist/inbox/InboxLayout.js +3 -2
  141. package/dist/inbox/InboxLayout.js.map +1 -1
  142. package/dist/inbox/MessageList.js +3 -2
  143. package/dist/inbox/MessageList.js.map +1 -1
  144. package/dist/inbox/MessageView.js +3 -2
  145. package/dist/inbox/MessageView.js.map +1 -1
  146. package/dist/index.js +193 -163
  147. package/dist/index.js.map +1 -1
  148. package/dist/inputs/CatalogInput.js +32 -25
  149. package/dist/inputs/CatalogInput.js.map +1 -1
  150. package/dist/inputs/CheckboxGroupInput.js +8 -5
  151. package/dist/inputs/CheckboxGroupInput.js.map +1 -1
  152. package/dist/inputs/ColorInput.js +7 -4
  153. package/dist/inputs/ColorInput.js.map +1 -1
  154. package/dist/inputs/FieldFrame.js +10 -4
  155. package/dist/inputs/FieldFrame.js.map +1 -1
  156. package/dist/inputs/FormSection.js +1 -1
  157. package/dist/inputs/MaskedInput.js +1 -0
  158. package/dist/inputs/MaskedInput.js.map +1 -1
  159. package/dist/inputs/NumberInput.js +29 -24
  160. package/dist/inputs/NumberInput.js.map +1 -1
  161. package/dist/inputs/RepeatingFields.js +8 -5
  162. package/dist/inputs/RepeatingFields.js.map +1 -1
  163. package/dist/inputs/SelectInput.js +8 -5
  164. package/dist/inputs/SelectInput.js.map +1 -1
  165. package/dist/inputs/TextInput.js +5 -3
  166. package/dist/inputs/TextInput.js.map +1 -1
  167. package/dist/inputs/TransferListInput.js +8 -5
  168. package/dist/inputs/TransferListInput.js.map +1 -1
  169. package/dist/inputs/WizardLayout.js +48 -19
  170. package/dist/inputs/WizardLayout.js.map +1 -1
  171. package/dist/inputs/useWizardSteps.js +36 -0
  172. package/dist/inputs/useWizardSteps.js.map +1 -0
  173. package/dist/inputs/wizardSteps.js +32 -0
  174. package/dist/inputs/wizardSteps.js.map +1 -0
  175. package/dist/kanban/KanbanBoard.js +3 -2
  176. package/dist/kanban/KanbanBoard.js.map +1 -1
  177. package/dist/legal/CookieNotice.js +3 -2
  178. package/dist/legal/CookieNotice.js.map +1 -1
  179. package/dist/legal/TermsAcceptanceDialog.js +3 -2
  180. package/dist/legal/TermsAcceptanceDialog.js.map +1 -1
  181. package/dist/locales/en.js +24 -0
  182. package/dist/locales/en.js.map +1 -1
  183. package/dist/locales/es.js +24 -0
  184. package/dist/locales/es.js.map +1 -1
  185. package/dist/maps/MapView.js +3 -2
  186. package/dist/maps/MapView.js.map +1 -1
  187. package/dist/mexico/CfdiSummary.js +3 -2
  188. package/dist/mexico/CfdiSummary.js.map +1 -1
  189. package/dist/mexico/EfirmaFields.js +3 -2
  190. package/dist/mexico/EfirmaFields.js.map +1 -1
  191. package/dist/mexico/mexicoIdentifiers.js +5 -0
  192. package/dist/mexico/mexicoIdentifiers.js.map +1 -1
  193. package/dist/mexico/mexicoRules.js +9 -4
  194. package/dist/mexico/mexicoRules.js.map +1 -1
  195. package/dist/mexico.js +4 -2
  196. package/dist/pwa/InstallAppSetting.js +3 -2
  197. package/dist/pwa/InstallAppSetting.js.map +1 -1
  198. package/dist/pwa/InstallInstructionsDialog.js +3 -2
  199. package/dist/pwa/InstallInstructionsDialog.js.map +1 -1
  200. package/dist/pwa/InstallPromptBanner.js +3 -2
  201. package/dist/pwa/InstallPromptBanner.js.map +1 -1
  202. package/dist/react-hook-form.js +3 -0
  203. package/dist/react-hook-form.js.map +1 -1
  204. package/dist/richText/RichTextEditor.js +7 -4
  205. package/dist/richText/RichTextEditor.js.map +1 -1
  206. package/dist/richText/RichTextView.js +3 -2
  207. package/dist/richText/RichTextView.js.map +1 -1
  208. package/dist/security/ActivityLog.js +3 -2
  209. package/dist/security/ActivityLog.js.map +1 -1
  210. package/dist/security/RecoveryCodesDialog.js +3 -2
  211. package/dist/security/RecoveryCodesDialog.js.map +1 -1
  212. package/dist/security/SessionsCard.js +3 -2
  213. package/dist/security/SessionsCard.js.map +1 -1
  214. package/dist/table.js +21 -2
  215. package/dist/table.js.map +1 -1
  216. package/dist/theme/themePieces.js +70 -4
  217. package/dist/theme/themePieces.js.map +1 -1
  218. package/dist/toolkit/ToolkitProvider.js +8 -1
  219. package/dist/toolkit/ToolkitProvider.js.map +1 -1
  220. package/dist/toolkit/browserNavigation.js +19 -4
  221. package/dist/toolkit/browserNavigation.js.map +1 -1
  222. package/dist/toolkit/combineTexts.js +32 -0
  223. package/dist/toolkit/combineTexts.js.map +1 -0
  224. package/dist/toolkit/hashNavigation.js +17 -3
  225. package/dist/toolkit/hashNavigation.js.map +1 -1
  226. package/dist/toolkit/navigationPaths.js +15 -0
  227. package/dist/toolkit/navigationPaths.js.map +1 -1
  228. package/dist/toolkit/pathIndex.js +66 -0
  229. package/dist/toolkit/pathIndex.js.map +1 -0
  230. package/dist/toolkit/toolkitSettings.js +19 -1
  231. package/dist/toolkit/toolkitSettings.js.map +1 -1
  232. package/dist/types/DataTable/AuditTrailDialog.d.ts +6 -17
  233. package/dist/types/DataTable/ColumnFilters/HeaderFilterPopover.d.ts +6 -5
  234. package/dist/types/DataTable/ColumnFilters/MultiSelectColumnFilter.d.ts +6 -9
  235. package/dist/types/DataTable/ColumnFilters/SortableFilterHeader.d.ts +6 -14
  236. package/dist/types/DataTable/EmptyState.d.ts +6 -9
  237. package/dist/types/DataTable/FilterChips.d.ts +6 -11
  238. package/dist/types/DataTable/GoToPage.d.ts +6 -9
  239. package/dist/types/DataTable/ServerTable.d.ts +16 -80
  240. package/dist/types/DataTable/ServerTableFilterDrawer.d.ts +6 -13
  241. package/dist/types/DataTable/StackedCell.d.ts +12 -0
  242. package/dist/types/DataTable/TableCardsView.d.ts +27 -0
  243. package/dist/types/DataTable/columnWidths.d.ts +21 -0
  244. package/dist/types/DataTable/columns.d.ts +111 -0
  245. package/dist/types/DataTable/fixedColumns.d.ts +29 -0
  246. package/dist/types/DataTable/index.d.ts +6 -1
  247. package/dist/types/DataTable/useTableView.d.ts +22 -0
  248. package/dist/types/access/PermissionMatrix.d.ts +6 -10
  249. package/dist/types/account/AccountSecuritySection.d.ts +6 -7
  250. package/dist/types/account/DemoTotpCodeButton.d.ts +6 -5
  251. package/dist/types/account/ProfileScreen.d.ts +6 -18
  252. package/dist/types/account/SignInScreen.d.ts +6 -13
  253. package/dist/types/appShell/AccountMenu.d.ts +6 -11
  254. package/dist/types/appShell/AppLayout.d.ts +3 -40
  255. package/dist/types/appShell/AppearanceSettings.d.ts +6 -12
  256. package/dist/types/appShell/AuthLayout.d.ts +3 -11
  257. package/dist/types/appShell/BarActionButton.d.ts +7 -10
  258. package/dist/types/appShell/BarActions.d.ts +6 -15
  259. package/dist/types/appShell/BarCapsule.d.ts +6 -9
  260. package/dist/types/appShell/BarSearch.d.ts +6 -15
  261. package/dist/types/appShell/HeaderTools.d.ts +6 -16
  262. package/dist/types/appShell/MobileTabBar.d.ts +6 -13
  263. package/dist/types/appShell/SettingsMenu.d.ts +6 -10
  264. package/dist/types/appShell/SideMenu.d.ts +6 -20
  265. package/dist/types/appShell/SideMenuEntry.d.ts +6 -11
  266. package/dist/types/appShell/SubmenuActionsMenu.d.ts +6 -12
  267. package/dist/types/appShell/TabBarEditor.d.ts +6 -9
  268. package/dist/types/appShell/TopMenu.d.ts +6 -5
  269. package/dist/types/appShell/Wordmark.d.ts +6 -7
  270. package/dist/types/auth/PasswordChecklist.d.ts +6 -9
  271. package/dist/types/calendar/EventCalendar.d.ts +6 -23
  272. package/dist/types/calendar/EventDetails.d.ts +6 -10
  273. package/dist/types/datePickers/DateInput.d.ts +7 -22
  274. package/dist/types/datePickers/DateTimeInput.d.ts +7 -27
  275. package/dist/types/datePickers/MonthInput.d.ts +7 -21
  276. package/dist/types/datePickers/TimeInput.d.ts +7 -21
  277. package/dist/types/datePickers/usePickerField.d.ts +5 -1
  278. package/dist/types/downloads/DownloadManager.d.ts +6 -6
  279. package/dist/types/feedback/ConfirmDialog.d.ts +6 -18
  280. package/dist/types/feedback/ModalWaiting.d.ts +6 -9
  281. package/dist/types/feedback/NewBuildNotice.d.ts +6 -10
  282. package/dist/types/filepond/FileDropzone.d.ts +6 -29
  283. package/dist/types/forms/FormProblemAlert.d.ts +6 -5
  284. package/dist/types/forms/FormWizard.d.ts +12 -1
  285. package/dist/types/forms/SubmitButton.d.ts +6 -6
  286. package/dist/types/forms/auth/SignInForm.d.ts +6 -11
  287. package/dist/types/forms/fieldRules.d.ts +44 -0
  288. package/dist/types/forms/index.d.ts +1 -0
  289. package/dist/types/forms/security/SecondStepForm.d.ts +6 -14
  290. package/dist/types/forms/security/TwoStepVerificationCard.d.ts +6 -21
  291. package/dist/types/forms/useValidationText.d.ts +12 -0
  292. package/dist/types/forms/validation.d.ts +117 -174
  293. package/dist/types/forms/validationMessages.d.ts +54 -6
  294. package/dist/types/forms.d.ts +1 -1
  295. package/dist/types/hookForm/FormProblemAlert.d.ts +6 -5
  296. package/dist/types/hookForm/FormWizard.d.ts +12 -1
  297. package/dist/types/hookForm/SubmitButton.d.ts +6 -13
  298. package/dist/types/inbox/InboxLayout.d.ts +6 -17
  299. package/dist/types/inbox/MessageList.d.ts +6 -18
  300. package/dist/types/inbox/MessageView.d.ts +6 -14
  301. package/dist/types/index.d.ts +10 -2
  302. package/dist/types/inputs/CatalogInput.d.ts +7 -24
  303. package/dist/types/inputs/CheckboxGroupInput.d.ts +7 -18
  304. package/dist/types/inputs/ColorInput.d.ts +7 -16
  305. package/dist/types/inputs/FieldFrame.d.ts +6 -10
  306. package/dist/types/inputs/MaskedInput.d.ts +3 -0
  307. package/dist/types/inputs/NumberInput.d.ts +7 -20
  308. package/dist/types/inputs/RepeatingFields.d.ts +7 -28
  309. package/dist/types/inputs/SelectInput.d.ts +7 -20
  310. package/dist/types/inputs/TextInput.d.ts +3 -0
  311. package/dist/types/inputs/TransferListInput.d.ts +7 -20
  312. package/dist/types/inputs/WizardLayout.d.ts +11 -21
  313. package/dist/types/inputs/useWizardSteps.d.ts +23 -0
  314. package/dist/types/inputs/wizardSteps.d.ts +65 -0
  315. package/dist/types/kanban/KanbanBoard.d.ts +6 -25
  316. package/dist/types/legal/CookieNotice.d.ts +6 -16
  317. package/dist/types/legal/TermsAcceptanceDialog.d.ts +6 -18
  318. package/dist/types/locales/en.d.ts +24 -0
  319. package/dist/types/locales/es.d.ts +24 -0
  320. package/dist/types/maps/MapView.d.ts +6 -17
  321. package/dist/types/mexico/CfdiSummary.d.ts +6 -11
  322. package/dist/types/mexico/EfirmaFields.d.ts +6 -16
  323. package/dist/types/mexico/mexicoIdentifiers.d.ts +7 -0
  324. package/dist/types/mexico/mexicoRules.d.ts +19 -3
  325. package/dist/types/mexico.d.ts +2 -2
  326. package/dist/types/pwa/InstallAppSetting.d.ts +6 -6
  327. package/dist/types/pwa/InstallInstructionsDialog.d.ts +6 -9
  328. package/dist/types/pwa/InstallPromptBanner.d.ts +6 -11
  329. package/dist/types/react-hook-form.d.ts +1 -0
  330. package/dist/types/richText/RichTextEditor.d.ts +7 -22
  331. package/dist/types/richText/RichTextView.d.ts +6 -9
  332. package/dist/types/security/ActivityLog.d.ts +6 -9
  333. package/dist/types/security/RecoveryCodesDialog.d.ts +6 -11
  334. package/dist/types/security/SessionsCard.d.ts +6 -11
  335. package/dist/types/table.d.ts +3 -1
  336. package/dist/types/theme/themePieces.d.ts +55 -3
  337. package/dist/types/toolkit/ToolkitProvider.d.ts +13 -1
  338. package/dist/types/toolkit/browserNavigation.d.ts +7 -3
  339. package/dist/types/toolkit/combineTexts.d.ts +6 -0
  340. package/dist/types/toolkit/hashNavigation.d.ts +4 -2
  341. package/dist/types/toolkit/navigationPaths.d.ts +35 -0
  342. package/dist/types/toolkit/pathIndex.d.ts +27 -0
  343. package/dist/types/toolkit/toolkitSettings.d.ts +7 -4
  344. package/dist/types/ui/actions/ActionsMenu.d.ts +9 -11
  345. package/dist/types/ui/actions/CopyButton.d.ts +6 -12
  346. package/dist/types/ui/actions/DownloadMenu.d.ts +6 -29
  347. package/dist/types/ui/actions/SecretField.d.ts +6 -11
  348. package/dist/types/ui/actions/SelectionActions.d.ts +6 -13
  349. package/dist/types/ui/cards/RecordCard.d.ts +16 -29
  350. package/dist/types/ui/cards/RecordCardSkeleton.d.ts +6 -11
  351. package/dist/types/ui/countdown/Countdown.d.ts +6 -15
  352. package/dist/types/ui/documents/PdfViewerDialog.d.ts +6 -13
  353. package/dist/types/ui/filters/DateRangeFilter.d.ts +6 -10
  354. package/dist/types/ui/filters/FilterDrawer.d.ts +6 -17
  355. package/dist/types/ui/filters/PeriodRangeSelector.d.ts +6 -13
  356. package/dist/types/ui/filters/QuickFilters.d.ts +6 -12
  357. package/dist/types/ui/help/HelpButton.d.ts +6 -10
  358. package/dist/types/ui/help/HelpCarouselDialog.d.ts +6 -14
  359. package/dist/types/ui/index.d.ts +1 -1
  360. package/dist/types/ui/labels/MarkedText.d.ts +10 -0
  361. package/dist/types/ui/labels/Tag.d.ts +6 -12
  362. package/dist/types/ui/labels/markedTextPieces.d.ts +22 -0
  363. package/dist/types/ui/layout/CollapsibleSection.d.ts +6 -12
  364. package/dist/types/ui/layout/ContentDialog.d.ts +6 -10
  365. package/dist/types/ui/layout/DefinitionList.d.ts +6 -9
  366. package/dist/types/ui/layout/DetailHeader.d.ts +6 -10
  367. package/dist/types/ui/layout/ErrorPage.d.ts +6 -17
  368. package/dist/types/ui/layout/FullPageLoader.d.ts +6 -6
  369. package/dist/types/ui/layout/GlassPanel.d.ts +6 -8
  370. package/dist/types/ui/layout/PageHeader.d.ts +6 -10
  371. package/dist/types/ui/layout/PageHeading.d.ts +6 -11
  372. package/dist/types/ui/layout/ProfileHeader.d.ts +6 -11
  373. package/dist/types/ui/layout/ScrollableRow.d.ts +6 -13
  374. package/dist/types/ui/layout/SectionCard.d.ts +6 -8
  375. package/dist/types/ui/metrics/BarList.d.ts +6 -12
  376. package/dist/types/ui/metrics/CalendarHeatmap.d.ts +6 -19
  377. package/dist/types/ui/metrics/ChartTooltip.d.ts +6 -6
  378. package/dist/types/ui/metrics/ColumnChart.d.ts +6 -25
  379. package/dist/types/ui/metrics/LineChart.d.ts +6 -20
  380. package/dist/types/ui/metrics/MetricCard.d.ts +6 -17
  381. package/dist/types/ui/metrics/TableToggle.d.ts +6 -6
  382. package/dist/types/ui/metrics/chartParts.d.ts +15 -30
  383. package/dist/types/ui/navigation/BackButton.d.ts +7 -9
  384. package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +6 -9
  385. package/dist/types/ui/navigation/FontSizeToggle.d.ts +6 -8
  386. package/dist/types/ui/navigation/LanguageToggle.d.ts +6 -8
  387. package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +6 -7
  388. package/dist/types/ui/navigation/RouteTabs.d.ts +7 -12
  389. package/dist/types/ui/timeline/GroupedTimeline.d.ts +6 -23
  390. package/dist/types/upload/AttachmentsInput.d.ts +11 -1
  391. package/dist/types/upload/FileDropzone.d.ts +6 -21
  392. package/dist/types/upload/FileInput.d.ts +7 -24
  393. package/dist/types/upload/FileUploadInput.d.ts +7 -31
  394. package/dist/types/upload/ImageInput.d.ts +7 -25
  395. package/dist/types/upload/TemplateDownloadButton.d.ts +6 -18
  396. package/dist/ui/actions/ActionsMenu.js +14 -5
  397. package/dist/ui/actions/ActionsMenu.js.map +1 -1
  398. package/dist/ui/actions/CopyButton.js +8 -3
  399. package/dist/ui/actions/CopyButton.js.map +1 -1
  400. package/dist/ui/actions/DownloadMenu.js +3 -2
  401. package/dist/ui/actions/DownloadMenu.js.map +1 -1
  402. package/dist/ui/actions/SecretField.js +8 -3
  403. package/dist/ui/actions/SecretField.js.map +1 -1
  404. package/dist/ui/actions/SelectionActions.js +3 -2
  405. package/dist/ui/actions/SelectionActions.js.map +1 -1
  406. package/dist/ui/cards/RecordCard.js +10 -5
  407. package/dist/ui/cards/RecordCard.js.map +1 -1
  408. package/dist/ui/cards/RecordCardSkeleton.js +8 -3
  409. package/dist/ui/cards/RecordCardSkeleton.js.map +1 -1
  410. package/dist/ui/countdown/Countdown.js +3 -2
  411. package/dist/ui/countdown/Countdown.js.map +1 -1
  412. package/dist/ui/documents/PdfViewerDialog.js +3 -2
  413. package/dist/ui/documents/PdfViewerDialog.js.map +1 -1
  414. package/dist/ui/filters/DateRangeFilter.js +3 -2
  415. package/dist/ui/filters/DateRangeFilter.js.map +1 -1
  416. package/dist/ui/filters/FilterDrawer.js +3 -2
  417. package/dist/ui/filters/FilterDrawer.js.map +1 -1
  418. package/dist/ui/filters/PeriodRangeSelector.js +3 -2
  419. package/dist/ui/filters/PeriodRangeSelector.js.map +1 -1
  420. package/dist/ui/filters/QuickFilters.js +3 -2
  421. package/dist/ui/filters/QuickFilters.js.map +1 -1
  422. package/dist/ui/help/HelpButton.js +8 -3
  423. package/dist/ui/help/HelpButton.js.map +1 -1
  424. package/dist/ui/help/HelpCarouselDialog.js +3 -2
  425. package/dist/ui/help/HelpCarouselDialog.js.map +1 -1
  426. package/dist/ui/labels/MarkedText.js +31 -0
  427. package/dist/ui/labels/MarkedText.js.map +1 -0
  428. package/dist/ui/labels/Tag.js +3 -2
  429. package/dist/ui/labels/Tag.js.map +1 -1
  430. package/dist/ui/labels/markedTextPieces.js +64 -0
  431. package/dist/ui/labels/markedTextPieces.js.map +1 -0
  432. package/dist/ui/layout/CollapsibleSection.js +3 -2
  433. package/dist/ui/layout/CollapsibleSection.js.map +1 -1
  434. package/dist/ui/layout/ContentDialog.js +3 -2
  435. package/dist/ui/layout/ContentDialog.js.map +1 -1
  436. package/dist/ui/layout/DefinitionList.js +3 -2
  437. package/dist/ui/layout/DefinitionList.js.map +1 -1
  438. package/dist/ui/layout/DetailHeader.js +3 -2
  439. package/dist/ui/layout/DetailHeader.js.map +1 -1
  440. package/dist/ui/layout/ErrorPage.js +3 -2
  441. package/dist/ui/layout/ErrorPage.js.map +1 -1
  442. package/dist/ui/layout/FullPageLoader.js +3 -2
  443. package/dist/ui/layout/FullPageLoader.js.map +1 -1
  444. package/dist/ui/layout/GlassPanel.js +3 -2
  445. package/dist/ui/layout/GlassPanel.js.map +1 -1
  446. package/dist/ui/layout/PageHeader.js +3 -2
  447. package/dist/ui/layout/PageHeader.js.map +1 -1
  448. package/dist/ui/layout/PageHeading.js +3 -2
  449. package/dist/ui/layout/PageHeading.js.map +1 -1
  450. package/dist/ui/layout/ProfileHeader.js +3 -2
  451. package/dist/ui/layout/ProfileHeader.js.map +1 -1
  452. package/dist/ui/layout/ScrollableRow.js +3 -2
  453. package/dist/ui/layout/ScrollableRow.js.map +1 -1
  454. package/dist/ui/layout/SectionCard.js +3 -2
  455. package/dist/ui/layout/SectionCard.js.map +1 -1
  456. package/dist/ui/metrics/BarList.js +3 -2
  457. package/dist/ui/metrics/BarList.js.map +1 -1
  458. package/dist/ui/metrics/CalendarHeatmap.js +3 -2
  459. package/dist/ui/metrics/CalendarHeatmap.js.map +1 -1
  460. package/dist/ui/metrics/ChartTooltip.js +3 -2
  461. package/dist/ui/metrics/ChartTooltip.js.map +1 -1
  462. package/dist/ui/metrics/ColumnChart.js +3 -2
  463. package/dist/ui/metrics/ColumnChart.js.map +1 -1
  464. package/dist/ui/metrics/LineChart.js +3 -2
  465. package/dist/ui/metrics/LineChart.js.map +1 -1
  466. package/dist/ui/metrics/MetricCard.js +3 -2
  467. package/dist/ui/metrics/MetricCard.js.map +1 -1
  468. package/dist/ui/metrics/TableToggle.js +3 -2
  469. package/dist/ui/metrics/TableToggle.js.map +1 -1
  470. package/dist/ui/metrics/chartParts.js +7 -4
  471. package/dist/ui/metrics/chartParts.js.map +1 -1
  472. package/dist/ui/navigation/BackButton.js +7 -2
  473. package/dist/ui/navigation/BackButton.js.map +1 -1
  474. package/dist/ui/navigation/ColorSchemeToggle.js +3 -2
  475. package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -1
  476. package/dist/ui/navigation/FontSizeToggle.js +3 -2
  477. package/dist/ui/navigation/FontSizeToggle.js.map +1 -1
  478. package/dist/ui/navigation/LanguageToggle.js +3 -2
  479. package/dist/ui/navigation/LanguageToggle.js.map +1 -1
  480. package/dist/ui/navigation/PageBreadcrumbs.js +3 -2
  481. package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -1
  482. package/dist/ui/navigation/RouteTabs.js +8 -4
  483. package/dist/ui/navigation/RouteTabs.js.map +1 -1
  484. package/dist/ui/timeline/GroupedTimeline.js +3 -2
  485. package/dist/ui/timeline/GroupedTimeline.js.map +1 -1
  486. package/dist/upload/AttachmentsInput.js +9 -6
  487. package/dist/upload/AttachmentsInput.js.map +1 -1
  488. package/dist/upload/FileChip.js +2 -1
  489. package/dist/upload/FileChip.js.map +1 -1
  490. package/dist/upload/FileDropzone.js +5 -4
  491. package/dist/upload/FileDropzone.js.map +1 -1
  492. package/dist/upload/FileInput.js +9 -6
  493. package/dist/upload/FileInput.js.map +1 -1
  494. package/dist/upload/FileUploadInput.js +9 -6
  495. package/dist/upload/FileUploadInput.js.map +1 -1
  496. package/dist/upload/ImageInput.js +8 -5
  497. package/dist/upload/ImageInput.js.map +1 -1
  498. package/dist/upload/TemplateDownloadButton.js +3 -2
  499. package/dist/upload/TemplateDownloadButton.js.map +1 -1
  500. package/package.json +1 -1
  501. package/cli/templates/project/src/app/combineTexts.js.tpl +0 -31
@@ -5,24 +5,30 @@ import Box from "@mui/material/Box";
5
5
  import Button from "@mui/material/Button";
6
6
  import Stack from "@mui/material/Stack";
7
7
  import Step from "@mui/material/Step";
8
+ import StepButton from "@mui/material/StepButton";
9
+ import StepContent from "@mui/material/StepContent";
8
10
  import StepLabel from "@mui/material/StepLabel";
9
11
  import Stepper from "@mui/material/Stepper";
10
12
  import Typography from "@mui/material/Typography";
11
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
13
+ import { WIZARD_ORIENTATION, isStepCompleted } from "./wizardSteps.js";
14
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
12
15
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
16
+ const NO_SKIPPED_KEYS = /* @__PURE__ */ new Set();
13
17
  const THEME_NAME = "CalcitaWizardLayout";
14
18
  const WizardStepper = piecePart(THEME_NAME, "Stepper", Stepper);
15
19
  const WizardPhoneSteps = piecePart(THEME_NAME, "PhoneSteps", Box);
16
20
  const WizardActions = piecePart(THEME_NAME, "Actions", Stack);
17
- function WizardLayout(props) {
21
+ function WizardLayoutContent(props) {
18
22
  const {
19
23
  steps,
20
24
  activeIndex,
21
- skippedKeys,
25
+ skippedKeys = NO_SKIPPED_KEYS,
22
26
  isSubmitting = false,
27
+ orientation = WIZARD_ORIENTATION.horizontal,
23
28
  onBack,
24
29
  onNext,
25
30
  onSkip,
31
+ onStepSelect,
26
32
  submitButton,
27
33
  problemAlert,
28
34
  texts,
@@ -32,31 +38,54 @@ function WizardLayout(props) {
32
38
  const { t } = useToolkitTranslation("common", texts);
33
39
  const activeStep = steps[activeIndex];
34
40
  const isLastStep = activeIndex === steps.length - 1;
41
+ const isVertical = orientation === WIZARD_ORIENTATION.vertical;
42
+ const isSelectable = typeof onStepSelect === "function";
43
+ const stepTitleOf = (step, index) => {
44
+ let caption;
45
+ if (skippedKeys.has(step.key)) {
46
+ caption = t("wizard.skipped");
47
+ } else if (step.optional) {
48
+ caption = t("wizard.optional");
49
+ }
50
+ const optional = caption && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: caption });
51
+ if (isSelectable) {
52
+ return /* @__PURE__ */ jsx(StepButton, { optional, onClick: () => onStepSelect(index), children: step.label });
53
+ }
54
+ return /* @__PURE__ */ jsx(StepLabel, { optional, children: step.label });
55
+ };
56
+ const actions = /* @__PURE__ */ jsxs(WizardActions, { direction: { xs: "column-reverse", sm: "row" }, spacing: 1.5, ownSx: { justifyContent: "space-between" }, children: [
57
+ /* @__PURE__ */ jsx(Button, { variant: "text", color: "inherit", disabled: activeIndex === 0 || isSubmitting, onClick: onBack, children: t("wizard.back") }),
58
+ /* @__PURE__ */ jsxs(Stack, { direction: { xs: "column-reverse", sm: "row" }, spacing: 1.5, children: [
59
+ activeStep.optional && !isLastStep && onSkip && /* @__PURE__ */ jsx(Button, { variant: "text", onClick: onSkip, children: t("wizard.skip") }),
60
+ isLastStep ? submitButton : /* @__PURE__ */ jsx(Button, { variant: "contained", size: "large", onClick: onNext, children: t("wizard.next") })
61
+ ] })
62
+ ] });
63
+ const completedOf = (step, index) => isStepCompleted(step, { index, activeIndex, skippedKeys, isSelectable });
64
+ if (isVertical) {
65
+ return (
66
+ // nonLinear: con los títulos que se pulsan, MUI no debe apagar los pasos de adelante
67
+ /* @__PURE__ */ jsx(WizardStepper, { activeStep: activeIndex, orientation: "vertical", nonLinear: isSelectable, children: steps.map((step, index) => /* @__PURE__ */ jsxs(Step, { completed: completedOf(step, index), children: [
68
+ stepTitleOf(step, index),
69
+ /* @__PURE__ */ jsx(StepContent, { slotProps: { transition: { unmountOnExit: true } }, children: /* @__PURE__ */ jsxs(Stack, { spacing: 3, sx: { pt: 1 }, children: [
70
+ /* @__PURE__ */ jsx(Box, { children: step.content }),
71
+ index === activeIndex && isLastStep && problemAlert,
72
+ index === activeIndex && actions
73
+ ] }) })
74
+ ] }, step.key)) })
75
+ );
76
+ }
35
77
  return /* @__PURE__ */ jsxs(Stack, { spacing: 3, children: [
36
- /* @__PURE__ */ jsx(WizardStepper, { activeStep: activeIndex, alternativeLabel: true, ownSx: { display: { xs: "none", sm: "flex" } }, children: steps.map((step) => {
37
- let caption;
38
- if (skippedKeys.has(step.key)) {
39
- caption = t("wizard.skipped");
40
- } else if (step.optional) {
41
- caption = t("wizard.optional");
42
- }
43
- return /* @__PURE__ */ jsx(Step, { completed: skippedKeys.has(step.key) ? false : void 0, children: /* @__PURE__ */ jsx(StepLabel, { optional: caption && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: caption }), children: step.label }) }, step.key);
44
- }) }),
78
+ /* @__PURE__ */ jsx(WizardStepper, { activeStep: activeIndex, alternativeLabel: true, nonLinear: isSelectable, ownSx: { display: { xs: "none", sm: "flex" } }, children: steps.map((step, index) => /* @__PURE__ */ jsx(Step, { completed: completedOf(step, index), children: stepTitleOf(step, index) }, step.key)) }),
45
79
  /* @__PURE__ */ jsxs(WizardPhoneSteps, { ownSx: { display: { xs: "block", sm: "none" } }, children: [
46
80
  /* @__PURE__ */ jsx(Typography, { variant: "overline", color: "text.secondary", children: t("wizard.stepOf", { current: activeIndex + 1, total: steps.length }) }),
47
81
  /* @__PURE__ */ jsx(Typography, { variant: "h6", children: activeStep.label })
48
82
  ] }),
49
83
  /* @__PURE__ */ jsx(Box, { children: activeStep.content }),
50
84
  isLastStep && problemAlert,
51
- /* @__PURE__ */ jsxs(WizardActions, { direction: { xs: "column-reverse", sm: "row" }, spacing: 1.5, ownSx: { justifyContent: "space-between" }, children: [
52
- /* @__PURE__ */ jsx(Button, { variant: "text", color: "inherit", disabled: activeIndex === 0 || isSubmitting, onClick: onBack, children: t("wizard.back") }),
53
- /* @__PURE__ */ jsxs(Stack, { direction: { xs: "column-reverse", sm: "row" }, spacing: 1.5, children: [
54
- activeStep.optional && !isLastStep && /* @__PURE__ */ jsx(Button, { variant: "text", onClick: onSkip, children: t("wizard.skip") }),
55
- isLastStep ? submitButton : /* @__PURE__ */ jsx(Button, { variant: "contained", size: "large", onClick: onNext, children: t("wizard.next") })
56
- ] })
57
- ] })
85
+ actions
58
86
  ] });
59
87
  }
88
+ const WizardLayout = withPieceSlots(WizardLayoutContent, THEME_NAME);
60
89
  export {
61
90
  WizardLayout as default
62
91
  };
@@ -1 +1 @@
1
- {"version":3,"file":"WizardLayout.js","sources":["../../src/inputs/WizardLayout.jsx"],"sourcesContent":["// Lo que se ve de un formulario por pasos: los pasos arriba (en el teléfono, «Paso 2 de 4» y su nombre), los campos del paso\n// y los botones (Anterior · Omitir este paso · Siguiente o Enviar). No sabe de formik ni de react-hook-form: el FormWizard de\n// cada uno (/forms y /react-hook-form) pone la lógica (qué revisa «Siguiente», qué hace «Omitir») y le pasa su botón de\n// enviar y su aviso de errores. Suelto sirve para armar un asistente propio con otra librería.\n//\n// Los textos se cambian con `texts`, con la forma de `common` en los textos del paquete: {wizard: {next: 'Continuar'}}.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaWizardLayout con defaultProps y\n// styleOverrides de sus partes: stepper, phoneSteps, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Step from '@mui/material/Step';\nimport StepLabel from '@mui/material/StepLabel';\nimport Stepper from '@mui/material/Stepper';\nimport Typography from '@mui/material/Typography';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaWizardLayout)\nconst THEME_NAME = 'CalcitaWizardLayout';\nconst WizardStepper = piecePart(THEME_NAME, 'Stepper', Stepper);\nconst WizardPhoneSteps = piecePart(THEME_NAME, 'PhoneSteps', Box);\nconst WizardActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/**\n * @param {object} props\n * @param {Object[]} props.steps en orden\n * @param {string} props.steps[].key\n * @param {string} props.steps[].label ya traducido\n * @param {boolean} [props.steps[].optional] se puede omitir\n * @param {import('react').ReactNode} props.steps[].content los campos del paso\n * @param {number} props.activeIndex el paso que se ve\n * @param {Set<string>} props.skippedKeys los pasos omitidos\n * @param {boolean} [props.isSubmitting] mientras se envía, «Anterior» se apaga\n * @param {() => void} props.onBack\n * @param {() => void} props.onNext\n * @param {() => void} props.onSkip\n * @param {import('react').ReactNode} props.submitButton el botón de enviar del último paso\n * @param {import('react').ReactNode} [props.problemAlert] el aviso de errores del servidor, arriba de los botones del último paso\n * @param {object} [props.texts] los textos que cambian, con la forma de `common`: {wizard: {next, back, skip, optional, skipped, stepOf}}\n */\nexport default function WizardLayout(props) {\n // lo que el proyecto puso en su tema (components.CalcitaWizardLayout.defaultProps) y encima lo que llega aquí\n const {\n steps, activeIndex, skippedKeys, isSubmitting = false, onBack, onNext, onSkip, submitButton, problemAlert, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const activeStep = steps[activeIndex];\n const isLastStep = activeIndex === steps.length - 1;\n\n return (\n <Stack spacing={3}>\n {/* en el teléfono los nombres de los pasos no caben: se dice en qué paso va */}\n <WizardStepper activeStep={activeIndex} alternativeLabel ownSx={{display: {xs: 'none', sm: 'flex'}}}>\n {steps.map((step) => {\n let caption;\n if (skippedKeys.has(step.key)) {\n caption = t('wizard.skipped');\n } else if (step.optional) {\n caption = t('wizard.optional');\n }\n return (\n <Step key={step.key} completed={skippedKeys.has(step.key) ? false : undefined}>\n <StepLabel optional={caption && <Typography variant=\"caption\" color=\"text.secondary\">{caption}</Typography>}>\n {step.label}\n </StepLabel>\n </Step>\n );\n })}\n </WizardStepper>\n <WizardPhoneSteps ownSx={{display: {xs: 'block', sm: 'none'}}}>\n <Typography variant=\"overline\" color=\"text.secondary\">{t('wizard.stepOf', {current: activeIndex + 1, total: steps.length})}</Typography>\n <Typography variant=\"h6\">{activeStep.label}</Typography>\n </WizardPhoneSteps>\n\n <Box>{activeStep.content}</Box>\n\n {isLastStep && problemAlert}\n\n <WizardActions direction={{xs: 'column-reverse', sm: 'row'}} spacing={1.5} ownSx={{justifyContent: 'space-between'}}>\n <Button variant=\"text\" color=\"inherit\" disabled={activeIndex === 0 || isSubmitting} onClick={onBack}>\n {t('wizard.back')}\n </Button>\n <Stack direction={{xs: 'column-reverse', sm: 'row'}} spacing={1.5}>\n {activeStep.optional && !isLastStep && (\n <Button variant=\"text\" onClick={onSkip}>{t('wizard.skip')}</Button>\n )}\n {isLastStep\n ? submitButton\n : <Button variant=\"contained\" size=\"large\" onClick={onNext}>{t('wizard.next')}</Button>}\n </Stack>\n </WizardActions>\n </Stack>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAuBA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,WAAW,OAAO;AAC9D,MAAM,mBAAmB,UAAU,YAAY,cAAc,GAAG;AAChE,MAAM,gBAAgB,UAAU,YAAY,WAAW,KAAK;AAmB5D,SAAwB,aAAa,OAAO;AAExC,QAAM;AAAA,IACN;AAAA,IAAO;AAAA,IAAa;AAAA,IAAa,eAAe;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAc;AAAA,IAAc;AAAA,IAC3G,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AAC/B,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,aAAa,MAAM,WAAW;AACpC,QAAM,aAAa,gBAAgB,MAAM,SAAS;AAElD,SACI,qBAAC,OAAA,EAAM,SAAS,GAEZ,UAAA;AAAA,IAAA,oBAAC,iBAAc,YAAY,aAAa,kBAAgB,MAAC,OAAO,EAAC,SAAS,EAAC,IAAI,QAAQ,IAAI,OAAA,EAAM,GAC5F,UAAA,MAAM,IAAI,CAAC,SAAS;AACjB,UAAI;AACJ,UAAI,YAAY,IAAI,KAAK,GAAG,GAAG;AAC3B,kBAAU,EAAE,gBAAgB;AAAA,MAChC,WAAW,KAAK,UAAU;AACtB,kBAAU,EAAE,iBAAiB;AAAA,MACjC;AACA,aACI,oBAAC,MAAA,EAAoB,WAAW,YAAY,IAAI,KAAK,GAAG,IAAI,QAAQ,QAChE,UAAA,oBAAC,WAAA,EAAU,UAAU,WAAW,oBAAC,YAAA,EAAW,SAAQ,WAAU,OAAM,kBAAkB,UAAA,QAAA,CAAQ,GACzF,UAAA,KAAK,MAAA,CACV,EAAA,GAHO,KAAK,GAIhB;AAAA,IAER,CAAC,EAAA,CACL;AAAA,IACA,qBAAC,kBAAA,EAAiB,OAAO,EAAC,SAAS,EAAC,IAAI,SAAS,IAAI,OAAA,EAAM,GACvD,UAAA;AAAA,MAAA,oBAAC,YAAA,EAAW,SAAQ,YAAW,OAAM,kBAAkB,UAAA,EAAE,iBAAiB,EAAC,SAAS,cAAc,GAAG,OAAO,MAAM,OAAA,CAAO,GAAE;AAAA,MAC3H,oBAAC,YAAA,EAAW,SAAQ,MAAM,qBAAW,MAAA,CAAM;AAAA,IAAA,GAC/C;AAAA,IAEA,oBAAC,KAAA,EAAK,UAAA,WAAW,QAAA,CAAQ;AAAA,IAExB,cAAc;AAAA,IAEf,qBAAC,eAAA,EAAc,WAAW,EAAC,IAAI,kBAAkB,IAAI,MAAA,GAAQ,SAAS,KAAK,OAAO,EAAC,gBAAgB,mBAC/F,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAO,SAAQ,QAAO,OAAM,WAAU,UAAU,gBAAgB,KAAK,cAAc,SAAS,QACxF,UAAA,EAAE,aAAa,GACpB;AAAA,MACA,qBAAC,OAAA,EAAM,WAAW,EAAC,IAAI,kBAAkB,IAAI,MAAA,GAAQ,SAAS,KACzD,UAAA;AAAA,QAAA,WAAW,YAAY,CAAC,cACrB,oBAAC,QAAA,EAAO,SAAQ,QAAO,SAAS,QAAS,UAAA,EAAE,aAAa,EAAA,CAAE;AAAA,QAE7D,aACK,eACA,oBAAC,QAAA,EAAO,SAAQ,aAAY,MAAK,SAAQ,SAAS,QAAS,UAAA,EAAE,aAAa,EAAA,CAAE;AAAA,MAAA,EAAA,CACtF;AAAA,IAAA,EAAA,CACJ;AAAA,EAAA,GACJ;AAER;"}
1
+ {"version":3,"file":"WizardLayout.js","sources":["../../src/inputs/WizardLayout.jsx"],"sourcesContent":["// Lo que se ve de un formulario por pasos: los pasos, los campos del paso abierto y los botones (Anterior · Omitir este paso ·\n// Siguiente o Enviar). No sabe de formik ni de react-hook-form: el FormWizard de cada uno (/forms y /react-hook-form) pone la\n// lógica (qué revisa «Siguiente», qué hace «Omitir», si se puede saltar a otro paso) y le pasa su botón de enviar y su aviso de\n// errores. Suelto sirve para armar un asistente propio con otra librería.\n//\n// Dos acomodos (WIZARD_ORIENTATION):\n// horizontal los pasos en fila arriba y los campos abajo; en el teléfono no caben los nombres: «Paso 2 de 4» y su nombre;\n// vertical uno debajo del otro, como un acordeón: los campos y los botones van dentro del paso abierto (también en el\n// teléfono). Es el de editar un expediente: se ve de un vistazo qué pasos hay y se entra al que hace falta.\n//\n// Con onStepSelect los títulos de los pasos se pulsan (con teclado también: son botones) y avisan qué paso se pidió; quien lo\n// usa decide si salta. Sin él, los títulos solo informan (lo de siempre). Omitir es opcional: sin onSkip no sale el botón.\n//\n// Los textos se cambian con `texts`, con la forma de `common` en los textos del paquete: {wizard: {next: 'Continuar'}}.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaWizardLayout con defaultProps y\n// styleOverrides de sus partes: stepper, phoneSteps, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Step from '@mui/material/Step';\nimport StepButton from '@mui/material/StepButton';\nimport StepContent from '@mui/material/StepContent';\nimport StepLabel from '@mui/material/StepLabel';\nimport Stepper from '@mui/material/Stepper';\nimport Typography from '@mui/material/Typography';\nimport {WIZARD_ORIENTATION, isStepCompleted} from '@/inputs/wizardSteps.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// sin pasos omitidos (quien no usa «Omitir» no tiene que mandar nada)\nconst NO_SKIPPED_KEYS = new Set();\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaWizardLayout)\nconst THEME_NAME = 'CalcitaWizardLayout';\nconst WizardStepper = piecePart(THEME_NAME, 'Stepper', Stepper);\nconst WizardPhoneSteps = piecePart(THEME_NAME, 'PhoneSteps', Box);\nconst WizardActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/**\n * @param {object} props\n * @param {Object[]} props.steps en orden\n * @param {string} props.steps[].key\n * @param {string} props.steps[].label ya traducido\n * @param {boolean} [props.steps[].optional] se puede omitir\n * @param {boolean} [props.steps[].completed] lleva la palomita; por omisión, en fila y sin pulsar, los de antes del abierto\n * @param {import('react').ReactNode} props.steps[].content los campos del paso\n * @param {number} props.activeIndex el paso que se ve\n * @param {Set<string>} [props.skippedKeys] los pasos omitidos\n * @param {boolean} [props.isSubmitting] mientras se envía, «Anterior» se apaga\n * @param {'horizontal'|'vertical'} [props.orientation] uno de WIZARD_ORIENTATION; por omisión horizontal\n * @param {() => void} props.onBack\n * @param {() => void} props.onNext\n * @param {() => void} [props.onSkip] sin él no sale «Omitir este paso»\n * @param {(index: number) => void} [props.onStepSelect] con él, los títulos de los pasos se pulsan y avisan cuál se pidió\n * @param {import('react').ReactNode} props.submitButton el botón de enviar del último paso\n * @param {import('react').ReactNode} [props.problemAlert] el aviso de errores del servidor, arriba de los botones del último paso\n * @param {object} [props.texts] los textos que cambian, con la forma de `common`: {wizard: {next, back, skip, optional, skipped, stepOf}}\n */\nfunction WizardLayoutContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaWizardLayout.defaultProps) y encima lo que llega aquí\n const {\n steps, activeIndex, skippedKeys = NO_SKIPPED_KEYS, isSubmitting = false, orientation = WIZARD_ORIENTATION.horizontal,\n onBack, onNext, onSkip, onStepSelect, submitButton, problemAlert, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const activeStep = steps[activeIndex];\n const isLastStep = activeIndex === steps.length - 1;\n const isVertical = orientation === WIZARD_ORIENTATION.vertical;\n const isSelectable = typeof onStepSelect === 'function';\n\n // el título de un paso: con onStepSelect es un botón (se pulsa y se llega con Tab); sin él, solo informa\n const stepTitleOf = (step, index) => {\n let caption;\n if (skippedKeys.has(step.key)) {\n caption = t('wizard.skipped');\n } else if (step.optional) {\n caption = t('wizard.optional');\n }\n const optional = caption && <Typography variant=\"caption\" color=\"text.secondary\">{caption}</Typography>;\n if (isSelectable) {\n return <StepButton optional={optional} onClick={() => onStepSelect(index)}>{step.label}</StepButton>;\n }\n return <StepLabel optional={optional}>{step.label}</StepLabel>;\n };\n\n // los botones del paso abierto: en fila van abajo de los campos; en vertical, dentro del paso\n const actions = (\n <WizardActions direction={{xs: 'column-reverse', sm: 'row'}} spacing={1.5} ownSx={{justifyContent: 'space-between'}}>\n <Button variant=\"text\" color=\"inherit\" disabled={activeIndex === 0 || isSubmitting} onClick={onBack}>\n {t('wizard.back')}\n </Button>\n <Stack direction={{xs: 'column-reverse', sm: 'row'}} spacing={1.5}>\n {activeStep.optional && !isLastStep && onSkip && (\n <Button variant=\"text\" onClick={onSkip}>{t('wizard.skip')}</Button>\n )}\n {isLastStep\n ? submitButton\n : <Button variant=\"contained\" size=\"large\" onClick={onNext}>{t('wizard.next')}</Button>}\n </Stack>\n </WizardActions>\n );\n const completedOf = (step, index) => isStepCompleted(step, {index, activeIndex, skippedKeys, isSelectable});\n\n if (isVertical) {\n return (\n // nonLinear: con los títulos que se pulsan, MUI no debe apagar los pasos de adelante\n <WizardStepper activeStep={activeIndex} orientation=\"vertical\" nonLinear={isSelectable}>\n {steps.map((step, index) => (\n <Step key={step.key} completed={completedOf(step, index)}>\n {stepTitleOf(step, index)}\n {/* solo el paso abierto tiene sus campos montados: al cerrarse se desmontan (unmountOnExit). Los botones\n van solo en el abierto: el que se cierra (la animación dura un momento) ya no es el paso de esos\n botones, y un «Guardar» repetido confunde */}\n <StepContent slotProps={{transition: {unmountOnExit: true}}}>\n <Stack spacing={3} sx={{pt: 1}}>\n <Box>{step.content}</Box>\n {index === activeIndex && isLastStep && problemAlert}\n {index === activeIndex && actions}\n </Stack>\n </StepContent>\n </Step>\n ))}\n </WizardStepper>\n );\n }\n\n return (\n <Stack spacing={3}>\n {/* en el teléfono los nombres de los pasos no caben: se dice en qué paso va */}\n <WizardStepper activeStep={activeIndex} alternativeLabel nonLinear={isSelectable} ownSx={{display: {xs: 'none', sm: 'flex'}}}>\n {steps.map((step, index) => (\n <Step key={step.key} completed={completedOf(step, index)}>\n {stepTitleOf(step, index)}\n </Step>\n ))}\n </WizardStepper>\n <WizardPhoneSteps ownSx={{display: {xs: 'block', sm: 'none'}}}>\n <Typography variant=\"overline\" color=\"text.secondary\">{t('wizard.stepOf', {current: activeIndex + 1, total: steps.length})}</Typography>\n <Typography variant=\"h6\">{activeStep.label}</Typography>\n </WizardPhoneSteps>\n\n <Box>{activeStep.content}</Box>\n\n {isLastStep && problemAlert}\n\n {actions}\n </Stack>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst WizardLayout = withPieceSlots(WizardLayoutContent, THEME_NAME);\nexport default WizardLayout;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { useState, useRef, useEffect } from "react";
3
+ import { openingStepOf, WIZARD_STEP_SELECTION, stepSelectionActionOf } from "./wizardSteps.js";
4
+ import { createLogger } from "../observability/logger.js";
5
+ const logger = createLogger("FormWizard");
6
+ function useWizardSteps({ steps, initialStepKey, stepSelection = WIZARD_STEP_SELECTION.none, onStepChange, isStepValid }) {
7
+ const [opening] = useState(() => openingStepOf(steps, initialStepKey));
8
+ const [activeIndex, setActiveIndex] = useState(opening.index);
9
+ const announcedIndex = useRef(opening.index);
10
+ useEffect(() => {
11
+ if (opening.isUnknownKey) {
12
+ logger.warn(`initialStepKey «${initialStepKey}» no es de ningún paso: se abrió el primero`, { stepKeys: steps.map((step) => step.key) });
13
+ }
14
+ }, []);
15
+ useEffect(() => {
16
+ if (announcedIndex.current !== activeIndex) {
17
+ announcedIndex.current = activeIndex;
18
+ onStepChange?.(steps[activeIndex].key, activeIndex);
19
+ }
20
+ }, [activeIndex, onStepChange, steps]);
21
+ const selectStep = async (index) => {
22
+ const action = stepSelectionActionOf(stepSelection, activeIndex, index);
23
+ if (action === "ignore") {
24
+ return;
25
+ }
26
+ if (action === "checkFirst" && !await isStepValid(activeIndex)) {
27
+ return;
28
+ }
29
+ setActiveIndex(index);
30
+ };
31
+ return { activeIndex, setActiveIndex, selectStep: stepSelection === WIZARD_STEP_SELECTION.none ? void 0 : selectStep };
32
+ }
33
+ export {
34
+ useWizardSteps
35
+ };
36
+ //# sourceMappingURL=useWizardSteps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWizardSteps.js","sources":["../../src/inputs/useWizardSteps.js"],"sourcesContent":["// Lo que los dos FormWizard (formik y react-hook-form) hacen igual con el paso abierto: en qué paso empieza, avisar hacia\n// afuera cada vez que cambia y qué pasa al pulsar el título de otro paso. Lo de cada librería (cómo se revisa un paso) llega\n// en isStepValid.\n//\n// Hook genérico: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\n\nimport {WIZARD_STEP_SELECTION, openingStepOf, stepSelectionActionOf} from '@/inputs/wizardSteps.js';\nimport {createLogger} from '@/observability/logger.js';\n\nconst logger = createLogger('FormWizard');\n\n/**\n * @param {object} options\n * @param {Array<{key: string}>} options.steps\n * @param {string} [options.initialStepKey] el paso en el que se abre (el que diga el servidor); por omisión el primero\n * @param {string} [options.stepSelection] uno de WIZARD_STEP_SELECTION; por omisión none\n * @param {(stepKey: string, index: number) => void} [options.onStepChange] cada vez que cambia el paso abierto\n * @param {(index: number) => Promise<boolean>} options.isStepValid revisa los campos de ese paso y marca sus errores\n * @returns {{activeIndex: number, setActiveIndex: import('react').Dispatch<import('react').SetStateAction<number>>, selectStep: ((index: number) => Promise<void>)|undefined}}\n * selectStep es undefined con none: así WizardLayout sabe que los títulos no se pulsan\n */\nexport function useWizardSteps({steps, initialStepKey, stepSelection = WIZARD_STEP_SELECTION.none, onStepChange, isStepValid}) {\n const [opening] = useState(() => openingStepOf(steps, initialStepKey));\n const [activeIndex, setActiveIndex] = useState(opening.index);\n const announcedIndex = useRef(opening.index);\n\n // una llave que no es de ningún paso no tumba la pantalla: se abre el primero y se dice\n useEffect(() => {\n if (opening.isUnknownKey) {\n logger.warn(`initialStepKey «${initialStepKey}» no es de ningún paso: se abrió el primero`, {stepKeys: steps.map((step) => step.key)});\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // hacia afuera, solo cuando de veras cambia (no al abrir): la pantalla puede guardar el paso en la dirección\n useEffect(() => {\n if (announcedIndex.current !== activeIndex) {\n announcedIndex.current = activeIndex;\n onStepChange?.(steps[activeIndex].key, activeIndex);\n }\n }, [activeIndex, onStepChange, steps]);\n\n const selectStep = async (index) => {\n const action = stepSelectionActionOf(stepSelection, activeIndex, index);\n if (action === 'ignore') {\n return;\n }\n // con checked, un paso con errores no se deja: se queda ahí para que se corrijan\n if (action === 'checkFirst' && !(await isStepValid(activeIndex))) {\n return;\n }\n setActiveIndex(index);\n };\n\n return {activeIndex, setActiveIndex, selectStep: stepSelection === WIZARD_STEP_SELECTION.none ? undefined : selectStep};\n}\n"],"names":[],"mappings":";;;;AAUA,MAAM,SAAS,aAAa,YAAY;AAYjC,SAAS,eAAe,EAAC,OAAO,gBAAgB,gBAAgB,sBAAsB,MAAM,cAAc,YAAW,GAAG;AAC3H,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM,cAAc,OAAO,cAAc,CAAC;AACrE,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,QAAQ,KAAK;AAC5D,QAAM,iBAAiB,OAAO,QAAQ,KAAK;AAG3C,YAAU,MAAM;AACZ,QAAI,QAAQ,cAAc;AACtB,aAAO,KAAK,mBAAmB,cAAc,+CAA+C,EAAC,UAAU,MAAM,IAAI,CAAC,SAAS,KAAK,GAAG,EAAC,CAAC;AAAA,IACzI;AAAA,EAEJ,GAAG,CAAA,CAAE;AAGL,YAAU,MAAM;AACZ,QAAI,eAAe,YAAY,aAAa;AACxC,qBAAe,UAAU;AACzB,qBAAe,MAAM,WAAW,EAAE,KAAK,WAAW;AAAA,IACtD;AAAA,EACJ,GAAG,CAAC,aAAa,cAAc,KAAK,CAAC;AAErC,QAAM,aAAa,OAAO,UAAU;AAChC,UAAM,SAAS,sBAAsB,eAAe,aAAa,KAAK;AACtE,QAAI,WAAW,UAAU;AACrB;AAAA,IACJ;AAEA,QAAI,WAAW,gBAAgB,CAAE,MAAM,YAAY,WAAW,GAAI;AAC9D;AAAA,IACJ;AACA,mBAAe,KAAK;AAAA,EACxB;AAEA,SAAO,EAAC,aAAa,gBAAgB,YAAY,kBAAkB,sBAAsB,OAAO,SAAY,WAAU;AAC1H;"}
@@ -0,0 +1,32 @@
1
+ const WIZARD_ORIENTATION = Object.freeze({ horizontal: "horizontal", vertical: "vertical" });
2
+ const WIZARD_STEP_SELECTION = Object.freeze({ none: "none", free: "free", checked: "checked" });
3
+ function openingStepOf(steps, stepKey) {
4
+ if (stepKey === void 0 || stepKey === null) {
5
+ return { index: 0, isUnknownKey: false };
6
+ }
7
+ const index = steps.findIndex((step) => step.key === stepKey);
8
+ return index >= 0 ? { index, isUnknownKey: false } : { index: 0, isUnknownKey: true };
9
+ }
10
+ function stepSelectionActionOf(stepSelection, activeIndex, targetIndex) {
11
+ if (stepSelection === WIZARD_STEP_SELECTION.none || targetIndex === activeIndex) {
12
+ return "ignore";
13
+ }
14
+ return stepSelection === WIZARD_STEP_SELECTION.checked ? "checkFirst" : "jump";
15
+ }
16
+ function isStepCompleted(step, { index, activeIndex, skippedKeys, isSelectable }) {
17
+ if (typeof step.completed === "boolean") {
18
+ return step.completed;
19
+ }
20
+ if (isSelectable || skippedKeys.has(step.key)) {
21
+ return false;
22
+ }
23
+ return index < activeIndex;
24
+ }
25
+ export {
26
+ WIZARD_ORIENTATION,
27
+ WIZARD_STEP_SELECTION,
28
+ isStepCompleted,
29
+ openingStepOf,
30
+ stepSelectionActionOf
31
+ };
32
+ //# sourceMappingURL=wizardSteps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizardSteps.js","sources":["../../src/inputs/wizardSteps.js"],"sourcesContent":["// Las reglas del formulario por pasos que no dependen de formik, de react-hook-form ni de React: cómo se acomodan los pasos,\n// qué pasa al pulsar el título de otro paso y en qué paso se abre. Las usan WizardLayout y los dos FormWizard.\n//\n// Por qué existen: editar un registro de varios pasos (un expediente, un perfil) casi nunca es recorrerlos todos; se entra a\n// corregir un dato suelto y el servidor dice en qué paso está. Con «Siguiente» como único camino, eso es el camino largo.\n//\n// Funciones puras, sin React: function (regla de la casa). Pruebas en wizardSteps.test.js.\n\n/**\n * Cómo se acomodan los pasos:\n * horizontal los pasos en fila arriba y los campos abajo (lo de siempre; en el teléfono, «Paso 2 de 4» y su nombre);\n * vertical uno debajo del otro, como un acordeón: los campos y los botones van dentro del paso que está abierto.\n */\nexport const WIZARD_ORIENTATION = Object.freeze({horizontal: 'horizontal', vertical: 'vertical'});\n\n/**\n * Qué pasa al pulsar el título de otro paso:\n * none los títulos no se pulsan (lo de siempre): se avanza con «Siguiente»;\n * free salta directo, sin revisar el paso en el que está; al enviar, el formulario regresa al primer paso con error;\n * checked salta solo si el paso en el que está no tiene errores (igual que «Siguiente»).\n */\nexport const WIZARD_STEP_SELECTION = Object.freeze({none: 'none', free: 'free', checked: 'checked'});\n\n/**\n * El paso en el que se abre: el de esa llave (la que dice el servidor) o el primero si no llega.\n *\n * @param {Array<{key: string}>} steps\n * @param {string} [stepKey]\n * @returns {{index: number, isUnknownKey: boolean}} isUnknownKey: llegó una llave que no es de ningún paso (se abre el primero)\n */\nexport function openingStepOf(steps, stepKey) {\n if (stepKey === undefined || stepKey === null) {\n return {index: 0, isUnknownKey: false};\n }\n const index = steps.findIndex((step) => step.key === stepKey);\n return index >= 0 ? {index, isUnknownKey: false} : {index: 0, isUnknownKey: true};\n}\n\n/**\n * ¿Al pulsar el título del paso `targetIndex` hay que revisar antes el paso en el que está? Solo con `checked` y si de veras\n * cambia de paso. Pulsar el paso en el que ya está no hace nada.\n *\n * @param {string} stepSelection uno de WIZARD_STEP_SELECTION\n * @param {number} activeIndex\n * @param {number} targetIndex\n * @returns {'ignore'|'jump'|'checkFirst'}\n */\nexport function stepSelectionActionOf(stepSelection, activeIndex, targetIndex) {\n if (stepSelection === WIZARD_STEP_SELECTION.none || targetIndex === activeIndex) {\n return 'ignore';\n }\n return stepSelection === WIZARD_STEP_SELECTION.checked ? 'checkFirst' : 'jump';\n}\n\n/**\n * ¿El paso se pinta como hecho (la palomita)? En fila y sin pulsar, los de antes del que está abierto, salvo los omitidos\n * (lo de siempre). Cuando los títulos se pulsan, «antes» ya no quiere decir «hecho» (se pudo brincar): sin palomita, salvo\n * que la pantalla lo diga en `steps[].completed` (sabe qué datos ya están completos).\n *\n * @param {{key: string, completed?: boolean}} step\n * @param {object} place\n * @param {number} place.index\n * @param {number} place.activeIndex\n * @param {Set<string>} place.skippedKeys\n * @param {boolean} place.isSelectable\n * @returns {boolean}\n */\nexport function isStepCompleted(step, {index, activeIndex, skippedKeys, isSelectable}) {\n if (typeof step.completed === 'boolean') {\n return step.completed;\n }\n if (isSelectable || skippedKeys.has(step.key)) {\n return false;\n }\n return index < activeIndex;\n}\n"],"names":[],"mappings":"AAaY,MAAC,qBAAqB,OAAO,OAAO,EAAC,YAAY,cAAc,UAAU,WAAU,CAAC;AAQpF,MAAC,wBAAwB,OAAO,OAAO,EAAC,MAAM,QAAQ,MAAM,QAAQ,SAAS,UAAS,CAAC;AAS5F,SAAS,cAAc,OAAO,SAAS;AAC1C,MAAI,YAAY,UAAa,YAAY,MAAM;AAC3C,WAAO,EAAC,OAAO,GAAG,cAAc,MAAK;AAAA,EACzC;AACA,QAAM,QAAQ,MAAM,UAAU,CAAC,SAAS,KAAK,QAAQ,OAAO;AAC5D,SAAO,SAAS,IAAI,EAAC,OAAO,cAAc,MAAK,IAAI,EAAC,OAAO,GAAG,cAAc,KAAI;AACpF;AAWO,SAAS,sBAAsB,eAAe,aAAa,aAAa;AAC3E,MAAI,kBAAkB,sBAAsB,QAAQ,gBAAgB,aAAa;AAC7E,WAAO;AAAA,EACX;AACA,SAAO,kBAAkB,sBAAsB,UAAU,eAAe;AAC5E;AAeO,SAAS,gBAAgB,MAAM,EAAC,OAAO,aAAa,aAAa,aAAY,GAAG;AACnF,MAAI,OAAO,KAAK,cAAc,WAAW;AACrC,WAAO,KAAK;AAAA,EAChB;AACA,MAAI,gBAAgB,YAAY,IAAI,KAAK,GAAG,GAAG;AAC3C,WAAO;AAAA,EACX;AACA,SAAO,QAAQ;AACnB;"}
@@ -27,7 +27,7 @@ import { DUE_STATUS, todayIsoDateOf, dueStatusOf } from "./kanbanCards.js";
27
27
  import { cardsOfColumn, isOverLimit } from "./kanbanMoves.js";
28
28
  import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
29
29
  import ActionsMenu from "../ui/actions/ActionsMenu.js";
30
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
30
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
31
31
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
32
32
  import { tagOf } from "../ui/labels/tagOf.js";
33
33
  const THEME_NAME = "CalcitaKanbanBoard";
@@ -180,7 +180,7 @@ function QuickAdd({ columnTitle, onAdd, onClose, t }) {
180
180
  }
181
181
  );
182
182
  }
183
- function KanbanBoard(props) {
183
+ function KanbanBoardContent(props) {
184
184
  const {
185
185
  columns,
186
186
  cards,
@@ -367,6 +367,7 @@ function KanbanBoard(props) {
367
367
  );
368
368
  }) }) });
369
369
  }
370
+ const KanbanBoard = withPieceSlots(KanbanBoardContent, THEME_NAME);
370
371
  export {
371
372
  KanbanBoard as default
372
373
  };
@@ -1 +1 @@
1
- {"version":3,"file":"KanbanBoard.js","sources":["../../src/kanban/KanbanBoard.jsx"],"sourcesContent":["// Un tablero kanban (@stackcraftmx/calcita/kanban): columnas con tarjetas que se arrastran de una a otra con el ratón, con el\n// dedo o con el teclado (espacio para levantar, flechas para mover, espacio para soltar). Con @hello-pangea/dnd por dentro.\n//\n// <KanbanBoard columns={[{id: 'todo', title: 'Por hacer'}, {id: 'doing', title: 'En proceso', limit: 3}]}\n// cards={cards} onMove={(move) => api.post('/tasks/move', move)} ariaLabel=\"Tablero de tareas\" />\n//\n// El tablero no guarda nada: avisa la movida (onMove) y quien lo usa actualiza sus tarjetas (moveCard de kanbanMoves.js lo\n// hace sin esperar al servidor). Una columna con tope (limit, el trabajo en curso) avisa en ámbar cuando lo pasa.\n//\n// Accesible: el lector de pantalla anuncia en el idioma de la app qué se levantó, a dónde va y dónde quedó.\n//\n// Lo de un producto, todo hacia afuera (el tablero no guarda nada ni llama a ningún servidor):\n// - la tarjeta por omisión pinta lo que traiga: etiquetas (texto o {label, color}), responsables con su monograma, la\n// fecha límite (roja si ya venció, ámbar si es hoy), el avance de su lista de pendientes, comentarios y adjuntos. Para\n// otra tarjeta: renderCard;\n// - «+» en cada columna para agregar escribiendo el título (onAddCard({columnId, title}));\n// - «⋯» en cada tarjeta y en cada columna con las acciones que dé la pantalla (cardActions, columnActions): editar,\n// asignarme, mover sin arrastrar, borrar…;\n// - terminar una tarea: con onCardComplete cada tarjeta lleva su círculo para marcarla (y desmarcarla); qué pasa al\n// terminarla (pasarla a «Listo», guardar la fecha) lo decide la pantalla. Una tarjeta con completed: true sale con su\n// palomita verde y su fecha límite ya no se pinta de rojo;\n// - columnas que se encogen (collapsible), como el congelador (icebox) de ideas para después: se quedan en una tira angosta\n// con su nombre y su cuenta, y se les puede soltar una tarjeta igual. defaultCollapsed la abre encogida y\n// onColumnCollapse avisa cada cambio (para guardarlo si la pantalla quiere);\n// - texts para cualquier texto (la forma de `kanban` en los textos del paquete).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaKanbanBoard con defaultProps y\n// styleOverrides de sus partes: completeButton, tags, titleRow, doneIcon, cardTitle, meta, due, dueIcon, dueText,\n// checklist, checklistIcon, comments, commentsIcon, attachments, attachmentsIcon, assignees, root, collapsedColumn,\n// collapsedTitle, hidden, column, columnHeader, columnTitle, quickAdd, dropZone, card, cardActions, cardContent, empty.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {DragDropContext, Draggable, Droppable} from '@hello-pangea/dnd';\nimport Avatar from '@mui/material/Avatar';\nimport AvatarGroup from '@mui/material/AvatarGroup';\nimport Box from '@mui/material/Box';\nimport Chip from '@mui/material/Chip';\nimport IconButton from '@mui/material/IconButton';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport AttachFileRoundedIcon from '@mui/icons-material/AttachFileRounded';\nimport ChatBubbleOutlineRoundedIcon from '@mui/icons-material/ChatBubbleOutlineRounded';\nimport CheckBoxOutlinedIcon from '@mui/icons-material/CheckBoxOutlined';\nimport CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';\nimport EventOutlinedIcon from '@mui/icons-material/EventOutlined';\nimport KeyboardDoubleArrowLeftRoundedIcon from '@mui/icons-material/KeyboardDoubleArrowLeftRounded';\nimport KeyboardDoubleArrowRightRoundedIcon from '@mui/icons-material/KeyboardDoubleArrowRightRounded';\nimport RadioButtonUncheckedRoundedIcon from '@mui/icons-material/RadioButtonUncheckedRounded';\n\nimport {initialsOf} from '@/appShell/menuItemText.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {DUE_STATUS, dueStatusOf, tagOf, todayIsoDateOf} from '@/kanban/kanbanCards.js';\nimport {cardsOfColumn, isOverLimit} from '@/kanban/kanbanMoves.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport ActionsMenu from '@/ui/actions/ActionsMenu.jsx';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaKanbanBoard)\nconst THEME_NAME = 'CalcitaKanbanBoard';\nconst KanbanCompleteButton = piecePart(THEME_NAME, 'CompleteButton', IconButton);\nconst KanbanTags = piecePart(THEME_NAME, 'Tags', Stack);\nconst KanbanTitleRow = piecePart(THEME_NAME, 'TitleRow', Stack);\nconst KanbanDoneIcon = piecePart(THEME_NAME, 'DoneIcon', CheckCircleRoundedIcon);\nconst KanbanCardTitle = piecePart(THEME_NAME, 'CardTitle', Typography);\nconst KanbanMeta = piecePart(THEME_NAME, 'Meta', Stack);\nconst KanbanDue = piecePart(THEME_NAME, 'Due', Stack);\nconst KanbanDueIcon = piecePart(THEME_NAME, 'DueIcon', EventOutlinedIcon);\nconst KanbanDueText = piecePart(THEME_NAME, 'DueText', Typography);\nconst KanbanChecklist = piecePart(THEME_NAME, 'Checklist', Stack);\nconst KanbanChecklistIcon = piecePart(THEME_NAME, 'ChecklistIcon', CheckBoxOutlinedIcon);\nconst KanbanComments = piecePart(THEME_NAME, 'Comments', Stack);\nconst KanbanCommentsIcon = piecePart(THEME_NAME, 'CommentsIcon', ChatBubbleOutlineRoundedIcon);\nconst KanbanAttachments = piecePart(THEME_NAME, 'Attachments', Stack);\nconst KanbanAttachmentsIcon = piecePart(THEME_NAME, 'AttachmentsIcon', AttachFileRoundedIcon);\nconst KanbanAssignees = piecePart(THEME_NAME, 'Assignees', AvatarGroup);\nconst KanbanRoot = piecePart(THEME_NAME, 'Root', Box);\nconst KanbanCollapsedColumn = piecePart(THEME_NAME, 'CollapsedColumn', Paper);\nconst KanbanCollapsedTitle = piecePart(THEME_NAME, 'CollapsedTitle', Typography);\nconst KanbanHidden = piecePart(THEME_NAME, 'Hidden', Box);\nconst KanbanColumn = piecePart(THEME_NAME, 'Column', Paper);\nconst KanbanColumnHeader = piecePart(THEME_NAME, 'ColumnHeader', Stack);\nconst KanbanColumnTitle = piecePart(THEME_NAME, 'ColumnTitle', Typography);\nconst KanbanQuickAdd = piecePart(THEME_NAME, 'QuickAdd', Box);\nconst KanbanDropZone = piecePart(THEME_NAME, 'DropZone', Stack);\nconst KanbanCard = piecePart(THEME_NAME, 'Card', Paper);\nconst KanbanCardActions = piecePart(THEME_NAME, 'CardActions', Box);\nconst KanbanCardContent = piecePart(THEME_NAME, 'CardContent', Box);\nconst KanbanEmpty = piecePart(THEME_NAME, 'Empty', Typography);\n\n// las columnas se reparten el ancho, sin bajar de este mínimo; si no caben, el tablero desliza de lado.\n// OJO: con el teclado, la librería solo mueve una tarjeta a columnas que se ven COMPLETAS: con columnas fijas de 300 px la\n// cuarta quedaba cortada en un escritorio y no se podía soltar ahí con el teclado\nconst COLUMN_MIN_WIDTH_PIXELS = 220;\n// lo alto que mide una columna vacía: lo justo para soltar ahí una tarjeta\nconst EMPTY_COLUMN_MIN_HEIGHT = 96;\n// cuántas caras de responsables se ven antes del «+2»\nconst MAX_VISIBLE_ASSIGNEES = 3;\nconst ASSIGNEE_AVATAR_PIXELS = 24;\n// lo ancho de una columna encogida: su nombre de lado, su cuenta y su botón para abrirla\nconst COLLAPSED_COLUMN_WIDTH_PIXELS = 52;\n// el color del texto de la fecha según cómo va\nconst DUE_COLOR = Object.freeze({[DUE_STATUS.overdue]: 'error.main', [DUE_STATUS.today]: 'warning.dark', [DUE_STATUS.upcoming]: 'text.secondary'});\n\n/**\n * El círculo para terminar una tarea (o reabrirla, si ya está terminada). El clic no levanta la tarjeta ni la abre.\n *\n * @param {{card: any, t: Function, onComplete: (card: any, completed: boolean) => void}} props\n */\nfunction CompleteButton({card, t, onComplete}) {\n const label = card.completed ? t('reopen', {title: card.title}) : t('complete', {title: card.title});\n return (\n <Tooltip title={label}>\n <KanbanCompleteButton size=\"small\" aria-label={label} aria-pressed={Boolean(card.completed)} ownSx={{m: -0.5, color: card.completed ? 'success.main' : 'text.secondary'}}\n onClick={(event) => {\n event.stopPropagation();\n onComplete(card, !card.completed);\n }}>\n {card.completed ? <CheckCircleRoundedIcon fontSize=\"small\" /> : <RadioButtonUncheckedRoundedIcon fontSize=\"small\" />}\n </KanbanCompleteButton>\n </Tooltip>\n );\n}\n\n/**\n * Una tarjeta por omisión: lo que traiga, sin pedir nada (título, descripción, etiquetas, responsables, fecha, pendientes,\n * comentarios y adjuntos).\n *\n * @param {{card: any, t: Function, today: string, onComplete?: (card: any, completed: boolean) => void}} props\n */\nfunction DefaultCard({card, t, today, onComplete}) {\n const {formatDate} = useFormatters();\n // terminada, su fecha ya no apura: se pinta tenue, sin rojo ni ámbar\n const dueStatus = card.completed && card.dueDate ? DUE_STATUS.upcoming : dueStatusOf(card.dueDate, today);\n let dueText = '';\n if (card.completed && card.dueDate) {\n dueText = t('dueCompleted', {date: formatDate(card.dueDate)});\n } else if (dueStatus === DUE_STATUS.overdue) {\n dueText = t('dueOverdue', {date: formatDate(card.dueDate)});\n } else if (dueStatus === DUE_STATUS.today) {\n dueText = t('dueToday');\n } else if (dueStatus) {\n dueText = t('dueOn', {date: formatDate(card.dueDate)});\n }\n const hasFooter = dueStatus || card.checklist?.total > 0 || card.comments > 0 || card.attachments > 0 || card.assignees?.length > 0;\n\n return (\n <Stack spacing={0.75}>\n {card.tags?.length > 0 && (\n <KanbanTags direction=\"row\" spacing={0.5} useFlexGap ownSx={{flexWrap: 'wrap'}}>\n {card.tags.map((rawTag) => {\n const tag = tagOf(rawTag);\n return <Chip key={tag.label} label={tag.label} size=\"small\" color={tag.color} variant={tag.color === 'default' ? 'filled' : 'outlined'} />;\n })}\n </KanbanTags>\n )}\n <KanbanTitleRow direction=\"row\" spacing={1} ownSx={{alignItems: 'flex-start'}}>\n {onComplete && <CompleteButton card={card} t={t} onComplete={onComplete} />}\n {!onComplete && card.completed && (\n <KanbanDoneIcon fontSize=\"small\" ownSx={{color: 'success.main'}} titleAccess={t('completed')} />\n )}\n <KanbanCardTitle variant=\"subtitle2\" component=\"p\" ownSx={{color: card.completed ? 'text.secondary' : undefined}}>{card.title}</KanbanCardTitle>\n </KanbanTitleRow>\n {card.description && <Typography variant=\"body2\" color=\"text.secondary\">{card.description}</Typography>}\n {hasFooter && (\n <KanbanMeta direction=\"row\" spacing={1.25} useFlexGap ownSx={{alignItems: 'center', flexWrap: 'wrap', color: 'text.secondary'}}>\n {dueStatus && (\n <KanbanDue direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center', color: DUE_COLOR[dueStatus]}}>\n <KanbanDueIcon ownSx={{fontSize: 16}} />\n <KanbanDueText variant=\"caption\" ownSx={{fontWeight: dueStatus === DUE_STATUS.upcoming ? 400 : 600}}>{dueText}</KanbanDueText>\n </KanbanDue>\n )}\n {card.checklist?.total > 0 && (\n <KanbanChecklist direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center'}}\n aria-label={t('checklist', {done: card.checklist.done, total: card.checklist.total})}>\n <KanbanChecklistIcon ownSx={{fontSize: 16}} />\n <Typography variant=\"caption\" aria-hidden=\"true\">{card.checklist.done}/{card.checklist.total}</Typography>\n </KanbanChecklist>\n )}\n {card.comments > 0 && (\n <KanbanComments direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center'}} aria-label={t('comments', {count: card.comments})}>\n <KanbanCommentsIcon ownSx={{fontSize: 16}} />\n <Typography variant=\"caption\" aria-hidden=\"true\">{card.comments}</Typography>\n </KanbanComments>\n )}\n {card.attachments > 0 && (\n <KanbanAttachments direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center'}} aria-label={t('attachments', {count: card.attachments})}>\n <KanbanAttachmentsIcon ownSx={{fontSize: 16}} />\n <Typography variant=\"caption\" aria-hidden=\"true\">{card.attachments}</Typography>\n </KanbanAttachments>\n )}\n {card.assignees?.length > 0 && (\n <KanbanAssignees max={MAX_VISIBLE_ASSIGNEES} ownSx={{ml: 'auto', '& .MuiAvatar-root': {width: ASSIGNEE_AVATAR_PIXELS, height: ASSIGNEE_AVATAR_PIXELS, fontSize: 11}}}\n aria-label={t('assignees', {names: card.assignees.map((person) => person.name).join(', ')})}>\n {card.assignees.map((person) => (\n <Tooltip key={person.id} title={person.name}>\n <Avatar alt={person.name} src={person.avatarUrl}>{initialsOf(person.name)}</Avatar>\n </Tooltip>\n ))}\n </KanbanAssignees>\n )}\n </KanbanMeta>\n )}\n </Stack>\n );\n}\n\n/**\n * Agregar una tarjeta escribiendo su título: Enter la agrega (y deja el campo listo para otra), Escape cierra.\n *\n * @param {{columnTitle: string, onAdd: (title: string) => void, onClose: () => void, t: Function}} props\n */\nfunction QuickAdd({columnTitle, onAdd, onClose, t}) {\n const [title, setTitle] = useState('');\n return (\n <TextField size=\"small\" fullWidth autoFocus multiline maxRows={4} value={title} placeholder={t('addCardPlaceholder')}\n slotProps={{htmlInput: {'aria-label': t('addCard', {column: columnTitle})}}}\n onChange={(event) => setTitle(event.target.value)}\n onBlur={() => !title.trim() && onClose()}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n onClose();\n }\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (title.trim()) {\n onAdd(title.trim());\n setTitle('');\n }\n }\n }} />\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{id: string, title: string, limit?: number, count?: number, collapsible?: boolean, defaultCollapsed?: boolean}>} props.columns\n * en su orden. count: cuántas tarjetas tiene de verdad cuando la pantalla le pasa solo las filtradas (el tope se cuenta\n * contra todas). collapsible: lleva su botón para encogerse (el congelador); defaultCollapsed: empieza encogida\n * @param {Array<{id: string, columnId: string, title: string, completed?: boolean, description?: string, tags?: Array<string|{label: string, color?: string}>, assignees?: Array<{id: string, name: string, avatarUrl?: string}>, dueDate?: string, checklist?: {done: number, total: number}, comments?: number, attachments?: number} & Record<string, any>>} props.cards\n * el orden de cada columna es el orden en este arreglo; cada tarjeta puede traer sus campos propios (llegan a renderCard,\n * a cardActions y a onCardClick tal cual). dueDate: AAAA-MM-DD\n * @param {(move: {cardId: string, fromColumnId: string, toColumnId: string, toIndex: number}) => void} props.onMove\n * @param {(card: any) => import('react').ReactNode} [props.renderCard] lo de adentro de cada tarjeta (recibe la tarjeta de cards)\n * @param {(cardId: string) => void} [props.onCardClick]\n * @param {(newCard: {columnId: string, title: string}) => void} [props.onAddCard] con él cada columna lleva su «+» para agregar\n * escribiendo el título\n * @param {(card: any) => Array<{key: string, label: string, icon?: import('react').ReactNode, color?: string, disabled?: boolean, onClick: () => void}>} [props.cardActions]\n * las acciones del «⋯» de cada tarjeta (editar, asignarme, borrar…); sin ellas no hay «⋯»\n * @param {(column: any) => Array<{key: string, label: string, icon?: import('react').ReactNode, color?: string, disabled?: boolean, onClick: () => void}>} [props.columnActions]\n * las acciones del «⋯» de cada columna (renombrar, limpiar…)\n * @param {(card: any, completed: boolean) => void} [props.onCardComplete] con él cada tarjeta lleva su círculo para terminarla\n * (completed true) o reabrirla (false); la pantalla decide qué más pasa (moverla a «Listo», guardar la fecha)\n * @param {(columnId: string, collapsed: boolean) => void} [props.onColumnCollapse] cada que una columna se encoge o se abre\n * @param {string} props.ariaLabel ya traducido\n * @param {object} [props.texts] los textos que cambian, con la forma de `kanban` en los textos del paquete\n */\nexport default function KanbanBoard(props) {\n // lo que el proyecto puso en su tema (components.CalcitaKanbanBoard.defaultProps) y encima lo que llega aquí\n const {\n columns, cards, onMove, renderCard, onCardClick, onAddCard, cardActions, columnActions, onCardComplete, onColumnCollapse, ariaLabel, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('kanban', texts);\n // la columna donde se está escribiendo una tarjeta nueva\n const [addingColumnId, setAddingColumnId] = useState(null);\n // las columnas encogidas: empiezan como dice defaultCollapsed y luego las mueve la persona\n const [collapsedIds, setCollapsedIds] = useState(() => new Set(columns.filter((column) => column.defaultCollapsed).map((column) => column.id)));\n const toggleColumn = (columnId) => {\n const collapsed = !collapsedIds.has(columnId);\n setCollapsedIds((current) => {\n const next = new Set(current);\n if (collapsed) {\n next.add(columnId);\n } else {\n next.delete(columnId);\n }\n return next;\n });\n onColumnCollapse?.(columnId, collapsed);\n };\n const today = todayIsoDateOf();\n const columnTitleOf = (columnId) => columns.find((column) => column.id === columnId)?.title ?? columnId;\n const cardTitleOf = (cardId) => cards.find((card) => card.id === cardId)?.title ?? cardId;\n\n // lo que oye quien usa lector de pantalla (posiciones desde 1, como se cuentan)\n const announceStart = (start, provided) => provided.announce(t('lifted', {\n title: cardTitleOf(start.draggableId), column: columnTitleOf(start.source.droppableId), position: start.source.index + 1,\n }));\n const announceUpdate = (update, provided) => {\n if (update.destination) {\n provided.announce(t('moving', {column: columnTitleOf(update.destination.droppableId), position: update.destination.index + 1}));\n }\n };\n const finishMove = (result, provided) => {\n const {draggableId, source, destination} = result;\n // se soltó fuera de una columna o en el mismo lugar: nada que mover\n if (!destination || (destination.droppableId === source.droppableId && destination.index === source.index)) {\n provided.announce(t('cancelled', {title: cardTitleOf(draggableId)}));\n return;\n }\n provided.announce(t('dropped', {title: cardTitleOf(draggableId), column: columnTitleOf(destination.droppableId), position: destination.index + 1}));\n onMove({cardId: draggableId, fromColumnId: source.droppableId, toColumnId: destination.droppableId, toIndex: destination.index});\n };\n\n return (\n <DragDropContext onDragStart={announceStart} onDragUpdate={announceUpdate} onDragEnd={finishMove} dragHandleUsageInstructions={t('instructions')}>\n <KanbanRoot role=\"region\" aria-label={ariaLabel} ownSx={{\n display: 'flex', gap: 2, overflowX: 'auto', pb: 1, scrollSnapType: 'x proximity', alignItems: 'flex-start',\n }}>\n {columns.map((column) => {\n const columnCards = cardsOfColumn(cards, column.id);\n // con un filtro puesto la pantalla dice cuántas tiene de verdad: «1 / 3» mentía con la columna llena\n const total = Number.isInteger(column.count) ? column.count : columnCards.length;\n const isOver = isOverLimit(column, total);\n const count = Number.isInteger(column.limit) ? `${total} / ${column.limit}` : String(total);\n const isCollapsed = column.collapsible && collapsedIds.has(column.id);\n // encogida: una tira con su nombre de lado y su cuenta; se le puede soltar una tarjeta (queda arriba)\n if (isCollapsed) {\n return (\n <Droppable key={column.id} droppableId={column.id}>\n {(droppableProvided, droppableSnapshot) => (\n <KanbanCollapsedColumn ref={droppableProvided.innerRef} {...droppableProvided.droppableProps} variant=\"outlined\" component=\"section\"\n aria-label={column.title}\n ownSx={{\n flex: '0 0 auto', width: COLLAPSED_COLUMN_WIDTH_PIXELS, py: 1, borderRadius: 3, display: 'flex',\n flexDirection: 'column', alignItems: 'center', gap: 1, minHeight: EMPTY_COLUMN_MIN_HEIGHT * 2,\n bgcolor: droppableSnapshot.isDraggingOver ? 'action.hover' : undefined,\n }}>\n <Tooltip title={t('expandColumn', {column: column.title})} placement=\"right\">\n <IconButton size=\"small\" aria-label={t('expandColumn', {column: column.title})} aria-expanded=\"false\"\n onClick={() => toggleColumn(column.id)}>\n <KeyboardDoubleArrowRightRoundedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Chip size=\"small\" label={count} color={isOver ? 'warning' : 'default'} />\n <KanbanCollapsedTitle variant=\"subtitle2\" component=\"h3\" ownSx={{writingMode: 'vertical-rl', whiteSpace: 'nowrap'}}>\n {column.title}\n </KanbanCollapsedTitle>\n {/* el lugar de la tarjeta que se arrastra; encogida no la enseña */}\n <KanbanHidden ownSx={{display: 'none'}}>{droppableProvided.placeholder}</KanbanHidden>\n </KanbanCollapsedColumn>\n )}\n </Droppable>\n );\n }\n return (\n <KanbanColumn key={column.id} variant=\"outlined\" component=\"section\" aria-label={column.title}\n ownSx={{flex: '1 1 0', minWidth: COLUMN_MIN_WIDTH_PIXELS, p: 1.5, scrollSnapAlign: 'start', borderRadius: 3}}>\n <KanbanColumnHeader direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center', mb: 1.5, px: 0.5}}>\n <KanbanColumnTitle variant=\"subtitle2\" component=\"h3\" ownSx={{flexGrow: 1, minWidth: 0}}>{column.title}</KanbanColumnTitle>\n <Chip size=\"small\" label={count} color={isOver ? 'warning' : 'default'}\n title={isOver ? t('overLimit', {limit: column.limit}) : undefined} />\n {onAddCard && (\n <Tooltip title={t('addCard', {column: column.title})}>\n <IconButton size=\"small\" aria-label={t('addCard', {column: column.title})} onClick={() => setAddingColumnId(column.id)}>\n <AddRoundedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n <ActionsMenu label={t('columnActions', {column: column.title})} actions={columnActions?.(column)} />\n {column.collapsible && (\n <Tooltip title={t('collapseColumn', {column: column.title})}>\n <IconButton size=\"small\" aria-label={t('collapseColumn', {column: column.title})} aria-expanded=\"true\"\n onClick={() => toggleColumn(column.id)}>\n <KeyboardDoubleArrowLeftRoundedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </KanbanColumnHeader>\n {addingColumnId === column.id && (\n <KanbanQuickAdd ownSx={{mb: 1}}>\n <QuickAdd columnTitle={column.title} t={t} onClose={() => setAddingColumnId(null)}\n onAdd={(title) => onAddCard({columnId: column.id, title})} />\n </KanbanQuickAdd>\n )}\n <Droppable droppableId={column.id}>\n {(droppableProvided, droppableSnapshot) => (\n <KanbanDropZone ref={droppableProvided.innerRef} {...droppableProvided.droppableProps} spacing={1}\n ownSx={{\n minHeight: EMPTY_COLUMN_MIN_HEIGHT, borderRadius: 2, transition: 'background-color 160ms',\n bgcolor: droppableSnapshot.isDraggingOver ? 'action.hover' : 'transparent',\n }}>\n {columnCards.map((card, index) => (\n <Draggable key={card.id} draggableId={card.id} index={index}>\n {(draggableProvided, draggableSnapshot) => (\n <KanbanCard ref={draggableProvided.innerRef} {...draggableProvided.draggableProps} {...draggableProvided.dragHandleProps}\n elevation={draggableSnapshot.isDragging ? 8 : 1}\n onClick={onCardClick ? () => onCardClick(card.id) : undefined}\n ownSx={{p: 1.5, borderRadius: 2, cursor: 'grab', position: 'relative', '&:focus-visible': {outline: 2, outlineColor: 'primary.main'}}}>\n {/* el «⋯» arriba a la derecha; el contenido le deja su lugar */}\n {cardActions && (\n <KanbanCardActions ownSx={{position: 'absolute', top: 4, right: 4}}>\n <ActionsMenu label={t('cardActions', {title: card.title})} actions={cardActions(card)} />\n </KanbanCardActions>\n )}\n <KanbanCardContent ownSx={cardActions ? {pr: 3} : undefined}>\n {renderCard ? renderCard(card) : <DefaultCard card={card} t={t} today={today} onComplete={onCardComplete} />}\n </KanbanCardContent>\n </KanbanCard>\n )}\n </Draggable>\n ))}\n {droppableProvided.placeholder}\n {/* vacía de verdad, o con tarjetas que el filtro de la pantalla esconde (no se dice «sin tarjetas») */}\n {columnCards.length === 0 && !droppableSnapshot.isDraggingOver && addingColumnId !== column.id && (\n <KanbanEmpty variant=\"caption\" color=\"text.secondary\" ownSx={{textAlign: 'center', py: 3}}>\n {total > 0 ? t('emptyFiltered') : t('empty')}\n </KanbanEmpty>\n )}\n </KanbanDropZone>\n )}\n </Droppable>\n </KanbanColumn>\n );\n })}\n </KanbanRoot>\n </DragDropContext>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KanbanBoard.js","sources":["../../src/kanban/KanbanBoard.jsx"],"sourcesContent":["// Un tablero kanban (@stackcraftmx/calcita/kanban): columnas con tarjetas que se arrastran de una a otra con el ratón, con el\n// dedo o con el teclado (espacio para levantar, flechas para mover, espacio para soltar). Con @hello-pangea/dnd por dentro.\n//\n// <KanbanBoard columns={[{id: 'todo', title: 'Por hacer'}, {id: 'doing', title: 'En proceso', limit: 3}]}\n// cards={cards} onMove={(move) => api.post('/tasks/move', move)} ariaLabel=\"Tablero de tareas\" />\n//\n// El tablero no guarda nada: avisa la movida (onMove) y quien lo usa actualiza sus tarjetas (moveCard de kanbanMoves.js lo\n// hace sin esperar al servidor). Una columna con tope (limit, el trabajo en curso) avisa en ámbar cuando lo pasa.\n//\n// Accesible: el lector de pantalla anuncia en el idioma de la app qué se levantó, a dónde va y dónde quedó.\n//\n// Lo de un producto, todo hacia afuera (el tablero no guarda nada ni llama a ningún servidor):\n// - la tarjeta por omisión pinta lo que traiga: etiquetas (texto o {label, color}), responsables con su monograma, la\n// fecha límite (roja si ya venció, ámbar si es hoy), el avance de su lista de pendientes, comentarios y adjuntos. Para\n// otra tarjeta: renderCard;\n// - «+» en cada columna para agregar escribiendo el título (onAddCard({columnId, title}));\n// - «⋯» en cada tarjeta y en cada columna con las acciones que dé la pantalla (cardActions, columnActions): editar,\n// asignarme, mover sin arrastrar, borrar…;\n// - terminar una tarea: con onCardComplete cada tarjeta lleva su círculo para marcarla (y desmarcarla); qué pasa al\n// terminarla (pasarla a «Listo», guardar la fecha) lo decide la pantalla. Una tarjeta con completed: true sale con su\n// palomita verde y su fecha límite ya no se pinta de rojo;\n// - columnas que se encogen (collapsible), como el congelador (icebox) de ideas para después: se quedan en una tira angosta\n// con su nombre y su cuenta, y se les puede soltar una tarjeta igual. defaultCollapsed la abre encogida y\n// onColumnCollapse avisa cada cambio (para guardarlo si la pantalla quiere);\n// - texts para cualquier texto (la forma de `kanban` en los textos del paquete).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaKanbanBoard con defaultProps y\n// styleOverrides de sus partes: completeButton, tags, titleRow, doneIcon, cardTitle, meta, due, dueIcon, dueText,\n// checklist, checklistIcon, comments, commentsIcon, attachments, attachmentsIcon, assignees, root, collapsedColumn,\n// collapsedTitle, hidden, column, columnHeader, columnTitle, quickAdd, dropZone, card, cardActions, cardContent, empty.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {DragDropContext, Draggable, Droppable} from '@hello-pangea/dnd';\nimport Avatar from '@mui/material/Avatar';\nimport AvatarGroup from '@mui/material/AvatarGroup';\nimport Box from '@mui/material/Box';\nimport Chip from '@mui/material/Chip';\nimport IconButton from '@mui/material/IconButton';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport AttachFileRoundedIcon from '@mui/icons-material/AttachFileRounded';\nimport ChatBubbleOutlineRoundedIcon from '@mui/icons-material/ChatBubbleOutlineRounded';\nimport CheckBoxOutlinedIcon from '@mui/icons-material/CheckBoxOutlined';\nimport CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';\nimport EventOutlinedIcon from '@mui/icons-material/EventOutlined';\nimport KeyboardDoubleArrowLeftRoundedIcon from '@mui/icons-material/KeyboardDoubleArrowLeftRounded';\nimport KeyboardDoubleArrowRightRoundedIcon from '@mui/icons-material/KeyboardDoubleArrowRightRounded';\nimport RadioButtonUncheckedRoundedIcon from '@mui/icons-material/RadioButtonUncheckedRounded';\n\nimport {initialsOf} from '@/appShell/menuItemText.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {DUE_STATUS, dueStatusOf, tagOf, todayIsoDateOf} from '@/kanban/kanbanCards.js';\nimport {cardsOfColumn, isOverLimit} from '@/kanban/kanbanMoves.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport ActionsMenu from '@/ui/actions/ActionsMenu.jsx';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaKanbanBoard)\nconst THEME_NAME = 'CalcitaKanbanBoard';\nconst KanbanCompleteButton = piecePart(THEME_NAME, 'CompleteButton', IconButton);\nconst KanbanTags = piecePart(THEME_NAME, 'Tags', Stack);\nconst KanbanTitleRow = piecePart(THEME_NAME, 'TitleRow', Stack);\nconst KanbanDoneIcon = piecePart(THEME_NAME, 'DoneIcon', CheckCircleRoundedIcon);\nconst KanbanCardTitle = piecePart(THEME_NAME, 'CardTitle', Typography);\nconst KanbanMeta = piecePart(THEME_NAME, 'Meta', Stack);\nconst KanbanDue = piecePart(THEME_NAME, 'Due', Stack);\nconst KanbanDueIcon = piecePart(THEME_NAME, 'DueIcon', EventOutlinedIcon);\nconst KanbanDueText = piecePart(THEME_NAME, 'DueText', Typography);\nconst KanbanChecklist = piecePart(THEME_NAME, 'Checklist', Stack);\nconst KanbanChecklistIcon = piecePart(THEME_NAME, 'ChecklistIcon', CheckBoxOutlinedIcon);\nconst KanbanComments = piecePart(THEME_NAME, 'Comments', Stack);\nconst KanbanCommentsIcon = piecePart(THEME_NAME, 'CommentsIcon', ChatBubbleOutlineRoundedIcon);\nconst KanbanAttachments = piecePart(THEME_NAME, 'Attachments', Stack);\nconst KanbanAttachmentsIcon = piecePart(THEME_NAME, 'AttachmentsIcon', AttachFileRoundedIcon);\nconst KanbanAssignees = piecePart(THEME_NAME, 'Assignees', AvatarGroup);\nconst KanbanRoot = piecePart(THEME_NAME, 'Root', Box);\nconst KanbanCollapsedColumn = piecePart(THEME_NAME, 'CollapsedColumn', Paper);\nconst KanbanCollapsedTitle = piecePart(THEME_NAME, 'CollapsedTitle', Typography);\nconst KanbanHidden = piecePart(THEME_NAME, 'Hidden', Box);\nconst KanbanColumn = piecePart(THEME_NAME, 'Column', Paper);\nconst KanbanColumnHeader = piecePart(THEME_NAME, 'ColumnHeader', Stack);\nconst KanbanColumnTitle = piecePart(THEME_NAME, 'ColumnTitle', Typography);\nconst KanbanQuickAdd = piecePart(THEME_NAME, 'QuickAdd', Box);\nconst KanbanDropZone = piecePart(THEME_NAME, 'DropZone', Stack);\nconst KanbanCard = piecePart(THEME_NAME, 'Card', Paper);\nconst KanbanCardActions = piecePart(THEME_NAME, 'CardActions', Box);\nconst KanbanCardContent = piecePart(THEME_NAME, 'CardContent', Box);\nconst KanbanEmpty = piecePart(THEME_NAME, 'Empty', Typography);\n\n// las columnas se reparten el ancho, sin bajar de este mínimo; si no caben, el tablero desliza de lado.\n// OJO: con el teclado, la librería solo mueve una tarjeta a columnas que se ven COMPLETAS: con columnas fijas de 300 px la\n// cuarta quedaba cortada en un escritorio y no se podía soltar ahí con el teclado\nconst COLUMN_MIN_WIDTH_PIXELS = 220;\n// lo alto que mide una columna vacía: lo justo para soltar ahí una tarjeta\nconst EMPTY_COLUMN_MIN_HEIGHT = 96;\n// cuántas caras de responsables se ven antes del «+2»\nconst MAX_VISIBLE_ASSIGNEES = 3;\nconst ASSIGNEE_AVATAR_PIXELS = 24;\n// lo ancho de una columna encogida: su nombre de lado, su cuenta y su botón para abrirla\nconst COLLAPSED_COLUMN_WIDTH_PIXELS = 52;\n// el color del texto de la fecha según cómo va\nconst DUE_COLOR = Object.freeze({[DUE_STATUS.overdue]: 'error.main', [DUE_STATUS.today]: 'warning.dark', [DUE_STATUS.upcoming]: 'text.secondary'});\n\n/**\n * El círculo para terminar una tarea (o reabrirla, si ya está terminada). El clic no levanta la tarjeta ni la abre.\n *\n * @param {{card: any, t: Function, onComplete: (card: any, completed: boolean) => void}} props\n */\nfunction CompleteButton({card, t, onComplete}) {\n const label = card.completed ? t('reopen', {title: card.title}) : t('complete', {title: card.title});\n return (\n <Tooltip title={label}>\n <KanbanCompleteButton size=\"small\" aria-label={label} aria-pressed={Boolean(card.completed)} ownSx={{m: -0.5, color: card.completed ? 'success.main' : 'text.secondary'}}\n onClick={(event) => {\n event.stopPropagation();\n onComplete(card, !card.completed);\n }}>\n {card.completed ? <CheckCircleRoundedIcon fontSize=\"small\" /> : <RadioButtonUncheckedRoundedIcon fontSize=\"small\" />}\n </KanbanCompleteButton>\n </Tooltip>\n );\n}\n\n/**\n * Una tarjeta por omisión: lo que traiga, sin pedir nada (título, descripción, etiquetas, responsables, fecha, pendientes,\n * comentarios y adjuntos).\n *\n * @param {{card: any, t: Function, today: string, onComplete?: (card: any, completed: boolean) => void}} props\n */\nfunction DefaultCard({card, t, today, onComplete}) {\n const {formatDate} = useFormatters();\n // terminada, su fecha ya no apura: se pinta tenue, sin rojo ni ámbar\n const dueStatus = card.completed && card.dueDate ? DUE_STATUS.upcoming : dueStatusOf(card.dueDate, today);\n let dueText = '';\n if (card.completed && card.dueDate) {\n dueText = t('dueCompleted', {date: formatDate(card.dueDate)});\n } else if (dueStatus === DUE_STATUS.overdue) {\n dueText = t('dueOverdue', {date: formatDate(card.dueDate)});\n } else if (dueStatus === DUE_STATUS.today) {\n dueText = t('dueToday');\n } else if (dueStatus) {\n dueText = t('dueOn', {date: formatDate(card.dueDate)});\n }\n const hasFooter = dueStatus || card.checklist?.total > 0 || card.comments > 0 || card.attachments > 0 || card.assignees?.length > 0;\n\n return (\n <Stack spacing={0.75}>\n {card.tags?.length > 0 && (\n <KanbanTags direction=\"row\" spacing={0.5} useFlexGap ownSx={{flexWrap: 'wrap'}}>\n {card.tags.map((rawTag) => {\n const tag = tagOf(rawTag);\n return <Chip key={tag.label} label={tag.label} size=\"small\" color={tag.color} variant={tag.color === 'default' ? 'filled' : 'outlined'} />;\n })}\n </KanbanTags>\n )}\n <KanbanTitleRow direction=\"row\" spacing={1} ownSx={{alignItems: 'flex-start'}}>\n {onComplete && <CompleteButton card={card} t={t} onComplete={onComplete} />}\n {!onComplete && card.completed && (\n <KanbanDoneIcon fontSize=\"small\" ownSx={{color: 'success.main'}} titleAccess={t('completed')} />\n )}\n <KanbanCardTitle variant=\"subtitle2\" component=\"p\" ownSx={{color: card.completed ? 'text.secondary' : undefined}}>{card.title}</KanbanCardTitle>\n </KanbanTitleRow>\n {card.description && <Typography variant=\"body2\" color=\"text.secondary\">{card.description}</Typography>}\n {hasFooter && (\n <KanbanMeta direction=\"row\" spacing={1.25} useFlexGap ownSx={{alignItems: 'center', flexWrap: 'wrap', color: 'text.secondary'}}>\n {dueStatus && (\n <KanbanDue direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center', color: DUE_COLOR[dueStatus]}}>\n <KanbanDueIcon ownSx={{fontSize: 16}} />\n <KanbanDueText variant=\"caption\" ownSx={{fontWeight: dueStatus === DUE_STATUS.upcoming ? 400 : 600}}>{dueText}</KanbanDueText>\n </KanbanDue>\n )}\n {card.checklist?.total > 0 && (\n <KanbanChecklist direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center'}}\n aria-label={t('checklist', {done: card.checklist.done, total: card.checklist.total})}>\n <KanbanChecklistIcon ownSx={{fontSize: 16}} />\n <Typography variant=\"caption\" aria-hidden=\"true\">{card.checklist.done}/{card.checklist.total}</Typography>\n </KanbanChecklist>\n )}\n {card.comments > 0 && (\n <KanbanComments direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center'}} aria-label={t('comments', {count: card.comments})}>\n <KanbanCommentsIcon ownSx={{fontSize: 16}} />\n <Typography variant=\"caption\" aria-hidden=\"true\">{card.comments}</Typography>\n </KanbanComments>\n )}\n {card.attachments > 0 && (\n <KanbanAttachments direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center'}} aria-label={t('attachments', {count: card.attachments})}>\n <KanbanAttachmentsIcon ownSx={{fontSize: 16}} />\n <Typography variant=\"caption\" aria-hidden=\"true\">{card.attachments}</Typography>\n </KanbanAttachments>\n )}\n {card.assignees?.length > 0 && (\n <KanbanAssignees max={MAX_VISIBLE_ASSIGNEES} ownSx={{ml: 'auto', '& .MuiAvatar-root': {width: ASSIGNEE_AVATAR_PIXELS, height: ASSIGNEE_AVATAR_PIXELS, fontSize: 11}}}\n aria-label={t('assignees', {names: card.assignees.map((person) => person.name).join(', ')})}>\n {card.assignees.map((person) => (\n <Tooltip key={person.id} title={person.name}>\n <Avatar alt={person.name} src={person.avatarUrl}>{initialsOf(person.name)}</Avatar>\n </Tooltip>\n ))}\n </KanbanAssignees>\n )}\n </KanbanMeta>\n )}\n </Stack>\n );\n}\n\n/**\n * Agregar una tarjeta escribiendo su título: Enter la agrega (y deja el campo listo para otra), Escape cierra.\n *\n * @param {{columnTitle: string, onAdd: (title: string) => void, onClose: () => void, t: Function}} props\n */\nfunction QuickAdd({columnTitle, onAdd, onClose, t}) {\n const [title, setTitle] = useState('');\n return (\n <TextField size=\"small\" fullWidth autoFocus multiline maxRows={4} value={title} placeholder={t('addCardPlaceholder')}\n slotProps={{htmlInput: {'aria-label': t('addCard', {column: columnTitle})}}}\n onChange={(event) => setTitle(event.target.value)}\n onBlur={() => !title.trim() && onClose()}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n onClose();\n }\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n if (title.trim()) {\n onAdd(title.trim());\n setTitle('');\n }\n }\n }} />\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{id: string, title: string, limit?: number, count?: number, collapsible?: boolean, defaultCollapsed?: boolean}>} props.columns\n * en su orden. count: cuántas tarjetas tiene de verdad cuando la pantalla le pasa solo las filtradas (el tope se cuenta\n * contra todas). collapsible: lleva su botón para encogerse (el congelador); defaultCollapsed: empieza encogida\n * @param {Array<{id: string, columnId: string, title: string, completed?: boolean, description?: string, tags?: Array<string|{label: string, color?: string}>, assignees?: Array<{id: string, name: string, avatarUrl?: string}>, dueDate?: string, checklist?: {done: number, total: number}, comments?: number, attachments?: number} & Record<string, any>>} props.cards\n * el orden de cada columna es el orden en este arreglo; cada tarjeta puede traer sus campos propios (llegan a renderCard,\n * a cardActions y a onCardClick tal cual). dueDate: AAAA-MM-DD\n * @param {(move: {cardId: string, fromColumnId: string, toColumnId: string, toIndex: number}) => void} props.onMove\n * @param {(card: any) => import('react').ReactNode} [props.renderCard] lo de adentro de cada tarjeta (recibe la tarjeta de cards)\n * @param {(cardId: string) => void} [props.onCardClick]\n * @param {(newCard: {columnId: string, title: string}) => void} [props.onAddCard] con él cada columna lleva su «+» para agregar\n * escribiendo el título\n * @param {(card: any) => Array<{key: string, label: string, icon?: import('react').ReactNode, color?: string, disabled?: boolean, onClick: () => void}>} [props.cardActions]\n * las acciones del «⋯» de cada tarjeta (editar, asignarme, borrar…); sin ellas no hay «⋯»\n * @param {(column: any) => Array<{key: string, label: string, icon?: import('react').ReactNode, color?: string, disabled?: boolean, onClick: () => void}>} [props.columnActions]\n * las acciones del «⋯» de cada columna (renombrar, limpiar…)\n * @param {(card: any, completed: boolean) => void} [props.onCardComplete] con él cada tarjeta lleva su círculo para terminarla\n * (completed true) o reabrirla (false); la pantalla decide qué más pasa (moverla a «Listo», guardar la fecha)\n * @param {(columnId: string, collapsed: boolean) => void} [props.onColumnCollapse] cada que una columna se encoge o se abre\n * @param {string} props.ariaLabel ya traducido\n * @param {object} [props.texts] los textos que cambian, con la forma de `kanban` en los textos del paquete\n */\nfunction KanbanBoardContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaKanbanBoard.defaultProps) y encima lo que llega aquí\n const {\n columns, cards, onMove, renderCard, onCardClick, onAddCard, cardActions, columnActions, onCardComplete, onColumnCollapse, ariaLabel, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('kanban', texts);\n // la columna donde se está escribiendo una tarjeta nueva\n const [addingColumnId, setAddingColumnId] = useState(null);\n // las columnas encogidas: empiezan como dice defaultCollapsed y luego las mueve la persona\n const [collapsedIds, setCollapsedIds] = useState(() => new Set(columns.filter((column) => column.defaultCollapsed).map((column) => column.id)));\n const toggleColumn = (columnId) => {\n const collapsed = !collapsedIds.has(columnId);\n setCollapsedIds((current) => {\n const next = new Set(current);\n if (collapsed) {\n next.add(columnId);\n } else {\n next.delete(columnId);\n }\n return next;\n });\n onColumnCollapse?.(columnId, collapsed);\n };\n const today = todayIsoDateOf();\n const columnTitleOf = (columnId) => columns.find((column) => column.id === columnId)?.title ?? columnId;\n const cardTitleOf = (cardId) => cards.find((card) => card.id === cardId)?.title ?? cardId;\n\n // lo que oye quien usa lector de pantalla (posiciones desde 1, como se cuentan)\n const announceStart = (start, provided) => provided.announce(t('lifted', {\n title: cardTitleOf(start.draggableId), column: columnTitleOf(start.source.droppableId), position: start.source.index + 1,\n }));\n const announceUpdate = (update, provided) => {\n if (update.destination) {\n provided.announce(t('moving', {column: columnTitleOf(update.destination.droppableId), position: update.destination.index + 1}));\n }\n };\n const finishMove = (result, provided) => {\n const {draggableId, source, destination} = result;\n // se soltó fuera de una columna o en el mismo lugar: nada que mover\n if (!destination || (destination.droppableId === source.droppableId && destination.index === source.index)) {\n provided.announce(t('cancelled', {title: cardTitleOf(draggableId)}));\n return;\n }\n provided.announce(t('dropped', {title: cardTitleOf(draggableId), column: columnTitleOf(destination.droppableId), position: destination.index + 1}));\n onMove({cardId: draggableId, fromColumnId: source.droppableId, toColumnId: destination.droppableId, toIndex: destination.index});\n };\n\n return (\n <DragDropContext onDragStart={announceStart} onDragUpdate={announceUpdate} onDragEnd={finishMove} dragHandleUsageInstructions={t('instructions')}>\n <KanbanRoot role=\"region\" aria-label={ariaLabel} ownSx={{\n display: 'flex', gap: 2, overflowX: 'auto', pb: 1, scrollSnapType: 'x proximity', alignItems: 'flex-start',\n }}>\n {columns.map((column) => {\n const columnCards = cardsOfColumn(cards, column.id);\n // con un filtro puesto la pantalla dice cuántas tiene de verdad: «1 / 3» mentía con la columna llena\n const total = Number.isInteger(column.count) ? column.count : columnCards.length;\n const isOver = isOverLimit(column, total);\n const count = Number.isInteger(column.limit) ? `${total} / ${column.limit}` : String(total);\n const isCollapsed = column.collapsible && collapsedIds.has(column.id);\n // encogida: una tira con su nombre de lado y su cuenta; se le puede soltar una tarjeta (queda arriba)\n if (isCollapsed) {\n return (\n <Droppable key={column.id} droppableId={column.id}>\n {(droppableProvided, droppableSnapshot) => (\n <KanbanCollapsedColumn ref={droppableProvided.innerRef} {...droppableProvided.droppableProps} variant=\"outlined\" component=\"section\"\n aria-label={column.title}\n ownSx={{\n flex: '0 0 auto', width: COLLAPSED_COLUMN_WIDTH_PIXELS, py: 1, borderRadius: 3, display: 'flex',\n flexDirection: 'column', alignItems: 'center', gap: 1, minHeight: EMPTY_COLUMN_MIN_HEIGHT * 2,\n bgcolor: droppableSnapshot.isDraggingOver ? 'action.hover' : undefined,\n }}>\n <Tooltip title={t('expandColumn', {column: column.title})} placement=\"right\">\n <IconButton size=\"small\" aria-label={t('expandColumn', {column: column.title})} aria-expanded=\"false\"\n onClick={() => toggleColumn(column.id)}>\n <KeyboardDoubleArrowRightRoundedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Chip size=\"small\" label={count} color={isOver ? 'warning' : 'default'} />\n <KanbanCollapsedTitle variant=\"subtitle2\" component=\"h3\" ownSx={{writingMode: 'vertical-rl', whiteSpace: 'nowrap'}}>\n {column.title}\n </KanbanCollapsedTitle>\n {/* el lugar de la tarjeta que se arrastra; encogida no la enseña */}\n <KanbanHidden ownSx={{display: 'none'}}>{droppableProvided.placeholder}</KanbanHidden>\n </KanbanCollapsedColumn>\n )}\n </Droppable>\n );\n }\n return (\n <KanbanColumn key={column.id} variant=\"outlined\" component=\"section\" aria-label={column.title}\n ownSx={{flex: '1 1 0', minWidth: COLUMN_MIN_WIDTH_PIXELS, p: 1.5, scrollSnapAlign: 'start', borderRadius: 3}}>\n <KanbanColumnHeader direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center', mb: 1.5, px: 0.5}}>\n <KanbanColumnTitle variant=\"subtitle2\" component=\"h3\" ownSx={{flexGrow: 1, minWidth: 0}}>{column.title}</KanbanColumnTitle>\n <Chip size=\"small\" label={count} color={isOver ? 'warning' : 'default'}\n title={isOver ? t('overLimit', {limit: column.limit}) : undefined} />\n {onAddCard && (\n <Tooltip title={t('addCard', {column: column.title})}>\n <IconButton size=\"small\" aria-label={t('addCard', {column: column.title})} onClick={() => setAddingColumnId(column.id)}>\n <AddRoundedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n <ActionsMenu label={t('columnActions', {column: column.title})} actions={columnActions?.(column)} />\n {column.collapsible && (\n <Tooltip title={t('collapseColumn', {column: column.title})}>\n <IconButton size=\"small\" aria-label={t('collapseColumn', {column: column.title})} aria-expanded=\"true\"\n onClick={() => toggleColumn(column.id)}>\n <KeyboardDoubleArrowLeftRoundedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </KanbanColumnHeader>\n {addingColumnId === column.id && (\n <KanbanQuickAdd ownSx={{mb: 1}}>\n <QuickAdd columnTitle={column.title} t={t} onClose={() => setAddingColumnId(null)}\n onAdd={(title) => onAddCard({columnId: column.id, title})} />\n </KanbanQuickAdd>\n )}\n <Droppable droppableId={column.id}>\n {(droppableProvided, droppableSnapshot) => (\n <KanbanDropZone ref={droppableProvided.innerRef} {...droppableProvided.droppableProps} spacing={1}\n ownSx={{\n minHeight: EMPTY_COLUMN_MIN_HEIGHT, borderRadius: 2, transition: 'background-color 160ms',\n bgcolor: droppableSnapshot.isDraggingOver ? 'action.hover' : 'transparent',\n }}>\n {columnCards.map((card, index) => (\n <Draggable key={card.id} draggableId={card.id} index={index}>\n {(draggableProvided, draggableSnapshot) => (\n <KanbanCard ref={draggableProvided.innerRef} {...draggableProvided.draggableProps} {...draggableProvided.dragHandleProps}\n elevation={draggableSnapshot.isDragging ? 8 : 1}\n onClick={onCardClick ? () => onCardClick(card.id) : undefined}\n ownSx={{p: 1.5, borderRadius: 2, cursor: 'grab', position: 'relative', '&:focus-visible': {outline: 2, outlineColor: 'primary.main'}}}>\n {/* el «⋯» arriba a la derecha; el contenido le deja su lugar */}\n {cardActions && (\n <KanbanCardActions ownSx={{position: 'absolute', top: 4, right: 4}}>\n <ActionsMenu label={t('cardActions', {title: card.title})} actions={cardActions(card)} />\n </KanbanCardActions>\n )}\n <KanbanCardContent ownSx={cardActions ? {pr: 3} : undefined}>\n {renderCard ? renderCard(card) : <DefaultCard card={card} t={t} today={today} onComplete={onCardComplete} />}\n </KanbanCardContent>\n </KanbanCard>\n )}\n </Draggable>\n ))}\n {droppableProvided.placeholder}\n {/* vacía de verdad, o con tarjetas que el filtro de la pantalla esconde (no se dice «sin tarjetas») */}\n {columnCards.length === 0 && !droppableSnapshot.isDraggingOver && addingColumnId !== column.id && (\n <KanbanEmpty variant=\"caption\" color=\"text.secondary\" ownSx={{textAlign: 'center', py: 3}}>\n {total > 0 ? t('emptyFiltered') : t('empty')}\n </KanbanEmpty>\n )}\n </KanbanDropZone>\n )}\n </Droppable>\n </KanbanColumn>\n );\n })}\n </KanbanRoot>\n </DragDropContext>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst KanbanBoard = withPieceSlots(KanbanBoardContent, THEME_NAME);\nexport default KanbanBoard;\n"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import Stack from "@mui/material/Stack";
7
7
  import Typography from "@mui/material/Typography";
8
8
  import { FLOATING_BOTTOM_SPACE_CSS_VARIABLE } from "../appShell/shellSizes.js";
9
9
  import { DEFAULT_COOKIE_CONSENT_KEY, useCookieConsent } from "./useCookieConsent.js";
10
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
10
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
11
11
  import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
12
12
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
13
13
  const THEME_NAME = "CalcitaCookieNotice";
@@ -16,7 +16,7 @@ const NoticeText = piecePart(THEME_NAME, "Text", Typography);
16
16
  const NoticeActions = piecePart(THEME_NAME, "Actions", Stack);
17
17
  const NOTICE_MAX_WIDTH = 420;
18
18
  const NOTICE_Z_INDEX = 1200;
19
- function CookieNotice(props) {
19
+ function CookieNoticeContent(props) {
20
20
  const {
21
21
  version = "1",
22
22
  storageKey = DEFAULT_COOKIE_CONSENT_KEY,
@@ -73,6 +73,7 @@ function CookieNotice(props) {
73
73
  }
74
74
  );
75
75
  }
76
+ const CookieNotice = withPieceSlots(CookieNoticeContent, THEME_NAME);
76
77
  export {
77
78
  CookieNotice as default
78
79
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CookieNotice.js","sources":["../../src/legal/CookieNotice.jsx"],"sourcesContent":["// El aviso de cookies: un recuadro abajo con el texto, la liga a la política y «Aceptar». Sale hasta que la persona acepta\n// ESA versión del aviso en este navegador; al cambiar la versión vuelve a salir. No tapa la pantalla ni la bloquea: se puede\n// seguir trabajando.\n//\n// La política se abre con su dirección (policyHref, en otra pestaña) o con lo que diga la pantalla (onPolicyClick: un\n// PdfViewerDialog, por ejemplo). El texto, los botones y dónde se recuerda se cambian desde afuera; para uno a su manera está\n// useCookieConsent.\n//\n// Con la barra de pestañas abajo del teléfono, se sube para no quedar encima (FLOATING_BOTTOM_SPACE del marco).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCookieNotice con defaultProps y\n// styleOverrides de sus partes: root, text, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport Link from '@mui/material/Link';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {FLOATING_BOTTOM_SPACE_CSS_VARIABLE} from '@/appShell/shellSizes.js';\nimport {DEFAULT_COOKIE_CONSENT_KEY, useCookieConsent} from '@/legal/useCookieConsent.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaCookieNotice)\nconst THEME_NAME = 'CalcitaCookieNotice';\nconst NoticeRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst NoticeText = piecePart(THEME_NAME, 'Text', Typography);\nconst NoticeActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n// lo ancho del recuadro en escritorio: un párrafo cómodo, no toda la orilla\nconst NOTICE_MAX_WIDTH = 420;\n// por encima de la app, debajo de los diálogos (MUI: modal 1300)\nconst NOTICE_Z_INDEX = 1200;\n\n/**\n * @param {object} props\n * @param {string} [props.version] la del aviso; al cambiarla se vuelve a preguntar (por omisión '1')\n * @param {string} [props.storageKey] dónde se recuerda en este navegador (por omisión 'calcita:cookieConsent')\n * @param {import('react').ReactNode} [props.text] ya traducido; por omisión el del paquete\n * @param {string} [props.policyHref] la dirección de la política (se abre en otra pestaña)\n * @param {() => void} [props.onPolicyClick] en lugar de la dirección: la pantalla la abre a su manera\n * @param {string} [props.policyLabel] ya traducido; por omisión «Política de cookies»\n * @param {string} [props.acceptLabel] ya traducido; por omisión «Aceptar»\n * @param {(acceptance: {version: string, acceptedAt: string}) => void} [props.onAccept] al aceptar (para registrarlo en su API)\n * @param {import('react').ReactNode} [props.actions] botones suyos junto a «Aceptar» («Configurar»)\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function CookieNotice(props) {\n const {\n version = '1', storageKey = DEFAULT_COOKIE_CONSENT_KEY, text, policyHref, onPolicyClick, policyLabel, acceptLabel, onAccept, actions, sx,\n texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {hasAccepted, accept} = useCookieConsent({version, storageKey});\n\n // guard clause: ya aceptó esta versión\n if (hasAccepted) {\n return null;\n }\n\n const policyText = policyLabel ?? t('legal.cookies.policy');\n const policyLink = onPolicyClick\n ? <Link component=\"button\" type=\"button\" onClick={onPolicyClick} sx={{verticalAlign: 'baseline'}}>{policyText}</Link>\n : policyHref && <Link href={policyHref} target=\"_blank\" rel=\"noopener noreferrer\">{policyText}</Link>;\n\n return (\n <NoticeRoot\n role=\"region\"\n aria-label={t('legal.cookies.region')}\n elevation={8}\n ownSx={{\n position: 'fixed', zIndex: NOTICE_Z_INDEX, left: {xs: 16, sm: 24}, right: {xs: 16, sm: 'auto'}, maxWidth: {sm: NOTICE_MAX_WIDTH},\n bottom: `calc(16px + env(safe-area-inset-bottom, 0px) + var(${FLOATING_BOTTOM_SPACE_CSS_VARIABLE}, 0px))`,\n p: 2.5, borderRadius: 3,\n }}\n sx={sx}\n >\n <NoticeText variant=\"body2\" ownSx={{mb: 2}}>\n {text ?? t('legal.cookies.text')} {policyLink}\n </NoticeText>\n <NoticeActions direction=\"row\" ownSx={{gap: 1, justifyContent: 'flex-end', flexWrap: 'wrap'}}>\n {actions}\n <Button variant=\"contained\" onClick={() => {\n accept();\n onAccept?.({version, acceptedAt: new Date().toISOString()});\n }}>\n {acceptLabel ?? t('legal.cookies.accept')}\n </Button>\n </NoticeActions>\n </NoticeRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AA2BA,MAAM,aAAa;AACnB,MAAM,aAAa,UAAU,YAAY,QAAQ,KAAK;AACtD,MAAM,aAAa,UAAU,YAAY,QAAQ,UAAU;AAC3D,MAAM,gBAAgB,UAAU,YAAY,WAAW,KAAK;AAG5D,MAAM,mBAAmB;AAEzB,MAAM,iBAAiB;AAgBvB,SAAwB,aAAa,OAAO;AACxC,QAAM;AAAA,IACF,UAAU;AAAA,IAAK,aAAa;AAAA,IAA4B;AAAA,IAAM;AAAA,IAAY;AAAA,IAAe;AAAA,IAAa;AAAA,IAAa;AAAA,IAAU;AAAA,IAAS;AAAA,IACtI;AAAA,IACA,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,aAAa,OAAA,IAAU,iBAAiB,EAAC,SAAS,YAAW;AAGpE,MAAI,aAAa;AACb,WAAO;AAAA,EACX;AAEA,QAAM,aAAa,eAAe,EAAE,sBAAsB;AAC1D,QAAM,aAAa,gBACb,oBAAC,MAAA,EAAK,WAAU,UAAS,MAAK,UAAS,SAAS,eAAe,IAAI,EAAC,eAAe,cAAc,UAAA,WAAA,CAAW,IAC5G,cAAc,oBAAC,MAAA,EAAK,MAAM,YAAY,QAAO,UAAS,KAAI,uBAAuB,UAAA,WAAA,CAAW;AAElG,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAK;AAAA,MACL,cAAY,EAAE,sBAAsB;AAAA,MACpC,WAAW;AAAA,MACX,OAAO;AAAA,QACH,UAAU;AAAA,QAAS,QAAQ;AAAA,QAAgB,MAAM,EAAC,IAAI,IAAI,IAAI,GAAA;AAAA,QAAK,OAAO,EAAC,IAAI,IAAI,IAAI,OAAA;AAAA,QAAS,UAAU,EAAC,IAAI,iBAAA;AAAA,QAC/G,QAAQ,sDAAsD,kCAAkC;AAAA,QAChG,GAAG;AAAA,QAAK,cAAc;AAAA,MAAA;AAAA,MAE1B;AAAA,MAEA,UAAA;AAAA,QAAA,qBAAC,cAAW,SAAQ,SAAQ,OAAO,EAAC,IAAI,KACnC,UAAA;AAAA,UAAA,QAAQ,EAAE,oBAAoB;AAAA,UAAE;AAAA,UAAE;AAAA,QAAA,GACvC;AAAA,QACA,qBAAC,eAAA,EAAc,WAAU,OAAM,OAAO,EAAC,KAAK,GAAG,gBAAgB,YAAY,UAAU,OAAA,GAChF,UAAA;AAAA,UAAA;AAAA,UACD,oBAAC,QAAA,EAAO,SAAQ,aAAY,SAAS,MAAM;AACvC,mBAAA;AACA,uBAAW,EAAC,SAAS,aAAY,oBAAI,QAAO,YAAA,GAAc;AAAA,UAC9D,GACK,UAAA,eAAe,EAAE,sBAAsB,EAAA,CAC5C;AAAA,QAAA,EAAA,CACJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGZ;"}
1
+ {"version":3,"file":"CookieNotice.js","sources":["../../src/legal/CookieNotice.jsx"],"sourcesContent":["// El aviso de cookies: un recuadro abajo con el texto, la liga a la política y «Aceptar». Sale hasta que la persona acepta\n// ESA versión del aviso en este navegador; al cambiar la versión vuelve a salir. No tapa la pantalla ni la bloquea: se puede\n// seguir trabajando.\n//\n// La política se abre con su dirección (policyHref, en otra pestaña) o con lo que diga la pantalla (onPolicyClick: un\n// PdfViewerDialog, por ejemplo). El texto, los botones y dónde se recuerda se cambian desde afuera; para uno a su manera está\n// useCookieConsent.\n//\n// Con la barra de pestañas abajo del teléfono, se sube para no quedar encima (FLOATING_BOTTOM_SPACE del marco).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCookieNotice con defaultProps y\n// styleOverrides de sus partes: root, text, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport Link from '@mui/material/Link';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {FLOATING_BOTTOM_SPACE_CSS_VARIABLE} from '@/appShell/shellSizes.js';\nimport {DEFAULT_COOKIE_CONSENT_KEY, useCookieConsent} from '@/legal/useCookieConsent.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaCookieNotice)\nconst THEME_NAME = 'CalcitaCookieNotice';\nconst NoticeRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst NoticeText = piecePart(THEME_NAME, 'Text', Typography);\nconst NoticeActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n// lo ancho del recuadro en escritorio: un párrafo cómodo, no toda la orilla\nconst NOTICE_MAX_WIDTH = 420;\n// por encima de la app, debajo de los diálogos (MUI: modal 1300)\nconst NOTICE_Z_INDEX = 1200;\n\n/**\n * @param {object} props\n * @param {string} [props.version] la del aviso; al cambiarla se vuelve a preguntar (por omisión '1')\n * @param {string} [props.storageKey] dónde se recuerda en este navegador (por omisión 'calcita:cookieConsent')\n * @param {import('react').ReactNode} [props.text] ya traducido; por omisión el del paquete\n * @param {string} [props.policyHref] la dirección de la política (se abre en otra pestaña)\n * @param {() => void} [props.onPolicyClick] en lugar de la dirección: la pantalla la abre a su manera\n * @param {string} [props.policyLabel] ya traducido; por omisión «Política de cookies»\n * @param {string} [props.acceptLabel] ya traducido; por omisión «Aceptar»\n * @param {(acceptance: {version: string, acceptedAt: string}) => void} [props.onAccept] al aceptar (para registrarlo en su API)\n * @param {import('react').ReactNode} [props.actions] botones suyos junto a «Aceptar» («Configurar»)\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction CookieNoticeContent(props) {\n const {\n version = '1', storageKey = DEFAULT_COOKIE_CONSENT_KEY, text, policyHref, onPolicyClick, policyLabel, acceptLabel, onAccept, actions, sx,\n texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {hasAccepted, accept} = useCookieConsent({version, storageKey});\n\n // guard clause: ya aceptó esta versión\n if (hasAccepted) {\n return null;\n }\n\n const policyText = policyLabel ?? t('legal.cookies.policy');\n const policyLink = onPolicyClick\n ? <Link component=\"button\" type=\"button\" onClick={onPolicyClick} sx={{verticalAlign: 'baseline'}}>{policyText}</Link>\n : policyHref && <Link href={policyHref} target=\"_blank\" rel=\"noopener noreferrer\">{policyText}</Link>;\n\n return (\n <NoticeRoot\n role=\"region\"\n aria-label={t('legal.cookies.region')}\n elevation={8}\n ownSx={{\n position: 'fixed', zIndex: NOTICE_Z_INDEX, left: {xs: 16, sm: 24}, right: {xs: 16, sm: 'auto'}, maxWidth: {sm: NOTICE_MAX_WIDTH},\n bottom: `calc(16px + env(safe-area-inset-bottom, 0px) + var(${FLOATING_BOTTOM_SPACE_CSS_VARIABLE}, 0px))`,\n p: 2.5, borderRadius: 3,\n }}\n sx={sx}\n >\n <NoticeText variant=\"body2\" ownSx={{mb: 2}}>\n {text ?? t('legal.cookies.text')} {policyLink}\n </NoticeText>\n <NoticeActions direction=\"row\" ownSx={{gap: 1, justifyContent: 'flex-end', flexWrap: 'wrap'}}>\n {actions}\n <Button variant=\"contained\" onClick={() => {\n accept();\n onAccept?.({version, acceptedAt: new Date().toISOString()});\n }}>\n {acceptLabel ?? t('legal.cookies.accept')}\n </Button>\n </NoticeActions>\n </NoticeRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst CookieNotice = withPieceSlots(CookieNoticeContent, THEME_NAME);\nexport default CookieNotice;\n"],"names":[],"mappings":";;;;;;;;;;;;AA2BA,MAAM,aAAa;AACnB,MAAM,aAAa,UAAU,YAAY,QAAQ,KAAK;AACtD,MAAM,aAAa,UAAU,YAAY,QAAQ,UAAU;AAC3D,MAAM,gBAAgB,UAAU,YAAY,WAAW,KAAK;AAG5D,MAAM,mBAAmB;AAEzB,MAAM,iBAAiB;AAgBvB,SAAS,oBAAoB,OAAO;AAChC,QAAM;AAAA,IACF,UAAU;AAAA,IAAK,aAAa;AAAA,IAA4B;AAAA,IAAM;AAAA,IAAY;AAAA,IAAe;AAAA,IAAa;AAAA,IAAa;AAAA,IAAU;AAAA,IAAS;AAAA,IACtI;AAAA,IACA,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,aAAa,OAAA,IAAU,iBAAiB,EAAC,SAAS,YAAW;AAGpE,MAAI,aAAa;AACb,WAAO;AAAA,EACX;AAEA,QAAM,aAAa,eAAe,EAAE,sBAAsB;AAC1D,QAAM,aAAa,gBACb,oBAAC,MAAA,EAAK,WAAU,UAAS,MAAK,UAAS,SAAS,eAAe,IAAI,EAAC,eAAe,cAAc,UAAA,WAAA,CAAW,IAC5G,cAAc,oBAAC,MAAA,EAAK,MAAM,YAAY,QAAO,UAAS,KAAI,uBAAuB,UAAA,WAAA,CAAW;AAElG,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAK;AAAA,MACL,cAAY,EAAE,sBAAsB;AAAA,MACpC,WAAW;AAAA,MACX,OAAO;AAAA,QACH,UAAU;AAAA,QAAS,QAAQ;AAAA,QAAgB,MAAM,EAAC,IAAI,IAAI,IAAI,GAAA;AAAA,QAAK,OAAO,EAAC,IAAI,IAAI,IAAI,OAAA;AAAA,QAAS,UAAU,EAAC,IAAI,iBAAA;AAAA,QAC/G,QAAQ,sDAAsD,kCAAkC;AAAA,QAChG,GAAG;AAAA,QAAK,cAAc;AAAA,MAAA;AAAA,MAE1B;AAAA,MAEA,UAAA;AAAA,QAAA,qBAAC,cAAW,SAAQ,SAAQ,OAAO,EAAC,IAAI,KACnC,UAAA;AAAA,UAAA,QAAQ,EAAE,oBAAoB;AAAA,UAAE;AAAA,UAAE;AAAA,QAAA,GACvC;AAAA,QACA,qBAAC,eAAA,EAAc,WAAU,OAAM,OAAO,EAAC,KAAK,GAAG,gBAAgB,YAAY,UAAU,OAAA,GAChF,UAAA;AAAA,UAAA;AAAA,UACD,oBAAC,QAAA,EAAO,SAAQ,aAAY,SAAS,MAAM;AACvC,mBAAA;AACA,uBAAW,EAAC,SAAS,aAAY,oBAAI,QAAO,YAAA,GAAc;AAAA,UAC9D,GACK,UAAA,eAAe,EAAE,sBAAsB,EAAA,CAC5C;AAAA,QAAA,EAAA,CACJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGZ;AAGA,MAAM,eAAe,eAAe,qBAAqB,UAAU;"}
@@ -11,7 +11,7 @@ import DialogTitle from "@mui/material/DialogTitle";
11
11
  import FormControlLabel from "@mui/material/FormControlLabel";
12
12
  import Stack from "@mui/material/Stack";
13
13
  import Typography from "@mui/material/Typography";
14
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
14
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
15
15
  import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
16
16
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
17
17
  const THEME_NAME = "CalcitaTermsAcceptanceDialog";
@@ -20,7 +20,7 @@ const TermsFrame = piecePart(THEME_NAME, "Frame", "iframe");
20
20
  const TermsFooter = piecePart(THEME_NAME, "Footer", Stack);
21
21
  const READ_TO_END_SLACK_PIXELS = 16;
22
22
  const IGNORED_CLOSE_REASONS = /* @__PURE__ */ new Set(["backdropClick", "escapeKeyDown"]);
23
- function TermsAcceptanceDialog(props) {
23
+ function TermsAcceptanceDialogContent(props) {
24
24
  const {
25
25
  open,
26
26
  version,
@@ -123,6 +123,7 @@ function TermsAcceptanceDialog(props) {
123
123
  }
124
124
  );
125
125
  }
126
+ const TermsAcceptanceDialog = withPieceSlots(TermsAcceptanceDialogContent, THEME_NAME);
126
127
  export {
127
128
  TermsAcceptanceDialog as default
128
129
  };