@stackcraftmx/calcita 0.32.2 → 0.51.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 (680) hide show
  1. package/README.md +426 -4
  2. package/cli/calcita.js +15 -0
  3. package/cli/checkTexts.js +209 -0
  4. package/cli/packageVersions.js +17 -3
  5. package/cli/projectFiles.js +7 -2
  6. package/cli/templates/module/__Name__Page.test.jsx.tpl +24 -0
  7. package/cli/templates/project/README.md.tpl +35 -2
  8. package/cli/templates/project/eslint.config.js.tpl +27 -0
  9. package/cli/templates/project/src/app/appRouter.jsx.tpl +5 -2
  10. package/cli/templates/project/src/app/appTexts.js.tpl +2 -1
  11. package/cli/templates/project/src/core/accountConnector.js.tpl +4 -2
  12. package/cli/templates/project/src/core/publicPaths.js.tpl +10 -2
  13. package/cli/templates/project/src/modules/auth/SignInPage.test.jsx.tpl +20 -0
  14. package/cli/templates/project/src/modules/home/HomePage.test.jsx.tpl +16 -0
  15. package/cli/templates/project/src/testing/browserGaps.js.tpl +70 -0
  16. package/cli/templates/project/src/testing/openScreen.jsx.tpl +58 -0
  17. package/cli/templates/project/src/testing/setup.js.tpl +25 -0
  18. package/cli/templates/project/vite.config.js.tpl +20 -1
  19. package/dist/DataTable/AuditTrailDialog.js +3 -2
  20. package/dist/DataTable/AuditTrailDialog.js.map +1 -1
  21. package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js +3 -2
  22. package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js.map +1 -1
  23. package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +3 -2
  24. package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -1
  25. package/dist/DataTable/ColumnFilters/SortableFilterHeader.js +3 -2
  26. package/dist/DataTable/ColumnFilters/SortableFilterHeader.js.map +1 -1
  27. package/dist/DataTable/EmptyState.js +3 -2
  28. package/dist/DataTable/EmptyState.js.map +1 -1
  29. package/dist/DataTable/FilterChips.js +3 -2
  30. package/dist/DataTable/FilterChips.js.map +1 -1
  31. package/dist/DataTable/GoToPage.js +71 -14
  32. package/dist/DataTable/GoToPage.js.map +1 -1
  33. package/dist/DataTable/ServerTable.js +97 -28
  34. package/dist/DataTable/ServerTable.js.map +1 -1
  35. package/dist/DataTable/ServerTableFilterDrawer.js +57 -0
  36. package/dist/DataTable/ServerTableFilterDrawer.js.map +1 -0
  37. package/dist/DataTable/StackedCell.js +60 -0
  38. package/dist/DataTable/StackedCell.js.map +1 -0
  39. package/dist/DataTable/TableCardsView.js +88 -0
  40. package/dist/DataTable/TableCardsView.js.map +1 -0
  41. package/dist/DataTable/columnWidths.js +30 -0
  42. package/dist/DataTable/columnWidths.js.map +1 -0
  43. package/dist/DataTable/columns.js +47 -1
  44. package/dist/DataTable/columns.js.map +1 -1
  45. package/dist/DataTable/filterContext.js.map +1 -1
  46. package/dist/DataTable/fixedColumns.js +24 -0
  47. package/dist/DataTable/fixedColumns.js.map +1 -0
  48. package/dist/DataTable/goToPageOptions.js +17 -0
  49. package/dist/DataTable/goToPageOptions.js.map +1 -0
  50. package/dist/DataTable/useTableView.js +29 -0
  51. package/dist/DataTable/useTableView.js.map +1 -0
  52. package/dist/access/PermissionMatrix.js +3 -2
  53. package/dist/access/PermissionMatrix.js.map +1 -1
  54. package/dist/account/AccountProvider.js +1 -1
  55. package/dist/account/AccountSecuritySection.js +3 -2
  56. package/dist/account/AccountSecuritySection.js.map +1 -1
  57. package/dist/account/DemoTotpCodeButton.js +3 -2
  58. package/dist/account/DemoTotpCodeButton.js.map +1 -1
  59. package/dist/account/ProfileScreen.js +3 -2
  60. package/dist/account/ProfileScreen.js.map +1 -1
  61. package/dist/account/SignInScreen.js +3 -2
  62. package/dist/account/SignInScreen.js.map +1 -1
  63. package/dist/appShell/AccountMenu.js +3 -2
  64. package/dist/appShell/AccountMenu.js.map +1 -1
  65. package/dist/appShell/AppLayout.js +3 -2
  66. package/dist/appShell/AppLayout.js.map +1 -1
  67. package/dist/appShell/AppearanceSettings.js +3 -2
  68. package/dist/appShell/AppearanceSettings.js.map +1 -1
  69. package/dist/appShell/AuthLayout.js +3 -2
  70. package/dist/appShell/AuthLayout.js.map +1 -1
  71. package/dist/appShell/BarActionButton.js +11 -4
  72. package/dist/appShell/BarActionButton.js.map +1 -1
  73. package/dist/appShell/BarActions.js +3 -2
  74. package/dist/appShell/BarActions.js.map +1 -1
  75. package/dist/appShell/BarCapsule.js +3 -2
  76. package/dist/appShell/BarCapsule.js.map +1 -1
  77. package/dist/appShell/BarSearch.js +3 -2
  78. package/dist/appShell/BarSearch.js.map +1 -1
  79. package/dist/appShell/HeaderTools.js +3 -2
  80. package/dist/appShell/HeaderTools.js.map +1 -1
  81. package/dist/appShell/MobileTabBar.js +3 -2
  82. package/dist/appShell/MobileTabBar.js.map +1 -1
  83. package/dist/appShell/SettingsMenu.js +3 -2
  84. package/dist/appShell/SettingsMenu.js.map +1 -1
  85. package/dist/appShell/SideMenu.js +3 -2
  86. package/dist/appShell/SideMenu.js.map +1 -1
  87. package/dist/appShell/SideMenuEntry.js +3 -2
  88. package/dist/appShell/SideMenuEntry.js.map +1 -1
  89. package/dist/appShell/SubmenuActionsMenu.js +3 -2
  90. package/dist/appShell/SubmenuActionsMenu.js.map +1 -1
  91. package/dist/appShell/TabBarEditor.js +3 -2
  92. package/dist/appShell/TabBarEditor.js.map +1 -1
  93. package/dist/appShell/TopMenu.js +3 -2
  94. package/dist/appShell/TopMenu.js.map +1 -1
  95. package/dist/appShell/Wordmark.js +3 -2
  96. package/dist/appShell/Wordmark.js.map +1 -1
  97. package/dist/auth/PasswordChecklist.js +3 -2
  98. package/dist/auth/PasswordChecklist.js.map +1 -1
  99. package/dist/calendar/EventCalendar.js +3 -2
  100. package/dist/calendar/EventCalendar.js.map +1 -1
  101. package/dist/calendar/EventDetails.js +3 -2
  102. package/dist/calendar/EventDetails.js.map +1 -1
  103. package/dist/date-pickers.js +28 -2
  104. package/dist/date-pickers.js.map +1 -1
  105. package/dist/datePickers/DateInput.js +41 -54
  106. package/dist/datePickers/DateInput.js.map +1 -1
  107. package/dist/datePickers/DateTimeInput.js +81 -0
  108. package/dist/datePickers/DateTimeInput.js.map +1 -0
  109. package/dist/datePickers/FormDateTimeField.js +12 -0
  110. package/dist/datePickers/FormDateTimeField.js.map +1 -0
  111. package/dist/datePickers/FormMonthField.js +12 -0
  112. package/dist/datePickers/FormMonthField.js.map +1 -0
  113. package/dist/datePickers/FormTimeField.js +12 -0
  114. package/dist/datePickers/FormTimeField.js.map +1 -0
  115. package/dist/datePickers/MonthInput.js +64 -0
  116. package/dist/datePickers/MonthInput.js.map +1 -0
  117. package/dist/datePickers/PickerFrame.js +27 -0
  118. package/dist/datePickers/PickerFrame.js.map +1 -0
  119. package/dist/datePickers/TimeInput.js +61 -0
  120. package/dist/datePickers/TimeInput.js.map +1 -0
  121. package/dist/datePickers/dateTimeRules.js +24 -0
  122. package/dist/datePickers/dateTimeRules.js.map +1 -0
  123. package/dist/datePickers/pickerValues.js +106 -0
  124. package/dist/datePickers/pickerValues.js.map +1 -0
  125. package/dist/datePickers/useCurrentMinute.js +28 -0
  126. package/dist/datePickers/useCurrentMinute.js.map +1 -0
  127. package/dist/datePickers/usePickerField.js +23 -0
  128. package/dist/datePickers/usePickerField.js.map +1 -0
  129. package/dist/dictionaries/dictionaries.js +3 -1
  130. package/dist/dictionaries/dictionaries.js.map +1 -1
  131. package/dist/downloads/DownloadManager.js +3 -2
  132. package/dist/downloads/DownloadManager.js.map +1 -1
  133. package/dist/feedback/ConfirmDialog.js +3 -2
  134. package/dist/feedback/ConfirmDialog.js.map +1 -1
  135. package/dist/feedback/ModalWaiting.js +3 -2
  136. package/dist/feedback/ModalWaiting.js.map +1 -1
  137. package/dist/feedback/NewBuildNotice.js +3 -2
  138. package/dist/feedback/NewBuildNotice.js.map +1 -1
  139. package/dist/filepond/FileDropzone.js +3 -2
  140. package/dist/filepond/FileDropzone.js.map +1 -1
  141. package/dist/forms/FormAttachmentsField.js +12 -0
  142. package/dist/forms/FormAttachmentsField.js.map +1 -0
  143. package/dist/forms/FormCheckboxGroupField.js +12 -0
  144. package/dist/forms/FormCheckboxGroupField.js.map +1 -0
  145. package/dist/forms/FormFileField.js +12 -0
  146. package/dist/forms/FormFileField.js.map +1 -0
  147. package/dist/forms/FormFileUploadField.js +12 -0
  148. package/dist/forms/FormFileUploadField.js.map +1 -0
  149. package/dist/forms/FormImageField.js +12 -0
  150. package/dist/forms/FormImageField.js.map +1 -0
  151. package/dist/forms/FormMaskedField.js +12 -0
  152. package/dist/forms/FormMaskedField.js.map +1 -0
  153. package/dist/forms/FormProblemAlert.js +3 -2
  154. package/dist/forms/FormProblemAlert.js.map +1 -1
  155. package/dist/forms/FormRepeatingFields.js +54 -0
  156. package/dist/forms/FormRepeatingFields.js.map +1 -0
  157. package/dist/forms/FormTransferListField.js +12 -0
  158. package/dist/forms/FormTransferListField.js.map +1 -0
  159. package/dist/forms/SubmitButton.js +7 -2
  160. package/dist/forms/SubmitButton.js.map +1 -1
  161. package/dist/forms/applyServerProblem.js +10 -3
  162. package/dist/forms/applyServerProblem.js.map +1 -1
  163. package/dist/forms/auth/SignInForm.js +3 -2
  164. package/dist/forms/auth/SignInForm.js.map +1 -1
  165. package/dist/forms/fieldRules.js +30 -0
  166. package/dist/forms/fieldRules.js.map +1 -0
  167. package/dist/forms/listRules.js +111 -0
  168. package/dist/forms/listRules.js.map +1 -0
  169. package/dist/forms/security/SecondStepForm.js +3 -2
  170. package/dist/forms/security/SecondStepForm.js.map +1 -1
  171. package/dist/forms/security/TwoStepVerificationCard.js +3 -2
  172. package/dist/forms/security/TwoStepVerificationCard.js.map +1 -1
  173. package/dist/forms/serverProblemFields.js +17 -0
  174. package/dist/forms/serverProblemFields.js.map +1 -1
  175. package/dist/forms/useValidationText.js +18 -0
  176. package/dist/forms/useValidationText.js.map +1 -0
  177. package/dist/forms/validation.js +35 -31
  178. package/dist/forms/validation.js.map +1 -1
  179. package/dist/forms/validationMessages.js +64 -7
  180. package/dist/forms/validationMessages.js.map +1 -1
  181. package/dist/forms.js +54 -29
  182. package/dist/forms.js.map +1 -1
  183. package/dist/hookForm/FormAttachmentsField.js +12 -0
  184. package/dist/hookForm/FormAttachmentsField.js.map +1 -0
  185. package/dist/hookForm/FormCheckboxGroupField.js +12 -0
  186. package/dist/hookForm/FormCheckboxGroupField.js.map +1 -0
  187. package/dist/hookForm/FormFileField.js +12 -0
  188. package/dist/hookForm/FormFileField.js.map +1 -0
  189. package/dist/hookForm/FormFileUploadField.js +12 -0
  190. package/dist/hookForm/FormFileUploadField.js.map +1 -0
  191. package/dist/hookForm/FormImageField.js +12 -0
  192. package/dist/hookForm/FormImageField.js.map +1 -0
  193. package/dist/hookForm/FormMaskedField.js +12 -0
  194. package/dist/hookForm/FormMaskedField.js.map +1 -0
  195. package/dist/hookForm/FormProblemAlert.js +3 -2
  196. package/dist/hookForm/FormProblemAlert.js.map +1 -1
  197. package/dist/hookForm/FormRepeatingFields.js +44 -0
  198. package/dist/hookForm/FormRepeatingFields.js.map +1 -0
  199. package/dist/hookForm/FormTransferListField.js +12 -0
  200. package/dist/hookForm/FormTransferListField.js.map +1 -0
  201. package/dist/hookForm/SubmitButton.js +7 -2
  202. package/dist/hookForm/SubmitButton.js.map +1 -1
  203. package/dist/hookForm/applyServerProblem.js +8 -3
  204. package/dist/hookForm/applyServerProblem.js.map +1 -1
  205. package/dist/inbox/InboxLayout.js +3 -2
  206. package/dist/inbox/InboxLayout.js.map +1 -1
  207. package/dist/inbox/MessageList.js +3 -2
  208. package/dist/inbox/MessageList.js.map +1 -1
  209. package/dist/inbox/MessageView.js +3 -2
  210. package/dist/inbox/MessageView.js.map +1 -1
  211. package/dist/index.js +235 -124
  212. package/dist/index.js.map +1 -1
  213. package/dist/inputs/CatalogInput.js +103 -29
  214. package/dist/inputs/CatalogInput.js.map +1 -1
  215. package/dist/inputs/CheckboxGroupInput.js +103 -0
  216. package/dist/inputs/CheckboxGroupInput.js.map +1 -0
  217. package/dist/inputs/ColorInput.js +7 -4
  218. package/dist/inputs/ColorInput.js.map +1 -1
  219. package/dist/inputs/FieldFrame.js +10 -4
  220. package/dist/inputs/FieldFrame.js.map +1 -1
  221. package/dist/inputs/FormSection.js +1 -1
  222. package/dist/inputs/MaskedInput.js +87 -0
  223. package/dist/inputs/MaskedInput.js.map +1 -0
  224. package/dist/inputs/NumberInput.js +41 -25
  225. package/dist/inputs/NumberInput.js.map +1 -1
  226. package/dist/inputs/RepeatingFields.js +180 -0
  227. package/dist/inputs/RepeatingFields.js.map +1 -0
  228. package/dist/inputs/SelectInput.js +50 -9
  229. package/dist/inputs/SelectInput.js.map +1 -1
  230. package/dist/inputs/TextInput.js +5 -3
  231. package/dist/inputs/TextInput.js.map +1 -1
  232. package/dist/inputs/TransferListInput.js +218 -0
  233. package/dist/inputs/TransferListInput.js.map +1 -0
  234. package/dist/inputs/WizardLayout.js +3 -2
  235. package/dist/inputs/WizardLayout.js.map +1 -1
  236. package/dist/inputs/inputMasks.js +84 -0
  237. package/dist/inputs/inputMasks.js.map +1 -0
  238. package/dist/inputs/selectAllState.js +20 -0
  239. package/dist/inputs/selectAllState.js.map +1 -0
  240. package/dist/inputs/useRowKeys.js +26 -0
  241. package/dist/inputs/useRowKeys.js.map +1 -0
  242. package/dist/kanban/KanbanBoard.js +3 -2
  243. package/dist/kanban/KanbanBoard.js.map +1 -1
  244. package/dist/legal/CookieNotice.js +80 -0
  245. package/dist/legal/CookieNotice.js.map +1 -0
  246. package/dist/legal/TermsAcceptanceDialog.js +130 -0
  247. package/dist/legal/TermsAcceptanceDialog.js.map +1 -0
  248. package/dist/legal/consentStorage.js +18 -0
  249. package/dist/legal/consentStorage.js.map +1 -0
  250. package/dist/legal/useCookieConsent.js +17 -0
  251. package/dist/legal/useCookieConsent.js.map +1 -0
  252. package/dist/locales/en.js +257 -1
  253. package/dist/locales/en.js.map +1 -1
  254. package/dist/locales/es.js +257 -1
  255. package/dist/locales/es.js.map +1 -1
  256. package/dist/maps/MapView.js +3 -2
  257. package/dist/maps/MapView.js.map +1 -1
  258. package/dist/mexico/CfdiSummary.js +82 -0
  259. package/dist/mexico/CfdiSummary.js.map +1 -0
  260. package/dist/mexico/EfirmaFields.js +168 -0
  261. package/dist/mexico/EfirmaFields.js.map +1 -0
  262. package/dist/mexico/certificateReader.js +79 -0
  263. package/dist/mexico/certificateReader.js.map +1 -0
  264. package/dist/mexico/cfdiReader.js +81 -0
  265. package/dist/mexico/cfdiReader.js.map +1 -0
  266. package/dist/mexico/derReader.js +81 -0
  267. package/dist/mexico/derReader.js.map +1 -0
  268. package/dist/mexico/efirmaKey.js +51 -0
  269. package/dist/mexico/efirmaKey.js.map +1 -0
  270. package/dist/mexico/mexicoIdentifiers.js +91 -0
  271. package/dist/mexico/mexicoIdentifiers.js.map +1 -0
  272. package/dist/mexico/mexicoRules.js +21 -0
  273. package/dist/mexico/mexicoRules.js.map +1 -0
  274. package/dist/mexico.js +34 -0
  275. package/dist/mexico.js.map +1 -0
  276. package/dist/pwa/InstallAppSetting.js +3 -2
  277. package/dist/pwa/InstallAppSetting.js.map +1 -1
  278. package/dist/pwa/InstallInstructionsDialog.js +3 -2
  279. package/dist/pwa/InstallInstructionsDialog.js.map +1 -1
  280. package/dist/pwa/InstallPromptBanner.js +3 -2
  281. package/dist/pwa/InstallPromptBanner.js.map +1 -1
  282. package/dist/react-hook-form.js +43 -17
  283. package/dist/react-hook-form.js.map +1 -1
  284. package/dist/rich-text.js +19 -0
  285. package/dist/rich-text.js.map +1 -0
  286. package/dist/richText/FormRichTextField.js +12 -0
  287. package/dist/richText/FormRichTextField.js.map +1 -0
  288. package/dist/richText/RichTextEditor.js +111 -0
  289. package/dist/richText/RichTextEditor.js.map +1 -0
  290. package/dist/richText/RichTextLinkPopover.js +57 -0
  291. package/dist/richText/RichTextLinkPopover.js.map +1 -0
  292. package/dist/richText/RichTextToolbar.js +189 -0
  293. package/dist/richText/RichTextToolbar.js.map +1 -0
  294. package/dist/richText/RichTextView.js +27 -0
  295. package/dist/richText/RichTextView.js.map +1 -0
  296. package/dist/richText/richTextContentSx.js +42 -0
  297. package/dist/richText/richTextContentSx.js.map +1 -0
  298. package/dist/richText/richTextExtensions.js +44 -0
  299. package/dist/richText/richTextExtensions.js.map +1 -0
  300. package/dist/richText/richTextRules.js +46 -0
  301. package/dist/richText/richTextRules.js.map +1 -0
  302. package/dist/security/ActivityLog.js +3 -2
  303. package/dist/security/ActivityLog.js.map +1 -1
  304. package/dist/security/RecoveryCodesDialog.js +3 -2
  305. package/dist/security/RecoveryCodesDialog.js.map +1 -1
  306. package/dist/security/SessionsCard.js +3 -2
  307. package/dist/security/SessionsCard.js.map +1 -1
  308. package/dist/table.js +23 -2
  309. package/dist/table.js.map +1 -1
  310. package/dist/theme/components/glassComponents.js +27 -0
  311. package/dist/theme/components/glassComponents.js.map +1 -1
  312. package/dist/theme/components/minimalComponents.js +12 -0
  313. package/dist/theme/components/minimalComponents.js.map +1 -1
  314. package/dist/theme/themePieces.js +70 -4
  315. package/dist/theme/themePieces.js.map +1 -1
  316. package/dist/toolkit/ToolkitProvider.js +8 -1
  317. package/dist/toolkit/ToolkitProvider.js.map +1 -1
  318. package/dist/toolkit/browserNavigation.js +19 -4
  319. package/dist/toolkit/browserNavigation.js.map +1 -1
  320. package/dist/toolkit/combineTexts.js +32 -0
  321. package/dist/toolkit/combineTexts.js.map +1 -0
  322. package/dist/toolkit/hashNavigation.js +17 -3
  323. package/dist/toolkit/hashNavigation.js.map +1 -1
  324. package/dist/toolkit/navigationPaths.js +15 -0
  325. package/dist/toolkit/navigationPaths.js.map +1 -1
  326. package/dist/toolkit/pathIndex.js +66 -0
  327. package/dist/toolkit/pathIndex.js.map +1 -0
  328. package/dist/toolkit/toolkitSettings.js +19 -1
  329. package/dist/toolkit/toolkitSettings.js.map +1 -1
  330. package/dist/types/DataTable/AuditTrailDialog.d.ts +6 -17
  331. package/dist/types/DataTable/ColumnFilters/HeaderFilterPopover.d.ts +6 -5
  332. package/dist/types/DataTable/ColumnFilters/MultiSelectColumnFilter.d.ts +6 -9
  333. package/dist/types/DataTable/ColumnFilters/SortableFilterHeader.d.ts +6 -14
  334. package/dist/types/DataTable/EmptyState.d.ts +6 -9
  335. package/dist/types/DataTable/FilterChips.d.ts +6 -11
  336. package/dist/types/DataTable/GoToPage.d.ts +6 -9
  337. package/dist/types/DataTable/ServerTable.d.ts +16 -80
  338. package/dist/types/DataTable/ServerTableFilterDrawer.d.ts +14 -0
  339. package/dist/types/DataTable/StackedCell.d.ts +12 -0
  340. package/dist/types/DataTable/TableCardsView.d.ts +27 -0
  341. package/dist/types/DataTable/columnWidths.d.ts +21 -0
  342. package/dist/types/DataTable/columns.d.ts +111 -0
  343. package/dist/types/DataTable/filterContext.d.ts +2 -1
  344. package/dist/types/DataTable/fixedColumns.d.ts +29 -0
  345. package/dist/types/DataTable/goToPageOptions.d.ts +15 -0
  346. package/dist/types/DataTable/index.d.ts +7 -1
  347. package/dist/types/DataTable/useTableView.d.ts +22 -0
  348. package/dist/types/access/PermissionMatrix.d.ts +6 -10
  349. package/dist/types/account/AccountSecuritySection.d.ts +6 -7
  350. package/dist/types/account/DemoTotpCodeButton.d.ts +6 -5
  351. package/dist/types/account/ProfileScreen.d.ts +6 -18
  352. package/dist/types/account/SignInScreen.d.ts +6 -13
  353. package/dist/types/appShell/AccountMenu.d.ts +6 -11
  354. package/dist/types/appShell/AppLayout.d.ts +3 -40
  355. package/dist/types/appShell/AppearanceSettings.d.ts +6 -12
  356. package/dist/types/appShell/AuthLayout.d.ts +3 -11
  357. package/dist/types/appShell/BarActionButton.d.ts +6 -10
  358. package/dist/types/appShell/BarActions.d.ts +6 -15
  359. package/dist/types/appShell/BarCapsule.d.ts +6 -9
  360. package/dist/types/appShell/BarSearch.d.ts +6 -15
  361. package/dist/types/appShell/HeaderTools.d.ts +6 -16
  362. package/dist/types/appShell/MobileTabBar.d.ts +6 -13
  363. package/dist/types/appShell/SettingsMenu.d.ts +6 -10
  364. package/dist/types/appShell/SideMenu.d.ts +6 -20
  365. package/dist/types/appShell/SideMenuEntry.d.ts +6 -11
  366. package/dist/types/appShell/SubmenuActionsMenu.d.ts +6 -12
  367. package/dist/types/appShell/TabBarEditor.d.ts +6 -9
  368. package/dist/types/appShell/TopMenu.d.ts +6 -5
  369. package/dist/types/appShell/Wordmark.d.ts +6 -7
  370. package/dist/types/auth/PasswordChecklist.d.ts +6 -9
  371. package/dist/types/calendar/EventCalendar.d.ts +6 -23
  372. package/dist/types/calendar/EventDetails.d.ts +6 -10
  373. package/dist/types/date-pickers.d.ts +10 -1
  374. package/dist/types/datePickers/DateInput.d.ts +10 -23
  375. package/dist/types/datePickers/DateTimeInput.d.ts +30 -0
  376. package/dist/types/datePickers/FormDateTimeField.d.ts +7 -0
  377. package/dist/types/datePickers/FormMonthField.d.ts +7 -0
  378. package/dist/types/datePickers/FormTimeField.d.ts +7 -0
  379. package/dist/types/datePickers/MonthInput.d.ts +25 -0
  380. package/dist/types/datePickers/PickerFrame.d.ts +22 -0
  381. package/dist/types/datePickers/TimeInput.d.ts +24 -0
  382. package/dist/types/datePickers/dateTimeRules.d.ts +31 -0
  383. package/dist/types/datePickers/pickerValues.d.ts +114 -0
  384. package/dist/types/datePickers/useCurrentMinute.d.ts +5 -0
  385. package/dist/types/datePickers/usePickerField.d.ts +28 -0
  386. package/dist/types/dictionaries/dictionaries.d.ts +6 -3
  387. package/dist/types/downloads/DownloadManager.d.ts +6 -6
  388. package/dist/types/feedback/ConfirmDialog.d.ts +6 -18
  389. package/dist/types/feedback/ModalWaiting.d.ts +6 -9
  390. package/dist/types/feedback/NewBuildNotice.d.ts +6 -10
  391. package/dist/types/filepond/FileDropzone.d.ts +6 -29
  392. package/dist/types/forms/FormAttachmentsField.d.ts +7 -0
  393. package/dist/types/forms/FormCheckboxGroupField.d.ts +7 -0
  394. package/dist/types/forms/FormFileField.d.ts +7 -0
  395. package/dist/types/forms/FormFileUploadField.d.ts +7 -0
  396. package/dist/types/forms/FormImageField.d.ts +7 -0
  397. package/dist/types/forms/FormMaskedField.d.ts +7 -0
  398. package/dist/types/forms/FormProblemAlert.d.ts +6 -5
  399. package/dist/types/forms/FormRepeatingFields.d.ts +25 -0
  400. package/dist/types/forms/FormTransferListField.d.ts +7 -0
  401. package/dist/types/forms/SubmitButton.d.ts +6 -6
  402. package/dist/types/forms/auth/SignInForm.d.ts +6 -11
  403. package/dist/types/forms/fieldRules.d.ts +44 -0
  404. package/dist/types/forms/index.d.ts +11 -1
  405. package/dist/types/forms/listRules.d.ts +48 -0
  406. package/dist/types/forms/security/SecondStepForm.d.ts +6 -14
  407. package/dist/types/forms/security/TwoStepVerificationCard.d.ts +6 -21
  408. package/dist/types/forms/serverProblemFields.d.ts +13 -0
  409. package/dist/types/forms/useValidationText.d.ts +12 -0
  410. package/dist/types/forms/validation.d.ts +117 -174
  411. package/dist/types/forms/validationMessages.d.ts +54 -6
  412. package/dist/types/forms.d.ts +1 -1
  413. package/dist/types/hookForm/FormAttachmentsField.d.ts +8 -0
  414. package/dist/types/hookForm/FormCheckboxGroupField.d.ts +8 -0
  415. package/dist/types/hookForm/FormFileField.d.ts +8 -0
  416. package/dist/types/hookForm/FormFileUploadField.d.ts +8 -0
  417. package/dist/types/hookForm/FormImageField.d.ts +8 -0
  418. package/dist/types/hookForm/FormMaskedField.d.ts +9 -0
  419. package/dist/types/hookForm/FormProblemAlert.d.ts +6 -5
  420. package/dist/types/hookForm/FormRepeatingFields.d.ts +27 -0
  421. package/dist/types/hookForm/FormTransferListField.d.ts +8 -0
  422. package/dist/types/hookForm/SubmitButton.d.ts +6 -13
  423. package/dist/types/inbox/InboxLayout.d.ts +6 -17
  424. package/dist/types/inbox/MessageList.d.ts +6 -18
  425. package/dist/types/inbox/MessageView.d.ts +6 -14
  426. package/dist/types/index.d.ts +33 -4
  427. package/dist/types/inputs/CatalogInput.d.ts +10 -21
  428. package/dist/types/inputs/CheckboxGroupInput.d.ts +28 -0
  429. package/dist/types/inputs/ColorInput.d.ts +7 -16
  430. package/dist/types/inputs/FieldFrame.d.ts +6 -10
  431. package/dist/types/inputs/MaskedInput.d.ts +38 -0
  432. package/dist/types/inputs/NumberInput.d.ts +7 -20
  433. package/dist/types/inputs/RepeatingFields.d.ts +31 -0
  434. package/dist/types/inputs/SelectInput.d.ts +10 -18
  435. package/dist/types/inputs/TextInput.d.ts +3 -0
  436. package/dist/types/inputs/TransferListInput.d.ts +30 -0
  437. package/dist/types/inputs/WizardLayout.d.ts +6 -19
  438. package/dist/types/inputs/inputMasks.d.ts +52 -0
  439. package/dist/types/inputs/selectAllState.d.ts +11 -0
  440. package/dist/types/inputs/useRowKeys.d.ts +11 -0
  441. package/dist/types/kanban/KanbanBoard.d.ts +6 -25
  442. package/dist/types/legal/CookieNotice.d.ts +20 -0
  443. package/dist/types/legal/TermsAcceptanceDialog.d.ts +20 -0
  444. package/dist/types/legal/consentStorage.d.ts +16 -0
  445. package/dist/types/legal/useCookieConsent.d.ts +13 -0
  446. package/dist/types/locales/en.d.ts +256 -0
  447. package/dist/types/locales/es.d.ts +256 -0
  448. package/dist/types/maps/MapView.d.ts +6 -17
  449. package/dist/types/mexico/CfdiSummary.d.ts +12 -0
  450. package/dist/types/mexico/EfirmaFields.d.ts +28 -0
  451. package/dist/types/mexico/certificateReader.d.ts +37 -0
  452. package/dist/types/mexico/cfdiReader.d.ts +95 -0
  453. package/dist/types/mexico/derReader.d.ts +54 -0
  454. package/dist/types/mexico/efirmaKey.d.ts +26 -0
  455. package/dist/types/mexico/mexicoIdentifiers.d.ts +68 -0
  456. package/dist/types/mexico/mexicoRules.d.ts +45 -0
  457. package/dist/types/mexico.d.ts +11 -0
  458. package/dist/types/pwa/InstallAppSetting.d.ts +6 -6
  459. package/dist/types/pwa/InstallInstructionsDialog.d.ts +6 -9
  460. package/dist/types/pwa/InstallPromptBanner.d.ts +6 -11
  461. package/dist/types/react-hook-form.d.ts +11 -1
  462. package/dist/types/rich-text.d.ts +5 -0
  463. package/dist/types/richText/FormRichTextField.d.ts +7 -0
  464. package/dist/types/richText/RichTextEditor.d.ts +27 -0
  465. package/dist/types/richText/RichTextLinkPopover.d.ts +17 -0
  466. package/dist/types/richText/RichTextToolbar.d.ts +15 -0
  467. package/dist/types/richText/RichTextView.d.ts +10 -0
  468. package/dist/types/richText/richTextContentSx.d.ts +7 -0
  469. package/dist/types/richText/richTextExtensions.d.ts +15 -0
  470. package/dist/types/richText/richTextRules.d.ts +41 -0
  471. package/dist/types/security/ActivityLog.d.ts +6 -9
  472. package/dist/types/security/RecoveryCodesDialog.d.ts +6 -11
  473. package/dist/types/security/SessionsCard.d.ts +6 -11
  474. package/dist/types/table.d.ts +3 -1
  475. package/dist/types/theme/themePieces.d.ts +55 -3
  476. package/dist/types/toolkit/ToolkitProvider.d.ts +13 -1
  477. package/dist/types/toolkit/browserNavigation.d.ts +7 -3
  478. package/dist/types/toolkit/combineTexts.d.ts +6 -0
  479. package/dist/types/toolkit/hashNavigation.d.ts +4 -2
  480. package/dist/types/toolkit/navigationPaths.d.ts +35 -0
  481. package/dist/types/toolkit/pathIndex.d.ts +27 -0
  482. package/dist/types/toolkit/toolkitSettings.d.ts +7 -4
  483. package/dist/types/ui/actions/ActionsMenu.d.ts +24 -11
  484. package/dist/types/ui/actions/CopyButton.d.ts +8 -11
  485. package/dist/types/ui/actions/DownloadMenu.d.ts +6 -29
  486. package/dist/types/ui/actions/SecretField.d.ts +6 -11
  487. package/dist/types/ui/actions/SelectionActions.d.ts +6 -13
  488. package/dist/types/ui/actions/tableRowText.d.ts +6 -0
  489. package/dist/types/ui/cards/RecordCard.d.ts +40 -0
  490. package/dist/types/ui/cards/RecordCardSkeleton.d.ts +12 -0
  491. package/dist/types/ui/countdown/Countdown.d.ts +22 -0
  492. package/dist/types/ui/countdown/countdownParts.d.ts +39 -0
  493. package/dist/types/ui/countdown/useCountdown.d.ts +14 -0
  494. package/dist/types/ui/documents/PdfViewerDialog.d.ts +14 -0
  495. package/dist/types/ui/filters/DateRangeFilter.d.ts +6 -10
  496. package/dist/types/ui/filters/FilterDrawer.d.ts +23 -0
  497. package/dist/types/ui/filters/PeriodRangeSelector.d.ts +6 -13
  498. package/dist/types/ui/filters/QuickFilters.d.ts +6 -12
  499. package/dist/types/ui/filters/filterDrawerFields.d.ts +139 -0
  500. package/dist/types/ui/help/HelpButton.d.ts +11 -0
  501. package/dist/types/ui/help/HelpCarouselDialog.d.ts +27 -0
  502. package/dist/types/ui/help/useHelpCarousel.d.ts +21 -0
  503. package/dist/types/ui/index.d.ts +10 -0
  504. package/dist/types/ui/labels/IconBadge.d.ts +34 -0
  505. package/dist/types/ui/labels/MarkedText.d.ts +10 -0
  506. package/dist/types/ui/labels/Tag.d.ts +6 -12
  507. package/dist/types/ui/labels/markedTextPieces.d.ts +22 -0
  508. package/dist/types/ui/layout/CollapsibleSection.d.ts +6 -12
  509. package/dist/types/ui/layout/ContentDialog.d.ts +6 -10
  510. package/dist/types/ui/layout/DefinitionList.d.ts +6 -9
  511. package/dist/types/ui/layout/DetailHeader.d.ts +6 -10
  512. package/dist/types/ui/layout/ErrorPage.d.ts +6 -17
  513. package/dist/types/ui/layout/FullPageLoader.d.ts +6 -6
  514. package/dist/types/ui/layout/GlassPanel.d.ts +6 -8
  515. package/dist/types/ui/layout/PageHeader.d.ts +6 -10
  516. package/dist/types/ui/layout/PageHeading.d.ts +6 -11
  517. package/dist/types/ui/layout/ProfileHeader.d.ts +6 -11
  518. package/dist/types/ui/layout/ScrollableRow.d.ts +6 -13
  519. package/dist/types/ui/layout/SectionCard.d.ts +6 -8
  520. package/dist/types/ui/metrics/BarList.d.ts +6 -12
  521. package/dist/types/ui/metrics/CalendarHeatmap.d.ts +6 -19
  522. package/dist/types/ui/metrics/ChartTooltip.d.ts +6 -6
  523. package/dist/types/ui/metrics/ColumnChart.d.ts +6 -25
  524. package/dist/types/ui/metrics/LineChart.d.ts +6 -20
  525. package/dist/types/ui/metrics/MetricCard.d.ts +6 -17
  526. package/dist/types/ui/metrics/TableToggle.d.ts +6 -6
  527. package/dist/types/ui/metrics/chartParts.d.ts +15 -30
  528. package/dist/types/ui/navigation/BackButton.d.ts +6 -9
  529. package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +6 -9
  530. package/dist/types/ui/navigation/FontSizeToggle.d.ts +6 -8
  531. package/dist/types/ui/navigation/LanguageToggle.d.ts +6 -8
  532. package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +6 -7
  533. package/dist/types/ui/navigation/RouteTabs.d.ts +39 -0
  534. package/dist/types/ui/navigation/routeTabMatching.d.ts +27 -0
  535. package/dist/types/ui/timeline/GroupedTimeline.d.ts +6 -23
  536. package/dist/types/upload/AttachmentsInput.d.ts +72 -0
  537. package/dist/types/upload/FileChip.d.ts +18 -0
  538. package/dist/types/upload/FileDropzone.d.ts +7 -19
  539. package/dist/types/upload/FileInput.d.ts +31 -0
  540. package/dist/types/upload/FileUploadInput.d.ts +56 -0
  541. package/dist/types/upload/ImageInput.d.ts +35 -0
  542. package/dist/types/upload/TemplateDownloadButton.d.ts +27 -0
  543. package/dist/types/upload/fileAppearance.d.ts +8 -0
  544. package/dist/types/upload/fileRules.d.ts +38 -0
  545. package/dist/types/upload/transferProgress.d.ts +18 -0
  546. package/dist/types/upload/uploadMachine.d.ts +6 -2
  547. package/dist/types/upload/uploadWithProgress.d.ts +6 -2
  548. package/dist/types/upload/useFilePicker.d.ts +39 -0
  549. package/dist/ui/actions/ActionsMenu.js +109 -17
  550. package/dist/ui/actions/ActionsMenu.js.map +1 -1
  551. package/dist/ui/actions/CopyButton.js +37 -12
  552. package/dist/ui/actions/CopyButton.js.map +1 -1
  553. package/dist/ui/actions/DownloadMenu.js +3 -2
  554. package/dist/ui/actions/DownloadMenu.js.map +1 -1
  555. package/dist/ui/actions/SecretField.js +8 -3
  556. package/dist/ui/actions/SecretField.js.map +1 -1
  557. package/dist/ui/actions/SelectionActions.js +3 -2
  558. package/dist/ui/actions/SelectionActions.js.map +1 -1
  559. package/dist/ui/actions/tableRowText.js +7 -0
  560. package/dist/ui/actions/tableRowText.js.map +1 -0
  561. package/dist/ui/cards/RecordCard.js +146 -0
  562. package/dist/ui/cards/RecordCard.js.map +1 -0
  563. package/dist/ui/cards/RecordCardSkeleton.js +38 -0
  564. package/dist/ui/cards/RecordCardSkeleton.js.map +1 -0
  565. package/dist/ui/countdown/Countdown.js +39 -0
  566. package/dist/ui/countdown/Countdown.js.map +1 -0
  567. package/dist/ui/countdown/countdownParts.js +34 -0
  568. package/dist/ui/countdown/countdownParts.js.map +1 -0
  569. package/dist/ui/countdown/useCountdown.js +35 -0
  570. package/dist/ui/countdown/useCountdown.js.map +1 -0
  571. package/dist/ui/documents/PdfViewerDialog.js +82 -0
  572. package/dist/ui/documents/PdfViewerDialog.js.map +1 -0
  573. package/dist/ui/filters/DateRangeFilter.js +3 -2
  574. package/dist/ui/filters/DateRangeFilter.js.map +1 -1
  575. package/dist/ui/filters/FilterDrawer.js +212 -0
  576. package/dist/ui/filters/FilterDrawer.js.map +1 -0
  577. package/dist/ui/filters/PeriodRangeSelector.js +3 -2
  578. package/dist/ui/filters/PeriodRangeSelector.js.map +1 -1
  579. package/dist/ui/filters/QuickFilters.js +3 -2
  580. package/dist/ui/filters/QuickFilters.js.map +1 -1
  581. package/dist/ui/filters/filterDrawerFields.js +119 -0
  582. package/dist/ui/filters/filterDrawerFields.js.map +1 -0
  583. package/dist/ui/help/HelpButton.js +22 -0
  584. package/dist/ui/help/HelpButton.js.map +1 -0
  585. package/dist/ui/help/HelpCarouselDialog.js +155 -0
  586. package/dist/ui/help/HelpCarouselDialog.js.map +1 -0
  587. package/dist/ui/help/useHelpCarousel.js +25 -0
  588. package/dist/ui/help/useHelpCarousel.js.map +1 -0
  589. package/dist/ui/labels/IconBadge.js +82 -0
  590. package/dist/ui/labels/IconBadge.js.map +1 -0
  591. package/dist/ui/labels/MarkedText.js +31 -0
  592. package/dist/ui/labels/MarkedText.js.map +1 -0
  593. package/dist/ui/labels/Tag.js +3 -2
  594. package/dist/ui/labels/Tag.js.map +1 -1
  595. package/dist/ui/labels/markedTextPieces.js +64 -0
  596. package/dist/ui/labels/markedTextPieces.js.map +1 -0
  597. package/dist/ui/layout/CollapsibleSection.js +3 -2
  598. package/dist/ui/layout/CollapsibleSection.js.map +1 -1
  599. package/dist/ui/layout/ContentDialog.js +3 -2
  600. package/dist/ui/layout/ContentDialog.js.map +1 -1
  601. package/dist/ui/layout/DefinitionList.js +3 -2
  602. package/dist/ui/layout/DefinitionList.js.map +1 -1
  603. package/dist/ui/layout/DetailHeader.js +3 -2
  604. package/dist/ui/layout/DetailHeader.js.map +1 -1
  605. package/dist/ui/layout/ErrorPage.js +3 -2
  606. package/dist/ui/layout/ErrorPage.js.map +1 -1
  607. package/dist/ui/layout/FullPageLoader.js +3 -2
  608. package/dist/ui/layout/FullPageLoader.js.map +1 -1
  609. package/dist/ui/layout/GlassPanel.js +3 -2
  610. package/dist/ui/layout/GlassPanel.js.map +1 -1
  611. package/dist/ui/layout/PageHeader.js +3 -2
  612. package/dist/ui/layout/PageHeader.js.map +1 -1
  613. package/dist/ui/layout/PageHeading.js +3 -2
  614. package/dist/ui/layout/PageHeading.js.map +1 -1
  615. package/dist/ui/layout/ProfileHeader.js +3 -2
  616. package/dist/ui/layout/ProfileHeader.js.map +1 -1
  617. package/dist/ui/layout/ScrollableRow.js +3 -2
  618. package/dist/ui/layout/ScrollableRow.js.map +1 -1
  619. package/dist/ui/layout/SectionCard.js +3 -2
  620. package/dist/ui/layout/SectionCard.js.map +1 -1
  621. package/dist/ui/metrics/BarList.js +3 -2
  622. package/dist/ui/metrics/BarList.js.map +1 -1
  623. package/dist/ui/metrics/CalendarHeatmap.js +3 -2
  624. package/dist/ui/metrics/CalendarHeatmap.js.map +1 -1
  625. package/dist/ui/metrics/ChartTooltip.js +3 -2
  626. package/dist/ui/metrics/ChartTooltip.js.map +1 -1
  627. package/dist/ui/metrics/ColumnChart.js +3 -2
  628. package/dist/ui/metrics/ColumnChart.js.map +1 -1
  629. package/dist/ui/metrics/LineChart.js +3 -2
  630. package/dist/ui/metrics/LineChart.js.map +1 -1
  631. package/dist/ui/metrics/MetricCard.js +3 -2
  632. package/dist/ui/metrics/MetricCard.js.map +1 -1
  633. package/dist/ui/metrics/TableToggle.js +3 -2
  634. package/dist/ui/metrics/TableToggle.js.map +1 -1
  635. package/dist/ui/metrics/chartParts.js +7 -4
  636. package/dist/ui/metrics/chartParts.js.map +1 -1
  637. package/dist/ui/navigation/BackButton.js +7 -2
  638. package/dist/ui/navigation/BackButton.js.map +1 -1
  639. package/dist/ui/navigation/ColorSchemeToggle.js +3 -2
  640. package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -1
  641. package/dist/ui/navigation/FontSizeToggle.js +3 -2
  642. package/dist/ui/navigation/FontSizeToggle.js.map +1 -1
  643. package/dist/ui/navigation/LanguageToggle.js +3 -2
  644. package/dist/ui/navigation/LanguageToggle.js.map +1 -1
  645. package/dist/ui/navigation/PageBreadcrumbs.js +3 -2
  646. package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -1
  647. package/dist/ui/navigation/RouteTabs.js +79 -0
  648. package/dist/ui/navigation/RouteTabs.js.map +1 -0
  649. package/dist/ui/navigation/routeTabMatching.js +23 -0
  650. package/dist/ui/navigation/routeTabMatching.js.map +1 -0
  651. package/dist/ui/timeline/GroupedTimeline.js +3 -2
  652. package/dist/ui/timeline/GroupedTimeline.js.map +1 -1
  653. package/dist/upload/AttachmentsInput.js +130 -0
  654. package/dist/upload/AttachmentsInput.js.map +1 -0
  655. package/dist/upload/FileChip.js +28 -0
  656. package/dist/upload/FileChip.js.map +1 -0
  657. package/dist/upload/FileDropzone.js +23 -87
  658. package/dist/upload/FileDropzone.js.map +1 -1
  659. package/dist/upload/FileInput.js +115 -0
  660. package/dist/upload/FileInput.js.map +1 -0
  661. package/dist/upload/FileUploadInput.js +288 -0
  662. package/dist/upload/FileUploadInput.js.map +1 -0
  663. package/dist/upload/ImageInput.js +128 -0
  664. package/dist/upload/ImageInput.js.map +1 -0
  665. package/dist/upload/TemplateDownloadButton.js +68 -0
  666. package/dist/upload/TemplateDownloadButton.js.map +1 -0
  667. package/dist/upload/fileAppearance.js +21 -0
  668. package/dist/upload/fileAppearance.js.map +1 -0
  669. package/dist/upload/fileRules.js +27 -1
  670. package/dist/upload/fileRules.js.map +1 -1
  671. package/dist/upload/transferProgress.js +23 -0
  672. package/dist/upload/transferProgress.js.map +1 -0
  673. package/dist/upload/uploadMachine.js +8 -8
  674. package/dist/upload/uploadMachine.js.map +1 -1
  675. package/dist/upload/uploadWithProgress.js +1 -1
  676. package/dist/upload/uploadWithProgress.js.map +1 -1
  677. package/dist/upload/useFilePicker.js +101 -0
  678. package/dist/upload/useFilePicker.js.map +1 -0
  679. package/package.json +44 -1
  680. package/cli/templates/project/src/app/combineTexts.js.tpl +0 -31
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
3
3
  import Box from "@mui/material/Box";
4
4
  import { paletteOf } from "../theme/components/paletteOf.js";
5
5
  import { isGlassTheme, glassStylesOf } from "../theme/glassSurface.js";
6
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
6
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
7
7
  const THEME_NAME = "CalcitaBarCapsule";
8
8
  const CapsuleRoot = piecePart(THEME_NAME, "Root", Box);
9
9
  const BAR_CAPSULE_HEIGHT_PIXELS = 48;
@@ -23,7 +23,7 @@ function monochromeButtonsSxOf(color) {
23
23
  }
24
24
  };
25
25
  }
26
- function BarCapsule(props) {
26
+ function BarCapsuleContent(props) {
27
27
  const { children, sx, role = "group", ...rest } = usePieceProps(props, THEME_NAME);
28
28
  return /* @__PURE__ */ jsx(
29
29
  CapsuleRoot,
@@ -47,6 +47,7 @@ function BarCapsule(props) {
47
47
  }
48
48
  );
49
49
  }
50
+ const BarCapsule = withPieceSlots(BarCapsuleContent, THEME_NAME);
50
51
  export {
51
52
  BAR_CAPSULE_HEIGHT_PIXELS,
52
53
  BarCapsule as default,
@@ -1 +1 @@
1
- {"version":3,"file":"BarCapsule.js","sources":["../../src/appShell/BarCapsule.jsx"],"sourcesContent":["// Una cápsula de la barra de arriba (como las de las ventanas de macOS Tahoe): un grupo de botones juntos, con vidrio si el\n// tema lo trae y, con el minimalista, un bloque del tono de las tarjetas sin borde ni sombra. La usan el marco (la ☰ con el\n// nombre, la cuenta), las acciones de cada pantalla (BarActions) y el proyecto para algo suyo que deba verse igual (unos\n// botones encima de un mapa, una barra de herramientas propia).\n//\n// Con vidrio, los botones de adentro van SIEMPRE del color del texto y sin relleno, borde ni sombra, aunque quien los usa\n// les ponga color o variante (color=\"primary\", variant=\"contained\" u \"outlined\", un sx propio): en las barras de Apple los\n// símbolos son de un solo color y el color queda para el contenido (HIG Toolbars y Color). Lo pidió el autor. OJO: al\n// principio solo se quitó el color del texto y un «Redactar» con relleno seguía naranja en la barra (lo cachó el autor). Se\n// logra con selectores de más clases que las del botón; los deshabilitados se quedan con su gris. Con el minimalista\n// conservan su color.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarCapsule con defaultProps y\n// styleOverrides.root (el sx de la pantalla sigue ganando a todo).\n//\n// Genérico del paquete: function (regla de la casa).\nimport Box from '@mui/material/Box';\n\nimport {paletteOf} from '@/theme/components/paletteOf.js';\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaBarCapsule)\nconst THEME_NAME = 'CalcitaBarCapsule';\nconst CapsuleRoot = piecePart(THEME_NAME, 'Root', Box);\n\n// lo alto de una cápsula (px): cabe en el alto de siempre de la barra con aire arriba y abajo\nexport const BAR_CAPSULE_HEIGHT_PIXELS = 48;\n\n/**\n * Los botones de adentro de un solo color y sin relleno, borde ni sombra (la regla de la barra con vidrio). La usan también\n * la franja (BarActions) y lo que se ponga junto a la barra.\n *\n * @param {string} color el del texto de la barra ('inherit' en la franja)\n * @returns {object} estilos para el sx del contenedor\n */\nexport function monochromeButtonsSxOf(color) {\n return {\n '& .MuiIconButton-root:not(.Mui-disabled), & .MuiButton-root:not(.Mui-disabled)': {color},\n // un botón con relleno o con borde se queda como uno de texto: sin fondo, sin borde y sin sombra, también al pasar el\n // cursor (ahí lleva el velo de cualquier botón de texto). OJO: la barra es un Paper y el tema tiñe los botones con\n // borde «dentro de una tarjeta» con body[data-glass-lens] .MuiPaper-root … (cuatro clases y un elemento): por eso\n // .MuiButton-root va repetido, para pesar cinco clases (con menos, «Restablecer» seguía teñido; medido en Chrome)\n '& .MuiButton-root.MuiButton-root.MuiButton-root.MuiButton-contained, & .MuiButton-root.MuiButton-root.MuiButton-root.MuiButton-outlined': {\n backgroundColor: 'transparent', backgroundImage: 'none', boxShadow: 'none', border: 0,\n '&:hover': {backgroundColor: 'action.hover', boxShadow: 'none'},\n },\n };\n}\n\n/**\n * Lo demás va al div de la cápsula: aria-label (el nombre del grupo para quien usa lector de pantalla), id, onClick…\n * role va por omisión en 'group' (lo que se agrupa se anuncia junto).\n *\n * @param {Omit<import('react').HTMLAttributes<HTMLDivElement>, 'children'> & {children: import('react').ReactNode, sx?: object|Function|Array<any>}} props\n * children: los botones del grupo; sx: estilos propios, encima de los de la cápsula\n */\nexport default function BarCapsule(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarCapsule.defaultProps) y encima lo que llega aquí\n const {children, sx, role = 'group', ...rest} = usePieceProps(props, THEME_NAME);\n // el estilo de la cápsula va abajo (ownSx): encima el del tema del proyecto y, al final, el sx de la pantalla\n return (\n <CapsuleRoot role={role} {...rest}\n ownSx={(theme) => ({\n ...(isGlassTheme(theme) ? glassStylesOf(theme, {isControl: true}) : {backgroundColor: paletteOf(theme).background.paper}),\n ...(isGlassTheme(theme) && monochromeButtonsSxOf(paletteOf(theme).text.primary)),\n display: 'flex', alignItems: 'center', gap: 0.5, flexShrink: 0, minWidth: 0,\n height: BAR_CAPSULE_HEIGHT_PIXELS, px: 0.75, borderRadius: '999px',\n })}\n sx={sx}>\n {children}\n </CapsuleRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;AAuBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,QAAQ,GAAG;AAG9C,MAAM,4BAA4B;AASlC,SAAS,sBAAsB,OAAO;AACzC,SAAO;AAAA,IACH,kFAAkF,EAAC,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnF,2IAA2I;AAAA,MACvI,iBAAiB;AAAA,MAAe,iBAAiB;AAAA,MAAQ,WAAW;AAAA,MAAQ,QAAQ;AAAA,MACpF,WAAW,EAAC,iBAAiB,gBAAgB,WAAW,OAAA;AAAA,IAAM;AAAA,EAClE;AAER;AASA,SAAwB,WAAW,OAAO;AAEtC,QAAM,EAAC,UAAU,IAAI,OAAO,SAAS,GAAG,SAAQ,cAAc,OAAO,UAAU;AAE/E,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAY;AAAA,MAAa,GAAG;AAAA,MACxB,OAAO,CAAC,WAAW;AAAA,QACf,GAAI,aAAa,KAAK,IAAI,cAAc,OAAO,EAAC,WAAW,KAAA,CAAK,IAAI,EAAC,iBAAiB,UAAU,KAAK,EAAE,WAAW,MAAA;AAAA,QAClH,GAAI,aAAa,KAAK,KAAK,sBAAsB,UAAU,KAAK,EAAE,KAAK,OAAO;AAAA,QAC9E,SAAS;AAAA,QAAQ,YAAY;AAAA,QAAU,KAAK;AAAA,QAAK,YAAY;AAAA,QAAG,UAAU;AAAA,QAC1E,QAAQ;AAAA,QAA2B,IAAI;AAAA,QAAM,cAAc;AAAA,MAAA;AAAA,MAE/D;AAAA,MACA;AAAA,IAAA;AAAA,EAAA;AAGb;"}
1
+ {"version":3,"file":"BarCapsule.js","sources":["../../src/appShell/BarCapsule.jsx"],"sourcesContent":["// Una cápsula de la barra de arriba (como las de las ventanas de macOS Tahoe): un grupo de botones juntos, con vidrio si el\n// tema lo trae y, con el minimalista, un bloque del tono de las tarjetas sin borde ni sombra. La usan el marco (la ☰ con el\n// nombre, la cuenta), las acciones de cada pantalla (BarActions) y el proyecto para algo suyo que deba verse igual (unos\n// botones encima de un mapa, una barra de herramientas propia).\n//\n// Con vidrio, los botones de adentro van SIEMPRE del color del texto y sin relleno, borde ni sombra, aunque quien los usa\n// les ponga color o variante (color=\"primary\", variant=\"contained\" u \"outlined\", un sx propio): en las barras de Apple los\n// símbolos son de un solo color y el color queda para el contenido (HIG Toolbars y Color). Lo pidió el autor. OJO: al\n// principio solo se quitó el color del texto y un «Redactar» con relleno seguía naranja en la barra (lo cachó el autor). Se\n// logra con selectores de más clases que las del botón; los deshabilitados se quedan con su gris. Con el minimalista\n// conservan su color.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarCapsule con defaultProps y\n// styleOverrides.root (el sx de la pantalla sigue ganando a todo).\n//\n// Genérico del paquete: function (regla de la casa).\nimport Box from '@mui/material/Box';\n\nimport {paletteOf} from '@/theme/components/paletteOf.js';\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaBarCapsule)\nconst THEME_NAME = 'CalcitaBarCapsule';\nconst CapsuleRoot = piecePart(THEME_NAME, 'Root', Box);\n\n// lo alto de una cápsula (px): cabe en el alto de siempre de la barra con aire arriba y abajo\nexport const BAR_CAPSULE_HEIGHT_PIXELS = 48;\n\n/**\n * Los botones de adentro de un solo color y sin relleno, borde ni sombra (la regla de la barra con vidrio). La usan también\n * la franja (BarActions) y lo que se ponga junto a la barra.\n *\n * @param {string} color el del texto de la barra ('inherit' en la franja)\n * @returns {object} estilos para el sx del contenedor\n */\nexport function monochromeButtonsSxOf(color) {\n return {\n '& .MuiIconButton-root:not(.Mui-disabled), & .MuiButton-root:not(.Mui-disabled)': {color},\n // un botón con relleno o con borde se queda como uno de texto: sin fondo, sin borde y sin sombra, también al pasar el\n // cursor (ahí lleva el velo de cualquier botón de texto). OJO: la barra es un Paper y el tema tiñe los botones con\n // borde «dentro de una tarjeta» con body[data-glass-lens] .MuiPaper-root … (cuatro clases y un elemento): por eso\n // .MuiButton-root va repetido, para pesar cinco clases (con menos, «Restablecer» seguía teñido; medido en Chrome)\n '& .MuiButton-root.MuiButton-root.MuiButton-root.MuiButton-contained, & .MuiButton-root.MuiButton-root.MuiButton-root.MuiButton-outlined': {\n backgroundColor: 'transparent', backgroundImage: 'none', boxShadow: 'none', border: 0,\n '&:hover': {backgroundColor: 'action.hover', boxShadow: 'none'},\n },\n };\n}\n\n/**\n * Lo demás va al div de la cápsula: aria-label (el nombre del grupo para quien usa lector de pantalla), id, onClick…\n * role va por omisión en 'group' (lo que se agrupa se anuncia junto).\n *\n * @param {Omit<import('react').HTMLAttributes<HTMLDivElement>, 'children'> & {children: import('react').ReactNode, sx?: object|Function|Array<any>}} props\n * children: los botones del grupo; sx: estilos propios, encima de los de la cápsula\n */\nfunction BarCapsuleContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarCapsule.defaultProps) y encima lo que llega aquí\n const {children, sx, role = 'group', ...rest} = usePieceProps(props, THEME_NAME);\n // el estilo de la cápsula va abajo (ownSx): encima el del tema del proyecto y, al final, el sx de la pantalla\n return (\n <CapsuleRoot role={role} {...rest}\n ownSx={(theme) => ({\n ...(isGlassTheme(theme) ? glassStylesOf(theme, {isControl: true}) : {backgroundColor: paletteOf(theme).background.paper}),\n ...(isGlassTheme(theme) && monochromeButtonsSxOf(paletteOf(theme).text.primary)),\n display: 'flex', alignItems: 'center', gap: 0.5, flexShrink: 0, minWidth: 0,\n height: BAR_CAPSULE_HEIGHT_PIXELS, px: 0.75, borderRadius: '999px',\n })}\n sx={sx}>\n {children}\n </CapsuleRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst BarCapsule = withPieceSlots(BarCapsuleContent, THEME_NAME);\nexport default BarCapsule;\n"],"names":[],"mappings":";;;;;;AAuBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,QAAQ,GAAG;AAG9C,MAAM,4BAA4B;AASlC,SAAS,sBAAsB,OAAO;AACzC,SAAO;AAAA,IACH,kFAAkF,EAAC,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnF,2IAA2I;AAAA,MACvI,iBAAiB;AAAA,MAAe,iBAAiB;AAAA,MAAQ,WAAW;AAAA,MAAQ,QAAQ;AAAA,MACpF,WAAW,EAAC,iBAAiB,gBAAgB,WAAW,OAAA;AAAA,IAAM;AAAA,EAClE;AAER;AASA,SAAS,kBAAkB,OAAO;AAE9B,QAAM,EAAC,UAAU,IAAI,OAAO,SAAS,GAAG,SAAQ,cAAc,OAAO,UAAU;AAE/E,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAY;AAAA,MAAa,GAAG;AAAA,MACxB,OAAO,CAAC,WAAW;AAAA,QACf,GAAI,aAAa,KAAK,IAAI,cAAc,OAAO,EAAC,WAAW,KAAA,CAAK,IAAI,EAAC,iBAAiB,UAAU,KAAK,EAAE,WAAW,MAAA;AAAA,QAClH,GAAI,aAAa,KAAK,KAAK,sBAAsB,UAAU,KAAK,EAAE,KAAK,OAAO;AAAA,QAC9E,SAAS;AAAA,QAAQ,YAAY;AAAA,QAAU,KAAK;AAAA,QAAK,YAAY;AAAA,QAAG,UAAU;AAAA,QAC1E,QAAQ;AAAA,QAA2B,IAAI;AAAA,QAAM,cAAc;AAAA,MAAA;AAAA,MAE/D;AAAA,MACA;AAAA,IAAA;AAAA,EAAA;AAGb;AAGA,MAAM,aAAa,eAAe,mBAAmB,UAAU;"}
@@ -7,13 +7,13 @@ import SearchIcon from "@mui/icons-material/Search";
7
7
  import BarActions from "./BarActions.js";
8
8
  import { BAR_CAPSULE_HEIGHT_PIXELS } from "./BarCapsule.js";
9
9
  import { PHONE_MEDIA_QUERY } from "./shellSizes.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 = "CalcitaBarSearch";
13
13
  const SearchField = piecePart(THEME_NAME, "Field", TextField);
14
14
  const SEARCH_BOX_MIN_WIDTH_PIXELS = 400;
15
15
  const SEARCH_IN_BAR_WIDTH_PIXELS = 380;
16
- function BarSearch(props) {
16
+ function BarSearchContent(props) {
17
17
  const { value, onChange, placeholder, inBar = true, collapsible = true, order = 0, onFocus, onBlur, inputRef, ...unknownProps } = usePieceProps(props, THEME_NAME);
18
18
  warnUnknownProps(THEME_NAME, unknownProps);
19
19
  const [isFocused, setIsFocused] = useState(false);
@@ -92,6 +92,7 @@ function BarSearch(props) {
92
92
  }
93
93
  );
94
94
  }
95
+ const BarSearch = withPieceSlots(BarSearchContent, THEME_NAME);
95
96
  export {
96
97
  BarSearch as default
97
98
  };
@@ -1 +1 @@
1
- {"version":3,"file":"BarSearch.js","sources":["../../src/appShell/BarSearch.jsx"],"sourcesContent":["// Una caja de búsqueda que sube a la barra de la app, como el buscador de las ventanas de macOS: sin usar se encoge a la\n// lupa, al picarla (o llegar con Tab) se estira, y con texto se queda abierta. En el teléfono con cápsulas flota arriba con\n// las demás; sin barra en cápsulas se queda donde la pantalla la puso. Escape borra lo escrito y la suelta.\n//\n// <BarSearch value={query} onChange={setQuery} placeholder=\"Buscar por título o etiqueta\" />\n//\n// La usan la tabla de servidor (searchInBar) y cualquier pantalla que busque en lo suyo (Tareas). Con inBar={false} es la\n// misma caja dentro de la pantalla.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarSearch con defaultProps y\n// styleOverrides de sus partes: field.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport TextField from '@mui/material/TextField';\nimport SearchIcon from '@mui/icons-material/Search';\n\nimport BarActions from '@/appShell/BarActions.jsx';\nimport {BAR_CAPSULE_HEIGHT_PIXELS} from '@/appShell/BarCapsule.jsx';\nimport {PHONE_MEDIA_QUERY} from '@/appShell/shellSizes.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.CalcitaBarSearch)\nconst THEME_NAME = 'CalcitaBarSearch';\nconst SearchField = piecePart(THEME_NAME, 'Field', TextField);\n\n// ancho de la caja dentro de la pantalla en escritorio: cabe un texto de ayuda como «Buscar por pedido, cliente o producto…».\n// OJO: con 280 se cortaba («…cliente o pro»); en el teléfono la caja toma todo el ancho\nconst SEARCH_BOX_MIN_WIDTH_PIXELS = 400;\n// en la barra un poco más angosta: comparte el renglón con el título y las cápsulas\nconst SEARCH_IN_BAR_WIDTH_PIXELS = 380;\n\n/**\n * @param {object} props\n * @param {string} props.value lo escrito\n * @param {(value: string) => void} props.onChange recibe el texto, no el evento\n * @param {string} props.placeholder ya traducido: qué se busca («Buscar por título o etiqueta»); también es su nombre para el\n * lector de pantalla\n * @param {boolean} [props.inBar] en la barra de la app (por omisión) o dentro de la pantalla\n * @param {boolean} [props.collapsible] en la barra, sin usar se encoge a la lupa; por omisión sí (false: siempre abierta)\n * @param {number} [props.order] en qué lugar va entre las cápsulas de la barra (por omisión la primera)\n * @param {() => void} [props.onFocus]\n * @param {() => void} [props.onBlur]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef] la caja, para enfocarla desde afuera (un atajo «/»)\n */\nexport default function BarSearch(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarSearch.defaultProps) y encima lo que llega aquí\n const {value, onChange, placeholder, inBar = true, collapsible = true, order = 0, onFocus, onBlur, inputRef, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const [isFocused, setIsFocused] = useState(false);\n // en la barra, chica cuando no se usa: ni tiene el foco ni tiene texto\n const isCompact = inBar && collapsible && !isFocused && !value;\n const searchBox = (\n <SearchField\n type=\"search\"\n size=\"small\"\n inputRef={inputRef}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n onFocus={() => {\n setIsFocused(true);\n onFocus?.();\n }}\n onBlur={() => {\n setIsFocused(false);\n onBlur?.();\n }}\n // Escape borra lo escrito y suelta la caja (en la barra, regresa a la lupa)\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n onChange('');\n event.currentTarget.querySelector('input')?.blur();\n }\n }}\n placeholder={placeholder}\n ownSx={{\n minWidth: {xs: 0, md: inBar ? 0 : SEARCH_BOX_MIN_WIDTH_PIXELS},\n // la × del navegador para type=\"search\" no va: la caja se borra con Escape\n '& input[type=\"search\"]::-webkit-search-cancel-button': {WebkitAppearance: 'none', display: 'none'},\n }}\n slotProps={{\n input: {startAdornment: <InputAdornment position=\"start\"><SearchIcon fontSize=\"small\" /></InputAdornment>},\n htmlInput: {'aria-label': placeholder},\n }}\n />\n );\n\n if (!inBar) {\n return searchBox;\n }\n\n // en la barra: la caja ya es su propia cápsula (bare), del alto y la forma de las demás y más angosta.\n // OJO: la barra es un Paper y el tema le pone al campo el radio de «campo dentro de tarjeta», con el lente\n // (body[data-glass-lens] .MuiPaper-root …) aún más específica: por eso las tres clases (con menos salía con esquinas de\n // 12 px y no en cápsula; medido en Chrome). La lupa no atrapa el clic: lo deja pasar a la caja, que es la que se enfoca\n return (\n <BarActions label={placeholder} bare order={order}\n sx={(theme) => ({\n // en el teléfono flota arriba junto a las demás cápsulas. Su lugar SIEMPRE ocupa lo libre del renglón y\n // la caja va pegada a la derecha: así se abre de derecha a izquierda y regresa igual (el ancho pasa de 48 px\n // a 100 % con transición). OJO: antes el lugar brincaba de golpe (flex-grow no se anima) y la caja crecía\n // de izquierda a derecha. El hueco de la izquierda deja pasar el dedo a lo de abajo; solo la caja lo recibe\n [PHONE_MEDIA_QUERY]: {\n flexGrow: 1, minWidth: 0, justifyContent: 'flex-end', pointerEvents: 'none',\n '& .MuiTextField-root': {pointerEvents: 'auto'},\n },\n '& .MuiTextField-root': {\n width: isCompact ? BAR_CAPSULE_HEIGHT_PIXELS : SEARCH_IN_BAR_WIDTH_PIXELS,\n minWidth: 0,\n transition: theme.transitions.create('width', {duration: theme.transitions.duration.short}),\n '@media (prefers-reduced-motion: reduce)': {transition: 'none'},\n [PHONE_MEDIA_QUERY]: {width: isCompact ? BAR_CAPSULE_HEIGHT_PIXELS : '100%'},\n },\n '& .MuiFormControl-root .MuiInputBase-root.MuiOutlinedInput-root': {\n height: BAR_CAPSULE_HEIGHT_PIXELS, borderRadius: '999px', cursor: isCompact ? 'pointer' : 'text',\n },\n '& .MuiInputAdornment-root': {pointerEvents: 'none'},\n '& input::placeholder': {opacity: isCompact ? 0 : undefined},\n })}>\n {searchBox}\n </BarActions>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,SAAS,SAAS;AAI5D,MAAM,8BAA8B;AAEpC,MAAM,6BAA6B;AAenC,SAAwB,UAAU,OAAO;AAErC,QAAM,EAAC,OAAO,UAAU,aAAa,QAAQ,MAAM,cAAc,MAAM,QAAQ,GAAG,SAAS,QAAQ,UAAU,GAAG,iBAAgB,cAAc,OAAO,UAAU;AAC/J,mBAAiB,YAAY,YAAY;AACzC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,QAAM,YAAY,SAAS,eAAe,CAAC,aAAa,CAAC;AACzD,QAAM,YACF;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAK;AAAA,MACL,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,MAChD,SAAS,MAAM;AACX,qBAAa,IAAI;AACjB,kBAAA;AAAA,MACJ;AAAA,MACA,QAAQ,MAAM;AACV,qBAAa,KAAK;AAClB,iBAAA;AAAA,MACJ;AAAA,MAEA,WAAW,CAAC,UAAU;AAClB,YAAI,MAAM,QAAQ,UAAU;AACxB,mBAAS,EAAE;AACX,gBAAM,cAAc,cAAc,OAAO,GAAG,KAAA;AAAA,QAChD;AAAA,MACJ;AAAA,MACA;AAAA,MACA,OAAO;AAAA,QACH,UAAU,EAAC,IAAI,GAAG,IAAI,QAAQ,IAAI,4BAAA;AAAA;AAAA,QAElC,wDAAwD,EAAC,kBAAkB,QAAQ,SAAS,OAAA;AAAA,MAAM;AAAA,MAEtG,WAAW;AAAA,QACP,OAAO,EAAC,gBAAgB,oBAAC,gBAAA,EAAe,UAAS,SAAQ,UAAA,oBAAC,YAAA,EAAW,UAAS,QAAA,CAAQ,EAAA,CAAE,EAAA;AAAA,QACxF,WAAW,EAAC,cAAc,YAAA;AAAA,MAAW;AAAA,IACzC;AAAA,EAAA;AAIR,MAAI,CAAC,OAAO;AACR,WAAO;AAAA,EACX;AAMA,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAW,OAAO;AAAA,MAAa,MAAI;AAAA,MAAC;AAAA,MACzB,IAAI,CAAC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,QAKZ,CAAC,iBAAiB,GAAG;AAAA,UACjB,UAAU;AAAA,UAAG,UAAU;AAAA,UAAG,gBAAgB;AAAA,UAAY,eAAe;AAAA,UACrE,wBAAwB,EAAC,eAAe,OAAA;AAAA,QAAM;AAAA,QAElD,wBAAwB;AAAA,UACpB,OAAO,YAAY,4BAA4B;AAAA,UAC/C,UAAU;AAAA,UACV,YAAY,MAAM,YAAY,OAAO,SAAS,EAAC,UAAU,MAAM,YAAY,SAAS,MAAA,CAAM;AAAA,UAC1F,2CAA2C,EAAC,YAAY,OAAA;AAAA,UACxD,CAAC,iBAAiB,GAAG,EAAC,OAAO,YAAY,4BAA4B,OAAA;AAAA,QAAM;AAAA,QAE/E,mEAAmE;AAAA,UAC/D,QAAQ;AAAA,UAA2B,cAAc;AAAA,UAAS,QAAQ,YAAY,YAAY;AAAA,QAAA;AAAA,QAE9F,6BAA6B,EAAC,eAAe,OAAA;AAAA,QAC7C,wBAAwB,EAAC,SAAS,YAAY,IAAI,OAAA;AAAA,MAAS;AAAA,MAEtE,UAAA;AAAA,IAAA;AAAA,EAAA;AAGb;"}
1
+ {"version":3,"file":"BarSearch.js","sources":["../../src/appShell/BarSearch.jsx"],"sourcesContent":["// Una caja de búsqueda que sube a la barra de la app, como el buscador de las ventanas de macOS: sin usar se encoge a la\n// lupa, al picarla (o llegar con Tab) se estira, y con texto se queda abierta. En el teléfono con cápsulas flota arriba con\n// las demás; sin barra en cápsulas se queda donde la pantalla la puso. Escape borra lo escrito y la suelta.\n//\n// <BarSearch value={query} onChange={setQuery} placeholder=\"Buscar por título o etiqueta\" />\n//\n// La usan la tabla de servidor (searchInBar) y cualquier pantalla que busque en lo suyo (Tareas). Con inBar={false} es la\n// misma caja dentro de la pantalla.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarSearch con defaultProps y\n// styleOverrides de sus partes: field.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport TextField from '@mui/material/TextField';\nimport SearchIcon from '@mui/icons-material/Search';\n\nimport BarActions from '@/appShell/BarActions.jsx';\nimport {BAR_CAPSULE_HEIGHT_PIXELS} from '@/appShell/BarCapsule.jsx';\nimport {PHONE_MEDIA_QUERY} from '@/appShell/shellSizes.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.CalcitaBarSearch)\nconst THEME_NAME = 'CalcitaBarSearch';\nconst SearchField = piecePart(THEME_NAME, 'Field', TextField);\n\n// ancho de la caja dentro de la pantalla en escritorio: cabe un texto de ayuda como «Buscar por pedido, cliente o producto…».\n// OJO: con 280 se cortaba («…cliente o pro»); en el teléfono la caja toma todo el ancho\nconst SEARCH_BOX_MIN_WIDTH_PIXELS = 400;\n// en la barra un poco más angosta: comparte el renglón con el título y las cápsulas\nconst SEARCH_IN_BAR_WIDTH_PIXELS = 380;\n\n/**\n * @param {object} props\n * @param {string} props.value lo escrito\n * @param {(value: string) => void} props.onChange recibe el texto, no el evento\n * @param {string} props.placeholder ya traducido: qué se busca («Buscar por título o etiqueta»); también es su nombre para el\n * lector de pantalla\n * @param {boolean} [props.inBar] en la barra de la app (por omisión) o dentro de la pantalla\n * @param {boolean} [props.collapsible] en la barra, sin usar se encoge a la lupa; por omisión sí (false: siempre abierta)\n * @param {number} [props.order] en qué lugar va entre las cápsulas de la barra (por omisión la primera)\n * @param {() => void} [props.onFocus]\n * @param {() => void} [props.onBlur]\n * @param {import('react').Ref<HTMLInputElement>} [props.inputRef] la caja, para enfocarla desde afuera (un atajo «/»)\n */\nfunction BarSearchContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarSearch.defaultProps) y encima lo que llega aquí\n const {value, onChange, placeholder, inBar = true, collapsible = true, order = 0, onFocus, onBlur, inputRef, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const [isFocused, setIsFocused] = useState(false);\n // en la barra, chica cuando no se usa: ni tiene el foco ni tiene texto\n const isCompact = inBar && collapsible && !isFocused && !value;\n const searchBox = (\n <SearchField\n type=\"search\"\n size=\"small\"\n inputRef={inputRef}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n onFocus={() => {\n setIsFocused(true);\n onFocus?.();\n }}\n onBlur={() => {\n setIsFocused(false);\n onBlur?.();\n }}\n // Escape borra lo escrito y suelta la caja (en la barra, regresa a la lupa)\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n onChange('');\n event.currentTarget.querySelector('input')?.blur();\n }\n }}\n placeholder={placeholder}\n ownSx={{\n minWidth: {xs: 0, md: inBar ? 0 : SEARCH_BOX_MIN_WIDTH_PIXELS},\n // la × del navegador para type=\"search\" no va: la caja se borra con Escape\n '& input[type=\"search\"]::-webkit-search-cancel-button': {WebkitAppearance: 'none', display: 'none'},\n }}\n slotProps={{\n input: {startAdornment: <InputAdornment position=\"start\"><SearchIcon fontSize=\"small\" /></InputAdornment>},\n htmlInput: {'aria-label': placeholder},\n }}\n />\n );\n\n if (!inBar) {\n return searchBox;\n }\n\n // en la barra: la caja ya es su propia cápsula (bare), del alto y la forma de las demás y más angosta.\n // OJO: la barra es un Paper y el tema le pone al campo el radio de «campo dentro de tarjeta», con el lente\n // (body[data-glass-lens] .MuiPaper-root …) aún más específica: por eso las tres clases (con menos salía con esquinas de\n // 12 px y no en cápsula; medido en Chrome). La lupa no atrapa el clic: lo deja pasar a la caja, que es la que se enfoca\n return (\n <BarActions label={placeholder} bare order={order}\n sx={(theme) => ({\n // en el teléfono flota arriba junto a las demás cápsulas. Su lugar SIEMPRE ocupa lo libre del renglón y\n // la caja va pegada a la derecha: así se abre de derecha a izquierda y regresa igual (el ancho pasa de 48 px\n // a 100 % con transición). OJO: antes el lugar brincaba de golpe (flex-grow no se anima) y la caja crecía\n // de izquierda a derecha. El hueco de la izquierda deja pasar el dedo a lo de abajo; solo la caja lo recibe\n [PHONE_MEDIA_QUERY]: {\n flexGrow: 1, minWidth: 0, justifyContent: 'flex-end', pointerEvents: 'none',\n '& .MuiTextField-root': {pointerEvents: 'auto'},\n },\n '& .MuiTextField-root': {\n width: isCompact ? BAR_CAPSULE_HEIGHT_PIXELS : SEARCH_IN_BAR_WIDTH_PIXELS,\n minWidth: 0,\n transition: theme.transitions.create('width', {duration: theme.transitions.duration.short}),\n '@media (prefers-reduced-motion: reduce)': {transition: 'none'},\n [PHONE_MEDIA_QUERY]: {width: isCompact ? BAR_CAPSULE_HEIGHT_PIXELS : '100%'},\n },\n '& .MuiFormControl-root .MuiInputBase-root.MuiOutlinedInput-root': {\n height: BAR_CAPSULE_HEIGHT_PIXELS, borderRadius: '999px', cursor: isCompact ? 'pointer' : 'text',\n },\n '& .MuiInputAdornment-root': {pointerEvents: 'none'},\n '& input::placeholder': {opacity: isCompact ? 0 : undefined},\n })}>\n {searchBox}\n </BarActions>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst BarSearch = withPieceSlots(BarSearchContent, THEME_NAME);\nexport default BarSearch;\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,SAAS,SAAS;AAI5D,MAAM,8BAA8B;AAEpC,MAAM,6BAA6B;AAenC,SAAS,iBAAiB,OAAO;AAE7B,QAAM,EAAC,OAAO,UAAU,aAAa,QAAQ,MAAM,cAAc,MAAM,QAAQ,GAAG,SAAS,QAAQ,UAAU,GAAG,iBAAgB,cAAc,OAAO,UAAU;AAC/J,mBAAiB,YAAY,YAAY;AACzC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,QAAM,YAAY,SAAS,eAAe,CAAC,aAAa,CAAC;AACzD,QAAM,YACF;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAK;AAAA,MACL,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,MAChD,SAAS,MAAM;AACX,qBAAa,IAAI;AACjB,kBAAA;AAAA,MACJ;AAAA,MACA,QAAQ,MAAM;AACV,qBAAa,KAAK;AAClB,iBAAA;AAAA,MACJ;AAAA,MAEA,WAAW,CAAC,UAAU;AAClB,YAAI,MAAM,QAAQ,UAAU;AACxB,mBAAS,EAAE;AACX,gBAAM,cAAc,cAAc,OAAO,GAAG,KAAA;AAAA,QAChD;AAAA,MACJ;AAAA,MACA;AAAA,MACA,OAAO;AAAA,QACH,UAAU,EAAC,IAAI,GAAG,IAAI,QAAQ,IAAI,4BAAA;AAAA;AAAA,QAElC,wDAAwD,EAAC,kBAAkB,QAAQ,SAAS,OAAA;AAAA,MAAM;AAAA,MAEtG,WAAW;AAAA,QACP,OAAO,EAAC,gBAAgB,oBAAC,gBAAA,EAAe,UAAS,SAAQ,UAAA,oBAAC,YAAA,EAAW,UAAS,QAAA,CAAQ,EAAA,CAAE,EAAA;AAAA,QACxF,WAAW,EAAC,cAAc,YAAA;AAAA,MAAW;AAAA,IACzC;AAAA,EAAA;AAIR,MAAI,CAAC,OAAO;AACR,WAAO;AAAA,EACX;AAMA,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAW,OAAO;AAAA,MAAa,MAAI;AAAA,MAAC;AAAA,MACzB,IAAI,CAAC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,QAKZ,CAAC,iBAAiB,GAAG;AAAA,UACjB,UAAU;AAAA,UAAG,UAAU;AAAA,UAAG,gBAAgB;AAAA,UAAY,eAAe;AAAA,UACrE,wBAAwB,EAAC,eAAe,OAAA;AAAA,QAAM;AAAA,QAElD,wBAAwB;AAAA,UACpB,OAAO,YAAY,4BAA4B;AAAA,UAC/C,UAAU;AAAA,UACV,YAAY,MAAM,YAAY,OAAO,SAAS,EAAC,UAAU,MAAM,YAAY,SAAS,MAAA,CAAM;AAAA,UAC1F,2CAA2C,EAAC,YAAY,OAAA;AAAA,UACxD,CAAC,iBAAiB,GAAG,EAAC,OAAO,YAAY,4BAA4B,OAAA;AAAA,QAAM;AAAA,QAE/E,mEAAmE;AAAA,UAC/D,QAAQ;AAAA,UAA2B,cAAc;AAAA,UAAS,QAAQ,YAAY,YAAY;AAAA,QAAA;AAAA,QAE9F,6BAA6B,EAAC,eAAe,OAAA;AAAA,QAC7C,wBAAwB,EAAC,SAAS,YAAY,IAAI,OAAA;AAAA,MAAS;AAAA,MAEtE,UAAA;AAAA,IAAA;AAAA,EAAA;AAGb;AAGA,MAAM,YAAY,eAAe,kBAAkB,UAAU;"}
@@ -5,12 +5,12 @@ import Divider from "@mui/material/Divider";
5
5
  import AccountMenu from "./AccountMenu.js";
6
6
  import SettingsMenu from "./SettingsMenu.js";
7
7
  import AppearanceSettings from "./AppearanceSettings.js";
8
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
8
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
9
9
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
10
10
  const THEME_NAME = "CalcitaHeaderTools";
11
11
  const ToolsDivider = piecePart(THEME_NAME, "Divider", Divider);
12
12
  const ToolsRoot = piecePart(THEME_NAME, "Root", Box);
13
- function HeaderTools(props) {
13
+ function HeaderToolsContent(props) {
14
14
  const {
15
15
  headerActions,
16
16
  showFontSizeToggle,
@@ -57,6 +57,7 @@ function HeaderTools(props) {
57
57
  )
58
58
  ] });
59
59
  }
60
+ const HeaderTools = withPieceSlots(HeaderToolsContent, THEME_NAME);
60
61
  export {
61
62
  HeaderTools as default
62
63
  };
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderTools.js","sources":["../../src/appShell/HeaderTools.jsx"],"sourcesContent":["// Lo de la derecha de la barra, igual en los dos estilos de barra (menú lateral o arriba):\n// - lo que el proyecto agregue (headerActions: un botón de «reporte urgente», un buscador…);\n// - la cuenta (AccountMenu), y DENTRO de su menú los ajustes de la app: tamaño de letra, idioma, claro u oscuro y los del\n// proyecto (accountSettings). Antes iban sueltos en la barra, cada uno con su botón: ocupaban lugar y en el menú lateral\n// encogido (que hace de barra) tapaban el menú (lo reportaron; el autor pidió «un solo menú como el de perfil»);\n// - sin sesión no hay cuenta: los ajustes van detrás del engrane (SettingsMenu).\n// En columna (vertical) van abajo del menú lateral encogido con vidrio, que hace también de barra (AppLayout).\n//\n// Los botones toman el color de la barra (color: inherit): sobre la barra naranja de Stackcraft van claros, sobre una\n// barra blanca van oscuros, sin que cada botón sepa de qué color es la barra.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaHeaderTools con defaultProps y\n// styleOverrides de sus partes: divider, root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\n\nimport AccountMenu from '@/appShell/AccountMenu.jsx';\nimport SettingsMenu from '@/appShell/SettingsMenu.jsx';\nimport AppearanceSettings from '@/appShell/AppearanceSettings.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.CalcitaHeaderTools)\nconst THEME_NAME = 'CalcitaHeaderTools';\nconst ToolsDivider = piecePart(THEME_NAME, 'Divider', Divider);\nconst ToolsRoot = piecePart(THEME_NAME, 'Root', Box);\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.headerActions]\n * @param {boolean} props.showFontSizeToggle\n * @param {boolean} props.showLanguageToggle\n * @param {boolean} props.showColorSchemeToggle\n * @param {object|null} props.user\n * @param {string} [props.profilePath]\n * @param {object[]} [props.accountMenuItems]\n * @param {import('react').ReactNode} [props.accountSettings] los ajustes del proyecto, en el menú de la cuenta (SettingSection)\n * @param {boolean} [props.vertical] en columna, para el menú lateral encogido\n * @param {() => void} [props.onSignOut]\n * @param {boolean} [props.isSigningOut]\n */\nexport default function HeaderTools(props) {\n // lo que el proyecto puso en su tema (components.CalcitaHeaderTools.defaultProps) y encima lo que llega aquí\n const {\n headerActions, showFontSizeToggle, showLanguageToggle, showColorSchemeToggle, user, profilePath, accountMenuItems, onSignOut, isSigningOut,\n accountSettings, vertical = false,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const hasAppearance = showFontSizeToggle || showLanguageToggle || showColorSchemeToggle;\n const settings = hasAppearance || accountSettings ? (\n <>\n <AppearanceSettings showFontSize={showFontSizeToggle} showLanguage={showLanguageToggle} showColorScheme={showColorSchemeToggle} />\n {hasAppearance && accountSettings && <ToolsDivider ownSx={{my: 0.5}} />}\n {accountSettings}\n </>\n ) : null;\n\n return (\n <ToolsRoot ownSx={{display: 'flex', flexDirection: vertical ? 'column' : 'row', alignItems: 'center', gap: 0.5, flexShrink: 0, '& .MuiButtonBase-root': {color: 'inherit'}}}>\n {headerActions}\n {user ? (\n <AccountMenu user={user} profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut} isSigningOut={isSigningOut}\n settings={settings} />\n ) : (settings || accountMenuItems?.length > 0) && (\n // sin sesión: el engrane con los ajustes y las ligas propias (en un sistema que ya existía, «Regresar» se perdía)\n <SettingsMenu showFontSize={showFontSizeToggle} showLanguage={showLanguageToggle} showColorScheme={showColorSchemeToggle}\n extraSettings={accountSettings} menuLinks={accountMenuItems} />\n )}\n </ToolsRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,eAAe,UAAU,YAAY,WAAW,OAAO;AAC7D,MAAM,YAAY,UAAU,YAAY,QAAQ,GAAG;AAgBnD,SAAwB,YAAY,OAAO;AAEvC,QAAM;AAAA,IACN;AAAA,IAAe;AAAA,IAAoB;AAAA,IAAoB;AAAA,IAAuB;AAAA,IAAM;AAAA,IAAa;AAAA,IAAkB;AAAA,IAAW;AAAA,IAC9H;AAAA,IAAiB,WAAW;AAAA,IAC5B,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AAC/B,mBAAiB,YAAY,YAAY;AACzC,QAAM,gBAAgB,sBAAsB,sBAAsB;AAClE,QAAM,WAAW,iBAAiB,kBAC9B,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA,oBAAC,sBAAmB,cAAc,oBAAoB,cAAc,oBAAoB,iBAAiB,uBAAuB;AAAA,IAC/H,iBAAiB,mBAAmB,oBAAC,cAAA,EAAa,OAAO,EAAC,IAAI,OAAM;AAAA,IACpE;AAAA,EAAA,EAAA,CACL,IACA;AAEJ,SACI,qBAAC,aAAU,OAAO,EAAC,SAAS,QAAQ,eAAe,WAAW,WAAW,OAAO,YAAY,UAAU,KAAK,KAAK,YAAY,GAAG,yBAAyB,EAAC,OAAO,YAAS,GACpK,UAAA;AAAA,IAAA;AAAA,IACA,OACG;AAAA,MAAC;AAAA,MAAA;AAAA,QAAY;AAAA,QAAY;AAAA,QAA0B;AAAA,QAAoC;AAAA,QAAsB;AAAA,QAChG;AAAA,MAAA;AAAA,IAAA,KACZ,YAAY,kBAAkB,SAAS;AAAA,IAExC;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,cAAc;AAAA,QAAoB,cAAc;AAAA,QAAoB,iBAAiB;AAAA,QACrF,eAAe;AAAA,QAAiB,WAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EAAkB,GAEnF;AAER;"}
1
+ {"version":3,"file":"HeaderTools.js","sources":["../../src/appShell/HeaderTools.jsx"],"sourcesContent":["// Lo de la derecha de la barra, igual en los dos estilos de barra (menú lateral o arriba):\n// - lo que el proyecto agregue (headerActions: un botón de «reporte urgente», un buscador…);\n// - la cuenta (AccountMenu), y DENTRO de su menú los ajustes de la app: tamaño de letra, idioma, claro u oscuro y los del\n// proyecto (accountSettings). Antes iban sueltos en la barra, cada uno con su botón: ocupaban lugar y en el menú lateral\n// encogido (que hace de barra) tapaban el menú (lo reportaron; el autor pidió «un solo menú como el de perfil»);\n// - sin sesión no hay cuenta: los ajustes van detrás del engrane (SettingsMenu).\n// En columna (vertical) van abajo del menú lateral encogido con vidrio, que hace también de barra (AppLayout).\n//\n// Los botones toman el color de la barra (color: inherit): sobre la barra naranja de Stackcraft van claros, sobre una\n// barra blanca van oscuros, sin que cada botón sepa de qué color es la barra.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaHeaderTools con defaultProps y\n// styleOverrides de sus partes: divider, root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\n\nimport AccountMenu from '@/appShell/AccountMenu.jsx';\nimport SettingsMenu from '@/appShell/SettingsMenu.jsx';\nimport AppearanceSettings from '@/appShell/AppearanceSettings.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.CalcitaHeaderTools)\nconst THEME_NAME = 'CalcitaHeaderTools';\nconst ToolsDivider = piecePart(THEME_NAME, 'Divider', Divider);\nconst ToolsRoot = piecePart(THEME_NAME, 'Root', Box);\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.headerActions]\n * @param {boolean} props.showFontSizeToggle\n * @param {boolean} props.showLanguageToggle\n * @param {boolean} props.showColorSchemeToggle\n * @param {object|null} props.user\n * @param {string} [props.profilePath]\n * @param {object[]} [props.accountMenuItems]\n * @param {import('react').ReactNode} [props.accountSettings] los ajustes del proyecto, en el menú de la cuenta (SettingSection)\n * @param {boolean} [props.vertical] en columna, para el menú lateral encogido\n * @param {() => void} [props.onSignOut]\n * @param {boolean} [props.isSigningOut]\n */\nfunction HeaderToolsContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaHeaderTools.defaultProps) y encima lo que llega aquí\n const {\n headerActions, showFontSizeToggle, showLanguageToggle, showColorSchemeToggle, user, profilePath, accountMenuItems, onSignOut, isSigningOut,\n accountSettings, vertical = false,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const hasAppearance = showFontSizeToggle || showLanguageToggle || showColorSchemeToggle;\n const settings = hasAppearance || accountSettings ? (\n <>\n <AppearanceSettings showFontSize={showFontSizeToggle} showLanguage={showLanguageToggle} showColorScheme={showColorSchemeToggle} />\n {hasAppearance && accountSettings && <ToolsDivider ownSx={{my: 0.5}} />}\n {accountSettings}\n </>\n ) : null;\n\n return (\n <ToolsRoot ownSx={{display: 'flex', flexDirection: vertical ? 'column' : 'row', alignItems: 'center', gap: 0.5, flexShrink: 0, '& .MuiButtonBase-root': {color: 'inherit'}}}>\n {headerActions}\n {user ? (\n <AccountMenu user={user} profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut} isSigningOut={isSigningOut}\n settings={settings} />\n ) : (settings || accountMenuItems?.length > 0) && (\n // sin sesión: el engrane con los ajustes y las ligas propias (en un sistema que ya existía, «Regresar» se perdía)\n <SettingsMenu showFontSize={showFontSizeToggle} showLanguage={showLanguageToggle} showColorScheme={showColorSchemeToggle}\n extraSettings={accountSettings} menuLinks={accountMenuItems} />\n )}\n </ToolsRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst HeaderTools = withPieceSlots(HeaderToolsContent, THEME_NAME);\nexport default HeaderTools;\n"],"names":[],"mappings":";;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,eAAe,UAAU,YAAY,WAAW,OAAO;AAC7D,MAAM,YAAY,UAAU,YAAY,QAAQ,GAAG;AAgBnD,SAAS,mBAAmB,OAAO;AAE/B,QAAM;AAAA,IACN;AAAA,IAAe;AAAA,IAAoB;AAAA,IAAoB;AAAA,IAAuB;AAAA,IAAM;AAAA,IAAa;AAAA,IAAkB;AAAA,IAAW;AAAA,IAC9H;AAAA,IAAiB,WAAW;AAAA,IAC5B,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AAC/B,mBAAiB,YAAY,YAAY;AACzC,QAAM,gBAAgB,sBAAsB,sBAAsB;AAClE,QAAM,WAAW,iBAAiB,kBAC9B,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA,oBAAC,sBAAmB,cAAc,oBAAoB,cAAc,oBAAoB,iBAAiB,uBAAuB;AAAA,IAC/H,iBAAiB,mBAAmB,oBAAC,cAAA,EAAa,OAAO,EAAC,IAAI,OAAM;AAAA,IACpE;AAAA,EAAA,EAAA,CACL,IACA;AAEJ,SACI,qBAAC,aAAU,OAAO,EAAC,SAAS,QAAQ,eAAe,WAAW,WAAW,OAAO,YAAY,UAAU,KAAK,KAAK,YAAY,GAAG,yBAAyB,EAAC,OAAO,YAAS,GACpK,UAAA;AAAA,IAAA;AAAA,IACA,OACG;AAAA,MAAC;AAAA,MAAA;AAAA,QAAY;AAAA,QAAY;AAAA,QAA0B;AAAA,QAAoC;AAAA,QAAsB;AAAA,QAChG;AAAA,MAAA;AAAA,IAAA,KACZ,YAAY,kBAAkB,SAAS;AAAA,IAExC;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,cAAc;AAAA,QAAoB,cAAc;AAAA,QAAoB,iBAAiB;AAAA,QACrF,eAAe;AAAA,QAAiB,WAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EAAkB,GAEnF;AAER;AAGA,MAAM,cAAc,eAAe,oBAAoB,UAAU;"}
@@ -23,7 +23,7 @@ import { accentTextStylesOf, isGlassTheme, glassStylesOf } from "../theme/glassS
23
23
  import { mergeStyles } from "../theme/mergeComponents.js";
24
24
  import { useToolkitNavigation } from "../toolkit/toolkitContext.js";
25
25
  import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
26
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
26
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
27
27
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
28
28
  const THEME_NAME = "CalcitaMobileTabBar";
29
29
  const TabBarTab = piecePart(THEME_NAME, "Tab", ButtonBase);
@@ -155,7 +155,7 @@ function useFittingTabCount(capsule, minTabPixels) {
155
155
  }, [capsule, minTabPixels]);
156
156
  return tabCount;
157
157
  }
158
- function MobileTabBar(props) {
158
+ function MobileTabBarContent(props) {
159
159
  const { menuItems, activeItem, menuBadges, account, moreFooter, minimizeOnScroll = true, onPinnedTabsChange, ...unknownProps } = usePieceProps(props, THEME_NAME);
160
160
  warnUnknownProps(THEME_NAME, unknownProps);
161
161
  const { t } = useToolkitTranslation("layout");
@@ -355,6 +355,7 @@ function MobileTabBar(props) {
355
355
  )
356
356
  ] });
357
357
  }
358
+ const MobileTabBar = withPieceSlots(MobileTabBarContent, THEME_NAME);
358
359
  export {
359
360
  MobileTabBar as default
360
361
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MobileTabBar.js","sources":["../../src/appShell/MobileTabBar.jsx"],"sourcesContent":["// La barra de pestañas del teléfono con vidrio, como la de iOS 26: una cápsula de vidrio flotando abajo con las secciones\n// principales (mobileTabsOf: las que caben a lo ancho, y «Más» con el resto), y aparte, en su círculo de vidrio, la cuenta\n// (con todos los ajustes adentro). La reemplaza a la barra de abajo con ☰ y al cajón del menú (lo pidió el autor: «estilo\n// Apple pero con sus submenús de acciones»). También va con el minimalista cuando la barra va en cápsulas (usesMobileTabBar), sólida y\n// del gris de lo que flota (minimalFloatingStylesOf).\n//\n// - Una pestaña con submenú no navega: abre el menú de acciones de Apple arriba de ella (SubmenuActionsMenu).\n// - «Más» abre una hoja desde abajo con el resto del menú, por secciones (SideMenu, el mismo del escritorio). Arriba trae\n// «Editar la barra»: cada quien elige qué pantallas van abajo (TabBarEditor; se recuerda con usePinnedMobileTabs),\n// como pide la guía de Apple. Sin elegir, van las que marca el proyecto (mobileTab en menu.js).\n// - Cada pestaña lleva su badge como los de Apple (HIG «Tab bars»): ROJO con el número en blanco y solo para conteos (lo\n// pendiente, del servidor); un badge de texto («Nuevo») no va en la pestaña, se queda en el menú: Apple los reserva para\n// lo que pide atención.\n// - Cuántas pestañas van se mide (useFittingTabCount): las que caben con al menos MIN_TAB_PIXELS cada una; las demás van\n// a «Más». En una ventana angosta salen menos y en una ancha más, y los nombres no se cortan («Compone…»).\n// - Acostado (pantalla bajita), la barra va compacta: ícono y nombre lado a lado, para dejarle el alto al contenido.\n// - Al leer hacia abajo se encoge (como iOS 26): queda una cápsula chica con la pestaña donde está la persona, y la cuenta\n// más chica; al subir un poco, o al tocar la cápsula, regresa completa (cuándo: tabBarScroll.js). Se mueve solo con\n// opacidad y escala, lo que el navegador anima sin volver a acomodar la página: en un teléfono barato no se traba.\n// Solo se ve en el teléfono (PHONE_MEDIA_QUERY); en escritorio no ocupa nada.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaMobileTabBar con defaultProps y\n// styleOverrides de sus partes: tab, tabIconPlaceholder, tabLabel, root, bar, minimized, account, sheetHeader.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useLayoutEffect, useState} from 'react';\nimport Badge from '@mui/material/Badge';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Drawer from '@mui/material/Drawer';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\nimport MoreHorizRoundedIcon from '@mui/icons-material/MoreHorizRounded';\n\nimport {menuItemLabelOf, menuLinkPropsOf} from '@/appShell/menuItemText.js';\nimport {\n GLASS_PANEL_GAP_PIXELS, MOBILE_TAB_BAR_HEIGHT_PIXELS, PHONE_LANDSCAPE_MEDIA_QUERY, PHONE_MEDIA_QUERY,\n} from '@/appShell/shellSizes.js';\nimport SideMenu from '@/appShell/SideMenu.jsx';\nimport SubmenuActionsMenu, {SUBMENU_PLACEMENT} from '@/appShell/SubmenuActionsMenu.jsx';\nimport TabBarEditor from '@/appShell/TabBarEditor.jsx';\nimport {usePinnedMobileTabs} from '@/appShell/usePinnedMobileTabs.js';\nimport {useTabBarMinimized} from '@/appShell/useTabBarMinimized.js';\nimport {menuBadgeOf, menuItemKeyOf, mobileTabsOf} from '@/navigation/appMenu.js';\nimport {textSizeOf} from '@/theme/appleTracking.js';\nimport {minimalFloatingStylesOf} from '@/theme/components/minimalComponents.js';\nimport {accentTextStylesOf, glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {mergeStyles} from '@/theme/mergeComponents.js';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaMobileTabBar)\nconst THEME_NAME = 'CalcitaMobileTabBar';\nconst TabBarTab = piecePart(THEME_NAME, 'Tab', ButtonBase);\nconst TabBarTabIconPlaceholder = piecePart(THEME_NAME, 'TabIconPlaceholder', Box);\nconst TabBarTabLabel = piecePart(THEME_NAME, 'TabLabel', Typography);\nconst TabBarRoot = piecePart(THEME_NAME, 'Root', Box);\nconst TabBarBar = piecePart(THEME_NAME, 'Bar', Box);\nconst TabBarMinimized = piecePart(THEME_NAME, 'Minimized', ButtonBase);\nconst TabBarAccount = piecePart(THEME_NAME, 'Account', Box);\nconst TabBarSheetHeader = piecePart(THEME_NAME, 'SheetHeader', Box);\n\n// el nombre de la pestaña parado y acostado (px), lo ancho máximo de la cápsula y lo alto de la hoja de «Más»\nconst TAB_LABEL_PIXELS = Object.freeze({portrait: 10, landscape: 12});\nconst TAB_ICON_SIZE = '1.5rem';\nconst TAB_BAR_MAX_WIDTH_PIXELS = 560;\n// lo menos que mide una pestaña (px) para que su nombre se lea entero: parada, un nombre de unas 11 letras («Formularios»\n// pide 61 px, medido en Chrome); acostada, ícono y nombre lado a lado. Con menos, la pestaña se va a «Más»\nconst MIN_TAB_PIXELS = Object.freeze({portrait: 60, landscape: 104});\n// antes de medir (o si la barra no se ve): las de siempre, 4 y «Más»\nconst DEFAULT_TAB_COUNT = 5;\nconst MORE_SHEET_MAX_WIDTH_PIXELS = 640;\nconst MORE_SHEET_MAX_HEIGHT = '75vh';\nconst BADGE_MAX = 99;\n// la barra flota sobre el contenido: vidrio más opaco que el de los controles, una línea fina en la orilla y una sombra\n// debajo. Con el vidrio de siempre, en claro se perdía sobre las tarjetas blancas y no parecía flotar (lo reportaron)\nconst FLOATING_GLASS_OPACITY = 0.8;\nconst FLOATING_EDGE = Object.freeze({\n light: {outline: 'rgba(15, 23, 42, 0.12)', shadow: '0 10px 30px rgba(15, 23, 42, 0.20), 0 2px 6px rgba(15, 23, 42, 0.10)'},\n dark: {outline: 'rgba(255, 255, 255, 0.16)', shadow: '0 10px 30px rgba(0, 0, 0, 0.65), 0 2px 6px rgba(0, 0, 0, 0.4)'},\n});\n// la pestaña elegida: un tinte del acento (en claro una gota blanca sobre la cápsula blanca no se distinguía)\nconst ACTIVE_TINT_PERCENT = Object.freeze({light: 14, dark: 24});\n// encogida: lo alto de la cápsula chica (px) y a qué tamaño se va lo que desaparece\nconst MINIMIZED_PIXELS = Object.freeze({portrait: 48, landscape: 40});\nconst HIDDEN_SCALE = 0.6;\n\n/**\n * Lo que aparece o desaparece al encoger la barra: solo opacidad y escala. visibility espera a que termine la animación\n * para esconderlo, y así lo que ya no se ve tampoco se puede tocar.\n *\n * @param {object} theme\n * @param {boolean} isShown\n * @param {string} transformOrigin hacia dónde se encoge ('left bottom')\n * @returns {object}\n */\nfunction appearStylesOf(theme, isShown, transformOrigin) {\n const duration = theme.transitions.duration.short;\n return {\n transformOrigin,\n opacity: isShown ? 1 : 0,\n transform: isShown ? 'none' : `scale(${HIDDEN_SCALE})`,\n visibility: isShown ? 'visible' : 'hidden',\n transition: `${theme.transitions.create(['opacity', 'transform'], {duration})}, visibility 0s linear ${isShown ? 0 : duration}ms`,\n };\n}\n\n/**\n * La superficie de la barra y del círculo de la cuenta: vidrio más opaco, su línea fina y su sombra (la sombra va en una\n * capa detrás, ::before, para no pisar el filo de luz del vidrio, que también es una sombra). Con el minimalista, sólida.\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction floatingSurfaceOf(theme) {\n // con el minimalista (barra en cápsulas) la barra es sólida: su gris de lo que flota, sin línea ni sombra\n if (!isGlassTheme(theme)) {\n return {...minimalFloatingStylesOf(theme), position: 'relative', borderRadius: '999px', height: '100%'};\n }\n return {\n ...glassStylesOf(theme, {opacity: FLOATING_GLASS_OPACITY}),\n position: 'relative',\n borderRadius: '999px',\n height: '100%',\n outline: `1px solid ${FLOATING_EDGE.light.outline}`,\n '&::before': {\n content: '\"\"', position: 'absolute', inset: 0, borderRadius: 'inherit', zIndex: -1, pointerEvents: 'none',\n boxShadow: FLOATING_EDGE.light.shadow,\n },\n ...theme.applyStyles('dark', {\n outline: `1px solid ${FLOATING_EDGE.dark.outline}`,\n '&::before': {boxShadow: FLOATING_EDGE.dark.shadow},\n }),\n };\n}\n\n/**\n * La pestaña elegida: el tinte del acento y su letra legible.\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction activeTabOf(theme) {\n const primary = (theme.vars ?? theme).palette.primary.main;\n return mergeStyles({\n backgroundColor: `color-mix(in srgb, ${primary} ${ACTIVE_TINT_PERCENT.light}%, transparent)`,\n ...theme.applyStyles('dark', {backgroundColor: `color-mix(in srgb, ${primary} ${ACTIVE_TINT_PERCENT.dark}%, transparent)`}),\n }, accentTextStylesOf(theme));\n}\n\n/**\n * Una pestaña: liga a su pantalla o, con submenú, botón que abre el menú de acciones.\n *\n * @param {object} props\n * @param {string} props.label ya traducido\n * @param {import('react').ElementType} [props.Icon]\n * @param {boolean} props.isActive\n * @param {{content: number|string, isCount: boolean}|null} props.badge\n * @param {object} [props.linkProps] {component, to} si navega\n * @param {(event: object) => void} [props.onClick]\n * @param {boolean} [props.hasPopup] abre un menú\n */\nfunction TabButton({label, Icon, isActive, badge, linkProps = {}, onClick, hasPopup = false}) {\n return (\n <TabBarTab {...linkProps} onClick={onClick} aria-haspopup={hasPopup ? 'menu' : undefined} aria-current={isActive ? 'page' : undefined}\n ownSx={(theme) => mergeStyles({\n flex: '1 1 0', minWidth: 0, height: '100%', borderRadius: '999px', px: 0,\n display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 0.25,\n color: 'text.primary',\n transition: theme.transitions.create(['background-color', 'color'], {duration: theme.transitions.duration.shortest}),\n [PHONE_LANDSCAPE_MEDIA_QUERY]: {flexDirection: 'row', gap: 0.75},\n }, isActive ? activeTabOf(theme) : {})}>\n <Badge invisible={!badge?.isCount} color=\"error\" max={BADGE_MAX} overlap=\"circular\" badgeContent={badge?.isCount ? badge.content : undefined}>\n {Icon ? <Icon sx={{fontSize: TAB_ICON_SIZE}} /> : <TabBarTabIconPlaceholder ownSx={{width: TAB_ICON_SIZE, height: TAB_ICON_SIZE}} />}\n </Badge>\n <TabBarTabLabel component=\"span\" noWrap\n ownSx={{...textSizeOf(TAB_LABEL_PIXELS.portrait), fontWeight: 500, maxWidth: '100%',\n [PHONE_LANDSCAPE_MEDIA_QUERY]: textSizeOf(TAB_LABEL_PIXELS.landscape)}}>\n {label}\n </TabBarTabLabel>\n </TabBarTab>\n );\n}\n\n/**\n * Cuántas pestañas caben en la cápsula (contando «Más»). Se mide la cápsula, que no cambia de ancho con sus pestañas (se\n * estira hasta su tope), así que la cuenta no da vueltas. Se vuelve a medir al girar el teléfono o cambiar la ventana.\n *\n * @param {HTMLElement|null} capsule\n * @param {number} minTabPixels lo menos que mide una pestaña\n * @returns {number}\n */\nfunction useFittingTabCount(capsule, minTabPixels) {\n const [tabCount, setTabCount] = useState(DEFAULT_TAB_COUNT);\n // antes de pintar: así no se ve un momento con las pestañas apretadas\n useLayoutEffect(() => {\n if (!capsule) {\n return undefined;\n }\n const measure = () => {\n const style = window.getComputedStyle(capsule);\n const innerWidth = capsule.clientWidth - Number.parseFloat(style.paddingLeft) - Number.parseFloat(style.paddingRight);\n // en escritorio la barra no se ve (ancho 0): se quedan las de siempre\n if (innerWidth > 0) {\n setTabCount(Math.max(2, Math.floor(innerWidth / minTabPixels)));\n }\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(capsule);\n return () => observer.disconnect();\n }, [capsule, minTabPixels]);\n return tabCount;\n}\n\n/**\n * @param {object} props\n * @param {object[]} props.menuItems lo que regresa composeMenu\n * @param {object|null} props.activeItem la entrada de la pantalla abierta\n * @param {Record<string, number>} [props.menuBadges] los conteos del servidor por badgeKey\n * @param {import('react').ReactNode} [props.account] la cuenta (o el engrane), en su círculo junto a la barra\n * @param {import('react').ReactNode} [props.moreFooter] lo que va al final de la hoja de «Más» (la tarjeta del menú lateral)\n * @param {boolean} [props.minimizeOnScroll] se encoge al leer hacia abajo; por omisión sí\n * @param {(keys: string[]|null) => void} [props.onPinnedTabsChange] la persona eligió sus pestañas (null: regresó a las de\n * omisión)\n */\nexport default function MobileTabBar(props) {\n // lo que el proyecto puso en su tema (components.CalcitaMobileTabBar.defaultProps) y encima lo que llega aquí\n const {menuItems, activeItem, menuBadges, account, moreFooter, minimizeOnScroll = true, onPinnedTabsChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout');\n const {Link: RouterLink} = useToolkitNavigation();\n const {pinnedKeys, setPinnedKeys} = usePinnedMobileTabs();\n const [tabsCapsule, setTabsCapsule] = useState(null);\n const isLandscape = useMediaQuery(PHONE_LANDSCAPE_MEDIA_QUERY);\n const tabCount = useFittingTabCount(tabsCapsule, isLandscape ? MIN_TAB_PIXELS.landscape : MIN_TAB_PIXELS.portrait);\n const {tabs, more} = mobileTabsOf(menuItems, pinnedKeys, tabCount);\n const [submenu, setSubmenu] = useState({anchorElement: null, menuItem: null});\n const [isMoreOpen, setIsMoreOpen] = useState(false);\n const [isEditingTabs, setIsEditingTabs] = useState(false);\n // al salir del editor su botón desaparece con el foco adentro: el foco regresa a «Editar la barra» (sin eso se perdía\n // y Escape ya no cerraba la hoja; también lo necesita quien usa lector de pantalla)\n const [returnsFromEditor, setReturnsFromEditor] = useState(false);\n const leaveEditor = () => {\n setIsEditingTabs(false);\n setReturnsFromEditor(true);\n };\n const closeMore = () => {\n setIsMoreOpen(false);\n setIsEditingTabs(false);\n setReturnsFromEditor(false);\n };\n const {isMinimized, expand} = useTabBarMinimized(minimizeOnScroll);\n const closeSubmenu = () => setSubmenu({anchorElement: null, menuItem: null});\n const isInside = (menuItem) => menuItem === activeItem || (menuItem.children ?? []).includes(activeItem);\n const moreHasActive = more.some(isInside);\n // la cápsula chica enseña dónde está la persona: su pestaña, «Más» si está en algo de ahí, o la primera\n const activeTab = tabs.find(isInside);\n const MinimizedIcon = (!activeTab && moreHasActive ? MoreHorizRoundedIcon : (activeTab ?? tabs[0])?.Icon) ?? MoreHorizRoundedIcon;\n // «Más» suma los conteos de lo que guarda (solo conteos: los de texto no van en la pestaña)\n const moreCount = more.reduce((total, menuItem) => {\n const badge = menuBadgeOf(menuItem, menuBadges);\n return total + (badge?.isCount ? badge.content : 0);\n }, 0);\n const moreBadge = moreCount > 0 ? {content: moreCount, isCount: true} : null;\n\n const glassSurfaceSx = floatingSurfaceOf;\n\n return (\n <>\n <TabBarRoot component=\"nav\" aria-label={t('drawer.ariaLabel')}\n ownSx={(theme) => ({\n display: 'none',\n [PHONE_MEDIA_QUERY]: {display: 'flex'},\n position: 'fixed', zIndex: theme.zIndex.appBar, gap: 0.75, justifyContent: 'center',\n left: GLASS_PANEL_GAP_PIXELS, right: GLASS_PANEL_GAP_PIXELS,\n bottom: `calc(${GLASS_PANEL_GAP_PIXELS}px + env(safe-area-inset-bottom))`,\n height: MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait,\n [PHONE_LANDSCAPE_MEDIA_QUERY]: {height: MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape},\n })}>\n <TabBarBar ref={setTabsCapsule} inert={isMinimized}\n ownSx={(theme) => ({...glassSurfaceSx(theme), display: 'flex', flex: 1, maxWidth: TAB_BAR_MAX_WIDTH_PIXELS, p: 0.375,\n ...appearStylesOf(theme, !isMinimized, 'left bottom')})}>\n {tabs.map((menuItem) => {\n const hasChildren = (menuItem.children ?? []).length > 0;\n return (\n <TabButton key={menuItem.to ?? menuItem.href ?? menuItemLabelOf(menuItem, t)} label={menuItemLabelOf(menuItem, t)} Icon={menuItem.Icon}\n isActive={isInside(menuItem)} badge={menuBadgeOf(menuItem, menuBadges)} hasPopup={hasChildren}\n linkProps={hasChildren ? {} : menuLinkPropsOf(menuItem, RouterLink)}\n onClick={hasChildren ? (event) => setSubmenu({anchorElement: event.currentTarget, menuItem}) : undefined} />\n );\n })}\n {more.length > 0 && (\n <TabButton label={t('drawer.more')} Icon={MoreHorizRoundedIcon} isActive={moreHasActive} badge={moreBadge} hasPopup\n onClick={() => setIsMoreOpen(true)} />\n )}\n </TabBarBar>\n {/* encogida: la cápsula chica en la esquina, con la pestaña de ahorita; tocarla regresa la barra completa */}\n <TabBarMinimized inert={!isMinimized} onClick={expand} aria-label={t('drawer.showTabs')} aria-expanded={false}\n ownSx={(theme) => mergeStyles({\n ...glassSurfaceSx(theme), position: 'absolute', left: 0, bottom: 0,\n width: MINIMIZED_PIXELS.portrait, height: MINIMIZED_PIXELS.portrait,\n [PHONE_LANDSCAPE_MEDIA_QUERY]: {width: MINIMIZED_PIXELS.landscape, height: MINIMIZED_PIXELS.landscape},\n ...appearStylesOf(theme, isMinimized, 'left bottom'),\n }, accentTextStylesOf(theme))}>\n <MinimizedIcon sx={{fontSize: TAB_ICON_SIZE}} />\n </TabBarMinimized>\n {account && (\n <TabBarAccount ownSx={(theme) => ({\n ...glassSurfaceSx(theme), flexShrink: 0, minWidth: MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait, px: 0.5, display: 'flex', alignItems: 'center',\n justifyContent: 'center', [PHONE_LANDSCAPE_MEDIA_QUERY]: {minWidth: MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape},\n '& .MuiButtonBase-root': {color: 'inherit'},\n // encogida, la cuenta se queda pero del alto de la cápsula chica, pegada a su esquina\n transformOrigin: 'right bottom',\n transform: isMinimized ? `scale(${MINIMIZED_PIXELS.portrait / MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait})` : 'none',\n transition: theme.transitions.create('transform', {duration: theme.transitions.duration.short}),\n ...(isMinimized && {[PHONE_LANDSCAPE_MEDIA_QUERY]: {\n minWidth: MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape,\n transform: `scale(${MINIMIZED_PIXELS.landscape / MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape})`,\n }}),\n })}>\n {account}\n </TabBarAccount>\n )}\n </TabBarRoot>\n\n {submenu.menuItem && (\n <SubmenuActionsMenu anchorElement={submenu.anchorElement} onClose={closeSubmenu} menuItem={submenu.menuItem} activeItem={activeItem}\n menuBadges={menuBadges} placement={SUBMENU_PLACEMENT.above} />\n )}\n\n {/* «Más»: el resto del menú en una hoja desde abajo, separada de las orillas como las hojas de iOS */}\n <Drawer anchor=\"bottom\" open={isMoreOpen} onClose={closeMore}\n slotProps={{paper: {sx: {\n m: `${GLASS_PANEL_GAP_PIXELS}px auto calc(${GLASS_PANEL_GAP_PIXELS}px + env(safe-area-inset-bottom))`,\n width: `min(${MORE_SHEET_MAX_WIDTH_PIXELS}px, calc(100% - ${GLASS_PANEL_GAP_PIXELS * 2}px))`,\n maxHeight: MORE_SHEET_MAX_HEIGHT, borderRadius: '20px', overflow: 'hidden',\n }}}}>\n {isEditingTabs ? (\n <TabBarEditor menuItems={menuItems} pinnedKeys={tabs.map(menuItemKeyOf)}\n onDone={(keys) => {\n setPinnedKeys(keys);\n onPinnedTabsChange?.(keys);\n leaveEditor();\n }}\n onReset={() => {\n setPinnedKeys(null);\n onPinnedTabsChange?.(null);\n leaveEditor();\n }} />\n ) : (\n <>\n <TabBarSheetHeader ownSx={{display: 'flex', justifyContent: 'flex-end', px: 1.5, pt: 1, flexShrink: 0}}>\n <Button size=\"small\" autoFocus={returnsFromEditor} onClick={() => setIsEditingTabs(true)}>{t('drawer.editTabs')}</Button>\n </TabBarSheetHeader>\n <SideMenu menuItems={more} activeItem={activeItem} menuBadges={menuBadges} collapsed={false} showBrand={false} footer={moreFooter}\n onNavigate={closeMore} />\n </>\n )}\n </Drawer>\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,MAAM,aAAa;AACnB,MAAM,YAAY,UAAU,YAAY,OAAO,UAAU;AACzD,MAAM,2BAA2B,UAAU,YAAY,sBAAsB,GAAG;AAChF,MAAM,iBAAiB,UAAU,YAAY,YAAY,UAAU;AACnE,MAAM,aAAa,UAAU,YAAY,QAAQ,GAAG;AACpD,MAAM,YAAY,UAAU,YAAY,OAAO,GAAG;AAClD,MAAM,kBAAkB,UAAU,YAAY,aAAa,UAAU;AACrE,MAAM,gBAAgB,UAAU,YAAY,WAAW,GAAG;AAC1D,MAAM,oBAAoB,UAAU,YAAY,eAAe,GAAG;AAGlE,MAAM,mBAAmB,OAAO,OAAO,EAAC,UAAU,IAAI,WAAW,IAAG;AACpE,MAAM,gBAAgB;AACtB,MAAM,2BAA2B;AAGjC,MAAM,iBAAiB,OAAO,OAAO,EAAC,UAAU,IAAI,WAAW,KAAI;AAEnE,MAAM,oBAAoB;AAC1B,MAAM,8BAA8B;AACpC,MAAM,wBAAwB;AAC9B,MAAM,YAAY;AAGlB,MAAM,yBAAyB;AAC/B,MAAM,gBAAgB,OAAO,OAAO;AAAA,EAChC,OAAO,EAAC,SAAS,0BAA0B,QAAQ,uEAAA;AAAA,EACnD,MAAM,EAAC,SAAS,6BAA6B,QAAQ,gEAAA;AACzD,CAAC;AAED,MAAM,sBAAsB,OAAO,OAAO,EAAC,OAAO,IAAI,MAAM,IAAG;AAE/D,MAAM,mBAAmB,OAAO,OAAO,EAAC,UAAU,IAAI,WAAW,IAAG;AACpE,MAAM,eAAe;AAWrB,SAAS,eAAe,OAAO,SAAS,iBAAiB;AACrD,QAAM,WAAW,MAAM,YAAY,SAAS;AAC5C,SAAO;AAAA,IACH;AAAA,IACA,SAAS,UAAU,IAAI;AAAA,IACvB,WAAW,UAAU,SAAS,SAAS,YAAY;AAAA,IACnD,YAAY,UAAU,YAAY;AAAA,IAClC,YAAY,GAAG,MAAM,YAAY,OAAO,CAAC,WAAW,WAAW,GAAG,EAAC,UAAS,CAAC,0BAA0B,UAAU,IAAI,QAAQ;AAAA,EAAA;AAErI;AASA,SAAS,kBAAkB,OAAO;AAE9B,MAAI,CAAC,aAAa,KAAK,GAAG;AACtB,WAAO,EAAC,GAAG,wBAAwB,KAAK,GAAG,UAAU,YAAY,cAAc,SAAS,QAAQ,OAAA;AAAA,EACpG;AACA,SAAO;AAAA,IACH,GAAG,cAAc,OAAO,EAAC,SAAS,wBAAuB;AAAA,IACzD,UAAU;AAAA,IACV,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS,aAAa,cAAc,MAAM,OAAO;AAAA,IACjD,aAAa;AAAA,MACT,SAAS;AAAA,MAAM,UAAU;AAAA,MAAY,OAAO;AAAA,MAAG,cAAc;AAAA,MAAW,QAAQ;AAAA,MAAI,eAAe;AAAA,MACnG,WAAW,cAAc,MAAM;AAAA,IAAA;AAAA,IAEnC,GAAG,MAAM,YAAY,QAAQ;AAAA,MACzB,SAAS,aAAa,cAAc,KAAK,OAAO;AAAA,MAChD,aAAa,EAAC,WAAW,cAAc,KAAK,OAAA;AAAA,IAAM,CACrD;AAAA,EAAA;AAET;AAQA,SAAS,YAAY,OAAO;AACxB,QAAM,WAAW,MAAM,QAAQ,OAAO,QAAQ,QAAQ;AACtD,SAAO,YAAY;AAAA,IACf,iBAAiB,sBAAsB,OAAO,IAAI,oBAAoB,KAAK;AAAA,IAC3E,GAAG,MAAM,YAAY,QAAQ,EAAC,iBAAiB,sBAAsB,OAAO,IAAI,oBAAoB,IAAI,kBAAA,CAAkB;AAAA,EAAA,GAC3H,mBAAmB,KAAK,CAAC;AAChC;AAcA,SAAS,UAAU,EAAC,OAAO,MAAM,UAAU,OAAO,YAAY,IAAI,SAAS,WAAW,MAAA,GAAQ;AAC1F,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAW,GAAG;AAAA,MAAW;AAAA,MAAkB,iBAAe,WAAW,SAAS;AAAA,MAAW,gBAAc,WAAW,SAAS;AAAA,MAChH,OAAO,CAAC,UAAU,YAAY;AAAA,QAC1B,MAAM;AAAA,QAAS,UAAU;AAAA,QAAG,QAAQ;AAAA,QAAQ,cAAc;AAAA,QAAS,IAAI;AAAA,QACvE,SAAS;AAAA,QAAQ,eAAe;AAAA,QAAU,YAAY;AAAA,QAAU,gBAAgB;AAAA,QAAU,KAAK;AAAA,QAC/F,OAAO;AAAA,QACP,YAAY,MAAM,YAAY,OAAO,CAAC,oBAAoB,OAAO,GAAG,EAAC,UAAU,MAAM,YAAY,SAAS,UAAS;AAAA,QACnH,CAAC,2BAA2B,GAAG,EAAC,eAAe,OAAO,KAAK,KAAA;AAAA,MAAI,GAChE,WAAW,YAAY,KAAK,IAAI,CAAA,CAAE;AAAA,MAC7C,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAM,WAAW,CAAC,OAAO,SAAS,OAAM,SAAQ,KAAK,WAAW,SAAQ,YAAW,cAAc,OAAO,UAAU,MAAM,UAAU,QAC9H,UAAA,OAAO,oBAAC,QAAK,IAAI,EAAC,UAAU,cAAA,GAAgB,IAAK,oBAAC,0BAAA,EAAyB,OAAO,EAAC,OAAO,eAAe,QAAQ,cAAA,GAAgB,GACtI;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YAAe,WAAU;AAAA,YAAO,QAAM;AAAA,YAC3B,OAAO;AAAA,cAAC,GAAG,WAAW,iBAAiB,QAAQ;AAAA,cAAG,YAAY;AAAA,cAAK,UAAU;AAAA,cACxE,CAAC,2BAA2B,GAAG,WAAW,iBAAiB,SAAS;AAAA,YAAA;AAAA,YAChF,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACL;AAAA,IAAA;AAAA,EAAA;AAGZ;AAUA,SAAS,mBAAmB,SAAS,cAAc;AAC/C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,iBAAiB;AAE1D,kBAAgB,MAAM;AAClB,QAAI,CAAC,SAAS;AACV,aAAO;AAAA,IACX;AACA,UAAM,UAAU,MAAM;AAClB,YAAM,QAAQ,OAAO,iBAAiB,OAAO;AAC7C,YAAM,aAAa,QAAQ,cAAc,OAAO,WAAW,MAAM,WAAW,IAAI,OAAO,WAAW,MAAM,YAAY;AAEpH,UAAI,aAAa,GAAG;AAChB,oBAAY,KAAK,IAAI,GAAG,KAAK,MAAM,aAAa,YAAY,CAAC,CAAC;AAAA,MAClE;AAAA,IACJ;AACA,YAAA;AACA,UAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,aAAS,QAAQ,OAAO;AACxB,WAAO,MAAM,SAAS,WAAA;AAAA,EAC1B,GAAG,CAAC,SAAS,YAAY,CAAC;AAC1B,SAAO;AACX;AAaA,SAAwB,aAAa,OAAO;AAExC,QAAM,EAAC,WAAW,YAAY,YAAY,SAAS,YAAY,mBAAmB,MAAM,oBAAoB,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC9J,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,QAAQ;AAC1C,QAAM,EAAC,MAAM,WAAA,IAAc,qBAAA;AAC3B,QAAM,EAAC,YAAY,cAAA,IAAiB,oBAAA;AACpC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,IAAI;AACnD,QAAM,cAAc,cAAc,2BAA2B;AAC7D,QAAM,WAAW,mBAAmB,aAAa,cAAc,eAAe,YAAY,eAAe,QAAQ;AACjH,QAAM,EAAC,MAAM,KAAA,IAAQ,aAAa,WAAW,YAAY,QAAQ;AACjE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,EAAC,eAAe,MAAM,UAAU,MAAK;AAC5E,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AAGxD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAS,KAAK;AAChE,QAAM,cAAc,MAAM;AACtB,qBAAiB,KAAK;AACtB,yBAAqB,IAAI;AAAA,EAC7B;AACA,QAAM,YAAY,MAAM;AACpB,kBAAc,KAAK;AACnB,qBAAiB,KAAK;AACtB,yBAAqB,KAAK;AAAA,EAC9B;AACA,QAAM,EAAC,aAAa,WAAU,mBAAmB,gBAAgB;AACjE,QAAM,eAAe,MAAM,WAAW,EAAC,eAAe,MAAM,UAAU,MAAK;AAC3E,QAAM,WAAW,CAAC,aAAa,aAAa,eAAe,SAAS,YAAY,CAAA,GAAI,SAAS,UAAU;AACvG,QAAM,gBAAgB,KAAK,KAAK,QAAQ;AAExC,QAAM,YAAY,KAAK,KAAK,QAAQ;AACpC,QAAM,iBAAiB,CAAC,aAAa,gBAAgB,wBAAwB,aAAa,KAAK,CAAC,IAAI,SAAS;AAE7G,QAAM,YAAY,KAAK,OAAO,CAAC,OAAO,aAAa;AAC/C,UAAM,QAAQ,YAAY,UAAU,UAAU;AAC9C,WAAO,SAAS,OAAO,UAAU,MAAM,UAAU;AAAA,EACrD,GAAG,CAAC;AACJ,QAAM,YAAY,YAAY,IAAI,EAAC,SAAS,WAAW,SAAS,SAAQ;AAExE,QAAM,iBAAiB;AAEvB,SACI,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAW,WAAU;AAAA,QAAM,cAAY,EAAE,kBAAkB;AAAA,QACvD,OAAO,CAAC,WAAW;AAAA,UACf,SAAS;AAAA,UACT,CAAC,iBAAiB,GAAG,EAAC,SAAS,OAAA;AAAA,UAC/B,UAAU;AAAA,UAAS,QAAQ,MAAM,OAAO;AAAA,UAAQ,KAAK;AAAA,UAAM,gBAAgB;AAAA,UAC3E,MAAM;AAAA,UAAwB,OAAO;AAAA,UACrC,QAAQ,QAAQ,sBAAsB;AAAA,UACtC,QAAQ,6BAA6B;AAAA,UACrC,CAAC,2BAA2B,GAAG,EAAC,QAAQ,6BAA6B,UAAA;AAAA,QAAS;AAAA,QAEnF,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cAAU,KAAK;AAAA,cAAgB,OAAO;AAAA,cAClC,OAAO,CAAC,WAAW;AAAA,gBAAC,GAAG,eAAe,KAAK;AAAA,gBAAG,SAAS;AAAA,gBAAQ,MAAM;AAAA,gBAAG,UAAU;AAAA,gBAA0B,GAAG;AAAA,gBAC9F,GAAG,eAAe,OAAO,CAAC,aAAa,aAAa;AAAA,cAAA;AAAA,cACrE,UAAA;AAAA,gBAAA,KAAK,IAAI,CAAC,aAAa;AACpB,wBAAM,eAAe,SAAS,YAAY,CAAA,GAAI,SAAS;AACvD,yBACI;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBAA6E,OAAO,gBAAgB,UAAU,CAAC;AAAA,sBAAG,MAAM,SAAS;AAAA,sBACvH,UAAU,SAAS,QAAQ;AAAA,sBAAG,OAAO,YAAY,UAAU,UAAU;AAAA,sBAAG,UAAU;AAAA,sBAClF,WAAW,cAAc,CAAA,IAAK,gBAAgB,UAAU,UAAU;AAAA,sBAClE,SAAS,cAAc,CAAC,UAAU,WAAW,EAAC,eAAe,MAAM,eAAe,SAAA,CAAS,IAAI;AAAA,oBAAA;AAAA,oBAH1F,SAAS,MAAM,SAAS,QAAQ,gBAAgB,UAAU,CAAC;AAAA,kBAAA;AAAA,gBAKnF,CAAC;AAAA,gBACA,KAAK,SAAS,KACX;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBAAU,OAAO,EAAE,aAAa;AAAA,oBAAG,MAAM;AAAA,oBAAsB,UAAU;AAAA,oBAAe,OAAO;AAAA,oBAAW,UAAQ;AAAA,oBACxG,SAAS,MAAM,cAAc,IAAI;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAG;AAAA,YAAA;AAAA,UAAA;AAAA,UAIvD;AAAA,YAAC;AAAA,YAAA;AAAA,cAAgB,OAAO,CAAC;AAAA,cAAa,SAAS;AAAA,cAAQ,cAAY,EAAE,iBAAiB;AAAA,cAAG,iBAAe;AAAA,cAC5F,OAAO,CAAC,UAAU,YAAY;AAAA,gBAC1B,GAAG,eAAe,KAAK;AAAA,gBAAG,UAAU;AAAA,gBAAY,MAAM;AAAA,gBAAG,QAAQ;AAAA,gBACjE,OAAO,iBAAiB;AAAA,gBAAU,QAAQ,iBAAiB;AAAA,gBAC3D,CAAC,2BAA2B,GAAG,EAAC,OAAO,iBAAiB,WAAW,QAAQ,iBAAiB,UAAA;AAAA,gBAC5F,GAAG,eAAe,OAAO,aAAa,aAAa;AAAA,cAAA,GACpD,mBAAmB,KAAK,CAAC;AAAA,cACpC,8BAAC,eAAA,EAAc,IAAI,EAAC,UAAU,gBAAa,CAAG;AAAA,YAAA;AAAA,UAAA;AAAA,UAEjD,WACG,oBAAC,eAAA,EAAc,OAAO,CAAC,WAAW;AAAA,YAC9B,GAAG,eAAe,KAAK;AAAA,YAAG,YAAY;AAAA,YAAG,UAAU,6BAA6B;AAAA,YAAU,IAAI;AAAA,YAAK,SAAS;AAAA,YAAQ,YAAY;AAAA,YAChI,gBAAgB;AAAA,YAAU,CAAC,2BAA2B,GAAG,EAAC,UAAU,6BAA6B,UAAA;AAAA,YACjG,yBAAyB,EAAC,OAAO,UAAA;AAAA;AAAA,YAEjC,iBAAiB;AAAA,YACjB,WAAW,cAAc,SAAS,iBAAiB,WAAW,6BAA6B,QAAQ,MAAM;AAAA,YACzG,YAAY,MAAM,YAAY,OAAO,aAAa,EAAC,UAAU,MAAM,YAAY,SAAS,MAAA,CAAM;AAAA,YAC9F,GAAI,eAAe,EAAC,CAAC,2BAA2B,GAAG;AAAA,cAC/C,UAAU,6BAA6B;AAAA,cACvC,WAAW,SAAS,iBAAiB,YAAY,6BAA6B,SAAS;AAAA,YAAA,EAC3F;AAAA,UAAC,IAEA,UAAA,QAAA,CACL;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIP,QAAQ,YACL;AAAA,MAAC;AAAA,MAAA;AAAA,QAAmB,eAAe,QAAQ;AAAA,QAAe,SAAS;AAAA,QAAc,UAAU,QAAQ;AAAA,QAAU;AAAA,QACzF;AAAA,QAAwB,WAAW,kBAAkB;AAAA,MAAA;AAAA,IAAA;AAAA,IAI7E;AAAA,MAAC;AAAA,MAAA;AAAA,QAAO,QAAO;AAAA,QAAS,MAAM;AAAA,QAAY,SAAS;AAAA,QAC3C,WAAW,EAAC,OAAO,EAAC,IAAI;AAAA,UACpB,GAAG,GAAG,sBAAsB,gBAAgB,sBAAsB;AAAA,UAClE,OAAO,OAAO,2BAA2B,mBAAmB,yBAAyB,CAAC;AAAA,UACtF,WAAW;AAAA,UAAuB,cAAc;AAAA,UAAQ,UAAU;AAAA,QAAA,IACrE;AAAA,QACJ,UAAA,gBACG;AAAA,UAAC;AAAA,UAAA;AAAA,YAAa;AAAA,YAAsB,YAAY,KAAK,IAAI,aAAa;AAAA,YACxD,QAAQ,CAAC,SAAS;AACd,4BAAc,IAAI;AAClB,mCAAqB,IAAI;AACzB,0BAAA;AAAA,YACJ;AAAA,YACA,SAAS,MAAM;AACX,4BAAc,IAAI;AAClB,mCAAqB,IAAI;AACzB,0BAAA;AAAA,YACJ;AAAA,UAAA;AAAA,QAAA,IAEd,qBAAA,UAAA,EACI,UAAA;AAAA,UAAA,oBAAC,mBAAA,EAAkB,OAAO,EAAC,SAAS,QAAQ,gBAAgB,YAAY,IAAI,KAAK,IAAI,GAAG,YAAY,EAAA,GAChG,UAAA,oBAAC,QAAA,EAAO,MAAK,SAAQ,WAAW,mBAAmB,SAAS,MAAM,iBAAiB,IAAI,GAAI,UAAA,EAAE,iBAAiB,EAAA,CAAE,GACpH;AAAA,UACA;AAAA,YAAC;AAAA,YAAA;AAAA,cAAS,WAAW;AAAA,cAAM;AAAA,cAAwB;AAAA,cAAwB,WAAW;AAAA,cAAO,WAAW;AAAA,cAAO,QAAQ;AAAA,cAC7G,YAAY;AAAA,YAAA;AAAA,UAAA;AAAA,QAAW,EAAA,CACrC;AAAA,MAAA;AAAA,IAAA;AAAA,EAER,GACJ;AAER;"}
1
+ {"version":3,"file":"MobileTabBar.js","sources":["../../src/appShell/MobileTabBar.jsx"],"sourcesContent":["// La barra de pestañas del teléfono con vidrio, como la de iOS 26: una cápsula de vidrio flotando abajo con las secciones\n// principales (mobileTabsOf: las que caben a lo ancho, y «Más» con el resto), y aparte, en su círculo de vidrio, la cuenta\n// (con todos los ajustes adentro). La reemplaza a la barra de abajo con ☰ y al cajón del menú (lo pidió el autor: «estilo\n// Apple pero con sus submenús de acciones»). También va con el minimalista cuando la barra va en cápsulas (usesMobileTabBar), sólida y\n// del gris de lo que flota (minimalFloatingStylesOf).\n//\n// - Una pestaña con submenú no navega: abre el menú de acciones de Apple arriba de ella (SubmenuActionsMenu).\n// - «Más» abre una hoja desde abajo con el resto del menú, por secciones (SideMenu, el mismo del escritorio). Arriba trae\n// «Editar la barra»: cada quien elige qué pantallas van abajo (TabBarEditor; se recuerda con usePinnedMobileTabs),\n// como pide la guía de Apple. Sin elegir, van las que marca el proyecto (mobileTab en menu.js).\n// - Cada pestaña lleva su badge como los de Apple (HIG «Tab bars»): ROJO con el número en blanco y solo para conteos (lo\n// pendiente, del servidor); un badge de texto («Nuevo») no va en la pestaña, se queda en el menú: Apple los reserva para\n// lo que pide atención.\n// - Cuántas pestañas van se mide (useFittingTabCount): las que caben con al menos MIN_TAB_PIXELS cada una; las demás van\n// a «Más». En una ventana angosta salen menos y en una ancha más, y los nombres no se cortan («Compone…»).\n// - Acostado (pantalla bajita), la barra va compacta: ícono y nombre lado a lado, para dejarle el alto al contenido.\n// - Al leer hacia abajo se encoge (como iOS 26): queda una cápsula chica con la pestaña donde está la persona, y la cuenta\n// más chica; al subir un poco, o al tocar la cápsula, regresa completa (cuándo: tabBarScroll.js). Se mueve solo con\n// opacidad y escala, lo que el navegador anima sin volver a acomodar la página: en un teléfono barato no se traba.\n// Solo se ve en el teléfono (PHONE_MEDIA_QUERY); en escritorio no ocupa nada.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaMobileTabBar con defaultProps y\n// styleOverrides de sus partes: tab, tabIconPlaceholder, tabLabel, root, bar, minimized, account, sheetHeader.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useLayoutEffect, useState} from 'react';\nimport Badge from '@mui/material/Badge';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Drawer from '@mui/material/Drawer';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\nimport MoreHorizRoundedIcon from '@mui/icons-material/MoreHorizRounded';\n\nimport {menuItemLabelOf, menuLinkPropsOf} from '@/appShell/menuItemText.js';\nimport {\n GLASS_PANEL_GAP_PIXELS, MOBILE_TAB_BAR_HEIGHT_PIXELS, PHONE_LANDSCAPE_MEDIA_QUERY, PHONE_MEDIA_QUERY,\n} from '@/appShell/shellSizes.js';\nimport SideMenu from '@/appShell/SideMenu.jsx';\nimport SubmenuActionsMenu, {SUBMENU_PLACEMENT} from '@/appShell/SubmenuActionsMenu.jsx';\nimport TabBarEditor from '@/appShell/TabBarEditor.jsx';\nimport {usePinnedMobileTabs} from '@/appShell/usePinnedMobileTabs.js';\nimport {useTabBarMinimized} from '@/appShell/useTabBarMinimized.js';\nimport {menuBadgeOf, menuItemKeyOf, mobileTabsOf} from '@/navigation/appMenu.js';\nimport {textSizeOf} from '@/theme/appleTracking.js';\nimport {minimalFloatingStylesOf} from '@/theme/components/minimalComponents.js';\nimport {accentTextStylesOf, glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {mergeStyles} from '@/theme/mergeComponents.js';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaMobileTabBar)\nconst THEME_NAME = 'CalcitaMobileTabBar';\nconst TabBarTab = piecePart(THEME_NAME, 'Tab', ButtonBase);\nconst TabBarTabIconPlaceholder = piecePart(THEME_NAME, 'TabIconPlaceholder', Box);\nconst TabBarTabLabel = piecePart(THEME_NAME, 'TabLabel', Typography);\nconst TabBarRoot = piecePart(THEME_NAME, 'Root', Box);\nconst TabBarBar = piecePart(THEME_NAME, 'Bar', Box);\nconst TabBarMinimized = piecePart(THEME_NAME, 'Minimized', ButtonBase);\nconst TabBarAccount = piecePart(THEME_NAME, 'Account', Box);\nconst TabBarSheetHeader = piecePart(THEME_NAME, 'SheetHeader', Box);\n\n// el nombre de la pestaña parado y acostado (px), lo ancho máximo de la cápsula y lo alto de la hoja de «Más»\nconst TAB_LABEL_PIXELS = Object.freeze({portrait: 10, landscape: 12});\nconst TAB_ICON_SIZE = '1.5rem';\nconst TAB_BAR_MAX_WIDTH_PIXELS = 560;\n// lo menos que mide una pestaña (px) para que su nombre se lea entero: parada, un nombre de unas 11 letras («Formularios»\n// pide 61 px, medido en Chrome); acostada, ícono y nombre lado a lado. Con menos, la pestaña se va a «Más»\nconst MIN_TAB_PIXELS = Object.freeze({portrait: 60, landscape: 104});\n// antes de medir (o si la barra no se ve): las de siempre, 4 y «Más»\nconst DEFAULT_TAB_COUNT = 5;\nconst MORE_SHEET_MAX_WIDTH_PIXELS = 640;\nconst MORE_SHEET_MAX_HEIGHT = '75vh';\nconst BADGE_MAX = 99;\n// la barra flota sobre el contenido: vidrio más opaco que el de los controles, una línea fina en la orilla y una sombra\n// debajo. Con el vidrio de siempre, en claro se perdía sobre las tarjetas blancas y no parecía flotar (lo reportaron)\nconst FLOATING_GLASS_OPACITY = 0.8;\nconst FLOATING_EDGE = Object.freeze({\n light: {outline: 'rgba(15, 23, 42, 0.12)', shadow: '0 10px 30px rgba(15, 23, 42, 0.20), 0 2px 6px rgba(15, 23, 42, 0.10)'},\n dark: {outline: 'rgba(255, 255, 255, 0.16)', shadow: '0 10px 30px rgba(0, 0, 0, 0.65), 0 2px 6px rgba(0, 0, 0, 0.4)'},\n});\n// la pestaña elegida: un tinte del acento (en claro una gota blanca sobre la cápsula blanca no se distinguía)\nconst ACTIVE_TINT_PERCENT = Object.freeze({light: 14, dark: 24});\n// encogida: lo alto de la cápsula chica (px) y a qué tamaño se va lo que desaparece\nconst MINIMIZED_PIXELS = Object.freeze({portrait: 48, landscape: 40});\nconst HIDDEN_SCALE = 0.6;\n\n/**\n * Lo que aparece o desaparece al encoger la barra: solo opacidad y escala. visibility espera a que termine la animación\n * para esconderlo, y así lo que ya no se ve tampoco se puede tocar.\n *\n * @param {object} theme\n * @param {boolean} isShown\n * @param {string} transformOrigin hacia dónde se encoge ('left bottom')\n * @returns {object}\n */\nfunction appearStylesOf(theme, isShown, transformOrigin) {\n const duration = theme.transitions.duration.short;\n return {\n transformOrigin,\n opacity: isShown ? 1 : 0,\n transform: isShown ? 'none' : `scale(${HIDDEN_SCALE})`,\n visibility: isShown ? 'visible' : 'hidden',\n transition: `${theme.transitions.create(['opacity', 'transform'], {duration})}, visibility 0s linear ${isShown ? 0 : duration}ms`,\n };\n}\n\n/**\n * La superficie de la barra y del círculo de la cuenta: vidrio más opaco, su línea fina y su sombra (la sombra va en una\n * capa detrás, ::before, para no pisar el filo de luz del vidrio, que también es una sombra). Con el minimalista, sólida.\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction floatingSurfaceOf(theme) {\n // con el minimalista (barra en cápsulas) la barra es sólida: su gris de lo que flota, sin línea ni sombra\n if (!isGlassTheme(theme)) {\n return {...minimalFloatingStylesOf(theme), position: 'relative', borderRadius: '999px', height: '100%'};\n }\n return {\n ...glassStylesOf(theme, {opacity: FLOATING_GLASS_OPACITY}),\n position: 'relative',\n borderRadius: '999px',\n height: '100%',\n outline: `1px solid ${FLOATING_EDGE.light.outline}`,\n '&::before': {\n content: '\"\"', position: 'absolute', inset: 0, borderRadius: 'inherit', zIndex: -1, pointerEvents: 'none',\n boxShadow: FLOATING_EDGE.light.shadow,\n },\n ...theme.applyStyles('dark', {\n outline: `1px solid ${FLOATING_EDGE.dark.outline}`,\n '&::before': {boxShadow: FLOATING_EDGE.dark.shadow},\n }),\n };\n}\n\n/**\n * La pestaña elegida: el tinte del acento y su letra legible.\n *\n * @param {object} theme\n * @returns {object}\n */\nfunction activeTabOf(theme) {\n const primary = (theme.vars ?? theme).palette.primary.main;\n return mergeStyles({\n backgroundColor: `color-mix(in srgb, ${primary} ${ACTIVE_TINT_PERCENT.light}%, transparent)`,\n ...theme.applyStyles('dark', {backgroundColor: `color-mix(in srgb, ${primary} ${ACTIVE_TINT_PERCENT.dark}%, transparent)`}),\n }, accentTextStylesOf(theme));\n}\n\n/**\n * Una pestaña: liga a su pantalla o, con submenú, botón que abre el menú de acciones.\n *\n * @param {object} props\n * @param {string} props.label ya traducido\n * @param {import('react').ElementType} [props.Icon]\n * @param {boolean} props.isActive\n * @param {{content: number|string, isCount: boolean}|null} props.badge\n * @param {object} [props.linkProps] {component, to} si navega\n * @param {(event: object) => void} [props.onClick]\n * @param {boolean} [props.hasPopup] abre un menú\n */\nfunction TabButton({label, Icon, isActive, badge, linkProps = {}, onClick, hasPopup = false}) {\n return (\n <TabBarTab {...linkProps} onClick={onClick} aria-haspopup={hasPopup ? 'menu' : undefined} aria-current={isActive ? 'page' : undefined}\n ownSx={(theme) => mergeStyles({\n flex: '1 1 0', minWidth: 0, height: '100%', borderRadius: '999px', px: 0,\n display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 0.25,\n color: 'text.primary',\n transition: theme.transitions.create(['background-color', 'color'], {duration: theme.transitions.duration.shortest}),\n [PHONE_LANDSCAPE_MEDIA_QUERY]: {flexDirection: 'row', gap: 0.75},\n }, isActive ? activeTabOf(theme) : {})}>\n <Badge invisible={!badge?.isCount} color=\"error\" max={BADGE_MAX} overlap=\"circular\" badgeContent={badge?.isCount ? badge.content : undefined}>\n {Icon ? <Icon sx={{fontSize: TAB_ICON_SIZE}} /> : <TabBarTabIconPlaceholder ownSx={{width: TAB_ICON_SIZE, height: TAB_ICON_SIZE}} />}\n </Badge>\n <TabBarTabLabel component=\"span\" noWrap\n ownSx={{...textSizeOf(TAB_LABEL_PIXELS.portrait), fontWeight: 500, maxWidth: '100%',\n [PHONE_LANDSCAPE_MEDIA_QUERY]: textSizeOf(TAB_LABEL_PIXELS.landscape)}}>\n {label}\n </TabBarTabLabel>\n </TabBarTab>\n );\n}\n\n/**\n * Cuántas pestañas caben en la cápsula (contando «Más»). Se mide la cápsula, que no cambia de ancho con sus pestañas (se\n * estira hasta su tope), así que la cuenta no da vueltas. Se vuelve a medir al girar el teléfono o cambiar la ventana.\n *\n * @param {HTMLElement|null} capsule\n * @param {number} minTabPixels lo menos que mide una pestaña\n * @returns {number}\n */\nfunction useFittingTabCount(capsule, minTabPixels) {\n const [tabCount, setTabCount] = useState(DEFAULT_TAB_COUNT);\n // antes de pintar: así no se ve un momento con las pestañas apretadas\n useLayoutEffect(() => {\n if (!capsule) {\n return undefined;\n }\n const measure = () => {\n const style = window.getComputedStyle(capsule);\n const innerWidth = capsule.clientWidth - Number.parseFloat(style.paddingLeft) - Number.parseFloat(style.paddingRight);\n // en escritorio la barra no se ve (ancho 0): se quedan las de siempre\n if (innerWidth > 0) {\n setTabCount(Math.max(2, Math.floor(innerWidth / minTabPixels)));\n }\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(capsule);\n return () => observer.disconnect();\n }, [capsule, minTabPixels]);\n return tabCount;\n}\n\n/**\n * @param {object} props\n * @param {object[]} props.menuItems lo que regresa composeMenu\n * @param {object|null} props.activeItem la entrada de la pantalla abierta\n * @param {Record<string, number>} [props.menuBadges] los conteos del servidor por badgeKey\n * @param {import('react').ReactNode} [props.account] la cuenta (o el engrane), en su círculo junto a la barra\n * @param {import('react').ReactNode} [props.moreFooter] lo que va al final de la hoja de «Más» (la tarjeta del menú lateral)\n * @param {boolean} [props.minimizeOnScroll] se encoge al leer hacia abajo; por omisión sí\n * @param {(keys: string[]|null) => void} [props.onPinnedTabsChange] la persona eligió sus pestañas (null: regresó a las de\n * omisión)\n */\nfunction MobileTabBarContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaMobileTabBar.defaultProps) y encima lo que llega aquí\n const {menuItems, activeItem, menuBadges, account, moreFooter, minimizeOnScroll = true, onPinnedTabsChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout');\n const {Link: RouterLink} = useToolkitNavigation();\n const {pinnedKeys, setPinnedKeys} = usePinnedMobileTabs();\n const [tabsCapsule, setTabsCapsule] = useState(null);\n const isLandscape = useMediaQuery(PHONE_LANDSCAPE_MEDIA_QUERY);\n const tabCount = useFittingTabCount(tabsCapsule, isLandscape ? MIN_TAB_PIXELS.landscape : MIN_TAB_PIXELS.portrait);\n const {tabs, more} = mobileTabsOf(menuItems, pinnedKeys, tabCount);\n const [submenu, setSubmenu] = useState({anchorElement: null, menuItem: null});\n const [isMoreOpen, setIsMoreOpen] = useState(false);\n const [isEditingTabs, setIsEditingTabs] = useState(false);\n // al salir del editor su botón desaparece con el foco adentro: el foco regresa a «Editar la barra» (sin eso se perdía\n // y Escape ya no cerraba la hoja; también lo necesita quien usa lector de pantalla)\n const [returnsFromEditor, setReturnsFromEditor] = useState(false);\n const leaveEditor = () => {\n setIsEditingTabs(false);\n setReturnsFromEditor(true);\n };\n const closeMore = () => {\n setIsMoreOpen(false);\n setIsEditingTabs(false);\n setReturnsFromEditor(false);\n };\n const {isMinimized, expand} = useTabBarMinimized(minimizeOnScroll);\n const closeSubmenu = () => setSubmenu({anchorElement: null, menuItem: null});\n const isInside = (menuItem) => menuItem === activeItem || (menuItem.children ?? []).includes(activeItem);\n const moreHasActive = more.some(isInside);\n // la cápsula chica enseña dónde está la persona: su pestaña, «Más» si está en algo de ahí, o la primera\n const activeTab = tabs.find(isInside);\n const MinimizedIcon = (!activeTab && moreHasActive ? MoreHorizRoundedIcon : (activeTab ?? tabs[0])?.Icon) ?? MoreHorizRoundedIcon;\n // «Más» suma los conteos de lo que guarda (solo conteos: los de texto no van en la pestaña)\n const moreCount = more.reduce((total, menuItem) => {\n const badge = menuBadgeOf(menuItem, menuBadges);\n return total + (badge?.isCount ? badge.content : 0);\n }, 0);\n const moreBadge = moreCount > 0 ? {content: moreCount, isCount: true} : null;\n\n const glassSurfaceSx = floatingSurfaceOf;\n\n return (\n <>\n <TabBarRoot component=\"nav\" aria-label={t('drawer.ariaLabel')}\n ownSx={(theme) => ({\n display: 'none',\n [PHONE_MEDIA_QUERY]: {display: 'flex'},\n position: 'fixed', zIndex: theme.zIndex.appBar, gap: 0.75, justifyContent: 'center',\n left: GLASS_PANEL_GAP_PIXELS, right: GLASS_PANEL_GAP_PIXELS,\n bottom: `calc(${GLASS_PANEL_GAP_PIXELS}px + env(safe-area-inset-bottom))`,\n height: MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait,\n [PHONE_LANDSCAPE_MEDIA_QUERY]: {height: MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape},\n })}>\n <TabBarBar ref={setTabsCapsule} inert={isMinimized}\n ownSx={(theme) => ({...glassSurfaceSx(theme), display: 'flex', flex: 1, maxWidth: TAB_BAR_MAX_WIDTH_PIXELS, p: 0.375,\n ...appearStylesOf(theme, !isMinimized, 'left bottom')})}>\n {tabs.map((menuItem) => {\n const hasChildren = (menuItem.children ?? []).length > 0;\n return (\n <TabButton key={menuItem.to ?? menuItem.href ?? menuItemLabelOf(menuItem, t)} label={menuItemLabelOf(menuItem, t)} Icon={menuItem.Icon}\n isActive={isInside(menuItem)} badge={menuBadgeOf(menuItem, menuBadges)} hasPopup={hasChildren}\n linkProps={hasChildren ? {} : menuLinkPropsOf(menuItem, RouterLink)}\n onClick={hasChildren ? (event) => setSubmenu({anchorElement: event.currentTarget, menuItem}) : undefined} />\n );\n })}\n {more.length > 0 && (\n <TabButton label={t('drawer.more')} Icon={MoreHorizRoundedIcon} isActive={moreHasActive} badge={moreBadge} hasPopup\n onClick={() => setIsMoreOpen(true)} />\n )}\n </TabBarBar>\n {/* encogida: la cápsula chica en la esquina, con la pestaña de ahorita; tocarla regresa la barra completa */}\n <TabBarMinimized inert={!isMinimized} onClick={expand} aria-label={t('drawer.showTabs')} aria-expanded={false}\n ownSx={(theme) => mergeStyles({\n ...glassSurfaceSx(theme), position: 'absolute', left: 0, bottom: 0,\n width: MINIMIZED_PIXELS.portrait, height: MINIMIZED_PIXELS.portrait,\n [PHONE_LANDSCAPE_MEDIA_QUERY]: {width: MINIMIZED_PIXELS.landscape, height: MINIMIZED_PIXELS.landscape},\n ...appearStylesOf(theme, isMinimized, 'left bottom'),\n }, accentTextStylesOf(theme))}>\n <MinimizedIcon sx={{fontSize: TAB_ICON_SIZE}} />\n </TabBarMinimized>\n {account && (\n <TabBarAccount ownSx={(theme) => ({\n ...glassSurfaceSx(theme), flexShrink: 0, minWidth: MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait, px: 0.5, display: 'flex', alignItems: 'center',\n justifyContent: 'center', [PHONE_LANDSCAPE_MEDIA_QUERY]: {minWidth: MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape},\n '& .MuiButtonBase-root': {color: 'inherit'},\n // encogida, la cuenta se queda pero del alto de la cápsula chica, pegada a su esquina\n transformOrigin: 'right bottom',\n transform: isMinimized ? `scale(${MINIMIZED_PIXELS.portrait / MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait})` : 'none',\n transition: theme.transitions.create('transform', {duration: theme.transitions.duration.short}),\n ...(isMinimized && {[PHONE_LANDSCAPE_MEDIA_QUERY]: {\n minWidth: MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape,\n transform: `scale(${MINIMIZED_PIXELS.landscape / MOBILE_TAB_BAR_HEIGHT_PIXELS.landscape})`,\n }}),\n })}>\n {account}\n </TabBarAccount>\n )}\n </TabBarRoot>\n\n {submenu.menuItem && (\n <SubmenuActionsMenu anchorElement={submenu.anchorElement} onClose={closeSubmenu} menuItem={submenu.menuItem} activeItem={activeItem}\n menuBadges={menuBadges} placement={SUBMENU_PLACEMENT.above} />\n )}\n\n {/* «Más»: el resto del menú en una hoja desde abajo, separada de las orillas como las hojas de iOS */}\n <Drawer anchor=\"bottom\" open={isMoreOpen} onClose={closeMore}\n slotProps={{paper: {sx: {\n m: `${GLASS_PANEL_GAP_PIXELS}px auto calc(${GLASS_PANEL_GAP_PIXELS}px + env(safe-area-inset-bottom))`,\n width: `min(${MORE_SHEET_MAX_WIDTH_PIXELS}px, calc(100% - ${GLASS_PANEL_GAP_PIXELS * 2}px))`,\n maxHeight: MORE_SHEET_MAX_HEIGHT, borderRadius: '20px', overflow: 'hidden',\n }}}}>\n {isEditingTabs ? (\n <TabBarEditor menuItems={menuItems} pinnedKeys={tabs.map(menuItemKeyOf)}\n onDone={(keys) => {\n setPinnedKeys(keys);\n onPinnedTabsChange?.(keys);\n leaveEditor();\n }}\n onReset={() => {\n setPinnedKeys(null);\n onPinnedTabsChange?.(null);\n leaveEditor();\n }} />\n ) : (\n <>\n <TabBarSheetHeader ownSx={{display: 'flex', justifyContent: 'flex-end', px: 1.5, pt: 1, flexShrink: 0}}>\n <Button size=\"small\" autoFocus={returnsFromEditor} onClick={() => setIsEditingTabs(true)}>{t('drawer.editTabs')}</Button>\n </TabBarSheetHeader>\n <SideMenu menuItems={more} activeItem={activeItem} menuBadges={menuBadges} collapsed={false} showBrand={false} footer={moreFooter}\n onNavigate={closeMore} />\n </>\n )}\n </Drawer>\n </>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst MobileTabBar = withPieceSlots(MobileTabBarContent, THEME_NAME);\nexport default MobileTabBar;\n"],"names":[],"mappings":"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"}
@@ -10,11 +10,11 @@ import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined";
10
10
  import AppearanceSettings from "./AppearanceSettings.js";
11
11
  import { barMenuPlacementOf } from "./barMenuPlacement.js";
12
12
  import MenuLinks from "./MenuLinks.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 = "CalcitaSettingsMenu";
16
16
  const SettingsDivider = piecePart(THEME_NAME, "Divider", Divider);
17
- function SettingsMenu(props) {
17
+ function SettingsMenuContent(props) {
18
18
  const { showFontSize = true, showLanguage = true, showColorScheme = true, extraSettings, menuLinks = [], ...unknownProps } = usePieceProps(props, THEME_NAME);
19
19
  warnUnknownProps(THEME_NAME, unknownProps);
20
20
  const { t } = useToolkitTranslation("layout");
@@ -46,6 +46,7 @@ function SettingsMenu(props) {
46
46
  )
47
47
  ] });
48
48
  }
49
+ const SettingsMenu = withPieceSlots(SettingsMenuContent, THEME_NAME);
49
50
  export {
50
51
  SettingsMenu as default
51
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsMenu.js","sources":["../../src/appShell/SettingsMenu.jsx"],"sourcesContent":["// Los ajustes sin sesión (del marco de walk-ot): tres botones de configuración que casi no se usan van juntos detrás de un\n// engrane (AppearanceSettings: tamaño de letra, idioma y claro / oscuro), con los del proyecto y sus ligas (las de la cuenta:\n// sin sesión siguen a la mano, como «Regresar al sistema»).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSettingsMenu con defaultProps y\n// styleOverrides de sus partes: divider.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport IconButton from '@mui/material/IconButton';\nimport Divider from '@mui/material/Divider';\nimport Menu from '@mui/material/Menu';\nimport Tooltip from '@mui/material/Tooltip';\nimport SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined';\n\nimport AppearanceSettings from '@/appShell/AppearanceSettings.jsx';\nimport {barMenuPlacementOf} from '@/appShell/barMenuPlacement.js';\nimport MenuLinks from '@/appShell/MenuLinks.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.CalcitaSettingsMenu)\nconst THEME_NAME = 'CalcitaSettingsMenu';\nconst SettingsDivider = piecePart(THEME_NAME, 'Divider', Divider);\n\n/**\n * @param {object} props\n * @param {boolean} [props.showFontSize]\n * @param {boolean} [props.showLanguage]\n * @param {boolean} [props.showColorScheme]\n * @param {import('react').ReactNode} [props.extraSettings] los ajustes del proyecto, debajo de los del paquete\n * @param {object[]} [props.menuLinks] las ligas propias (accountMenuItems), al final\n */\nexport default function SettingsMenu(props) {\n // lo que el proyecto puso en su tema (components.CalcitaSettingsMenu.defaultProps) y encima lo que llega aquí\n const {showFontSize = true, showLanguage = true, showColorScheme = true, extraSettings, menuLinks = [], ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout');\n const [anchorElement, setAnchorElement] = useState(null);\n // hacia arriba si la barra está abajo (teléfono con vidrio)\n const placement = barMenuPlacementOf(anchorElement);\n const hasAppearance = showFontSize || showLanguage || showColorScheme;\n const closeMenu = () => setAnchorElement(null);\n\n return (\n <>\n <Tooltip title={t('settings.open')}>\n <IconButton size=\"small\" aria-label={t('settings.open')} aria-haspopup=\"menu\" onClick={(event) => setAnchorElement(event.currentTarget)}>\n <SettingsOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Menu anchorEl={anchorElement} open={Boolean(anchorElement)} onClose={closeMenu}\n anchorOrigin={placement.anchorOrigin} transformOrigin={placement.transformOrigin}\n slotProps={{paper: {sx: {minWidth: 280, maxWidth: 360, py: 0.5, ...placement.gapSx}}}}>\n {hasAppearance && <AppearanceSettings showFontSize={showFontSize} showLanguage={showLanguage} showColorScheme={showColorScheme} />}\n {extraSettings && <>{hasAppearance && <SettingsDivider ownSx={{my: 0.5}} />}{extraSettings}</>}\n {menuLinks.length > 0 && (hasAppearance || extraSettings) && <SettingsDivider ownSx={{my: 0.5}} />}\n <MenuLinks links={menuLinks} onClose={closeMenu} />\n </Menu>\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAuBA,MAAM,aAAa;AACnB,MAAM,kBAAkB,UAAU,YAAY,WAAW,OAAO;AAUhE,SAAwB,aAAa,OAAO;AAExC,QAAM,EAAC,eAAe,MAAM,eAAe,MAAM,kBAAkB,MAAM,eAAe,YAAY,CAAA,GAAI,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC1J,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,QAAQ;AAC1C,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,IAAI;AAEvD,QAAM,YAAY,mBAAmB,aAAa;AAClD,QAAM,gBAAgB,gBAAgB,gBAAgB;AACtD,QAAM,YAAY,MAAM,iBAAiB,IAAI;AAE7C,SACI,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA,oBAAC,SAAA,EAAQ,OAAO,EAAE,eAAe,GAC7B,UAAA,oBAAC,YAAA,EAAW,MAAK,SAAQ,cAAY,EAAE,eAAe,GAAG,iBAAc,QAAO,SAAS,CAAC,UAAU,iBAAiB,MAAM,aAAa,GAClI,UAAA,oBAAC,sBAAA,EAAqB,UAAS,QAAA,CAAQ,EAAA,CAC3C,GACJ;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAK,UAAU;AAAA,QAAe,MAAM,QAAQ,aAAa;AAAA,QAAG,SAAS;AAAA,QAChE,cAAc,UAAU;AAAA,QAAc,iBAAiB,UAAU;AAAA,QACjE,WAAW,EAAC,OAAO,EAAC,IAAI,EAAC,UAAU,KAAK,UAAU,KAAK,IAAI,KAAK,GAAG,UAAU,MAAA,IAAM;AAAA,QACpF,UAAA;AAAA,UAAA,iBAAiB,oBAAC,oBAAA,EAAmB,cAA4B,cAA4B,iBAAkC;AAAA,UAC/H,iBAAiB,qBAAA,UAAA,EAAG,UAAA;AAAA,YAAA,qCAAkB,iBAAA,EAAgB,OAAO,EAAC,IAAI,OAAM;AAAA,YAAI;AAAA,UAAA,GAAc;AAAA,UAC1F,UAAU,SAAS,MAAM,iBAAiB,kBAAkB,oBAAC,iBAAA,EAAgB,OAAO,EAAC,IAAI,IAAA,EAAG,CAAG;AAAA,UAChG,oBAAC,WAAA,EAAU,OAAO,WAAW,SAAS,UAAA,CAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACrD,GACJ;AAER;"}
1
+ {"version":3,"file":"SettingsMenu.js","sources":["../../src/appShell/SettingsMenu.jsx"],"sourcesContent":["// Los ajustes sin sesión (del marco de walk-ot): tres botones de configuración que casi no se usan van juntos detrás de un\n// engrane (AppearanceSettings: tamaño de letra, idioma y claro / oscuro), con los del proyecto y sus ligas (las de la cuenta:\n// sin sesión siguen a la mano, como «Regresar al sistema»).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSettingsMenu con defaultProps y\n// styleOverrides de sus partes: divider.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport IconButton from '@mui/material/IconButton';\nimport Divider from '@mui/material/Divider';\nimport Menu from '@mui/material/Menu';\nimport Tooltip from '@mui/material/Tooltip';\nimport SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined';\n\nimport AppearanceSettings from '@/appShell/AppearanceSettings.jsx';\nimport {barMenuPlacementOf} from '@/appShell/barMenuPlacement.js';\nimport MenuLinks from '@/appShell/MenuLinks.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.CalcitaSettingsMenu)\nconst THEME_NAME = 'CalcitaSettingsMenu';\nconst SettingsDivider = piecePart(THEME_NAME, 'Divider', Divider);\n\n/**\n * @param {object} props\n * @param {boolean} [props.showFontSize]\n * @param {boolean} [props.showLanguage]\n * @param {boolean} [props.showColorScheme]\n * @param {import('react').ReactNode} [props.extraSettings] los ajustes del proyecto, debajo de los del paquete\n * @param {object[]} [props.menuLinks] las ligas propias (accountMenuItems), al final\n */\nfunction SettingsMenuContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaSettingsMenu.defaultProps) y encima lo que llega aquí\n const {showFontSize = true, showLanguage = true, showColorScheme = true, extraSettings, menuLinks = [], ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout');\n const [anchorElement, setAnchorElement] = useState(null);\n // hacia arriba si la barra está abajo (teléfono con vidrio)\n const placement = barMenuPlacementOf(anchorElement);\n const hasAppearance = showFontSize || showLanguage || showColorScheme;\n const closeMenu = () => setAnchorElement(null);\n\n return (\n <>\n <Tooltip title={t('settings.open')}>\n <IconButton size=\"small\" aria-label={t('settings.open')} aria-haspopup=\"menu\" onClick={(event) => setAnchorElement(event.currentTarget)}>\n <SettingsOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Menu anchorEl={anchorElement} open={Boolean(anchorElement)} onClose={closeMenu}\n anchorOrigin={placement.anchorOrigin} transformOrigin={placement.transformOrigin}\n slotProps={{paper: {sx: {minWidth: 280, maxWidth: 360, py: 0.5, ...placement.gapSx}}}}>\n {hasAppearance && <AppearanceSettings showFontSize={showFontSize} showLanguage={showLanguage} showColorScheme={showColorScheme} />}\n {extraSettings && <>{hasAppearance && <SettingsDivider ownSx={{my: 0.5}} />}{extraSettings}</>}\n {menuLinks.length > 0 && (hasAppearance || extraSettings) && <SettingsDivider ownSx={{my: 0.5}} />}\n <MenuLinks links={menuLinks} onClose={closeMenu} />\n </Menu>\n </>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst SettingsMenu = withPieceSlots(SettingsMenuContent, THEME_NAME);\nexport default SettingsMenu;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAuBA,MAAM,aAAa;AACnB,MAAM,kBAAkB,UAAU,YAAY,WAAW,OAAO;AAUhE,SAAS,oBAAoB,OAAO;AAEhC,QAAM,EAAC,eAAe,MAAM,eAAe,MAAM,kBAAkB,MAAM,eAAe,YAAY,CAAA,GAAI,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC1J,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,QAAQ;AAC1C,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,IAAI;AAEvD,QAAM,YAAY,mBAAmB,aAAa;AAClD,QAAM,gBAAgB,gBAAgB,gBAAgB;AACtD,QAAM,YAAY,MAAM,iBAAiB,IAAI;AAE7C,SACI,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA,oBAAC,SAAA,EAAQ,OAAO,EAAE,eAAe,GAC7B,UAAA,oBAAC,YAAA,EAAW,MAAK,SAAQ,cAAY,EAAE,eAAe,GAAG,iBAAc,QAAO,SAAS,CAAC,UAAU,iBAAiB,MAAM,aAAa,GAClI,UAAA,oBAAC,sBAAA,EAAqB,UAAS,QAAA,CAAQ,EAAA,CAC3C,GACJ;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAK,UAAU;AAAA,QAAe,MAAM,QAAQ,aAAa;AAAA,QAAG,SAAS;AAAA,QAChE,cAAc,UAAU;AAAA,QAAc,iBAAiB,UAAU;AAAA,QACjE,WAAW,EAAC,OAAO,EAAC,IAAI,EAAC,UAAU,KAAK,UAAU,KAAK,IAAI,KAAK,GAAG,UAAU,MAAA,IAAM;AAAA,QACpF,UAAA;AAAA,UAAA,iBAAiB,oBAAC,oBAAA,EAAmB,cAA4B,cAA4B,iBAAkC;AAAA,UAC/H,iBAAiB,qBAAA,UAAA,EAAG,UAAA;AAAA,YAAA,qCAAkB,iBAAA,EAAgB,OAAO,EAAC,IAAI,OAAM;AAAA,YAAI;AAAA,UAAA,GAAc;AAAA,UAC1F,UAAU,SAAS,MAAM,iBAAiB,kBAAkB,oBAAC,iBAAA,EAAgB,OAAO,EAAC,IAAI,IAAA,EAAG,CAAG;AAAA,UAChG,oBAAC,WAAA,EAAU,OAAO,WAAW,SAAS,UAAA,CAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACrD,GACJ;AAER;AAGA,MAAM,eAAe,eAAe,qBAAqB,UAAU;"}
@@ -19,7 +19,7 @@ import Wordmark from "./Wordmark.js";
19
19
  import { APP_BAR_HEIGHT_PIXELS } from "./shellSizes.js";
20
20
  import SideMenuEntry from "./SideMenuEntry.js";
21
21
  import { isGlassTheme, glassStylesOf } from "../theme/glassSurface.js";
22
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
22
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
23
23
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
24
24
  const THEME_NAME = "CalcitaSideMenu";
25
25
  const MenuScrollArrow = piecePart(THEME_NAME, "ScrollArrow", IconButton);
@@ -64,7 +64,7 @@ function ScrollArrow({ label, onClick, sx, children }) {
64
64
  }
65
65
  const BRAND_LEFT_PADDING = "18px";
66
66
  const SECTION_TITLE_FONT_REM = Object.freeze({ solid: 0.6875, glass: 0.75 });
67
- function SideMenu(props) {
67
+ function SideMenuContent(props) {
68
68
  const {
69
69
  logo,
70
70
  wordmark,
@@ -234,6 +234,7 @@ function SideMenu(props) {
234
234
  ] })
235
235
  );
236
236
  }
237
+ const SideMenu = withPieceSlots(SideMenuContent, THEME_NAME);
237
238
  export {
238
239
  SideMenu as default
239
240
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SideMenu.js","sources":["../../src/appShell/SideMenu.jsx"],"sourcesContent":["// Lo de adentro del menú lateral (el fijo de escritorio y el cajón del teléfono): arriba el logo y el nombre de la app\n// (solo en el cajón del teléfono: en escritorio van en la barra), en medio las secciones del menú (composeMenu, con el\n// título de cada sección) y abajo lo que el proyecto quiera (sidebarFooter: una tarjeta de ayuda, el plan contratado…).\n//\n// Es una columna de toda la altura: el menú crece y se desliza solo, y el pie se queda abajo.\n// Encogido (solo íconos): el título de cada sección se vuelve una rayita del mismo alto (los huecos entre secciones se\n// quedan parejos y nada brinca al abrirlo), el pie se quita (escondido seguía ocupando su lugar y sacaba la barra de\n// desplazamiento). La barra de desplazamiento no se pinta nunca: se comía el ancho de los nombres (la rueda sigue).\n// Con el vidrio del tema, los títulos de sección van como se escriben («Operación») y no en mayúsculas: la guía de Liquid\n// Glass de Apple los dejó de poner en mayúsculas porque se leen mejor.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSideMenu con defaultProps y\n// styleOverrides de sus partes: scrollArrow, root, brand, brandLogo, brandText, brandName, brandCaption, railTop,\n// listArea, list, section, sectionTitle, sectionTitleText, footer, railBottom.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Divider from '@mui/material/Divider';\nimport IconButton from '@mui/material/IconButton';\nimport List from '@mui/material/List';\nimport ListSubheader from '@mui/material/ListSubheader';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\nimport KeyboardArrowDownRoundedIcon from '@mui/icons-material/KeyboardArrowDownRounded';\nimport KeyboardArrowUpRoundedIcon from '@mui/icons-material/KeyboardArrowUpRounded';\n\nimport {menuItemLabelOf, menuSectionsOf} from '@/appShell/menuItemText.js';\nimport Wordmark from '@/appShell/Wordmark.jsx';\nimport {APP_BAR_HEIGHT_PIXELS} from '@/appShell/shellSizes.js';\nimport SideMenuEntry from '@/appShell/SideMenuEntry.jsx';\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.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.CalcitaSideMenu)\nconst THEME_NAME = 'CalcitaSideMenu';\nconst MenuScrollArrow = piecePart(THEME_NAME, 'ScrollArrow', IconButton);\nconst MenuRoot = piecePart(THEME_NAME, 'Root', Box);\nconst MenuBrand = piecePart(THEME_NAME, 'Brand', ButtonBase);\nconst MenuBrandLogo = piecePart(THEME_NAME, 'BrandLogo', Box);\nconst MenuBrandText = piecePart(THEME_NAME, 'BrandText', Box);\nconst MenuBrandName = piecePart(THEME_NAME, 'BrandName', Typography);\nconst MenuBrandCaption = piecePart(THEME_NAME, 'BrandCaption', Typography);\nconst MenuRailTop = piecePart(THEME_NAME, 'RailTop', Box);\nconst MenuListArea = piecePart(THEME_NAME, 'ListArea', Box);\nconst MenuList = piecePart(THEME_NAME, 'List', List);\nconst MenuSection = piecePart(THEME_NAME, 'Section', Box);\nconst MenuSectionTitle = piecePart(THEME_NAME, 'SectionTitle', ListSubheader);\nconst MenuSectionTitleText = piecePart(THEME_NAME, 'SectionTitleText', Box);\nconst MenuFooter = piecePart(THEME_NAME, 'Footer', Box);\nconst MenuRailBottom = piecePart(THEME_NAME, 'RailBottom', Box);\n\n// lo alto del desvanecido en la orilla del menú que tiene más (px)\nconst SCROLL_FADE_PIXELS = 28;\n// el estilo minimalista del tema (THEME_LOOK.minimal; se repite el texto para no importar el tema desde el menú)\nconst MINIMAL_LOOK = 'minimal';\n// la flecha: a cuánto de la orilla va y cuánto se repite al deslizar un tramo (px)\nconst SCROLL_ARROW_INSET_PIXELS = 4;\nconst SCROLL_STEP_OVERLAP_PIXELS = 44;\n\n/** La flecha de una orilla del menú: un botoncito de vidrio centrado que lo desliza un tramo. */\nfunction ScrollArrow({label, onClick, sx, children}) {\n return (\n <Tooltip title={label} placement=\"right\">\n <MenuScrollArrow size=\"small\" aria-label={label} onClick={onClick}\n ownSx={[(theme) => ({\n position: 'absolute', left: '50%', transform: 'translateX(-50%)', zIndex: 1, width: 32, height: 24, borderRadius: '999px',\n ...(isGlassTheme(theme) ? glassStylesOf(theme, {isControl: true}) : {bgcolor: 'background.paper', boxShadow: 2}),\n }), sx]}>\n {children}\n </MenuScrollArrow>\n </Tooltip>\n );\n}\n\n// el logo de 28 px queda centrado en el menú encogido de 64 px: (64 - 28) / 2\nconst BRAND_LEFT_PADDING = '18px';\n// la letra del título de sección (rem): en mayúsculas, más chica; con vidrio, como se escribe, un poco más grande. Con\n// alto de renglón 2, la mitad del renglón mide lo mismo que la letra: ahí va la rayita del encogido\nconst SECTION_TITLE_FONT_REM = Object.freeze({solid: 0.6875, glass: 0.75});\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.logo] el logo chico (28 px), el que se queda con el menú encogido\n * @param {import('react').ReactNode | {light?: import('react').ReactNode, dark?: import('react').ReactNode}} [props.wordmark] el logo\n * ancho (en lugar del logo y el nombre arriba), o uno para cada modo ({light, dark})\n * @param {string} props.brandName el nombre de la app\n * @param {string} [props.brandCaption] el renglón chico debajo del nombre («Panel de administración»)\n * @param {string} props.homePath\n * @param {object[]} props.menuItems lo que regresa composeMenu\n * @param {object|null} props.activeItem\n * @param {boolean} props.collapsed\n * @param {import('react').ReactNode} [props.footer]\n * @param {boolean} [props.showBrand] el logo y el nombre arriba; por omisión sí (en escritorio van en la barra)\n * @param {() => void} [props.onNavigate]\n * @param {Record<string, number>} [props.menuBadges] los conteos del servidor por badgeKey\n * @param {import('react').ReactNode} [props.railTop] arriba del menú encogido que hace de barra: la ☰ y el logo\n * @param {import('react').ReactNode} [props.railBottom] abajo de ese menú: los ajustes y la cuenta\n */\nexport default function SideMenu(props) {\n // lo que el proyecto puso en su tema (components.CalcitaSideMenu.defaultProps) y encima lo que llega aquí\n const {\n logo, wordmark, brandName, brandCaption, homePath, menuItems, activeItem, collapsed, footer, showBrand = true, onNavigate, railTop, railBottom, menuBadges,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout');\n const {Link: RouterLink} = useToolkitNavigation();\n const theme = useTheme();\n // con vidrio y con el minimalista (los dos siguen a Apple) los títulos de sección van como se escriben, no en mayúsculas\n const isAppleStyle = isGlassTheme(theme) || theme.toolkit?.look === MINIMAL_LOOK;\n const sectionTitleFontRem = isAppleStyle ? SECTION_TITLE_FONT_REM.glass : SECTION_TITLE_FONT_REM.solid;\n const fadeWhenCollapsed = (theme) => ({opacity: collapsed ? 0 : 1, transition: theme.transitions.create('opacity')});\n // el menú no lleva barra de desplazamiento (ver abajo): cuando no cabe, se desvanece en la orilla de donde hay más, para\n // que se entienda que se desliza (lo reportaron: «no se entiende que scrollea»)\n const listRef = useRef(null);\n const [hiddenEdges, setHiddenEdges] = useState({top: false, bottom: false});\n useEffect(() => {\n const list = listRef.current;\n if (!list) {\n return undefined;\n }\n const measure = () => setHiddenEdges({\n top: list.scrollTop > 1,\n bottom: list.scrollTop + list.clientHeight < list.scrollHeight - 1,\n });\n measure();\n list.addEventListener('scroll', measure, {passive: true});\n const resizeObserver = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure);\n resizeObserver?.observe(list);\n return () => {\n list.removeEventListener('scroll', measure);\n resizeObserver?.disconnect();\n };\n }, [menuItems, collapsed]);\n // la flecha desliza el menú lo que mide su parte visible, menos un renglón para no perder de vista dónde se iba\n const scrollMenu = (direction) => listRef.current?.scrollBy({top: direction * (listRef.current.clientHeight - SCROLL_STEP_OVERLAP_PIXELS), behavior: 'smooth'});\n const fadeMask = `linear-gradient(to bottom, ${hiddenEdges.top ? 'transparent' : 'black'}, black ${SCROLL_FADE_PIXELS}px, black calc(100% - ${SCROLL_FADE_PIXELS}px), ${hiddenEdges.bottom ? 'transparent' : 'black'})`;\n\n return (\n // OJO: flex y no height 100%: dentro de la hoja de «Más» (que solo tiene alto máximo) un 100 % no se resuelve, el menú\n // crecía sin límite y la hoja no se deslizaba (lo reportaron con el teléfono acostado)\n <MenuRoot ownSx={{display: 'flex', flexDirection: 'column', flex: '1 1 auto', minHeight: 0}}>\n {showBrand && (\n <>\n <MenuBrand component={RouterLink} to={homePath} onClick={onNavigate} aria-label={brandName}\n ownSx={{display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: 1.25, minHeight: APP_BAR_HEIGHT_PIXELS,\n pl: BRAND_LEFT_PADDING, pr: 2, flexShrink: 0}}>\n {wordmark ? <Wordmark>{wordmark}</Wordmark> : (\n <>\n <MenuBrandLogo ownSx={{width: 28, height: 28, flex: '0 0 auto', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</MenuBrandLogo>\n <MenuBrandText ownSx={(theme) => ({minWidth: 0, textAlign: 'left', ...fadeWhenCollapsed(theme)})}>\n <MenuBrandName variant=\"subtitle2\" component=\"span\" noWrap ownSx={{display: 'block', fontWeight: 600, lineHeight: 1.3}}>{brandName}</MenuBrandName>\n {brandCaption && <MenuBrandCaption variant=\"caption\" component=\"span\" color=\"text.secondary\" noWrap ownSx={{display: 'block', lineHeight: 1.3}}>{brandCaption}</MenuBrandCaption>}\n </MenuBrandText>\n </>\n )}\n </MenuBrand>\n <Divider />\n </>\n )}\n\n {railTop && <MenuRailTop ownSx={{display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1, pt: 1.25, pb: 0.5, flexShrink: 0}}>{railTop}</MenuRailTop>}\n\n {/* la lista y sus flechas: cuando no cabe, una flecha en la orilla de donde hay más (como los menús largos de la Mac)\n que la desliza un tramo; el desvanecido la refuerza. Sin barra de desplazamiento no se entendía que había más */}\n <MenuListArea ownSx={{position: 'relative', flexGrow: 1, minHeight: 0, display: 'flex', flexDirection: 'column'}}>\n <MenuList ref={listRef} component=\"nav\" aria-label={t('drawer.ariaLabel')} dense disablePadding\n ownSx={{\n px: 1, pt: 1, pb: 2, flexGrow: 1, minHeight: 0, height: '100%', overflowY: 'auto', overflowX: 'hidden',\n // sin barra de desplazamiento, abierto o encogido (se desliza igual con la rueda, el trackpad o el\n // teclado, como en la Mac, donde la barra solo sale al deslizar): a la vista se veía una raya junto a\n // los nombres, y aunque fuera transparente se comía su ancho y cortaba «Alta con react-hook-form»\n scrollbarWidth: 'none',\n maskImage: fadeMask,\n WebkitMaskImage: fadeMask,\n '&::-webkit-scrollbar': {display: 'none'},\n }}>\n {menuSectionsOf(menuItems, t).map((section, sectionIndex) => (\n <MenuSection component=\"li\" key={section.title ?? `section-${sectionIndex}`} ownSx={{listStyle: 'none'}}>\n <List dense disablePadding\n subheader={section.title ? (\n <MenuSectionTitle disableSticky component=\"div\"\n ownSx={(theme) => ({position: 'relative', bgcolor: 'transparent', px: 1.5, pt: 1.5, lineHeight: 2, fontSize: `${sectionTitleFontRem}rem`,\n fontWeight: 600, letterSpacing: isAppleStyle ? 0 : '0.08em', textTransform: isAppleStyle ? 'none' : 'uppercase',\n color: 'text.secondary', whiteSpace: 'nowrap',\n // encogido: en lugar del título, una rayita a media altura del renglón\n '&::after': {\n content: '\"\"', position: 'absolute', left: '25%', right: '25%', height: '1px',\n top: `calc(${theme.spacing(1.5)} + ${sectionTitleFontRem}rem)`, bgcolor: 'divider',\n opacity: collapsed ? 1 : 0, transition: theme.transitions.create('opacity'),\n }})}>\n <MenuSectionTitleText component=\"span\" ownSx={fadeWhenCollapsed}>{section.title}</MenuSectionTitleText>\n </MenuSectionTitle>\n ) : null}>\n {section.menuItems.map((menuItem) => (\n <SideMenuEntry key={menuItem.to ?? menuItemLabelOf(menuItem, t)} menuItem={menuItem} activeItem={activeItem} collapsed={collapsed}\n onNavigate={onNavigate} menuBadges={menuBadges} />\n ))}\n </List>\n </MenuSection>\n ))}\n {/* la tarjeta de abajo va al final de lo que se desliza, no fija: en una pantalla baja (el teléfono acostado) se\n comía el menú y solo se veía «Inicio» (lo reportaron) */}\n {footer && (\n <MenuFooter component=\"li\" ownSx={{listStyle: 'none', pt: 2, px: 0.5, display: collapsed ? 'none' : 'block'}}>{footer}</MenuFooter>\n )}\n </MenuList>\n {hiddenEdges.top && (\n <ScrollArrow label={t('drawer.scrollUp')} onClick={() => scrollMenu(-1)} sx={{top: SCROLL_ARROW_INSET_PIXELS}}>\n <KeyboardArrowUpRoundedIcon fontSize=\"small\" />\n </ScrollArrow>\n )}\n {hiddenEdges.bottom && (\n <ScrollArrow label={t('drawer.scrollDown')} onClick={() => scrollMenu(1)} sx={{bottom: SCROLL_ARROW_INSET_PIXELS}}>\n <KeyboardArrowDownRoundedIcon fontSize=\"small\" />\n </ScrollArrow>\n )}\n </MenuListArea>\n\n {railBottom && <MenuRailBottom ownSx={{display: 'flex', justifyContent: 'center', pt: 1, pb: 1.25, flexShrink: 0, borderTop: 1, borderColor: 'divider'}}>{railBottom}</MenuRailBottom>}\n </MenuRoot>\n );\n}\n"],"names":["theme"],"mappings":"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"}
1
+ {"version":3,"file":"SideMenu.js","sources":["../../src/appShell/SideMenu.jsx"],"sourcesContent":["// Lo de adentro del menú lateral (el fijo de escritorio y el cajón del teléfono): arriba el logo y el nombre de la app\n// (solo en el cajón del teléfono: en escritorio van en la barra), en medio las secciones del menú (composeMenu, con el\n// título de cada sección) y abajo lo que el proyecto quiera (sidebarFooter: una tarjeta de ayuda, el plan contratado…).\n//\n// Es una columna de toda la altura: el menú crece y se desliza solo, y el pie se queda abajo.\n// Encogido (solo íconos): el título de cada sección se vuelve una rayita del mismo alto (los huecos entre secciones se\n// quedan parejos y nada brinca al abrirlo), el pie se quita (escondido seguía ocupando su lugar y sacaba la barra de\n// desplazamiento). La barra de desplazamiento no se pinta nunca: se comía el ancho de los nombres (la rueda sigue).\n// Con el vidrio del tema, los títulos de sección van como se escriben («Operación») y no en mayúsculas: la guía de Liquid\n// Glass de Apple los dejó de poner en mayúsculas porque se leen mejor.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSideMenu con defaultProps y\n// styleOverrides de sus partes: scrollArrow, root, brand, brandLogo, brandText, brandName, brandCaption, railTop,\n// listArea, list, section, sectionTitle, sectionTitleText, footer, railBottom.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Divider from '@mui/material/Divider';\nimport IconButton from '@mui/material/IconButton';\nimport List from '@mui/material/List';\nimport ListSubheader from '@mui/material/ListSubheader';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\nimport KeyboardArrowDownRoundedIcon from '@mui/icons-material/KeyboardArrowDownRounded';\nimport KeyboardArrowUpRoundedIcon from '@mui/icons-material/KeyboardArrowUpRounded';\n\nimport {menuItemLabelOf, menuSectionsOf} from '@/appShell/menuItemText.js';\nimport Wordmark from '@/appShell/Wordmark.jsx';\nimport {APP_BAR_HEIGHT_PIXELS} from '@/appShell/shellSizes.js';\nimport SideMenuEntry from '@/appShell/SideMenuEntry.jsx';\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.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.CalcitaSideMenu)\nconst THEME_NAME = 'CalcitaSideMenu';\nconst MenuScrollArrow = piecePart(THEME_NAME, 'ScrollArrow', IconButton);\nconst MenuRoot = piecePart(THEME_NAME, 'Root', Box);\nconst MenuBrand = piecePart(THEME_NAME, 'Brand', ButtonBase);\nconst MenuBrandLogo = piecePart(THEME_NAME, 'BrandLogo', Box);\nconst MenuBrandText = piecePart(THEME_NAME, 'BrandText', Box);\nconst MenuBrandName = piecePart(THEME_NAME, 'BrandName', Typography);\nconst MenuBrandCaption = piecePart(THEME_NAME, 'BrandCaption', Typography);\nconst MenuRailTop = piecePart(THEME_NAME, 'RailTop', Box);\nconst MenuListArea = piecePart(THEME_NAME, 'ListArea', Box);\nconst MenuList = piecePart(THEME_NAME, 'List', List);\nconst MenuSection = piecePart(THEME_NAME, 'Section', Box);\nconst MenuSectionTitle = piecePart(THEME_NAME, 'SectionTitle', ListSubheader);\nconst MenuSectionTitleText = piecePart(THEME_NAME, 'SectionTitleText', Box);\nconst MenuFooter = piecePart(THEME_NAME, 'Footer', Box);\nconst MenuRailBottom = piecePart(THEME_NAME, 'RailBottom', Box);\n\n// lo alto del desvanecido en la orilla del menú que tiene más (px)\nconst SCROLL_FADE_PIXELS = 28;\n// el estilo minimalista del tema (THEME_LOOK.minimal; se repite el texto para no importar el tema desde el menú)\nconst MINIMAL_LOOK = 'minimal';\n// la flecha: a cuánto de la orilla va y cuánto se repite al deslizar un tramo (px)\nconst SCROLL_ARROW_INSET_PIXELS = 4;\nconst SCROLL_STEP_OVERLAP_PIXELS = 44;\n\n/** La flecha de una orilla del menú: un botoncito de vidrio centrado que lo desliza un tramo. */\nfunction ScrollArrow({label, onClick, sx, children}) {\n return (\n <Tooltip title={label} placement=\"right\">\n <MenuScrollArrow size=\"small\" aria-label={label} onClick={onClick}\n ownSx={[(theme) => ({\n position: 'absolute', left: '50%', transform: 'translateX(-50%)', zIndex: 1, width: 32, height: 24, borderRadius: '999px',\n ...(isGlassTheme(theme) ? glassStylesOf(theme, {isControl: true}) : {bgcolor: 'background.paper', boxShadow: 2}),\n }), sx]}>\n {children}\n </MenuScrollArrow>\n </Tooltip>\n );\n}\n\n// el logo de 28 px queda centrado en el menú encogido de 64 px: (64 - 28) / 2\nconst BRAND_LEFT_PADDING = '18px';\n// la letra del título de sección (rem): en mayúsculas, más chica; con vidrio, como se escribe, un poco más grande. Con\n// alto de renglón 2, la mitad del renglón mide lo mismo que la letra: ahí va la rayita del encogido\nconst SECTION_TITLE_FONT_REM = Object.freeze({solid: 0.6875, glass: 0.75});\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.logo] el logo chico (28 px), el que se queda con el menú encogido\n * @param {import('react').ReactNode | {light?: import('react').ReactNode, dark?: import('react').ReactNode}} [props.wordmark] el logo\n * ancho (en lugar del logo y el nombre arriba), o uno para cada modo ({light, dark})\n * @param {string} props.brandName el nombre de la app\n * @param {string} [props.brandCaption] el renglón chico debajo del nombre («Panel de administración»)\n * @param {string} props.homePath\n * @param {object[]} props.menuItems lo que regresa composeMenu\n * @param {object|null} props.activeItem\n * @param {boolean} props.collapsed\n * @param {import('react').ReactNode} [props.footer]\n * @param {boolean} [props.showBrand] el logo y el nombre arriba; por omisión sí (en escritorio van en la barra)\n * @param {() => void} [props.onNavigate]\n * @param {Record<string, number>} [props.menuBadges] los conteos del servidor por badgeKey\n * @param {import('react').ReactNode} [props.railTop] arriba del menú encogido que hace de barra: la ☰ y el logo\n * @param {import('react').ReactNode} [props.railBottom] abajo de ese menú: los ajustes y la cuenta\n */\nfunction SideMenuContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaSideMenu.defaultProps) y encima lo que llega aquí\n const {\n logo, wordmark, brandName, brandCaption, homePath, menuItems, activeItem, collapsed, footer, showBrand = true, onNavigate, railTop, railBottom, menuBadges,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout');\n const {Link: RouterLink} = useToolkitNavigation();\n const theme = useTheme();\n // con vidrio y con el minimalista (los dos siguen a Apple) los títulos de sección van como se escriben, no en mayúsculas\n const isAppleStyle = isGlassTheme(theme) || theme.toolkit?.look === MINIMAL_LOOK;\n const sectionTitleFontRem = isAppleStyle ? SECTION_TITLE_FONT_REM.glass : SECTION_TITLE_FONT_REM.solid;\n const fadeWhenCollapsed = (theme) => ({opacity: collapsed ? 0 : 1, transition: theme.transitions.create('opacity')});\n // el menú no lleva barra de desplazamiento (ver abajo): cuando no cabe, se desvanece en la orilla de donde hay más, para\n // que se entienda que se desliza (lo reportaron: «no se entiende que scrollea»)\n const listRef = useRef(null);\n const [hiddenEdges, setHiddenEdges] = useState({top: false, bottom: false});\n useEffect(() => {\n const list = listRef.current;\n if (!list) {\n return undefined;\n }\n const measure = () => setHiddenEdges({\n top: list.scrollTop > 1,\n bottom: list.scrollTop + list.clientHeight < list.scrollHeight - 1,\n });\n measure();\n list.addEventListener('scroll', measure, {passive: true});\n const resizeObserver = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure);\n resizeObserver?.observe(list);\n return () => {\n list.removeEventListener('scroll', measure);\n resizeObserver?.disconnect();\n };\n }, [menuItems, collapsed]);\n // la flecha desliza el menú lo que mide su parte visible, menos un renglón para no perder de vista dónde se iba\n const scrollMenu = (direction) => listRef.current?.scrollBy({top: direction * (listRef.current.clientHeight - SCROLL_STEP_OVERLAP_PIXELS), behavior: 'smooth'});\n const fadeMask = `linear-gradient(to bottom, ${hiddenEdges.top ? 'transparent' : 'black'}, black ${SCROLL_FADE_PIXELS}px, black calc(100% - ${SCROLL_FADE_PIXELS}px), ${hiddenEdges.bottom ? 'transparent' : 'black'})`;\n\n return (\n // OJO: flex y no height 100%: dentro de la hoja de «Más» (que solo tiene alto máximo) un 100 % no se resuelve, el menú\n // crecía sin límite y la hoja no se deslizaba (lo reportaron con el teléfono acostado)\n <MenuRoot ownSx={{display: 'flex', flexDirection: 'column', flex: '1 1 auto', minHeight: 0}}>\n {showBrand && (\n <>\n <MenuBrand component={RouterLink} to={homePath} onClick={onNavigate} aria-label={brandName}\n ownSx={{display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: 1.25, minHeight: APP_BAR_HEIGHT_PIXELS,\n pl: BRAND_LEFT_PADDING, pr: 2, flexShrink: 0}}>\n {wordmark ? <Wordmark>{wordmark}</Wordmark> : (\n <>\n <MenuBrandLogo ownSx={{width: 28, height: 28, flex: '0 0 auto', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</MenuBrandLogo>\n <MenuBrandText ownSx={(theme) => ({minWidth: 0, textAlign: 'left', ...fadeWhenCollapsed(theme)})}>\n <MenuBrandName variant=\"subtitle2\" component=\"span\" noWrap ownSx={{display: 'block', fontWeight: 600, lineHeight: 1.3}}>{brandName}</MenuBrandName>\n {brandCaption && <MenuBrandCaption variant=\"caption\" component=\"span\" color=\"text.secondary\" noWrap ownSx={{display: 'block', lineHeight: 1.3}}>{brandCaption}</MenuBrandCaption>}\n </MenuBrandText>\n </>\n )}\n </MenuBrand>\n <Divider />\n </>\n )}\n\n {railTop && <MenuRailTop ownSx={{display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1, pt: 1.25, pb: 0.5, flexShrink: 0}}>{railTop}</MenuRailTop>}\n\n {/* la lista y sus flechas: cuando no cabe, una flecha en la orilla de donde hay más (como los menús largos de la Mac)\n que la desliza un tramo; el desvanecido la refuerza. Sin barra de desplazamiento no se entendía que había más */}\n <MenuListArea ownSx={{position: 'relative', flexGrow: 1, minHeight: 0, display: 'flex', flexDirection: 'column'}}>\n <MenuList ref={listRef} component=\"nav\" aria-label={t('drawer.ariaLabel')} dense disablePadding\n ownSx={{\n px: 1, pt: 1, pb: 2, flexGrow: 1, minHeight: 0, height: '100%', overflowY: 'auto', overflowX: 'hidden',\n // sin barra de desplazamiento, abierto o encogido (se desliza igual con la rueda, el trackpad o el\n // teclado, como en la Mac, donde la barra solo sale al deslizar): a la vista se veía una raya junto a\n // los nombres, y aunque fuera transparente se comía su ancho y cortaba «Alta con react-hook-form»\n scrollbarWidth: 'none',\n maskImage: fadeMask,\n WebkitMaskImage: fadeMask,\n '&::-webkit-scrollbar': {display: 'none'},\n }}>\n {menuSectionsOf(menuItems, t).map((section, sectionIndex) => (\n <MenuSection component=\"li\" key={section.title ?? `section-${sectionIndex}`} ownSx={{listStyle: 'none'}}>\n <List dense disablePadding\n subheader={section.title ? (\n <MenuSectionTitle disableSticky component=\"div\"\n ownSx={(theme) => ({position: 'relative', bgcolor: 'transparent', px: 1.5, pt: 1.5, lineHeight: 2, fontSize: `${sectionTitleFontRem}rem`,\n fontWeight: 600, letterSpacing: isAppleStyle ? 0 : '0.08em', textTransform: isAppleStyle ? 'none' : 'uppercase',\n color: 'text.secondary', whiteSpace: 'nowrap',\n // encogido: en lugar del título, una rayita a media altura del renglón\n '&::after': {\n content: '\"\"', position: 'absolute', left: '25%', right: '25%', height: '1px',\n top: `calc(${theme.spacing(1.5)} + ${sectionTitleFontRem}rem)`, bgcolor: 'divider',\n opacity: collapsed ? 1 : 0, transition: theme.transitions.create('opacity'),\n }})}>\n <MenuSectionTitleText component=\"span\" ownSx={fadeWhenCollapsed}>{section.title}</MenuSectionTitleText>\n </MenuSectionTitle>\n ) : null}>\n {section.menuItems.map((menuItem) => (\n <SideMenuEntry key={menuItem.to ?? menuItemLabelOf(menuItem, t)} menuItem={menuItem} activeItem={activeItem} collapsed={collapsed}\n onNavigate={onNavigate} menuBadges={menuBadges} />\n ))}\n </List>\n </MenuSection>\n ))}\n {/* la tarjeta de abajo va al final de lo que se desliza, no fija: en una pantalla baja (el teléfono acostado) se\n comía el menú y solo se veía «Inicio» (lo reportaron) */}\n {footer && (\n <MenuFooter component=\"li\" ownSx={{listStyle: 'none', pt: 2, px: 0.5, display: collapsed ? 'none' : 'block'}}>{footer}</MenuFooter>\n )}\n </MenuList>\n {hiddenEdges.top && (\n <ScrollArrow label={t('drawer.scrollUp')} onClick={() => scrollMenu(-1)} sx={{top: SCROLL_ARROW_INSET_PIXELS}}>\n <KeyboardArrowUpRoundedIcon fontSize=\"small\" />\n </ScrollArrow>\n )}\n {hiddenEdges.bottom && (\n <ScrollArrow label={t('drawer.scrollDown')} onClick={() => scrollMenu(1)} sx={{bottom: SCROLL_ARROW_INSET_PIXELS}}>\n <KeyboardArrowDownRoundedIcon fontSize=\"small\" />\n </ScrollArrow>\n )}\n </MenuListArea>\n\n {railBottom && <MenuRailBottom ownSx={{display: 'flex', justifyContent: 'center', pt: 1, pb: 1.25, flexShrink: 0, borderTop: 1, borderColor: 'divider'}}>{railBottom}</MenuRailBottom>}\n </MenuRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst SideMenu = withPieceSlots(SideMenuContent, THEME_NAME);\nexport default SideMenu;\n"],"names":["theme"],"mappings":"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"}
@@ -21,7 +21,7 @@ import { menuBadgeOf } from "../navigation/appMenu.js";
21
21
  import { isGlassTheme, accentTextStylesOf, glassDropOf } from "../theme/glassSurface.js";
22
22
  import { mergeStyles } from "../theme/mergeComponents.js";
23
23
  import { textSizeOf } from "../theme/appleTracking.js";
24
- import { piecePart, usePieceProps } from "../theme/themePieces.js";
24
+ import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
25
25
  import { warnUnknownProps } from "../toolkit/unknownProps.js";
26
26
  const THEME_NAME = "CalcitaSideMenuEntry";
27
27
  const EntryButton = piecePart(THEME_NAME, "Button", ListItemButton);
@@ -45,7 +45,7 @@ const MENU_TEXT_PIXELS = 13;
45
45
  const MENU_BADGE_PIXELS = 11;
46
46
  const BADGE_MAX = 99;
47
47
  const RAIL_BUTTON_RADIUS_PIXELS = 10;
48
- function SideMenuEntry(props) {
48
+ function SideMenuEntryContent(props) {
49
49
  const { menuItem, activeItem, collapsed, onNavigate, menuBadges, depth = 0, ...unknownProps } = usePieceProps(props, THEME_NAME);
50
50
  warnUnknownProps(THEME_NAME, unknownProps);
51
51
  const { t } = useToolkitTranslation("layout");
@@ -145,6 +145,7 @@ function SideMenuEntry(props) {
145
145
  )) }) })
146
146
  ] });
147
147
  }
148
+ const SideMenuEntry = withPieceSlots(SideMenuEntryContent, THEME_NAME);
148
149
  export {
149
150
  SideMenuEntry as default
150
151
  };