@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
@@ -4,12 +4,16 @@ import Box from "@mui/material/Box";
4
4
  import Paper from "@mui/material/Paper";
5
5
  import Skeleton from "@mui/material/Skeleton";
6
6
  import Stack from "@mui/material/Stack";
7
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
7
8
  import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
8
9
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
9
- function RecordCardSkeleton({ groups = 2, factsPerGroup = 3, withAvatar = true, withHighlight = true, sx, texts, ...unknownProps }) {
10
- warnUnknownProps("RecordCardSkeleton", unknownProps);
10
+ const THEME_NAME = "CalcitaRecordCardSkeleton";
11
+ const RecordCardSkeletonRoot = piecePart(THEME_NAME, "Root", Paper);
12
+ function RecordCardSkeletonContent(props) {
13
+ const { groups = 2, factsPerGroup = 3, withAvatar = true, withHighlight = true, sx, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
14
+ warnUnknownProps(THEME_NAME, unknownProps);
11
15
  const { t } = useToolkitTranslation("common", texts);
12
- return /* @__PURE__ */ jsxs(Paper, { variant: "outlined", role: "status", "aria-label": t("recordCard.loading"), sx: { p: { xs: 2, sm: 2.5 }, ...sx }, children: [
16
+ return /* @__PURE__ */ jsxs(RecordCardSkeletonRoot, { variant: "outlined", role: "status", "aria-label": t("recordCard.loading"), ownSx: { p: { xs: 2, sm: 2.5 } }, sx, children: [
13
17
  /* @__PURE__ */ jsxs(Stack, { direction: "row", sx: { gap: 1.5, alignItems: "center" }, children: [
14
18
  withAvatar && /* @__PURE__ */ jsx(Skeleton, { variant: "circular", width: 44, height: 44 }),
15
19
  /* @__PURE__ */ jsxs(Box, { sx: { flex: 1 }, children: [
@@ -27,6 +31,7 @@ function RecordCardSkeleton({ groups = 2, factsPerGroup = 3, withAvatar = true,
27
31
  ] })
28
32
  ] });
29
33
  }
34
+ const RecordCardSkeleton = withPieceSlots(RecordCardSkeletonContent, THEME_NAME);
30
35
  export {
31
36
  RecordCardSkeleton as default
32
37
  };
@@ -1 +1 @@
1
- {"version":3,"file":"RecordCardSkeleton.js","sources":["../../../src/ui/cards/RecordCardSkeleton.jsx"],"sourcesContent":["// El esqueleto de RecordCard mientras llega la lista: la misma forma (avatar, títulos, grupos de datos y dato principal),\n// así la página no brinca cuando aparecen las tarjetas de verdad. Para un lector de pantalla dice «Cargando».\n//\n// Genérico del paquete: function (regla de la casa).\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Skeleton from '@mui/material/Skeleton';\nimport Stack from '@mui/material/Stack';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/**\n * @param {object} props\n * @param {number} [props.groups] cuántos grupos de datos (como los de la tarjeta)\n * @param {number} [props.factsPerGroup]\n * @param {boolean} [props.withAvatar]\n * @param {boolean} [props.withHighlight]\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function RecordCardSkeleton({groups = 2, factsPerGroup = 3, withAvatar = true, withHighlight = true, sx, texts, ...unknownProps}) {\n warnUnknownProps('RecordCardSkeleton', unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n return (\n <Paper variant=\"outlined\" role=\"status\" aria-label={t('recordCard.loading')} sx={{p: {xs: 2, sm: 2.5}, ...sx}}>\n <Stack direction=\"row\" sx={{gap: 1.5, alignItems: 'center'}}>\n {withAvatar && <Skeleton variant=\"circular\" width={44} height={44} />}\n <Box sx={{flex: 1}}>\n <Skeleton width=\"20%\" />\n <Skeleton width=\"45%\" height={28} />\n </Box>\n <Skeleton variant=\"rounded\" width={88} height={24} />\n </Stack>\n <Box sx={{mt: 2, display: 'grid', gap: 3, gridTemplateColumns: {xs: '1fr', md: `repeat(${groups}, 1fr)${withHighlight ? ' 140px' : ''}`}}}>\n {Array.from({length: groups}, (unused, groupIndex) => (\n <Box key={groupIndex}>\n {Array.from({length: factsPerGroup}, (unusedFact, factIndex) => <Skeleton key={factIndex} />)}\n </Box>\n ))}\n {withHighlight && <Box><Skeleton width=\"60%\" /><Skeleton height={36} /></Box>}\n </Box>\n </Paper>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAqBA,SAAwB,mBAAmB,EAAC,SAAS,GAAG,gBAAgB,GAAG,aAAa,MAAM,gBAAgB,MAAM,IAAI,OAAO,GAAG,gBAAe;AAC7I,mBAAiB,sBAAsB,YAAY;AACnD,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,SACI,qBAAC,SAAM,SAAQ,YAAW,MAAK,UAAS,cAAY,EAAE,oBAAoB,GAAG,IAAI,EAAC,GAAG,EAAC,IAAI,GAAG,IAAI,OAAM,GAAG,GAAA,GACtG,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAM,WAAU,OAAM,IAAI,EAAC,KAAK,KAAK,YAAY,SAAA,GAC7C,UAAA;AAAA,MAAA,kCAAe,UAAA,EAAS,SAAQ,YAAW,OAAO,IAAI,QAAQ,IAAI;AAAA,2BAClE,KAAA,EAAI,IAAI,EAAC,MAAM,KACZ,UAAA;AAAA,QAAA,oBAAC,UAAA,EAAS,OAAM,MAAA,CAAM;AAAA,QACtB,oBAAC,UAAA,EAAS,OAAM,OAAM,QAAQ,GAAA,CAAI;AAAA,MAAA,GACtC;AAAA,0BACC,UAAA,EAAS,SAAQ,WAAU,OAAO,IAAI,QAAQ,GAAA,CAAI;AAAA,IAAA,GACvD;AAAA,IACA,qBAAC,OAAI,IAAI,EAAC,IAAI,GAAG,SAAS,QAAQ,KAAK,GAAG,qBAAqB,EAAC,IAAI,OAAO,IAAI,UAAU,MAAM,SAAS,gBAAgB,WAAW,EAAE,GAAA,EAAE,GAClI,UAAA;AAAA,MAAA,MAAM,KAAK,EAAC,QAAQ,OAAA,GAAS,CAAC,QAAQ,eACnC,oBAAC,KAAA,EACI,UAAA,MAAM,KAAK,EAAC,QAAQ,cAAA,GAAgB,CAAC,YAAY,cAAc,oBAAC,UAAA,CAAA,GAAc,SAAW,CAAE,EAAA,GADtF,UAEV,CACH;AAAA,MACA,sCAAkB,KAAA,EAAI,UAAA;AAAA,QAAA,oBAAC,UAAA,EAAS,OAAM,MAAA,CAAM;AAAA,QAAE,oBAAC,UAAA,EAAS,QAAQ,GAAA,CAAI;AAAA,MAAA,EAAA,CAAE;AAAA,IAAA,EAAA,CAC3E;AAAA,EAAA,GACJ;AAER;"}
1
+ {"version":3,"file":"RecordCardSkeleton.js","sources":["../../../src/ui/cards/RecordCardSkeleton.jsx"],"sourcesContent":["// El esqueleto de RecordCard mientras llega la lista: la misma forma (avatar, títulos, grupos de datos y dato principal),\n// así la página no brinca cuando aparecen las tarjetas de verdad. Para un lector de pantalla dice «Cargando».\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaRecordCardSkeleton con defaultProps (p. ej.\n// {groups: 3}), styleOverrides de su parte root y slots/slotProps.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Skeleton from '@mui/material/Skeleton';\nimport Stack from '@mui/material/Stack';\n\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaRecordCardSkeleton)\nconst THEME_NAME = 'CalcitaRecordCardSkeleton';\nconst RecordCardSkeletonRoot = piecePart(THEME_NAME, 'Root', Paper);\n\n/**\n * @param {object} props\n * @param {number} [props.groups] cuántos grupos de datos (como los de la tarjeta)\n * @param {number} [props.factsPerGroup]\n * @param {boolean} [props.withAvatar]\n * @param {boolean} [props.withHighlight]\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction RecordCardSkeletonContent(props) {\n const {groups = 2, factsPerGroup = 3, withAvatar = true, withHighlight = true, sx, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n return (\n <RecordCardSkeletonRoot variant=\"outlined\" role=\"status\" aria-label={t('recordCard.loading')} ownSx={{p: {xs: 2, sm: 2.5}}} sx={sx}>\n <Stack direction=\"row\" sx={{gap: 1.5, alignItems: 'center'}}>\n {withAvatar && <Skeleton variant=\"circular\" width={44} height={44} />}\n <Box sx={{flex: 1}}>\n <Skeleton width=\"20%\" />\n <Skeleton width=\"45%\" height={28} />\n </Box>\n <Skeleton variant=\"rounded\" width={88} height={24} />\n </Stack>\n <Box sx={{mt: 2, display: 'grid', gap: 3, gridTemplateColumns: {xs: '1fr', md: `repeat(${groups}, 1fr)${withHighlight ? ' 140px' : ''}`}}}>\n {Array.from({length: groups}, (unused, groupIndex) => (\n <Box key={groupIndex}>\n {Array.from({length: factsPerGroup}, (unusedFact, factIndex) => <Skeleton key={factIndex} />)}\n </Box>\n ))}\n {withHighlight && <Box><Skeleton width=\"60%\" /><Skeleton height={36} /></Box>}\n </Box>\n </RecordCardSkeletonRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst RecordCardSkeleton = withPieceSlots(RecordCardSkeletonContent, THEME_NAME);\nexport default RecordCardSkeleton;\n"],"names":[],"mappings":";;;;;;;;;AAiBA,MAAM,aAAa;AACnB,MAAM,yBAAyB,UAAU,YAAY,QAAQ,KAAK;AAWlE,SAAS,0BAA0B,OAAO;AACtC,QAAM,EAAC,SAAS,GAAG,gBAAgB,GAAG,aAAa,MAAM,gBAAgB,MAAM,IAAI,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC5I,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,SACI,qBAAC,0BAAuB,SAAQ,YAAW,MAAK,UAAS,cAAY,EAAE,oBAAoB,GAAG,OAAO,EAAC,GAAG,EAAC,IAAI,GAAG,IAAI,IAAA,EAAG,GAAI,IACxH,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAM,WAAU,OAAM,IAAI,EAAC,KAAK,KAAK,YAAY,SAAA,GAC7C,UAAA;AAAA,MAAA,kCAAe,UAAA,EAAS,SAAQ,YAAW,OAAO,IAAI,QAAQ,IAAI;AAAA,2BAClE,KAAA,EAAI,IAAI,EAAC,MAAM,KACZ,UAAA;AAAA,QAAA,oBAAC,UAAA,EAAS,OAAM,MAAA,CAAM;AAAA,QACtB,oBAAC,UAAA,EAAS,OAAM,OAAM,QAAQ,GAAA,CAAI;AAAA,MAAA,GACtC;AAAA,0BACC,UAAA,EAAS,SAAQ,WAAU,OAAO,IAAI,QAAQ,GAAA,CAAI;AAAA,IAAA,GACvD;AAAA,IACA,qBAAC,OAAI,IAAI,EAAC,IAAI,GAAG,SAAS,QAAQ,KAAK,GAAG,qBAAqB,EAAC,IAAI,OAAO,IAAI,UAAU,MAAM,SAAS,gBAAgB,WAAW,EAAE,GAAA,EAAE,GAClI,UAAA;AAAA,MAAA,MAAM,KAAK,EAAC,QAAQ,OAAA,GAAS,CAAC,QAAQ,eACnC,oBAAC,KAAA,EACI,UAAA,MAAM,KAAK,EAAC,QAAQ,cAAA,GAAgB,CAAC,YAAY,cAAc,oBAAC,UAAA,CAAA,GAAc,SAAW,CAAE,EAAA,GADtF,UAEV,CACH;AAAA,MACA,sCAAkB,KAAA,EAAI,UAAA;AAAA,QAAA,oBAAC,UAAA,EAAS,OAAM,MAAA,CAAM;AAAA,QAAE,oBAAC,UAAA,EAAS,QAAQ,GAAA,CAAI;AAAA,MAAA,EAAA,CAAE;AAAA,IAAA,EAAA,CAC3E;AAAA,EAAA,GACJ;AAER;AAGA,MAAM,qBAAqB,eAAe,2BAA2B,UAAU;"}
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import Typography from "@mui/material/Typography";
4
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
4
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
5
5
  import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
6
6
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
7
7
  import { countdownClockOf } from "./countdownParts.js";
8
8
  import { useCountdown } from "./useCountdown.js";
9
9
  const THEME_NAME = "CalcitaCountdown";
10
10
  const CountdownRoot = piecePart(THEME_NAME, "Root", Typography);
11
- function Countdown(props) {
11
+ function CountdownContent(props) {
12
12
  const {
13
13
  until,
14
14
  label,
@@ -32,6 +32,7 @@ function Countdown(props) {
32
32
  }
33
33
  return /* @__PURE__ */ jsx(CountdownRoot, { variant, role: "timer", "aria-label": label, ownSx: { fontVariantNumeric: "tabular-nums" }, sx, children: countdownClockOf(parts, { daysLabel: t("countdown.daysShort"), showSeconds }) });
34
34
  }
35
+ const Countdown = withPieceSlots(CountdownContent, THEME_NAME);
35
36
  export {
36
37
  Countdown as default
37
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Countdown.js","sources":["../../../src/ui/countdown/Countdown.jsx"],"sourcesContent":["// La cuenta regresiva ya pintada: «02:14:30» hasta un momento (el cierre de unas inscripciones, el inicio de una cita, el fin de\n// una oferta), con días cuando faltan («3 d 02:14:30»), y lo que dice al llegar a cero («Ya terminó»). Avisa con onComplete\n// una sola vez.\n//\n// Para un lector de pantalla es un temporizador (role=\"timer\"): no anuncia cada segundo, sí el final (role=\"status\").\n// Con children como función se pinta a su manera: children(parts) recibe {days, hours, minutes, seconds, isOver}.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCountdown con defaultProps y\n// styleOverrides de su parte root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Typography from '@mui/material/Typography';\n\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {countdownClockOf} from '@/ui/countdown/countdownParts.js';\nimport {useCountdown} from '@/ui/countdown/useCountdown.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaCountdown)\nconst THEME_NAME = 'CalcitaCountdown';\nconst CountdownRoot = piecePart(THEME_NAME, 'Root', Typography);\n\n/**\n * @param {object} props\n * @param {string|number|Date} props.until el momento: un instante en texto, un Date o milisegundos\n * @param {string} [props.label] ya traducido: qué se cuenta («Tiempo para que cierren las inscripciones»), para un lector de pantalla\n * @param {() => void} [props.onComplete] al llegar a cero (una vez)\n * @param {import('react').ReactNode} [props.completedText] lo que dice al terminar; por omisión «Ya terminó»\n * @param {boolean} [props.showSeconds] por omisión, sí\n * @param {(parts: {days: number, hours: number, minutes: number, seconds: number, totalSeconds: number, isOver: boolean}) => import('react').ReactNode} [props.children]\n * para pintarla a su manera\n * @param {import('@mui/material/Typography').TypographyProps['variant']} [props.variant] por omisión body1\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function Countdown(props) {\n const {\n until, label, onComplete, completedText, showSeconds = true, children, variant = 'body1', sx, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {parts, isOver} = useCountdown(until, {onComplete});\n\n if (typeof children === 'function') {\n return children(parts);\n }\n if (isOver) {\n return (\n <CountdownRoot variant={variant} role=\"status\" ownSx={{fontVariantNumeric: 'tabular-nums'}} sx={sx}>\n {completedText ?? t('countdown.done')}\n </CountdownRoot>\n );\n }\n return (\n <CountdownRoot variant={variant} role=\"timer\" aria-label={label} ownSx={{fontVariantNumeric: 'tabular-nums'}} sx={sx}>\n {countdownClockOf(parts, {daysLabel: t('countdown.daysShort'), showSeconds})}\n </CountdownRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAoBA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,QAAQ,UAAU;AAe9D,SAAwB,UAAU,OAAO;AACrC,QAAM;AAAA,IACF;AAAA,IAAO;AAAA,IAAO;AAAA,IAAY;AAAA,IAAe,cAAc;AAAA,IAAM;AAAA,IAAU,UAAU;AAAA,IAAS;AAAA,IAAI;AAAA,IAC9F,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,OAAO,OAAA,IAAU,aAAa,OAAO,EAAC,YAAW;AAExD,MAAI,OAAO,aAAa,YAAY;AAChC,WAAO,SAAS,KAAK;AAAA,EACzB;AACA,MAAI,QAAQ;AACR,WACI,oBAAC,eAAA,EAAc,SAAkB,MAAK,UAAS,OAAO,EAAC,oBAAoB,eAAA,GAAiB,IACvF,UAAA,iBAAiB,EAAE,gBAAgB,GACxC;AAAA,EAER;AACA,SACI,oBAAC,iBAAc,SAAkB,MAAK,SAAQ,cAAY,OAAO,OAAO,EAAC,oBAAoB,kBAAiB,IACzG,UAAA,iBAAiB,OAAO,EAAC,WAAW,EAAE,qBAAqB,GAAG,YAAA,CAAY,GAC/E;AAER;"}
1
+ {"version":3,"file":"Countdown.js","sources":["../../../src/ui/countdown/Countdown.jsx"],"sourcesContent":["// La cuenta regresiva ya pintada: «02:14:30» hasta un momento (el cierre de unas inscripciones, el inicio de una cita, el fin de\n// una oferta), con días cuando faltan («3 d 02:14:30»), y lo que dice al llegar a cero («Ya terminó»). Avisa con onComplete\n// una sola vez.\n//\n// Para un lector de pantalla es un temporizador (role=\"timer\"): no anuncia cada segundo, sí el final (role=\"status\").\n// Con children como función se pinta a su manera: children(parts) recibe {days, hours, minutes, seconds, isOver}.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCountdown con defaultProps y\n// styleOverrides de su parte root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Typography from '@mui/material/Typography';\n\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {countdownClockOf} from '@/ui/countdown/countdownParts.js';\nimport {useCountdown} from '@/ui/countdown/useCountdown.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaCountdown)\nconst THEME_NAME = 'CalcitaCountdown';\nconst CountdownRoot = piecePart(THEME_NAME, 'Root', Typography);\n\n/**\n * @param {object} props\n * @param {string|number|Date} props.until el momento: un instante en texto, un Date o milisegundos\n * @param {string} [props.label] ya traducido: qué se cuenta («Tiempo para que cierren las inscripciones»), para un lector de pantalla\n * @param {() => void} [props.onComplete] al llegar a cero (una vez)\n * @param {import('react').ReactNode} [props.completedText] lo que dice al terminar; por omisión «Ya terminó»\n * @param {boolean} [props.showSeconds] por omisión, sí\n * @param {(parts: {days: number, hours: number, minutes: number, seconds: number, totalSeconds: number, isOver: boolean}) => import('react').ReactNode} [props.children]\n * para pintarla a su manera\n * @param {import('@mui/material/Typography').TypographyProps['variant']} [props.variant] por omisión body1\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction CountdownContent(props) {\n const {\n until, label, onComplete, completedText, showSeconds = true, children, variant = 'body1', sx, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {parts, isOver} = useCountdown(until, {onComplete});\n\n if (typeof children === 'function') {\n return children(parts);\n }\n if (isOver) {\n return (\n <CountdownRoot variant={variant} role=\"status\" ownSx={{fontVariantNumeric: 'tabular-nums'}} sx={sx}>\n {completedText ?? t('countdown.done')}\n </CountdownRoot>\n );\n }\n return (\n <CountdownRoot variant={variant} role=\"timer\" aria-label={label} ownSx={{fontVariantNumeric: 'tabular-nums'}} sx={sx}>\n {countdownClockOf(parts, {daysLabel: t('countdown.daysShort'), showSeconds})}\n </CountdownRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst Countdown = withPieceSlots(CountdownContent, THEME_NAME);\nexport default Countdown;\n"],"names":[],"mappings":";;;;;;;;AAoBA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,QAAQ,UAAU;AAe9D,SAAS,iBAAiB,OAAO;AAC7B,QAAM;AAAA,IACF;AAAA,IAAO;AAAA,IAAO;AAAA,IAAY;AAAA,IAAe,cAAc;AAAA,IAAM;AAAA,IAAU,UAAU;AAAA,IAAS;AAAA,IAAI;AAAA,IAC9F,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,OAAO,OAAA,IAAU,aAAa,OAAO,EAAC,YAAW;AAExD,MAAI,OAAO,aAAa,YAAY;AAChC,WAAO,SAAS,KAAK;AAAA,EACzB;AACA,MAAI,QAAQ;AACR,WACI,oBAAC,eAAA,EAAc,SAAkB,MAAK,UAAS,OAAO,EAAC,oBAAoB,eAAA,GAAiB,IACvF,UAAA,iBAAiB,EAAE,gBAAgB,GACxC;AAAA,EAER;AACA,SACI,oBAAC,iBAAc,SAAkB,MAAK,SAAQ,cAAY,OAAO,OAAO,EAAC,oBAAoB,kBAAiB,IACzG,UAAA,iBAAiB,OAAO,EAAC,WAAW,EAAE,qBAAqB,GAAG,YAAA,CAAY,GAC/E;AAER;AAGA,MAAM,YAAY,eAAe,kBAAkB,UAAU;"}
@@ -6,7 +6,7 @@ import Stack from "@mui/material/Stack";
6
6
  import Box from "@mui/material/Box";
7
7
  import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
8
8
  import OpenInNewRoundedIcon from "@mui/icons-material/OpenInNewRounded";
9
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
9
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
10
10
  import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
11
11
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
12
12
  import ContentDialog from "../layout/ContentDialog.js";
@@ -30,7 +30,7 @@ function usePdfUrl(src) {
30
30
  }
31
31
  return typeof src === "string" && src ? src : null;
32
32
  }
33
- function PdfViewerDialog(props) {
33
+ function PdfViewerDialogContent(props) {
34
34
  const { open, onClose, title, src, fileName, actions, onDownload, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
35
35
  warnUnknownProps(THEME_NAME, unknownProps);
36
36
  const { t } = useToolkitTranslation("common", texts);
@@ -75,6 +75,7 @@ function PdfViewerDialog(props) {
75
75
  ) : /* @__PURE__ */ jsx(Box, { sx: { height: { xs: "62vh", md: "72vh" }, borderRadius: 1, bgcolor: "action.hover" } })
76
76
  ] });
77
77
  }
78
+ const PdfViewerDialog = withPieceSlots(PdfViewerDialogContent, THEME_NAME);
78
79
  export {
79
80
  PdfViewerDialog as default
80
81
  };
@@ -1 +1 @@
1
- {"version":3,"file":"PdfViewerDialog.js","sources":["../../../src/ui/documents/PdfViewerDialog.jsx"],"sourcesContent":["// Un PDF en una ventana: el aviso de privacidad, un contrato, un estado de cuenta. Lo pinta el visor del navegador (sin\n// librerías: nada que descargar ni que actualizar) en la hoja de lectura de la casa (ContentDialog), con «Abrir en otra\n// pestaña» y «Descargar» arriba.\n//\n// OJO: en el iPhone el visor dentro de la página enseña solo la primera hoja y en algunos navegadores no se pinta; por eso\n// los dos botones siempre están a la vista: abrirlo aparte o bajarlo funciona en todos.\n//\n// src es la dirección del PDF o el archivo mismo (un Blob que mandó el API, un File elegido): del archivo se arma una\n// dirección en el navegador, sin subirlo, y se libera al cerrar.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPdfViewerDialog con defaultProps y\n// styleOverrides de sus partes: actions, frame.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useState} from 'react';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Box from '@mui/material/Box';\nimport FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';\nimport OpenInNewRoundedIcon from '@mui/icons-material/OpenInNewRounded';\n\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport ContentDialog from '@/ui/layout/ContentDialog.jsx';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPdfViewerDialog)\nconst THEME_NAME = 'CalcitaPdfViewerDialog';\nconst ViewerActions = piecePart(THEME_NAME, 'Actions', Stack);\nconst ViewerFrame = piecePart(THEME_NAME, 'Frame', 'iframe');\n\n/**\n * La dirección del PDF: la que llega tal cual, o una del navegador para un archivo (se libera al cambiarlo o al cerrar).\n *\n * @param {string|Blob|null|undefined} src\n * @returns {string|null}\n */\nfunction usePdfUrl(src) {\n const [blobUrl, setBlobUrl] = useState(null);\n const isBlob = typeof Blob !== 'undefined' && src instanceof Blob;\n\n useEffect(() => {\n if (!isBlob) {\n setBlobUrl(null);\n return undefined;\n }\n const url = URL.createObjectURL(src);\n setBlobUrl(url);\n return () => URL.revokeObjectURL(url);\n }, [isBlob, src]);\n\n if (isBlob) {\n return blobUrl;\n }\n return typeof src === 'string' && src ? src : null;\n}\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {string} props.title ya traducido: qué documento es\n * @param {string|Blob|null} props.src la dirección del PDF o el archivo (Blob o File)\n * @param {string} [props.fileName] con qué nombre se descarga (por omisión, el título con .pdf)\n * @param {import('react').ReactNode} [props.actions] botones suyos junto a «Abrir en otra pestaña» y «Descargar»\n * @param {() => void} [props.onDownload] al descargar (para registrarlo, por ejemplo)\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function PdfViewerDialog(props) {\n const {open, onClose, title, src, fileName, actions, onDownload, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const pdfUrl = usePdfUrl(open ? src : null);\n\n return (\n <ContentDialog open={open} onClose={onClose} title={title} texts={texts}>\n <ViewerActions direction=\"row\" ownSx={{gap: 1, flexWrap: 'wrap', mb: 2}}>\n <Button size=\"small\" variant=\"outlined\" startIcon={<OpenInNewRoundedIcon />} href={pdfUrl ?? undefined} target=\"_blank\"\n rel=\"noopener noreferrer\" disabled={!pdfUrl}>\n {t('pdfViewer.openInTab')}\n </Button>\n <Button size=\"small\" variant=\"outlined\" startIcon={<FileDownloadOutlinedIcon />} href={pdfUrl ?? undefined}\n download={fileName ?? `${title}.pdf`} disabled={!pdfUrl} onClick={onDownload}>\n {t('pdfViewer.download')}\n </Button>\n {actions}\n </ViewerActions>\n {pdfUrl ? (\n <ViewerFrame src={pdfUrl} title={title}\n ownSx={{display: 'block', width: '100%', height: {xs: '62vh', md: '72vh'}, border: 0, borderRadius: 1, bgcolor: 'action.hover'}} />\n ) : (\n <Box sx={{height: {xs: '62vh', md: '72vh'}, borderRadius: 1, bgcolor: 'action.hover'}} />\n )}\n </ContentDialog>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AA2BA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,WAAW,KAAK;AAC5D,MAAM,cAAc,UAAU,YAAY,SAAS,QAAQ;AAQ3D,SAAS,UAAU,KAAK;AACpB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,SAAS,OAAO,SAAS,eAAe,eAAe;AAE7D,YAAU,MAAM;AACZ,QAAI,CAAC,QAAQ;AACT,iBAAW,IAAI;AACf,aAAO;AAAA,IACX;AACA,UAAM,MAAM,IAAI,gBAAgB,GAAG;AACnC,eAAW,GAAG;AACd,WAAO,MAAM,IAAI,gBAAgB,GAAG;AAAA,EACxC,GAAG,CAAC,QAAQ,GAAG,CAAC;AAEhB,MAAI,QAAQ;AACR,WAAO;AAAA,EACX;AACA,SAAO,OAAO,QAAQ,YAAY,MAAM,MAAM;AAClD;AAaA,SAAwB,gBAAgB,OAAO;AAC3C,QAAM,EAAC,MAAM,SAAS,OAAO,KAAK,UAAU,SAAS,YAAY,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC1H,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,SAAS,UAAU,OAAO,MAAM,IAAI;AAE1C,SACI,qBAAC,eAAA,EAAc,MAAY,SAAkB,OAAc,OACvD,UAAA;AAAA,IAAA,qBAAC,eAAA,EAAc,WAAU,OAAM,OAAO,EAAC,KAAK,GAAG,UAAU,QAAQ,IAAI,EAAA,GACjE,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UAAO,MAAK;AAAA,UAAQ,SAAQ;AAAA,UAAW,+BAAY,sBAAA,EAAqB;AAAA,UAAI,MAAM,UAAU;AAAA,UAAW,QAAO;AAAA,UACvG,KAAI;AAAA,UAAsB,UAAU,CAAC;AAAA,UACxC,YAAE,qBAAqB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE5B;AAAA,QAAC;AAAA,QAAA;AAAA,UAAO,MAAK;AAAA,UAAQ,SAAQ;AAAA,UAAW,+BAAY,0BAAA,EAAyB;AAAA,UAAI,MAAM,UAAU;AAAA,UACzF,UAAU,YAAY,GAAG,KAAK;AAAA,UAAQ,UAAU,CAAC;AAAA,UAAQ,SAAS;AAAA,UACrE,YAAE,oBAAoB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE1B;AAAA,IAAA,GACL;AAAA,IACC,SACG;AAAA,MAAC;AAAA,MAAA;AAAA,QAAY,KAAK;AAAA,QAAQ;AAAA,QACb,OAAO,EAAC,SAAS,SAAS,OAAO,QAAQ,QAAQ,EAAC,IAAI,QAAQ,IAAI,UAAS,QAAQ,GAAG,cAAc,GAAG,SAAS,eAAA;AAAA,MAAc;AAAA,IAAA,IAE3I,oBAAC,KAAA,EAAI,IAAI,EAAC,QAAQ,EAAC,IAAI,QAAQ,IAAI,UAAS,cAAc,GAAG,SAAS,iBAAc,CAAG;AAAA,EAAA,GAE/F;AAER;"}
1
+ {"version":3,"file":"PdfViewerDialog.js","sources":["../../../src/ui/documents/PdfViewerDialog.jsx"],"sourcesContent":["// Un PDF en una ventana: el aviso de privacidad, un contrato, un estado de cuenta. Lo pinta el visor del navegador (sin\n// librerías: nada que descargar ni que actualizar) en la hoja de lectura de la casa (ContentDialog), con «Abrir en otra\n// pestaña» y «Descargar» arriba.\n//\n// OJO: en el iPhone el visor dentro de la página enseña solo la primera hoja y en algunos navegadores no se pinta; por eso\n// los dos botones siempre están a la vista: abrirlo aparte o bajarlo funciona en todos.\n//\n// src es la dirección del PDF o el archivo mismo (un Blob que mandó el API, un File elegido): del archivo se arma una\n// dirección en el navegador, sin subirlo, y se libera al cerrar.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPdfViewerDialog con defaultProps y\n// styleOverrides de sus partes: actions, frame.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useState} from 'react';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Box from '@mui/material/Box';\nimport FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';\nimport OpenInNewRoundedIcon from '@mui/icons-material/OpenInNewRounded';\n\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport ContentDialog from '@/ui/layout/ContentDialog.jsx';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPdfViewerDialog)\nconst THEME_NAME = 'CalcitaPdfViewerDialog';\nconst ViewerActions = piecePart(THEME_NAME, 'Actions', Stack);\nconst ViewerFrame = piecePart(THEME_NAME, 'Frame', 'iframe');\n\n/**\n * La dirección del PDF: la que llega tal cual, o una del navegador para un archivo (se libera al cambiarlo o al cerrar).\n *\n * @param {string|Blob|null|undefined} src\n * @returns {string|null}\n */\nfunction usePdfUrl(src) {\n const [blobUrl, setBlobUrl] = useState(null);\n const isBlob = typeof Blob !== 'undefined' && src instanceof Blob;\n\n useEffect(() => {\n if (!isBlob) {\n setBlobUrl(null);\n return undefined;\n }\n const url = URL.createObjectURL(src);\n setBlobUrl(url);\n return () => URL.revokeObjectURL(url);\n }, [isBlob, src]);\n\n if (isBlob) {\n return blobUrl;\n }\n return typeof src === 'string' && src ? src : null;\n}\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {string} props.title ya traducido: qué documento es\n * @param {string|Blob|null} props.src la dirección del PDF o el archivo (Blob o File)\n * @param {string} [props.fileName] con qué nombre se descarga (por omisión, el título con .pdf)\n * @param {import('react').ReactNode} [props.actions] botones suyos junto a «Abrir en otra pestaña» y «Descargar»\n * @param {() => void} [props.onDownload] al descargar (para registrarlo, por ejemplo)\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction PdfViewerDialogContent(props) {\n const {open, onClose, title, src, fileName, actions, onDownload, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const pdfUrl = usePdfUrl(open ? src : null);\n\n return (\n <ContentDialog open={open} onClose={onClose} title={title} texts={texts}>\n <ViewerActions direction=\"row\" ownSx={{gap: 1, flexWrap: 'wrap', mb: 2}}>\n <Button size=\"small\" variant=\"outlined\" startIcon={<OpenInNewRoundedIcon />} href={pdfUrl ?? undefined} target=\"_blank\"\n rel=\"noopener noreferrer\" disabled={!pdfUrl}>\n {t('pdfViewer.openInTab')}\n </Button>\n <Button size=\"small\" variant=\"outlined\" startIcon={<FileDownloadOutlinedIcon />} href={pdfUrl ?? undefined}\n download={fileName ?? `${title}.pdf`} disabled={!pdfUrl} onClick={onDownload}>\n {t('pdfViewer.download')}\n </Button>\n {actions}\n </ViewerActions>\n {pdfUrl ? (\n <ViewerFrame src={pdfUrl} title={title}\n ownSx={{display: 'block', width: '100%', height: {xs: '62vh', md: '72vh'}, border: 0, borderRadius: 1, bgcolor: 'action.hover'}} />\n ) : (\n <Box sx={{height: {xs: '62vh', md: '72vh'}, borderRadius: 1, bgcolor: 'action.hover'}} />\n )}\n </ContentDialog>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst PdfViewerDialog = withPieceSlots(PdfViewerDialogContent, THEME_NAME);\nexport default PdfViewerDialog;\n"],"names":[],"mappings":";;;;;;;;;;;;AA2BA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,WAAW,KAAK;AAC5D,MAAM,cAAc,UAAU,YAAY,SAAS,QAAQ;AAQ3D,SAAS,UAAU,KAAK;AACpB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,SAAS,OAAO,SAAS,eAAe,eAAe;AAE7D,YAAU,MAAM;AACZ,QAAI,CAAC,QAAQ;AACT,iBAAW,IAAI;AACf,aAAO;AAAA,IACX;AACA,UAAM,MAAM,IAAI,gBAAgB,GAAG;AACnC,eAAW,GAAG;AACd,WAAO,MAAM,IAAI,gBAAgB,GAAG;AAAA,EACxC,GAAG,CAAC,QAAQ,GAAG,CAAC;AAEhB,MAAI,QAAQ;AACR,WAAO;AAAA,EACX;AACA,SAAO,OAAO,QAAQ,YAAY,MAAM,MAAM;AAClD;AAaA,SAAS,uBAAuB,OAAO;AACnC,QAAM,EAAC,MAAM,SAAS,OAAO,KAAK,UAAU,SAAS,YAAY,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC1H,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,SAAS,UAAU,OAAO,MAAM,IAAI;AAE1C,SACI,qBAAC,eAAA,EAAc,MAAY,SAAkB,OAAc,OACvD,UAAA;AAAA,IAAA,qBAAC,eAAA,EAAc,WAAU,OAAM,OAAO,EAAC,KAAK,GAAG,UAAU,QAAQ,IAAI,EAAA,GACjE,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UAAO,MAAK;AAAA,UAAQ,SAAQ;AAAA,UAAW,+BAAY,sBAAA,EAAqB;AAAA,UAAI,MAAM,UAAU;AAAA,UAAW,QAAO;AAAA,UACvG,KAAI;AAAA,UAAsB,UAAU,CAAC;AAAA,UACxC,YAAE,qBAAqB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE5B;AAAA,QAAC;AAAA,QAAA;AAAA,UAAO,MAAK;AAAA,UAAQ,SAAQ;AAAA,UAAW,+BAAY,0BAAA,EAAyB;AAAA,UAAI,MAAM,UAAU;AAAA,UACzF,UAAU,YAAY,GAAG,KAAK;AAAA,UAAQ,UAAU,CAAC;AAAA,UAAQ,SAAS;AAAA,UACrE,YAAE,oBAAoB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE1B;AAAA,IAAA,GACL;AAAA,IACC,SACG;AAAA,MAAC;AAAA,MAAA;AAAA,QAAY,KAAK;AAAA,QAAQ;AAAA,QACb,OAAO,EAAC,SAAS,SAAS,OAAO,QAAQ,QAAQ,EAAC,IAAI,QAAQ,IAAI,UAAS,QAAQ,GAAG,cAAc,GAAG,SAAS,eAAA;AAAA,MAAc;AAAA,IAAA,IAE3I,oBAAC,KAAA,EAAI,IAAI,EAAC,QAAQ,EAAC,IAAI,QAAQ,IAAI,UAAS,cAAc,GAAG,SAAS,iBAAc,CAAG;AAAA,EAAA,GAE/F;AAER;AAGA,MAAM,kBAAkB,eAAe,wBAAwB,UAAU;"}
@@ -10,13 +10,13 @@ import TextField from "@mui/material/TextField";
10
10
  import Typography from "@mui/material/Typography";
11
11
  import DateRangeOutlinedIcon from "@mui/icons-material/DateRangeOutlined";
12
12
  import { useFormatters } from "../../toolkit/useFormatters.js";
13
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
13
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
14
14
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
15
15
  const THEME_NAME = "CalcitaDateRangeFilter";
16
16
  const RangeChip = piecePart(THEME_NAME, "Chip", Chip);
17
17
  const RangePanel = piecePart(THEME_NAME, "Panel", Stack);
18
18
  const RangeActions = piecePart(THEME_NAME, "Actions", Stack);
19
- function DateRangeFilter(props) {
19
+ function DateRangeFilterContent(props) {
20
20
  const { from = "", to = "", onChange, label, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
21
21
  warnUnknownProps(THEME_NAME, unknownProps);
22
22
  const { t } = useToolkitTranslation("table", texts);
@@ -89,6 +89,7 @@ function DateRangeFilter(props) {
89
89
  ] }) })
90
90
  ] });
91
91
  }
92
+ const DateRangeFilter = withPieceSlots(DateRangeFilterContent, THEME_NAME);
92
93
  export {
93
94
  DateRangeFilter as default
94
95
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangeFilter.js","sources":["../../../src/ui/filters/DateRangeFilter.jsx"],"sourcesContent":["// Un rango de fechas personalizado, como chip al lado de los accesos rápidos.\n//\n// Viaja como AAAA-MM-DD (día, no instante). Convertirlo a \"inicio del día\" y \"fin del día\" lo hace el SERVIDOR con la\n// zona del negocio: si lo hiciera el navegador con la suya, alguien en otra zona pediría otro rango sin saberlo.\n//\n// El calendario es el <input type=\"date\"> del TextField de MUI y no el DatePicker de @mui/x-date-pickers con moment,\n// para no sumar dos dependencias (x-date-pickers y moment) que ninguna\n// pantalla del 22-sep necesita. Si el calendario nativo estorba (Safari de escritorio), se cambia SOLO este archivo.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaDateRangeFilter con defaultProps y\n// styleOverrides de sus partes: chip, panel, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Popover from '@mui/material/Popover';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport DateRangeOutlinedIcon from '@mui/icons-material/DateRangeOutlined';\n\nimport {useFormatters} from '@/toolkit/useFormatters.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.CalcitaDateRangeFilter)\nconst THEME_NAME = 'CalcitaDateRangeFilter';\nconst RangeChip = piecePart(THEME_NAME, 'Chip', Chip);\nconst RangePanel = piecePart(THEME_NAME, 'Panel', Stack);\nconst RangeActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/**\n * @param {object} props\n * @param {string} [props.from] AAAA-MM-DD o '' si no hay\n * @param {string} [props.to] AAAA-MM-DD o '' si no hay\n * @param {(range: {from: string, to: string}) => void} props.onChange '' para quitar\n * @param {string} [props.label] ya traducido; por defecto \"Personalizado\"\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nexport default function DateRangeFilter(props) {\n // lo que el proyecto puso en su tema (components.CalcitaDateRangeFilter.defaultProps) y encima lo que llega aquí\n const {from = '', to = '', onChange, label, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const {formatDate} = useFormatters();\n const [anchorElement, setAnchorElement] = useState(null);\n const [draft, setDraft] = useState({from, to});\n const isActive = Boolean(from || to);\n // AAAA-MM-DD se compara bien como texto\n const isInvalid = Boolean(draft.from && draft.to && draft.from > draft.to);\n\n const open = (event) => {\n setDraft({from, to});\n setAnchorElement(event.currentTarget);\n };\n const close = () => setAnchorElement(null);\n const apply = () => {\n onChange(draft);\n close();\n };\n const clear = () => {\n onChange({from: '', to: ''});\n close();\n };\n\n const summary = isActive\n ? t('dateRange.summary', {from: from ? formatDate(from) : '…', to: to ? formatDate(to) : t('dateRange.today')})\n : (label ?? t('dateRange.label'));\n\n return (\n <>\n <RangeChip icon={<DateRangeOutlinedIcon />} label={summary} clickable onClick={open}\n variant={isActive ? 'filled' : 'outlined'} color={isActive ? 'primary' : 'default'}\n onDelete={isActive ? clear : undefined} ownSx={{flex: '0 0 auto', height: 32}} />\n <Popover open={Boolean(anchorElement)} anchorEl={anchorElement} onClose={close} anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}>\n <RangePanel spacing={2} ownSx={{p: 2, width: 280}}>\n <Typography variant=\"subtitle2\">{t('dateRange.title')}</Typography>\n <TextField type=\"date\" size=\"small\" fullWidth label={t('dateRange.from')} value={draft.from}\n helperText={t('dateRange.fromHelp')}\n onChange={(event) => setDraft((currentDraft) => ({...currentDraft, from: event.target.value}))}\n slotProps={{inputLabel: {shrink: true}, htmlInput: {max: draft.to || undefined}}} />\n <TextField type=\"date\" size=\"small\" fullWidth label={t('dateRange.to')} value={draft.to} error={isInvalid}\n helperText={isInvalid ? t('dateRange.invalid') : t('dateRange.toHelp')}\n onChange={(event) => setDraft((currentDraft) => ({...currentDraft, to: event.target.value}))}\n slotProps={{inputLabel: {shrink: true}, htmlInput: {min: draft.from || undefined}}} />\n <RangeActions direction=\"row\" spacing={1} ownSx={{justifyContent: 'flex-end'}}>\n {isActive && <Button onClick={clear}>{t('dateRange.clear')}</Button>}\n <Button variant=\"contained\" onClick={apply} disabled={isInvalid || !(draft.from || draft.to)}>\n {t('dateRange.apply')}\n </Button>\n </RangeActions>\n </RangePanel>\n </Popover>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DateRangeFilter.js","sources":["../../../src/ui/filters/DateRangeFilter.jsx"],"sourcesContent":["// Un rango de fechas personalizado, como chip al lado de los accesos rápidos.\n//\n// Viaja como AAAA-MM-DD (día, no instante). Convertirlo a \"inicio del día\" y \"fin del día\" lo hace el SERVIDOR con la\n// zona del negocio: si lo hiciera el navegador con la suya, alguien en otra zona pediría otro rango sin saberlo.\n//\n// El calendario es el <input type=\"date\"> del TextField de MUI y no el DatePicker de @mui/x-date-pickers con moment,\n// para no sumar dos dependencias (x-date-pickers y moment) que ninguna\n// pantalla del 22-sep necesita. Si el calendario nativo estorba (Safari de escritorio), se cambia SOLO este archivo.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaDateRangeFilter con defaultProps y\n// styleOverrides de sus partes: chip, panel, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Popover from '@mui/material/Popover';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport DateRangeOutlinedIcon from '@mui/icons-material/DateRangeOutlined';\n\nimport {useFormatters} from '@/toolkit/useFormatters.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.CalcitaDateRangeFilter)\nconst THEME_NAME = 'CalcitaDateRangeFilter';\nconst RangeChip = piecePart(THEME_NAME, 'Chip', Chip);\nconst RangePanel = piecePart(THEME_NAME, 'Panel', Stack);\nconst RangeActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/**\n * @param {object} props\n * @param {string} [props.from] AAAA-MM-DD o '' si no hay\n * @param {string} [props.to] AAAA-MM-DD o '' si no hay\n * @param {(range: {from: string, to: string}) => void} props.onChange '' para quitar\n * @param {string} [props.label] ya traducido; por defecto \"Personalizado\"\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nfunction DateRangeFilterContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaDateRangeFilter.defaultProps) y encima lo que llega aquí\n const {from = '', to = '', onChange, label, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const {formatDate} = useFormatters();\n const [anchorElement, setAnchorElement] = useState(null);\n const [draft, setDraft] = useState({from, to});\n const isActive = Boolean(from || to);\n // AAAA-MM-DD se compara bien como texto\n const isInvalid = Boolean(draft.from && draft.to && draft.from > draft.to);\n\n const open = (event) => {\n setDraft({from, to});\n setAnchorElement(event.currentTarget);\n };\n const close = () => setAnchorElement(null);\n const apply = () => {\n onChange(draft);\n close();\n };\n const clear = () => {\n onChange({from: '', to: ''});\n close();\n };\n\n const summary = isActive\n ? t('dateRange.summary', {from: from ? formatDate(from) : '…', to: to ? formatDate(to) : t('dateRange.today')})\n : (label ?? t('dateRange.label'));\n\n return (\n <>\n <RangeChip icon={<DateRangeOutlinedIcon />} label={summary} clickable onClick={open}\n variant={isActive ? 'filled' : 'outlined'} color={isActive ? 'primary' : 'default'}\n onDelete={isActive ? clear : undefined} ownSx={{flex: '0 0 auto', height: 32}} />\n <Popover open={Boolean(anchorElement)} anchorEl={anchorElement} onClose={close} anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}>\n <RangePanel spacing={2} ownSx={{p: 2, width: 280}}>\n <Typography variant=\"subtitle2\">{t('dateRange.title')}</Typography>\n <TextField type=\"date\" size=\"small\" fullWidth label={t('dateRange.from')} value={draft.from}\n helperText={t('dateRange.fromHelp')}\n onChange={(event) => setDraft((currentDraft) => ({...currentDraft, from: event.target.value}))}\n slotProps={{inputLabel: {shrink: true}, htmlInput: {max: draft.to || undefined}}} />\n <TextField type=\"date\" size=\"small\" fullWidth label={t('dateRange.to')} value={draft.to} error={isInvalid}\n helperText={isInvalid ? t('dateRange.invalid') : t('dateRange.toHelp')}\n onChange={(event) => setDraft((currentDraft) => ({...currentDraft, to: event.target.value}))}\n slotProps={{inputLabel: {shrink: true}, htmlInput: {min: draft.from || undefined}}} />\n <RangeActions direction=\"row\" spacing={1} ownSx={{justifyContent: 'flex-end'}}>\n {isActive && <Button onClick={clear}>{t('dateRange.clear')}</Button>}\n <Button variant=\"contained\" onClick={apply} disabled={isInvalid || !(draft.from || draft.to)}>\n {t('dateRange.apply')}\n </Button>\n </RangeActions>\n </RangePanel>\n </Popover>\n </>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst DateRangeFilter = withPieceSlots(DateRangeFilterContent, THEME_NAME);\nexport default DateRangeFilter;\n"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ import FieldFrame from "../../inputs/FieldFrame.js";
14
14
  import NumberInput from "../../inputs/NumberInput.js";
15
15
  import SelectInput from "../../inputs/SelectInput.js";
16
16
  import TextInput from "../../inputs/TextInput.js";
17
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
17
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
18
18
  import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
19
19
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
20
20
  import { drawerValuesOf, invalidRangesOf, emptyDrawerValuesOf, filterKeysOf, FILTER_FIELD_KIND, comparisonOf, COMPARISON_OPERATOR, comparisonTextOf } from "./filterDrawerFields.js";
@@ -132,7 +132,7 @@ function DrawerField({ field, values, setValue, invalidRanges, t }) {
132
132
  return null;
133
133
  }
134
134
  }
135
- function FilterDrawer(props) {
135
+ function FilterDrawerContent(props) {
136
136
  const {
137
137
  open,
138
138
  onClose,
@@ -204,6 +204,7 @@ function FilterDrawer(props) {
204
204
  }
205
205
  );
206
206
  }
207
+ const FilterDrawer = withPieceSlots(FilterDrawerContent, THEME_NAME);
207
208
  export {
208
209
  FILTER_DRAWER_ANCHOR,
209
210
  FilterDrawer as default
@@ -1 +1 @@
1
- {"version":3,"file":"FilterDrawer.js","sources":["../../../src/ui/filters/FilterDrawer.jsx"],"sourcesContent":["// El cajón de búsqueda: un panel que sale de un lado con los campos que filtran una lista (las listas, un rango\n// «desde-hasta», unas fechas, un monto con su operador), para cuando los filtros ya no caben arriba de la tabla.\n//\n// Lo que se cambia adentro es un BORRADOR: la lista no se mueve hasta «Buscar» (no se consulta al servidor con cada tecla).\n// «Limpiar» vacía los campos del cajón; «Buscar» manda todos juntos (onApply) y cierra. Un rango al revés («hasta» menor que\n// «desde») se dice en su campo y no deja buscar.\n//\n// Los campos se declaran (filterDrawerFields.js dice cómo viaja cada uno); con kind 'custom' va uno propio (render). Para\n// conectarlo a ServerTable con su botón y sus chips: ServerTableFilterDrawer de /table.\n//\n// Configurable: de qué lado sale (anchor), su ancho, su título y los textos de sus botones. En el teléfono ocupa todo el\n// ancho.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaFilterDrawer con defaultProps y\n// styleOverrides de sus partes: paper, header, body, footer.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useId, useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Drawer from '@mui/material/Drawer';\nimport IconButton from '@mui/material/IconButton';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport CloseRoundedIcon from '@mui/icons-material/CloseRounded';\n\nimport CatalogInput from '@/inputs/CatalogInput.jsx';\nimport CheckboxGroupInput from '@/inputs/CheckboxGroupInput.jsx';\nimport FieldFrame from '@/inputs/FieldFrame.jsx';\nimport NumberInput from '@/inputs/NumberInput.jsx';\nimport SelectInput from '@/inputs/SelectInput.jsx';\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {\n COMPARISON_OPERATOR, FILTER_FIELD_KIND, comparisonOf, comparisonTextOf, drawerValuesOf, emptyDrawerValuesOf, filterKeysOf,\n invalidRangesOf,\n} from '@/ui/filters/filterDrawerFields.js';\n\n/** De qué lado sale el cajón. */\nexport const FILTER_DRAWER_ANCHOR = Object.freeze({left: 'left', right: 'right'});\nconst DEFAULT_WIDTH = 380;\n// «Cualquiera» de una lista de una sola opción: no es una opción y viaja como '' (sin filtro)\nconst ANY_OPTION = '__calcita_any__';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaFilterDrawer)\nconst THEME_NAME = 'CalcitaFilterDrawer';\nconst FilterDrawerHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst FilterDrawerBody = piecePart(THEME_NAME, 'Body', Stack);\nconst FilterDrawerFooter = piecePart(THEME_NAME, 'Footer', Stack);\n\n/**\n * Dos campos lado a lado (desde y hasta, operador y número); en un cajón angosto se ven bien juntos.\n *\n * @param {{label: import('react').ReactNode, inputId: string, children: import('react').ReactNode, template?: string}} props\n */\nfunction PairedField({label, inputId, children, template = '1fr 1fr'}) {\n return (\n <FieldFrame inputId={inputId} label={label}>\n <Box sx={{display: 'grid', gridTemplateColumns: template, gap: 1.5, alignItems: 'start'}}>{children}</Box>\n </FieldFrame>\n );\n}\n\n/**\n * Un campo del cajón según su tipo, con las piezas de la casa.\n *\n * @param {object} props\n */\nfunction DrawerField({field, values, setValue, invalidRanges, t}) {\n const fieldId = useId();\n const [key] = filterKeysOf(field);\n switch (field.kind) {\n case FILTER_FIELD_KIND.text:\n return <TextInput label={field.label} value={values[key]} onChange={(text) => setValue(key, text)} placeholder={field.placeholder} />;\n case FILTER_FIELD_KIND.select:\n return (\n <SelectInput label={field.label} value={values[key] || ANY_OPTION} onChange={(chosen) => setValue(key, chosen === ANY_OPTION ? '' : chosen)}\n options={[{value: ANY_OPTION, label: t('filterDrawer.any')}, ...field.options]} />\n );\n case FILTER_FIELD_KIND.multiSelect:\n return <SelectInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options} multiple selectAll checkboxes />;\n case FILTER_FIELD_KIND.catalog:\n return (\n <CatalogInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options}\n multiple={field.multiple} selectAll={field.multiple} checkboxes={field.multiple} formatLabel={field.formatLabel}\n placeholder={field.placeholder} />\n );\n case FILTER_FIELD_KIND.checkboxes:\n return <CheckboxGroupInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options} selectAll={field.selectAll} />;\n case FILTER_FIELD_KIND.numberRange: {\n const [fromKey, toKey] = filterKeysOf(field);\n const numberProps = {decimals: field.decimals ?? 0, prefix: field.prefix, suffix: field.suffix, helperText: ''};\n return (\n <PairedField label={field.label} inputId={`${fieldId}-from`}>\n <NumberInput label={t('filterDrawer.from')} value={values[fromKey]} onChange={(number) => setValue(fromKey, number)} {...numberProps} />\n <NumberInput label={t('filterDrawer.to')} value={values[toKey]} onChange={(number) => setValue(toKey, number)} {...numberProps}\n error={invalidRanges[toKey] ? t('filterDrawer.rangeBackwards') : undefined} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.dateRange: {\n const [fromKey, toKey] = filterKeysOf(field);\n // el calendario del navegador (como DateRangeFilter): viaja AAAA-MM-DD, sin pedir MUI X\n return (\n <PairedField label={field.label} inputId={`${fieldId}-from`}>\n <TextInput type=\"date\" label={t('filterDrawer.from')} value={values[fromKey]} onChange={(date) => setValue(fromKey, date)} clearable={false} helperText=\"\" />\n <TextInput type=\"date\" label={t('filterDrawer.to')} value={values[toKey]} onChange={(date) => setValue(toKey, date)} clearable={false}\n error={invalidRanges[toKey] ? t('filterDrawer.rangeBackwards') : undefined} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.comparison: {\n const parts = comparisonOf(values[key]);\n const operators = field.operators ?? Object.values(COMPARISON_OPERATOR);\n const operator = parts?.operator ?? field.defaultOperator ?? operators[0];\n return (\n <PairedField label={field.label} inputId={`${fieldId}-value`} template=\"minmax(0, 1fr) minmax(0, 1.2fr)\">\n <SelectInput label={t('filterDrawer.operator')} value={operator} helperText=\"\"\n options={operators.map((option) => ({value: option, label: t(`filterDrawer.operators.${option}`)}))}\n onChange={(chosen) => setValue(key, comparisonTextOf(chosen, parts?.value ?? ''))} />\n <NumberInput label={t('filterDrawer.value')} value={parts?.value ?? ''} decimals={field.decimals ?? 2} prefix={field.prefix} suffix={field.suffix}\n helperText=\"\" onChange={(number) => setValue(key, comparisonTextOf(operator, number))} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.custom:\n return field.render({value: values[key], onChange: (next) => setValue(key, next), values, setValue});\n default:\n return null;\n }\n}\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {object[]} props.fields los campos (filterDrawerFields.js): {name, label, kind, options?, keys?, prefix?, suffix?, decimals?, operators?, render?…}\n * @param {Record<string, unknown>} props.values los filtros puestos hoy (de ahí sale el borrador al abrir)\n * @param {(values: Record<string, unknown>) => void} props.onApply todos los campos del cajón juntos, al picar «Buscar»\n * @param {'left'|'right'} [props.anchor] de qué lado sale (FILTER_DRAWER_ANCHOR); por omisión la derecha\n * @param {number} [props.width] su ancho en escritorio, en px\n * @param {string} [props.title] ya traducido; por omisión «Filtros»\n * @param {string} [props.applyLabel] ya traducido; por omisión «Buscar»\n * @param {boolean} [props.closeOnApply] por omisión sí\n * @param {import('react').ReactNode} [props.children] algo más abajo de los campos (una nota, un enlace)\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function FilterDrawer(props) {\n const {\n open, onClose, fields, values, onApply, anchor = FILTER_DRAWER_ANCHOR.right, width = DEFAULT_WIDTH, title, applyLabel,\n closeOnApply = true, children, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const titleId = useId();\n const [draft, setDraft] = useState(() => drawerValuesOf(fields, values));\n // cada vez que se abre, el borrador empieza de lo que hay puesto (lo de la vez pasada sin buscar no se queda)\n useEffect(() => {\n if (open) {\n setDraft(drawerValuesOf(fields, values));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n const invalidRanges = invalidRangesOf(fields, draft);\n const hasInvalidRange = Object.keys(invalidRanges).length > 0;\n const setValue = (key, value) => setDraft((current) => ({...current, [key]: value}));\n const apply = () => {\n onApply(draft);\n if (closeOnApply) {\n onClose();\n }\n };\n\n return (\n <Drawer\n anchor={anchor}\n open={open}\n onClose={onClose}\n slotProps={{paper: {'aria-labelledby': titleId, className: `${THEME_NAME}-paper`, sx: {width: {xs: '100%', sm: width}, maxWidth: '100%'}}}}\n >\n <Box component=\"form\" noValidate sx={{display: 'flex', flexDirection: 'column', height: '100%'}}\n onSubmit={(event) => {\n event.preventDefault();\n if (!hasInvalidRange) {\n apply();\n }\n }}>\n <FilterDrawerHeader direction=\"row\" ownSx={{alignItems: 'center', gap: 1, px: 2, py: 1.5, borderBottom: 1, borderColor: 'divider'}}>\n <IconButton aria-label={t('filterDrawer.close')} onClick={onClose} edge=\"start\"><CloseRoundedIcon /></IconButton>\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{flexGrow: 1}}>{title ?? t('filterDrawer.title')}</Typography>\n </FilterDrawerHeader>\n <FilterDrawerBody spacing={1} ownSx={{flex: 1, overflowY: 'auto', px: 2.5, py: 2}}>\n {fields.map((field) => (\n <DrawerField key={field.name} field={field} values={draft} setValue={setValue} invalidRanges={invalidRanges} t={t} />\n ))}\n {children}\n </FilterDrawerBody>\n <FilterDrawerFooter direction=\"row\" ownSx={{gap: 1, justifyContent: 'flex-end', px: 2.5, py: 1.5, borderTop: 1, borderColor: 'divider'}}>\n <Button onClick={() => setDraft(emptyDrawerValuesOf(fields))}>{t('filterDrawer.clear')}</Button>\n <Button type=\"submit\" variant=\"contained\" disabled={hasInvalidRange}>{applyLabel ?? t('filterDrawer.apply')}</Button>\n </FilterDrawerFooter>\n </Box>\n </Drawer>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FilterDrawer.js","sources":["../../../src/ui/filters/FilterDrawer.jsx"],"sourcesContent":["// El cajón de búsqueda: un panel que sale de un lado con los campos que filtran una lista (las listas, un rango\n// «desde-hasta», unas fechas, un monto con su operador), para cuando los filtros ya no caben arriba de la tabla.\n//\n// Lo que se cambia adentro es un BORRADOR: la lista no se mueve hasta «Buscar» (no se consulta al servidor con cada tecla).\n// «Limpiar» vacía los campos del cajón; «Buscar» manda todos juntos (onApply) y cierra. Un rango al revés («hasta» menor que\n// «desde») se dice en su campo y no deja buscar.\n//\n// Los campos se declaran (filterDrawerFields.js dice cómo viaja cada uno); con kind 'custom' va uno propio (render). Para\n// conectarlo a ServerTable con su botón y sus chips: ServerTableFilterDrawer de /table.\n//\n// Configurable: de qué lado sale (anchor), su ancho, su título y los textos de sus botones. En el teléfono ocupa todo el\n// ancho.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaFilterDrawer con defaultProps y\n// styleOverrides de sus partes: paper, header, body, footer.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useId, useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Drawer from '@mui/material/Drawer';\nimport IconButton from '@mui/material/IconButton';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport CloseRoundedIcon from '@mui/icons-material/CloseRounded';\n\nimport CatalogInput from '@/inputs/CatalogInput.jsx';\nimport CheckboxGroupInput from '@/inputs/CheckboxGroupInput.jsx';\nimport FieldFrame from '@/inputs/FieldFrame.jsx';\nimport NumberInput from '@/inputs/NumberInput.jsx';\nimport SelectInput from '@/inputs/SelectInput.jsx';\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {\n COMPARISON_OPERATOR, FILTER_FIELD_KIND, comparisonOf, comparisonTextOf, drawerValuesOf, emptyDrawerValuesOf, filterKeysOf,\n invalidRangesOf,\n} from '@/ui/filters/filterDrawerFields.js';\n\n/** De qué lado sale el cajón. */\nexport const FILTER_DRAWER_ANCHOR = Object.freeze({left: 'left', right: 'right'});\nconst DEFAULT_WIDTH = 380;\n// «Cualquiera» de una lista de una sola opción: no es una opción y viaja como '' (sin filtro)\nconst ANY_OPTION = '__calcita_any__';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaFilterDrawer)\nconst THEME_NAME = 'CalcitaFilterDrawer';\nconst FilterDrawerHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst FilterDrawerBody = piecePart(THEME_NAME, 'Body', Stack);\nconst FilterDrawerFooter = piecePart(THEME_NAME, 'Footer', Stack);\n\n/**\n * Dos campos lado a lado (desde y hasta, operador y número); en un cajón angosto se ven bien juntos.\n *\n * @param {{label: import('react').ReactNode, inputId: string, children: import('react').ReactNode, template?: string}} props\n */\nfunction PairedField({label, inputId, children, template = '1fr 1fr'}) {\n return (\n <FieldFrame inputId={inputId} label={label}>\n <Box sx={{display: 'grid', gridTemplateColumns: template, gap: 1.5, alignItems: 'start'}}>{children}</Box>\n </FieldFrame>\n );\n}\n\n/**\n * Un campo del cajón según su tipo, con las piezas de la casa.\n *\n * @param {object} props\n */\nfunction DrawerField({field, values, setValue, invalidRanges, t}) {\n const fieldId = useId();\n const [key] = filterKeysOf(field);\n switch (field.kind) {\n case FILTER_FIELD_KIND.text:\n return <TextInput label={field.label} value={values[key]} onChange={(text) => setValue(key, text)} placeholder={field.placeholder} />;\n case FILTER_FIELD_KIND.select:\n return (\n <SelectInput label={field.label} value={values[key] || ANY_OPTION} onChange={(chosen) => setValue(key, chosen === ANY_OPTION ? '' : chosen)}\n options={[{value: ANY_OPTION, label: t('filterDrawer.any')}, ...field.options]} />\n );\n case FILTER_FIELD_KIND.multiSelect:\n return <SelectInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options} multiple selectAll checkboxes />;\n case FILTER_FIELD_KIND.catalog:\n return (\n <CatalogInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options}\n multiple={field.multiple} selectAll={field.multiple} checkboxes={field.multiple} formatLabel={field.formatLabel}\n placeholder={field.placeholder} />\n );\n case FILTER_FIELD_KIND.checkboxes:\n return <CheckboxGroupInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options} selectAll={field.selectAll} />;\n case FILTER_FIELD_KIND.numberRange: {\n const [fromKey, toKey] = filterKeysOf(field);\n const numberProps = {decimals: field.decimals ?? 0, prefix: field.prefix, suffix: field.suffix, helperText: ''};\n return (\n <PairedField label={field.label} inputId={`${fieldId}-from`}>\n <NumberInput label={t('filterDrawer.from')} value={values[fromKey]} onChange={(number) => setValue(fromKey, number)} {...numberProps} />\n <NumberInput label={t('filterDrawer.to')} value={values[toKey]} onChange={(number) => setValue(toKey, number)} {...numberProps}\n error={invalidRanges[toKey] ? t('filterDrawer.rangeBackwards') : undefined} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.dateRange: {\n const [fromKey, toKey] = filterKeysOf(field);\n // el calendario del navegador (como DateRangeFilter): viaja AAAA-MM-DD, sin pedir MUI X\n return (\n <PairedField label={field.label} inputId={`${fieldId}-from`}>\n <TextInput type=\"date\" label={t('filterDrawer.from')} value={values[fromKey]} onChange={(date) => setValue(fromKey, date)} clearable={false} helperText=\"\" />\n <TextInput type=\"date\" label={t('filterDrawer.to')} value={values[toKey]} onChange={(date) => setValue(toKey, date)} clearable={false}\n error={invalidRanges[toKey] ? t('filterDrawer.rangeBackwards') : undefined} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.comparison: {\n const parts = comparisonOf(values[key]);\n const operators = field.operators ?? Object.values(COMPARISON_OPERATOR);\n const operator = parts?.operator ?? field.defaultOperator ?? operators[0];\n return (\n <PairedField label={field.label} inputId={`${fieldId}-value`} template=\"minmax(0, 1fr) minmax(0, 1.2fr)\">\n <SelectInput label={t('filterDrawer.operator')} value={operator} helperText=\"\"\n options={operators.map((option) => ({value: option, label: t(`filterDrawer.operators.${option}`)}))}\n onChange={(chosen) => setValue(key, comparisonTextOf(chosen, parts?.value ?? ''))} />\n <NumberInput label={t('filterDrawer.value')} value={parts?.value ?? ''} decimals={field.decimals ?? 2} prefix={field.prefix} suffix={field.suffix}\n helperText=\"\" onChange={(number) => setValue(key, comparisonTextOf(operator, number))} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.custom:\n return field.render({value: values[key], onChange: (next) => setValue(key, next), values, setValue});\n default:\n return null;\n }\n}\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {object[]} props.fields los campos (filterDrawerFields.js): {name, label, kind, options?, keys?, prefix?, suffix?, decimals?, operators?, render?…}\n * @param {Record<string, unknown>} props.values los filtros puestos hoy (de ahí sale el borrador al abrir)\n * @param {(values: Record<string, unknown>) => void} props.onApply todos los campos del cajón juntos, al picar «Buscar»\n * @param {'left'|'right'} [props.anchor] de qué lado sale (FILTER_DRAWER_ANCHOR); por omisión la derecha\n * @param {number} [props.width] su ancho en escritorio, en px\n * @param {string} [props.title] ya traducido; por omisión «Filtros»\n * @param {string} [props.applyLabel] ya traducido; por omisión «Buscar»\n * @param {boolean} [props.closeOnApply] por omisión sí\n * @param {import('react').ReactNode} [props.children] algo más abajo de los campos (una nota, un enlace)\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction FilterDrawerContent(props) {\n const {\n open, onClose, fields, values, onApply, anchor = FILTER_DRAWER_ANCHOR.right, width = DEFAULT_WIDTH, title, applyLabel,\n closeOnApply = true, children, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const titleId = useId();\n const [draft, setDraft] = useState(() => drawerValuesOf(fields, values));\n // cada vez que se abre, el borrador empieza de lo que hay puesto (lo de la vez pasada sin buscar no se queda)\n useEffect(() => {\n if (open) {\n setDraft(drawerValuesOf(fields, values));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n const invalidRanges = invalidRangesOf(fields, draft);\n const hasInvalidRange = Object.keys(invalidRanges).length > 0;\n const setValue = (key, value) => setDraft((current) => ({...current, [key]: value}));\n const apply = () => {\n onApply(draft);\n if (closeOnApply) {\n onClose();\n }\n };\n\n return (\n <Drawer\n anchor={anchor}\n open={open}\n onClose={onClose}\n slotProps={{paper: {'aria-labelledby': titleId, className: `${THEME_NAME}-paper`, sx: {width: {xs: '100%', sm: width}, maxWidth: '100%'}}}}\n >\n <Box component=\"form\" noValidate sx={{display: 'flex', flexDirection: 'column', height: '100%'}}\n onSubmit={(event) => {\n event.preventDefault();\n if (!hasInvalidRange) {\n apply();\n }\n }}>\n <FilterDrawerHeader direction=\"row\" ownSx={{alignItems: 'center', gap: 1, px: 2, py: 1.5, borderBottom: 1, borderColor: 'divider'}}>\n <IconButton aria-label={t('filterDrawer.close')} onClick={onClose} edge=\"start\"><CloseRoundedIcon /></IconButton>\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{flexGrow: 1}}>{title ?? t('filterDrawer.title')}</Typography>\n </FilterDrawerHeader>\n <FilterDrawerBody spacing={1} ownSx={{flex: 1, overflowY: 'auto', px: 2.5, py: 2}}>\n {fields.map((field) => (\n <DrawerField key={field.name} field={field} values={draft} setValue={setValue} invalidRanges={invalidRanges} t={t} />\n ))}\n {children}\n </FilterDrawerBody>\n <FilterDrawerFooter direction=\"row\" ownSx={{gap: 1, justifyContent: 'flex-end', px: 2.5, py: 1.5, borderTop: 1, borderColor: 'divider'}}>\n <Button onClick={() => setDraft(emptyDrawerValuesOf(fields))}>{t('filterDrawer.clear')}</Button>\n <Button type=\"submit\" variant=\"contained\" disabled={hasInvalidRange}>{applyLabel ?? t('filterDrawer.apply')}</Button>\n </FilterDrawerFooter>\n </Box>\n </Drawer>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst FilterDrawer = withPieceSlots(FilterDrawerContent, THEME_NAME);\nexport default FilterDrawer;\n"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import MenuItem from "@mui/material/MenuItem";
7
7
  import Select from "@mui/material/Select";
8
8
  import Stack from "@mui/material/Stack";
9
9
  import { rangeEndOptionsOf, rangeEndAfterStartChange } from "../../periodRanges.js";
10
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
10
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
11
11
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
12
12
  const THEME_NAME = "CalcitaPeriodRangeSelector";
13
13
  const PeriodField = piecePart(THEME_NAME, "Field", FormControl);
@@ -31,7 +31,7 @@ function PeriodSelect({ id, label, value, options, onChange }) {
31
31
  )
32
32
  ] });
33
33
  }
34
- function PeriodRangeSelector(props) {
34
+ function PeriodRangeSelectorContent(props) {
35
35
  const { id, options, from, to, fromLabel, toLabel, onChange, ...unknownProps } = usePieceProps(props, THEME_NAME);
36
36
  warnUnknownProps(THEME_NAME, unknownProps);
37
37
  const endOptions = rangeEndOptionsOf(options, from);
@@ -58,6 +58,7 @@ function PeriodRangeSelector(props) {
58
58
  )
59
59
  ] });
60
60
  }
61
+ const PeriodRangeSelector = withPieceSlots(PeriodRangeSelectorContent, THEME_NAME);
61
62
  export {
62
63
  PeriodRangeSelector as default
63
64
  };
@@ -1 +1 @@
1
- {"version":3,"file":"PeriodRangeSelector.js","sources":["../../../src/ui/filters/PeriodRangeSelector.jsx"],"sourcesContent":["// Un rango de periodos: «desde» y «hasta», cada uno una lista para elegir (de tal quincena a tal quincena, de tal mes a\n// tal mes). Se usa en lugar de un calendario porque los periodos no son días: solo se ofrecen los que existen, y los que no\n// se pueden elegir salen apagados con su razón.\n//\n// «Hasta» solo ofrece lo que hace un rango válido con «desde»: nada de antes y nada que salte un periodo apagado\n// (periodRanges.js). Al cambiar «desde», si el «hasta» que había ya no vale, se iguala a «desde».\n//\n// No sabe de quincenas ni de productos: recibe las opciones ya ordenadas y con sus textos traducidos.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPeriodRangeSelector con defaultProps y\n// styleOverrides de sus partes: field, select, root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport FormControl from '@mui/material/FormControl';\nimport InputLabel from '@mui/material/InputLabel';\nimport ListItemText from '@mui/material/ListItemText';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport Stack from '@mui/material/Stack';\n\nimport {rangeEndAfterStartChange, rangeEndOptionsOf} from '@/periodRanges.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.CalcitaPeriodRangeSelector)\nconst THEME_NAME = 'CalcitaPeriodRangeSelector';\nconst PeriodField = piecePart(THEME_NAME, 'Field', FormControl);\nconst PeriodSelectPart = piecePart(THEME_NAME, 'Select', Select);\nconst PeriodRoot = piecePart(THEME_NAME, 'Root', Stack);\n\n// ancho de cada lista: cabe «septiembre 2026 · Q2» sin cortarse\nconst SELECT_MINIMUM_WIDTH = 210;\n\n/**\n * Una lista del rango.\n *\n * @param {object} props\n * @param {string} props.id\n * @param {string} props.label\n * @param {string} props.value\n * @param {(value: string) => void} props.onChange\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options\n */\nfunction PeriodSelect({id, label, value, options, onChange}) {\n return (\n <PeriodField size=\"small\" ownSx={{minWidth: SELECT_MINIMUM_WIDTH, flex: '0 0 auto'}}>\n <InputLabel id={`${id}-label`}>{label}</InputLabel>\n <PeriodSelectPart labelId={`${id}-label`} label={label} value={value ?? ''} onChange={(event) => onChange(event.target.value)}\n ownSx={{bgcolor: 'background.paper'}}\n renderValue={(selectedValue) => options.find((option) => option.value === selectedValue)?.label ?? ''}>\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value} disabled={option.disabled}>\n {/* la razón de una opción apagada va debajo de su nombre: «sin validar» se lee sin tooltip */}\n <ListItemText primary={option.label} secondary={option.disabled ? option.hint : undefined} />\n </MenuItem>\n ))}\n </PeriodSelectPart>\n </PeriodField>\n );\n}\n\n/**\n * @param {object} props\n * @param {string} props.id prefijo de los id de las dos listas (accesibilidad)\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options en orden; ya\n * traducidas\n * @param {string|null} props.from\n * @param {string|null} props.to\n * @param {string} props.fromLabel ya traducido\n * @param {string} props.toLabel ya traducido\n * @param {(range: {from: string, to: string}) => void} props.onChange\n */\nexport default function PeriodRangeSelector(props) {\n // lo que el proyecto puso en su tema (components.CalcitaPeriodRangeSelector.defaultProps) y encima lo que llega aquí\n const {id, options, from, to, fromLabel, toLabel, onChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const endOptions = rangeEndOptionsOf(options, from);\n\n return (\n <PeriodRoot direction=\"row\" spacing={1.5} useFlexGap ownSx={{alignItems: 'center', flexWrap: 'wrap'}}>\n <PeriodSelect id={`${id}-from`} label={fromLabel} value={from} options={options}\n onChange={(nextFrom) => onChange({from: nextFrom, to: rangeEndAfterStartChange(options, nextFrom, to)})} />\n <PeriodSelect id={`${id}-to`} label={toLabel} value={to} options={endOptions}\n onChange={(nextTo) => onChange({from, to: nextTo})} />\n </PeriodRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,SAAS,WAAW;AAC9D,MAAM,mBAAmB,UAAU,YAAY,UAAU,MAAM;AAC/D,MAAM,aAAa,UAAU,YAAY,QAAQ,KAAK;AAGtD,MAAM,uBAAuB;AAY7B,SAAS,aAAa,EAAC,IAAI,OAAO,OAAO,SAAS,YAAW;AACzD,SACI,qBAAC,aAAA,EAAY,MAAK,SAAQ,OAAO,EAAC,UAAU,sBAAsB,MAAM,WAAA,GACpE,UAAA;AAAA,IAAA,oBAAC,YAAA,EAAW,IAAI,GAAG,EAAE,UAAW,UAAA,OAAM;AAAA,IACtC;AAAA,MAAC;AAAA,MAAA;AAAA,QAAiB,SAAS,GAAG,EAAE;AAAA,QAAU;AAAA,QAAc,OAAO,SAAS;AAAA,QAAI,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,QACpH,OAAO,EAAC,SAAS,mBAAA;AAAA,QACjB,aAAa,CAAC,kBAAkB,QAAQ,KAAK,CAAC,WAAW,OAAO,UAAU,aAAa,GAAG,SAAS;AAAA,QACtG,UAAA,QAAQ,IAAI,CAAC,WACV,oBAAC,UAAA,EAA4B,OAAO,OAAO,OAAO,UAAU,OAAO,UAE/D,UAAA,oBAAC,gBAAa,SAAS,OAAO,OAAO,WAAW,OAAO,WAAW,OAAO,OAAO,OAAA,CAAW,EAAA,GAFhF,OAAO,KAGtB,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACL,GACJ;AAER;AAaA,SAAwB,oBAAoB,OAAO;AAE/C,QAAM,EAAC,IAAI,SAAS,MAAM,IAAI,WAAW,SAAS,UAAU,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC9G,mBAAiB,YAAY,YAAY;AACzC,QAAM,aAAa,kBAAkB,SAAS,IAAI;AAElD,SACI,qBAAC,YAAA,EAAW,WAAU,OAAM,SAAS,KAAK,YAAU,MAAC,OAAO,EAAC,YAAY,UAAU,UAAU,UACzF,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,IAAI,GAAG,EAAE;AAAA,QAAS,OAAO;AAAA,QAAW,OAAO;AAAA,QAAM;AAAA,QACjD,UAAU,CAAC,aAAa,SAAS,EAAC,MAAM,UAAU,IAAI,yBAAyB,SAAS,UAAU,EAAE,GAAE;AAAA,MAAA;AAAA,IAAA;AAAA,IACpH;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,IAAI,GAAG,EAAE;AAAA,QAAO,OAAO;AAAA,QAAS,OAAO;AAAA,QAAI,SAAS;AAAA,QACpD,UAAU,CAAC,WAAW,SAAS,EAAC,MAAM,IAAI,QAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EAAG,GACtE;AAER;"}
1
+ {"version":3,"file":"PeriodRangeSelector.js","sources":["../../../src/ui/filters/PeriodRangeSelector.jsx"],"sourcesContent":["// Un rango de periodos: «desde» y «hasta», cada uno una lista para elegir (de tal quincena a tal quincena, de tal mes a\n// tal mes). Se usa en lugar de un calendario porque los periodos no son días: solo se ofrecen los que existen, y los que no\n// se pueden elegir salen apagados con su razón.\n//\n// «Hasta» solo ofrece lo que hace un rango válido con «desde»: nada de antes y nada que salte un periodo apagado\n// (periodRanges.js). Al cambiar «desde», si el «hasta» que había ya no vale, se iguala a «desde».\n//\n// No sabe de quincenas ni de productos: recibe las opciones ya ordenadas y con sus textos traducidos.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPeriodRangeSelector con defaultProps y\n// styleOverrides de sus partes: field, select, root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport FormControl from '@mui/material/FormControl';\nimport InputLabel from '@mui/material/InputLabel';\nimport ListItemText from '@mui/material/ListItemText';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport Stack from '@mui/material/Stack';\n\nimport {rangeEndAfterStartChange, rangeEndOptionsOf} from '@/periodRanges.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.CalcitaPeriodRangeSelector)\nconst THEME_NAME = 'CalcitaPeriodRangeSelector';\nconst PeriodField = piecePart(THEME_NAME, 'Field', FormControl);\nconst PeriodSelectPart = piecePart(THEME_NAME, 'Select', Select);\nconst PeriodRoot = piecePart(THEME_NAME, 'Root', Stack);\n\n// ancho de cada lista: cabe «septiembre 2026 · Q2» sin cortarse\nconst SELECT_MINIMUM_WIDTH = 210;\n\n/**\n * Una lista del rango.\n *\n * @param {object} props\n * @param {string} props.id\n * @param {string} props.label\n * @param {string} props.value\n * @param {(value: string) => void} props.onChange\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options\n */\nfunction PeriodSelect({id, label, value, options, onChange}) {\n return (\n <PeriodField size=\"small\" ownSx={{minWidth: SELECT_MINIMUM_WIDTH, flex: '0 0 auto'}}>\n <InputLabel id={`${id}-label`}>{label}</InputLabel>\n <PeriodSelectPart labelId={`${id}-label`} label={label} value={value ?? ''} onChange={(event) => onChange(event.target.value)}\n ownSx={{bgcolor: 'background.paper'}}\n renderValue={(selectedValue) => options.find((option) => option.value === selectedValue)?.label ?? ''}>\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value} disabled={option.disabled}>\n {/* la razón de una opción apagada va debajo de su nombre: «sin validar» se lee sin tooltip */}\n <ListItemText primary={option.label} secondary={option.disabled ? option.hint : undefined} />\n </MenuItem>\n ))}\n </PeriodSelectPart>\n </PeriodField>\n );\n}\n\n/**\n * @param {object} props\n * @param {string} props.id prefijo de los id de las dos listas (accesibilidad)\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options en orden; ya\n * traducidas\n * @param {string|null} props.from\n * @param {string|null} props.to\n * @param {string} props.fromLabel ya traducido\n * @param {string} props.toLabel ya traducido\n * @param {(range: {from: string, to: string}) => void} props.onChange\n */\nfunction PeriodRangeSelectorContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaPeriodRangeSelector.defaultProps) y encima lo que llega aquí\n const {id, options, from, to, fromLabel, toLabel, onChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const endOptions = rangeEndOptionsOf(options, from);\n\n return (\n <PeriodRoot direction=\"row\" spacing={1.5} useFlexGap ownSx={{alignItems: 'center', flexWrap: 'wrap'}}>\n <PeriodSelect id={`${id}-from`} label={fromLabel} value={from} options={options}\n onChange={(nextFrom) => onChange({from: nextFrom, to: rangeEndAfterStartChange(options, nextFrom, to)})} />\n <PeriodSelect id={`${id}-to`} label={toLabel} value={to} options={endOptions}\n onChange={(nextTo) => onChange({from, to: nextTo})} />\n </PeriodRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst PeriodRangeSelector = withPieceSlots(PeriodRangeSelectorContent, THEME_NAME);\nexport default PeriodRangeSelector;\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,SAAS,WAAW;AAC9D,MAAM,mBAAmB,UAAU,YAAY,UAAU,MAAM;AAC/D,MAAM,aAAa,UAAU,YAAY,QAAQ,KAAK;AAGtD,MAAM,uBAAuB;AAY7B,SAAS,aAAa,EAAC,IAAI,OAAO,OAAO,SAAS,YAAW;AACzD,SACI,qBAAC,aAAA,EAAY,MAAK,SAAQ,OAAO,EAAC,UAAU,sBAAsB,MAAM,WAAA,GACpE,UAAA;AAAA,IAAA,oBAAC,YAAA,EAAW,IAAI,GAAG,EAAE,UAAW,UAAA,OAAM;AAAA,IACtC;AAAA,MAAC;AAAA,MAAA;AAAA,QAAiB,SAAS,GAAG,EAAE;AAAA,QAAU;AAAA,QAAc,OAAO,SAAS;AAAA,QAAI,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,QACpH,OAAO,EAAC,SAAS,mBAAA;AAAA,QACjB,aAAa,CAAC,kBAAkB,QAAQ,KAAK,CAAC,WAAW,OAAO,UAAU,aAAa,GAAG,SAAS;AAAA,QACtG,UAAA,QAAQ,IAAI,CAAC,WACV,oBAAC,UAAA,EAA4B,OAAO,OAAO,OAAO,UAAU,OAAO,UAE/D,UAAA,oBAAC,gBAAa,SAAS,OAAO,OAAO,WAAW,OAAO,WAAW,OAAO,OAAO,OAAA,CAAW,EAAA,GAFhF,OAAO,KAGtB,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACL,GACJ;AAER;AAaA,SAAS,2BAA2B,OAAO;AAEvC,QAAM,EAAC,IAAI,SAAS,MAAM,IAAI,WAAW,SAAS,UAAU,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC9G,mBAAiB,YAAY,YAAY;AACzC,QAAM,aAAa,kBAAkB,SAAS,IAAI;AAElD,SACI,qBAAC,YAAA,EAAW,WAAU,OAAM,SAAS,KAAK,YAAU,MAAC,OAAO,EAAC,YAAY,UAAU,UAAU,UACzF,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,IAAI,GAAG,EAAE;AAAA,QAAS,OAAO;AAAA,QAAW,OAAO;AAAA,QAAM;AAAA,QACjD,UAAU,CAAC,aAAa,SAAS,EAAC,MAAM,UAAU,IAAI,yBAAyB,SAAS,UAAU,EAAE,GAAE;AAAA,MAAA;AAAA,IAAA;AAAA,IACpH;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,IAAI,GAAG,EAAE;AAAA,QAAO,OAAO;AAAA,QAAS,OAAO;AAAA,QAAI,SAAS;AAAA,QACpD,UAAU,CAAC,WAAW,SAAS,EAAC,MAAM,IAAI,QAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EAAG,GACtE;AAER;AAGA,MAAM,sBAAsB,eAAe,4BAA4B,UAAU;"}
@@ -7,7 +7,7 @@ import { alpha } from "@mui/material/styles";
7
7
  import Chip from "@mui/material/Chip";
8
8
  import Typography from "@mui/material/Typography";
9
9
  import ScrollableRow from "../layout/ScrollableRow.js";
10
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
10
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
11
11
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
12
12
  const THEME_NAME = "CalcitaQuickFilters";
13
13
  const QuickRoot = piecePart(THEME_NAME, "Root", Box);
@@ -32,7 +32,7 @@ function compactCount(count) {
32
32
  }
33
33
  return String(count);
34
34
  }
35
- function QuickFilters(props) {
35
+ function QuickFiltersContent(props) {
36
36
  const { value, onChange, options = [], caption, ariaLabel, extra, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
37
37
  warnUnknownProps(THEME_NAME, unknownProps);
38
38
  const { t } = useToolkitTranslation("table", texts);
@@ -95,6 +95,7 @@ function QuickFilters(props) {
95
95
  ] })
96
96
  ] });
97
97
  }
98
+ const QuickFilters = withPieceSlots(QuickFiltersContent, THEME_NAME);
98
99
  export {
99
100
  QuickFilters as default
100
101
  };
@@ -1 +1 @@
1
- {"version":3,"file":"QuickFilters.js","sources":["../../../src/ui/filters/QuickFilters.jsx"],"sourcesContent":["// Accesos rápidos: una tira de chips donde se elige UNO (p. ej. el estatus de un pedido).\n//\n// Es el complemento de FilterChips, no lo mismo:\n// - FilterChips dice qué filtros están PUESTOS y sirve para quitarlos;\n// - esto dice qué opciones HAY y sirve para saltar entre ellas de un toque.\n//\n// El conteo de cada chip sale de las facetas del servidor, contadas sobre el conjunto COMPLETO y sin este filtro\n// puesto: al elegir una, las demás siguen diciendo cuántas tienen.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaQuickFilters con defaultProps y\n// styleOverrides de sus partes: root, caption, chip, chipLabel, chipCount.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport {alpha} from '@mui/material/styles';\nimport Chip from '@mui/material/Chip';\nimport Typography from '@mui/material/Typography';\n\nimport ScrollableRow from '@/ui/layout/ScrollableRow.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.CalcitaQuickFilters)\nconst THEME_NAME = 'CalcitaQuickFilters';\nconst QuickRoot = piecePart(THEME_NAME, 'Root', Box);\nconst QuickCaption = piecePart(THEME_NAME, 'Caption', Typography);\nconst QuickChip = piecePart(THEME_NAME, 'Chip', Chip);\nconst QuickChipLabel = piecePart(THEME_NAME, 'ChipLabel', Box);\nconst QuickChipCount = piecePart(THEME_NAME, 'ChipCount', Box);\n\n\n// qué tan marcado va el velo del contador del filtro elegido\nconst ACTIVE_COUNT_VEIL_OPACITY = 0.18;\n\n/**\n * El velo del contador del filtro elegido: el color del texto base (negro en claro, blanco en oscuro) casi transparente.\n * Un tema con variables CSS trae ese color en theme.vars; el tema por omisión de MUI, en su modo.\n *\n * @param {object} theme tema de MUI\n * @returns {string} color CSS\n */\nfunction activeCountVeilOf(theme) {\n if (theme.vars) {\n return `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${ACTIVE_COUNT_VEIL_OPACITY})`;\n }\n const baseTextColor = theme.palette.mode === 'dark' ? theme.palette.common.white : theme.palette.common.black;\n\n return alpha(baseTextColor, ACTIVE_COUNT_VEIL_OPACITY);\n}\n\n/** \"99+\" arriba de 99 y \"1.2k\" arriba de 999: el chip no se estira. */\nfunction compactCount(count) {\n if (count > 999) {\n return `${(count / 1000).toFixed(1)}k`;\n }\n if (count > 99) {\n return '99+';\n }\n return String(count);\n}\n\n/**\n * @param {object} props\n * @param {string} props.value opción activa ('' = todas)\n * @param {(value: string) => void} props.onChange\n * @param {Array<{value: string, label: import('react').ReactNode, count?: number}>} [props.options]\n * @param {import('react').ReactNode} [props.caption]\n * @param {string} [props.ariaLabel]\n * @param {import('react').ReactNode} [props.extra] al final de la tira (p. ej. un rango de fechas)\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nexport default function QuickFilters(props) {\n // lo que el proyecto puso en su tema (components.CalcitaQuickFilters.defaultProps) y encima lo que llega aquí\n const {value, onChange, options = [], caption, ariaLabel, extra, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const activeChip = useRef(null);\n const isFirstRender = useRef(true);\n\n // al cambiar la selección desde fuera (alguien limpió los filtros) el chip activo se trae a la vista; en el primer\n // render sin animación: una tira que se mueve sola al abrir la pantalla se siente rota\n useEffect(() => {\n if (!activeChip.current) {\n return;\n }\n const behavior = isFirstRender.current ? 'instant' : 'smooth';\n isFirstRender.current = false;\n activeChip.current.scrollIntoView({behavior, block: 'nearest', inline: 'center'});\n }, [value]);\n\n // guard clause: con una sola opción no hay entre qué saltar\n if (options.length <= 1) {\n return null;\n }\n\n return (\n <QuickRoot ownSx={{mb: 1}}>\n {caption && (\n <QuickCaption variant=\"caption\" color=\"text.secondary\" ownSx={{px: 0.25}}>{caption}</QuickCaption>\n )}\n <ScrollableRow role=\"tablist\" aria-label={ariaLabel}>\n {options.map((option) => {\n const isActive = option.value === value;\n return (\n <QuickChip\n key={option.value || '__all__'}\n ref={isActive ? activeChip : null}\n role=\"tab\"\n aria-selected={isActive}\n clickable\n onClick={() => onChange(isActive ? '' : option.value)}\n // el elegido trae su ×: \"volver a Todas\" no se descubre solo\n onDelete={isActive && option.value ? () => onChange('') : undefined}\n variant={isActive ? 'filled' : 'outlined'}\n color={isActive ? 'primary' : 'default'}\n label={(\n <QuickChipLabel component=\"span\" ownSx={{display: 'inline-flex', alignItems: 'center', gap: 0.75}}>\n <span>{option.label}</span>\n {option.count !== null && option.count !== undefined && (\n <QuickChipCount component=\"span\"\n aria-label={t('quickFilters.countAriaLabel', {count: option.count})}\n // velo del color del texto base (negro en claro, blanco en oscuro) y no rgba fijo\n ownSx={(theme) => ({\n px: 0.75, borderRadius: '6px', fontSize: 11, fontWeight: 700, minWidth: 18,\n textAlign: 'center', color: 'inherit',\n bgcolor: isActive ? activeCountVeilOf(theme) : 'action.selected',\n })}>\n {compactCount(option.count)}\n </QuickChipCount>\n )}\n </QuickChipLabel>\n )}\n ownSx={{flex: '0 0 auto', height: 32}}\n />\n );\n })}\n {extra}\n </ScrollableRow>\n </QuickRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,YAAY,UAAU,YAAY,QAAQ,GAAG;AACnD,MAAM,eAAe,UAAU,YAAY,WAAW,UAAU;AAChE,MAAM,YAAY,UAAU,YAAY,QAAQ,IAAI;AACpD,MAAM,iBAAiB,UAAU,YAAY,aAAa,GAAG;AAC7D,MAAM,iBAAiB,UAAU,YAAY,aAAa,GAAG;AAI7D,MAAM,4BAA4B;AASlC,SAAS,kBAAkB,OAAO;AAC9B,MAAI,MAAM,MAAM;AACZ,WAAO,QAAQ,MAAM,KAAK,QAAQ,OAAO,mBAAmB,MAAM,yBAAyB;AAAA,EAC/F;AACA,QAAM,gBAAgB,MAAM,QAAQ,SAAS,SAAS,MAAM,QAAQ,OAAO,QAAQ,MAAM,QAAQ,OAAO;AAExG,SAAO,MAAM,eAAe,yBAAyB;AACzD;AAGA,SAAS,aAAa,OAAO;AACzB,MAAI,QAAQ,KAAK;AACb,WAAO,IAAI,QAAQ,KAAM,QAAQ,CAAC,CAAC;AAAA,EACvC;AACA,MAAI,QAAQ,IAAI;AACZ,WAAO;AAAA,EACX;AACA,SAAO,OAAO,KAAK;AACvB;AAYA,SAAwB,aAAa,OAAO;AAExC,QAAM,EAAC,OAAO,UAAU,UAAU,CAAA,GAAI,SAAS,WAAW,OAAO,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC1H,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS,KAAK;AAChD,QAAM,aAAa,OAAO,IAAI;AAC9B,QAAM,gBAAgB,OAAO,IAAI;AAIjC,YAAU,MAAM;AACZ,QAAI,CAAC,WAAW,SAAS;AACrB;AAAA,IACJ;AACA,UAAM,WAAW,cAAc,UAAU,YAAY;AACrD,kBAAc,UAAU;AACxB,eAAW,QAAQ,eAAe,EAAC,UAAU,OAAO,WAAW,QAAQ,UAAS;AAAA,EACpF,GAAG,CAAC,KAAK,CAAC;AAGV,MAAI,QAAQ,UAAU,GAAG;AACrB,WAAO;AAAA,EACX;AAEA,8BACK,WAAA,EAAU,OAAO,EAAC,IAAI,KAClB,UAAA;AAAA,IAAA,WACG,oBAAC,cAAA,EAAa,SAAQ,WAAU,OAAM,kBAAiB,OAAO,EAAC,IAAI,KAAA,GAAQ,UAAA,QAAA,CAAQ;AAAA,IAEvF,qBAAC,eAAA,EAAc,MAAK,WAAU,cAAY,WACrC,UAAA;AAAA,MAAA,QAAQ,IAAI,CAAC,WAAW;AACrB,cAAM,WAAW,OAAO,UAAU;AAClC,eACI;AAAA,UAAC;AAAA,UAAA;AAAA,YAEG,KAAK,WAAW,aAAa;AAAA,YAC7B,MAAK;AAAA,YACL,iBAAe;AAAA,YACf,WAAS;AAAA,YACT,SAAS,MAAM,SAAS,WAAW,KAAK,OAAO,KAAK;AAAA,YAEpD,UAAU,YAAY,OAAO,QAAQ,MAAM,SAAS,EAAE,IAAI;AAAA,YAC1D,SAAS,WAAW,WAAW;AAAA,YAC/B,OAAO,WAAW,YAAY;AAAA,YAC9B,OACI,qBAAC,gBAAA,EAAe,WAAU,QAAO,OAAO,EAAC,SAAS,eAAe,YAAY,UAAU,KAAK,QACxF,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAM,iBAAO,MAAA,CAAM;AAAA,cACnB,OAAO,UAAU,QAAQ,OAAO,UAAU,UACvC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAAe,WAAU;AAAA,kBACrB,cAAY,EAAE,+BAA+B,EAAC,OAAO,OAAO,OAAM;AAAA,kBAElE,OAAO,CAAC,WAAW;AAAA,oBACf,IAAI;AAAA,oBAAM,cAAc;AAAA,oBAAO,UAAU;AAAA,oBAAI,YAAY;AAAA,oBAAK,UAAU;AAAA,oBACxE,WAAW;AAAA,oBAAU,OAAO;AAAA,oBAC5B,SAAS,WAAW,kBAAkB,KAAK,IAAI;AAAA,kBAAA;AAAA,kBAEnD,UAAA,aAAa,OAAO,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC9B,GAER;AAAA,YAEJ,OAAO,EAAC,MAAM,YAAY,QAAQ,GAAA;AAAA,UAAE;AAAA,UA3B/B,OAAO,SAAS;AAAA,QAAA;AAAA,MA8BjC,CAAC;AAAA,MACA;AAAA,IAAA,EAAA,CACL;AAAA,EAAA,GACJ;AAER;"}
1
+ {"version":3,"file":"QuickFilters.js","sources":["../../../src/ui/filters/QuickFilters.jsx"],"sourcesContent":["// Accesos rápidos: una tira de chips donde se elige UNO (p. ej. el estatus de un pedido).\n//\n// Es el complemento de FilterChips, no lo mismo:\n// - FilterChips dice qué filtros están PUESTOS y sirve para quitarlos;\n// - esto dice qué opciones HAY y sirve para saltar entre ellas de un toque.\n//\n// El conteo de cada chip sale de las facetas del servidor, contadas sobre el conjunto COMPLETO y sin este filtro\n// puesto: al elegir una, las demás siguen diciendo cuántas tienen.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaQuickFilters con defaultProps y\n// styleOverrides de sus partes: root, caption, chip, chipLabel, chipCount.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport {alpha} from '@mui/material/styles';\nimport Chip from '@mui/material/Chip';\nimport Typography from '@mui/material/Typography';\n\nimport ScrollableRow from '@/ui/layout/ScrollableRow.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.CalcitaQuickFilters)\nconst THEME_NAME = 'CalcitaQuickFilters';\nconst QuickRoot = piecePart(THEME_NAME, 'Root', Box);\nconst QuickCaption = piecePart(THEME_NAME, 'Caption', Typography);\nconst QuickChip = piecePart(THEME_NAME, 'Chip', Chip);\nconst QuickChipLabel = piecePart(THEME_NAME, 'ChipLabel', Box);\nconst QuickChipCount = piecePart(THEME_NAME, 'ChipCount', Box);\n\n\n// qué tan marcado va el velo del contador del filtro elegido\nconst ACTIVE_COUNT_VEIL_OPACITY = 0.18;\n\n/**\n * El velo del contador del filtro elegido: el color del texto base (negro en claro, blanco en oscuro) casi transparente.\n * Un tema con variables CSS trae ese color en theme.vars; el tema por omisión de MUI, en su modo.\n *\n * @param {object} theme tema de MUI\n * @returns {string} color CSS\n */\nfunction activeCountVeilOf(theme) {\n if (theme.vars) {\n return `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${ACTIVE_COUNT_VEIL_OPACITY})`;\n }\n const baseTextColor = theme.palette.mode === 'dark' ? theme.palette.common.white : theme.palette.common.black;\n\n return alpha(baseTextColor, ACTIVE_COUNT_VEIL_OPACITY);\n}\n\n/** \"99+\" arriba de 99 y \"1.2k\" arriba de 999: el chip no se estira. */\nfunction compactCount(count) {\n if (count > 999) {\n return `${(count / 1000).toFixed(1)}k`;\n }\n if (count > 99) {\n return '99+';\n }\n return String(count);\n}\n\n/**\n * @param {object} props\n * @param {string} props.value opción activa ('' = todas)\n * @param {(value: string) => void} props.onChange\n * @param {Array<{value: string, label: import('react').ReactNode, count?: number}>} [props.options]\n * @param {import('react').ReactNode} [props.caption]\n * @param {string} [props.ariaLabel]\n * @param {import('react').ReactNode} [props.extra] al final de la tira (p. ej. un rango de fechas)\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nfunction QuickFiltersContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaQuickFilters.defaultProps) y encima lo que llega aquí\n const {value, onChange, options = [], caption, ariaLabel, extra, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const activeChip = useRef(null);\n const isFirstRender = useRef(true);\n\n // al cambiar la selección desde fuera (alguien limpió los filtros) el chip activo se trae a la vista; en el primer\n // render sin animación: una tira que se mueve sola al abrir la pantalla se siente rota\n useEffect(() => {\n if (!activeChip.current) {\n return;\n }\n const behavior = isFirstRender.current ? 'instant' : 'smooth';\n isFirstRender.current = false;\n activeChip.current.scrollIntoView({behavior, block: 'nearest', inline: 'center'});\n }, [value]);\n\n // guard clause: con una sola opción no hay entre qué saltar\n if (options.length <= 1) {\n return null;\n }\n\n return (\n <QuickRoot ownSx={{mb: 1}}>\n {caption && (\n <QuickCaption variant=\"caption\" color=\"text.secondary\" ownSx={{px: 0.25}}>{caption}</QuickCaption>\n )}\n <ScrollableRow role=\"tablist\" aria-label={ariaLabel}>\n {options.map((option) => {\n const isActive = option.value === value;\n return (\n <QuickChip\n key={option.value || '__all__'}\n ref={isActive ? activeChip : null}\n role=\"tab\"\n aria-selected={isActive}\n clickable\n onClick={() => onChange(isActive ? '' : option.value)}\n // el elegido trae su ×: \"volver a Todas\" no se descubre solo\n onDelete={isActive && option.value ? () => onChange('') : undefined}\n variant={isActive ? 'filled' : 'outlined'}\n color={isActive ? 'primary' : 'default'}\n label={(\n <QuickChipLabel component=\"span\" ownSx={{display: 'inline-flex', alignItems: 'center', gap: 0.75}}>\n <span>{option.label}</span>\n {option.count !== null && option.count !== undefined && (\n <QuickChipCount component=\"span\"\n aria-label={t('quickFilters.countAriaLabel', {count: option.count})}\n // velo del color del texto base (negro en claro, blanco en oscuro) y no rgba fijo\n ownSx={(theme) => ({\n px: 0.75, borderRadius: '6px', fontSize: 11, fontWeight: 700, minWidth: 18,\n textAlign: 'center', color: 'inherit',\n bgcolor: isActive ? activeCountVeilOf(theme) : 'action.selected',\n })}>\n {compactCount(option.count)}\n </QuickChipCount>\n )}\n </QuickChipLabel>\n )}\n ownSx={{flex: '0 0 auto', height: 32}}\n />\n );\n })}\n {extra}\n </ScrollableRow>\n </QuickRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst QuickFilters = withPieceSlots(QuickFiltersContent, THEME_NAME);\nexport default QuickFilters;\n"],"names":[],"mappings":"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"}
@@ -5,12 +5,17 @@ import Tooltip from "@mui/material/Tooltip";
5
5
  import HelpOutlineRoundedIcon from "@mui/icons-material/HelpOutlineRounded";
6
6
  import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
7
7
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
8
- function HelpButton({ onClick, label, size = "medium", sx, texts, ...unknownProps }) {
9
- warnUnknownProps("HelpButton", unknownProps);
8
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
9
+ const THEME_NAME = "CalcitaHelpButton";
10
+ const HelpButtonRoot = piecePart(THEME_NAME, "Root", IconButton);
11
+ function HelpButtonContent(props) {
12
+ const { onClick, label, size = "medium", sx, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
13
+ warnUnknownProps(THEME_NAME, unknownProps);
10
14
  const { t } = useToolkitTranslation("common", texts);
11
15
  const text = label ?? t("help.button");
12
- return /* @__PURE__ */ jsx(Tooltip, { title: text, children: /* @__PURE__ */ jsx(IconButton, { "aria-label": text, onClick, size, sx, children: /* @__PURE__ */ jsx(HelpOutlineRoundedIcon, { fontSize: size === "small" ? "small" : "medium" }) }) });
16
+ return /* @__PURE__ */ jsx(Tooltip, { title: text, children: /* @__PURE__ */ jsx(HelpButtonRoot, { "aria-label": text, onClick, size, sx, children: /* @__PURE__ */ jsx(HelpOutlineRoundedIcon, { fontSize: size === "small" ? "small" : "medium" }) }) });
13
17
  }
18
+ const HelpButton = withPieceSlots(HelpButtonContent, THEME_NAME);
14
19
  export {
15
20
  HelpButton as default
16
21
  };
@@ -1 +1 @@
1
- {"version":3,"file":"HelpButton.js","sources":["../../../src/ui/help/HelpButton.jsx"],"sourcesContent":["// El botón «?» que vuelve a abrir la ayuda de una pantalla (la del carrusel o la que sea): un ícono con su nombre para el\n// lector de pantalla y su globo al pasar el cursor.\n//\n// Genérico del paquete: function (regla de la casa).\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport HelpOutlineRoundedIcon from '@mui/icons-material/HelpOutlineRounded';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/**\n * @param {object} props\n * @param {() => void} props.onClick\n * @param {string} [props.label] ya traducido; por omisión «Ayuda de esta pantalla»\n * @param {'small'|'medium'|'large'} [props.size]\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function HelpButton({onClick, label, size = 'medium', sx, texts, ...unknownProps}) {\n warnUnknownProps('HelpButton', unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const text = label ?? t('help.button');\n return (\n <Tooltip title={text}>\n <IconButton aria-label={text} onClick={onClick} size={size} sx={sx}>\n <HelpOutlineRoundedIcon fontSize={size === 'small' ? 'small' : 'medium'} />\n </IconButton>\n </Tooltip>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAmBA,SAAwB,WAAW,EAAC,SAAS,OAAO,OAAO,UAAU,IAAI,OAAO,GAAG,gBAAe;AAC9F,mBAAiB,cAAc,YAAY;AAC3C,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,OAAO,SAAS,EAAE,aAAa;AACrC,6BACK,SAAA,EAAQ,OAAO,MACZ,UAAA,oBAAC,YAAA,EAAW,cAAY,MAAM,SAAkB,MAAY,IACxD,UAAA,oBAAC,0BAAuB,UAAU,SAAS,UAAU,UAAU,UAAU,GAC7E,EAAA,CACJ;AAER;"}
1
+ {"version":3,"file":"HelpButton.js","sources":["../../../src/ui/help/HelpButton.jsx"],"sourcesContent":["// El botón «?» que vuelve a abrir la ayuda de una pantalla (la del carrusel o la que sea): un ícono con su nombre para el\n// lector de pantalla y su globo al pasar el cursor.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaHelpButton con defaultProps, styleOverrides de\n// sus partes (root) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport HelpOutlineRoundedIcon from '@mui/icons-material/HelpOutlineRounded';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.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.CalcitaHelpButton)\nconst THEME_NAME = 'CalcitaHelpButton';\nconst HelpButtonRoot = piecePart(THEME_NAME, 'Root', IconButton);\n\n/**\n * @param {object} props\n * @param {() => void} props.onClick\n * @param {string} [props.label] ya traducido; por omisión «Ayuda de esta pantalla»\n * @param {'small'|'medium'|'large'} [props.size]\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction HelpButtonContent(props) {\n const {onClick, label, size = 'medium', sx, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const text = label ?? t('help.button');\n return (\n <Tooltip title={text}>\n <HelpButtonRoot aria-label={text} onClick={onClick} size={size} sx={sx}>\n <HelpOutlineRoundedIcon fontSize={size === 'small' ? 'small' : 'medium'} />\n </HelpButtonRoot>\n </Tooltip>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst HelpButton = withPieceSlots(HelpButtonContent, THEME_NAME);\nexport default HelpButton;\n"],"names":[],"mappings":";;;;;;;;AAgBA,MAAM,aAAa;AACnB,MAAM,iBAAiB,UAAU,YAAY,QAAQ,UAAU;AAU/D,SAAS,kBAAkB,OAAO;AAC9B,QAAM,EAAC,SAAS,OAAO,OAAO,UAAU,IAAI,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AACrG,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,OAAO,SAAS,EAAE,aAAa;AACrC,6BACK,SAAA,EAAQ,OAAO,MACZ,UAAA,oBAAC,gBAAA,EAAe,cAAY,MAAM,SAAkB,MAAY,IAC5D,UAAA,oBAAC,0BAAuB,UAAU,SAAS,UAAU,UAAU,UAAU,GAC7E,EAAA,CACJ;AAER;AAGA,MAAM,aAAa,eAAe,mBAAmB,UAAU;"}
@@ -15,7 +15,7 @@ import Stack from "@mui/material/Stack";
15
15
  import Typography from "@mui/material/Typography";
16
16
  import useMediaQuery from "@mui/material/useMediaQuery";
17
17
  import CloseRoundedIcon from "@mui/icons-material/CloseRounded";
18
- import { piecePart, usePieceProps } from "../../theme/themePieces.js";
18
+ import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
19
19
  import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
20
20
  import { warnUnknownProps } from "../../toolkit/unknownProps.js";
21
21
  const HELP_CLOSE_REASON = Object.freeze({ finished: "finished", closed: "closed" });
@@ -27,7 +27,7 @@ const HelpMedia = piecePart(THEME_NAME, "Media", Box);
27
27
  const HelpContent = piecePart(THEME_NAME, "Content", DialogContent);
28
28
  const HelpDots = piecePart(THEME_NAME, "Dots", Stack);
29
29
  const HelpActions = piecePart(THEME_NAME, "Actions", DialogActions);
30
- function HelpCarouselDialog(props) {
30
+ function HelpCarouselDialogContent(props) {
31
31
  const {
32
32
  open,
33
33
  onClose,
@@ -147,6 +147,7 @@ function HelpCarouselDialog(props) {
147
147
  }
148
148
  );
149
149
  }
150
+ const HelpCarouselDialog = withPieceSlots(HelpCarouselDialogContent, THEME_NAME);
150
151
  export {
151
152
  HELP_CLOSE_REASON,
152
153
  HelpCarouselDialog as default