@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
@@ -1 +1 @@
1
- {"version":3,"file":"EventCalendar.js","sources":["../../src/calendar/EventCalendar.jsx"],"sourcesContent":["// Un calendario de eventos (@stackcraftmx/calcita/calendar): FullCalendar por dentro, con la barra del framework (anterior y\n// siguiente, «Hoy», el título y la vista con el control segmentado) y los colores del tema. En el idioma de\n// ToolkitProvider, la semana empieza en lunes y marca la hora actual. Las citas van en bloques de su color (el color es\n// información: el tipo de cita), no en puntitos.\n//\n// <EventCalendar events={[{id: '1', title: 'Entrega P-2375', start: '2026-10-20T10:00', end: '2026-10-20T11:00', tone: 'info'}]}\n// onEventClick={openDetail} onDateSelect={openNewEvent} onEventChange={(change) => api.patch(...)} />\n//\n// Arrastrar un evento lo cambia de día u hora: onEventChange recibe lo nuevo y, si truena (el servidor dijo que no), el\n// evento regresa a donde estaba. Sin onEventChange no se puede arrastrar; sin onDateSelect no se pueden elegir días.\n//\n// Se extiende sin tocar el framework: onDatesChange avisa el rango que se ve (para que el backend mande solo esas citas),\n// onViewChange la vista, renderEvent pinta cada cita a su manera (recibe la cita tal cual, con sus campos propios),\n// fullCalendarProps pasa lo demás de FullCalendar (horario laboral, días ocultos, horas visibles…) y texts los textos. El\n// detalle de una cita para su ventana: EventDetails.\n//\n// OJO: las horas se pintan en la zona del navegador (FullCalendar pide un complemento aparte para zonas con nombre).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaEventCalendar con defaultProps y\n// styleOverrides de sus partes: toolbar, navigation, title, calendar.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useRef, useState} from 'react';\nimport FullCalendar from '@fullcalendar/react';\nimport dayGridPlugin from '@fullcalendar/daygrid';\nimport interactionPlugin from '@fullcalendar/interaction';\nimport listPlugin from '@fullcalendar/list';\nimport timeGridPlugin from '@fullcalendar/timegrid';\nimport spanishLocale from '@fullcalendar/core/locales/es';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\nimport ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';\nimport ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded';\n\nimport {paletteOf} from '@/theme/components/paletteOf.js';\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport SegmentedControl from '@/ui/filters/SegmentedControl.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.CalcitaEventCalendar)\nconst THEME_NAME = 'CalcitaEventCalendar';\nconst CalendarToolbar = piecePart(THEME_NAME, 'Toolbar', Stack);\nconst CalendarNavigation = piecePart(THEME_NAME, 'Navigation', Stack);\nconst CalendarTitle = piecePart(THEME_NAME, 'Title', Typography);\nconst CalendarCalendar = piecePart(THEME_NAME, 'Calendar', Box);\n\n/** Las vistas del calendario (los nombres de FullCalendar). */\nexport const CALENDAR_VIEW = Object.freeze({month: 'dayGridMonth', week: 'timeGridWeek', day: 'timeGridDay', list: 'listWeek'});\n\n// el texto de cada vista en los textos del paquete (calendar.views.*)\nconst VIEW_TEXT_KEY = Object.freeze({\n [CALENDAR_VIEW.month]: 'month', [CALENDAR_VIEW.week]: 'week', [CALENDAR_VIEW.day]: 'day', [CALENDAR_VIEW.list]: 'list',\n});\n// cuántos eventos caben en un día del mes antes del «+2 más»\nconst DAY_MAX_EVENTS = 3;\nconst MONDAY = 1;\n\n/**\n * La primera letra en mayúscula y lo demás como viene: «octubre de 2026» → «Octubre de 2026». OJO: con CSS\n * (text-transform: capitalize) salía «Octubre De 2026»: en español solo va la primera.\n *\n * @param {string} text\n * @returns {string}\n */\nfunction capitalizeFirst(text) {\n return text ? text.charAt(0).toLocaleUpperCase() + text.slice(1) : text;\n}\n\n/**\n * Los colores del calendario sobre el tema (las variables CSS de FullCalendar), en claro y en oscuro.\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction calendarStylesOf(theme) {\n const palette = paletteOf(theme);\n return {\n '--fc-border-color': palette.divider,\n '--fc-page-bg-color': 'transparent',\n '--fc-neutral-bg-color': palette.action.hover,\n '--fc-today-bg-color': `color-mix(in srgb, ${palette.primary.main} 8%, transparent)`,\n '--fc-list-event-hover-bg-color': palette.action.hover,\n '--fc-now-indicator-color': palette.error.main,\n '--fc-highlight-color': `color-mix(in srgb, ${palette.primary.main} 14%, transparent)`,\n '& .fc': {fontFamily: 'inherit', fontSize: theme.typography.body2.fontSize},\n // los números de los días y los encabezados son ligas en FullCalendar: sin subrayado y del color del texto\n '& .fc a': {color: 'inherit', textDecoration: 'none'},\n '& .fc-col-header-cell-cushion': {fontWeight: 600, py: 1},\n '& .fc-event': {borderRadius: '6px', px: 0.5},\n // la hora no se encoge: en un día angosto se recortaba («1C» en lugar de «10»); lo que se corta es el nombre\n '& .fc-event-time': {flexShrink: 0, overflow: 'visible'},\n '& .fc-scrollgrid': {borderRadius: '12px', overflow: 'hidden'},\n '& .fc-list': {borderRadius: '12px'},\n };\n}\n\n/**\n * @param {object} props\n * @param {Array<{id: string, title: string, start: string, end?: string, allDay?: boolean, tone?: string}>} props.events\n * start y end como texto ISO; tone: un color del tema (por omisión primary)\n * @param {string} [props.initialView] una de CALENDAR_VIEW\n * @param {string[]} [props.views] las que se ofrecen en el control segmentado\n * @param {(eventId: string) => void} [props.onEventClick]\n * @param {(range: {start: string, end: string, allDay: boolean}) => void} [props.onDateSelect] al elegir días u horas\n * @param {(change: {id: string, start: string, end: string|null, allDay: boolean}) => Promise<unknown>|void} [props.onEventChange]\n * al arrastrar un evento; si truena, el evento regresa\n * @param {number|'auto'} [props.height]\n * @param {string} props.ariaLabel ya traducido\n * @param {(range: {start: string, end: string, view: string}) => void} [props.onDatesChange] cada que cambia lo que se ve (al\n * abrir, al ir al anterior o siguiente, al cambiar de vista): para pedir al backend solo las citas de ese rango\n * @param {(view: string) => void} [props.onViewChange] al cambiar de vista (CALENDAR_VIEW)\n * @param {(event: any) => import('react').ReactNode} [props.renderEvent] lo de adentro de cada cita (recibe la cita de events\n * tal cual, con sus campos propios)\n * @param {object} [props.fullCalendarProps] lo demás de FullCalendar (businessHours, hiddenDays, slotMinTime, locale…); lo\n * que el calendario controla (las citas, la barra, los eventos de arriba) no se reemplaza desde aquí\n * @param {object} [props.texts] los textos que cambian, con la forma de `calendar` en los textos del paquete\n */\nexport default function EventCalendar(props) {\n // lo que el proyecto puso en su tema (components.CalcitaEventCalendar.defaultProps) y encima lo que llega aquí\n const {\n events, initialView = CALENDAR_VIEW.month, views = Object.values(CALENDAR_VIEW), onEventClick, onDateSelect, onEventChange, height = 'auto', ariaLabel,\n onDatesChange, onViewChange, renderEvent, fullCalendarProps, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const theme = useTheme();\n const palette = paletteOf(theme);\n const {t} = useToolkitTranslation('calendar', texts);\n const {language} = useToolkitSettings();\n const calendarRef = useRef(null);\n const [title, setTitle] = useState('');\n const [view, setView] = useState(initialView);\n const calendarApi = () => calendarRef.current?.getApi();\n\n const coloredEvents = events.map((event) => {\n const color = palette[event.tone] ?? palette.primary;\n return {...event, backgroundColor: color.main, borderColor: color.main, textColor: color.contrastText};\n });\n\n const changeEvent = async ({event, revert}) => {\n try {\n await onEventChange({id: event.id, start: event.startStr, end: event.endStr || null, allDay: event.allDay});\n } catch {\n // el servidor dijo que no: el evento regresa a donde estaba (quien llama ya avisó el error)\n revert();\n }\n };\n\n return (\n <Stack spacing={2} role=\"region\" aria-label={ariaLabel}>\n <CalendarToolbar direction={{xs: 'column', md: 'row'}} spacing={1.5} ownSx={{alignItems: {md: 'center'}, justifyContent: 'space-between'}}>\n <CalendarNavigation direction=\"row\" spacing={1} ownSx={{alignItems: 'center'}}>\n <Tooltip title={t('previous')}>\n <IconButton aria-label={t('previous')} onClick={() => calendarApi()?.prev()}><ChevronLeftRoundedIcon /></IconButton>\n </Tooltip>\n <Tooltip title={t('next')}>\n <IconButton aria-label={t('next')} onClick={() => calendarApi()?.next()}><ChevronRightRoundedIcon /></IconButton>\n </Tooltip>\n <Button variant=\"outlined\" size=\"small\" onClick={() => calendarApi()?.today()}>{t('today')}</Button>\n <CalendarTitle variant=\"h6\" component=\"h2\" ownSx={{pl: 1}} aria-live=\"polite\">{capitalizeFirst(title)}</CalendarTitle>\n </CalendarNavigation>\n {views.length > 1 && (\n <SegmentedControl ariaLabel={t('view')} value={view} onChange={(nextView) => calendarApi()?.changeView(nextView)}\n options={views.map((value) => ({value, label: t(`views.${VIEW_TEXT_KEY[value]}`)}))} />\n )}\n </CalendarToolbar>\n <CalendarCalendar ownSx={calendarStylesOf}>\n {/* primero lo del proyecto (fullCalendarProps); lo de abajo es lo que el calendario controla y le gana */}\n <FullCalendar locale={language === 'es' ? spanishLocale : 'en'} firstDay={MONDAY} {...fullCalendarProps}\n ref={calendarRef} plugins={[dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin, ...(fullCalendarProps?.plugins ?? [])]}\n initialView={initialView} headerToolbar={false} height={height}\n nowIndicator dayMaxEvents={DAY_MAX_EVENTS} events={coloredEvents} eventDisplay=\"block\"\n eventContent={renderEvent ? (contentInfo) => renderEvent(events.find((event) => event.id === contentInfo.event.id) ?? contentInfo.event) : undefined}\n datesSet={(dateInfo) => {\n setTitle(dateInfo.view.title);\n if (dateInfo.view.type !== view) {\n onViewChange?.(dateInfo.view.type);\n }\n setView(dateInfo.view.type);\n onDatesChange?.({start: dateInfo.startStr, end: dateInfo.endStr, view: dateInfo.view.type});\n }}\n eventClick={onEventClick ? (clickInfo) => onEventClick(clickInfo.event.id) : undefined}\n selectable={Boolean(onDateSelect)} selectMirror\n select={onDateSelect ? (selectInfo) => {\n onDateSelect({start: selectInfo.startStr, end: selectInfo.endStr, allDay: selectInfo.allDay});\n calendarApi()?.unselect();\n } : undefined}\n editable={Boolean(onEventChange)} eventChange={onEventChange ? changeEvent : undefined} />\n </CalendarCalendar>\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EventCalendar.js","sources":["../../src/calendar/EventCalendar.jsx"],"sourcesContent":["// Un calendario de eventos (@stackcraftmx/calcita/calendar): FullCalendar por dentro, con la barra del framework (anterior y\n// siguiente, «Hoy», el título y la vista con el control segmentado) y los colores del tema. En el idioma de\n// ToolkitProvider, la semana empieza en lunes y marca la hora actual. Las citas van en bloques de su color (el color es\n// información: el tipo de cita), no en puntitos.\n//\n// <EventCalendar events={[{id: '1', title: 'Entrega P-2375', start: '2026-10-20T10:00', end: '2026-10-20T11:00', tone: 'info'}]}\n// onEventClick={openDetail} onDateSelect={openNewEvent} onEventChange={(change) => api.patch(...)} />\n//\n// Arrastrar un evento lo cambia de día u hora: onEventChange recibe lo nuevo y, si truena (el servidor dijo que no), el\n// evento regresa a donde estaba. Sin onEventChange no se puede arrastrar; sin onDateSelect no se pueden elegir días.\n//\n// Se extiende sin tocar el framework: onDatesChange avisa el rango que se ve (para que el backend mande solo esas citas),\n// onViewChange la vista, renderEvent pinta cada cita a su manera (recibe la cita tal cual, con sus campos propios),\n// fullCalendarProps pasa lo demás de FullCalendar (horario laboral, días ocultos, horas visibles…) y texts los textos. El\n// detalle de una cita para su ventana: EventDetails.\n//\n// OJO: las horas se pintan en la zona del navegador (FullCalendar pide un complemento aparte para zonas con nombre).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaEventCalendar con defaultProps y\n// styleOverrides de sus partes: toolbar, navigation, title, calendar.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useRef, useState} from 'react';\nimport FullCalendar from '@fullcalendar/react';\nimport dayGridPlugin from '@fullcalendar/daygrid';\nimport interactionPlugin from '@fullcalendar/interaction';\nimport listPlugin from '@fullcalendar/list';\nimport timeGridPlugin from '@fullcalendar/timegrid';\nimport spanishLocale from '@fullcalendar/core/locales/es';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\nimport ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';\nimport ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded';\n\nimport {paletteOf} from '@/theme/components/paletteOf.js';\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport SegmentedControl from '@/ui/filters/SegmentedControl.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.CalcitaEventCalendar)\nconst THEME_NAME = 'CalcitaEventCalendar';\nconst CalendarToolbar = piecePart(THEME_NAME, 'Toolbar', Stack);\nconst CalendarNavigation = piecePart(THEME_NAME, 'Navigation', Stack);\nconst CalendarTitle = piecePart(THEME_NAME, 'Title', Typography);\nconst CalendarCalendar = piecePart(THEME_NAME, 'Calendar', Box);\n\n/** Las vistas del calendario (los nombres de FullCalendar). */\nexport const CALENDAR_VIEW = Object.freeze({month: 'dayGridMonth', week: 'timeGridWeek', day: 'timeGridDay', list: 'listWeek'});\n\n// el texto de cada vista en los textos del paquete (calendar.views.*)\nconst VIEW_TEXT_KEY = Object.freeze({\n [CALENDAR_VIEW.month]: 'month', [CALENDAR_VIEW.week]: 'week', [CALENDAR_VIEW.day]: 'day', [CALENDAR_VIEW.list]: 'list',\n});\n// cuántos eventos caben en un día del mes antes del «+2 más»\nconst DAY_MAX_EVENTS = 3;\nconst MONDAY = 1;\n\n/**\n * La primera letra en mayúscula y lo demás como viene: «octubre de 2026» → «Octubre de 2026». OJO: con CSS\n * (text-transform: capitalize) salía «Octubre De 2026»: en español solo va la primera.\n *\n * @param {string} text\n * @returns {string}\n */\nfunction capitalizeFirst(text) {\n return text ? text.charAt(0).toLocaleUpperCase() + text.slice(1) : text;\n}\n\n/**\n * Los colores del calendario sobre el tema (las variables CSS de FullCalendar), en claro y en oscuro.\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction calendarStylesOf(theme) {\n const palette = paletteOf(theme);\n return {\n '--fc-border-color': palette.divider,\n '--fc-page-bg-color': 'transparent',\n '--fc-neutral-bg-color': palette.action.hover,\n '--fc-today-bg-color': `color-mix(in srgb, ${palette.primary.main} 8%, transparent)`,\n '--fc-list-event-hover-bg-color': palette.action.hover,\n '--fc-now-indicator-color': palette.error.main,\n '--fc-highlight-color': `color-mix(in srgb, ${palette.primary.main} 14%, transparent)`,\n '& .fc': {fontFamily: 'inherit', fontSize: theme.typography.body2.fontSize},\n // los números de los días y los encabezados son ligas en FullCalendar: sin subrayado y del color del texto\n '& .fc a': {color: 'inherit', textDecoration: 'none'},\n '& .fc-col-header-cell-cushion': {fontWeight: 600, py: 1},\n '& .fc-event': {borderRadius: '6px', px: 0.5},\n // la hora no se encoge: en un día angosto se recortaba («1C» en lugar de «10»); lo que se corta es el nombre\n '& .fc-event-time': {flexShrink: 0, overflow: 'visible'},\n '& .fc-scrollgrid': {borderRadius: '12px', overflow: 'hidden'},\n '& .fc-list': {borderRadius: '12px'},\n };\n}\n\n/**\n * @param {object} props\n * @param {Array<{id: string, title: string, start: string, end?: string, allDay?: boolean, tone?: string}>} props.events\n * start y end como texto ISO; tone: un color del tema (por omisión primary)\n * @param {string} [props.initialView] una de CALENDAR_VIEW\n * @param {string[]} [props.views] las que se ofrecen en el control segmentado\n * @param {(eventId: string) => void} [props.onEventClick]\n * @param {(range: {start: string, end: string, allDay: boolean}) => void} [props.onDateSelect] al elegir días u horas\n * @param {(change: {id: string, start: string, end: string|null, allDay: boolean}) => Promise<unknown>|void} [props.onEventChange]\n * al arrastrar un evento; si truena, el evento regresa\n * @param {number|'auto'} [props.height]\n * @param {string} props.ariaLabel ya traducido\n * @param {(range: {start: string, end: string, view: string}) => void} [props.onDatesChange] cada que cambia lo que se ve (al\n * abrir, al ir al anterior o siguiente, al cambiar de vista): para pedir al backend solo las citas de ese rango\n * @param {(view: string) => void} [props.onViewChange] al cambiar de vista (CALENDAR_VIEW)\n * @param {(event: any) => import('react').ReactNode} [props.renderEvent] lo de adentro de cada cita (recibe la cita de events\n * tal cual, con sus campos propios)\n * @param {object} [props.fullCalendarProps] lo demás de FullCalendar (businessHours, hiddenDays, slotMinTime, locale…); lo\n * que el calendario controla (las citas, la barra, los eventos de arriba) no se reemplaza desde aquí\n * @param {object} [props.texts] los textos que cambian, con la forma de `calendar` en los textos del paquete\n */\nfunction EventCalendarContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaEventCalendar.defaultProps) y encima lo que llega aquí\n const {\n events, initialView = CALENDAR_VIEW.month, views = Object.values(CALENDAR_VIEW), onEventClick, onDateSelect, onEventChange, height = 'auto', ariaLabel,\n onDatesChange, onViewChange, renderEvent, fullCalendarProps, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const theme = useTheme();\n const palette = paletteOf(theme);\n const {t} = useToolkitTranslation('calendar', texts);\n const {language} = useToolkitSettings();\n const calendarRef = useRef(null);\n const [title, setTitle] = useState('');\n const [view, setView] = useState(initialView);\n const calendarApi = () => calendarRef.current?.getApi();\n\n const coloredEvents = events.map((event) => {\n const color = palette[event.tone] ?? palette.primary;\n return {...event, backgroundColor: color.main, borderColor: color.main, textColor: color.contrastText};\n });\n\n const changeEvent = async ({event, revert}) => {\n try {\n await onEventChange({id: event.id, start: event.startStr, end: event.endStr || null, allDay: event.allDay});\n } catch {\n // el servidor dijo que no: el evento regresa a donde estaba (quien llama ya avisó el error)\n revert();\n }\n };\n\n return (\n <Stack spacing={2} role=\"region\" aria-label={ariaLabel}>\n <CalendarToolbar direction={{xs: 'column', md: 'row'}} spacing={1.5} ownSx={{alignItems: {md: 'center'}, justifyContent: 'space-between'}}>\n <CalendarNavigation direction=\"row\" spacing={1} ownSx={{alignItems: 'center'}}>\n <Tooltip title={t('previous')}>\n <IconButton aria-label={t('previous')} onClick={() => calendarApi()?.prev()}><ChevronLeftRoundedIcon /></IconButton>\n </Tooltip>\n <Tooltip title={t('next')}>\n <IconButton aria-label={t('next')} onClick={() => calendarApi()?.next()}><ChevronRightRoundedIcon /></IconButton>\n </Tooltip>\n <Button variant=\"outlined\" size=\"small\" onClick={() => calendarApi()?.today()}>{t('today')}</Button>\n <CalendarTitle variant=\"h6\" component=\"h2\" ownSx={{pl: 1}} aria-live=\"polite\">{capitalizeFirst(title)}</CalendarTitle>\n </CalendarNavigation>\n {views.length > 1 && (\n <SegmentedControl ariaLabel={t('view')} value={view} onChange={(nextView) => calendarApi()?.changeView(nextView)}\n options={views.map((value) => ({value, label: t(`views.${VIEW_TEXT_KEY[value]}`)}))} />\n )}\n </CalendarToolbar>\n <CalendarCalendar ownSx={calendarStylesOf}>\n {/* primero lo del proyecto (fullCalendarProps); lo de abajo es lo que el calendario controla y le gana */}\n <FullCalendar locale={language === 'es' ? spanishLocale : 'en'} firstDay={MONDAY} {...fullCalendarProps}\n ref={calendarRef} plugins={[dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin, ...(fullCalendarProps?.plugins ?? [])]}\n initialView={initialView} headerToolbar={false} height={height}\n nowIndicator dayMaxEvents={DAY_MAX_EVENTS} events={coloredEvents} eventDisplay=\"block\"\n eventContent={renderEvent ? (contentInfo) => renderEvent(events.find((event) => event.id === contentInfo.event.id) ?? contentInfo.event) : undefined}\n datesSet={(dateInfo) => {\n setTitle(dateInfo.view.title);\n if (dateInfo.view.type !== view) {\n onViewChange?.(dateInfo.view.type);\n }\n setView(dateInfo.view.type);\n onDatesChange?.({start: dateInfo.startStr, end: dateInfo.endStr, view: dateInfo.view.type});\n }}\n eventClick={onEventClick ? (clickInfo) => onEventClick(clickInfo.event.id) : undefined}\n selectable={Boolean(onDateSelect)} selectMirror\n select={onDateSelect ? (selectInfo) => {\n onDateSelect({start: selectInfo.startStr, end: selectInfo.endStr, allDay: selectInfo.allDay});\n calendarApi()?.unselect();\n } : undefined}\n editable={Boolean(onEventChange)} eventChange={onEventChange ? changeEvent : undefined} />\n </CalendarCalendar>\n </Stack>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst EventCalendar = withPieceSlots(EventCalendarContent, THEME_NAME);\nexport default EventCalendar;\n"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ import { initialsOf } from "../appShell/menuItemText.js";
16
16
  import { reminderOf, isOpenableMeetingUrl, REMINDER_UNIT } from "./calendarEvents.js";
17
17
  import { useFormatters } from "../toolkit/useFormatters.js";
18
18
  import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
19
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
19
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
20
20
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
21
21
  const THEME_NAME = "CalcitaEventDetails";
22
22
  const EventRow = piecePart(THEME_NAME, "Row", Stack);
@@ -45,7 +45,7 @@ function DetailRow({ Icon, label, children }) {
45
45
  /* @__PURE__ */ jsx(EventRowContent, { ownSx: { minWidth: 0, flexGrow: 1 }, children })
46
46
  ] });
47
47
  }
48
- function EventDetails(props) {
48
+ function EventDetailsContent(props) {
49
49
  const { event, actions, titleId, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
50
50
  warnUnknownProps(THEME_NAME, unknownProps);
51
51
  const { t } = useToolkitTranslation("calendar", texts);
@@ -84,6 +84,7 @@ function EventDetails(props) {
84
84
  actions && /* @__PURE__ */ jsx(EventActions, { direction: "row", spacing: 1, useFlexGap: true, ownSx: { justifyContent: "flex-end", flexWrap: "wrap" }, children: actions })
85
85
  ] });
86
86
  }
87
+ const EventDetails = withPieceSlots(EventDetailsContent, THEME_NAME);
87
88
  export {
88
89
  ATTENDEE_RESPONSE,
89
90
  EventDetails as default
@@ -1 +1 @@
1
- {"version":3,"file":"EventDetails.js","sources":["../../src/calendar/EventDetails.jsx"],"sourcesContent":["// El detalle de una cita, para la ventana que se abre al picarla en el calendario: su título con el color de su tipo,\n// cuándo (el día y las horas), dónde, la liga de la reunión con «Unirse», los invitados con su respuesta, el recordatorio y\n// las notas. Pinta lo que la cita traiga; lo que no trae no ocupa lugar.\n//\n// <EventDetails event={{title: 'Junta de cierre', start: '2026-10-20T10:00', end: '2026-10-20T11:00', location: 'Sala 2',\n// meetingUrl: 'https://meet.example.com/abc', attendees: [{id: 'ana', name: 'Ana', response: 'accepted'}],\n// reminderMinutes: 15}}\n// actions={<Button onClick={edit}>Editar</Button>} />\n//\n// No llama a ningún servidor ni abre la reunión por su cuenta: «Unirse» es una liga (solo http o https) y lo demás lo pone la\n// pantalla en actions. Sus textos se cambian con texts (la forma de `calendar` en los textos del paquete).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaEventDetails con defaultProps y\n// styleOverrides de sus partes: row, rowContent, titleRow, toneDot, linkRow, link, guestsTitle, guest, guestAvatar,\n// guestName, notes, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Avatar from '@mui/material/Avatar';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport AccessTimeRoundedIcon from '@mui/icons-material/AccessTimeRounded';\nimport NotesRoundedIcon from '@mui/icons-material/NotesRounded';\nimport NotificationsNoneRoundedIcon from '@mui/icons-material/NotificationsNoneRounded';\nimport PeopleOutlineRoundedIcon from '@mui/icons-material/PeopleOutlineRounded';\nimport PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined';\nimport VideocamOutlinedIcon from '@mui/icons-material/VideocamOutlined';\n\nimport {initialsOf} from '@/appShell/menuItemText.js';\nimport {REMINDER_UNIT, isOpenableMeetingUrl, reminderOf} from '@/calendar/calendarEvents.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\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.CalcitaEventDetails)\nconst THEME_NAME = 'CalcitaEventDetails';\nconst EventRow = piecePart(THEME_NAME, 'Row', Stack);\nconst EventRowContent = piecePart(THEME_NAME, 'RowContent', Box);\nconst EventTitleRow = piecePart(THEME_NAME, 'TitleRow', Stack);\nconst EventToneDot = piecePart(THEME_NAME, 'ToneDot', Box);\nconst EventLinkRow = piecePart(THEME_NAME, 'LinkRow', Stack);\nconst EventLink = piecePart(THEME_NAME, 'Link', Typography);\nconst EventGuestsTitle = piecePart(THEME_NAME, 'GuestsTitle', Typography);\nconst EventGuest = piecePart(THEME_NAME, 'Guest', Stack);\nconst EventGuestAvatar = piecePart(THEME_NAME, 'GuestAvatar', Avatar);\nconst EventGuestName = piecePart(THEME_NAME, 'GuestName', Typography);\nconst EventNotes = piecePart(THEME_NAME, 'Notes', Typography);\nconst EventActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/** Las respuestas de un invitado. */\nexport const ATTENDEE_RESPONSE = Object.freeze({accepted: 'accepted', declined: 'declined', pending: 'pending'});\n// el color de cada respuesta (el color es información: verde va, rojo no va, gris no ha contestado)\nconst RESPONSE_COLOR = Object.freeze({\n [ATTENDEE_RESPONSE.accepted]: 'success', [ATTENDEE_RESPONSE.declined]: 'error', [ATTENDEE_RESPONSE.pending]: 'default',\n});\n// un día completo viene sin hora («2026-10-20»)\nconst WHOLE_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst ICON_SIZE = 20;\n\n/** Un renglón del detalle: su ícono a la izquierda y lo de adentro. */\nfunction DetailRow({Icon, label, children}) {\n return (\n <EventRow direction=\"row\" spacing={1.5} ownSx={{alignItems: 'flex-start'}} aria-label={label} role=\"group\">\n <Icon sx={{fontSize: ICON_SIZE, color: 'text.secondary', mt: 0.25}} aria-hidden=\"true\" />\n <EventRowContent ownSx={{minWidth: 0, flexGrow: 1}}>{children}</EventRowContent>\n </EventRow>\n );\n}\n\n/**\n * @param {object} props\n * @param {{title: string, start: string, end?: string|null, allDay?: boolean, tone?: string, location?: string, meetingUrl?: string, attendees?: Array<{id: string, name: string, email?: string, response?: 'accepted'|'declined'|'pending'}>, reminderMinutes?: number|null, description?: string}} props.event\n * start y end como texto ISO (o AAAA-MM-DD un día completo); tone: el color de su tipo\n * @param {import('react').ReactNode} [props.actions] botones de la pantalla (editar, borrar, responder…)\n * @param {string} [props.titleId] el id del título: la ventana que lo contiene se nombra con él (aria-labelledby)\n * @param {object} [props.texts] los textos que cambian, con la forma de `calendar` en los textos del paquete\n */\nexport default function EventDetails(props) {\n // lo que el proyecto puso en su tema (components.CalcitaEventDetails.defaultProps) y encima lo que llega aquí\n const {event, actions, titleId, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('calendar', texts);\n const {formatDate, formatTime} = useFormatters();\n const isWholeDay = event.allDay || WHOLE_DAY_PATTERN.test(event.start);\n let when = formatDate(event.start);\n if (!isWholeDay) {\n when = t('details.timeRange', {date: formatDate(event.start), start: formatTime(event.start), end: event.end ? formatTime(event.end) : ''});\n }\n const reminder = reminderOf(event.reminderMinutes);\n const canJoin = isOpenableMeetingUrl(event.meetingUrl);\n\n return (\n <Stack spacing={2}>\n <EventTitleRow direction=\"row\" spacing={1.5} ownSx={{alignItems: 'center'}}>\n <EventToneDot aria-hidden=\"true\" ownSx={{width: 12, height: 12, borderRadius: '4px', flexShrink: 0, bgcolor: `${event.tone ?? 'primary'}.main`}} />\n <Typography id={titleId} variant=\"h6\" component=\"h2\">{event.title}</Typography>\n </EventTitleRow>\n <DetailRow Icon={AccessTimeRoundedIcon} label={t('details.when')}>\n <Typography variant=\"body2\">{isWholeDay ? t('details.allDay', {date: when}) : when}</Typography>\n </DetailRow>\n {event.location && (\n <DetailRow Icon={PlaceOutlinedIcon} label={t('details.location')}>\n <Typography variant=\"body2\">{event.location}</Typography>\n </DetailRow>\n )}\n {event.meetingUrl && (\n <DetailRow Icon={VideocamOutlinedIcon} label={t('details.meeting')}>\n <EventLinkRow direction=\"row\" spacing={1} ownSx={{alignItems: 'center', flexWrap: 'wrap'}} useFlexGap>\n {canJoin && (\n <Button variant=\"contained\" size=\"small\" href={event.meetingUrl} target=\"_blank\" rel=\"noreferrer\">{t('details.join')}</Button>\n )}\n <EventLink variant=\"caption\" color=\"text.secondary\" ownSx={{wordBreak: 'break-all'}}>{event.meetingUrl}</EventLink>\n </EventLinkRow>\n </DetailRow>\n )}\n {event.attendees?.length > 0 && (\n <DetailRow Icon={PeopleOutlineRoundedIcon} label={t('details.attendees')}>\n <EventGuestsTitle variant=\"body2\" ownSx={{mb: 0.75}}>{t('details.attendeesCount', {count: event.attendees.length})}</EventGuestsTitle>\n <Stack spacing={0.75}>\n {event.attendees.map((attendee) => {\n const response = attendee.response ?? ATTENDEE_RESPONSE.pending;\n return (\n <EventGuest key={attendee.id} direction=\"row\" spacing={1} ownSx={{alignItems: 'center'}}>\n <EventGuestAvatar ownSx={{width: 24, height: 24, fontSize: 11}}>{initialsOf(attendee.name)}</EventGuestAvatar>\n <EventGuestName variant=\"body2\" ownSx={{flexGrow: 1, minWidth: 0}} noWrap>{attendee.name}</EventGuestName>\n <Chip size=\"small\" variant=\"outlined\" color={RESPONSE_COLOR[response] ?? 'default'} label={t(`details.response.${response}`)} />\n </EventGuest>\n );\n })}\n </Stack>\n </DetailRow>\n )}\n {reminder.unit !== REMINDER_UNIT.none && (\n <DetailRow Icon={NotificationsNoneRoundedIcon} label={t('details.reminder')}>\n <Typography variant=\"body2\">{t(`details.reminderUnit.${reminder.unit}`, {count: reminder.count})}</Typography>\n </DetailRow>\n )}\n {event.description && (\n <DetailRow Icon={NotesRoundedIcon} label={t('details.notes')}>\n <EventNotes variant=\"body2\" ownSx={{whiteSpace: 'pre-wrap'}}>{event.description}</EventNotes>\n </DetailRow>\n )}\n {actions && <EventActions direction=\"row\" spacing={1} useFlexGap ownSx={{justifyContent: 'flex-end', flexWrap: 'wrap'}}>{actions}</EventActions>}\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EventDetails.js","sources":["../../src/calendar/EventDetails.jsx"],"sourcesContent":["// El detalle de una cita, para la ventana que se abre al picarla en el calendario: su título con el color de su tipo,\n// cuándo (el día y las horas), dónde, la liga de la reunión con «Unirse», los invitados con su respuesta, el recordatorio y\n// las notas. Pinta lo que la cita traiga; lo que no trae no ocupa lugar.\n//\n// <EventDetails event={{title: 'Junta de cierre', start: '2026-10-20T10:00', end: '2026-10-20T11:00', location: 'Sala 2',\n// meetingUrl: 'https://meet.example.com/abc', attendees: [{id: 'ana', name: 'Ana', response: 'accepted'}],\n// reminderMinutes: 15}}\n// actions={<Button onClick={edit}>Editar</Button>} />\n//\n// No llama a ningún servidor ni abre la reunión por su cuenta: «Unirse» es una liga (solo http o https) y lo demás lo pone la\n// pantalla en actions. Sus textos se cambian con texts (la forma de `calendar` en los textos del paquete).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaEventDetails con defaultProps y\n// styleOverrides de sus partes: row, rowContent, titleRow, toneDot, linkRow, link, guestsTitle, guest, guestAvatar,\n// guestName, notes, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Avatar from '@mui/material/Avatar';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport AccessTimeRoundedIcon from '@mui/icons-material/AccessTimeRounded';\nimport NotesRoundedIcon from '@mui/icons-material/NotesRounded';\nimport NotificationsNoneRoundedIcon from '@mui/icons-material/NotificationsNoneRounded';\nimport PeopleOutlineRoundedIcon from '@mui/icons-material/PeopleOutlineRounded';\nimport PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined';\nimport VideocamOutlinedIcon from '@mui/icons-material/VideocamOutlined';\n\nimport {initialsOf} from '@/appShell/menuItemText.js';\nimport {REMINDER_UNIT, isOpenableMeetingUrl, reminderOf} from '@/calendar/calendarEvents.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\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.CalcitaEventDetails)\nconst THEME_NAME = 'CalcitaEventDetails';\nconst EventRow = piecePart(THEME_NAME, 'Row', Stack);\nconst EventRowContent = piecePart(THEME_NAME, 'RowContent', Box);\nconst EventTitleRow = piecePart(THEME_NAME, 'TitleRow', Stack);\nconst EventToneDot = piecePart(THEME_NAME, 'ToneDot', Box);\nconst EventLinkRow = piecePart(THEME_NAME, 'LinkRow', Stack);\nconst EventLink = piecePart(THEME_NAME, 'Link', Typography);\nconst EventGuestsTitle = piecePart(THEME_NAME, 'GuestsTitle', Typography);\nconst EventGuest = piecePart(THEME_NAME, 'Guest', Stack);\nconst EventGuestAvatar = piecePart(THEME_NAME, 'GuestAvatar', Avatar);\nconst EventGuestName = piecePart(THEME_NAME, 'GuestName', Typography);\nconst EventNotes = piecePart(THEME_NAME, 'Notes', Typography);\nconst EventActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/** Las respuestas de un invitado. */\nexport const ATTENDEE_RESPONSE = Object.freeze({accepted: 'accepted', declined: 'declined', pending: 'pending'});\n// el color de cada respuesta (el color es información: verde va, rojo no va, gris no ha contestado)\nconst RESPONSE_COLOR = Object.freeze({\n [ATTENDEE_RESPONSE.accepted]: 'success', [ATTENDEE_RESPONSE.declined]: 'error', [ATTENDEE_RESPONSE.pending]: 'default',\n});\n// un día completo viene sin hora («2026-10-20»)\nconst WHOLE_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst ICON_SIZE = 20;\n\n/** Un renglón del detalle: su ícono a la izquierda y lo de adentro. */\nfunction DetailRow({Icon, label, children}) {\n return (\n <EventRow direction=\"row\" spacing={1.5} ownSx={{alignItems: 'flex-start'}} aria-label={label} role=\"group\">\n <Icon sx={{fontSize: ICON_SIZE, color: 'text.secondary', mt: 0.25}} aria-hidden=\"true\" />\n <EventRowContent ownSx={{minWidth: 0, flexGrow: 1}}>{children}</EventRowContent>\n </EventRow>\n );\n}\n\n/**\n * @param {object} props\n * @param {{title: string, start: string, end?: string|null, allDay?: boolean, tone?: string, location?: string, meetingUrl?: string, attendees?: Array<{id: string, name: string, email?: string, response?: 'accepted'|'declined'|'pending'}>, reminderMinutes?: number|null, description?: string}} props.event\n * start y end como texto ISO (o AAAA-MM-DD un día completo); tone: el color de su tipo\n * @param {import('react').ReactNode} [props.actions] botones de la pantalla (editar, borrar, responder…)\n * @param {string} [props.titleId] el id del título: la ventana que lo contiene se nombra con él (aria-labelledby)\n * @param {object} [props.texts] los textos que cambian, con la forma de `calendar` en los textos del paquete\n */\nfunction EventDetailsContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaEventDetails.defaultProps) y encima lo que llega aquí\n const {event, actions, titleId, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('calendar', texts);\n const {formatDate, formatTime} = useFormatters();\n const isWholeDay = event.allDay || WHOLE_DAY_PATTERN.test(event.start);\n let when = formatDate(event.start);\n if (!isWholeDay) {\n when = t('details.timeRange', {date: formatDate(event.start), start: formatTime(event.start), end: event.end ? formatTime(event.end) : ''});\n }\n const reminder = reminderOf(event.reminderMinutes);\n const canJoin = isOpenableMeetingUrl(event.meetingUrl);\n\n return (\n <Stack spacing={2}>\n <EventTitleRow direction=\"row\" spacing={1.5} ownSx={{alignItems: 'center'}}>\n <EventToneDot aria-hidden=\"true\" ownSx={{width: 12, height: 12, borderRadius: '4px', flexShrink: 0, bgcolor: `${event.tone ?? 'primary'}.main`}} />\n <Typography id={titleId} variant=\"h6\" component=\"h2\">{event.title}</Typography>\n </EventTitleRow>\n <DetailRow Icon={AccessTimeRoundedIcon} label={t('details.when')}>\n <Typography variant=\"body2\">{isWholeDay ? t('details.allDay', {date: when}) : when}</Typography>\n </DetailRow>\n {event.location && (\n <DetailRow Icon={PlaceOutlinedIcon} label={t('details.location')}>\n <Typography variant=\"body2\">{event.location}</Typography>\n </DetailRow>\n )}\n {event.meetingUrl && (\n <DetailRow Icon={VideocamOutlinedIcon} label={t('details.meeting')}>\n <EventLinkRow direction=\"row\" spacing={1} ownSx={{alignItems: 'center', flexWrap: 'wrap'}} useFlexGap>\n {canJoin && (\n <Button variant=\"contained\" size=\"small\" href={event.meetingUrl} target=\"_blank\" rel=\"noreferrer\">{t('details.join')}</Button>\n )}\n <EventLink variant=\"caption\" color=\"text.secondary\" ownSx={{wordBreak: 'break-all'}}>{event.meetingUrl}</EventLink>\n </EventLinkRow>\n </DetailRow>\n )}\n {event.attendees?.length > 0 && (\n <DetailRow Icon={PeopleOutlineRoundedIcon} label={t('details.attendees')}>\n <EventGuestsTitle variant=\"body2\" ownSx={{mb: 0.75}}>{t('details.attendeesCount', {count: event.attendees.length})}</EventGuestsTitle>\n <Stack spacing={0.75}>\n {event.attendees.map((attendee) => {\n const response = attendee.response ?? ATTENDEE_RESPONSE.pending;\n return (\n <EventGuest key={attendee.id} direction=\"row\" spacing={1} ownSx={{alignItems: 'center'}}>\n <EventGuestAvatar ownSx={{width: 24, height: 24, fontSize: 11}}>{initialsOf(attendee.name)}</EventGuestAvatar>\n <EventGuestName variant=\"body2\" ownSx={{flexGrow: 1, minWidth: 0}} noWrap>{attendee.name}</EventGuestName>\n <Chip size=\"small\" variant=\"outlined\" color={RESPONSE_COLOR[response] ?? 'default'} label={t(`details.response.${response}`)} />\n </EventGuest>\n );\n })}\n </Stack>\n </DetailRow>\n )}\n {reminder.unit !== REMINDER_UNIT.none && (\n <DetailRow Icon={NotificationsNoneRoundedIcon} label={t('details.reminder')}>\n <Typography variant=\"body2\">{t(`details.reminderUnit.${reminder.unit}`, {count: reminder.count})}</Typography>\n </DetailRow>\n )}\n {event.description && (\n <DetailRow Icon={NotesRoundedIcon} label={t('details.notes')}>\n <EventNotes variant=\"body2\" ownSx={{whiteSpace: 'pre-wrap'}}>{event.description}</EventNotes>\n </DetailRow>\n )}\n {actions && <EventActions direction=\"row\" spacing={1} useFlexGap ownSx={{justifyContent: 'flex-end', flexWrap: 'wrap'}}>{actions}</EventActions>}\n </Stack>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst EventDetails = withPieceSlots(EventDetailsContent, THEME_NAME);\nexport default EventDetails;\n"],"names":[],"mappings":"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"}
@@ -6,32 +6,37 @@ import PickerFrame, { textFieldSlotPropsOf } from "./PickerFrame.js";
6
6
  import { CALENDAR_DATE_FORMAT } from "./pickerValues.js";
7
7
  import { usePickerField } from "./usePickerField.js";
8
8
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
9
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
10
+ const THEME_NAME = "CalcitaDateInput";
11
+ const DateInputPicker = piecePart(THEME_NAME, "Picker", DatePicker);
9
12
  function pickerValueOf(calendarDate) {
10
13
  return calendarDate ? dayjs(calendarDate) : null;
11
14
  }
12
- function DateInput({
13
- name,
14
- label,
15
- value,
16
- onChange,
17
- onBlur,
18
- error,
19
- helperText = " ",
20
- minDate,
21
- maxDate,
22
- disableFuture = false,
23
- disablePast = false,
24
- openTo = "day",
25
- disabled = false,
26
- inputRef,
27
- pickerProps,
28
- texts,
29
- ...unknownProps
30
- }) {
31
- warnUnknownProps("DateInput", unknownProps);
32
- const { language, inputId, errorText, formats } = usePickerField({ name, kind: "date", error, texts });
15
+ function DateInputContent(props) {
16
+ const {
17
+ name,
18
+ label,
19
+ value,
20
+ onChange,
21
+ onBlur,
22
+ error,
23
+ helperText = " ",
24
+ minDate,
25
+ maxDate,
26
+ disableFuture = false,
27
+ disablePast = false,
28
+ openTo = "day",
29
+ disabled = false,
30
+ inputRef,
31
+ pickerProps,
32
+ messages,
33
+ texts,
34
+ ...unknownProps
35
+ } = usePieceProps(props, THEME_NAME);
36
+ warnUnknownProps(THEME_NAME, unknownProps);
37
+ const { language, inputId, errorText, formats } = usePickerField({ name, kind: "date", error, label, messages, texts });
33
38
  return /* @__PURE__ */ jsx(PickerFrame, { inputId, label, language, children: /* @__PURE__ */ jsx(
34
- DatePicker,
39
+ DateInputPicker,
35
40
  {
36
41
  ...pickerProps,
37
42
  format: formats.date,
@@ -53,6 +58,7 @@ function DateInput({
53
58
  }
54
59
  ) });
55
60
  }
61
+ const DateInput = withPieceSlots(DateInputContent, THEME_NAME);
56
62
  export {
57
63
  CALENDAR_DATE_FORMAT,
58
64
  DateInput as default
@@ -1 +1 @@
1
- {"version":3,"file":"DateInput.js","sources":["../../src/datePickers/DateInput.jsx"],"sourcesContent":["// Campo de FECHA suelto con el DatePicker de MUI X (@stackcraftmx/calcita/date-pickers), con la etiqueta arriba como los\n// demás campos del paquete.\n//\n// Al formulario (y al servidor) viaja la fecha de calendario 'AAAA-MM-DD' en texto; en pantalla se ve DD/MM/AAAA en español\n// y MM/DD/AAAA en inglés, con el calendario y sus textos en el idioma activo. '' = sin fecha. Una fecha de calendario no\n// tiene hora ni zona: nunca se pasa por Date (que la movería de día según la zona).\n//\n// Cada campo trae su LocalizationProvider con dayjs (PickerFrame): la pantalla no tiene que poner nada alrededor.\n//\n// Genérico del paquete: function (regla de la casa).\nimport dayjs from 'dayjs';\nimport {DatePicker} from '@mui/x-date-pickers/DatePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {CALENDAR_DATE_FORMAT} from '@/datePickers/pickerValues.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\nexport {CALENDAR_DATE_FORMAT};\n\n/**\n * Una fecha de calendario 'AAAA-MM-DD' como la quiere el DatePicker; null si está vacía.\n *\n * @param {string|null|undefined} calendarDate\n * @returns {import('dayjs').Dayjs|null}\n */\nfunction pickerValueOf(calendarDate) {\n // dayjs lee 'AAAA-MM-DD' como día local (a diferencia de new Date, que lo toma en UTC y lo mueve de día)\n return calendarDate ? dayjs(calendarDate) : null;\n}\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value 'AAAA-MM-DD' o ''\n * @param {(value: string) => void} props.onChange recibe 'AAAA-MM-DD' ('' al borrar o con una fecha a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText]\n * @param {string} [props.minDate] 'AAAA-MM-DD'\n * @param {string} [props.maxDate] 'AAAA-MM-DD'\n * @param {boolean} [props.disableFuture] p. ej. una fecha de nacimiento\n * @param {boolean} [props.disablePast] p. ej. una cita\n * @param {'day'|'month'|'year'} [props.openTo] por dónde abre el calendario (year para un nacimiento)\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del DatePicker de MUI X que aquí no tiene nombre (shouldDisableDate, slots,\n * slotProps…); value y onChange son del campo\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function DateInput({\n name, label, value, onChange, onBlur, error, helperText = ' ', minDate, maxDate, disableFuture = false, disablePast = false,\n openTo = 'day', disabled = false, inputRef, pickerProps, texts,\n ...unknownProps\n}) {\n warnUnknownProps('DateInput', unknownProps);\n const {language, inputId, errorText, formats} = usePickerField({name, kind: 'date', error, texts});\n\n return (\n <PickerFrame inputId={inputId} label={label} language={language}>\n <DatePicker\n {...pickerProps}\n format={formats.date}\n value={pickerValueOf(value)}\n minDate={pickerValueOf(minDate) ?? undefined}\n maxDate={pickerValueOf(maxDate) ?? undefined}\n disableFuture={disableFuture}\n disablePast={disablePast}\n disabled={disabled}\n openTo={openTo}\n views={openTo === 'year' ? ['year', 'month', 'day'] : pickerProps?.views}\n inputRef={inputRef}\n // una fecha a medias (25/1_/____) todavía no es fecha: viaja como vacía hasta que se complete\n onChange={(pickedDate) => onChange(pickedDate?.isValid() ? pickedDate.format(CALENDAR_DATE_FORMAT) : '')}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf({id: inputId, name, onBlur, error: Boolean(errorText), helperText: errorText ?? helperText}, pickerProps)}\n />\n </PickerFrame>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AA0BA,SAAS,cAAc,cAAc;AAEjC,SAAO,eAAe,MAAM,YAAY,IAAI;AAChD;AAsBA,SAAwB,UAAU;AAAA,EAC9B;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAO,aAAa;AAAA,EAAK;AAAA,EAAS;AAAA,EAAS,gBAAgB;AAAA,EAAO,cAAc;AAAA,EACtH,SAAS;AAAA,EAAO,WAAW;AAAA,EAAO;AAAA,EAAU;AAAA,EAAa;AAAA,EACzD,GAAG;AACP,GAAG;AACC,mBAAiB,aAAa,YAAY;AAC1C,QAAM,EAAC,UAAU,SAAS,WAAW,QAAA,IAAW,eAAe,EAAC,MAAM,MAAM,QAAQ,OAAO,OAAM;AAEjG,SACI,oBAAC,aAAA,EAAY,SAAkB,OAAc,UACzC,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,QAAQ,QAAQ;AAAA,MAChB,OAAO,cAAc,KAAK;AAAA,MAC1B,SAAS,cAAc,OAAO,KAAK;AAAA,MACnC,SAAS,cAAc,OAAO,KAAK;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,WAAW,SAAS,CAAC,QAAQ,SAAS,KAAK,IAAI,aAAa;AAAA,MACnE;AAAA,MAEA,UAAU,CAAC,eAAe,SAAS,YAAY,YAAY,WAAW,OAAO,oBAAoB,IAAI,EAAE;AAAA,MACvG,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW,qBAAqB,EAAC,IAAI,SAAS,MAAM,QAAQ,OAAO,QAAQ,SAAS,GAAG,YAAY,aAAa,WAAA,GAAa,WAAW;AAAA,IAAA;AAAA,EAAA,GAEhJ;AAER;"}
1
+ {"version":3,"file":"DateInput.js","sources":["../../src/datePickers/DateInput.jsx"],"sourcesContent":["// Campo de FECHA suelto con el DatePicker de MUI X (@stackcraftmx/calcita/date-pickers), con la etiqueta arriba como los\n// demás campos del paquete.\n//\n// Al formulario (y al servidor) viaja la fecha de calendario 'AAAA-MM-DD' en texto; en pantalla se ve DD/MM/AAAA en español\n// y MM/DD/AAAA en inglés, con el calendario y sus textos en el idioma activo. '' = sin fecha. Una fecha de calendario no\n// tiene hora ni zona: nunca se pasa por Date (que la movería de día según la zona).\n//\n// Cada campo trae su LocalizationProvider con dayjs (PickerFrame): la pantalla no tiene que poner nada alrededor.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaDateInput con defaultProps, styleOverrides de\n// sus partes (picker) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport dayjs from 'dayjs';\nimport {DatePicker} from '@mui/x-date-pickers/DatePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {CALENDAR_DATE_FORMAT} from '@/datePickers/pickerValues.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaDateInput)\nconst THEME_NAME = 'CalcitaDateInput';\nconst DateInputPicker = piecePart(THEME_NAME, 'Picker', DatePicker);\n\nexport {CALENDAR_DATE_FORMAT};\n\n/**\n * Una fecha de calendario 'AAAA-MM-DD' como la quiere el DatePicker; null si está vacía.\n *\n * @param {string|null|undefined} calendarDate\n * @returns {import('dayjs').Dayjs|null}\n */\nfunction pickerValueOf(calendarDate) {\n // dayjs lee 'AAAA-MM-DD' como día local (a diferencia de new Date, que lo toma en UTC y lo mueve de día)\n return calendarDate ? dayjs(calendarDate) : null;\n}\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value 'AAAA-MM-DD' o ''\n * @param {(value: string) => void} props.onChange recibe 'AAAA-MM-DD' ('' al borrar o con una fecha a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText]\n * @param {string} [props.minDate] 'AAAA-MM-DD'\n * @param {string} [props.maxDate] 'AAAA-MM-DD'\n * @param {boolean} [props.disableFuture] p. ej. una fecha de nacimiento\n * @param {boolean} [props.disablePast] p. ej. una cita\n * @param {'day'|'month'|'year'} [props.openTo] por dónde abre el calendario (year para un nacimiento)\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del DatePicker de MUI X que aquí no tiene nombre (shouldDisableDate, slots,\n * slotProps…); value y onChange son del campo\n * @param {Record<string, string|object>} [props.messages] el texto del error de este campo, por regla de validación\n * ({required: 'Elija la fecha', min: 'Desde mañana'}): gana al de Calcita y al de los textos\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction DateInputContent(props) {\n const {\n name, label, value, onChange, onBlur, error, helperText = ' ', minDate, maxDate, disableFuture = false, disablePast = false,\n openTo = 'day', disabled = false, inputRef, pickerProps, messages, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {language, inputId, errorText, formats} = usePickerField({name, kind: 'date', error, label, messages, texts});\n\n return (\n <PickerFrame inputId={inputId} label={label} language={language}>\n <DateInputPicker\n {...pickerProps}\n format={formats.date}\n value={pickerValueOf(value)}\n minDate={pickerValueOf(minDate) ?? undefined}\n maxDate={pickerValueOf(maxDate) ?? undefined}\n disableFuture={disableFuture}\n disablePast={disablePast}\n disabled={disabled}\n openTo={openTo}\n views={openTo === 'year' ? ['year', 'month', 'day'] : pickerProps?.views}\n inputRef={inputRef}\n // una fecha a medias (25/1_/____) todavía no es fecha: viaja como vacía hasta que se complete\n onChange={(pickedDate) => onChange(pickedDate?.isValid() ? pickedDate.format(CALENDAR_DATE_FORMAT) : '')}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf({id: inputId, name, onBlur, error: Boolean(errorText), helperText: errorText ?? helperText}, pickerProps)}\n />\n </PickerFrame>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst DateInput = withPieceSlots(DateInputContent, THEME_NAME);\nexport default DateInput;\n"],"names":[],"mappings":";;;;;;;;;AAuBA,MAAM,aAAa;AACnB,MAAM,kBAAkB,UAAU,YAAY,UAAU,UAAU;AAUlE,SAAS,cAAc,cAAc;AAEjC,SAAO,eAAe,MAAM,YAAY,IAAI;AAChD;AAwBA,SAAS,iBAAiB,OAAO;AAC7B,QAAM;AAAA,IACF;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAO,aAAa;AAAA,IAAK;AAAA,IAAS;AAAA,IAAS,gBAAgB;AAAA,IAAO,cAAc;AAAA,IACtH,SAAS;AAAA,IAAO,WAAW;AAAA,IAAO;AAAA,IAAU;AAAA,IAAa;AAAA,IAAU;AAAA,IACnE,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,UAAU,SAAS,WAAW,YAAW,eAAe,EAAC,MAAM,MAAM,QAAQ,OAAO,OAAO,UAAU,OAAM;AAElH,SACI,oBAAC,aAAA,EAAY,SAAkB,OAAc,UACzC,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,QAAQ,QAAQ;AAAA,MAChB,OAAO,cAAc,KAAK;AAAA,MAC1B,SAAS,cAAc,OAAO,KAAK;AAAA,MACnC,SAAS,cAAc,OAAO,KAAK;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,WAAW,SAAS,CAAC,QAAQ,SAAS,KAAK,IAAI,aAAa;AAAA,MACnE;AAAA,MAEA,UAAU,CAAC,eAAe,SAAS,YAAY,YAAY,WAAW,OAAO,oBAAoB,IAAI,EAAE;AAAA,MACvG,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW,qBAAqB,EAAC,IAAI,SAAS,MAAM,QAAQ,OAAO,QAAQ,SAAS,GAAG,YAAY,aAAa,WAAA,GAAa,WAAW;AAAA,IAAA;AAAA,EAAA,GAEhJ;AAER;AAGA,MAAM,YAAY,eAAe,kBAAkB,UAAU;"}
@@ -2,38 +2,43 @@
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker";
4
4
  import PickerFrame, { textFieldSlotPropsOf } from "./PickerFrame.js";
5
- import { timeZoneNameOf, latestInstantOf, earliestInstantFromNow, DEFAULT_MINUTES_STEP, instantTextOf, pickerInstantOf } from "./pickerValues.js";
5
+ import { DEFAULT_MINUTES_STEP, timeZoneNameOf, latestInstantOf, earliestInstantFromNow, instantTextOf, pickerInstantOf } from "./pickerValues.js";
6
6
  import { useCurrentMinute } from "./useCurrentMinute.js";
7
7
  import { usePickerField } from "./usePickerField.js";
8
8
  import { intlLocaleOf } from "../toolkit/toolkitSettings.js";
9
9
  import { useToolkitSettings } from "../toolkit/toolkitContext.js";
10
10
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
11
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
12
+ const THEME_NAME = "CalcitaDateTimeInput";
13
+ const DateTimeInputPicker = piecePart(THEME_NAME, "Picker", DateTimePicker);
11
14
  const HELPER_SEPARATOR = " · ";
12
- function DateTimeInput({
13
- name,
14
- label,
15
- value,
16
- onChange,
17
- onBlur,
18
- error,
19
- helperText,
20
- minDateTime,
21
- minimumMinutesFromNow,
22
- maxDateTime,
23
- disableFuture = false,
24
- disablePast = false,
25
- minutesStep = DEFAULT_MINUTES_STEP,
26
- timeZone,
27
- showTimeZone = true,
28
- timeZoneLabel,
29
- disabled = false,
30
- inputRef,
31
- pickerProps,
32
- texts,
33
- ...unknownProps
34
- }) {
35
- warnUnknownProps("DateTimeInput", unknownProps);
36
- const field = usePickerField({ name, kind: "dateTime", error, texts });
15
+ function DateTimeInputContent(props) {
16
+ const {
17
+ name,
18
+ label,
19
+ value,
20
+ onChange,
21
+ onBlur,
22
+ error,
23
+ helperText,
24
+ minDateTime,
25
+ minimumMinutesFromNow,
26
+ maxDateTime,
27
+ disableFuture = false,
28
+ disablePast = false,
29
+ minutesStep = DEFAULT_MINUTES_STEP,
30
+ timeZone,
31
+ showTimeZone = true,
32
+ timeZoneLabel,
33
+ disabled = false,
34
+ inputRef,
35
+ pickerProps,
36
+ messages,
37
+ texts,
38
+ ...unknownProps
39
+ } = usePieceProps(props, THEME_NAME);
40
+ warnUnknownProps(THEME_NAME, unknownProps);
41
+ const field = usePickerField({ name, kind: "dateTime", error, label, messages, texts });
37
42
  const { languages } = useToolkitSettings();
38
43
  const shownTimeZone = timeZone ?? field.timeZone;
39
44
  const zoneText = showTimeZone ? timeZoneLabel ?? timeZoneNameOf(shownTimeZone, intlLocaleOf(field.language, languages)) : null;
@@ -42,7 +47,7 @@ function DateTimeInput({
42
47
  const currentMinute = useCurrentMinute(hasClockRule);
43
48
  const earliest = latestInstantOf(minDateTime, hasClockRule ? earliestInstantFromNow(minimumMinutesFromNow, currentMinute) : "");
44
49
  return /* @__PURE__ */ jsx(PickerFrame, { inputId: field.inputId, label, language: field.language, children: /* @__PURE__ */ jsx(
45
- DateTimePicker,
50
+ DateTimeInputPicker,
46
51
  {
47
52
  ...pickerProps,
48
53
  timezone: shownTimeZone,
@@ -69,6 +74,7 @@ function DateTimeInput({
69
74
  }
70
75
  ) });
71
76
  }
77
+ const DateTimeInput = withPieceSlots(DateTimeInputContent, THEME_NAME);
72
78
  export {
73
79
  DateTimeInput as default
74
80
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DateTimeInput.js","sources":["../../src/datePickers/DateTimeInput.jsx"],"sourcesContent":["// Campo de FECHA CON HORA suelto con el DateTimePicker de MUI X (@stackcraftmx/calcita/date-pickers), para un instante:\n// una cita, un envío programado, «posponer hasta».\n//\n// Viaja como instante en UTC ('2026-11-01T18:30:00Z') y se pinta en la zona del proveedor (ToolkitProvider timeZone),\n// rotulada abajo con su nombre («Hora estándar central»): quien lo ve sabe en qué hora está escribiendo aunque su equipo\n// esté en otra zona. Lee también lo que llega del servidor con desfase ('…-06:00'). '' = vacío. La hora sale de 24 horas o\n// con a.m. y p.m. según el hourCycle del proveedor.\n//\n// Los minutos van de uno en uno (minutesStep los cambia). Para «al menos N minutos después de ahora» (publicar con\n// anticipación) está minimumMinutesFromNow: el mínimo se recorre solo con el reloj mientras la pantalla está abierta. Para\n// «el fin, al menos N minutos después del inicio», minDateTime={instantPlusMinutes(startsAt, N)}. Con formik, las mismas\n// reglas en yup: minutesFromNowRule y minutesAfterRule (el servidor vuelve a revisar).\n//\n// Para una hora del día sin fecha («abre a las 09:00») va TimeInput; para una fecha sin hora, DateInput.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {DateTimePicker} from '@mui/x-date-pickers/DateTimePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {\n DEFAULT_MINUTES_STEP, earliestInstantFromNow, instantTextOf, latestInstantOf, pickerInstantOf, timeZoneNameOf,\n} from '@/datePickers/pickerValues.js';\nimport {useCurrentMinute} from '@/datePickers/useCurrentMinute.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {intlLocaleOf} from '@/toolkit/toolkitSettings.js';\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// entre la ayuda de la pantalla y el nombre de la zona\nconst HELPER_SEPARATOR = ' · ';\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value el instante ('2026-11-01T18:30:00Z' o con desfase) o ''\n * @param {(value: string) => void} props.onChange recibe el instante en UTC ('' al borrar o a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText] ya traducida; va antes del nombre de la zona\n * @param {string} [props.minDateTime] instante (el fin de algo: instantPlusMinutes(startsAt, 30))\n * @param {number} [props.minimumMinutesFromNow] al menos tantos minutos después de ahora; se recorre con el reloj\n * @param {string} [props.maxDateTime] instante\n * @param {boolean} [props.disableFuture]\n * @param {boolean} [props.disablePast] p. ej. un envío programado\n * @param {number} [props.minutesStep] de cuánto en cuánto van los minutos; por omisión de uno en uno (15 para citas de\n * cuarto de hora)\n * @param {string} [props.timeZone] otra zona que la del proveedor (la de una sucursal); rotulada igual\n * @param {boolean} [props.showTimeZone] false quita el nombre de la zona de abajo (por omisión se ve)\n * @param {string} [props.timeZoneLabel] ya traducido, en lugar del nombre que da el navegador\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del DateTimePicker de MUI X que aquí no tiene nombre (views, shouldDisableDate,\n * slots, slotProps…); value y onChange son del campo\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function DateTimeInput({\n name, label, value, onChange, onBlur, error, helperText, minDateTime, minimumMinutesFromNow, maxDateTime, disableFuture = false,\n disablePast = false, minutesStep = DEFAULT_MINUTES_STEP, timeZone, showTimeZone = true, timeZoneLabel, disabled = false, inputRef, pickerProps, texts,\n ...unknownProps\n}) {\n warnUnknownProps('DateTimeInput', unknownProps);\n const field = usePickerField({name, kind: 'dateTime', error, texts});\n const {languages} = useToolkitSettings();\n const shownTimeZone = timeZone ?? field.timeZone;\n const zoneText = showTimeZone ? (timeZoneLabel ?? timeZoneNameOf(shownTimeZone, intlLocaleOf(field.language, languages))) : null;\n const helperLine = [helperText, zoneText].filter(Boolean).join(HELPER_SEPARATOR) || ' ';\n // el mínimo que de verdad aplica: el que da la pantalla o el de «ahora + N minutos», el más tarde\n const hasClockRule = minimumMinutesFromNow != null;\n const currentMinute = useCurrentMinute(hasClockRule);\n const earliest = latestInstantOf(minDateTime, hasClockRule ? earliestInstantFromNow(minimumMinutesFromNow, currentMinute) : '');\n\n return (\n <PickerFrame inputId={field.inputId} label={label} language={field.language}>\n <DateTimePicker\n {...pickerProps}\n timezone={shownTimeZone}\n format={field.formats.dateTime}\n ampm={field.formats.ampm}\n value={pickerInstantOf(value, shownTimeZone)}\n minDateTime={pickerInstantOf(earliest, shownTimeZone) ?? undefined}\n maxDateTime={pickerInstantOf(maxDateTime, shownTimeZone) ?? undefined}\n disableFuture={disableFuture}\n disablePast={disablePast}\n disabled={disabled}\n minutesStep={minutesStep}\n timeSteps={{minutes: minutesStep, ...pickerProps?.timeSteps}}\n inputRef={inputRef}\n onChange={(pickedValue) => onChange(instantTextOf(pickedValue))}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf(\n {id: field.inputId, name, onBlur, error: Boolean(field.errorText), helperText: field.errorText ?? helperLine},\n pickerProps,\n )}\n />\n </PickerFrame>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AA6BA,MAAM,mBAAmB;AA2BzB,SAAwB,cAAc;AAAA,EAClC;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAY;AAAA,EAAa;AAAA,EAAuB;AAAA,EAAa,gBAAgB;AAAA,EAC1H,cAAc;AAAA,EAAO,cAAc;AAAA,EAAsB;AAAA,EAAU,eAAe;AAAA,EAAM;AAAA,EAAe,WAAW;AAAA,EAAO;AAAA,EAAU;AAAA,EAAa;AAAA,EAChJ,GAAG;AACP,GAAG;AACC,mBAAiB,iBAAiB,YAAY;AAC9C,QAAM,QAAQ,eAAe,EAAC,MAAM,MAAM,YAAY,OAAO,OAAM;AACnE,QAAM,EAAC,UAAA,IAAa,mBAAA;AACpB,QAAM,gBAAgB,YAAY,MAAM;AACxC,QAAM,WAAW,eAAgB,iBAAiB,eAAe,eAAe,aAAa,MAAM,UAAU,SAAS,CAAC,IAAK;AAC5H,QAAM,aAAa,CAAC,YAAY,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,gBAAgB,KAAK;AAEpF,QAAM,eAAe,yBAAyB;AAC9C,QAAM,gBAAgB,iBAAiB,YAAY;AACnD,QAAM,WAAW,gBAAgB,aAAa,eAAe,uBAAuB,uBAAuB,aAAa,IAAI,EAAE;AAE9H,SACI,oBAAC,eAAY,SAAS,MAAM,SAAS,OAAc,UAAU,MAAM,UAC/D,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,UAAU;AAAA,MACV,QAAQ,MAAM,QAAQ;AAAA,MACtB,MAAM,MAAM,QAAQ;AAAA,MACpB,OAAO,gBAAgB,OAAO,aAAa;AAAA,MAC3C,aAAa,gBAAgB,UAAU,aAAa,KAAK;AAAA,MACzD,aAAa,gBAAgB,aAAa,aAAa,KAAK;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,EAAC,SAAS,aAAa,GAAG,aAAa,UAAA;AAAA,MAClD;AAAA,MACA,UAAU,CAAC,gBAAgB,SAAS,cAAc,WAAW,CAAC;AAAA,MAC9D,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACP,EAAC,IAAI,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,SAAS,GAAG,YAAY,MAAM,aAAa,WAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA,GAER;AAER;"}
1
+ {"version":3,"file":"DateTimeInput.js","sources":["../../src/datePickers/DateTimeInput.jsx"],"sourcesContent":["// Campo de FECHA CON HORA suelto con el DateTimePicker de MUI X (@stackcraftmx/calcita/date-pickers), para un instante:\n// una cita, un envío programado, «posponer hasta».\n//\n// Viaja como instante en UTC ('2026-11-01T18:30:00Z') y se pinta en la zona del proveedor (ToolkitProvider timeZone),\n// rotulada abajo con su nombre («Hora estándar central»): quien lo ve sabe en qué hora está escribiendo aunque su equipo\n// esté en otra zona. Lee también lo que llega del servidor con desfase ('…-06:00'). '' = vacío. La hora sale de 24 horas o\n// con a.m. y p.m. según el hourCycle del proveedor.\n//\n// Los minutos van de uno en uno (minutesStep los cambia). Para «al menos N minutos después de ahora» (publicar con\n// anticipación) está minimumMinutesFromNow: el mínimo se recorre solo con el reloj mientras la pantalla está abierta. Para\n// «el fin, al menos N minutos después del inicio», minDateTime={instantPlusMinutes(startsAt, N)}. Con formik, las mismas\n// reglas en yup: minutesFromNowRule y minutesAfterRule (el servidor vuelve a revisar).\n//\n// Para una hora del día sin fecha («abre a las 09:00») va TimeInput; para una fecha sin hora, DateInput.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaDateTimeInput con defaultProps, styleOverrides de\n// sus partes (picker) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {DateTimePicker} from '@mui/x-date-pickers/DateTimePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {\n DEFAULT_MINUTES_STEP, earliestInstantFromNow, instantTextOf, latestInstantOf, pickerInstantOf, timeZoneNameOf,\n} from '@/datePickers/pickerValues.js';\nimport {useCurrentMinute} from '@/datePickers/useCurrentMinute.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {intlLocaleOf} from '@/toolkit/toolkitSettings.js';\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaDateTimeInput)\nconst THEME_NAME = 'CalcitaDateTimeInput';\nconst DateTimeInputPicker = piecePart(THEME_NAME, 'Picker', DateTimePicker);\n\n// entre la ayuda de la pantalla y el nombre de la zona\nconst HELPER_SEPARATOR = ' · ';\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value el instante ('2026-11-01T18:30:00Z' o con desfase) o ''\n * @param {(value: string) => void} props.onChange recibe el instante en UTC ('' al borrar o a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText] ya traducida; va antes del nombre de la zona\n * @param {string} [props.minDateTime] instante (el fin de algo: instantPlusMinutes(startsAt, 30))\n * @param {number} [props.minimumMinutesFromNow] al menos tantos minutos después de ahora; se recorre con el reloj\n * @param {string} [props.maxDateTime] instante\n * @param {boolean} [props.disableFuture]\n * @param {boolean} [props.disablePast] p. ej. un envío programado\n * @param {number} [props.minutesStep] de cuánto en cuánto van los minutos; por omisión de uno en uno (15 para citas de\n * cuarto de hora)\n * @param {string} [props.timeZone] otra zona que la del proveedor (la de una sucursal); rotulada igual\n * @param {boolean} [props.showTimeZone] false quita el nombre de la zona de abajo (por omisión se ve)\n * @param {string} [props.timeZoneLabel] ya traducido, en lugar del nombre que da el navegador\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del DateTimePicker de MUI X que aquí no tiene nombre (views, shouldDisableDate,\n * slots, slotProps…); value y onChange son del campo\n * @param {Record<string, string|object>} [props.messages] el texto del error de este campo, por regla de validación\n * ({required: 'Elija la fecha', min: 'Desde mañana'}): gana al de Calcita y al de los textos\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction DateTimeInputContent(props) {\n const {\n name, label, value, onChange, onBlur, error, helperText, minDateTime, minimumMinutesFromNow, maxDateTime, disableFuture = false,\n disablePast = false, minutesStep = DEFAULT_MINUTES_STEP, timeZone, showTimeZone = true, timeZoneLabel, disabled = false, inputRef, pickerProps, messages, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const field = usePickerField({name, kind: 'dateTime', error, label, messages, texts});\n const {languages} = useToolkitSettings();\n const shownTimeZone = timeZone ?? field.timeZone;\n const zoneText = showTimeZone ? (timeZoneLabel ?? timeZoneNameOf(shownTimeZone, intlLocaleOf(field.language, languages))) : null;\n const helperLine = [helperText, zoneText].filter(Boolean).join(HELPER_SEPARATOR) || ' ';\n // el mínimo que de verdad aplica: el que da la pantalla o el de «ahora + N minutos», el más tarde\n const hasClockRule = minimumMinutesFromNow != null;\n const currentMinute = useCurrentMinute(hasClockRule);\n const earliest = latestInstantOf(minDateTime, hasClockRule ? earliestInstantFromNow(minimumMinutesFromNow, currentMinute) : '');\n\n return (\n <PickerFrame inputId={field.inputId} label={label} language={field.language}>\n <DateTimeInputPicker\n {...pickerProps}\n timezone={shownTimeZone}\n format={field.formats.dateTime}\n ampm={field.formats.ampm}\n value={pickerInstantOf(value, shownTimeZone)}\n minDateTime={pickerInstantOf(earliest, shownTimeZone) ?? undefined}\n maxDateTime={pickerInstantOf(maxDateTime, shownTimeZone) ?? undefined}\n disableFuture={disableFuture}\n disablePast={disablePast}\n disabled={disabled}\n minutesStep={minutesStep}\n timeSteps={{minutes: minutesStep, ...pickerProps?.timeSteps}}\n inputRef={inputRef}\n onChange={(pickedValue) => onChange(instantTextOf(pickedValue))}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf(\n {id: field.inputId, name, onBlur, error: Boolean(field.errorText), helperText: field.errorText ?? helperLine},\n pickerProps,\n )}\n />\n </PickerFrame>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst DateTimeInput = withPieceSlots(DateTimeInputContent, THEME_NAME);\nexport default DateTimeInput;\n"],"names":[],"mappings":";;;;;;;;;;;AAiCA,MAAM,aAAa;AACnB,MAAM,sBAAsB,UAAU,YAAY,UAAU,cAAc;AAG1E,MAAM,mBAAmB;AA6BzB,SAAS,qBAAqB,OAAO;AACjC,QAAM;AAAA,IACF;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAY;AAAA,IAAa;AAAA,IAAuB;AAAA,IAAa,gBAAgB;AAAA,IAC1H,cAAc;AAAA,IAAO,cAAc;AAAA,IAAsB;AAAA,IAAU,eAAe;AAAA,IAAM;AAAA,IAAe,WAAW;AAAA,IAAO;AAAA,IAAU;AAAA,IAAa;AAAA,IAAU;AAAA,IAC1J,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,QAAQ,eAAe,EAAC,MAAM,MAAM,YAAY,OAAO,OAAO,UAAU,OAAM;AACpF,QAAM,EAAC,UAAA,IAAa,mBAAA;AACpB,QAAM,gBAAgB,YAAY,MAAM;AACxC,QAAM,WAAW,eAAgB,iBAAiB,eAAe,eAAe,aAAa,MAAM,UAAU,SAAS,CAAC,IAAK;AAC5H,QAAM,aAAa,CAAC,YAAY,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,gBAAgB,KAAK;AAEpF,QAAM,eAAe,yBAAyB;AAC9C,QAAM,gBAAgB,iBAAiB,YAAY;AACnD,QAAM,WAAW,gBAAgB,aAAa,eAAe,uBAAuB,uBAAuB,aAAa,IAAI,EAAE;AAE9H,SACI,oBAAC,eAAY,SAAS,MAAM,SAAS,OAAc,UAAU,MAAM,UAC/D,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,UAAU;AAAA,MACV,QAAQ,MAAM,QAAQ;AAAA,MACtB,MAAM,MAAM,QAAQ;AAAA,MACpB,OAAO,gBAAgB,OAAO,aAAa;AAAA,MAC3C,aAAa,gBAAgB,UAAU,aAAa,KAAK;AAAA,MACzD,aAAa,gBAAgB,aAAa,aAAa,KAAK;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,EAAC,SAAS,aAAa,GAAG,aAAa,UAAA;AAAA,MAClD;AAAA,MACA,UAAU,CAAC,gBAAgB,SAAS,cAAc,WAAW,CAAC;AAAA,MAC9D,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACP,EAAC,IAAI,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,SAAS,GAAG,YAAY,MAAM,aAAa,WAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA,GAER;AAER;AAGA,MAAM,gBAAgB,eAAe,sBAAsB,UAAU;"}
@@ -5,29 +5,34 @@ import PickerFrame, { textFieldSlotPropsOf } from "./PickerFrame.js";
5
5
  import { monthTextOf, pickerMonthOf } from "./pickerValues.js";
6
6
  import { usePickerField } from "./usePickerField.js";
7
7
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
8
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
9
+ const THEME_NAME = "CalcitaMonthInput";
10
+ const MonthInputPicker = piecePart(THEME_NAME, "Picker", DatePicker);
8
11
  const MONTH_VIEWS = ["year", "month"];
9
- function MonthInput({
10
- name,
11
- label,
12
- value,
13
- onChange,
14
- onBlur,
15
- error,
16
- helperText = " ",
17
- minMonth,
18
- maxMonth,
19
- disableFuture = false,
20
- disablePast = false,
21
- disabled = false,
22
- inputRef,
23
- pickerProps,
24
- texts,
25
- ...unknownProps
26
- }) {
27
- warnUnknownProps("MonthInput", unknownProps);
28
- const field = usePickerField({ name, kind: "month", error, texts });
12
+ function MonthInputContent(props) {
13
+ const {
14
+ name,
15
+ label,
16
+ value,
17
+ onChange,
18
+ onBlur,
19
+ error,
20
+ helperText = " ",
21
+ minMonth,
22
+ maxMonth,
23
+ disableFuture = false,
24
+ disablePast = false,
25
+ disabled = false,
26
+ inputRef,
27
+ pickerProps,
28
+ messages,
29
+ texts,
30
+ ...unknownProps
31
+ } = usePieceProps(props, THEME_NAME);
32
+ warnUnknownProps(THEME_NAME, unknownProps);
33
+ const field = usePickerField({ name, kind: "month", error, label, messages, texts });
29
34
  return /* @__PURE__ */ jsx(PickerFrame, { inputId: field.inputId, label, language: field.language, children: /* @__PURE__ */ jsx(
30
- DatePicker,
35
+ MonthInputPicker,
31
36
  {
32
37
  ...pickerProps,
33
38
  views: MONTH_VIEWS,
@@ -52,6 +57,7 @@ function MonthInput({
52
57
  }
53
58
  ) });
54
59
  }
60
+ const MonthInput = withPieceSlots(MonthInputContent, THEME_NAME);
55
61
  export {
56
62
  MonthInput as default
57
63
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MonthInput.js","sources":["../../src/datePickers/MonthInput.jsx"],"sourcesContent":["// Campo de MES suelto con el DatePicker de MUI X en meses y años (@stackcraftmx/calcita/date-pickers): el mes de un\n// reporte, de un saldo, de un cierre.\n//\n// Viaja 'AAAA-MM' en texto y se ve con el nombre del mes en el idioma activo («noviembre 2026»). Abre en los meses del año\n// que ya tiene; el año se cambia arriba. '' = vacío. Como la fecha, no se pasa por Date (que lo movería de mes según la\n// zona el día 1).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {DatePicker} from '@mui/x-date-pickers/DatePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {monthTextOf, pickerMonthOf} from '@/datePickers/pickerValues.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// primero el año y luego el mes: el selector abre en los meses y el año se cambia con su botón de arriba\nconst MONTH_VIEWS = ['year', 'month'];\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value 'AAAA-MM' o ''\n * @param {(value: string) => void} props.onChange recibe 'AAAA-MM' ('' al borrar o a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText]\n * @param {string} [props.minMonth] 'AAAA-MM'\n * @param {string} [props.maxMonth] 'AAAA-MM'\n * @param {boolean} [props.disableFuture] p. ej. el mes de un reporte que ya cerró\n * @param {boolean} [props.disablePast]\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del DatePicker de MUI X que aquí no tiene nombre (shouldDisableMonth, slots,\n * slotProps…); value y onChange son del campo\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function MonthInput({\n name, label, value, onChange, onBlur, error, helperText = ' ', minMonth, maxMonth, disableFuture = false, disablePast = false,\n disabled = false, inputRef, pickerProps, texts,\n ...unknownProps\n}) {\n warnUnknownProps('MonthInput', unknownProps);\n const field = usePickerField({name, kind: 'month', error, texts});\n\n return (\n <PickerFrame inputId={field.inputId} label={label} language={field.language}>\n <DatePicker\n {...pickerProps}\n views={MONTH_VIEWS}\n openTo=\"month\"\n format={field.formats.month}\n value={pickerMonthOf(value)}\n minDate={pickerMonthOf(minMonth) ?? undefined}\n maxDate={pickerMonthOf(maxMonth) ?? undefined}\n disableFuture={disableFuture}\n disablePast={disablePast}\n disabled={disabled}\n inputRef={inputRef}\n onChange={(pickedValue) => onChange(monthTextOf(pickedValue))}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf(\n {id: field.inputId, name, onBlur, error: Boolean(field.errorText), helperText: field.errorText ?? helperText},\n pickerProps,\n )}\n />\n </PickerFrame>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAgBA,MAAM,cAAc,CAAC,QAAQ,OAAO;AAqBpC,SAAwB,WAAW;AAAA,EAC/B;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAO,aAAa;AAAA,EAAK;AAAA,EAAU;AAAA,EAAU,gBAAgB;AAAA,EAAO,cAAc;AAAA,EACxH,WAAW;AAAA,EAAO;AAAA,EAAU;AAAA,EAAa;AAAA,EACzC,GAAG;AACP,GAAG;AACC,mBAAiB,cAAc,YAAY;AAC3C,QAAM,QAAQ,eAAe,EAAC,MAAM,MAAM,SAAS,OAAO,OAAM;AAEhE,SACI,oBAAC,eAAY,SAAS,MAAM,SAAS,OAAc,UAAU,MAAM,UAC/D,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,OAAO;AAAA,MACP,QAAO;AAAA,MACP,QAAQ,MAAM,QAAQ;AAAA,MACtB,OAAO,cAAc,KAAK;AAAA,MAC1B,SAAS,cAAc,QAAQ,KAAK;AAAA,MACpC,SAAS,cAAc,QAAQ,KAAK;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,CAAC,gBAAgB,SAAS,YAAY,WAAW,CAAC;AAAA,MAC5D,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACP,EAAC,IAAI,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,SAAS,GAAG,YAAY,MAAM,aAAa,WAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA,GAER;AAER;"}
1
+ {"version":3,"file":"MonthInput.js","sources":["../../src/datePickers/MonthInput.jsx"],"sourcesContent":["// Campo de MES suelto con el DatePicker de MUI X en meses y años (@stackcraftmx/calcita/date-pickers): el mes de un\n// reporte, de un saldo, de un cierre.\n//\n// Viaja 'AAAA-MM' en texto y se ve con el nombre del mes en el idioma activo («noviembre 2026»). Abre en los meses del año\n// que ya tiene; el año se cambia arriba. '' = vacío. Como la fecha, no se pasa por Date (que lo movería de mes según la\n// zona el día 1).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaMonthInput con defaultProps, styleOverrides de\n// sus partes (picker) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {DatePicker} from '@mui/x-date-pickers/DatePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {monthTextOf, pickerMonthOf} from '@/datePickers/pickerValues.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaMonthInput)\nconst THEME_NAME = 'CalcitaMonthInput';\nconst MonthInputPicker = piecePart(THEME_NAME, 'Picker', DatePicker);\n\n// primero el año y luego el mes: el selector abre en los meses y el año se cambia con su botón de arriba\nconst MONTH_VIEWS = ['year', 'month'];\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value 'AAAA-MM' o ''\n * @param {(value: string) => void} props.onChange recibe 'AAAA-MM' ('' al borrar o a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText]\n * @param {string} [props.minMonth] 'AAAA-MM'\n * @param {string} [props.maxMonth] 'AAAA-MM'\n * @param {boolean} [props.disableFuture] p. ej. el mes de un reporte que ya cerró\n * @param {boolean} [props.disablePast]\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del DatePicker de MUI X que aquí no tiene nombre (shouldDisableMonth, slots,\n * slotProps…); value y onChange son del campo\n * @param {Record<string, string|object>} [props.messages] el texto del error de este campo, por regla de validación\n * ({required: 'Elija la fecha', min: 'Desde mañana'}): gana al de Calcita y al de los textos\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction MonthInputContent(props) {\n const {\n name, label, value, onChange, onBlur, error, helperText = ' ', minMonth, maxMonth, disableFuture = false, disablePast = false,\n disabled = false, inputRef, pickerProps, messages, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const field = usePickerField({name, kind: 'month', error, label, messages, texts});\n\n return (\n <PickerFrame inputId={field.inputId} label={label} language={field.language}>\n <MonthInputPicker\n {...pickerProps}\n views={MONTH_VIEWS}\n openTo=\"month\"\n format={field.formats.month}\n value={pickerMonthOf(value)}\n minDate={pickerMonthOf(minMonth) ?? undefined}\n maxDate={pickerMonthOf(maxMonth) ?? undefined}\n disableFuture={disableFuture}\n disablePast={disablePast}\n disabled={disabled}\n inputRef={inputRef}\n onChange={(pickedValue) => onChange(monthTextOf(pickedValue))}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf(\n {id: field.inputId, name, onBlur, error: Boolean(field.errorText), helperText: field.errorText ?? helperText},\n pickerProps,\n )}\n />\n </PickerFrame>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst MonthInput = withPieceSlots(MonthInputContent, THEME_NAME);\nexport default MonthInput;\n"],"names":[],"mappings":";;;;;;;;AAoBA,MAAM,aAAa;AACnB,MAAM,mBAAmB,UAAU,YAAY,UAAU,UAAU;AAGnE,MAAM,cAAc,CAAC,QAAQ,OAAO;AAuBpC,SAAS,kBAAkB,OAAO;AAC9B,QAAM;AAAA,IACF;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAO,aAAa;AAAA,IAAK;AAAA,IAAU;AAAA,IAAU,gBAAgB;AAAA,IAAO,cAAc;AAAA,IACxH,WAAW;AAAA,IAAO;AAAA,IAAU;AAAA,IAAa;AAAA,IAAU;AAAA,IACnD,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,QAAQ,eAAe,EAAC,MAAM,MAAM,SAAS,OAAO,OAAO,UAAU,OAAM;AAEjF,SACI,oBAAC,eAAY,SAAS,MAAM,SAAS,OAAc,UAAU,MAAM,UAC/D,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,OAAO;AAAA,MACP,QAAO;AAAA,MACP,QAAQ,MAAM,QAAQ;AAAA,MACtB,OAAO,cAAc,KAAK;AAAA,MAC1B,SAAS,cAAc,QAAQ,KAAK;AAAA,MACpC,SAAS,cAAc,QAAQ,KAAK;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,CAAC,gBAAgB,SAAS,YAAY,WAAW,CAAC;AAAA,MAC5D,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACP,EAAC,IAAI,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,SAAS,GAAG,YAAY,MAAM,aAAa,WAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA,GAER;AAER;AAGA,MAAM,aAAa,eAAe,mBAAmB,UAAU;"}
@@ -5,27 +5,32 @@ import PickerFrame, { textFieldSlotPropsOf } from "./PickerFrame.js";
5
5
  import { DEFAULT_MINUTES_STEP, timeTextOf, pickerTimeOf } from "./pickerValues.js";
6
6
  import { usePickerField } from "./usePickerField.js";
7
7
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
8
- function TimeInput({
9
- name,
10
- label,
11
- value,
12
- onChange,
13
- onBlur,
14
- error,
15
- helperText = " ",
16
- minTime,
17
- maxTime,
18
- minutesStep = DEFAULT_MINUTES_STEP,
19
- disabled = false,
20
- inputRef,
21
- pickerProps,
22
- texts,
23
- ...unknownProps
24
- }) {
25
- warnUnknownProps("TimeInput", unknownProps);
26
- const field = usePickerField({ name, kind: "time", error, texts });
8
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
9
+ const THEME_NAME = "CalcitaTimeInput";
10
+ const TimeInputPicker = piecePart(THEME_NAME, "Picker", TimePicker);
11
+ function TimeInputContent(props) {
12
+ const {
13
+ name,
14
+ label,
15
+ value,
16
+ onChange,
17
+ onBlur,
18
+ error,
19
+ helperText = " ",
20
+ minTime,
21
+ maxTime,
22
+ minutesStep = DEFAULT_MINUTES_STEP,
23
+ disabled = false,
24
+ inputRef,
25
+ pickerProps,
26
+ messages,
27
+ texts,
28
+ ...unknownProps
29
+ } = usePieceProps(props, THEME_NAME);
30
+ warnUnknownProps(THEME_NAME, unknownProps);
31
+ const field = usePickerField({ name, kind: "time", error, label, messages, texts });
27
32
  return /* @__PURE__ */ jsx(PickerFrame, { inputId: field.inputId, label, language: field.language, children: /* @__PURE__ */ jsx(
28
- TimePicker,
33
+ TimeInputPicker,
29
34
  {
30
35
  ...pickerProps,
31
36
  format: field.formats.time,
@@ -49,6 +54,7 @@ function TimeInput({
49
54
  }
50
55
  ) });
51
56
  }
57
+ const TimeInput = withPieceSlots(TimeInputContent, THEME_NAME);
52
58
  export {
53
59
  TimeInput as default
54
60
  };
@@ -1 +1 @@
1
- {"version":3,"file":"TimeInput.js","sources":["../../src/datePickers/TimeInput.jsx"],"sourcesContent":["// Campo de HORA suelto con el TimePicker de MUI X (@stackcraftmx/calcita/date-pickers), para una hora del día sin fecha:\n// la hora de una cita en un día ya elegido, el horario de una sucursal, «recordar a las 08:00».\n//\n// Viaja 'HH:mm' de 24 horas aunque en pantalla se vea con a.m. y p.m. (el hourCycle del proveedor decide cómo se ve, no\n// cómo viaja). Una hora del día no tiene zona: no se pasa por Date ni por UTC. '' = vacía.\n//\n// Para un instante (fecha y hora de algo que pasa una vez) va DateTimeInput, que sí viaja en UTC.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {TimePicker} from '@mui/x-date-pickers/TimePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {DEFAULT_MINUTES_STEP, pickerTimeOf, timeTextOf} from '@/datePickers/pickerValues.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value 'HH:mm' o ''\n * @param {(value: string) => void} props.onChange recibe 'HH:mm' ('' al borrar o a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText]\n * @param {string} [props.minTime] 'HH:mm'\n * @param {string} [props.maxTime] 'HH:mm'\n * @param {number} [props.minutesStep] de cuánto en cuánto van los minutos; por omisión de uno en uno (30 para citas de\n * media hora)\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del TimePicker de MUI X que aquí no tiene nombre (views, shouldDisableTime,\n * slots, slotProps…); value y onChange son del campo\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function TimeInput({\n name, label, value, onChange, onBlur, error, helperText = ' ', minTime, maxTime, minutesStep = DEFAULT_MINUTES_STEP, disabled = false, inputRef,\n pickerProps, texts,\n ...unknownProps\n}) {\n warnUnknownProps('TimeInput', unknownProps);\n const field = usePickerField({name, kind: 'time', error, texts});\n\n return (\n <PickerFrame inputId={field.inputId} label={label} language={field.language}>\n <TimePicker\n {...pickerProps}\n format={field.formats.time}\n ampm={field.formats.ampm}\n value={pickerTimeOf(value)}\n minTime={pickerTimeOf(minTime) ?? undefined}\n maxTime={pickerTimeOf(maxTime) ?? undefined}\n disabled={disabled}\n minutesStep={minutesStep}\n timeSteps={{minutes: minutesStep, ...pickerProps?.timeSteps}}\n inputRef={inputRef}\n onChange={(pickedValue) => onChange(timeTextOf(pickedValue))}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf(\n {id: field.inputId, name, onBlur, error: Boolean(field.errorText), helperText: field.errorText ?? helperText},\n pickerProps,\n )}\n />\n </PickerFrame>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAmCA,SAAwB,UAAU;AAAA,EAC9B;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAO,aAAa;AAAA,EAAK;AAAA,EAAS;AAAA,EAAS,cAAc;AAAA,EAAsB,WAAW;AAAA,EAAO;AAAA,EACvI;AAAA,EAAa;AAAA,EACb,GAAG;AACP,GAAG;AACC,mBAAiB,aAAa,YAAY;AAC1C,QAAM,QAAQ,eAAe,EAAC,MAAM,MAAM,QAAQ,OAAO,OAAM;AAE/D,SACI,oBAAC,eAAY,SAAS,MAAM,SAAS,OAAc,UAAU,MAAM,UAC/D,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,QAAQ,MAAM,QAAQ;AAAA,MACtB,MAAM,MAAM,QAAQ;AAAA,MACpB,OAAO,aAAa,KAAK;AAAA,MACzB,SAAS,aAAa,OAAO,KAAK;AAAA,MAClC,SAAS,aAAa,OAAO,KAAK;AAAA,MAClC;AAAA,MACA;AAAA,MACA,WAAW,EAAC,SAAS,aAAa,GAAG,aAAa,UAAA;AAAA,MAClD;AAAA,MACA,UAAU,CAAC,gBAAgB,SAAS,WAAW,WAAW,CAAC;AAAA,MAC3D,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACP,EAAC,IAAI,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,SAAS,GAAG,YAAY,MAAM,aAAa,WAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA,GAER;AAER;"}
1
+ {"version":3,"file":"TimeInput.js","sources":["../../src/datePickers/TimeInput.jsx"],"sourcesContent":["// Campo de HORA suelto con el TimePicker de MUI X (@stackcraftmx/calcita/date-pickers), para una hora del día sin fecha:\n// la hora de una cita en un día ya elegido, el horario de una sucursal, «recordar a las 08:00».\n//\n// Viaja 'HH:mm' de 24 horas aunque en pantalla se vea con a.m. y p.m. (el hourCycle del proveedor decide cómo se ve, no\n// cómo viaja). Una hora del día no tiene zona: no se pasa por Date ni por UTC. '' = vacía.\n//\n// Para un instante (fecha y hora de algo que pasa una vez) va DateTimeInput, que sí viaja en UTC.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaTimeInput con defaultProps, styleOverrides de\n// sus partes (picker) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {TimePicker} from '@mui/x-date-pickers/TimePicker';\n\nimport PickerFrame, {textFieldSlotPropsOf} from '@/datePickers/PickerFrame.jsx';\nimport {DEFAULT_MINUTES_STEP, pickerTimeOf, timeTextOf} from '@/datePickers/pickerValues.js';\nimport {usePickerField} from '@/datePickers/usePickerField.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaTimeInput)\nconst THEME_NAME = 'CalcitaTimeInput';\nconst TimeInputPicker = piecePart(THEME_NAME, 'Picker', TimePicker);\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {string} props.label ya traducido\n * @param {string|null|undefined} props.value 'HH:mm' o ''\n * @param {(value: string) => void} props.onChange recibe 'HH:mm' ('' al borrar o a medias)\n * @param {() => void} [props.onBlur]\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText]\n * @param {string} [props.minTime] 'HH:mm'\n * @param {string} [props.maxTime] 'HH:mm'\n * @param {number} [props.minutesStep] de cuánto en cuánto van los minutos; por omisión de uno en uno (30 para citas de\n * media hora)\n * @param {boolean} [props.disabled]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef]\n * @param {object} [props.pickerProps] lo demás del TimePicker de MUI X que aquí no tiene nombre (views, shouldDisableTime,\n * slots, slotProps…); value y onChange son del campo\n * @param {Record<string, string|object>} [props.messages] el texto del error de este campo, por regla de validación\n * ({required: 'Elija la fecha', min: 'Desde mañana'}): gana al de Calcita y al de los textos\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction TimeInputContent(props) {\n const {\n name, label, value, onChange, onBlur, error, helperText = ' ', minTime, maxTime, minutesStep = DEFAULT_MINUTES_STEP, disabled = false, inputRef,\n pickerProps, messages, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const field = usePickerField({name, kind: 'time', error, label, messages, texts});\n\n return (\n <PickerFrame inputId={field.inputId} label={label} language={field.language}>\n <TimeInputPicker\n {...pickerProps}\n format={field.formats.time}\n ampm={field.formats.ampm}\n value={pickerTimeOf(value)}\n minTime={pickerTimeOf(minTime) ?? undefined}\n maxTime={pickerTimeOf(maxTime) ?? undefined}\n disabled={disabled}\n minutesStep={minutesStep}\n timeSteps={{minutes: minutesStep, ...pickerProps?.timeSteps}}\n inputRef={inputRef}\n onChange={(pickedValue) => onChange(timeTextOf(pickedValue))}\n onClose={() => {\n pickerProps?.onClose?.();\n onBlur?.();\n }}\n slotProps={textFieldSlotPropsOf(\n {id: field.inputId, name, onBlur, error: Boolean(field.errorText), helperText: field.errorText ?? helperText},\n pickerProps,\n )}\n />\n </PickerFrame>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst TimeInput = withPieceSlots(TimeInputContent, THEME_NAME);\nexport default TimeInput;\n"],"names":[],"mappings":";;;;;;;;AAqBA,MAAM,aAAa;AACnB,MAAM,kBAAkB,UAAU,YAAY,UAAU,UAAU;AAuBlE,SAAS,iBAAiB,OAAO;AAC7B,QAAM;AAAA,IACF;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAO,aAAa;AAAA,IAAK;AAAA,IAAS;AAAA,IAAS,cAAc;AAAA,IAAsB,WAAW;AAAA,IAAO;AAAA,IACvI;AAAA,IAAa;AAAA,IAAU;AAAA,IACvB,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,QAAQ,eAAe,EAAC,MAAM,MAAM,QAAQ,OAAO,OAAO,UAAU,OAAM;AAEhF,SACI,oBAAC,eAAY,SAAS,MAAM,SAAS,OAAc,UAAU,MAAM,UAC/D,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ,QAAQ,MAAM,QAAQ;AAAA,MACtB,MAAM,MAAM,QAAQ;AAAA,MACpB,OAAO,aAAa,KAAK;AAAA,MACzB,SAAS,aAAa,OAAO,KAAK;AAAA,MAClC,SAAS,aAAa,OAAO,KAAK;AAAA,MAClC;AAAA,MACA;AAAA,MACA,WAAW,EAAC,SAAS,aAAa,GAAG,aAAa,UAAA;AAAA,MAClD;AAAA,MACA,UAAU,CAAC,gBAAgB,SAAS,WAAW,WAAW,CAAC;AAAA,MAC3D,SAAS,MAAM;AACX,qBAAa,UAAA;AACb,iBAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,QACP,EAAC,IAAI,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,SAAS,GAAG,YAAY,MAAM,aAAa,WAAA;AAAA,QAClG;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA,GAER;AAER;AAGA,MAAM,YAAY,eAAe,kBAAkB,UAAU;"}