@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.
- package/README.md +426 -4
- package/cli/calcita.js +15 -0
- package/cli/checkTexts.js +209 -0
- package/cli/packageVersions.js +17 -3
- package/cli/projectFiles.js +7 -2
- package/cli/templates/module/__Name__Page.test.jsx.tpl +24 -0
- package/cli/templates/project/README.md.tpl +35 -2
- package/cli/templates/project/eslint.config.js.tpl +27 -0
- package/cli/templates/project/src/app/appRouter.jsx.tpl +5 -2
- package/cli/templates/project/src/app/appTexts.js.tpl +2 -1
- package/cli/templates/project/src/core/accountConnector.js.tpl +4 -2
- package/cli/templates/project/src/core/publicPaths.js.tpl +10 -2
- package/cli/templates/project/src/modules/auth/SignInPage.test.jsx.tpl +20 -0
- package/cli/templates/project/src/modules/home/HomePage.test.jsx.tpl +16 -0
- package/cli/templates/project/src/testing/browserGaps.js.tpl +70 -0
- package/cli/templates/project/src/testing/openScreen.jsx.tpl +58 -0
- package/cli/templates/project/src/testing/setup.js.tpl +25 -0
- package/cli/templates/project/vite.config.js.tpl +20 -1
- package/dist/DataTable/AuditTrailDialog.js +3 -2
- package/dist/DataTable/AuditTrailDialog.js.map +1 -1
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js +3 -2
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js.map +1 -1
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +3 -2
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -1
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js +3 -2
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js.map +1 -1
- package/dist/DataTable/EmptyState.js +3 -2
- package/dist/DataTable/EmptyState.js.map +1 -1
- package/dist/DataTable/FilterChips.js +3 -2
- package/dist/DataTable/FilterChips.js.map +1 -1
- package/dist/DataTable/GoToPage.js +71 -14
- package/dist/DataTable/GoToPage.js.map +1 -1
- package/dist/DataTable/ServerTable.js +97 -28
- package/dist/DataTable/ServerTable.js.map +1 -1
- package/dist/DataTable/ServerTableFilterDrawer.js +57 -0
- package/dist/DataTable/ServerTableFilterDrawer.js.map +1 -0
- package/dist/DataTable/StackedCell.js +60 -0
- package/dist/DataTable/StackedCell.js.map +1 -0
- package/dist/DataTable/TableCardsView.js +88 -0
- package/dist/DataTable/TableCardsView.js.map +1 -0
- package/dist/DataTable/columnWidths.js +30 -0
- package/dist/DataTable/columnWidths.js.map +1 -0
- package/dist/DataTable/columns.js +47 -1
- package/dist/DataTable/columns.js.map +1 -1
- package/dist/DataTable/filterContext.js.map +1 -1
- package/dist/DataTable/fixedColumns.js +24 -0
- package/dist/DataTable/fixedColumns.js.map +1 -0
- package/dist/DataTable/goToPageOptions.js +17 -0
- package/dist/DataTable/goToPageOptions.js.map +1 -0
- package/dist/DataTable/useTableView.js +29 -0
- package/dist/DataTable/useTableView.js.map +1 -0
- package/dist/access/PermissionMatrix.js +3 -2
- package/dist/access/PermissionMatrix.js.map +1 -1
- package/dist/account/AccountProvider.js +1 -1
- package/dist/account/AccountSecuritySection.js +3 -2
- package/dist/account/AccountSecuritySection.js.map +1 -1
- package/dist/account/DemoTotpCodeButton.js +3 -2
- package/dist/account/DemoTotpCodeButton.js.map +1 -1
- package/dist/account/ProfileScreen.js +3 -2
- package/dist/account/ProfileScreen.js.map +1 -1
- package/dist/account/SignInScreen.js +3 -2
- package/dist/account/SignInScreen.js.map +1 -1
- package/dist/appShell/AccountMenu.js +3 -2
- package/dist/appShell/AccountMenu.js.map +1 -1
- package/dist/appShell/AppLayout.js +3 -2
- package/dist/appShell/AppLayout.js.map +1 -1
- package/dist/appShell/AppearanceSettings.js +3 -2
- package/dist/appShell/AppearanceSettings.js.map +1 -1
- package/dist/appShell/AuthLayout.js +3 -2
- package/dist/appShell/AuthLayout.js.map +1 -1
- package/dist/appShell/BarActionButton.js +11 -4
- package/dist/appShell/BarActionButton.js.map +1 -1
- package/dist/appShell/BarActions.js +3 -2
- package/dist/appShell/BarActions.js.map +1 -1
- package/dist/appShell/BarCapsule.js +3 -2
- package/dist/appShell/BarCapsule.js.map +1 -1
- package/dist/appShell/BarSearch.js +3 -2
- package/dist/appShell/BarSearch.js.map +1 -1
- package/dist/appShell/HeaderTools.js +3 -2
- package/dist/appShell/HeaderTools.js.map +1 -1
- package/dist/appShell/MobileTabBar.js +3 -2
- package/dist/appShell/MobileTabBar.js.map +1 -1
- package/dist/appShell/SettingsMenu.js +3 -2
- package/dist/appShell/SettingsMenu.js.map +1 -1
- package/dist/appShell/SideMenu.js +3 -2
- package/dist/appShell/SideMenu.js.map +1 -1
- package/dist/appShell/SideMenuEntry.js +3 -2
- package/dist/appShell/SideMenuEntry.js.map +1 -1
- package/dist/appShell/SubmenuActionsMenu.js +3 -2
- package/dist/appShell/SubmenuActionsMenu.js.map +1 -1
- package/dist/appShell/TabBarEditor.js +3 -2
- package/dist/appShell/TabBarEditor.js.map +1 -1
- package/dist/appShell/TopMenu.js +3 -2
- package/dist/appShell/TopMenu.js.map +1 -1
- package/dist/appShell/Wordmark.js +3 -2
- package/dist/appShell/Wordmark.js.map +1 -1
- package/dist/auth/PasswordChecklist.js +3 -2
- package/dist/auth/PasswordChecklist.js.map +1 -1
- package/dist/calendar/EventCalendar.js +3 -2
- package/dist/calendar/EventCalendar.js.map +1 -1
- package/dist/calendar/EventDetails.js +3 -2
- package/dist/calendar/EventDetails.js.map +1 -1
- package/dist/date-pickers.js +28 -2
- package/dist/date-pickers.js.map +1 -1
- package/dist/datePickers/DateInput.js +41 -54
- package/dist/datePickers/DateInput.js.map +1 -1
- package/dist/datePickers/DateTimeInput.js +81 -0
- package/dist/datePickers/DateTimeInput.js.map +1 -0
- package/dist/datePickers/FormDateTimeField.js +12 -0
- package/dist/datePickers/FormDateTimeField.js.map +1 -0
- package/dist/datePickers/FormMonthField.js +12 -0
- package/dist/datePickers/FormMonthField.js.map +1 -0
- package/dist/datePickers/FormTimeField.js +12 -0
- package/dist/datePickers/FormTimeField.js.map +1 -0
- package/dist/datePickers/MonthInput.js +64 -0
- package/dist/datePickers/MonthInput.js.map +1 -0
- package/dist/datePickers/PickerFrame.js +27 -0
- package/dist/datePickers/PickerFrame.js.map +1 -0
- package/dist/datePickers/TimeInput.js +61 -0
- package/dist/datePickers/TimeInput.js.map +1 -0
- package/dist/datePickers/dateTimeRules.js +24 -0
- package/dist/datePickers/dateTimeRules.js.map +1 -0
- package/dist/datePickers/pickerValues.js +106 -0
- package/dist/datePickers/pickerValues.js.map +1 -0
- package/dist/datePickers/useCurrentMinute.js +28 -0
- package/dist/datePickers/useCurrentMinute.js.map +1 -0
- package/dist/datePickers/usePickerField.js +23 -0
- package/dist/datePickers/usePickerField.js.map +1 -0
- package/dist/dictionaries/dictionaries.js +3 -1
- package/dist/dictionaries/dictionaries.js.map +1 -1
- package/dist/downloads/DownloadManager.js +3 -2
- package/dist/downloads/DownloadManager.js.map +1 -1
- package/dist/feedback/ConfirmDialog.js +3 -2
- package/dist/feedback/ConfirmDialog.js.map +1 -1
- package/dist/feedback/ModalWaiting.js +3 -2
- package/dist/feedback/ModalWaiting.js.map +1 -1
- package/dist/feedback/NewBuildNotice.js +3 -2
- package/dist/feedback/NewBuildNotice.js.map +1 -1
- package/dist/filepond/FileDropzone.js +3 -2
- package/dist/filepond/FileDropzone.js.map +1 -1
- package/dist/forms/FormAttachmentsField.js +12 -0
- package/dist/forms/FormAttachmentsField.js.map +1 -0
- package/dist/forms/FormCheckboxGroupField.js +12 -0
- package/dist/forms/FormCheckboxGroupField.js.map +1 -0
- package/dist/forms/FormFileField.js +12 -0
- package/dist/forms/FormFileField.js.map +1 -0
- package/dist/forms/FormFileUploadField.js +12 -0
- package/dist/forms/FormFileUploadField.js.map +1 -0
- package/dist/forms/FormImageField.js +12 -0
- package/dist/forms/FormImageField.js.map +1 -0
- package/dist/forms/FormMaskedField.js +12 -0
- package/dist/forms/FormMaskedField.js.map +1 -0
- package/dist/forms/FormProblemAlert.js +3 -2
- package/dist/forms/FormProblemAlert.js.map +1 -1
- package/dist/forms/FormRepeatingFields.js +54 -0
- package/dist/forms/FormRepeatingFields.js.map +1 -0
- package/dist/forms/FormTransferListField.js +12 -0
- package/dist/forms/FormTransferListField.js.map +1 -0
- package/dist/forms/SubmitButton.js +7 -2
- package/dist/forms/SubmitButton.js.map +1 -1
- package/dist/forms/applyServerProblem.js +10 -3
- package/dist/forms/applyServerProblem.js.map +1 -1
- package/dist/forms/auth/SignInForm.js +3 -2
- package/dist/forms/auth/SignInForm.js.map +1 -1
- package/dist/forms/fieldRules.js +30 -0
- package/dist/forms/fieldRules.js.map +1 -0
- package/dist/forms/listRules.js +111 -0
- package/dist/forms/listRules.js.map +1 -0
- package/dist/forms/security/SecondStepForm.js +3 -2
- package/dist/forms/security/SecondStepForm.js.map +1 -1
- package/dist/forms/security/TwoStepVerificationCard.js +3 -2
- package/dist/forms/security/TwoStepVerificationCard.js.map +1 -1
- package/dist/forms/serverProblemFields.js +17 -0
- package/dist/forms/serverProblemFields.js.map +1 -1
- package/dist/forms/useValidationText.js +18 -0
- package/dist/forms/useValidationText.js.map +1 -0
- package/dist/forms/validation.js +35 -31
- package/dist/forms/validation.js.map +1 -1
- package/dist/forms/validationMessages.js +64 -7
- package/dist/forms/validationMessages.js.map +1 -1
- package/dist/forms.js +54 -29
- package/dist/forms.js.map +1 -1
- package/dist/hookForm/FormAttachmentsField.js +12 -0
- package/dist/hookForm/FormAttachmentsField.js.map +1 -0
- package/dist/hookForm/FormCheckboxGroupField.js +12 -0
- package/dist/hookForm/FormCheckboxGroupField.js.map +1 -0
- package/dist/hookForm/FormFileField.js +12 -0
- package/dist/hookForm/FormFileField.js.map +1 -0
- package/dist/hookForm/FormFileUploadField.js +12 -0
- package/dist/hookForm/FormFileUploadField.js.map +1 -0
- package/dist/hookForm/FormImageField.js +12 -0
- package/dist/hookForm/FormImageField.js.map +1 -0
- package/dist/hookForm/FormMaskedField.js +12 -0
- package/dist/hookForm/FormMaskedField.js.map +1 -0
- package/dist/hookForm/FormProblemAlert.js +3 -2
- package/dist/hookForm/FormProblemAlert.js.map +1 -1
- package/dist/hookForm/FormRepeatingFields.js +44 -0
- package/dist/hookForm/FormRepeatingFields.js.map +1 -0
- package/dist/hookForm/FormTransferListField.js +12 -0
- package/dist/hookForm/FormTransferListField.js.map +1 -0
- package/dist/hookForm/SubmitButton.js +7 -2
- package/dist/hookForm/SubmitButton.js.map +1 -1
- package/dist/hookForm/applyServerProblem.js +8 -3
- package/dist/hookForm/applyServerProblem.js.map +1 -1
- package/dist/inbox/InboxLayout.js +3 -2
- package/dist/inbox/InboxLayout.js.map +1 -1
- package/dist/inbox/MessageList.js +3 -2
- package/dist/inbox/MessageList.js.map +1 -1
- package/dist/inbox/MessageView.js +3 -2
- package/dist/inbox/MessageView.js.map +1 -1
- package/dist/index.js +235 -124
- package/dist/index.js.map +1 -1
- package/dist/inputs/CatalogInput.js +103 -29
- package/dist/inputs/CatalogInput.js.map +1 -1
- package/dist/inputs/CheckboxGroupInput.js +103 -0
- package/dist/inputs/CheckboxGroupInput.js.map +1 -0
- package/dist/inputs/ColorInput.js +7 -4
- package/dist/inputs/ColorInput.js.map +1 -1
- package/dist/inputs/FieldFrame.js +10 -4
- package/dist/inputs/FieldFrame.js.map +1 -1
- package/dist/inputs/FormSection.js +1 -1
- package/dist/inputs/MaskedInput.js +87 -0
- package/dist/inputs/MaskedInput.js.map +1 -0
- package/dist/inputs/NumberInput.js +41 -25
- package/dist/inputs/NumberInput.js.map +1 -1
- package/dist/inputs/RepeatingFields.js +180 -0
- package/dist/inputs/RepeatingFields.js.map +1 -0
- package/dist/inputs/SelectInput.js +50 -9
- package/dist/inputs/SelectInput.js.map +1 -1
- package/dist/inputs/TextInput.js +5 -3
- package/dist/inputs/TextInput.js.map +1 -1
- package/dist/inputs/TransferListInput.js +218 -0
- package/dist/inputs/TransferListInput.js.map +1 -0
- package/dist/inputs/WizardLayout.js +3 -2
- package/dist/inputs/WizardLayout.js.map +1 -1
- package/dist/inputs/inputMasks.js +84 -0
- package/dist/inputs/inputMasks.js.map +1 -0
- package/dist/inputs/selectAllState.js +20 -0
- package/dist/inputs/selectAllState.js.map +1 -0
- package/dist/inputs/useRowKeys.js +26 -0
- package/dist/inputs/useRowKeys.js.map +1 -0
- package/dist/kanban/KanbanBoard.js +3 -2
- package/dist/kanban/KanbanBoard.js.map +1 -1
- package/dist/legal/CookieNotice.js +80 -0
- package/dist/legal/CookieNotice.js.map +1 -0
- package/dist/legal/TermsAcceptanceDialog.js +130 -0
- package/dist/legal/TermsAcceptanceDialog.js.map +1 -0
- package/dist/legal/consentStorage.js +18 -0
- package/dist/legal/consentStorage.js.map +1 -0
- package/dist/legal/useCookieConsent.js +17 -0
- package/dist/legal/useCookieConsent.js.map +1 -0
- package/dist/locales/en.js +257 -1
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +257 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/maps/MapView.js +3 -2
- package/dist/maps/MapView.js.map +1 -1
- package/dist/mexico/CfdiSummary.js +82 -0
- package/dist/mexico/CfdiSummary.js.map +1 -0
- package/dist/mexico/EfirmaFields.js +168 -0
- package/dist/mexico/EfirmaFields.js.map +1 -0
- package/dist/mexico/certificateReader.js +79 -0
- package/dist/mexico/certificateReader.js.map +1 -0
- package/dist/mexico/cfdiReader.js +81 -0
- package/dist/mexico/cfdiReader.js.map +1 -0
- package/dist/mexico/derReader.js +81 -0
- package/dist/mexico/derReader.js.map +1 -0
- package/dist/mexico/efirmaKey.js +51 -0
- package/dist/mexico/efirmaKey.js.map +1 -0
- package/dist/mexico/mexicoIdentifiers.js +91 -0
- package/dist/mexico/mexicoIdentifiers.js.map +1 -0
- package/dist/mexico/mexicoRules.js +21 -0
- package/dist/mexico/mexicoRules.js.map +1 -0
- package/dist/mexico.js +34 -0
- package/dist/mexico.js.map +1 -0
- package/dist/pwa/InstallAppSetting.js +3 -2
- package/dist/pwa/InstallAppSetting.js.map +1 -1
- package/dist/pwa/InstallInstructionsDialog.js +3 -2
- package/dist/pwa/InstallInstructionsDialog.js.map +1 -1
- package/dist/pwa/InstallPromptBanner.js +3 -2
- package/dist/pwa/InstallPromptBanner.js.map +1 -1
- package/dist/react-hook-form.js +43 -17
- package/dist/react-hook-form.js.map +1 -1
- package/dist/rich-text.js +19 -0
- package/dist/rich-text.js.map +1 -0
- package/dist/richText/FormRichTextField.js +12 -0
- package/dist/richText/FormRichTextField.js.map +1 -0
- package/dist/richText/RichTextEditor.js +111 -0
- package/dist/richText/RichTextEditor.js.map +1 -0
- package/dist/richText/RichTextLinkPopover.js +57 -0
- package/dist/richText/RichTextLinkPopover.js.map +1 -0
- package/dist/richText/RichTextToolbar.js +189 -0
- package/dist/richText/RichTextToolbar.js.map +1 -0
- package/dist/richText/RichTextView.js +27 -0
- package/dist/richText/RichTextView.js.map +1 -0
- package/dist/richText/richTextContentSx.js +42 -0
- package/dist/richText/richTextContentSx.js.map +1 -0
- package/dist/richText/richTextExtensions.js +44 -0
- package/dist/richText/richTextExtensions.js.map +1 -0
- package/dist/richText/richTextRules.js +46 -0
- package/dist/richText/richTextRules.js.map +1 -0
- package/dist/security/ActivityLog.js +3 -2
- package/dist/security/ActivityLog.js.map +1 -1
- package/dist/security/RecoveryCodesDialog.js +3 -2
- package/dist/security/RecoveryCodesDialog.js.map +1 -1
- package/dist/security/SessionsCard.js +3 -2
- package/dist/security/SessionsCard.js.map +1 -1
- package/dist/table.js +23 -2
- package/dist/table.js.map +1 -1
- package/dist/theme/components/glassComponents.js +27 -0
- package/dist/theme/components/glassComponents.js.map +1 -1
- package/dist/theme/components/minimalComponents.js +12 -0
- package/dist/theme/components/minimalComponents.js.map +1 -1
- package/dist/theme/themePieces.js +70 -4
- package/dist/theme/themePieces.js.map +1 -1
- package/dist/toolkit/ToolkitProvider.js +8 -1
- package/dist/toolkit/ToolkitProvider.js.map +1 -1
- package/dist/toolkit/browserNavigation.js +19 -4
- package/dist/toolkit/browserNavigation.js.map +1 -1
- package/dist/toolkit/combineTexts.js +32 -0
- package/dist/toolkit/combineTexts.js.map +1 -0
- package/dist/toolkit/hashNavigation.js +17 -3
- package/dist/toolkit/hashNavigation.js.map +1 -1
- package/dist/toolkit/navigationPaths.js +15 -0
- package/dist/toolkit/navigationPaths.js.map +1 -1
- package/dist/toolkit/pathIndex.js +66 -0
- package/dist/toolkit/pathIndex.js.map +1 -0
- package/dist/toolkit/toolkitSettings.js +19 -1
- package/dist/toolkit/toolkitSettings.js.map +1 -1
- package/dist/types/DataTable/AuditTrailDialog.d.ts +6 -17
- package/dist/types/DataTable/ColumnFilters/HeaderFilterPopover.d.ts +6 -5
- package/dist/types/DataTable/ColumnFilters/MultiSelectColumnFilter.d.ts +6 -9
- package/dist/types/DataTable/ColumnFilters/SortableFilterHeader.d.ts +6 -14
- package/dist/types/DataTable/EmptyState.d.ts +6 -9
- package/dist/types/DataTable/FilterChips.d.ts +6 -11
- package/dist/types/DataTable/GoToPage.d.ts +6 -9
- package/dist/types/DataTable/ServerTable.d.ts +16 -80
- package/dist/types/DataTable/ServerTableFilterDrawer.d.ts +14 -0
- package/dist/types/DataTable/StackedCell.d.ts +12 -0
- package/dist/types/DataTable/TableCardsView.d.ts +27 -0
- package/dist/types/DataTable/columnWidths.d.ts +21 -0
- package/dist/types/DataTable/columns.d.ts +111 -0
- package/dist/types/DataTable/filterContext.d.ts +2 -1
- package/dist/types/DataTable/fixedColumns.d.ts +29 -0
- package/dist/types/DataTable/goToPageOptions.d.ts +15 -0
- package/dist/types/DataTable/index.d.ts +7 -1
- package/dist/types/DataTable/useTableView.d.ts +22 -0
- package/dist/types/access/PermissionMatrix.d.ts +6 -10
- package/dist/types/account/AccountSecuritySection.d.ts +6 -7
- package/dist/types/account/DemoTotpCodeButton.d.ts +6 -5
- package/dist/types/account/ProfileScreen.d.ts +6 -18
- package/dist/types/account/SignInScreen.d.ts +6 -13
- package/dist/types/appShell/AccountMenu.d.ts +6 -11
- package/dist/types/appShell/AppLayout.d.ts +3 -40
- package/dist/types/appShell/AppearanceSettings.d.ts +6 -12
- package/dist/types/appShell/AuthLayout.d.ts +3 -11
- package/dist/types/appShell/BarActionButton.d.ts +6 -10
- package/dist/types/appShell/BarActions.d.ts +6 -15
- package/dist/types/appShell/BarCapsule.d.ts +6 -9
- package/dist/types/appShell/BarSearch.d.ts +6 -15
- package/dist/types/appShell/HeaderTools.d.ts +6 -16
- package/dist/types/appShell/MobileTabBar.d.ts +6 -13
- package/dist/types/appShell/SettingsMenu.d.ts +6 -10
- package/dist/types/appShell/SideMenu.d.ts +6 -20
- package/dist/types/appShell/SideMenuEntry.d.ts +6 -11
- package/dist/types/appShell/SubmenuActionsMenu.d.ts +6 -12
- package/dist/types/appShell/TabBarEditor.d.ts +6 -9
- package/dist/types/appShell/TopMenu.d.ts +6 -5
- package/dist/types/appShell/Wordmark.d.ts +6 -7
- package/dist/types/auth/PasswordChecklist.d.ts +6 -9
- package/dist/types/calendar/EventCalendar.d.ts +6 -23
- package/dist/types/calendar/EventDetails.d.ts +6 -10
- package/dist/types/date-pickers.d.ts +10 -1
- package/dist/types/datePickers/DateInput.d.ts +10 -23
- package/dist/types/datePickers/DateTimeInput.d.ts +30 -0
- package/dist/types/datePickers/FormDateTimeField.d.ts +7 -0
- package/dist/types/datePickers/FormMonthField.d.ts +7 -0
- package/dist/types/datePickers/FormTimeField.d.ts +7 -0
- package/dist/types/datePickers/MonthInput.d.ts +25 -0
- package/dist/types/datePickers/PickerFrame.d.ts +22 -0
- package/dist/types/datePickers/TimeInput.d.ts +24 -0
- package/dist/types/datePickers/dateTimeRules.d.ts +31 -0
- package/dist/types/datePickers/pickerValues.d.ts +114 -0
- package/dist/types/datePickers/useCurrentMinute.d.ts +5 -0
- package/dist/types/datePickers/usePickerField.d.ts +28 -0
- package/dist/types/dictionaries/dictionaries.d.ts +6 -3
- package/dist/types/downloads/DownloadManager.d.ts +6 -6
- package/dist/types/feedback/ConfirmDialog.d.ts +6 -18
- package/dist/types/feedback/ModalWaiting.d.ts +6 -9
- package/dist/types/feedback/NewBuildNotice.d.ts +6 -10
- package/dist/types/filepond/FileDropzone.d.ts +6 -29
- package/dist/types/forms/FormAttachmentsField.d.ts +7 -0
- package/dist/types/forms/FormCheckboxGroupField.d.ts +7 -0
- package/dist/types/forms/FormFileField.d.ts +7 -0
- package/dist/types/forms/FormFileUploadField.d.ts +7 -0
- package/dist/types/forms/FormImageField.d.ts +7 -0
- package/dist/types/forms/FormMaskedField.d.ts +7 -0
- package/dist/types/forms/FormProblemAlert.d.ts +6 -5
- package/dist/types/forms/FormRepeatingFields.d.ts +25 -0
- package/dist/types/forms/FormTransferListField.d.ts +7 -0
- package/dist/types/forms/SubmitButton.d.ts +6 -6
- package/dist/types/forms/auth/SignInForm.d.ts +6 -11
- package/dist/types/forms/fieldRules.d.ts +44 -0
- package/dist/types/forms/index.d.ts +11 -1
- package/dist/types/forms/listRules.d.ts +48 -0
- package/dist/types/forms/security/SecondStepForm.d.ts +6 -14
- package/dist/types/forms/security/TwoStepVerificationCard.d.ts +6 -21
- package/dist/types/forms/serverProblemFields.d.ts +13 -0
- package/dist/types/forms/useValidationText.d.ts +12 -0
- package/dist/types/forms/validation.d.ts +117 -174
- package/dist/types/forms/validationMessages.d.ts +54 -6
- package/dist/types/forms.d.ts +1 -1
- package/dist/types/hookForm/FormAttachmentsField.d.ts +8 -0
- package/dist/types/hookForm/FormCheckboxGroupField.d.ts +8 -0
- package/dist/types/hookForm/FormFileField.d.ts +8 -0
- package/dist/types/hookForm/FormFileUploadField.d.ts +8 -0
- package/dist/types/hookForm/FormImageField.d.ts +8 -0
- package/dist/types/hookForm/FormMaskedField.d.ts +9 -0
- package/dist/types/hookForm/FormProblemAlert.d.ts +6 -5
- package/dist/types/hookForm/FormRepeatingFields.d.ts +27 -0
- package/dist/types/hookForm/FormTransferListField.d.ts +8 -0
- package/dist/types/hookForm/SubmitButton.d.ts +6 -13
- package/dist/types/inbox/InboxLayout.d.ts +6 -17
- package/dist/types/inbox/MessageList.d.ts +6 -18
- package/dist/types/inbox/MessageView.d.ts +6 -14
- package/dist/types/index.d.ts +33 -4
- package/dist/types/inputs/CatalogInput.d.ts +10 -21
- package/dist/types/inputs/CheckboxGroupInput.d.ts +28 -0
- package/dist/types/inputs/ColorInput.d.ts +7 -16
- package/dist/types/inputs/FieldFrame.d.ts +6 -10
- package/dist/types/inputs/MaskedInput.d.ts +38 -0
- package/dist/types/inputs/NumberInput.d.ts +7 -20
- package/dist/types/inputs/RepeatingFields.d.ts +31 -0
- package/dist/types/inputs/SelectInput.d.ts +10 -18
- package/dist/types/inputs/TextInput.d.ts +3 -0
- package/dist/types/inputs/TransferListInput.d.ts +30 -0
- package/dist/types/inputs/WizardLayout.d.ts +6 -19
- package/dist/types/inputs/inputMasks.d.ts +52 -0
- package/dist/types/inputs/selectAllState.d.ts +11 -0
- package/dist/types/inputs/useRowKeys.d.ts +11 -0
- package/dist/types/kanban/KanbanBoard.d.ts +6 -25
- package/dist/types/legal/CookieNotice.d.ts +20 -0
- package/dist/types/legal/TermsAcceptanceDialog.d.ts +20 -0
- package/dist/types/legal/consentStorage.d.ts +16 -0
- package/dist/types/legal/useCookieConsent.d.ts +13 -0
- package/dist/types/locales/en.d.ts +256 -0
- package/dist/types/locales/es.d.ts +256 -0
- package/dist/types/maps/MapView.d.ts +6 -17
- package/dist/types/mexico/CfdiSummary.d.ts +12 -0
- package/dist/types/mexico/EfirmaFields.d.ts +28 -0
- package/dist/types/mexico/certificateReader.d.ts +37 -0
- package/dist/types/mexico/cfdiReader.d.ts +95 -0
- package/dist/types/mexico/derReader.d.ts +54 -0
- package/dist/types/mexico/efirmaKey.d.ts +26 -0
- package/dist/types/mexico/mexicoIdentifiers.d.ts +68 -0
- package/dist/types/mexico/mexicoRules.d.ts +45 -0
- package/dist/types/mexico.d.ts +11 -0
- package/dist/types/pwa/InstallAppSetting.d.ts +6 -6
- package/dist/types/pwa/InstallInstructionsDialog.d.ts +6 -9
- package/dist/types/pwa/InstallPromptBanner.d.ts +6 -11
- package/dist/types/react-hook-form.d.ts +11 -1
- package/dist/types/rich-text.d.ts +5 -0
- package/dist/types/richText/FormRichTextField.d.ts +7 -0
- package/dist/types/richText/RichTextEditor.d.ts +27 -0
- package/dist/types/richText/RichTextLinkPopover.d.ts +17 -0
- package/dist/types/richText/RichTextToolbar.d.ts +15 -0
- package/dist/types/richText/RichTextView.d.ts +10 -0
- package/dist/types/richText/richTextContentSx.d.ts +7 -0
- package/dist/types/richText/richTextExtensions.d.ts +15 -0
- package/dist/types/richText/richTextRules.d.ts +41 -0
- package/dist/types/security/ActivityLog.d.ts +6 -9
- package/dist/types/security/RecoveryCodesDialog.d.ts +6 -11
- package/dist/types/security/SessionsCard.d.ts +6 -11
- package/dist/types/table.d.ts +3 -1
- package/dist/types/theme/themePieces.d.ts +55 -3
- package/dist/types/toolkit/ToolkitProvider.d.ts +13 -1
- package/dist/types/toolkit/browserNavigation.d.ts +7 -3
- package/dist/types/toolkit/combineTexts.d.ts +6 -0
- package/dist/types/toolkit/hashNavigation.d.ts +4 -2
- package/dist/types/toolkit/navigationPaths.d.ts +35 -0
- package/dist/types/toolkit/pathIndex.d.ts +27 -0
- package/dist/types/toolkit/toolkitSettings.d.ts +7 -4
- package/dist/types/ui/actions/ActionsMenu.d.ts +24 -11
- package/dist/types/ui/actions/CopyButton.d.ts +8 -11
- package/dist/types/ui/actions/DownloadMenu.d.ts +6 -29
- package/dist/types/ui/actions/SecretField.d.ts +6 -11
- package/dist/types/ui/actions/SelectionActions.d.ts +6 -13
- package/dist/types/ui/actions/tableRowText.d.ts +6 -0
- package/dist/types/ui/cards/RecordCard.d.ts +40 -0
- package/dist/types/ui/cards/RecordCardSkeleton.d.ts +12 -0
- package/dist/types/ui/countdown/Countdown.d.ts +22 -0
- package/dist/types/ui/countdown/countdownParts.d.ts +39 -0
- package/dist/types/ui/countdown/useCountdown.d.ts +14 -0
- package/dist/types/ui/documents/PdfViewerDialog.d.ts +14 -0
- package/dist/types/ui/filters/DateRangeFilter.d.ts +6 -10
- package/dist/types/ui/filters/FilterDrawer.d.ts +23 -0
- package/dist/types/ui/filters/PeriodRangeSelector.d.ts +6 -13
- package/dist/types/ui/filters/QuickFilters.d.ts +6 -12
- package/dist/types/ui/filters/filterDrawerFields.d.ts +139 -0
- package/dist/types/ui/help/HelpButton.d.ts +11 -0
- package/dist/types/ui/help/HelpCarouselDialog.d.ts +27 -0
- package/dist/types/ui/help/useHelpCarousel.d.ts +21 -0
- package/dist/types/ui/index.d.ts +10 -0
- package/dist/types/ui/labels/IconBadge.d.ts +34 -0
- package/dist/types/ui/labels/MarkedText.d.ts +10 -0
- package/dist/types/ui/labels/Tag.d.ts +6 -12
- package/dist/types/ui/labels/markedTextPieces.d.ts +22 -0
- package/dist/types/ui/layout/CollapsibleSection.d.ts +6 -12
- package/dist/types/ui/layout/ContentDialog.d.ts +6 -10
- package/dist/types/ui/layout/DefinitionList.d.ts +6 -9
- package/dist/types/ui/layout/DetailHeader.d.ts +6 -10
- package/dist/types/ui/layout/ErrorPage.d.ts +6 -17
- package/dist/types/ui/layout/FullPageLoader.d.ts +6 -6
- package/dist/types/ui/layout/GlassPanel.d.ts +6 -8
- package/dist/types/ui/layout/PageHeader.d.ts +6 -10
- package/dist/types/ui/layout/PageHeading.d.ts +6 -11
- package/dist/types/ui/layout/ProfileHeader.d.ts +6 -11
- package/dist/types/ui/layout/ScrollableRow.d.ts +6 -13
- package/dist/types/ui/layout/SectionCard.d.ts +6 -8
- package/dist/types/ui/metrics/BarList.d.ts +6 -12
- package/dist/types/ui/metrics/CalendarHeatmap.d.ts +6 -19
- package/dist/types/ui/metrics/ChartTooltip.d.ts +6 -6
- package/dist/types/ui/metrics/ColumnChart.d.ts +6 -25
- package/dist/types/ui/metrics/LineChart.d.ts +6 -20
- package/dist/types/ui/metrics/MetricCard.d.ts +6 -17
- package/dist/types/ui/metrics/TableToggle.d.ts +6 -6
- package/dist/types/ui/metrics/chartParts.d.ts +15 -30
- package/dist/types/ui/navigation/BackButton.d.ts +6 -9
- package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +6 -9
- package/dist/types/ui/navigation/FontSizeToggle.d.ts +6 -8
- package/dist/types/ui/navigation/LanguageToggle.d.ts +6 -8
- package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +6 -7
- package/dist/types/ui/navigation/RouteTabs.d.ts +39 -0
- package/dist/types/ui/navigation/routeTabMatching.d.ts +27 -0
- package/dist/types/ui/timeline/GroupedTimeline.d.ts +6 -23
- package/dist/types/upload/AttachmentsInput.d.ts +72 -0
- package/dist/types/upload/FileChip.d.ts +18 -0
- package/dist/types/upload/FileDropzone.d.ts +7 -19
- package/dist/types/upload/FileInput.d.ts +31 -0
- package/dist/types/upload/FileUploadInput.d.ts +56 -0
- package/dist/types/upload/ImageInput.d.ts +35 -0
- package/dist/types/upload/TemplateDownloadButton.d.ts +27 -0
- package/dist/types/upload/fileAppearance.d.ts +8 -0
- package/dist/types/upload/fileRules.d.ts +38 -0
- package/dist/types/upload/transferProgress.d.ts +18 -0
- package/dist/types/upload/uploadMachine.d.ts +6 -2
- package/dist/types/upload/uploadWithProgress.d.ts +6 -2
- package/dist/types/upload/useFilePicker.d.ts +39 -0
- package/dist/ui/actions/ActionsMenu.js +109 -17
- package/dist/ui/actions/ActionsMenu.js.map +1 -1
- package/dist/ui/actions/CopyButton.js +37 -12
- package/dist/ui/actions/CopyButton.js.map +1 -1
- package/dist/ui/actions/DownloadMenu.js +3 -2
- package/dist/ui/actions/DownloadMenu.js.map +1 -1
- package/dist/ui/actions/SecretField.js +8 -3
- package/dist/ui/actions/SecretField.js.map +1 -1
- package/dist/ui/actions/SelectionActions.js +3 -2
- package/dist/ui/actions/SelectionActions.js.map +1 -1
- package/dist/ui/actions/tableRowText.js +7 -0
- package/dist/ui/actions/tableRowText.js.map +1 -0
- package/dist/ui/cards/RecordCard.js +146 -0
- package/dist/ui/cards/RecordCard.js.map +1 -0
- package/dist/ui/cards/RecordCardSkeleton.js +38 -0
- package/dist/ui/cards/RecordCardSkeleton.js.map +1 -0
- package/dist/ui/countdown/Countdown.js +39 -0
- package/dist/ui/countdown/Countdown.js.map +1 -0
- package/dist/ui/countdown/countdownParts.js +34 -0
- package/dist/ui/countdown/countdownParts.js.map +1 -0
- package/dist/ui/countdown/useCountdown.js +35 -0
- package/dist/ui/countdown/useCountdown.js.map +1 -0
- package/dist/ui/documents/PdfViewerDialog.js +82 -0
- package/dist/ui/documents/PdfViewerDialog.js.map +1 -0
- package/dist/ui/filters/DateRangeFilter.js +3 -2
- package/dist/ui/filters/DateRangeFilter.js.map +1 -1
- package/dist/ui/filters/FilterDrawer.js +212 -0
- package/dist/ui/filters/FilterDrawer.js.map +1 -0
- package/dist/ui/filters/PeriodRangeSelector.js +3 -2
- package/dist/ui/filters/PeriodRangeSelector.js.map +1 -1
- package/dist/ui/filters/QuickFilters.js +3 -2
- package/dist/ui/filters/QuickFilters.js.map +1 -1
- package/dist/ui/filters/filterDrawerFields.js +119 -0
- package/dist/ui/filters/filterDrawerFields.js.map +1 -0
- package/dist/ui/help/HelpButton.js +22 -0
- package/dist/ui/help/HelpButton.js.map +1 -0
- package/dist/ui/help/HelpCarouselDialog.js +155 -0
- package/dist/ui/help/HelpCarouselDialog.js.map +1 -0
- package/dist/ui/help/useHelpCarousel.js +25 -0
- package/dist/ui/help/useHelpCarousel.js.map +1 -0
- package/dist/ui/labels/IconBadge.js +82 -0
- package/dist/ui/labels/IconBadge.js.map +1 -0
- package/dist/ui/labels/MarkedText.js +31 -0
- package/dist/ui/labels/MarkedText.js.map +1 -0
- package/dist/ui/labels/Tag.js +3 -2
- package/dist/ui/labels/Tag.js.map +1 -1
- package/dist/ui/labels/markedTextPieces.js +64 -0
- package/dist/ui/labels/markedTextPieces.js.map +1 -0
- package/dist/ui/layout/CollapsibleSection.js +3 -2
- package/dist/ui/layout/CollapsibleSection.js.map +1 -1
- package/dist/ui/layout/ContentDialog.js +3 -2
- package/dist/ui/layout/ContentDialog.js.map +1 -1
- package/dist/ui/layout/DefinitionList.js +3 -2
- package/dist/ui/layout/DefinitionList.js.map +1 -1
- package/dist/ui/layout/DetailHeader.js +3 -2
- package/dist/ui/layout/DetailHeader.js.map +1 -1
- package/dist/ui/layout/ErrorPage.js +3 -2
- package/dist/ui/layout/ErrorPage.js.map +1 -1
- package/dist/ui/layout/FullPageLoader.js +3 -2
- package/dist/ui/layout/FullPageLoader.js.map +1 -1
- package/dist/ui/layout/GlassPanel.js +3 -2
- package/dist/ui/layout/GlassPanel.js.map +1 -1
- package/dist/ui/layout/PageHeader.js +3 -2
- package/dist/ui/layout/PageHeader.js.map +1 -1
- package/dist/ui/layout/PageHeading.js +3 -2
- package/dist/ui/layout/PageHeading.js.map +1 -1
- package/dist/ui/layout/ProfileHeader.js +3 -2
- package/dist/ui/layout/ProfileHeader.js.map +1 -1
- package/dist/ui/layout/ScrollableRow.js +3 -2
- package/dist/ui/layout/ScrollableRow.js.map +1 -1
- package/dist/ui/layout/SectionCard.js +3 -2
- package/dist/ui/layout/SectionCard.js.map +1 -1
- package/dist/ui/metrics/BarList.js +3 -2
- package/dist/ui/metrics/BarList.js.map +1 -1
- package/dist/ui/metrics/CalendarHeatmap.js +3 -2
- package/dist/ui/metrics/CalendarHeatmap.js.map +1 -1
- package/dist/ui/metrics/ChartTooltip.js +3 -2
- package/dist/ui/metrics/ChartTooltip.js.map +1 -1
- package/dist/ui/metrics/ColumnChart.js +3 -2
- package/dist/ui/metrics/ColumnChart.js.map +1 -1
- package/dist/ui/metrics/LineChart.js +3 -2
- package/dist/ui/metrics/LineChart.js.map +1 -1
- package/dist/ui/metrics/MetricCard.js +3 -2
- package/dist/ui/metrics/MetricCard.js.map +1 -1
- package/dist/ui/metrics/TableToggle.js +3 -2
- package/dist/ui/metrics/TableToggle.js.map +1 -1
- package/dist/ui/metrics/chartParts.js +7 -4
- package/dist/ui/metrics/chartParts.js.map +1 -1
- package/dist/ui/navigation/BackButton.js +7 -2
- package/dist/ui/navigation/BackButton.js.map +1 -1
- package/dist/ui/navigation/ColorSchemeToggle.js +3 -2
- package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -1
- package/dist/ui/navigation/FontSizeToggle.js +3 -2
- package/dist/ui/navigation/FontSizeToggle.js.map +1 -1
- package/dist/ui/navigation/LanguageToggle.js +3 -2
- package/dist/ui/navigation/LanguageToggle.js.map +1 -1
- package/dist/ui/navigation/PageBreadcrumbs.js +3 -2
- package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -1
- package/dist/ui/navigation/RouteTabs.js +79 -0
- package/dist/ui/navigation/RouteTabs.js.map +1 -0
- package/dist/ui/navigation/routeTabMatching.js +23 -0
- package/dist/ui/navigation/routeTabMatching.js.map +1 -0
- package/dist/ui/timeline/GroupedTimeline.js +3 -2
- package/dist/ui/timeline/GroupedTimeline.js.map +1 -1
- package/dist/upload/AttachmentsInput.js +130 -0
- package/dist/upload/AttachmentsInput.js.map +1 -0
- package/dist/upload/FileChip.js +28 -0
- package/dist/upload/FileChip.js.map +1 -0
- package/dist/upload/FileDropzone.js +23 -87
- package/dist/upload/FileDropzone.js.map +1 -1
- package/dist/upload/FileInput.js +115 -0
- package/dist/upload/FileInput.js.map +1 -0
- package/dist/upload/FileUploadInput.js +288 -0
- package/dist/upload/FileUploadInput.js.map +1 -0
- package/dist/upload/ImageInput.js +128 -0
- package/dist/upload/ImageInput.js.map +1 -0
- package/dist/upload/TemplateDownloadButton.js +68 -0
- package/dist/upload/TemplateDownloadButton.js.map +1 -0
- package/dist/upload/fileAppearance.js +21 -0
- package/dist/upload/fileAppearance.js.map +1 -0
- package/dist/upload/fileRules.js +27 -1
- package/dist/upload/fileRules.js.map +1 -1
- package/dist/upload/transferProgress.js +23 -0
- package/dist/upload/transferProgress.js.map +1 -0
- package/dist/upload/uploadMachine.js +8 -8
- package/dist/upload/uploadMachine.js.map +1 -1
- package/dist/upload/uploadWithProgress.js +1 -1
- package/dist/upload/uploadWithProgress.js.map +1 -1
- package/dist/upload/useFilePicker.js +101 -0
- package/dist/upload/useFilePicker.js.map +1 -0
- package/package.json +44 -1
- package/cli/templates/project/src/app/combineTexts.js.tpl +0 -31
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppLayout.js","sources":["../../src/appShell/AppLayout.jsx"],"sourcesContent":["// El marco de las pantallas con sesión, al estilo de las plantillas de MUI (y del marco de walk-ot). Dos estilos de\n// barra con las mismas props, para que el proyecto (o el `init` del CLI) solo elija:\n//\n// menuPosition=\"side\" (por omisión) menuPosition=\"top\" (apps de pocos módulos)\n// ┌──────────────────────────────────────────┐ ┌──────────────────────────────────────────┐\n// │ ☰ Logo Nombre · Título al deslizar · ⚙ (A)│ │ Logo · Inicio Pedidos Clientes ▾ · ⚙ (A) │\n// ├────────┬─────────────────────────────────┤ ├──────────────────────────────────────────┤\n// │ Menú │ contenido │ │ contenido │\n// │ por │ │ │ │\n// │ secc. │ │ │ │\n// └────────┴─────────────────────────────────┘ └──────────────────────────────────────────┘\n//\n// En el teléfono los dos son iguales: hamburguesa, título y ajustes en la barra; el menú sale en un cajón con el logo.\n//\n// Lo que trae, con su porqué:\n// - La barra va a todo lo ancho, con el logo y el nombre de la app a la izquierda, y el menú lateral debajo de ella\n// (como el DashboardLayout de MUI). La ☰ de la barra encoge el menú a solo íconos y lo recuerda (useDrawerCollapsed);\n// antes era un botón montado en la orilla del menú y se encimaba con él.\n// - El título de la página sube a la barra cuando su título grande sale de la vista (pageTitle.jsx).\n// - Escritorio y teléfono se eligen con CSS, no con useMediaQuery: el servidor (Next.js) ya pinta lo correcto.\n// - Dentro de la barra, para que se queden pegados al deslizar: los avisos del proyecto (ribbons), el de versión nueva\n// (NewBuildNotice; con vidrio flota aparte en su cápsula, ver NewBuildNotice.jsx) y la rayita de «cargando la pantalla»\n// (isNavigating). La barra publica su alto real, y el menú lateral empieza justo debajo de ella aunque crezca con un aviso.\n// - Con vidrio, en el teléfono la barra flota ABAJO en una cápsula, como la de Safari en el iPhone; y en escritorio, con\n// el menú encogido, la barra desaparece y se funde con el menú (☰ y logo arriba, ajustes y cuenta abajo).\n// - El primer Tab lleva a «Saltar al contenido» (WCAG 2.4.1) y el contenido es <main>. Respeta el área segura del\n// iPhone (la muesca) cuando la app corre instalada.\n// - Huecos para extender sin tocar el framework: headerActions, sidebarFooter, accountMenuItems, accountSettings, ribbons.\n// - Los ajustes de la app (letra, idioma, claro u oscuro y los del proyecto) van DENTRO del menú de la cuenta, no sueltos\n// en la barra (HeaderTools).\n// - El menú queda al alcance de las páginas (appMenuContext): PageHeading arma sus migas sola.\n// - Con el vidrio del tema (createToolkitTheme({glass: true})): el lienzo lleva manchas de color, y en escritorio la\n// barra y el menú lateral flotan a 8 px de la orilla y entre ellos, con esquinas redondas, para que el contenido pase\n// por detrás y se vea desenfocado; encogido, el menú es una cápsula. En el teléfono la barra sigue de orilla a orilla\n// (como en iOS). Sin vidrio, todo igual que siempre: el marco lo sabe por el tema (isGlassTheme), sin otra prop.\n// - Con vidrio y con el minimalista la barra no lleva franja, como las ventanas de macOS Tahoe (TOP_BAR.capsules, lo de\n// omisión): la ☰ con el nombre, el menú de arriba y la cuenta van cada uno en su cápsula, y el título queda suelto.\n// Con vidrio las cápsulas son de vidrio y el contenido pasa por debajo, desenfocado en la orilla (scrollEdgeStylesOf);\n// con el minimalista son bloques del tono de las tarjetas sobre la barra del color del fondo, también en el teléfono.\n// Con cápsulas el menú encogido ya no se funde con la barra: la cuenta y los ajustes se quedan arriba. Con\n// bar: TOP_BAR.band, la franja de lado a lado. Mismo alto y mismo lugar las dos: el menú lateral y las páginas no se\n// mueven.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAppLayout con defaultProps y\n// styleOverrides de sus partes: skipLink, brand, brandLogo, brandText, brandName, brandCaption, titleArea, phoneTitle,\n// desktopTitle, railBrand, railLogo, collapseButton, root, scrollEdge, bar, toolbar, menuButton, spacer, tools,\n// progress, body, drawer, main, phoneSlot, content, phoneDrawer.\n//\n// Lo renderiza la app: arrow (regla de la casa).\nimport {useMemo, useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {useToolkitNavigation, useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport AppBar from '@mui/material/AppBar';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Drawer from '@mui/material/Drawer';\nimport Fade from '@mui/material/Fade';\nimport IconButton from '@mui/material/IconButton';\nimport LinearProgress from '@mui/material/LinearProgress';\nimport Link from '@mui/material/Link';\nimport Toolbar from '@mui/material/Toolbar';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\nimport MenuIcon from '@mui/icons-material/Menu';\nimport MenuOpenIcon from '@mui/icons-material/MenuOpen';\n\nimport {AppMenuContext} from '@/appShell/appMenuContext.js';\nimport BarCapsule from '@/appShell/BarCapsule.jsx';\nimport {BarActionsSlotContext} from '@/appShell/barActionsSlot.js';\nimport HeaderTools from '@/appShell/HeaderTools.jsx';\nimport MobileTabBar from '@/appShell/MobileTabBar.jsx';\nimport Wordmark from '@/appShell/Wordmark.jsx';\nimport {PageTitleProvider, usePageTitle} from '@/appShell/pageTitle.jsx';\nimport {\n APP_BAR_HEIGHT_PIXELS, DESKTOP_MEDIA_QUERY, DRAWER_WIDTH_COLLAPSED, DRAWER_WIDTH_EXPANDED, GLASS_PANEL_GAP_PIXELS, MAIN_CONTENT_ID,\n FLOATING_BOTTOM_SPACE_CSS_VARIABLE, MOBILE_TAB_BAR_HEIGHT_PIXELS, PHONE_MEDIA_QUERY, drawerTransitionOf,\n} from '@/appShell/shellSizes.js';\nimport SideMenu from '@/appShell/SideMenu.jsx';\nimport {usesMobileTabBar} from '@/appShell/tabBarRule.js';\nimport TopMenu from '@/appShell/TopMenu.jsx';\nimport {useDrawerCollapsed} from '@/appShell/useDrawerCollapsed.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport NewBuildNotice, {NEW_BUILD_NOTICE_VARIANT} from '@/feedback/NewBuildNotice.jsx';\nimport {activeMenuItemOf, menuItemsWithIconsOf} from '@/navigation/appMenu.js';\nimport {useNavigationTrail} from '@/navigationTrail.js';\nimport {THEME_LOOK, TOP_BAR} from '@/theme/createToolkitTheme.js';\nimport {PANEL_RADIUS, ambientBackgroundOf, isGlassTheme, scrollEdgeStylesOf} from '@/theme/glassSurface.js';\nimport GlassLensFilter from '@/ui/layout/GlassLensFilter.jsx';\nimport {APP_BAR_HEIGHT, useAppBarHeightPublisher} from '@/ui/layout/appBarHeight.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.CalcitaAppLayout)\nconst THEME_NAME = 'CalcitaAppLayout';\nconst LayoutSkipLink = piecePart(THEME_NAME, 'SkipLink', Link);\nconst LayoutBrand = piecePart(THEME_NAME, 'Brand', ButtonBase);\nconst LayoutBrandLogo = piecePart(THEME_NAME, 'BrandLogo', Box);\nconst LayoutBrandText = piecePart(THEME_NAME, 'BrandText', Box);\nconst LayoutBrandName = piecePart(THEME_NAME, 'BrandName', Typography);\nconst LayoutBrandCaption = piecePart(THEME_NAME, 'BrandCaption', Typography);\nconst LayoutTitleArea = piecePart(THEME_NAME, 'TitleArea', Box);\nconst LayoutPhoneTitle = piecePart(THEME_NAME, 'PhoneTitle', Typography);\nconst LayoutDesktopTitle = piecePart(THEME_NAME, 'DesktopTitle', Typography);\nconst LayoutRailBrand = piecePart(THEME_NAME, 'RailBrand', ButtonBase);\nconst LayoutRailLogo = piecePart(THEME_NAME, 'RailLogo', Box);\nconst LayoutCollapseButton = piecePart(THEME_NAME, 'CollapseButton', IconButton);\nconst LayoutRoot = piecePart(THEME_NAME, 'Root', Box);\nconst LayoutScrollEdge = piecePart(THEME_NAME, 'ScrollEdge', Box);\nconst LayoutBar = piecePart(THEME_NAME, 'Bar', AppBar);\nconst LayoutToolbar = piecePart(THEME_NAME, 'Toolbar', Toolbar);\nconst LayoutMenuButton = piecePart(THEME_NAME, 'MenuButton', IconButton);\nconst LayoutSpacer = piecePart(THEME_NAME, 'Spacer', Box);\nconst LayoutTools = piecePart(THEME_NAME, 'Tools', Box);\nconst LayoutProgress = piecePart(THEME_NAME, 'Progress', LinearProgress);\nconst LayoutBody = piecePart(THEME_NAME, 'Body', Box);\nconst LayoutDrawer = piecePart(THEME_NAME, 'Drawer', Drawer);\nconst LayoutMain = piecePart(THEME_NAME, 'Main', Box);\nconst LayoutPhoneSlot = piecePart(THEME_NAME, 'PhoneSlot', Box);\nconst LayoutContent = piecePart(THEME_NAME, 'Content', Box);\nconst LayoutPhoneDrawer = piecePart(THEME_NAME, 'PhoneDrawer', Drawer);\n\n/** Los dos estilos de barra. */\nexport const MENU_POSITION = Object.freeze({side: 'side', top: 'top'});\n\nconst NAVIGATING_BAR_PIXELS = 2;\n\n/**\n * Un grupo de la barra: con la barra en cápsulas, su cápsula (BarCapsule: de vidrio, o con el minimalista un bloque del\n * tono de las tarjetas); con la franja, sus piezas tal cual (sin caja de más, para que la franja se quede idéntica).\n */\nconst BarGroup = ({isCapsule, sx, children}) => {\n if (!isCapsule) {\n return children;\n }\n // presentation: lo de adentro (la ☰, el nombre, la cuenta) ya se anuncia solo; el grupo es solo la forma\n return <BarCapsule role=\"presentation\" sx={sx}>{children}</BarCapsule>;\n};\n\n/** «Saltar al contenido»: escondido arriba hasta que llega el foco del teclado. */\nconst SkipToContentLink = () => {\n const {t} = useToolkitTranslation('layout');\n return (\n <LayoutSkipLink href={`#${MAIN_CONTENT_ID}`} ownSx={{\n position: 'absolute', left: 8, top: -48, zIndex: (theme) => theme.zIndex.tooltip + 1, bgcolor: 'background.paper',\n px: 1.5, py: 0.75, borderRadius: 1, boxShadow: 3, '&:focus': {top: 8},\n }}>\n {t('skipToContent')}\n </LayoutSkipLink>\n );\n};\n\n/** El logo y el nombre de la app en la barra (con su renglón chico, si lo hay), o el logo ancho; lleva al inicio. */\nconst BarBrand = ({logo, wordmark, brandName, brandCaption, homePath, sx}) => {\n const {Link: RouterLink} = useToolkitNavigation();\n return (\n <LayoutBrand component={RouterLink} to={homePath} aria-label={wordmark ? brandName : undefined}\n ownSx={[{alignItems: 'center', gap: 1.25, borderRadius: 1, flexShrink: 0, minWidth: 0, pr: 1, textAlign: 'left'}, sx]}>\n {wordmark ? <Wordmark>{wordmark}</Wordmark> : (\n <>\n {logo && <LayoutBrandLogo ownSx={{width: 28, height: 28, flex: '0 0 auto', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</LayoutBrandLogo>}\n <LayoutBrandText ownSx={{minWidth: 0}}>\n <LayoutBrandName variant=\"subtitle2\" component=\"span\" noWrap ownSx={{display: 'block', fontWeight: 600, lineHeight: 1.3}}>{brandName}</LayoutBrandName>\n {/* el renglón chico hereda el color de la barra (sobre el naranja, el gris del texto secundario no se leía) */}\n {brandCaption && <LayoutBrandCaption variant=\"caption\" component=\"span\" noWrap ownSx={{display: 'block', lineHeight: 1.3, opacity: 0.8}}>{brandCaption}</LayoutBrandCaption>}\n </LayoutBrandText>\n </>\n )}\n </LayoutBrand>\n );\n};\n\n/**\n * El título en la barra: en escritorio, después del nombre de la app y solo cuando el título grande ya no se ve; en el\n * teléfono siempre (o el nombre de la app).\n */\nconst BarTitle = ({brandName}) => {\n const {title, isTitleVisible} = usePageTitle();\n return (\n <LayoutTitleArea ownSx={{flexGrow: 1, minWidth: 0}}>\n <LayoutPhoneTitle variant=\"subtitle1\" component=\"p\" noWrap ownSx={{display: 'block', [DESKTOP_MEDIA_QUERY]: {display: 'none'}, fontWeight: 600}}>{title ?? brandName}</LayoutPhoneTitle>\n <Fade in={Boolean(title) && !isTitleVisible}>\n <LayoutDesktopTitle variant=\"subtitle1\" component=\"p\" noWrap\n ownSx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'block'}, fontWeight: 600, ml: 1, pl: 2, borderLeft: '1px solid color-mix(in srgb, currentColor 30%, transparent)'}}>\n {title}\n </LayoutDesktopTitle>\n </Fade>\n </LayoutTitleArea>\n );\n};\n\n/** El logo solo, arriba del menú encogido que hace de barra; lleva al inicio. */\nconst RailBrand = ({logo, brandName, homePath}) => {\n const {Link: RouterLink} = useToolkitNavigation();\n return (\n <Tooltip title={brandName} placement=\"right\">\n <LayoutRailBrand component={RouterLink} to={homePath} aria-label={brandName}\n ownSx={{width: 44, height: 44, borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>\n <LayoutRailLogo ownSx={{width: 28, height: 28, display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</LayoutRailLogo>\n </LayoutRailBrand>\n </Tooltip>\n );\n};\n\n/** La ☰ de escritorio: encoge el menú lateral a solo íconos o lo vuelve a abrir. */\nconst CollapseMenuButton = ({collapsed, onToggle}) => {\n const {t} = useToolkitTranslation('layout');\n const label = collapsed ? t('drawer.expand') : t('drawer.collapse');\n return (\n <Tooltip title={label}>\n <LayoutCollapseButton aria-label={label} aria-expanded={!collapsed} onClick={onToggle} ownSx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'inline-flex'}, color: 'inherit'}}>\n {collapsed ? <MenuIcon /> : <MenuOpenIcon />}\n </LayoutCollapseButton>\n </Tooltip>\n );\n};\n\nconst AppLayoutFrame = ({\n logo, wordmark, brandName, brandCaption, homePath, menuItems, menuPosition, user, profilePath, accountMenuItems, onSignOut, isSigningOut, headerActions,\n accountSettings, menuBadges, sidebarFooter, showFontSizeToggle, showLanguageToggle, showColorSchemeToggle, ribbons, isNavigating, defaultCollapsed, minimizeTabBarOnScroll, contentMaxWidth,\n onMenuCollapse, onMobileMenuChange, onMobileTabsChange, children,\n}) => {\n const {t} = useToolkitTranslation('layout');\n const {useLocation} = useToolkitNavigation();\n const {pathname} = useLocation();\n const {collapsed, toggle} = useDrawerCollapsed(defaultCollapsed);\n const [isMobileMenuOpen, setIsMobileMenuOpenState] = useState(false);\n // cada cambio del menú también sale afuera (para medir, o para que el proyecto guarde la preferencia en su servidor)\n const toggleCollapsed = () => {\n toggle();\n onMenuCollapse?.(!collapsed);\n };\n const setIsMobileMenuOpen = (isOpen) => {\n setIsMobileMenuOpenState(isOpen);\n onMobileMenuChange?.(isOpen);\n };\n const appBarRef = useAppBarHeightPublisher();\n useNavigationTrail();\n\n const theme = useTheme();\n const isGlass = isGlassTheme(theme);\n // la barra de pestañas del teléfono (estilo Apple): con vidrio, y con el minimalista en cápsulas (usesMobileTabBar);\n // sin vidrio, o con el minimalista en franja, se queda la barra de MUI arriba con su cajón\n const usesTabBar = usesMobileTabBar(theme);\n\n const isSideMenu = menuPosition !== MENU_POSITION.top;\n // con vidrio y el menú encogido, en escritorio la barra de arriba desaparece y se funde con el menú: la ☰ y el logo van\n // arriba del menú y los ajustes y la cuenta abajo (lo pidió el autor). Si el proyecto trae avisos en la barra (ribbons),\n // la barra se queda: los avisos no tendrían dónde ir\n // la barra sin franja, en cápsulas (lo de omisión con vidrio y con el minimalista; TOP_BAR.band pide la franja). El\n // estilo de Stackcraft sin vidrio se queda con su barra de siempre\n const isMinimalLook = theme.toolkit?.look === THEME_LOOK.minimal;\n const usesBarCapsules = (isGlass || isMinimalLook) && theme.toolkit?.bar === TOP_BAR.capsules;\n // con vidrio, o con cápsulas, la barra y el menú lateral van a GLASS_PANEL_GAP_PIXELS de la orilla: la columna del menú\n // mide eso de más. OJO: con el minimalista en cápsulas era 0 y las cápsulas quedaban pegadas arriba (a 4 px) y el menú\n // pegado a la izquierda (lo reportó el autor; medido en Chrome)\n const panelGap = isGlass || usesBarCapsules ? GLASS_PANEL_GAP_PIXELS : 0;\n // con cápsulas no se funde: no hay franja que esconder, y la cuenta y los ajustes se quedan arriba en su cápsula en\n // lugar de bajar al pie del menú encogido (lo pidió el autor)\n const isBarMerged = isGlass && isSideMenu && collapsed && !ribbons && !usesBarCapsules;\n const drawerWidth = collapsed ? DRAWER_WIDTH_COLLAPSED : DRAWER_WIDTH_EXPANDED;\n const activeItem = activeMenuItemOf(menuItems, pathname);\n const sideMenuProps = {logo, wordmark, brandName, brandCaption, homePath, menuItems, activeItem, menuBadges, footer: sidebarFooter};\n // el lugar de la barra donde caen las acciones de cada pantalla (BarActions); con la barra fundida con el menú no hay\n // barra en escritorio y se quedan en la pantalla\n const [barActionsSlot, setBarActionsSlot] = useState(null);\n // en el teléfono con cápsulas no hay barra de arriba (la de pestañas va abajo): las acciones flotan arriba a la derecha\n const usesPhoneFloatingActions = usesTabBar && usesBarCapsules;\n const [phoneBarActionsSlot, setPhoneBarActionsSlot] = useState(null);\n const barActions = useMemo(() => ({\n slot: isBarMerged ? null : barActionsSlot,\n phoneSlot: usesPhoneFloatingActions ? phoneBarActionsSlot : null,\n usesCapsules: usesBarCapsules,\n }), [isBarMerged, barActionsSlot, usesPhoneFloatingActions, phoneBarActionsSlot, usesBarCapsules]);\n\n return (\n <BarActionsSlotContext.Provider value={barActions}>\n <LayoutRoot ownSx={[{display: 'flex', flexDirection: 'column', minHeight: '100vh', bgcolor: 'background.default'}, isGlass && ambientBackgroundOf]}>\n <SkipToContentLink />\n <GlassLensFilter />\n\n {/* en cápsulas, lo que pasa por debajo de la barra se desenfoca en la orilla: debajo del menú lateral, que sigue nítido */}\n {isGlass && usesBarCapsules && (\n <LayoutScrollEdge aria-hidden=\"true\"\n ownSx={(theme) => ({\n ...scrollEdgeStylesOf(theme), display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'block'},\n position: 'fixed', top: 0, left: 0, right: 0, height: `calc(${APP_BAR_HEIGHT} + ${panelGap}px)`,\n zIndex: theme.zIndex.drawer - 1, pointerEvents: 'none',\n })} />\n )}\n {/* en cápsulas con vidrio la barra va transparente (color=\"transparent\": el tema no le pone vidrio) y cada grupo\n lleva el suyo; con el minimalista se queda del color del fondo, que tapa lo que pasa por debajo */}\n <LayoutBar ref={appBarRef} position=\"sticky\" color={isGlass && usesBarCapsules ? 'transparent' : undefined}\n ownSx={(theme) => ({\n pt: 'env(safe-area-inset-top)',\n // encima del menú lateral, como en el DashboardLayout de MUI\n zIndex: theme.zIndex.drawer + 1,\n // con vidrio flota: en escritorio arriba, separada de las orillas; en el teléfono ABAJO, en una cápsula,\n // como la barra de Safari en el iPhone (en el teléfono se veía cuadrada y pegada arriba; lo reportaron).\n // Abajo se suma la zona del gesto de inicio del iPhone (safe-area) a la separación\n ...(isGlass && {\n // en cápsulas no se recorta: la sombra de cada cápsula se saldría cortada\n overflow: usesBarCapsules ? 'visible' : 'hidden',\n [DESKTOP_MEDIA_QUERY]: {\n top: panelGap, mt: `${panelGap}px`, mx: `${panelGap}px`, width: 'auto',\n borderRadius: PANEL_RADIUS,\n // sin la raya de abajo de la barra fija: no hay franja que separar\n ...(usesBarCapsules && {borderBottom: 0, boxShadow: 'none'}),\n ...(isBarMerged && {display: 'none'}),\n },\n }),\n // el minimalista en cápsulas no flota (su barra es del color del fondo y tapa lo que pasa por debajo):\n // la separación de las orillas va por dentro, para que las cápsulas queden donde las del vidrio\n ...(!isGlass && usesBarCapsules && {\n [DESKTOP_MEDIA_QUERY]: {pt: `calc(env(safe-area-inset-top) + ${panelGap}px)`, px: `${panelGap}px`},\n }),\n // en el teléfono la barra de pestañas (MobileTabBar) la reemplaza: con ella van el menú y la cuenta\n ...(usesTabBar && {[PHONE_MEDIA_QUERY]: {display: 'none'}}),\n })}>\n {/* a la izquierda, la ☰ queda alineada con los íconos del menú lateral (los dos a 32 px de su orilla) */}\n <LayoutToolbar disableGutters ownSx={{minHeight: {xs: APP_BAR_HEIGHT_PIXELS, sm: APP_BAR_HEIGHT_PIXELS}, gap: 1, pl: {xs: 1.5, md: isSideMenu ? 1.5 : 3}, pr: {xs: 1.5, md: 3}}}>\n {/* la ☰ del teléfono va en la primera cápsula (en escritorio la de encoger el menú y el nombre). OJO: dentro de\n una cápsula, sin el margen negativo de «orilla de inicio» de MUI (-12 px): el botón quedaba pegado a la\n curva. Así su círculo queda concéntrico con la cápsula */}\n <BarGroup isCapsule={usesBarCapsules}>\n <LayoutMenuButton edge=\"start\" aria-label={t('drawer.open')} aria-expanded={isMobileMenuOpen} onClick={() => setIsMobileMenuOpen(true)}\n ownSx={{display: 'inline-flex', [DESKTOP_MEDIA_QUERY]: {display: 'none'}, color: 'inherit', ...((isGlass || usesBarCapsules) && {ml: 0})}}>\n <MenuIcon />\n </LayoutMenuButton>\n {isSideMenu && <CollapseMenuButton collapsed={collapsed} onToggle={toggleCollapsed} />}\n <BarBrand logo={logo} wordmark={wordmark} brandName={brandName} brandCaption={brandCaption} homePath={homePath}\n sx={isSideMenu ? {display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'flex'}} : {display: 'flex'}} />\n </BarGroup>\n {isSideMenu ? (\n <BarTitle brandName={brandName} />\n ) : (\n <>\n {/* el menú de arriba no sale en el teléfono: su cápsula tampoco (vacía se vería) */}\n <BarGroup isCapsule={usesBarCapsules} sx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'flex'}}}>\n <TopMenu menuItems={menuItems} activeItem={activeItem} />\n </BarGroup>\n <LayoutSpacer ownSx={{flexGrow: 1}} />\n </>\n )}\n {/* las acciones de la pantalla abierta (BarActions, y las de PageHeading con cápsulas): cada grupo cae aquí,\n antes de la cuenta. Solo en escritorio: en el teléfono flotan arriba (phoneBarActionsSlot, en el contenido) */}\n <LayoutTools ref={setBarActionsSlot} ownSx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'flex'}, alignItems: 'center', gap: 1, minWidth: 0}} />\n <BarGroup isCapsule={usesBarCapsules}>\n <HeaderTools headerActions={headerActions} accountSettings={accountSettings} showFontSizeToggle={showFontSizeToggle} showLanguageToggle={showLanguageToggle}\n showColorSchemeToggle={showColorSchemeToggle} user={user} profilePath={profilePath} accountMenuItems={accountMenuItems}\n onSignOut={onSignOut} isSigningOut={isSigningOut} />\n </BarGroup>\n </LayoutToolbar>\n {ribbons}\n {/* con la barra de pestañas el aviso de versión nueva flota aparte, en su cápsula (en el teléfono esta barra no\n se ve); sin ella, franja dentro de la barra */}\n {!usesTabBar && <NewBuildNotice />}\n {isNavigating && (\n <LayoutProgress aria-label={t('navigating')} color=\"inherit\"\n ownSx={{position: 'absolute', bottom: 0, left: 0, right: 0, height: NAVIGATING_BAR_PIXELS}} />\n )}\n </LayoutBar>\n {usesTabBar && <NewBuildNotice variant={NEW_BUILD_NOTICE_VARIANT.floating} />}\n {usesTabBar && (\n <MobileTabBar menuItems={menuItems} activeItem={activeItem} menuBadges={menuBadges} moreFooter={sidebarFooter} minimizeOnScroll={minimizeTabBarOnScroll}\n onPinnedTabsChange={onMobileTabsChange}\n account={(\n <HeaderTools headerActions={headerActions} accountSettings={accountSettings} showFontSizeToggle={showFontSizeToggle}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle} user={user}\n profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut} isSigningOut={isSigningOut} />\n )} />\n )}\n\n <LayoutBody ownSx={{display: 'flex', flexGrow: 1, minWidth: 0}}>\n {isSideMenu && (\n <LayoutDrawer variant=\"permanent\"\n ownSx={(theme) => ({\n display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'block'}, width: drawerWidth + panelGap, flexShrink: 0, whiteSpace: 'nowrap',\n transition: drawerTransitionOf(theme),\n '& .MuiDrawer-paper': {\n width: drawerWidth, left: panelGap, boxSizing: 'border-box', overflowX: 'hidden', transition: drawerTransitionOf(theme, ['width']),\n // justo debajo de la barra (su alto real, con avisos o sin ellos) y hasta abajo; si la barra se\n // fundió con el menú, de arriba a abajo\n ...(isBarMerged\n ? {top: panelGap, height: `calc(100% - ${panelGap * 2}px)`}\n : {top: `calc(${APP_BAR_HEIGHT} + ${panelGap}px)`, height: `calc(100% - ${APP_BAR_HEIGHT} - ${panelGap * 2}px)`}),\n // el panel flotante: separado de las orillas y sin la línea de la derecha (lo separa su brillo).\n // Encogido es una cápsula (radio de la mitad de su ancho), como las barras de pestañas de vidrio\n ...(isGlass && {\n border: 0,\n borderRadius: PANEL_RADIUS,\n }),\n },\n })}>\n <SideMenu {...sideMenuProps} showBrand={false} collapsed={collapsed}\n railTop={isBarMerged ? (\n <>\n <CollapseMenuButton collapsed={collapsed} onToggle={toggleCollapsed} />\n {logo && <RailBrand logo={logo} brandName={brandName} homePath={homePath} />}\n </>\n ) : undefined}\n railBottom={isBarMerged ? (\n <HeaderTools vertical headerActions={headerActions} accountSettings={accountSettings} showFontSizeToggle={showFontSizeToggle}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle} user={user}\n profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut}\n isSigningOut={isSigningOut} />\n ) : undefined} />\n </LayoutDrawer>\n )}\n\n <LayoutMain component=\"main\" id={MAIN_CONTENT_ID} tabIndex={-1}\n ownSx={(theme) => ({\n flexGrow: 1, minWidth: 0, outline: 'none', px: {xs: 2, md: 3, lg: 4}, pt: 3, pb: 6,\n // con la barra de pestañas abajo (teléfono): arriba, lugar para la hora y la cámara del iPhone; abajo,\n // lugar para que la barra (que flota a GLASS_PANEL_GAP_PIXELS) no tape el final de la página\n ...(usesTabBar && {\n [PHONE_MEDIA_QUERY]: {\n pt: `calc(${theme.spacing(3)} + env(safe-area-inset-top))`,\n pb: `calc(${MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait + GLASS_PANEL_GAP_PIXELS * 2}px + env(safe-area-inset-bottom) + ${theme.spacing(3)} + var(${FLOATING_BOTTOM_SPACE_CSS_VARIABLE}, 0px))`,\n },\n }),\n })}>\n {/* teléfono con cápsulas: el renglón de las acciones de la pantalla, arriba a la derecha. Va pegado (sticky)\n y no fijo: así ocupa su lugar arriba de la página (no tapa las migas ni el título) y al bajar se queda\n flotando. Vacío no se ve. Solo las cápsulas reciben clics: el hueco de la izquierda deja pasar el dedo\n a lo de abajo */}\n {usesPhoneFloatingActions && (\n <LayoutPhoneSlot ref={setPhoneBarActionsSlot} data-phone-bar-actions=\"\"\n ownSx={(theme) => ({\n display: 'none',\n [PHONE_MEDIA_QUERY]: {\n display: 'flex', '&:empty': {display: 'none'},\n position: 'sticky', top: `calc(env(safe-area-inset-top) + ${GLASS_PANEL_GAP_PIXELS}px)`, zIndex: theme.zIndex.appBar,\n justifyContent: 'flex-end', alignItems: 'center', gap: 1, mb: 2,\n pointerEvents: 'none', '& > *': {pointerEvents: 'auto'},\n },\n })} />\n )}\n <LayoutContent ownSx={{maxWidth: contentMaxWidth, mx: 'auto'}}>{children}</LayoutContent>\n </LayoutMain>\n </LayoutBody>\n\n {/* el cajón del teléfono (los dos estilos): con el logo arriba, se cierra al elegir una pantalla */}\n <LayoutPhoneDrawer variant=\"temporary\" open={isMobileMenuOpen} onClose={() => setIsMobileMenuOpen(false)} ModalProps={{keepMounted: true}}\n ownSx={{[DESKTOP_MEDIA_QUERY]: {display: 'none'}}}\n slotProps={{paper: {sx: {width: DRAWER_WIDTH_EXPANDED, boxSizing: 'border-box', pt: 'env(safe-area-inset-top)', pb: 'env(safe-area-inset-bottom)'}}}}>\n <SideMenu {...sideMenuProps} collapsed={false} onNavigate={() => setIsMobileMenuOpen(false)} />\n </LayoutPhoneDrawer>\n </LayoutRoot>\n </BarActionsSlotContext.Provider>\n );\n};\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.logo] el logo chico (28 px), en la barra junto al nombre y en el cajón del teléfono\n * @param {import('react').ReactNode | {light?: import('react').ReactNode, dark?: import('react').ReactNode}} [props.wordmark] el logo\n * ancho, la marca con su nombre en una sola imagen (como el de muchas empresas), o uno para cada modo ({light, dark}: el de\n * color en claro y el blanco en oscuro): va en lugar del logo y el nombre en la barra y arriba del menú del teléfono, a 24 px de alto. Con el menú\n * encogido se queda el logo chico (logo), si lo hay. brandName sigue siendo su nombre para el lector de pantalla\n * @param {string} [props.brandName] el nombre de la app; por omisión el appName de ToolkitProvider\n * @param {string} [props.brandCaption] el renglón chico debajo del nombre («Panel de administración»)\n * @param {string} [props.homePath] por omisión '/'\n * @param {object[]} [props.menuItems] lo que regresa composeMenu\n * @param {'side'|'top'} [props.menuPosition] por omisión 'side' (MENU_POSITION)\n * @param {{name: string, email?: string, subtitle?: string, avatarUrl?: string}|null} [props.user] quién está dentro\n * @param {string} [props.profilePath] la ruta de Mi perfil\n * @param {object[]} [props.accountMenuItems] renglones propios en el menú de la cuenta ({to | onClick, label | labelKey, Icon})\n * @param {() => void} [props.onSignOut] sin él no sale «Salir» (una app sin sesión)\n * @param {boolean} [props.isSigningOut]\n * @param {import('react').ReactNode} [props.headerActions] botones propios en la barra, antes de la cuenta\n * @param {Record<string, number>} [props.menuBadges] los conteos del servidor por badgeKey de cada entrada del menú\n * (useMenuBadges): lo pendiente de cada pantalla, como numerito\n * @param {import('react').ReactNode} [props.accountSettings] ajustes propios del proyecto dentro del menú de la cuenta, debajo de\n * letra, idioma y claro u oscuro (con SettingSection, para que se vean igual)\n * @param {import('react').ReactNode} [props.sidebarFooter] lo de abajo del menú lateral (una tarjeta de ayuda…)\n * @param {boolean} [props.showFontSizeToggle] por omisión sí\n * @param {boolean} [props.showLanguageToggle] por omisión sí\n * @param {boolean} [props.showColorSchemeToggle] por omisión sí\n * @param {import('react').ReactNode} [props.ribbons] avisos propios dentro de la barra\n * @param {boolean} [props.isNavigating] la pantalla siguiente se está descargando (react-router: useIsNavigating)\n * @param {boolean} [props.defaultCollapsed] el menú lateral empieza encogido (la persona lo cambia y se recuerda)\n * @param {boolean} [props.minimizeTabBarOnScroll] en el teléfono con vidrio, la barra de pestañas se encoge al leer hacia\n * abajo y regresa al subir (como iOS 26); por omisión sí\n * @param {number|string} [props.contentMaxWidth] por omisión 1400\n * @param {(collapsed: boolean) => void} [props.onMenuCollapse] la persona encogió (true) o abrió (false) el menú lateral\n * @param {(isOpen: boolean) => void} [props.onMobileMenuChange] se abrió o se cerró el menú del teléfono (el cajón)\n * @param {(keys: string[]|null) => void} [props.onMobileTabsChange] la persona eligió sus pestañas del teléfono (las llaves\n * de menuItemKeyOf; null: regresó a las de omisión). Se recuerdan en el navegador; con esto el proyecto las puede guardar\n * en su servidor\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete (para todo el marco)\n * @param {import('react').ReactNode} props.children el contenido\n */\nexport const AppLayout = (props) => {\n // lo que el proyecto puso en su tema (components.CalcitaAppLayout.defaultProps) y encima lo que llega aquí\n const {\n logo, wordmark, brandName, brandCaption, homePath = '/', menuItems = [], menuPosition = MENU_POSITION.side, user = null, profilePath, accountMenuItems = [], onSignOut,\n isSigningOut = false, headerActions, accountSettings, menuBadges, sidebarFooter, showFontSizeToggle = true, showLanguageToggle = true, showColorSchemeToggle = true, ribbons,\n isNavigating = false, defaultCollapsed = false, minimizeTabBarOnScroll = true, contentMaxWidth = 1400, onMenuCollapse, onMobileMenuChange, onMobileTabsChange,\n texts, children,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {appName} = useToolkitSettings();\n // un ícono ya pintado (icon) se vuelve componente aquí, una vez: las piezas del menú pintan siempre Icon\n const shownMenuItems = useMemo(() => menuItemsWithIconsOf(menuItems), [menuItems]);\n const appMenu = useMemo(() => ({menuItems: shownMenuItems}), [shownMenuItems]);\n // los textos del marco llegan a todas sus piezas (la cuenta, el menú, las pestañas del teléfono), cada una lee los suyos\n return (\n <ComponentTexts namespace=\"layout\" texts={texts}>\n <PageTitleProvider>\n <AppMenuContext.Provider value={appMenu}>\n <AppLayoutFrame logo={logo} wordmark={wordmark} brandName={brandName ?? appName} brandCaption={brandCaption} homePath={homePath} menuItems={shownMenuItems} menuPosition={menuPosition}\n user={user} profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut} isSigningOut={isSigningOut}\n headerActions={headerActions} accountSettings={accountSettings} menuBadges={menuBadges} sidebarFooter={sidebarFooter} showFontSizeToggle={showFontSizeToggle}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle} ribbons={ribbons}\n isNavigating={isNavigating} defaultCollapsed={defaultCollapsed} minimizeTabBarOnScroll={minimizeTabBarOnScroll}\n contentMaxWidth={contentMaxWidth} onMenuCollapse={onMenuCollapse} onMobileMenuChange={onMobileMenuChange}\n onMobileTabsChange={onMobileTabsChange}>\n {children}\n </AppLayoutFrame>\n </AppMenuContext.Provider>\n </PageTitleProvider>\n </ComponentTexts>\n );\n};\n"],"names":["theme"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AppLayout.js","sources":["../../src/appShell/AppLayout.jsx"],"sourcesContent":["// El marco de las pantallas con sesión, al estilo de las plantillas de MUI (y del marco de walk-ot). Dos estilos de\n// barra con las mismas props, para que el proyecto (o el `init` del CLI) solo elija:\n//\n// menuPosition=\"side\" (por omisión) menuPosition=\"top\" (apps de pocos módulos)\n// ┌──────────────────────────────────────────┐ ┌──────────────────────────────────────────┐\n// │ ☰ Logo Nombre · Título al deslizar · ⚙ (A)│ │ Logo · Inicio Pedidos Clientes ▾ · ⚙ (A) │\n// ├────────┬─────────────────────────────────┤ ├──────────────────────────────────────────┤\n// │ Menú │ contenido │ │ contenido │\n// │ por │ │ │ │\n// │ secc. │ │ │ │\n// └────────┴─────────────────────────────────┘ └──────────────────────────────────────────┘\n//\n// En el teléfono los dos son iguales: hamburguesa, título y ajustes en la barra; el menú sale en un cajón con el logo.\n//\n// Lo que trae, con su porqué:\n// - La barra va a todo lo ancho, con el logo y el nombre de la app a la izquierda, y el menú lateral debajo de ella\n// (como el DashboardLayout de MUI). La ☰ de la barra encoge el menú a solo íconos y lo recuerda (useDrawerCollapsed);\n// antes era un botón montado en la orilla del menú y se encimaba con él.\n// - El título de la página sube a la barra cuando su título grande sale de la vista (pageTitle.jsx).\n// - Escritorio y teléfono se eligen con CSS, no con useMediaQuery: el servidor (Next.js) ya pinta lo correcto.\n// - Dentro de la barra, para que se queden pegados al deslizar: los avisos del proyecto (ribbons), el de versión nueva\n// (NewBuildNotice; con vidrio flota aparte en su cápsula, ver NewBuildNotice.jsx) y la rayita de «cargando la pantalla»\n// (isNavigating). La barra publica su alto real, y el menú lateral empieza justo debajo de ella aunque crezca con un aviso.\n// - Con vidrio, en el teléfono la barra flota ABAJO en una cápsula, como la de Safari en el iPhone; y en escritorio, con\n// el menú encogido, la barra desaparece y se funde con el menú (☰ y logo arriba, ajustes y cuenta abajo).\n// - El primer Tab lleva a «Saltar al contenido» (WCAG 2.4.1) y el contenido es <main>. Respeta el área segura del\n// iPhone (la muesca) cuando la app corre instalada.\n// - Huecos para extender sin tocar el framework: headerActions, sidebarFooter, accountMenuItems, accountSettings, ribbons.\n// - Los ajustes de la app (letra, idioma, claro u oscuro y los del proyecto) van DENTRO del menú de la cuenta, no sueltos\n// en la barra (HeaderTools).\n// - El menú queda al alcance de las páginas (appMenuContext): PageHeading arma sus migas sola.\n// - Con el vidrio del tema (createToolkitTheme({glass: true})): el lienzo lleva manchas de color, y en escritorio la\n// barra y el menú lateral flotan a 8 px de la orilla y entre ellos, con esquinas redondas, para que el contenido pase\n// por detrás y se vea desenfocado; encogido, el menú es una cápsula. En el teléfono la barra sigue de orilla a orilla\n// (como en iOS). Sin vidrio, todo igual que siempre: el marco lo sabe por el tema (isGlassTheme), sin otra prop.\n// - Con vidrio y con el minimalista la barra no lleva franja, como las ventanas de macOS Tahoe (TOP_BAR.capsules, lo de\n// omisión): la ☰ con el nombre, el menú de arriba y la cuenta van cada uno en su cápsula, y el título queda suelto.\n// Con vidrio las cápsulas son de vidrio y el contenido pasa por debajo, desenfocado en la orilla (scrollEdgeStylesOf);\n// con el minimalista son bloques del tono de las tarjetas sobre la barra del color del fondo, también en el teléfono.\n// Con cápsulas el menú encogido ya no se funde con la barra: la cuenta y los ajustes se quedan arriba. Con\n// bar: TOP_BAR.band, la franja de lado a lado. Mismo alto y mismo lugar las dos: el menú lateral y las páginas no se\n// mueven.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAppLayout con defaultProps y\n// styleOverrides de sus partes: skipLink, brand, brandLogo, brandText, brandName, brandCaption, titleArea, phoneTitle,\n// desktopTitle, railBrand, railLogo, collapseButton, root, scrollEdge, bar, toolbar, menuButton, spacer, tools,\n// progress, body, drawer, main, phoneSlot, content, phoneDrawer.\n//\n// Lo renderiza la app: arrow (regla de la casa).\nimport {useMemo, useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {useToolkitNavigation, useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport AppBar from '@mui/material/AppBar';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Drawer from '@mui/material/Drawer';\nimport Fade from '@mui/material/Fade';\nimport IconButton from '@mui/material/IconButton';\nimport LinearProgress from '@mui/material/LinearProgress';\nimport Link from '@mui/material/Link';\nimport Toolbar from '@mui/material/Toolbar';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\nimport MenuIcon from '@mui/icons-material/Menu';\nimport MenuOpenIcon from '@mui/icons-material/MenuOpen';\n\nimport {AppMenuContext} from '@/appShell/appMenuContext.js';\nimport BarCapsule from '@/appShell/BarCapsule.jsx';\nimport {BarActionsSlotContext} from '@/appShell/barActionsSlot.js';\nimport HeaderTools from '@/appShell/HeaderTools.jsx';\nimport MobileTabBar from '@/appShell/MobileTabBar.jsx';\nimport Wordmark from '@/appShell/Wordmark.jsx';\nimport {PageTitleProvider, usePageTitle} from '@/appShell/pageTitle.jsx';\nimport {\n APP_BAR_HEIGHT_PIXELS, DESKTOP_MEDIA_QUERY, DRAWER_WIDTH_COLLAPSED, DRAWER_WIDTH_EXPANDED, GLASS_PANEL_GAP_PIXELS, MAIN_CONTENT_ID,\n FLOATING_BOTTOM_SPACE_CSS_VARIABLE, MOBILE_TAB_BAR_HEIGHT_PIXELS, PHONE_MEDIA_QUERY, drawerTransitionOf,\n} from '@/appShell/shellSizes.js';\nimport SideMenu from '@/appShell/SideMenu.jsx';\nimport {usesMobileTabBar} from '@/appShell/tabBarRule.js';\nimport TopMenu from '@/appShell/TopMenu.jsx';\nimport {useDrawerCollapsed} from '@/appShell/useDrawerCollapsed.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport NewBuildNotice, {NEW_BUILD_NOTICE_VARIANT} from '@/feedback/NewBuildNotice.jsx';\nimport {activeMenuItemOf, menuItemsWithIconsOf} from '@/navigation/appMenu.js';\nimport {useNavigationTrail} from '@/navigationTrail.js';\nimport {THEME_LOOK, TOP_BAR} from '@/theme/createToolkitTheme.js';\nimport {PANEL_RADIUS, ambientBackgroundOf, isGlassTheme, scrollEdgeStylesOf} from '@/theme/glassSurface.js';\nimport GlassLensFilter from '@/ui/layout/GlassLensFilter.jsx';\nimport {APP_BAR_HEIGHT, useAppBarHeightPublisher} from '@/ui/layout/appBarHeight.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.CalcitaAppLayout)\nconst THEME_NAME = 'CalcitaAppLayout';\nconst LayoutSkipLink = piecePart(THEME_NAME, 'SkipLink', Link);\nconst LayoutBrand = piecePart(THEME_NAME, 'Brand', ButtonBase);\nconst LayoutBrandLogo = piecePart(THEME_NAME, 'BrandLogo', Box);\nconst LayoutBrandText = piecePart(THEME_NAME, 'BrandText', Box);\nconst LayoutBrandName = piecePart(THEME_NAME, 'BrandName', Typography);\nconst LayoutBrandCaption = piecePart(THEME_NAME, 'BrandCaption', Typography);\nconst LayoutTitleArea = piecePart(THEME_NAME, 'TitleArea', Box);\nconst LayoutPhoneTitle = piecePart(THEME_NAME, 'PhoneTitle', Typography);\nconst LayoutDesktopTitle = piecePart(THEME_NAME, 'DesktopTitle', Typography);\nconst LayoutRailBrand = piecePart(THEME_NAME, 'RailBrand', ButtonBase);\nconst LayoutRailLogo = piecePart(THEME_NAME, 'RailLogo', Box);\nconst LayoutCollapseButton = piecePart(THEME_NAME, 'CollapseButton', IconButton);\nconst LayoutRoot = piecePart(THEME_NAME, 'Root', Box);\nconst LayoutScrollEdge = piecePart(THEME_NAME, 'ScrollEdge', Box);\nconst LayoutBar = piecePart(THEME_NAME, 'Bar', AppBar);\nconst LayoutToolbar = piecePart(THEME_NAME, 'Toolbar', Toolbar);\nconst LayoutMenuButton = piecePart(THEME_NAME, 'MenuButton', IconButton);\nconst LayoutSpacer = piecePart(THEME_NAME, 'Spacer', Box);\nconst LayoutTools = piecePart(THEME_NAME, 'Tools', Box);\nconst LayoutProgress = piecePart(THEME_NAME, 'Progress', LinearProgress);\nconst LayoutBody = piecePart(THEME_NAME, 'Body', Box);\nconst LayoutDrawer = piecePart(THEME_NAME, 'Drawer', Drawer);\nconst LayoutMain = piecePart(THEME_NAME, 'Main', Box);\nconst LayoutPhoneSlot = piecePart(THEME_NAME, 'PhoneSlot', Box);\nconst LayoutContent = piecePart(THEME_NAME, 'Content', Box);\nconst LayoutPhoneDrawer = piecePart(THEME_NAME, 'PhoneDrawer', Drawer);\n\n/** Los dos estilos de barra. */\nexport const MENU_POSITION = Object.freeze({side: 'side', top: 'top'});\n\nconst NAVIGATING_BAR_PIXELS = 2;\n\n/**\n * Un grupo de la barra: con la barra en cápsulas, su cápsula (BarCapsule: de vidrio, o con el minimalista un bloque del\n * tono de las tarjetas); con la franja, sus piezas tal cual (sin caja de más, para que la franja se quede idéntica).\n */\nconst BarGroup = ({isCapsule, sx, children}) => {\n if (!isCapsule) {\n return children;\n }\n // presentation: lo de adentro (la ☰, el nombre, la cuenta) ya se anuncia solo; el grupo es solo la forma\n return <BarCapsule role=\"presentation\" sx={sx}>{children}</BarCapsule>;\n};\n\n/** «Saltar al contenido»: escondido arriba hasta que llega el foco del teclado. */\nconst SkipToContentLink = () => {\n const {t} = useToolkitTranslation('layout');\n return (\n <LayoutSkipLink href={`#${MAIN_CONTENT_ID}`} ownSx={{\n position: 'absolute', left: 8, top: -48, zIndex: (theme) => theme.zIndex.tooltip + 1, bgcolor: 'background.paper',\n px: 1.5, py: 0.75, borderRadius: 1, boxShadow: 3, '&:focus': {top: 8},\n }}>\n {t('skipToContent')}\n </LayoutSkipLink>\n );\n};\n\n/** El logo y el nombre de la app en la barra (con su renglón chico, si lo hay), o el logo ancho; lleva al inicio. */\nconst BarBrand = ({logo, wordmark, brandName, brandCaption, homePath, sx}) => {\n const {Link: RouterLink} = useToolkitNavigation();\n return (\n <LayoutBrand component={RouterLink} to={homePath} aria-label={wordmark ? brandName : undefined}\n ownSx={[{alignItems: 'center', gap: 1.25, borderRadius: 1, flexShrink: 0, minWidth: 0, pr: 1, textAlign: 'left'}, sx]}>\n {wordmark ? <Wordmark>{wordmark}</Wordmark> : (\n <>\n {logo && <LayoutBrandLogo ownSx={{width: 28, height: 28, flex: '0 0 auto', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</LayoutBrandLogo>}\n <LayoutBrandText ownSx={{minWidth: 0}}>\n <LayoutBrandName variant=\"subtitle2\" component=\"span\" noWrap ownSx={{display: 'block', fontWeight: 600, lineHeight: 1.3}}>{brandName}</LayoutBrandName>\n {/* el renglón chico hereda el color de la barra (sobre el naranja, el gris del texto secundario no se leía) */}\n {brandCaption && <LayoutBrandCaption variant=\"caption\" component=\"span\" noWrap ownSx={{display: 'block', lineHeight: 1.3, opacity: 0.8}}>{brandCaption}</LayoutBrandCaption>}\n </LayoutBrandText>\n </>\n )}\n </LayoutBrand>\n );\n};\n\n/**\n * El título en la barra: en escritorio, después del nombre de la app y solo cuando el título grande ya no se ve; en el\n * teléfono siempre (o el nombre de la app).\n */\nconst BarTitle = ({brandName}) => {\n const {title, isTitleVisible} = usePageTitle();\n return (\n <LayoutTitleArea ownSx={{flexGrow: 1, minWidth: 0}}>\n <LayoutPhoneTitle variant=\"subtitle1\" component=\"p\" noWrap ownSx={{display: 'block', [DESKTOP_MEDIA_QUERY]: {display: 'none'}, fontWeight: 600}}>{title ?? brandName}</LayoutPhoneTitle>\n <Fade in={Boolean(title) && !isTitleVisible}>\n <LayoutDesktopTitle variant=\"subtitle1\" component=\"p\" noWrap\n ownSx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'block'}, fontWeight: 600, ml: 1, pl: 2, borderLeft: '1px solid color-mix(in srgb, currentColor 30%, transparent)'}}>\n {title}\n </LayoutDesktopTitle>\n </Fade>\n </LayoutTitleArea>\n );\n};\n\n/** El logo solo, arriba del menú encogido que hace de barra; lleva al inicio. */\nconst RailBrand = ({logo, brandName, homePath}) => {\n const {Link: RouterLink} = useToolkitNavigation();\n return (\n <Tooltip title={brandName} placement=\"right\">\n <LayoutRailBrand component={RouterLink} to={homePath} aria-label={brandName}\n ownSx={{width: 44, height: 44, borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>\n <LayoutRailLogo ownSx={{width: 28, height: 28, display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</LayoutRailLogo>\n </LayoutRailBrand>\n </Tooltip>\n );\n};\n\n/** La ☰ de escritorio: encoge el menú lateral a solo íconos o lo vuelve a abrir. */\nconst CollapseMenuButton = ({collapsed, onToggle}) => {\n const {t} = useToolkitTranslation('layout');\n const label = collapsed ? t('drawer.expand') : t('drawer.collapse');\n return (\n <Tooltip title={label}>\n <LayoutCollapseButton aria-label={label} aria-expanded={!collapsed} onClick={onToggle} ownSx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'inline-flex'}, color: 'inherit'}}>\n {collapsed ? <MenuIcon /> : <MenuOpenIcon />}\n </LayoutCollapseButton>\n </Tooltip>\n );\n};\n\nconst AppLayoutFrame = ({\n logo, wordmark, brandName, brandCaption, homePath, menuItems, menuPosition, user, profilePath, accountMenuItems, onSignOut, isSigningOut, headerActions,\n accountSettings, menuBadges, sidebarFooter, showFontSizeToggle, showLanguageToggle, showColorSchemeToggle, ribbons, isNavigating, defaultCollapsed, minimizeTabBarOnScroll, contentMaxWidth,\n onMenuCollapse, onMobileMenuChange, onMobileTabsChange, children,\n}) => {\n const {t} = useToolkitTranslation('layout');\n const {useLocation} = useToolkitNavigation();\n const {pathname} = useLocation();\n const {collapsed, toggle} = useDrawerCollapsed(defaultCollapsed);\n const [isMobileMenuOpen, setIsMobileMenuOpenState] = useState(false);\n // cada cambio del menú también sale afuera (para medir, o para que el proyecto guarde la preferencia en su servidor)\n const toggleCollapsed = () => {\n toggle();\n onMenuCollapse?.(!collapsed);\n };\n const setIsMobileMenuOpen = (isOpen) => {\n setIsMobileMenuOpenState(isOpen);\n onMobileMenuChange?.(isOpen);\n };\n const appBarRef = useAppBarHeightPublisher();\n useNavigationTrail();\n\n const theme = useTheme();\n const isGlass = isGlassTheme(theme);\n // la barra de pestañas del teléfono (estilo Apple): con vidrio, y con el minimalista en cápsulas (usesMobileTabBar);\n // sin vidrio, o con el minimalista en franja, se queda la barra de MUI arriba con su cajón\n const usesTabBar = usesMobileTabBar(theme);\n\n const isSideMenu = menuPosition !== MENU_POSITION.top;\n // con vidrio y el menú encogido, en escritorio la barra de arriba desaparece y se funde con el menú: la ☰ y el logo van\n // arriba del menú y los ajustes y la cuenta abajo (lo pidió el autor). Si el proyecto trae avisos en la barra (ribbons),\n // la barra se queda: los avisos no tendrían dónde ir\n // la barra sin franja, en cápsulas (lo de omisión con vidrio y con el minimalista; TOP_BAR.band pide la franja). El\n // estilo de Stackcraft sin vidrio se queda con su barra de siempre\n const isMinimalLook = theme.toolkit?.look === THEME_LOOK.minimal;\n const usesBarCapsules = (isGlass || isMinimalLook) && theme.toolkit?.bar === TOP_BAR.capsules;\n // con vidrio, o con cápsulas, la barra y el menú lateral van a GLASS_PANEL_GAP_PIXELS de la orilla: la columna del menú\n // mide eso de más. OJO: con el minimalista en cápsulas era 0 y las cápsulas quedaban pegadas arriba (a 4 px) y el menú\n // pegado a la izquierda (lo reportó el autor; medido en Chrome)\n const panelGap = isGlass || usesBarCapsules ? GLASS_PANEL_GAP_PIXELS : 0;\n // con cápsulas no se funde: no hay franja que esconder, y la cuenta y los ajustes se quedan arriba en su cápsula en\n // lugar de bajar al pie del menú encogido (lo pidió el autor)\n const isBarMerged = isGlass && isSideMenu && collapsed && !ribbons && !usesBarCapsules;\n const drawerWidth = collapsed ? DRAWER_WIDTH_COLLAPSED : DRAWER_WIDTH_EXPANDED;\n const activeItem = activeMenuItemOf(menuItems, pathname);\n const sideMenuProps = {logo, wordmark, brandName, brandCaption, homePath, menuItems, activeItem, menuBadges, footer: sidebarFooter};\n // el lugar de la barra donde caen las acciones de cada pantalla (BarActions); con la barra fundida con el menú no hay\n // barra en escritorio y se quedan en la pantalla\n const [barActionsSlot, setBarActionsSlot] = useState(null);\n // en el teléfono con cápsulas no hay barra de arriba (la de pestañas va abajo): las acciones flotan arriba a la derecha\n const usesPhoneFloatingActions = usesTabBar && usesBarCapsules;\n const [phoneBarActionsSlot, setPhoneBarActionsSlot] = useState(null);\n const barActions = useMemo(() => ({\n slot: isBarMerged ? null : barActionsSlot,\n phoneSlot: usesPhoneFloatingActions ? phoneBarActionsSlot : null,\n usesCapsules: usesBarCapsules,\n }), [isBarMerged, barActionsSlot, usesPhoneFloatingActions, phoneBarActionsSlot, usesBarCapsules]);\n\n return (\n <BarActionsSlotContext.Provider value={barActions}>\n <LayoutRoot ownSx={[{display: 'flex', flexDirection: 'column', minHeight: '100vh', bgcolor: 'background.default'}, isGlass && ambientBackgroundOf]}>\n <SkipToContentLink />\n <GlassLensFilter />\n\n {/* en cápsulas, lo que pasa por debajo de la barra se desenfoca en la orilla: debajo del menú lateral, que sigue nítido */}\n {isGlass && usesBarCapsules && (\n <LayoutScrollEdge aria-hidden=\"true\"\n ownSx={(theme) => ({\n ...scrollEdgeStylesOf(theme), display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'block'},\n position: 'fixed', top: 0, left: 0, right: 0, height: `calc(${APP_BAR_HEIGHT} + ${panelGap}px)`,\n zIndex: theme.zIndex.drawer - 1, pointerEvents: 'none',\n })} />\n )}\n {/* en cápsulas con vidrio la barra va transparente (color=\"transparent\": el tema no le pone vidrio) y cada grupo\n lleva el suyo; con el minimalista se queda del color del fondo, que tapa lo que pasa por debajo */}\n <LayoutBar ref={appBarRef} position=\"sticky\" color={isGlass && usesBarCapsules ? 'transparent' : undefined}\n ownSx={(theme) => ({\n pt: 'env(safe-area-inset-top)',\n // encima del menú lateral, como en el DashboardLayout de MUI\n zIndex: theme.zIndex.drawer + 1,\n // con vidrio flota: en escritorio arriba, separada de las orillas; en el teléfono ABAJO, en una cápsula,\n // como la barra de Safari en el iPhone (en el teléfono se veía cuadrada y pegada arriba; lo reportaron).\n // Abajo se suma la zona del gesto de inicio del iPhone (safe-area) a la separación\n ...(isGlass && {\n // en cápsulas no se recorta: la sombra de cada cápsula se saldría cortada\n overflow: usesBarCapsules ? 'visible' : 'hidden',\n [DESKTOP_MEDIA_QUERY]: {\n top: panelGap, mt: `${panelGap}px`, mx: `${panelGap}px`, width: 'auto',\n borderRadius: PANEL_RADIUS,\n // sin la raya de abajo de la barra fija: no hay franja que separar\n ...(usesBarCapsules && {borderBottom: 0, boxShadow: 'none'}),\n ...(isBarMerged && {display: 'none'}),\n },\n }),\n // el minimalista en cápsulas no flota (su barra es del color del fondo y tapa lo que pasa por debajo):\n // la separación de las orillas va por dentro, para que las cápsulas queden donde las del vidrio\n ...(!isGlass && usesBarCapsules && {\n [DESKTOP_MEDIA_QUERY]: {pt: `calc(env(safe-area-inset-top) + ${panelGap}px)`, px: `${panelGap}px`},\n }),\n // en el teléfono la barra de pestañas (MobileTabBar) la reemplaza: con ella van el menú y la cuenta\n ...(usesTabBar && {[PHONE_MEDIA_QUERY]: {display: 'none'}}),\n })}>\n {/* a la izquierda, la ☰ queda alineada con los íconos del menú lateral (los dos a 32 px de su orilla) */}\n <LayoutToolbar disableGutters ownSx={{minHeight: {xs: APP_BAR_HEIGHT_PIXELS, sm: APP_BAR_HEIGHT_PIXELS}, gap: 1, pl: {xs: 1.5, md: isSideMenu ? 1.5 : 3}, pr: {xs: 1.5, md: 3}}}>\n {/* la ☰ del teléfono va en la primera cápsula (en escritorio la de encoger el menú y el nombre). OJO: dentro de\n una cápsula, sin el margen negativo de «orilla de inicio» de MUI (-12 px): el botón quedaba pegado a la\n curva. Así su círculo queda concéntrico con la cápsula */}\n <BarGroup isCapsule={usesBarCapsules}>\n <LayoutMenuButton edge=\"start\" aria-label={t('drawer.open')} aria-expanded={isMobileMenuOpen} onClick={() => setIsMobileMenuOpen(true)}\n ownSx={{display: 'inline-flex', [DESKTOP_MEDIA_QUERY]: {display: 'none'}, color: 'inherit', ...((isGlass || usesBarCapsules) && {ml: 0})}}>\n <MenuIcon />\n </LayoutMenuButton>\n {isSideMenu && <CollapseMenuButton collapsed={collapsed} onToggle={toggleCollapsed} />}\n <BarBrand logo={logo} wordmark={wordmark} brandName={brandName} brandCaption={brandCaption} homePath={homePath}\n sx={isSideMenu ? {display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'flex'}} : {display: 'flex'}} />\n </BarGroup>\n {isSideMenu ? (\n <BarTitle brandName={brandName} />\n ) : (\n <>\n {/* el menú de arriba no sale en el teléfono: su cápsula tampoco (vacía se vería) */}\n <BarGroup isCapsule={usesBarCapsules} sx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'flex'}}}>\n <TopMenu menuItems={menuItems} activeItem={activeItem} />\n </BarGroup>\n <LayoutSpacer ownSx={{flexGrow: 1}} />\n </>\n )}\n {/* las acciones de la pantalla abierta (BarActions, y las de PageHeading con cápsulas): cada grupo cae aquí,\n antes de la cuenta. Solo en escritorio: en el teléfono flotan arriba (phoneBarActionsSlot, en el contenido) */}\n <LayoutTools ref={setBarActionsSlot} ownSx={{display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'flex'}, alignItems: 'center', gap: 1, minWidth: 0}} />\n <BarGroup isCapsule={usesBarCapsules}>\n <HeaderTools headerActions={headerActions} accountSettings={accountSettings} showFontSizeToggle={showFontSizeToggle} showLanguageToggle={showLanguageToggle}\n showColorSchemeToggle={showColorSchemeToggle} user={user} profilePath={profilePath} accountMenuItems={accountMenuItems}\n onSignOut={onSignOut} isSigningOut={isSigningOut} />\n </BarGroup>\n </LayoutToolbar>\n {ribbons}\n {/* con la barra de pestañas el aviso de versión nueva flota aparte, en su cápsula (en el teléfono esta barra no\n se ve); sin ella, franja dentro de la barra */}\n {!usesTabBar && <NewBuildNotice />}\n {isNavigating && (\n <LayoutProgress aria-label={t('navigating')} color=\"inherit\"\n ownSx={{position: 'absolute', bottom: 0, left: 0, right: 0, height: NAVIGATING_BAR_PIXELS}} />\n )}\n </LayoutBar>\n {usesTabBar && <NewBuildNotice variant={NEW_BUILD_NOTICE_VARIANT.floating} />}\n {usesTabBar && (\n <MobileTabBar menuItems={menuItems} activeItem={activeItem} menuBadges={menuBadges} moreFooter={sidebarFooter} minimizeOnScroll={minimizeTabBarOnScroll}\n onPinnedTabsChange={onMobileTabsChange}\n account={(\n <HeaderTools headerActions={headerActions} accountSettings={accountSettings} showFontSizeToggle={showFontSizeToggle}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle} user={user}\n profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut} isSigningOut={isSigningOut} />\n )} />\n )}\n\n <LayoutBody ownSx={{display: 'flex', flexGrow: 1, minWidth: 0}}>\n {isSideMenu && (\n <LayoutDrawer variant=\"permanent\"\n ownSx={(theme) => ({\n display: 'none', [DESKTOP_MEDIA_QUERY]: {display: 'block'}, width: drawerWidth + panelGap, flexShrink: 0, whiteSpace: 'nowrap',\n transition: drawerTransitionOf(theme),\n '& .MuiDrawer-paper': {\n width: drawerWidth, left: panelGap, boxSizing: 'border-box', overflowX: 'hidden', transition: drawerTransitionOf(theme, ['width']),\n // justo debajo de la barra (su alto real, con avisos o sin ellos) y hasta abajo; si la barra se\n // fundió con el menú, de arriba a abajo\n ...(isBarMerged\n ? {top: panelGap, height: `calc(100% - ${panelGap * 2}px)`}\n : {top: `calc(${APP_BAR_HEIGHT} + ${panelGap}px)`, height: `calc(100% - ${APP_BAR_HEIGHT} - ${panelGap * 2}px)`}),\n // el panel flotante: separado de las orillas y sin la línea de la derecha (lo separa su brillo).\n // Encogido es una cápsula (radio de la mitad de su ancho), como las barras de pestañas de vidrio\n ...(isGlass && {\n border: 0,\n borderRadius: PANEL_RADIUS,\n }),\n },\n })}>\n <SideMenu {...sideMenuProps} showBrand={false} collapsed={collapsed}\n railTop={isBarMerged ? (\n <>\n <CollapseMenuButton collapsed={collapsed} onToggle={toggleCollapsed} />\n {logo && <RailBrand logo={logo} brandName={brandName} homePath={homePath} />}\n </>\n ) : undefined}\n railBottom={isBarMerged ? (\n <HeaderTools vertical headerActions={headerActions} accountSettings={accountSettings} showFontSizeToggle={showFontSizeToggle}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle} user={user}\n profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut}\n isSigningOut={isSigningOut} />\n ) : undefined} />\n </LayoutDrawer>\n )}\n\n <LayoutMain component=\"main\" id={MAIN_CONTENT_ID} tabIndex={-1}\n ownSx={(theme) => ({\n flexGrow: 1, minWidth: 0, outline: 'none', px: {xs: 2, md: 3, lg: 4}, pt: 3, pb: 6,\n // con la barra de pestañas abajo (teléfono): arriba, lugar para la hora y la cámara del iPhone; abajo,\n // lugar para que la barra (que flota a GLASS_PANEL_GAP_PIXELS) no tape el final de la página\n ...(usesTabBar && {\n [PHONE_MEDIA_QUERY]: {\n pt: `calc(${theme.spacing(3)} + env(safe-area-inset-top))`,\n pb: `calc(${MOBILE_TAB_BAR_HEIGHT_PIXELS.portrait + GLASS_PANEL_GAP_PIXELS * 2}px + env(safe-area-inset-bottom) + ${theme.spacing(3)} + var(${FLOATING_BOTTOM_SPACE_CSS_VARIABLE}, 0px))`,\n },\n }),\n })}>\n {/* teléfono con cápsulas: el renglón de las acciones de la pantalla, arriba a la derecha. Va pegado (sticky)\n y no fijo: así ocupa su lugar arriba de la página (no tapa las migas ni el título) y al bajar se queda\n flotando. Vacío no se ve. Solo las cápsulas reciben clics: el hueco de la izquierda deja pasar el dedo\n a lo de abajo */}\n {usesPhoneFloatingActions && (\n <LayoutPhoneSlot ref={setPhoneBarActionsSlot} data-phone-bar-actions=\"\"\n ownSx={(theme) => ({\n display: 'none',\n [PHONE_MEDIA_QUERY]: {\n display: 'flex', '&:empty': {display: 'none'},\n position: 'sticky', top: `calc(env(safe-area-inset-top) + ${GLASS_PANEL_GAP_PIXELS}px)`, zIndex: theme.zIndex.appBar,\n justifyContent: 'flex-end', alignItems: 'center', gap: 1, mb: 2,\n pointerEvents: 'none', '& > *': {pointerEvents: 'auto'},\n },\n })} />\n )}\n <LayoutContent ownSx={{maxWidth: contentMaxWidth, mx: 'auto'}}>{children}</LayoutContent>\n </LayoutMain>\n </LayoutBody>\n\n {/* el cajón del teléfono (los dos estilos): con el logo arriba, se cierra al elegir una pantalla */}\n <LayoutPhoneDrawer variant=\"temporary\" open={isMobileMenuOpen} onClose={() => setIsMobileMenuOpen(false)} ModalProps={{keepMounted: true}}\n ownSx={{[DESKTOP_MEDIA_QUERY]: {display: 'none'}}}\n slotProps={{paper: {sx: {width: DRAWER_WIDTH_EXPANDED, boxSizing: 'border-box', pt: 'env(safe-area-inset-top)', pb: 'env(safe-area-inset-bottom)'}}}}>\n <SideMenu {...sideMenuProps} collapsed={false} onNavigate={() => setIsMobileMenuOpen(false)} />\n </LayoutPhoneDrawer>\n </LayoutRoot>\n </BarActionsSlotContext.Provider>\n );\n};\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.logo] el logo chico (28 px), en la barra junto al nombre y en el cajón del teléfono\n * @param {import('react').ReactNode | {light?: import('react').ReactNode, dark?: import('react').ReactNode}} [props.wordmark] el logo\n * ancho, la marca con su nombre en una sola imagen (como el de muchas empresas), o uno para cada modo ({light, dark}: el de\n * color en claro y el blanco en oscuro): va en lugar del logo y el nombre en la barra y arriba del menú del teléfono, a 24 px de alto. Con el menú\n * encogido se queda el logo chico (logo), si lo hay. brandName sigue siendo su nombre para el lector de pantalla\n * @param {string} [props.brandName] el nombre de la app; por omisión el appName de ToolkitProvider\n * @param {string} [props.brandCaption] el renglón chico debajo del nombre («Panel de administración»)\n * @param {string} [props.homePath] por omisión '/'\n * @param {object[]} [props.menuItems] lo que regresa composeMenu\n * @param {'side'|'top'} [props.menuPosition] por omisión 'side' (MENU_POSITION)\n * @param {{name: string, email?: string, subtitle?: string, avatarUrl?: string}|null} [props.user] quién está dentro\n * @param {string} [props.profilePath] la ruta de Mi perfil\n * @param {object[]} [props.accountMenuItems] renglones propios en el menú de la cuenta ({to | onClick, label | labelKey, Icon})\n * @param {() => void} [props.onSignOut] sin él no sale «Salir» (una app sin sesión)\n * @param {boolean} [props.isSigningOut]\n * @param {import('react').ReactNode} [props.headerActions] botones propios en la barra, antes de la cuenta\n * @param {Record<string, number>} [props.menuBadges] los conteos del servidor por badgeKey de cada entrada del menú\n * (useMenuBadges): lo pendiente de cada pantalla, como numerito\n * @param {import('react').ReactNode} [props.accountSettings] ajustes propios del proyecto dentro del menú de la cuenta, debajo de\n * letra, idioma y claro u oscuro (con SettingSection, para que se vean igual)\n * @param {import('react').ReactNode} [props.sidebarFooter] lo de abajo del menú lateral (una tarjeta de ayuda…)\n * @param {boolean} [props.showFontSizeToggle] por omisión sí\n * @param {boolean} [props.showLanguageToggle] por omisión sí\n * @param {boolean} [props.showColorSchemeToggle] por omisión sí\n * @param {import('react').ReactNode} [props.ribbons] avisos propios dentro de la barra\n * @param {boolean} [props.isNavigating] la pantalla siguiente se está descargando (react-router: useIsNavigating)\n * @param {boolean} [props.defaultCollapsed] el menú lateral empieza encogido (la persona lo cambia y se recuerda)\n * @param {boolean} [props.minimizeTabBarOnScroll] en el teléfono con vidrio, la barra de pestañas se encoge al leer hacia\n * abajo y regresa al subir (como iOS 26); por omisión sí\n * @param {number|string} [props.contentMaxWidth] por omisión 1400\n * @param {(collapsed: boolean) => void} [props.onMenuCollapse] la persona encogió (true) o abrió (false) el menú lateral\n * @param {(isOpen: boolean) => void} [props.onMobileMenuChange] se abrió o se cerró el menú del teléfono (el cajón)\n * @param {(keys: string[]|null) => void} [props.onMobileTabsChange] la persona eligió sus pestañas del teléfono (las llaves\n * de menuItemKeyOf; null: regresó a las de omisión). Se recuerdan en el navegador; con esto el proyecto las puede guardar\n * en su servidor\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete (para todo el marco)\n * @param {import('react').ReactNode} props.children el contenido\n */\nconst AppLayoutContent = (props) => {\n // lo que el proyecto puso en su tema (components.CalcitaAppLayout.defaultProps) y encima lo que llega aquí\n const {\n logo, wordmark, brandName, brandCaption, homePath = '/', menuItems = [], menuPosition = MENU_POSITION.side, user = null, profilePath, accountMenuItems = [], onSignOut,\n isSigningOut = false, headerActions, accountSettings, menuBadges, sidebarFooter, showFontSizeToggle = true, showLanguageToggle = true, showColorSchemeToggle = true, ribbons,\n isNavigating = false, defaultCollapsed = false, minimizeTabBarOnScroll = true, contentMaxWidth = 1400, onMenuCollapse, onMobileMenuChange, onMobileTabsChange,\n texts, children,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {appName} = useToolkitSettings();\n // un ícono ya pintado (icon) se vuelve componente aquí, una vez: las piezas del menú pintan siempre Icon\n const shownMenuItems = useMemo(() => menuItemsWithIconsOf(menuItems), [menuItems]);\n const appMenu = useMemo(() => ({menuItems: shownMenuItems}), [shownMenuItems]);\n // los textos del marco llegan a todas sus piezas (la cuenta, el menú, las pestañas del teléfono), cada una lee los suyos\n return (\n <ComponentTexts namespace=\"layout\" texts={texts}>\n <PageTitleProvider>\n <AppMenuContext.Provider value={appMenu}>\n <AppLayoutFrame logo={logo} wordmark={wordmark} brandName={brandName ?? appName} brandCaption={brandCaption} homePath={homePath} menuItems={shownMenuItems} menuPosition={menuPosition}\n user={user} profilePath={profilePath} accountMenuItems={accountMenuItems} onSignOut={onSignOut} isSigningOut={isSigningOut}\n headerActions={headerActions} accountSettings={accountSettings} menuBadges={menuBadges} sidebarFooter={sidebarFooter} showFontSizeToggle={showFontSizeToggle}\n showLanguageToggle={showLanguageToggle} showColorSchemeToggle={showColorSchemeToggle} ribbons={ribbons}\n isNavigating={isNavigating} defaultCollapsed={defaultCollapsed} minimizeTabBarOnScroll={minimizeTabBarOnScroll}\n contentMaxWidth={contentMaxWidth} onMenuCollapse={onMenuCollapse} onMobileMenuChange={onMobileMenuChange}\n onMobileTabsChange={onMobileTabsChange}>\n {children}\n </AppLayoutFrame>\n </AppMenuContext.Provider>\n </PageTitleProvider>\n </ComponentTexts>\n );\n};\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nexport const AppLayout = withPieceSlots(AppLayoutContent, THEME_NAME);\n"],"names":["theme"],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ import LightModeIcon from "@mui/icons-material/LightModeOutlined";
|
|
|
16
16
|
import { useToolkitSettings } from "../toolkit/toolkitContext.js";
|
|
17
17
|
import { DEFAULT_LANGUAGES } from "../toolkit/toolkitSettings.js";
|
|
18
18
|
import { useFontSize } from "../ui/navigation/useFontSize.js";
|
|
19
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
19
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
20
20
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
21
21
|
const THEME_NAME = "CalcitaAppearanceSettings";
|
|
22
22
|
const AppearanceSelectSection = piecePart(THEME_NAME, "SelectSection", Box);
|
|
@@ -52,7 +52,7 @@ function SettingSection({ label, value, options, onChange }) {
|
|
|
52
52
|
)
|
|
53
53
|
] });
|
|
54
54
|
}
|
|
55
|
-
function
|
|
55
|
+
function AppearanceSettingsContent(props) {
|
|
56
56
|
const {
|
|
57
57
|
showFontSize = true,
|
|
58
58
|
showLanguage = true,
|
|
@@ -120,6 +120,7 @@ function AppearanceSettings(props) {
|
|
|
120
120
|
section
|
|
121
121
|
] }, section.key));
|
|
122
122
|
}
|
|
123
|
+
const AppearanceSettings = withPieceSlots(AppearanceSettingsContent, THEME_NAME);
|
|
123
124
|
export {
|
|
124
125
|
SettingSection,
|
|
125
126
|
AppearanceSettings as default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppearanceSettings.js","sources":["../../src/appShell/AppearanceSettings.jsx"],"sourcesContent":["// Los ajustes de cómo se ve la app para esta persona: tamaño de letra, idioma y claro u oscuro, cada uno con sus opciones\n// a la vista (botones de grupo) en lugar de un botón que cambia sin decir a qué. Los usan el engrane del teléfono\n// (SettingsMenu), el menú de la cuenta (AccountMenu) y la pantalla de «Mi perfil» del proyecto: un solo lugar para todos.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAppearanceSettings con defaultProps y\n// styleOverrides de sus partes: selectSection, section, sectionLabel, option, divider.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {Fragment} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\nimport MenuItem from '@mui/material/MenuItem';\nimport TextField from '@mui/material/TextField';\nimport ToggleButton from '@mui/material/ToggleButton';\nimport ToggleButtonGroup from '@mui/material/ToggleButtonGroup';\nimport Typography from '@mui/material/Typography';\nimport {useColorScheme} from '@mui/material/styles';\nimport AutomaticModeIcon from '@mui/icons-material/BrightnessAutoOutlined';\nimport DarkModeIcon from '@mui/icons-material/DarkModeOutlined';\nimport LightModeIcon from '@mui/icons-material/LightModeOutlined';\n\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {DEFAULT_LANGUAGES} from '@/toolkit/toolkitSettings.js';\nimport {useFontSize} from '@/ui/navigation/useFontSize.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.CalcitaAppearanceSettings)\nconst THEME_NAME = 'CalcitaAppearanceSettings';\nconst AppearanceSelectSection = piecePart(THEME_NAME, 'SelectSection', Box);\nconst AppearanceSection = piecePart(THEME_NAME, 'Section', Box);\nconst AppearanceSectionLabel = piecePart(THEME_NAME, 'SectionLabel', Typography);\nconst AppearanceOption = piecePart(THEME_NAME, 'Option', ToggleButton);\nconst AppearanceDivider = piecePart(THEME_NAME, 'Divider', Divider);\n\n// cuántas opciones caben como botones lado a lado en el menú de la cuenta; con más, lista desplegable\nconst SETTING_BUTTONS_LIMIT = 3;\n\n/**\n * Un ajuste: su nombre y sus opciones a la vista. Es público: el proyecto agrega los suyos al menú de la cuenta con la\n * misma forma (AppLayout accountSettings), como el vidrio en los ejemplos.\n *\n * @param {object} props\n * @param {string} props.label ya traducido\n * @param {string} props.value la opción elegida\n * @param {Object[]} props.options\n * @param {string} props.options[].value\n * @param {string} props.options[].label ya traducido\n * @param {import('react').ReactNode} [props.options[].icon]\n * @param {(value: string) => void} props.onChange\n */\nexport function SettingSection({label, value, options, onChange}) {\n // con muchas opciones (los idiomas de una app que ofrece cinco) los botones lado a lado no caben: lista desplegable\n if (options.length > SETTING_BUTTONS_LIMIT) {\n return (\n <AppearanceSelectSection ownSx={{px: 1, py: 0.5}}>\n <TextField select fullWidth size=\"small\" label={label} value={value} onChange={(event) => onChange(event.target.value)}>\n {options.map((option) => <MenuItem key={option.value} value={option.value}>{option.label}</MenuItem>)}\n </TextField>\n </AppearanceSelectSection>\n );\n }\n return (\n <AppearanceSection ownSx={{px: 1, py: 0.5}}>\n <AppearanceSectionLabel variant=\"overline\" color=\"text.secondary\" component=\"p\" ownSx={{px: 1, lineHeight: 1.6}}>{label}</AppearanceSectionLabel>\n <ToggleButtonGroup value={value} exclusive fullWidth size=\"small\" aria-label={label}\n onChange={(event, nextValue) => {\n // al picar la opción ya elegida MUI manda null: se queda la que estaba\n if (nextValue) {\n onChange(nextValue);\n }\n }}>\n {options.map((option) => (\n <AppearanceOption key={option.value} value={option.value} ownSx={{gap: 0.75}}>{option.icon}{option.label}</AppearanceOption>\n ))}\n </ToggleButtonGroup>\n </AppearanceSection>\n );\n}\n\n/**\n * @param {object} props\n * @param {boolean} [props.showFontSize] por omisión sí\n * @param {boolean} [props.showLanguage] por omisión sí\n * @param {boolean} [props.showColorScheme] por omisión sí\n * @param {(level: string) => void} [props.onFontSizeChange] la persona eligió otro tamaño de letra (para guardarlo en su\n * servidor; el idioma ya sale por onLanguageChange de ToolkitProvider)\n * @param {(mode: 'light'|'dark'|'system') => void} [props.onColorSchemeChange] la persona eligió otro modo\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete\n */\nexport default function AppearanceSettings(props) {\n // lo que el proyecto puso en su tema (components.CalcitaAppearanceSettings.defaultProps) y encima lo que llega aquí\n const {\n showFontSize = true, showLanguage = true, showColorScheme = true, onFontSizeChange, onColorSchemeChange, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t, language, changeLanguage} = useToolkitTranslation('layout', texts);\n const {languages = DEFAULT_LANGUAGES} = useToolkitSettings();\n const {level, setLevel, levels} = useFontSize();\n const {mode, setMode} = useColorScheme();\n const chooseFontSize = (nextLevel) => {\n setLevel(nextLevel);\n onFontSizeChange?.(nextLevel);\n };\n const chooseColorScheme = (nextMode) => {\n setMode(nextMode);\n onColorSchemeChange?.(nextMode);\n };\n\n const sections = [\n showFontSize && (\n <SettingSection key=\"fontSize\" label={t('fontSize.label')} value={level} onChange={chooseFontSize}\n options={levels.map((option) => ({value: option.key, label: t(option.labelKey)}))} />\n ),\n showLanguage && (\n <SettingSection key=\"language\" label={t('settings.language')} value={language} onChange={changeLanguage}\n // los idiomas de la app; español e inglés con su nombre de siempre, los del proyecto con el suyo\n options={languages.map((entry) => ({value: entry.code, label: t(`languageName.${entry.code}`, {defaultValue: entry.label})}))} />\n ),\n // antes de montar no se sabe el modo (el servidor no lo conoce): la sección sale ya montada.\n // Tres opciones: «Automático» (system de MUI) sigue lo que diga el equipo y es lo de omisión. Es la ÚNICA salida\n // para volver a seguirlo: el botón de la barra (ColorSchemeToggle) fija claro u oscuro para siempre. La guía de\n // Apple pide seguir el ajuste del equipo; el botón de la barra se queda con dos estados para no sumar una decisión.\n showColorScheme && mode && (\n <SettingSection key=\"colorScheme\" label={t('settings.colorScheme')} value={mode} onChange={chooseColorScheme}\n options={[\n {value: 'light', label: t('settings.light'), icon: <LightModeIcon fontSize=\"small\" />},\n {value: 'dark', label: t('settings.dark'), icon: <DarkModeIcon fontSize=\"small\" />},\n {value: 'system', label: t('settings.system'), icon: <AutomaticModeIcon fontSize=\"small\" />},\n ]} />\n ),\n ].filter(Boolean);\n\n return sections.map((section, index) => (\n <Fragment key={section.key}>\n {index > 0 && <AppearanceDivider ownSx={{my: 0.5}} />}\n {section}\n </Fragment>\n ));\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AppearanceSettings.js","sources":["../../src/appShell/AppearanceSettings.jsx"],"sourcesContent":["// Los ajustes de cómo se ve la app para esta persona: tamaño de letra, idioma y claro u oscuro, cada uno con sus opciones\n// a la vista (botones de grupo) en lugar de un botón que cambia sin decir a qué. Los usan el engrane del teléfono\n// (SettingsMenu), el menú de la cuenta (AccountMenu) y la pantalla de «Mi perfil» del proyecto: un solo lugar para todos.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAppearanceSettings con defaultProps y\n// styleOverrides de sus partes: selectSection, section, sectionLabel, option, divider.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {Fragment} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\nimport MenuItem from '@mui/material/MenuItem';\nimport TextField from '@mui/material/TextField';\nimport ToggleButton from '@mui/material/ToggleButton';\nimport ToggleButtonGroup from '@mui/material/ToggleButtonGroup';\nimport Typography from '@mui/material/Typography';\nimport {useColorScheme} from '@mui/material/styles';\nimport AutomaticModeIcon from '@mui/icons-material/BrightnessAutoOutlined';\nimport DarkModeIcon from '@mui/icons-material/DarkModeOutlined';\nimport LightModeIcon from '@mui/icons-material/LightModeOutlined';\n\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {DEFAULT_LANGUAGES} from '@/toolkit/toolkitSettings.js';\nimport {useFontSize} from '@/ui/navigation/useFontSize.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.CalcitaAppearanceSettings)\nconst THEME_NAME = 'CalcitaAppearanceSettings';\nconst AppearanceSelectSection = piecePart(THEME_NAME, 'SelectSection', Box);\nconst AppearanceSection = piecePart(THEME_NAME, 'Section', Box);\nconst AppearanceSectionLabel = piecePart(THEME_NAME, 'SectionLabel', Typography);\nconst AppearanceOption = piecePart(THEME_NAME, 'Option', ToggleButton);\nconst AppearanceDivider = piecePart(THEME_NAME, 'Divider', Divider);\n\n// cuántas opciones caben como botones lado a lado en el menú de la cuenta; con más, lista desplegable\nconst SETTING_BUTTONS_LIMIT = 3;\n\n/**\n * Un ajuste: su nombre y sus opciones a la vista. Es público: el proyecto agrega los suyos al menú de la cuenta con la\n * misma forma (AppLayout accountSettings), como el vidrio en los ejemplos.\n *\n * @param {object} props\n * @param {string} props.label ya traducido\n * @param {string} props.value la opción elegida\n * @param {Object[]} props.options\n * @param {string} props.options[].value\n * @param {string} props.options[].label ya traducido\n * @param {import('react').ReactNode} [props.options[].icon]\n * @param {(value: string) => void} props.onChange\n */\nexport function SettingSection({label, value, options, onChange}) {\n // con muchas opciones (los idiomas de una app que ofrece cinco) los botones lado a lado no caben: lista desplegable\n if (options.length > SETTING_BUTTONS_LIMIT) {\n return (\n <AppearanceSelectSection ownSx={{px: 1, py: 0.5}}>\n <TextField select fullWidth size=\"small\" label={label} value={value} onChange={(event) => onChange(event.target.value)}>\n {options.map((option) => <MenuItem key={option.value} value={option.value}>{option.label}</MenuItem>)}\n </TextField>\n </AppearanceSelectSection>\n );\n }\n return (\n <AppearanceSection ownSx={{px: 1, py: 0.5}}>\n <AppearanceSectionLabel variant=\"overline\" color=\"text.secondary\" component=\"p\" ownSx={{px: 1, lineHeight: 1.6}}>{label}</AppearanceSectionLabel>\n <ToggleButtonGroup value={value} exclusive fullWidth size=\"small\" aria-label={label}\n onChange={(event, nextValue) => {\n // al picar la opción ya elegida MUI manda null: se queda la que estaba\n if (nextValue) {\n onChange(nextValue);\n }\n }}>\n {options.map((option) => (\n <AppearanceOption key={option.value} value={option.value} ownSx={{gap: 0.75}}>{option.icon}{option.label}</AppearanceOption>\n ))}\n </ToggleButtonGroup>\n </AppearanceSection>\n );\n}\n\n/**\n * @param {object} props\n * @param {boolean} [props.showFontSize] por omisión sí\n * @param {boolean} [props.showLanguage] por omisión sí\n * @param {boolean} [props.showColorScheme] por omisión sí\n * @param {(level: string) => void} [props.onFontSizeChange] la persona eligió otro tamaño de letra (para guardarlo en su\n * servidor; el idioma ya sale por onLanguageChange de ToolkitProvider)\n * @param {(mode: 'light'|'dark'|'system') => void} [props.onColorSchemeChange] la persona eligió otro modo\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete\n */\nfunction AppearanceSettingsContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaAppearanceSettings.defaultProps) y encima lo que llega aquí\n const {\n showFontSize = true, showLanguage = true, showColorScheme = true, onFontSizeChange, onColorSchemeChange, texts,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t, language, changeLanguage} = useToolkitTranslation('layout', texts);\n const {languages = DEFAULT_LANGUAGES} = useToolkitSettings();\n const {level, setLevel, levels} = useFontSize();\n const {mode, setMode} = useColorScheme();\n const chooseFontSize = (nextLevel) => {\n setLevel(nextLevel);\n onFontSizeChange?.(nextLevel);\n };\n const chooseColorScheme = (nextMode) => {\n setMode(nextMode);\n onColorSchemeChange?.(nextMode);\n };\n\n const sections = [\n showFontSize && (\n <SettingSection key=\"fontSize\" label={t('fontSize.label')} value={level} onChange={chooseFontSize}\n options={levels.map((option) => ({value: option.key, label: t(option.labelKey)}))} />\n ),\n showLanguage && (\n <SettingSection key=\"language\" label={t('settings.language')} value={language} onChange={changeLanguage}\n // los idiomas de la app; español e inglés con su nombre de siempre, los del proyecto con el suyo\n options={languages.map((entry) => ({value: entry.code, label: t(`languageName.${entry.code}`, {defaultValue: entry.label})}))} />\n ),\n // antes de montar no se sabe el modo (el servidor no lo conoce): la sección sale ya montada.\n // Tres opciones: «Automático» (system de MUI) sigue lo que diga el equipo y es lo de omisión. Es la ÚNICA salida\n // para volver a seguirlo: el botón de la barra (ColorSchemeToggle) fija claro u oscuro para siempre. La guía de\n // Apple pide seguir el ajuste del equipo; el botón de la barra se queda con dos estados para no sumar una decisión.\n showColorScheme && mode && (\n <SettingSection key=\"colorScheme\" label={t('settings.colorScheme')} value={mode} onChange={chooseColorScheme}\n options={[\n {value: 'light', label: t('settings.light'), icon: <LightModeIcon fontSize=\"small\" />},\n {value: 'dark', label: t('settings.dark'), icon: <DarkModeIcon fontSize=\"small\" />},\n {value: 'system', label: t('settings.system'), icon: <AutomaticModeIcon fontSize=\"small\" />},\n ]} />\n ),\n ].filter(Boolean);\n\n return sections.map((section, index) => (\n <Fragment key={section.key}>\n {index > 0 && <AppearanceDivider ownSx={{my: 0.5}} />}\n {section}\n </Fragment>\n ));\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst AppearanceSettings = withPieceSlots(AppearanceSettingsContent, THEME_NAME);\nexport default AppearanceSettings;\n"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ import GlassLensFilter from "../ui/layout/GlassLensFilter.js";
|
|
|
11
11
|
import DocumentTitle from "../ui/navigation/DocumentTitle.js";
|
|
12
12
|
import ColorSchemeToggle from "../ui/navigation/ColorSchemeToggle.js";
|
|
13
13
|
import LanguageToggle from "../ui/navigation/LanguageToggle.js";
|
|
14
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
14
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
15
15
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
16
16
|
const THEME_NAME = "CalcitaAuthLayout";
|
|
17
17
|
const AuthRoot = piecePart(THEME_NAME, "Root", Box);
|
|
@@ -26,7 +26,7 @@ const AuthContent = piecePart(THEME_NAME, "Content", Box);
|
|
|
26
26
|
const AuthFooter = piecePart(THEME_NAME, "Footer", Box);
|
|
27
27
|
const CARD_MAX_WIDTH_PIXELS = 440;
|
|
28
28
|
const cardSurfaceOf = (theme) => isGlassTheme(theme) ? { ...glassStylesOf(theme), borderColor: "transparent", borderRadius: PANEL_RADIUS } : {};
|
|
29
|
-
const
|
|
29
|
+
const AuthLayoutContent = (props) => {
|
|
30
30
|
const { logo, brandName, title, description, children, footer, showLanguageToggle = true, showColorSchemeToggle = true, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
31
31
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
32
32
|
const { appName } = useToolkitSettings();
|
|
@@ -55,6 +55,7 @@ const AuthLayout = (props) => {
|
|
|
55
55
|
] })
|
|
56
56
|
] });
|
|
57
57
|
};
|
|
58
|
+
const AuthLayout = withPieceSlots(AuthLayoutContent, THEME_NAME);
|
|
58
59
|
export {
|
|
59
60
|
AuthLayout
|
|
60
61
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthLayout.js","sources":["../../src/appShell/AuthLayout.jsx"],"sourcesContent":["// La pantalla de entrada (iniciar sesión, «¿olvidó su contraseña?», elegir una contraseña nueva): el logo y el nombre de\n// la app, una tarjeta al centro con su título y lo que lleve adentro, y arriba a la derecha el idioma y claro u oscuro\n// (quien no ha entrado también los necesita). Como la plantilla «Sign in» de MUI.\n//\n// <AuthLayout logo={<Logo />} title={t('auth:signIn.title')} description={t('auth:signIn.subtitle')}>\n// <SignInForm onSubmit={signIn} forgotPasswordPath=\"/forgot-password\" />\n// </AuthLayout>\n//\n// Con el vidrio del tema (createToolkitTheme({glass: true})), el lienzo lleva sus manchas de color y la tarjeta es de\n// vidrio; sin vidrio, una tarjeta con borde sobre el lienzo.\n//\n// También pinta el aviso de versión nueva (cápsula flotante), como el marco: quien abre la app sin sesión (o la deja abierta\n// en esta pantalla) también debe enterarse; antes solo salía en las pantallas con sesión.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAuthLayout con defaultProps y\n// styleOverrides de sus partes: root, tools, body, brand, logo, brandName, card, description, content, footer.\n//\n// Lo renderiza la app: arrow (regla de la casa).\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {PANEL_RADIUS, ambientBackgroundOf, glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport NewBuildNotice, {NEW_BUILD_NOTICE_VARIANT} from '@/feedback/NewBuildNotice.jsx';\nimport GlassLensFilter from '@/ui/layout/GlassLensFilter.jsx';\nimport DocumentTitle from '@/ui/navigation/DocumentTitle.jsx';\nimport ColorSchemeToggle from '@/ui/navigation/ColorSchemeToggle.jsx';\nimport LanguageToggle from '@/ui/navigation/LanguageToggle.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.CalcitaAuthLayout)\nconst THEME_NAME = 'CalcitaAuthLayout';\nconst AuthRoot = piecePart(THEME_NAME, 'Root', Box);\nconst AuthTools = piecePart(THEME_NAME, 'Tools', Stack);\nconst AuthBody = piecePart(THEME_NAME, 'Body', Box);\nconst AuthBrand = piecePart(THEME_NAME, 'Brand', Stack);\nconst AuthLogo = piecePart(THEME_NAME, 'Logo', Box);\nconst AuthBrandName = piecePart(THEME_NAME, 'BrandName', Typography);\nconst AuthCard = piecePart(THEME_NAME, 'Card', Paper);\nconst AuthDescription = piecePart(THEME_NAME, 'Description', Typography);\nconst AuthContent = piecePart(THEME_NAME, 'Content', Box);\nconst AuthFooter = piecePart(THEME_NAME, 'Footer', Box);\n\n// lo ancho de la tarjeta: lo que cabe cómodo un correo largo\nconst CARD_MAX_WIDTH_PIXELS = 440;\n\n/**\n * La tarjeta: de vidrio si el tema lo trae; si no, con borde.\n *\n * @param {object} theme\n * @returns {object}\n */\nconst cardSurfaceOf = (theme) => (isGlassTheme(theme)\n ? {...glassStylesOf(theme), borderColor: 'transparent', borderRadius: PANEL_RADIUS}\n : {});\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.logo] el logo chico (28 px)\n * @param {string} [props.brandName] por omisión el appName de ToolkitProvider\n * @param {string} props.title el título de la tarjeta y de la pestaña, ya traducido\n * @param {import('react').ReactNode} [props.description] el renglón debajo del título\n * @param {import('react').ReactNode} props.children el formulario\n * @param {import('react').ReactNode} [props.footer] debajo de la tarjeta (los botones de prueba, el aviso de privacidad…)\n * @param {boolean} [props.showLanguageToggle] por omisión sí\n * @param {boolean} [props.showColorSchemeToggle] por omisión sí\n */\
|
|
1
|
+
{"version":3,"file":"AuthLayout.js","sources":["../../src/appShell/AuthLayout.jsx"],"sourcesContent":["// La pantalla de entrada (iniciar sesión, «¿olvidó su contraseña?», elegir una contraseña nueva): el logo y el nombre de\n// la app, una tarjeta al centro con su título y lo que lleve adentro, y arriba a la derecha el idioma y claro u oscuro\n// (quien no ha entrado también los necesita). Como la plantilla «Sign in» de MUI.\n//\n// <AuthLayout logo={<Logo />} title={t('auth:signIn.title')} description={t('auth:signIn.subtitle')}>\n// <SignInForm onSubmit={signIn} forgotPasswordPath=\"/forgot-password\" />\n// </AuthLayout>\n//\n// Con el vidrio del tema (createToolkitTheme({glass: true})), el lienzo lleva sus manchas de color y la tarjeta es de\n// vidrio; sin vidrio, una tarjeta con borde sobre el lienzo.\n//\n// También pinta el aviso de versión nueva (cápsula flotante), como el marco: quien abre la app sin sesión (o la deja abierta\n// en esta pantalla) también debe enterarse; antes solo salía en las pantallas con sesión.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAuthLayout con defaultProps y\n// styleOverrides de sus partes: root, tools, body, brand, logo, brandName, card, description, content, footer.\n//\n// Lo renderiza la app: arrow (regla de la casa).\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {PANEL_RADIUS, ambientBackgroundOf, glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport NewBuildNotice, {NEW_BUILD_NOTICE_VARIANT} from '@/feedback/NewBuildNotice.jsx';\nimport GlassLensFilter from '@/ui/layout/GlassLensFilter.jsx';\nimport DocumentTitle from '@/ui/navigation/DocumentTitle.jsx';\nimport ColorSchemeToggle from '@/ui/navigation/ColorSchemeToggle.jsx';\nimport LanguageToggle from '@/ui/navigation/LanguageToggle.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.CalcitaAuthLayout)\nconst THEME_NAME = 'CalcitaAuthLayout';\nconst AuthRoot = piecePart(THEME_NAME, 'Root', Box);\nconst AuthTools = piecePart(THEME_NAME, 'Tools', Stack);\nconst AuthBody = piecePart(THEME_NAME, 'Body', Box);\nconst AuthBrand = piecePart(THEME_NAME, 'Brand', Stack);\nconst AuthLogo = piecePart(THEME_NAME, 'Logo', Box);\nconst AuthBrandName = piecePart(THEME_NAME, 'BrandName', Typography);\nconst AuthCard = piecePart(THEME_NAME, 'Card', Paper);\nconst AuthDescription = piecePart(THEME_NAME, 'Description', Typography);\nconst AuthContent = piecePart(THEME_NAME, 'Content', Box);\nconst AuthFooter = piecePart(THEME_NAME, 'Footer', Box);\n\n// lo ancho de la tarjeta: lo que cabe cómodo un correo largo\nconst CARD_MAX_WIDTH_PIXELS = 440;\n\n/**\n * La tarjeta: de vidrio si el tema lo trae; si no, con borde.\n *\n * @param {object} theme\n * @returns {object}\n */\nconst cardSurfaceOf = (theme) => (isGlassTheme(theme)\n ? {...glassStylesOf(theme), borderColor: 'transparent', borderRadius: PANEL_RADIUS}\n : {});\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} [props.logo] el logo chico (28 px)\n * @param {string} [props.brandName] por omisión el appName de ToolkitProvider\n * @param {string} props.title el título de la tarjeta y de la pestaña, ya traducido\n * @param {import('react').ReactNode} [props.description] el renglón debajo del título\n * @param {import('react').ReactNode} props.children el formulario\n * @param {import('react').ReactNode} [props.footer] debajo de la tarjeta (los botones de prueba, el aviso de privacidad…)\n * @param {boolean} [props.showLanguageToggle] por omisión sí\n * @param {boolean} [props.showColorSchemeToggle] por omisión sí\n */\nconst AuthLayoutContent = (props) => {\n // lo que el proyecto puso en su tema (components.CalcitaAuthLayout.defaultProps) y encima lo que llega aquí\n const {logo, brandName, title, description, children, footer, showLanguageToggle = true, showColorSchemeToggle = true, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {appName} = useToolkitSettings();\n return (\n <AuthRoot ownSx={[{minHeight: '100vh', display: 'flex', flexDirection: 'column', bgcolor: 'background.default'},\n (theme) => (isGlassTheme(theme) ? ambientBackgroundOf(theme) : {})]}>\n <DocumentTitle title={title} />\n <GlassLensFilter />\n <NewBuildNotice variant={NEW_BUILD_NOTICE_VARIANT.floating} />\n <AuthTools direction=\"row\" spacing={1} ownSx={{justifyContent: 'flex-end', p: 2, pt: 'max(16px, env(safe-area-inset-top))'}}>\n {showLanguageToggle && <LanguageToggle />}\n {showColorSchemeToggle && <ColorSchemeToggle />}\n </AuthTools>\n <AuthBody component=\"main\" ownSx={{flexGrow: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', px: 2, pb: 6}}>\n <AuthBrand direction=\"row\" spacing={1.25} ownSx={{alignItems: 'center', mb: 3}}>\n {logo && <AuthLogo ownSx={{width: 28, height: 28, display: 'flex', alignItems: 'center', justifyContent: 'center'}}>{logo}</AuthLogo>}\n <AuthBrandName variant=\"subtitle1\" component=\"p\" ownSx={{fontWeight: 600}}>{brandName ?? appName}</AuthBrandName>\n </AuthBrand>\n <AuthCard variant=\"outlined\" ownSx={[{width: '100%', maxWidth: CARD_MAX_WIDTH_PIXELS, p: {xs: 3, sm: 4}}, cardSurfaceOf]}>\n <Typography variant=\"h5\" component=\"h1\">{title}</Typography>\n {description && <AuthDescription variant=\"body2\" color=\"text.secondary\" ownSx={{mt: 1}}>{description}</AuthDescription>}\n <AuthContent ownSx={{mt: 3}}>{children}</AuthContent>\n </AuthCard>\n {footer && <AuthFooter ownSx={{width: '100%', maxWidth: CARD_MAX_WIDTH_PIXELS, mt: 2}}>{footer}</AuthFooter>}\n </AuthBody>\n </AuthRoot>\n );\n};\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nexport const AuthLayout = withPieceSlots(AuthLayoutContent, THEME_NAME);\n"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,13 @@ import ListItemText from "@mui/material/ListItemText";
|
|
|
7
7
|
import MenuItem from "@mui/material/MenuItem";
|
|
8
8
|
import Tooltip from "@mui/material/Tooltip";
|
|
9
9
|
import { useBarActionsPlacement, useCloseBarActionsMenu, BAR_ACTIONS_PLACEMENT } from "./barActionsSlot.js";
|
|
10
|
-
|
|
10
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
11
|
+
const THEME_NAME = "CalcitaBarActionButton";
|
|
12
|
+
const BarActionButtonButton = piecePart(THEME_NAME, "Button", Button);
|
|
13
|
+
const BarActionButtonIconButton = piecePart(THEME_NAME, "IconButton", IconButton);
|
|
14
|
+
const BarActionButtonMenuItem = piecePart(THEME_NAME, "MenuItem", MenuItem);
|
|
15
|
+
function BarActionButtonContent(props) {
|
|
16
|
+
const { label, icon, onClick, disabled, color = "primary", ...buttonProps } = usePieceProps(props, THEME_NAME);
|
|
11
17
|
const placement = useBarActionsPlacement();
|
|
12
18
|
const closeMenu = useCloseBarActionsMenu();
|
|
13
19
|
if (placement === BAR_ACTIONS_PLACEMENT.menu) {
|
|
@@ -15,16 +21,17 @@ function BarActionButton({ label, icon, onClick, disabled, color = "primary", ..
|
|
|
15
21
|
closeMenu();
|
|
16
22
|
onClick?.(event);
|
|
17
23
|
};
|
|
18
|
-
return /* @__PURE__ */ jsxs(
|
|
24
|
+
return /* @__PURE__ */ jsxs(BarActionButtonMenuItem, { onClick: pickFromMenu, disabled, ...buttonProps, children: [
|
|
19
25
|
icon && /* @__PURE__ */ jsx(ListItemIcon, { children: icon }),
|
|
20
26
|
/* @__PURE__ */ jsx(ListItemText, { inset: !icon, children: label })
|
|
21
27
|
] });
|
|
22
28
|
}
|
|
23
29
|
if (placement === BAR_ACTIONS_PLACEMENT.capsule && icon) {
|
|
24
|
-
return /* @__PURE__ */ jsx(Tooltip, { title: label, children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
30
|
+
return /* @__PURE__ */ jsx(Tooltip, { title: label, children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(BarActionButtonIconButton, { "aria-label": label, onClick, disabled, color, ...buttonProps, children: icon }) }) });
|
|
25
31
|
}
|
|
26
|
-
return /* @__PURE__ */ jsx(
|
|
32
|
+
return /* @__PURE__ */ jsx(BarActionButtonButton, { startIcon: icon, onClick, disabled, color, ...buttonProps, children: label });
|
|
27
33
|
}
|
|
34
|
+
const BarActionButton = withPieceSlots(BarActionButtonContent, THEME_NAME);
|
|
28
35
|
export {
|
|
29
36
|
BarActionButton as default
|
|
30
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BarActionButton.js","sources":["../../src/appShell/BarActionButton.jsx"],"sourcesContent":["// Un botón de acción de la pantalla que se acomoda solo a donde quedó (lo pidió el autor, y es lo que pide la guía de Apple\n// para las barras: «Prefer simple, recognizable symbols for items instead of text»):\n// - en una cápsula (arriba en la barra, flotando en el teléfono o en la franja): solo el ícono, con su nombre en el tooltip\n// y para el lector de pantalla. En el teléfono el tooltip sale al dejar el dedo encima, como en iOS;\n// - en el menú «⋯» del teléfono (las que ya no caben en el renglón flotante): un renglón con ícono y texto;\n// - suelto (fuera de BarActions): ícono con texto, botón sin relleno.\n// Lo demás va al botón (disabled, color, component y to para una liga…). Sin ícono, en la cápsula va su texto (un botón sin\n// relleno) y en el «⋯» el renglón sin ícono: mejor un texto que un botón vacío.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport ListItemIcon from '@mui/material/ListItemIcon';\nimport ListItemText from '@mui/material/ListItemText';\nimport MenuItem from '@mui/material/MenuItem';\nimport Tooltip from '@mui/material/Tooltip';\n\nimport {BAR_ACTIONS_PLACEMENT, useBarActionsPlacement, useCloseBarActionsMenu} from '@/appShell/barActionsSlot.js';\n\n/**\n * @param {object} props\n * @param {string} props.label el nombre de la acción, ya traducido: «Agregar sucursal»\n * @param {import('react').ReactNode} [props.icon] el ícono (<AddRoundedIcon />); sin él, se ve su texto\n * @param {(event: object) => void} [props.onClick]\n * @param {boolean} [props.disabled]\n * @param {'inherit'|'primary'|'secondary'|'success'|'error'|'info'|'warning'} [props.color] por omisión primary\n */\
|
|
1
|
+
{"version":3,"file":"BarActionButton.js","sources":["../../src/appShell/BarActionButton.jsx"],"sourcesContent":["// Un botón de acción de la pantalla que se acomoda solo a donde quedó (lo pidió el autor, y es lo que pide la guía de Apple\n// para las barras: «Prefer simple, recognizable symbols for items instead of text»):\n// - en una cápsula (arriba en la barra, flotando en el teléfono o en la franja): solo el ícono, con su nombre en el tooltip\n// y para el lector de pantalla. En el teléfono el tooltip sale al dejar el dedo encima, como en iOS;\n// - en el menú «⋯» del teléfono (las que ya no caben en el renglón flotante): un renglón con ícono y texto;\n// - suelto (fuera de BarActions): ícono con texto, botón sin relleno.\n// Lo demás va al botón (disabled, color, component y to para una liga…). Sin ícono, en la cápsula va su texto (un botón sin\n// relleno) y en el «⋯» el renglón sin ícono: mejor un texto que un botón vacío.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarActionButton con defaultProps, styleOverrides de\n// sus partes (button, iconButton, menuItem) y slots/slotProps para cambiarlas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport ListItemIcon from '@mui/material/ListItemIcon';\nimport ListItemText from '@mui/material/ListItemText';\nimport MenuItem from '@mui/material/MenuItem';\nimport Tooltip from '@mui/material/Tooltip';\n\nimport {BAR_ACTIONS_PLACEMENT, useBarActionsPlacement, useCloseBarActionsMenu} from '@/appShell/barActionsSlot.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaBarActionButton)\nconst THEME_NAME = 'CalcitaBarActionButton';\nconst BarActionButtonButton = piecePart(THEME_NAME, 'Button', Button);\nconst BarActionButtonIconButton = piecePart(THEME_NAME, 'IconButton', IconButton);\nconst BarActionButtonMenuItem = piecePart(THEME_NAME, 'MenuItem', MenuItem);\n\n/**\n * @param {object} props\n * @param {string} props.label el nombre de la acción, ya traducido: «Agregar sucursal»\n * @param {import('react').ReactNode} [props.icon] el ícono (<AddRoundedIcon />); sin él, se ve su texto\n * @param {(event: object) => void} [props.onClick]\n * @param {boolean} [props.disabled]\n * @param {'inherit'|'primary'|'secondary'|'success'|'error'|'info'|'warning'} [props.color] por omisión primary\n */\nfunction BarActionButtonContent(props) {\n const {label, icon, onClick, disabled, color = 'primary', ...buttonProps} = usePieceProps(props, THEME_NAME);\n const placement = useBarActionsPlacement();\n const closeMenu = useCloseBarActionsMenu();\n\n if (placement === BAR_ACTIONS_PLACEMENT.menu) {\n // primero se cierra el menú: la acción puede abrir una ventana y el menú quedaba encima\n const pickFromMenu = (event) => {\n closeMenu();\n onClick?.(event);\n };\n return (\n <BarActionButtonMenuItem onClick={pickFromMenu} disabled={disabled} {...buttonProps}>\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText inset={!icon}>{label}</ListItemText>\n </BarActionButtonMenuItem>\n );\n }\n if (placement === BAR_ACTIONS_PLACEMENT.capsule && icon) {\n // OJO: el tooltip envuelve un span para que también salga con el botón deshabilitado (MUI no lo pinta sobre un\n // elemento deshabilitado)\n return (\n <Tooltip title={label}>\n <span>\n <BarActionButtonIconButton aria-label={label} onClick={onClick} disabled={disabled} color={color} {...buttonProps}>{icon}</BarActionButtonIconButton>\n </span>\n </Tooltip>\n );\n }\n return <BarActionButtonButton startIcon={icon} onClick={onClick} disabled={disabled} color={color} {...buttonProps}>{label}</BarActionButtonButton>;\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst BarActionButton = withPieceSlots(BarActionButtonContent, THEME_NAME);\nexport default BarActionButton;\n"],"names":[],"mappings":";;;;;;;;;;AAwBA,MAAM,aAAa;AACnB,MAAM,wBAAwB,UAAU,YAAY,UAAU,MAAM;AACpE,MAAM,4BAA4B,UAAU,YAAY,cAAc,UAAU;AAChF,MAAM,0BAA0B,UAAU,YAAY,YAAY,QAAQ;AAU1E,SAAS,uBAAuB,OAAO;AACnC,QAAM,EAAC,OAAO,MAAM,SAAS,UAAU,QAAQ,WAAW,GAAG,YAAA,IAAe,cAAc,OAAO,UAAU;AAC3G,QAAM,YAAY,uBAAA;AAClB,QAAM,YAAY,uBAAA;AAElB,MAAI,cAAc,sBAAsB,MAAM;AAE1C,UAAM,eAAe,CAAC,UAAU;AAC5B,gBAAA;AACA,gBAAU,KAAK;AAAA,IACnB;AACA,gCACK,yBAAA,EAAwB,SAAS,cAAc,UAAqB,GAAG,aACnE,UAAA;AAAA,MAAA,QAAQ,oBAAC,gBAAc,UAAA,KAAA,CAAK;AAAA,MAC7B,oBAAC,cAAA,EAAa,OAAO,CAAC,MAAO,UAAA,MAAA,CAAM;AAAA,IAAA,GACvC;AAAA,EAER;AACA,MAAI,cAAc,sBAAsB,WAAW,MAAM;AAGrD,+BACK,SAAA,EAAQ,OAAO,OACZ,UAAA,oBAAC,UACG,UAAA,oBAAC,2BAAA,EAA0B,cAAY,OAAO,SAAkB,UAAoB,OAAe,GAAG,aAAc,UAAA,MAAK,GAC7H,EAAA,CACJ;AAAA,EAER;AACA,SAAO,oBAAC,yBAAsB,WAAW,MAAM,SAAkB,UAAoB,OAAe,GAAG,aAAc,UAAA,MAAA,CAAM;AAC/H;AAGA,MAAM,kBAAkB,eAAe,wBAAwB,UAAU;"}
|
|
@@ -14,7 +14,7 @@ import { useBarActionsSlot, BarActionsPlacementContext, BAR_ACTIONS_PLACEMENT, B
|
|
|
14
14
|
import { DESKTOP_MEDIA_QUERY } from "./shellSizes.js";
|
|
15
15
|
import useFittingActionCount from "./useFittingActionCount.js";
|
|
16
16
|
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
17
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
17
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
18
18
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
19
19
|
const THEME_NAME = "CalcitaBarActions";
|
|
20
20
|
const ActionsGroup = piecePart(THEME_NAME, "Group", Box);
|
|
@@ -60,7 +60,7 @@ const PhoneFloatingCapsule = ({ phoneSlot, label, sx, texts, children, ...rest }
|
|
|
60
60
|
hiddenActions.length > 0 && /* @__PURE__ */ jsx(MoreActionsMenu, { label: t("barActions.more"), children: hiddenActions })
|
|
61
61
|
] });
|
|
62
62
|
};
|
|
63
|
-
function
|
|
63
|
+
function BarActionsContent(props) {
|
|
64
64
|
const { children, label, order, sx, inlineSx, bare = false, exclusive = false, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
65
65
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
66
66
|
const { slot, phoneSlot, usesCapsules } = useBarActionsSlot();
|
|
@@ -106,6 +106,7 @@ function BarActions(props) {
|
|
|
106
106
|
target
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
|
+
const BarActions = withPieceSlots(BarActionsContent, THEME_NAME);
|
|
109
110
|
export {
|
|
110
111
|
BarActions as default
|
|
111
112
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BarActions.js","sources":["../../src/appShell/BarActions.jsx"],"sourcesContent":["// Las acciones de UNA pantalla en una cápsula, como las barras de herramientas de Apple: la pantalla las pone en su código\n// donde quiera y el marco decide dónde se ven.\n//\n// - Escritorio con la barra en cápsulas (TOP_BAR.capsules): suben a la barra, cada <BarActions> en su cápsula. Dos grupos\n// que no van juntos (buscar; exportar y agregar) son dos <BarActions>, como Apple separa los grupos.\n// - Teléfono con cápsulas: las mismas cápsulas flotan arriba a la derecha y se quedan al bajar, como los botones de iOS 26\n// (en el teléfono no hay barra de arriba: la de pestañas va abajo). Se ven todas las que caben, solo con ícono; las que\n// ya no caben a lo ancho van a un menú «⋯» con su nombre (useFittingActionCount mide el renglón de verdad). Así una\n// pantalla con muchas acciones arriba no rompe el teléfono.\n// - Escritorio con la franja: entran a la franja como botones (con el color de la franja).\n// - Sin lugar (sin AppLayout, la barra fundida al menú, o el teléfono sin cápsulas): se quedan donde la pantalla las puso,\n// también en una cápsula de solo íconos. PageHeading ya las usa para sus `actions`.\n//\n// Se extiende sin tocar el framework: cualquier contenido adentro (lo normal es BarActionButton, que se acomoda solo), varias\n// por pantalla con su `order`, estilos propios con `sx` (la cápsula de arriba o la flotante) e `inlineSx` (la que se queda en\n// la pantalla), y `bare` cuando lo de adentro ya es una cápsula (el buscador de la tabla). Para una cápsula fuera de todo\n// esto: BarCapsule.\n//\n// OJO: escritorio o teléfono se decide con useMediaQuery (el único lugar del marco): hay que mover los botones a otro lugar\n// del árbol y eso no se puede solo con CSS sin pintarlos dos veces (con sus estados por duplicado). Con Next, el primer\n// pintado los deja en el contenido y se mueven a su lugar al hidratar; con Vite no se nota.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarActions con defaultProps y\n// styleOverrides.group (el grupo sin cápsula); la cápsula, con CalcitaBarCapsule. El sx y el inlineSx de la pantalla siguen\n// ganando a todo.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {Children, useState} from 'react';\nimport {createPortal} from 'react-dom';\nimport Box from '@mui/material/Box';\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport IconButton from '@mui/material/IconButton';\nimport Menu from '@mui/material/Menu';\nimport Tooltip from '@mui/material/Tooltip';\nimport useMediaQuery from '@mui/material/useMediaQuery';\nimport MoreHorizRoundedIcon from '@mui/icons-material/MoreHorizRounded';\n\nimport BarCapsule, {monochromeButtonsSxOf} from '@/appShell/BarCapsule.jsx';\nimport {\n BAR_ACTIONS_PLACEMENT, BarActionsMenuCloseContext, BarActionsPlacementContext, useBarActionsSlot,\n} from '@/appShell/barActionsSlot.js';\nimport {DESKTOP_MEDIA_QUERY} from '@/appShell/shellSizes.js';\nimport useFittingActionCount from '@/appShell/useFittingActionCount.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.CalcitaBarActions): el grupo sin cápsula (bare, o en la\n// franja); con cápsula, la cápsula es CalcitaBarCapsule\nconst THEME_NAME = 'CalcitaBarActions';\nconst ActionsGroup = piecePart(THEME_NAME, 'Group', Box);\n\n// la marca de un grupo exclusivo (BarActions exclusive) y la regla que, mientras exista, esconde a los demás grupos del\n// renglón flotante del teléfono (data-phone-bar-actions lo pone AppLayout)\nconst EXCLUSIVE_ATTRIBUTE = 'data-bar-exclusive';\nconst HIDE_NOT_EXCLUSIVE_STYLES = {[`[data-phone-bar-actions] > :not([${EXCLUSIVE_ATTRIBUTE}])`]: {display: 'none !important'}};\n\n/** Lo de adentro sabe que quedó en una cápsula (BarActionButton se vuelve solo ícono). */\nconst InCapsule = ({children}) => (\n <BarActionsPlacementContext.Provider value={BAR_ACTIONS_PLACEMENT.capsule}>{children}</BarActionsPlacementContext.Provider>\n);\n\n/** El «⋯» del teléfono con las acciones que no caben, como renglones de menú con su nombre. */\nconst MoreActionsMenu = ({label, children}) => {\n const [anchorElement, setAnchorElement] = useState(null);\n const close = () => setAnchorElement(null);\n return (\n <>\n <Tooltip title={label}>\n <IconButton aria-label={label} aria-haspopup=\"menu\" aria-expanded={Boolean(anchorElement)}\n onClick={(event) => setAnchorElement(event.currentTarget)}>\n <MoreHorizRoundedIcon />\n </IconButton>\n </Tooltip>\n {/* OJO keepMounted: una acción del «⋯» puede abrir algo suyo al picarla (DownloadMenu abre sus formatos y su\n confirmación); sin él, al cerrarse este menú se desmontaba con todo y lo que abrió */}\n <Menu anchorEl={anchorElement} open={Boolean(anchorElement)} onClose={close} keepMounted\n anchorOrigin={{vertical: 'bottom', horizontal: 'right'}} transformOrigin={{vertical: 'top', horizontal: 'right'}}>\n <BarActionsMenuCloseContext.Provider value={close}>\n <BarActionsPlacementContext.Provider value={BAR_ACTIONS_PLACEMENT.menu}>{children}</BarActionsPlacementContext.Provider>\n </BarActionsMenuCloseContext.Provider>\n </Menu>\n </>\n );\n};\n\n/** La cápsula que flota en el teléfono: las que caben como ícono y, si sobran, el «⋯» con las demás. */\nconst PhoneFloatingCapsule = ({phoneSlot, label, sx, texts, children, ...rest}) => {\n const {t} = useToolkitTranslation('layout', texts);\n const [capsuleElement, setCapsuleElement] = useState(null);\n const actions = Children.toArray(children);\n const visibleCount = useFittingActionCount(phoneSlot, capsuleElement, actions.length);\n const hiddenActions = actions.slice(visibleCount);\n return (\n <BarCapsule ref={setCapsuleElement} aria-label={label} sx={sx} {...rest}>\n <InCapsule>{actions.slice(0, visibleCount)}</InCapsule>\n {hiddenActions.length > 0 && <MoreActionsMenu label={t('barActions.more')}>{hiddenActions}</MoreActionsMenu>}\n </BarCapsule>\n );\n};\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} props.children los botones de este grupo (normalmente BarActionButton)\n * @param {string} [props.label] el nombre del grupo (lector de pantalla): «Acciones de pedidos»\n * @param {number} [props.order] en qué lugar va entre los grupos de la pantalla (CSS order; por omisión el de aparición)\n * @param {object|Function|Array} [props.sx] estilos propios de la cápsula de arriba o de la flotante del teléfono (o del\n * grupo, en la franja)\n * @param {object|Function|Array} [props.inlineSx] estilos de la cápsula cuando se queda en la pantalla\n * @param {boolean} [props.bare] sin cápsula alrededor: lo de adentro ya es una (un buscador)\n * @param {boolean} [props.exclusive] en el teléfono, mientras se ve, es lo único del renglón flotante (con los demás grupos\n * exclusivos): los otros se esconden, como el modo de edición del iPhone deja solo lo de lo elegido. Lo usa SelectionActions\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete\n */\nexport default function BarActions(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarActions.defaultProps) y encima lo que llega aquí\n const {children, label, order, sx, inlineSx, bare = false, exclusive = false, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {slot, phoneSlot, usesCapsules} = useBarActionsSlot();\n const isDesktop = useMediaQuery(DESKTOP_MEDIA_QUERY);\n // en escritorio, la barra; en el teléfono, el renglón flotante (solo existe con cápsulas)\n const target = isDesktop ? slot : phoneSlot;\n const orderSx = order === undefined ? {} : {order};\n const extraSx = Array.isArray(sx) ? sx : [sx];\n const extraInlineSx = Array.isArray(inlineSx) ? inlineSx : [inlineSx];\n\n // sin lugar: donde la pantalla las puso, en su cápsula de íconos\n if (!target) {\n if (bare) {\n return <ActionsGroup role=\"group\" aria-label={label} ownSx={{display: 'flex', alignItems: 'center'}} sx={extraInlineSx}>{children}</ActionsGroup>;\n }\n return (\n <BarCapsule aria-label={label} sx={[{alignSelf: 'flex-start'}, ...extraInlineSx]}>\n <InCapsule>{children}</InCapsule>\n </BarCapsule>\n );\n }\n // exclusivo en el teléfono: se marca y esconde a los demás grupos del renglón mientras se ve. OJO: sin esto, con algo\n // elegido no cabían el conteo, sus acciones, la lupa y las de la pantalla, y el renglón se salía por los dos lados\n const exclusiveProps = !isDesktop && exclusive ? {[EXCLUSIVE_ATTRIBUTE]: ''} : {};\n const hideOthers = !isDesktop && exclusive && <GlobalStyles styles={HIDE_NOT_EXCLUSIVE_STYLES} />;\n // flotando en el teléfono: las que caben y el «⋯»\n if (!isDesktop && !bare) {\n return (\n <>\n {hideOthers}\n {createPortal(<PhoneFloatingCapsule phoneSlot={phoneSlot} label={label} sx={[orderSx, ...extraSx]} texts={texts} {...exclusiveProps}>{children}</PhoneFloatingCapsule>, target)}\n </>\n );\n }\n // arriba en la barra (o el buscador flotando en el teléfono)\n if (usesCapsules && !bare) {\n return createPortal(<BarCapsule aria-label={label} sx={[orderSx, ...extraSx]}><InCapsule>{children}</InCapsule></BarCapsule>, target);\n }\n if (usesCapsules) {\n return (\n <>\n {hideOthers}\n {createPortal(<ActionsGroup role=\"group\" aria-label={label} ownSx={[{display: 'flex', alignItems: 'center'}, orderSx]} sx={extraSx} {...exclusiveProps}>{children}</ActionsGroup>, target)}\n </>\n );\n }\n // en la franja: botones sueltos (solo ícono) con el color de la franja (sobre el naranja de Stackcraft, el color\n // principal no se vería)\n return createPortal(\n <ActionsGroup role=\"group\" aria-label={label}\n ownSx={[{display: 'flex', alignItems: 'center', gap: 0.5, ...monochromeButtonsSxOf('inherit')}, orderSx]} sx={extraSx}>\n <InCapsule>{children}</InCapsule>\n </ActionsGroup>,\n target,\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BarActions.js","sources":["../../src/appShell/BarActions.jsx"],"sourcesContent":["// Las acciones de UNA pantalla en una cápsula, como las barras de herramientas de Apple: la pantalla las pone en su código\n// donde quiera y el marco decide dónde se ven.\n//\n// - Escritorio con la barra en cápsulas (TOP_BAR.capsules): suben a la barra, cada <BarActions> en su cápsula. Dos grupos\n// que no van juntos (buscar; exportar y agregar) son dos <BarActions>, como Apple separa los grupos.\n// - Teléfono con cápsulas: las mismas cápsulas flotan arriba a la derecha y se quedan al bajar, como los botones de iOS 26\n// (en el teléfono no hay barra de arriba: la de pestañas va abajo). Se ven todas las que caben, solo con ícono; las que\n// ya no caben a lo ancho van a un menú «⋯» con su nombre (useFittingActionCount mide el renglón de verdad). Así una\n// pantalla con muchas acciones arriba no rompe el teléfono.\n// - Escritorio con la franja: entran a la franja como botones (con el color de la franja).\n// - Sin lugar (sin AppLayout, la barra fundida al menú, o el teléfono sin cápsulas): se quedan donde la pantalla las puso,\n// también en una cápsula de solo íconos. PageHeading ya las usa para sus `actions`.\n//\n// Se extiende sin tocar el framework: cualquier contenido adentro (lo normal es BarActionButton, que se acomoda solo), varias\n// por pantalla con su `order`, estilos propios con `sx` (la cápsula de arriba o la flotante) e `inlineSx` (la que se queda en\n// la pantalla), y `bare` cuando lo de adentro ya es una cápsula (el buscador de la tabla). Para una cápsula fuera de todo\n// esto: BarCapsule.\n//\n// OJO: escritorio o teléfono se decide con useMediaQuery (el único lugar del marco): hay que mover los botones a otro lugar\n// del árbol y eso no se puede solo con CSS sin pintarlos dos veces (con sus estados por duplicado). Con Next, el primer\n// pintado los deja en el contenido y se mueven a su lugar al hidratar; con Vite no se nota.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarActions con defaultProps y\n// styleOverrides.group (el grupo sin cápsula); la cápsula, con CalcitaBarCapsule. El sx y el inlineSx de la pantalla siguen\n// ganando a todo.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {Children, useState} from 'react';\nimport {createPortal} from 'react-dom';\nimport Box from '@mui/material/Box';\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport IconButton from '@mui/material/IconButton';\nimport Menu from '@mui/material/Menu';\nimport Tooltip from '@mui/material/Tooltip';\nimport useMediaQuery from '@mui/material/useMediaQuery';\nimport MoreHorizRoundedIcon from '@mui/icons-material/MoreHorizRounded';\n\nimport BarCapsule, {monochromeButtonsSxOf} from '@/appShell/BarCapsule.jsx';\nimport {\n BAR_ACTIONS_PLACEMENT, BarActionsMenuCloseContext, BarActionsPlacementContext, useBarActionsSlot,\n} from '@/appShell/barActionsSlot.js';\nimport {DESKTOP_MEDIA_QUERY} from '@/appShell/shellSizes.js';\nimport useFittingActionCount from '@/appShell/useFittingActionCount.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.CalcitaBarActions): el grupo sin cápsula (bare, o en la\n// franja); con cápsula, la cápsula es CalcitaBarCapsule\nconst THEME_NAME = 'CalcitaBarActions';\nconst ActionsGroup = piecePart(THEME_NAME, 'Group', Box);\n\n// la marca de un grupo exclusivo (BarActions exclusive) y la regla que, mientras exista, esconde a los demás grupos del\n// renglón flotante del teléfono (data-phone-bar-actions lo pone AppLayout)\nconst EXCLUSIVE_ATTRIBUTE = 'data-bar-exclusive';\nconst HIDE_NOT_EXCLUSIVE_STYLES = {[`[data-phone-bar-actions] > :not([${EXCLUSIVE_ATTRIBUTE}])`]: {display: 'none !important'}};\n\n/** Lo de adentro sabe que quedó en una cápsula (BarActionButton se vuelve solo ícono). */\nconst InCapsule = ({children}) => (\n <BarActionsPlacementContext.Provider value={BAR_ACTIONS_PLACEMENT.capsule}>{children}</BarActionsPlacementContext.Provider>\n);\n\n/** El «⋯» del teléfono con las acciones que no caben, como renglones de menú con su nombre. */\nconst MoreActionsMenu = ({label, children}) => {\n const [anchorElement, setAnchorElement] = useState(null);\n const close = () => setAnchorElement(null);\n return (\n <>\n <Tooltip title={label}>\n <IconButton aria-label={label} aria-haspopup=\"menu\" aria-expanded={Boolean(anchorElement)}\n onClick={(event) => setAnchorElement(event.currentTarget)}>\n <MoreHorizRoundedIcon />\n </IconButton>\n </Tooltip>\n {/* OJO keepMounted: una acción del «⋯» puede abrir algo suyo al picarla (DownloadMenu abre sus formatos y su\n confirmación); sin él, al cerrarse este menú se desmontaba con todo y lo que abrió */}\n <Menu anchorEl={anchorElement} open={Boolean(anchorElement)} onClose={close} keepMounted\n anchorOrigin={{vertical: 'bottom', horizontal: 'right'}} transformOrigin={{vertical: 'top', horizontal: 'right'}}>\n <BarActionsMenuCloseContext.Provider value={close}>\n <BarActionsPlacementContext.Provider value={BAR_ACTIONS_PLACEMENT.menu}>{children}</BarActionsPlacementContext.Provider>\n </BarActionsMenuCloseContext.Provider>\n </Menu>\n </>\n );\n};\n\n/** La cápsula que flota en el teléfono: las que caben como ícono y, si sobran, el «⋯» con las demás. */\nconst PhoneFloatingCapsule = ({phoneSlot, label, sx, texts, children, ...rest}) => {\n const {t} = useToolkitTranslation('layout', texts);\n const [capsuleElement, setCapsuleElement] = useState(null);\n const actions = Children.toArray(children);\n const visibleCount = useFittingActionCount(phoneSlot, capsuleElement, actions.length);\n const hiddenActions = actions.slice(visibleCount);\n return (\n <BarCapsule ref={setCapsuleElement} aria-label={label} sx={sx} {...rest}>\n <InCapsule>{actions.slice(0, visibleCount)}</InCapsule>\n {hiddenActions.length > 0 && <MoreActionsMenu label={t('barActions.more')}>{hiddenActions}</MoreActionsMenu>}\n </BarCapsule>\n );\n};\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} props.children los botones de este grupo (normalmente BarActionButton)\n * @param {string} [props.label] el nombre del grupo (lector de pantalla): «Acciones de pedidos»\n * @param {number} [props.order] en qué lugar va entre los grupos de la pantalla (CSS order; por omisión el de aparición)\n * @param {object|Function|Array} [props.sx] estilos propios de la cápsula de arriba o de la flotante del teléfono (o del\n * grupo, en la franja)\n * @param {object|Function|Array} [props.inlineSx] estilos de la cápsula cuando se queda en la pantalla\n * @param {boolean} [props.bare] sin cápsula alrededor: lo de adentro ya es una (un buscador)\n * @param {boolean} [props.exclusive] en el teléfono, mientras se ve, es lo único del renglón flotante (con los demás grupos\n * exclusivos): los otros se esconden, como el modo de edición del iPhone deja solo lo de lo elegido. Lo usa SelectionActions\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete\n */\nfunction BarActionsContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarActions.defaultProps) y encima lo que llega aquí\n const {children, label, order, sx, inlineSx, bare = false, exclusive = false, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {slot, phoneSlot, usesCapsules} = useBarActionsSlot();\n const isDesktop = useMediaQuery(DESKTOP_MEDIA_QUERY);\n // en escritorio, la barra; en el teléfono, el renglón flotante (solo existe con cápsulas)\n const target = isDesktop ? slot : phoneSlot;\n const orderSx = order === undefined ? {} : {order};\n const extraSx = Array.isArray(sx) ? sx : [sx];\n const extraInlineSx = Array.isArray(inlineSx) ? inlineSx : [inlineSx];\n\n // sin lugar: donde la pantalla las puso, en su cápsula de íconos\n if (!target) {\n if (bare) {\n return <ActionsGroup role=\"group\" aria-label={label} ownSx={{display: 'flex', alignItems: 'center'}} sx={extraInlineSx}>{children}</ActionsGroup>;\n }\n return (\n <BarCapsule aria-label={label} sx={[{alignSelf: 'flex-start'}, ...extraInlineSx]}>\n <InCapsule>{children}</InCapsule>\n </BarCapsule>\n );\n }\n // exclusivo en el teléfono: se marca y esconde a los demás grupos del renglón mientras se ve. OJO: sin esto, con algo\n // elegido no cabían el conteo, sus acciones, la lupa y las de la pantalla, y el renglón se salía por los dos lados\n const exclusiveProps = !isDesktop && exclusive ? {[EXCLUSIVE_ATTRIBUTE]: ''} : {};\n const hideOthers = !isDesktop && exclusive && <GlobalStyles styles={HIDE_NOT_EXCLUSIVE_STYLES} />;\n // flotando en el teléfono: las que caben y el «⋯»\n if (!isDesktop && !bare) {\n return (\n <>\n {hideOthers}\n {createPortal(<PhoneFloatingCapsule phoneSlot={phoneSlot} label={label} sx={[orderSx, ...extraSx]} texts={texts} {...exclusiveProps}>{children}</PhoneFloatingCapsule>, target)}\n </>\n );\n }\n // arriba en la barra (o el buscador flotando en el teléfono)\n if (usesCapsules && !bare) {\n return createPortal(<BarCapsule aria-label={label} sx={[orderSx, ...extraSx]}><InCapsule>{children}</InCapsule></BarCapsule>, target);\n }\n if (usesCapsules) {\n return (\n <>\n {hideOthers}\n {createPortal(<ActionsGroup role=\"group\" aria-label={label} ownSx={[{display: 'flex', alignItems: 'center'}, orderSx]} sx={extraSx} {...exclusiveProps}>{children}</ActionsGroup>, target)}\n </>\n );\n }\n // en la franja: botones sueltos (solo ícono) con el color de la franja (sobre el naranja de Stackcraft, el color\n // principal no se vería)\n return createPortal(\n <ActionsGroup role=\"group\" aria-label={label}\n ownSx={[{display: 'flex', alignItems: 'center', gap: 0.5, ...monochromeButtonsSxOf('inherit')}, orderSx]} sx={extraSx}>\n <InCapsule>{children}</InCapsule>\n </ActionsGroup>,\n target,\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst BarActions = withPieceSlots(BarActionsContent, THEME_NAME);\nexport default BarActions;\n"],"names":[],"mappings":"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"}
|