@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
|
@@ -14,7 +14,7 @@ import { useRegisterPageTitle } from "../../appShell/pageTitle.js";
|
|
|
14
14
|
import { menuBreadcrumbsOf } from "../../navigation/appMenu.js";
|
|
15
15
|
import PageBreadcrumbs from "../navigation/PageBreadcrumbs.js";
|
|
16
16
|
import DocumentTitle from "../navigation/DocumentTitle.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 = "CalcitaPageHeading";
|
|
20
20
|
const HeadingRoot = piecePart(THEME_NAME, "Root", Box);
|
|
@@ -24,7 +24,7 @@ const HeadingTitle = piecePart(THEME_NAME, "Title", Typography);
|
|
|
24
24
|
const HeadingActions = piecePart(THEME_NAME, "Actions", Box);
|
|
25
25
|
const HeadingDescription = piecePart(THEME_NAME, "Description", Typography);
|
|
26
26
|
const MIN_BREADCRUMBS = 2;
|
|
27
|
-
function
|
|
27
|
+
function PageHeadingContent(props) {
|
|
28
28
|
const { title, description, breadcrumbs, actions, documentTitle, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
29
29
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
30
30
|
const { t } = useToolkitTranslation("layout", texts);
|
|
@@ -56,6 +56,7 @@ function PageHeading(props) {
|
|
|
56
56
|
description && /* @__PURE__ */ jsx(HeadingDescription, { variant: "body1", color: "text.secondary", component: "div", ownSx: { mt: 0.75, maxWidth: 760 }, children: description })
|
|
57
57
|
] });
|
|
58
58
|
}
|
|
59
|
+
const PageHeading = withPieceSlots(PageHeadingContent, THEME_NAME);
|
|
59
60
|
export {
|
|
60
61
|
PageHeading as default
|
|
61
62
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageHeading.js","sources":["../../../src/ui/layout/PageHeading.jsx"],"sourcesContent":["// El encabezado de una pantalla al estilo de las plantillas de MUI (y del PageContainer de walk-ot): las migas arriba, el\n// título a la izquierda con los botones a la derecha, y una descripción corta abajo.\n//\n// Las migas salen SOLAS del menú de AppLayout (Inicio › Sección › Pantalla): la página no las escribe. Una pantalla que\n// no está en el menú (un detalle) pasa las suyas con `breadcrumbs`; breadcrumbs={false} las quita.\n// El título sube a la barra de AppLayout cuando sale de la vista al deslizar, y también es el título de la pestaña.\n// Con la barra en cápsulas, sus `actions` van a la barra en su propia cápsula (BarActions), como las barras de\n// herramientas de macOS; en el teléfono, y con la franja, se quedan aquí (con la franja, para no mover pantallas que ya\n// existen: quien las quiera en la franja usa BarActions).\n//\n// Cuál usar: PageHeading en las pantallas de trabajo (listas, formularios, tableros); PageHeader (centrado) en una\n// portada; DetailHeader en el detalle de un registro (título con sus insignias de estatus).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPageHeading con defaultProps y\n// styleOverrides de sus partes: root, breadcrumbs, titleRow, title, actions, description.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useRef} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport Box from '@mui/material/Box';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {useAppMenu} from '@/appShell/appMenuContext.js';\nimport BarActions from '@/appShell/BarActions.jsx';\nimport {useBarActionsSlot} from '@/appShell/barActionsSlot.js';\nimport {menuItemLabelOf} from '@/appShell/menuItemText.js';\nimport {useRegisterPageTitle} from '@/appShell/pageTitle.jsx';\nimport {menuBreadcrumbsOf} from '@/navigation/appMenu.js';\nimport PageBreadcrumbs from '@/ui/navigation/PageBreadcrumbs.jsx';\nimport DocumentTitle from '@/ui/navigation/DocumentTitle.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.CalcitaPageHeading)\nconst THEME_NAME = 'CalcitaPageHeading';\nconst HeadingRoot = piecePart(THEME_NAME, 'Root', Box);\nconst HeadingBreadcrumbs = piecePart(THEME_NAME, 'Breadcrumbs', Box);\nconst HeadingTitleRow = piecePart(THEME_NAME, 'TitleRow', Stack);\nconst HeadingTitle = piecePart(THEME_NAME, 'Title', Typography);\nconst HeadingActions = piecePart(THEME_NAME, 'Actions', Box);\nconst HeadingDescription = piecePart(THEME_NAME, 'Description', Typography);\n\n// con una sola miga (estar en el inicio) no se pintan: no dicen nada\nconst MIN_BREADCRUMBS = 2;\n\n/**\n * @param {object} props\n * @param {string} props.title texto ya traducido\n * @param {import('react').ReactNode} [props.description]\n * @param {Array<{label: string, to?: string}>|false} [props.breadcrumbs] por omisión, las del menú\n * @param {import('react').ReactNode} [props.actions] botones a la derecha (en el teléfono, abajo y a lo ancho)\n * @param {string} [props.documentTitle] título de la pestaña si difiere del visible\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"PageHeading.js","sources":["../../../src/ui/layout/PageHeading.jsx"],"sourcesContent":["// El encabezado de una pantalla al estilo de las plantillas de MUI (y del PageContainer de walk-ot): las migas arriba, el\n// título a la izquierda con los botones a la derecha, y una descripción corta abajo.\n//\n// Las migas salen SOLAS del menú de AppLayout (Inicio › Sección › Pantalla): la página no las escribe. Una pantalla que\n// no está en el menú (un detalle) pasa las suyas con `breadcrumbs`; breadcrumbs={false} las quita.\n// El título sube a la barra de AppLayout cuando sale de la vista al deslizar, y también es el título de la pestaña.\n// Con la barra en cápsulas, sus `actions` van a la barra en su propia cápsula (BarActions), como las barras de\n// herramientas de macOS; en el teléfono, y con la franja, se quedan aquí (con la franja, para no mover pantallas que ya\n// existen: quien las quiera en la franja usa BarActions).\n//\n// Cuál usar: PageHeading en las pantallas de trabajo (listas, formularios, tableros); PageHeader (centrado) en una\n// portada; DetailHeader en el detalle de un registro (título con sus insignias de estatus).\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPageHeading con defaultProps y\n// styleOverrides de sus partes: root, breadcrumbs, titleRow, title, actions, description.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useRef} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {useToolkitNavigation} from '@/toolkit/toolkitContext.js';\nimport Box from '@mui/material/Box';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {useAppMenu} from '@/appShell/appMenuContext.js';\nimport BarActions from '@/appShell/BarActions.jsx';\nimport {useBarActionsSlot} from '@/appShell/barActionsSlot.js';\nimport {menuItemLabelOf} from '@/appShell/menuItemText.js';\nimport {useRegisterPageTitle} from '@/appShell/pageTitle.jsx';\nimport {menuBreadcrumbsOf} from '@/navigation/appMenu.js';\nimport PageBreadcrumbs from '@/ui/navigation/PageBreadcrumbs.jsx';\nimport DocumentTitle from '@/ui/navigation/DocumentTitle.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.CalcitaPageHeading)\nconst THEME_NAME = 'CalcitaPageHeading';\nconst HeadingRoot = piecePart(THEME_NAME, 'Root', Box);\nconst HeadingBreadcrumbs = piecePart(THEME_NAME, 'Breadcrumbs', Box);\nconst HeadingTitleRow = piecePart(THEME_NAME, 'TitleRow', Stack);\nconst HeadingTitle = piecePart(THEME_NAME, 'Title', Typography);\nconst HeadingActions = piecePart(THEME_NAME, 'Actions', Box);\nconst HeadingDescription = piecePart(THEME_NAME, 'Description', Typography);\n\n// con una sola miga (estar en el inicio) no se pintan: no dicen nada\nconst MIN_BREADCRUMBS = 2;\n\n/**\n * @param {object} props\n * @param {string} props.title texto ya traducido\n * @param {import('react').ReactNode} [props.description]\n * @param {Array<{label: string, to?: string}>|false} [props.breadcrumbs] por omisión, las del menú\n * @param {import('react').ReactNode} [props.actions] botones a la derecha (en el teléfono, abajo y a lo ancho)\n * @param {string} [props.documentTitle] título de la pestaña si difiere del visible\n * @param {object} [props.texts] los textos que cambian, con la forma de `layout` en los textos del paquete\n */\nfunction PageHeadingContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaPageHeading.defaultProps) y encima lo que llega aquí\n const {title, description, breadcrumbs, actions, documentTitle, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('layout', texts);\n const {useLocation} = useToolkitNavigation();\n const {pathname} = useLocation();\n const {menuItems} = useAppMenu();\n const titleRef = useRef(null);\n useRegisterPageTitle(title, titleRef);\n const {usesCapsules} = useBarActionsSlot();\n // sin cápsulas: a la derecha del título y, en el teléfono, abajo y a lo ancho\n const inlineActionsSx = {display: 'flex', gap: 1, flexWrap: 'wrap', flex: {xs: '1 1 auto', sm: '0 0 auto'}, '& > .MuiButton-root': {width: {xs: '100%', sm: 'auto'}}};\n // con cápsulas suben a la barra (escritorio) o flotan arriba (teléfono). Si no hay dónde (la barra fundida al menú), la\n // cápsula de solo íconos se queda a la derecha del título, en el mismo renglón; el título se parte si no cabe\n const isActionsCapsule = Boolean(actions) && usesCapsules;\n\n const crumbs = breadcrumbs === false\n ? []\n : breadcrumbs ?? menuBreadcrumbsOf(menuItems, pathname).map((menuItem) => ({label: menuItemLabelOf(menuItem, t), to: menuItem.to}));\n\n return (\n <HeadingRoot component=\"header\" ownSx={{mb: 3}}>\n <DocumentTitle title={documentTitle ?? title} />\n {crumbs.length >= MIN_BREADCRUMBS && <HeadingBreadcrumbs ownSx={{mb: 1}}><PageBreadcrumbs items={crumbs} /></HeadingBreadcrumbs>}\n <HeadingTitleRow direction={isActionsCapsule ? 'row' : {xs: 'column', sm: 'row'}} spacing={{xs: 1.5, sm: 2}}\n ownSx={{alignItems: isActionsCapsule ? 'flex-start' : {xs: 'stretch', sm: 'flex-start'}, justifyContent: 'space-between'}}>\n <HeadingTitle ref={titleRef} variant=\"h4\" component=\"h1\" ownSx={{minWidth: 0}}>{title}</HeadingTitle>\n {isActionsCapsule && <BarActions label={title} inlineSx={{flexShrink: 0}}>{actions}</BarActions>}\n {actions && !usesCapsules && <HeadingActions ownSx={inlineActionsSx}>{actions}</HeadingActions>}\n </HeadingTitleRow>\n {description && (\n <HeadingDescription variant=\"body1\" color=\"text.secondary\" component=\"div\" ownSx={{mt: 0.75, maxWidth: 760}}>{description}</HeadingDescription>\n )}\n </HeadingRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst PageHeading = withPieceSlots(PageHeadingContent, THEME_NAME);\nexport default PageHeading;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAoCA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,QAAQ,GAAG;AACrD,MAAM,qBAAqB,UAAU,YAAY,eAAe,GAAG;AACnE,MAAM,kBAAkB,UAAU,YAAY,YAAY,KAAK;AAC/D,MAAM,eAAe,UAAU,YAAY,SAAS,UAAU;AAC9D,MAAM,iBAAiB,UAAU,YAAY,WAAW,GAAG;AAC3D,MAAM,qBAAqB,UAAU,YAAY,eAAe,UAAU;AAG1E,MAAM,kBAAkB;AAWxB,SAAS,mBAAmB,OAAO;AAE/B,QAAM,EAAC,OAAO,aAAa,aAAa,SAAS,eAAe,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AACzH,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,YAAA,IAAe,qBAAA;AACtB,QAAM,EAAC,SAAA,IAAY,YAAA;AACnB,QAAM,EAAC,UAAA,IAAa,WAAA;AACpB,QAAM,WAAW,OAAO,IAAI;AAC5B,uBAAqB,OAAO,QAAQ;AACpC,QAAM,EAAC,aAAA,IAAgB,kBAAA;AAEvB,QAAM,kBAAkB,EAAC,SAAS,QAAQ,KAAK,GAAG,UAAU,QAAQ,MAAM,EAAC,IAAI,YAAY,IAAI,WAAA,GAAa,uBAAuB,EAAC,OAAO,EAAC,IAAI,QAAQ,IAAI,OAAA,IAAO;AAGnK,QAAM,mBAAmB,QAAQ,OAAO,KAAK;AAE7C,QAAM,SAAS,gBAAgB,QACzB,CAAA,IACA,eAAe,kBAAkB,WAAW,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAC,OAAO,gBAAgB,UAAU,CAAC,GAAG,IAAI,SAAS,GAAA,EAAI;AAEtI,SACI,qBAAC,eAAY,WAAU,UAAS,OAAO,EAAC,IAAI,KACxC,UAAA;AAAA,IAAA,oBAAC,eAAA,EAAc,OAAO,iBAAiB,MAAA,CAAO;AAAA,IAC7C,OAAO,UAAU,mBAAmB,oBAAC,sBAAmB,OAAO,EAAC,IAAI,EAAA,GAAI,UAAA,oBAAC,iBAAA,EAAgB,OAAO,QAAQ,GAAE;AAAA,IAC3G;AAAA,MAAC;AAAA,MAAA;AAAA,QAAgB,WAAW,mBAAmB,QAAQ,EAAC,IAAI,UAAU,IAAI,MAAA;AAAA,QAAQ,SAAS,EAAC,IAAI,KAAK,IAAI,EAAA;AAAA,QAClG,OAAO,EAAC,YAAY,mBAAmB,eAAe,EAAC,IAAI,WAAW,IAAI,gBAAe,gBAAgB,gBAAA;AAAA,QAC5G,UAAA;AAAA,UAAA,oBAAC,cAAA,EAAa,KAAK,UAAU,SAAQ,MAAK,WAAU,MAAK,OAAO,EAAC,UAAU,EAAA,GAAK,UAAA,OAAM;AAAA,UACrF,oBAAoB,oBAAC,YAAA,EAAW,OAAO,OAAO,UAAU,EAAC,YAAY,EAAA,GAAK,UAAA,QAAA,CAAQ;AAAA,UAClF,WAAW,CAAC,oCAAiB,gBAAA,EAAe,OAAO,iBAAkB,UAAA,QAAA,CAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEjF,eACG,oBAAC,oBAAA,EAAmB,SAAQ,SAAQ,OAAM,kBAAiB,WAAU,OAAM,OAAO,EAAC,IAAI,MAAM,UAAU,IAAA,GAAO,UAAA,YAAA,CAAY;AAAA,EAAA,GAElI;AAER;AAGA,MAAM,cAAc,eAAe,oBAAoB,UAAU;"}
|
|
@@ -11,7 +11,7 @@ import { initialsOf } from "../../appShell/menuItemText.js";
|
|
|
11
11
|
import { useRegisterPageTitle } from "../../appShell/pageTitle.js";
|
|
12
12
|
import { paletteOf } from "../../theme/components/paletteOf.js";
|
|
13
13
|
import DocumentTitle from "../navigation/DocumentTitle.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 = "CalcitaProfileHeader";
|
|
17
17
|
const ProfileRoot = piecePart(THEME_NAME, "Root", Paper);
|
|
@@ -33,7 +33,7 @@ const coverOf = (theme) => {
|
|
|
33
33
|
backgroundImage: `radial-gradient(80% 140% at 85% 0%, color-mix(in srgb, ${palette.primary.light} 70%, transparent), transparent 60%), linear-gradient(120deg, ${palette.primary.main}, ${palette.primary.dark})`
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
|
-
function
|
|
36
|
+
function ProfileHeaderContent(props) {
|
|
37
37
|
const { name, email, subtitle, avatarUrl, chips = [], actions, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
38
38
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
39
39
|
const titleRef = useRef(null);
|
|
@@ -71,6 +71,7 @@ function ProfileHeader(props) {
|
|
|
71
71
|
] })
|
|
72
72
|
] });
|
|
73
73
|
}
|
|
74
|
+
const ProfileHeader = withPieceSlots(ProfileHeaderContent, THEME_NAME);
|
|
74
75
|
export {
|
|
75
76
|
ProfileHeader as default
|
|
76
77
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileHeader.js","sources":["../../../src/ui/layout/ProfileHeader.jsx"],"sourcesContent":["// El encabezado de una persona («Mi perfil», el detalle de un usuario): una franja de color arriba, el avatar grande\n// (su foto o sus iniciales) montado sobre la franja, el nombre, el correo, sus perfiles como etiquetas y, a la derecha,\n// las acciones (editar, desactivar…). Como el de las plantillas de tablero de MUI.\n//\n// En el teléfono las acciones bajan debajo del nombre. El nombre es el título de la página (h1) y sube a la barra al\n// deslizar, como el de PageHeading.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaProfileHeader con defaultProps y\n// styleOverrides de sus partes: root, cover, body, avatar, text, name, chips, actions.\n//\n// Genérico del paquete: function (regla de la casa). No sabe de negocio: todo llega ya traducido.\nimport {useRef} from 'react';\nimport Avatar from '@mui/material/Avatar';\nimport Box from '@mui/material/Box';\nimport Chip from '@mui/material/Chip';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {initialsOf} from '@/appShell/menuItemText.js';\nimport {useRegisterPageTitle} from '@/appShell/pageTitle.jsx';\nimport {paletteOf} from '@/theme/components/paletteOf.js';\nimport DocumentTitle from '@/ui/navigation/DocumentTitle.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.CalcitaProfileHeader)\nconst THEME_NAME = 'CalcitaProfileHeader';\nconst ProfileRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst ProfileCover = piecePart(THEME_NAME, 'Cover', Box);\nconst ProfileBody = piecePart(THEME_NAME, 'Body', Stack);\nconst ProfileAvatar = piecePart(THEME_NAME, 'Avatar', Avatar);\nconst ProfileText = piecePart(THEME_NAME, 'Text', Box);\nconst ProfileName = piecePart(THEME_NAME, 'Name', Typography);\nconst ProfileChips = piecePart(THEME_NAME, 'Chips', Stack);\nconst ProfileActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n// la franja de arriba y el avatar que se monta en ella (la mitad del avatar sobre la franja)\nconst COVER_HEIGHT_PIXELS = 112;\nconst AVATAR_SIZE_PIXELS = 96;\nconst AVATAR_BORDER_PIXELS = 4;\n\n/**\n * La franja de color: el principal del tema, más oscuro hacia la derecha, con un brillo suave.\n *\n * @param {object} theme\n * @returns {object}\n */\nconst coverOf = (theme) => {\n const palette = paletteOf(theme);\n return {\n height: COVER_HEIGHT_PIXELS,\n backgroundColor: palette.primary.main,\n backgroundImage: `radial-gradient(80% 140% at 85% 0%, color-mix(in srgb, ${palette.primary.light} 70%, transparent), transparent 60%), `\n + `linear-gradient(120deg, ${palette.primary.main}, ${palette.primary.dark})`,\n };\n};\n\n/**\n * @param {object} props\n * @param {string} props.name el nombre de la persona\n * @param {string} [props.email]\n * @param {string} [props.subtitle] el renglón de abajo (puesto · sucursal)\n * @param {string} [props.avatarUrl] su foto; sin ella, sus iniciales\n * @param {string[]} [props.chips] sus perfiles o etiquetas, ya traducidos\n * @param {import('react').ReactNode} [props.actions] los botones de la derecha\n */\
|
|
1
|
+
{"version":3,"file":"ProfileHeader.js","sources":["../../../src/ui/layout/ProfileHeader.jsx"],"sourcesContent":["// El encabezado de una persona («Mi perfil», el detalle de un usuario): una franja de color arriba, el avatar grande\n// (su foto o sus iniciales) montado sobre la franja, el nombre, el correo, sus perfiles como etiquetas y, a la derecha,\n// las acciones (editar, desactivar…). Como el de las plantillas de tablero de MUI.\n//\n// En el teléfono las acciones bajan debajo del nombre. El nombre es el título de la página (h1) y sube a la barra al\n// deslizar, como el de PageHeading.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaProfileHeader con defaultProps y\n// styleOverrides de sus partes: root, cover, body, avatar, text, name, chips, actions.\n//\n// Genérico del paquete: function (regla de la casa). No sabe de negocio: todo llega ya traducido.\nimport {useRef} from 'react';\nimport Avatar from '@mui/material/Avatar';\nimport Box from '@mui/material/Box';\nimport Chip from '@mui/material/Chip';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport {initialsOf} from '@/appShell/menuItemText.js';\nimport {useRegisterPageTitle} from '@/appShell/pageTitle.jsx';\nimport {paletteOf} from '@/theme/components/paletteOf.js';\nimport DocumentTitle from '@/ui/navigation/DocumentTitle.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.CalcitaProfileHeader)\nconst THEME_NAME = 'CalcitaProfileHeader';\nconst ProfileRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst ProfileCover = piecePart(THEME_NAME, 'Cover', Box);\nconst ProfileBody = piecePart(THEME_NAME, 'Body', Stack);\nconst ProfileAvatar = piecePart(THEME_NAME, 'Avatar', Avatar);\nconst ProfileText = piecePart(THEME_NAME, 'Text', Box);\nconst ProfileName = piecePart(THEME_NAME, 'Name', Typography);\nconst ProfileChips = piecePart(THEME_NAME, 'Chips', Stack);\nconst ProfileActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n// la franja de arriba y el avatar que se monta en ella (la mitad del avatar sobre la franja)\nconst COVER_HEIGHT_PIXELS = 112;\nconst AVATAR_SIZE_PIXELS = 96;\nconst AVATAR_BORDER_PIXELS = 4;\n\n/**\n * La franja de color: el principal del tema, más oscuro hacia la derecha, con un brillo suave.\n *\n * @param {object} theme\n * @returns {object}\n */\nconst coverOf = (theme) => {\n const palette = paletteOf(theme);\n return {\n height: COVER_HEIGHT_PIXELS,\n backgroundColor: palette.primary.main,\n backgroundImage: `radial-gradient(80% 140% at 85% 0%, color-mix(in srgb, ${palette.primary.light} 70%, transparent), transparent 60%), `\n + `linear-gradient(120deg, ${palette.primary.main}, ${palette.primary.dark})`,\n };\n};\n\n/**\n * @param {object} props\n * @param {string} props.name el nombre de la persona\n * @param {string} [props.email]\n * @param {string} [props.subtitle] el renglón de abajo (puesto · sucursal)\n * @param {string} [props.avatarUrl] su foto; sin ella, sus iniciales\n * @param {string[]} [props.chips] sus perfiles o etiquetas, ya traducidos\n * @param {import('react').ReactNode} [props.actions] los botones de la derecha\n */\nfunction ProfileHeaderContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaProfileHeader.defaultProps) y encima lo que llega aquí\n const {name, email, subtitle, avatarUrl, chips = [], actions, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const titleRef = useRef(null);\n useRegisterPageTitle(name, titleRef);\n\n return (\n <ProfileRoot variant=\"outlined\" ownSx={{overflow: 'hidden', mb: 3}}>\n <DocumentTitle title={name} />\n <ProfileCover ownSx={coverOf} />\n <ProfileBody direction={{xs: 'column', sm: 'row'}} spacing={2} ownSx={{px: {xs: 2, md: 3}, pb: 2.5, alignItems: {sm: 'flex-end'}}}>\n <ProfileAvatar src={avatarUrl} alt={name}\n ownSx={{\n width: AVATAR_SIZE_PIXELS, height: AVATAR_SIZE_PIXELS, mt: `-${AVATAR_SIZE_PIXELS / 2}px`, fontSize: '2rem', fontWeight: 600,\n border: `${AVATAR_BORDER_PIXELS}px solid`, borderColor: 'background.paper', bgcolor: 'secondary.main', color: 'secondary.contrastText',\n }}>\n {initialsOf(name)}\n </ProfileAvatar>\n <ProfileText ownSx={{flexGrow: 1, minWidth: 0}}>\n <ProfileName ref={titleRef} variant=\"h5\" component=\"h1\" ownSx={{fontWeight: 600}}>{name}</ProfileName>\n {email && <Typography variant=\"body2\" color=\"text.secondary\">{email}</Typography>}\n {subtitle && <Typography variant=\"body2\" color=\"text.secondary\">{subtitle}</Typography>}\n {chips.length > 0 && (\n <ProfileChips direction=\"row\" spacing={1} useFlexGap ownSx={{flexWrap: 'wrap', mt: 1}}>\n {chips.map((chip) => <Chip key={chip} label={chip} size=\"small\" color=\"primary\" variant=\"outlined\" />)}\n </ProfileChips>\n )}\n </ProfileText>\n {actions && <ProfileActions direction=\"row\" spacing={1} useFlexGap ownSx={{flexWrap: 'wrap', flexShrink: 0}}>{actions}</ProfileActions>}\n </ProfileBody>\n </ProfileRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst ProfileHeader = withPieceSlots(ProfileHeaderContent, THEME_NAME);\nexport default ProfileHeader;\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useRef, useState, Children, useEffect } from "react";
|
|
4
4
|
import Box from "@mui/material/Box";
|
|
5
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
5
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
6
6
|
const THEME_NAME = "CalcitaScrollableRow";
|
|
7
7
|
const RowRoot = piecePart(THEME_NAME, "Root", Box);
|
|
8
8
|
const scrollableRow = {
|
|
@@ -15,7 +15,7 @@ const scrollableRow = {
|
|
|
15
15
|
"&::-webkit-scrollbar": { display: "none" }
|
|
16
16
|
};
|
|
17
17
|
const DRAG_THRESHOLD_PIXELS = 5;
|
|
18
|
-
function
|
|
18
|
+
function ScrollableRowContent(props) {
|
|
19
19
|
const {
|
|
20
20
|
children,
|
|
21
21
|
gap = 1,
|
|
@@ -153,6 +153,7 @@ function ScrollableRow(props) {
|
|
|
153
153
|
}
|
|
154
154
|
);
|
|
155
155
|
}
|
|
156
|
+
const ScrollableRow = withPieceSlots(ScrollableRowContent, THEME_NAME);
|
|
156
157
|
export {
|
|
157
158
|
ScrollableRow as default,
|
|
158
159
|
scrollableRow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScrollableRow.js","sources":["../../../src/ui/layout/ScrollableRow.jsx"],"sourcesContent":["// Tira horizontal que se desliza, no que se envuelve (chips de filtros y accesos rápidos).\n//\n// Con muchos filtros puestos los chips se envolvían en varios renglones y empujaban la tabla fuera de la pantalla,\n// justo cuando más falta hace ver el resultado. Encapsula lo que hace falta para que la tira se sienta nativa:\n// - overflow-x sin barra visible en los tres motores;\n// - arrastre con el mouse en escritorio (el deslizamiento táctil ya es gratis);\n// - la rueda vertical se convierte en desplazamiento horizontal;\n// - el borde por el que sigue habiendo contenido se DESVANECE: sin barra ni desvanecido, una tira cortada a la mitad\n// se lee como un chip mal pintado.\n// Todo eso se activa SOLO cuando de verdad hay desbordamiento.\n//\n// OJO: el umbral de 5 px separa el arrastre del clic; mover más cancela el clic que venía detrás, para no borrar un\n// filtro cuando lo que se quería era desplazar la tira.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaScrollableRow con defaultProps y\n// styleOverrides.root (el sx de la pantalla sigue ganando a todo).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {Children, useEffect, useRef, useState} from 'react';\nimport Box from '@mui/material/Box';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaScrollableRow)\nconst THEME_NAME = 'CalcitaScrollableRow';\nconst RowRoot = piecePart(THEME_NAME, 'Root', Box);\n\n/** El mixin sin arrastre, para cuando no se puede envolver el elemento. */\nexport const scrollableRow = {\n display: 'flex',\n flexWrap: 'nowrap',\n overflowX: 'auto',\n overflowY: 'hidden',\n scrollbarWidth: 'none',\n msOverflowStyle: 'none',\n '&::-webkit-scrollbar': {display: 'none'},\n};\n\nconst DRAG_THRESHOLD_PIXELS = 5;\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} props.children\n * @param {number} [props.gap]\n * @param {number} [props.py]\n * @param {object} [props.sx]\n * @param {boolean} [props.enableDragScroll]\n * @param {boolean} [props.enableWheelToX]\n * @param {boolean} [props.fadeEdges]\n * @param {import('react').Ref<HTMLElement>} [props.ref]\n */\nexport default function ScrollableRow(props) {\n // lo que el proyecto puso en su tema (components.CalcitaScrollableRow.defaultProps) y encima lo que llega aquí\n const {\n children, gap = 1, py = 0.5, sx, enableDragScroll = true, enableWheelToX = true, fadeEdges = true, ref, ...boxProps\n } = usePieceProps(props, THEME_NAME);\n const rowElement = useRef(null);\n // por dónde sigue habiendo contenido: decide de qué lado va el desvanecido\n const [edges, setEdges] = useState({overflow: false, start: false, end: false});\n\n const assignRef = (node) => {\n rowElement.current = node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref && typeof ref === 'object') {\n ref.current = node;\n }\n };\n\n // el número de hijos es la señal estable para revisar de nuevo (el padre agrega y quita chips)\n const childrenCount = Children.count(children);\n useEffect(() => {\n const element = rowElement.current;\n if (!element) {\n return undefined;\n }\n // el +1 evita el falso positivo por subpíxel\n const measureEdges = () => setEdges({\n overflow: element.scrollWidth > element.clientWidth + 1,\n start: element.scrollLeft > 1,\n end: element.scrollLeft + element.clientWidth < element.scrollWidth - 1,\n });\n measureEdges();\n\n const resizeObserver = new ResizeObserver(measureEdges);\n resizeObserver.observe(element);\n element.addEventListener('scroll', measureEdges, {passive: true});\n return () => {\n resizeObserver.disconnect();\n element.removeEventListener('scroll', measureEdges);\n };\n }, [childrenCount]);\n\n useEffect(() => {\n const element = rowElement.current;\n if (!element) {\n return undefined;\n }\n\n let isDragging = false;\n let hasMoved = false;\n let startX = 0;\n let scrollStart = 0;\n\n const isOverflowing = () => element.scrollWidth > element.clientWidth + 1;\n\n const handleMouseDown = (event) => {\n if (event.button !== 0 || !isOverflowing()) {\n return;\n }\n // arrastrar dentro de un campo de texto es seleccionar texto, no desplazar la tira\n if (['INPUT', 'TEXTAREA'].includes(event.target?.tagName)) {\n return;\n }\n isDragging = true;\n hasMoved = false;\n startX = event.pageX;\n scrollStart = element.scrollLeft;\n };\n\n const handleMouseMove = (event) => {\n if (!isDragging) {\n return;\n }\n const distance = event.pageX - startX;\n if (!hasMoved && Math.abs(distance) > DRAG_THRESHOLD_PIXELS) {\n hasMoved = true;\n element.style.cursor = 'grabbing';\n }\n if (hasMoved) {\n event.preventDefault();\n element.scrollLeft = scrollStart - distance;\n }\n };\n\n const stopDragging = () => {\n isDragging = false;\n element.style.cursor = '';\n };\n\n const handleClickCapture = (event) => {\n if (!hasMoved) {\n return;\n }\n // se arrastró: el clic que viene detrás NO es un clic\n event.preventDefault();\n event.stopPropagation();\n hasMoved = false;\n };\n\n const handleWheel = (event) => {\n if (isOverflowing() && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {\n event.preventDefault();\n element.scrollLeft += event.deltaY;\n }\n };\n\n if (enableDragScroll) {\n element.addEventListener('mousedown', handleMouseDown);\n element.addEventListener('mousemove', handleMouseMove);\n element.addEventListener('mouseup', stopDragging);\n element.addEventListener('mouseleave', stopDragging);\n element.addEventListener('click', handleClickCapture, true);\n }\n if (enableWheelToX) {\n element.addEventListener('wheel', handleWheel, {passive: false});\n }\n\n return () => {\n element.removeEventListener('mousedown', handleMouseDown);\n element.removeEventListener('mousemove', handleMouseMove);\n element.removeEventListener('mouseup', stopDragging);\n element.removeEventListener('mouseleave', stopDragging);\n element.removeEventListener('click', handleClickCapture, true);\n element.removeEventListener('wheel', handleWheel);\n };\n }, [enableDragScroll, enableWheelToX]);\n\n const isDragEnabled = enableDragScroll && edges.overflow;\n\n // máscara y no degradado encima: funciona sin saber de qué color es el fondo\n const fadeMask = fadeEdges && edges.overflow\n ? `linear-gradient(to right, ${[\n edges.start ? 'transparent 0, black 24px' : 'black 0',\n edges.end ? 'black calc(100% - 24px), transparent 100%' : 'black 100%',\n ].join(', ')})`\n : undefined;\n\n return (\n <RowRoot ref={assignRef}\n ownSx={{\n ...scrollableRow,\n gap,\n py,\n cursor: isDragEnabled ? 'grab' : 'auto',\n userSelect: isDragEnabled ? 'none' : 'auto',\n ...(fadeMask && {maskImage: fadeMask, WebkitMaskImage: fadeMask}),\n }}\n sx={sx}\n {...boxProps}>\n {children}\n </RowRoot>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ScrollableRow.js","sources":["../../../src/ui/layout/ScrollableRow.jsx"],"sourcesContent":["// Tira horizontal que se desliza, no que se envuelve (chips de filtros y accesos rápidos).\n//\n// Con muchos filtros puestos los chips se envolvían en varios renglones y empujaban la tabla fuera de la pantalla,\n// justo cuando más falta hace ver el resultado. Encapsula lo que hace falta para que la tira se sienta nativa:\n// - overflow-x sin barra visible en los tres motores;\n// - arrastre con el mouse en escritorio (el deslizamiento táctil ya es gratis);\n// - la rueda vertical se convierte en desplazamiento horizontal;\n// - el borde por el que sigue habiendo contenido se DESVANECE: sin barra ni desvanecido, una tira cortada a la mitad\n// se lee como un chip mal pintado.\n// Todo eso se activa SOLO cuando de verdad hay desbordamiento.\n//\n// OJO: el umbral de 5 px separa el arrastre del clic; mover más cancela el clic que venía detrás, para no borrar un\n// filtro cuando lo que se quería era desplazar la tira.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaScrollableRow con defaultProps y\n// styleOverrides.root (el sx de la pantalla sigue ganando a todo).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {Children, useEffect, useRef, useState} from 'react';\nimport Box from '@mui/material/Box';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaScrollableRow)\nconst THEME_NAME = 'CalcitaScrollableRow';\nconst RowRoot = piecePart(THEME_NAME, 'Root', Box);\n\n/** El mixin sin arrastre, para cuando no se puede envolver el elemento. */\nexport const scrollableRow = {\n display: 'flex',\n flexWrap: 'nowrap',\n overflowX: 'auto',\n overflowY: 'hidden',\n scrollbarWidth: 'none',\n msOverflowStyle: 'none',\n '&::-webkit-scrollbar': {display: 'none'},\n};\n\nconst DRAG_THRESHOLD_PIXELS = 5;\n\n/**\n * @param {object} props\n * @param {import('react').ReactNode} props.children\n * @param {number} [props.gap]\n * @param {number} [props.py]\n * @param {object} [props.sx]\n * @param {boolean} [props.enableDragScroll]\n * @param {boolean} [props.enableWheelToX]\n * @param {boolean} [props.fadeEdges]\n * @param {import('react').Ref<HTMLElement>} [props.ref]\n */\nfunction ScrollableRowContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaScrollableRow.defaultProps) y encima lo que llega aquí\n const {\n children, gap = 1, py = 0.5, sx, enableDragScroll = true, enableWheelToX = true, fadeEdges = true, ref, ...boxProps\n } = usePieceProps(props, THEME_NAME);\n const rowElement = useRef(null);\n // por dónde sigue habiendo contenido: decide de qué lado va el desvanecido\n const [edges, setEdges] = useState({overflow: false, start: false, end: false});\n\n const assignRef = (node) => {\n rowElement.current = node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref && typeof ref === 'object') {\n ref.current = node;\n }\n };\n\n // el número de hijos es la señal estable para revisar de nuevo (el padre agrega y quita chips)\n const childrenCount = Children.count(children);\n useEffect(() => {\n const element = rowElement.current;\n if (!element) {\n return undefined;\n }\n // el +1 evita el falso positivo por subpíxel\n const measureEdges = () => setEdges({\n overflow: element.scrollWidth > element.clientWidth + 1,\n start: element.scrollLeft > 1,\n end: element.scrollLeft + element.clientWidth < element.scrollWidth - 1,\n });\n measureEdges();\n\n const resizeObserver = new ResizeObserver(measureEdges);\n resizeObserver.observe(element);\n element.addEventListener('scroll', measureEdges, {passive: true});\n return () => {\n resizeObserver.disconnect();\n element.removeEventListener('scroll', measureEdges);\n };\n }, [childrenCount]);\n\n useEffect(() => {\n const element = rowElement.current;\n if (!element) {\n return undefined;\n }\n\n let isDragging = false;\n let hasMoved = false;\n let startX = 0;\n let scrollStart = 0;\n\n const isOverflowing = () => element.scrollWidth > element.clientWidth + 1;\n\n const handleMouseDown = (event) => {\n if (event.button !== 0 || !isOverflowing()) {\n return;\n }\n // arrastrar dentro de un campo de texto es seleccionar texto, no desplazar la tira\n if (['INPUT', 'TEXTAREA'].includes(event.target?.tagName)) {\n return;\n }\n isDragging = true;\n hasMoved = false;\n startX = event.pageX;\n scrollStart = element.scrollLeft;\n };\n\n const handleMouseMove = (event) => {\n if (!isDragging) {\n return;\n }\n const distance = event.pageX - startX;\n if (!hasMoved && Math.abs(distance) > DRAG_THRESHOLD_PIXELS) {\n hasMoved = true;\n element.style.cursor = 'grabbing';\n }\n if (hasMoved) {\n event.preventDefault();\n element.scrollLeft = scrollStart - distance;\n }\n };\n\n const stopDragging = () => {\n isDragging = false;\n element.style.cursor = '';\n };\n\n const handleClickCapture = (event) => {\n if (!hasMoved) {\n return;\n }\n // se arrastró: el clic que viene detrás NO es un clic\n event.preventDefault();\n event.stopPropagation();\n hasMoved = false;\n };\n\n const handleWheel = (event) => {\n if (isOverflowing() && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {\n event.preventDefault();\n element.scrollLeft += event.deltaY;\n }\n };\n\n if (enableDragScroll) {\n element.addEventListener('mousedown', handleMouseDown);\n element.addEventListener('mousemove', handleMouseMove);\n element.addEventListener('mouseup', stopDragging);\n element.addEventListener('mouseleave', stopDragging);\n element.addEventListener('click', handleClickCapture, true);\n }\n if (enableWheelToX) {\n element.addEventListener('wheel', handleWheel, {passive: false});\n }\n\n return () => {\n element.removeEventListener('mousedown', handleMouseDown);\n element.removeEventListener('mousemove', handleMouseMove);\n element.removeEventListener('mouseup', stopDragging);\n element.removeEventListener('mouseleave', stopDragging);\n element.removeEventListener('click', handleClickCapture, true);\n element.removeEventListener('wheel', handleWheel);\n };\n }, [enableDragScroll, enableWheelToX]);\n\n const isDragEnabled = enableDragScroll && edges.overflow;\n\n // máscara y no degradado encima: funciona sin saber de qué color es el fondo\n const fadeMask = fadeEdges && edges.overflow\n ? `linear-gradient(to right, ${[\n edges.start ? 'transparent 0, black 24px' : 'black 0',\n edges.end ? 'black calc(100% - 24px), transparent 100%' : 'black 100%',\n ].join(', ')})`\n : undefined;\n\n return (\n <RowRoot ref={assignRef}\n ownSx={{\n ...scrollableRow,\n gap,\n py,\n cursor: isDragEnabled ? 'grab' : 'auto',\n userSelect: isDragEnabled ? 'none' : 'auto',\n ...(fadeMask && {maskImage: fadeMask, WebkitMaskImage: fadeMask}),\n }}\n sx={sx}\n {...boxProps}>\n {children}\n </RowRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst ScrollableRow = withPieceSlots(ScrollableRowContent, THEME_NAME);\nexport default ScrollableRow;\n"],"names":[],"mappings":"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"}
|
|
@@ -3,13 +3,13 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import Box from "@mui/material/Box";
|
|
4
4
|
import Paper from "@mui/material/Paper";
|
|
5
5
|
import Typography from "@mui/material/Typography";
|
|
6
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
6
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
7
7
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
8
8
|
const THEME_NAME = "CalcitaSectionCard";
|
|
9
9
|
const SectionRoot = piecePart(THEME_NAME, "Root", Paper);
|
|
10
10
|
const SectionHeader = piecePart(THEME_NAME, "Header", Box);
|
|
11
11
|
const SectionTitle = piecePart(THEME_NAME, "Title", Typography);
|
|
12
|
-
function
|
|
12
|
+
function SectionCardContent(props) {
|
|
13
13
|
const { title, action, children, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
14
14
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
15
15
|
return /* @__PURE__ */ jsxs(SectionRoot, { component: "section", variant: "outlined", ownSx: { p: { xs: 2, md: 2.5 }, minWidth: 0 }, children: [
|
|
@@ -20,6 +20,7 @@ function SectionCard(props) {
|
|
|
20
20
|
children
|
|
21
21
|
] });
|
|
22
22
|
}
|
|
23
|
+
const SectionCard = withPieceSlots(SectionCardContent, THEME_NAME);
|
|
23
24
|
export {
|
|
24
25
|
SectionCard as default
|
|
25
26
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionCard.js","sources":["../../../src/ui/layout/SectionCard.jsx"],"sourcesContent":["// Tarjeta de una sección de una página de detalle: título en versalitas, una acción opcional a la derecha y el contenido.\n//\n// Por qué una tarjeta por sección y no una sola hoja larga con divisiones: en pantalla ancha las secciones se acomodan en\n// columnas (lo principal a la izquierda, los datos de apoyo a la derecha) y cada una se encuentra por su título.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSectionCard con defaultProps y\n// styleOverrides de sus partes: root, header, title.\n//\n// Genérico del paquete: function (regla de la casa). No sabe de negocio: el título y el contenido llegan ya traducidos.\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaSectionCard)\nconst THEME_NAME = 'CalcitaSectionCard';\nconst SectionRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst SectionHeader = piecePart(THEME_NAME, 'Header', Box);\nconst SectionTitle = piecePart(THEME_NAME, 'Title', Typography);\n\n/**\n * @param {object} props\n * @param {string} props.title texto ya traducido\n * @param {import('react').ReactNode} [props.action] botón o liga a la derecha del título\n * @param {import('react').ReactNode} props.children\n */\
|
|
1
|
+
{"version":3,"file":"SectionCard.js","sources":["../../../src/ui/layout/SectionCard.jsx"],"sourcesContent":["// Tarjeta de una sección de una página de detalle: título en versalitas, una acción opcional a la derecha y el contenido.\n//\n// Por qué una tarjeta por sección y no una sola hoja larga con divisiones: en pantalla ancha las secciones se acomodan en\n// columnas (lo principal a la izquierda, los datos de apoyo a la derecha) y cada una se encuentra por su título.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSectionCard con defaultProps y\n// styleOverrides de sus partes: root, header, title.\n//\n// Genérico del paquete: function (regla de la casa). No sabe de negocio: el título y el contenido llegan ya traducidos.\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\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.CalcitaSectionCard)\nconst THEME_NAME = 'CalcitaSectionCard';\nconst SectionRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst SectionHeader = piecePart(THEME_NAME, 'Header', Box);\nconst SectionTitle = piecePart(THEME_NAME, 'Title', Typography);\n\n/**\n * @param {object} props\n * @param {string} props.title texto ya traducido\n * @param {import('react').ReactNode} [props.action] botón o liga a la derecha del título\n * @param {import('react').ReactNode} props.children\n */\nfunction SectionCardContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaSectionCard.defaultProps) y encima lo que llega aquí\n const {title, action, children, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n return (\n <SectionRoot component=\"section\" variant=\"outlined\" ownSx={{p: {xs: 2, md: 2.5}, minWidth: 0}}>\n <SectionHeader ownSx={{display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 1, mb: 1.5}}>\n <SectionTitle variant=\"overline\" color=\"text.secondary\" component=\"h2\" ownSx={{lineHeight: 1.6}}>{title}</SectionTitle>\n {action}\n </SectionHeader>\n {children}\n </SectionRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst SectionCard = withPieceSlots(SectionCardContent, THEME_NAME);\nexport default SectionCard;\n"],"names":[],"mappings":";;;;;;;AAgBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,QAAQ,KAAK;AACvD,MAAM,gBAAgB,UAAU,YAAY,UAAU,GAAG;AACzD,MAAM,eAAe,UAAU,YAAY,SAAS,UAAU;AAQ9D,SAAS,mBAAmB,OAAO;AAE/B,QAAM,EAAC,OAAO,QAAQ,UAAU,GAAG,iBAAgB,cAAc,OAAO,UAAU;AAClF,mBAAiB,YAAY,YAAY;AACzC,8BACK,aAAA,EAAY,WAAU,WAAU,SAAQ,YAAW,OAAO,EAAC,GAAG,EAAC,IAAI,GAAG,IAAI,OAAM,UAAU,KACvF,UAAA;AAAA,IAAA,qBAAC,eAAA,EAAc,OAAO,EAAC,SAAS,QAAQ,YAAY,UAAU,gBAAgB,iBAAiB,KAAK,GAAG,IAAI,OACvG,UAAA;AAAA,MAAA,oBAAC,cAAA,EAAa,SAAQ,YAAW,OAAM,kBAAiB,WAAU,MAAK,OAAO,EAAC,YAAY,IAAA,GAAO,UAAA,OAAM;AAAA,MACvG;AAAA,IAAA,GACL;AAAA,IACC;AAAA,EAAA,GACL;AAER;AAGA,MAAM,cAAc,eAAe,oBAAoB,UAAU;"}
|
|
@@ -13,7 +13,7 @@ import ChartTooltip from "./ChartTooltip.js";
|
|
|
13
13
|
import TableToggle, { CHART_VIEW } from "./TableToggle.js";
|
|
14
14
|
import { BAR_MIN_POINT_SIZE, barLabelValueOf } from "./barListLabels.js";
|
|
15
15
|
import { useChartColors } from "./chartParts.js";
|
|
16
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
16
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
17
17
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
18
18
|
const THEME_NAME = "CalcitaBarList";
|
|
19
19
|
const BarListRow = piecePart(THEME_NAME, "Row", TableRow);
|
|
@@ -25,7 +25,7 @@ function ValueLabel({ x, y, width, height, value, colors, formatNumber }) {
|
|
|
25
25
|
value.detail && /* @__PURE__ */ jsx("tspan", { fill: colors.muted, fontSize: 12, children: ` ${value.detail}` })
|
|
26
26
|
] });
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function BarListContent(props) {
|
|
29
29
|
const { items, onSelect, emptyLabel, tone = "primary", texts, defaultView = CHART_VIEW.chart, onViewChange, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
30
30
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
31
31
|
const [asTable, setAsTable] = useState(defaultView === CHART_VIEW.table);
|
|
@@ -95,6 +95,7 @@ function BarList(props) {
|
|
|
95
95
|
] }) }) })
|
|
96
96
|
] });
|
|
97
97
|
}
|
|
98
|
+
const BarList = withPieceSlots(BarListContent, THEME_NAME);
|
|
98
99
|
export {
|
|
99
100
|
BarList as default
|
|
100
101
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BarList.js","sources":["../../../src/ui/metrics/BarList.jsx"],"sourcesContent":["// Barras horizontales de UNA serie con su nombre a la izquierda y su valor en la punta (ventas por producto,\n// cuentas por organización), dibujadas con Recharts.\n//\n// Horizontales porque los nombres son largos (\"Empresa / Área de ventas\"): se leen completos sin rotarlos. Una serie → un\n// color (el del tono, vía currentColor: los atributos SVG no leen var(...) pero sí currentColor); el valor va en tinta,\n// nunca del color de la barra; y cada barra puede llevar a la pantalla que la explica.\n//\n// OJO: el número y el detalle de la punta salen del renglón de la barra (barListLabels.js), nunca de items[index]: Recharts\n// descarta las barras de ancho 0 y renumera las etiquetas, y el detalle se corría al renglón de arriba.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarList con defaultProps y\n// styleOverrides de sus partes: row, chart.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableRow from '@mui/material/TableRow';\nimport Typography from '@mui/material/Typography';\nimport {Bar, BarChart, LabelList, ResponsiveContainer, Tooltip, XAxis, YAxis} from 'recharts';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport ChartTooltip from '@/ui/metrics/ChartTooltip.jsx';\nimport TableToggle, {CHART_VIEW} from '@/ui/metrics/TableToggle.jsx';\nimport {BAR_MIN_POINT_SIZE, barLabelValueOf} from '@/ui/metrics/barListLabels.js';\nimport {useChartColors} from '@/ui/metrics/chartParts.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.CalcitaBarList)\nconst THEME_NAME = 'CalcitaBarList';\nconst BarListRow = piecePart(THEME_NAME, 'Row', TableRow);\nconst BarListChart = piecePart(THEME_NAME, 'Chart', Box);\n\nconst ROW_HEIGHT_PIXELS = 36;\n\n/**\n * El valor en la punta: el número fuerte y el detalle (\"de 8\") tenue; value es {value, detail} de barLabelValueOf. colors y\n * formatNumber: los de useChartColors y useFormatters (los da BarList: este pedazo lo pinta recharts por su cuenta).\n */\nfunction ValueLabel({x, y, width, height, value, colors, formatNumber}) {\n return (\n <text x={x + width + 8} y={y + height / 2} dominantBaseline=\"central\" fontSize={13}>\n <tspan fill={colors.text} fontWeight={600}>{formatNumber(value.value)}</tspan>\n {value.detail && <tspan fill={colors.muted} fontSize={12}>{` ${value.detail}`}</tspan>}\n </text>\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{key: string, label: string, value: number, detail?: string, tooltip?: string}>} props.items\n * @param {(item: any) => void} [props.onSelect] recibe el renglón de items que se picó\n * @param {string} props.emptyLabel ya traducido\n * @param {'primary'|'success'|'warning'|'error'|'info'} [props.tone]\n * @param {'chart'|'table'} [props.defaultView] cómo se ve al abrir (CHART_VIEW); por omisión dibujada\n * @param {(view: 'chart'|'table') => void} [props.onViewChange] la persona cambió a la tabla o a la gráfica\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function BarList(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarList.defaultProps) y encima lo que llega aquí\n const {items, onSelect, emptyLabel, tone = 'primary', texts, defaultView = CHART_VIEW.chart, onViewChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const [asTable, setAsTable] = useState(defaultView === CHART_VIEW.table);\n const toggleView = () => {\n setAsTable(!asTable);\n onViewChange?.(asTable ? CHART_VIEW.chart : CHART_VIEW.table);\n };\n const colors = useChartColors();\n const {formatNumber} = useFormatters();\n\n // guard clause: sin datos se dice, no se pinta un eje vacío\n if (!items.length) {\n return <Typography variant=\"body2\" color=\"text.secondary\">{emptyLabel}</Typography>;\n }\n\n // lo más largo de la etiqueta decide el ancho del eje: sin esto el nombre se corta o sobra medio contenedor\n // OJO: String(... ?? '') porque un renglón sin nombre (catálogo dado de baja) tumbaba toda la gráfica\n // OJO: 220 px de tope. Con 160 se cortaban etiquetas largas («Cuenta pendiente de activar») sin puntos suspensivos\n // ni forma de leerlas; el tooltip de la barra sigue mostrando el texto completo\n const labelWidth = Math.min(220, 16 + Math.max(...items.map((item) => String(item.label ?? '').length)) * 7);\n const longestValue = Math.max(...items.map((item) => `${formatNumber(item.value)} ${item.detail ?? ''}`.length));\n\n return (\n <Box>\n <TableToggle asTable={asTable} onToggle={toggleView} texts={texts} />\n {asTable ? (\n <Table size=\"small\">\n <TableBody>\n {items.map((item) => (\n <BarListRow key={item.key} hover={Boolean(onSelect)} onClick={onSelect ? () => onSelect(item) : undefined}\n ownSx={{cursor: onSelect ? 'pointer' : 'default'}}>\n <TableCell>{item.label}</TableCell>\n <TableCell align=\"right\">{formatNumber(item.value)} {item.detail}</TableCell>\n </BarListRow>\n ))}\n </TableBody>\n </Table>\n ) : (\n <BarListChart ownSx={{height: items.length * ROW_HEIGHT_PIXELS, color: `${tone}.main`}}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={items} layout=\"vertical\" margin={{top: 0, bottom: 0, left: 0, right: 16 + longestValue * 7}}>\n {/* OJO: con todo en 0 el dominio [0, 0] manda el 0 a la MITAD del eje (escala degenerada de d3) y la\n barra de 1 px con su «0 de 2» saldría a medio renglón; el tope mínimo de 1 lo deja en el origen */}\n <XAxis type=\"number\" hide domain={[0, (dataMax) => Math.max(dataMax, 1)]} />\n <YAxis type=\"category\" dataKey=\"label\" width={labelWidth} tickLine={false} axisLine={false}\n tick={{fill: colors.text, fontSize: 13}} />\n <Tooltip cursor={{fill: colors.hover}}\n content={<ChartTooltip render={(item) => item.tooltip ?? `${item.label}: ${formatNumber(item.value)}`} />} />\n <Bar dataKey=\"value\" fill=\"currentColor\" maxBarSize={16} radius={[0, 4, 4, 0]} isAnimationActive={false}\n minPointSize={BAR_MIN_POINT_SIZE} cursor={onSelect ? 'pointer' : 'default'}\n onClick={onSelect ? (entry) => onSelect(entry.payload) : undefined}>\n {/* OJO: SIN dataKey; con dataKey LabelList ignora valueAccessor y regresa el índice corrido */}\n <LabelList valueAccessor={barLabelValueOf} content={(labelProps) => <ValueLabel {...labelProps} colors={colors} formatNumber={formatNumber} />} />\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </BarListChart>\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BarList.js","sources":["../../../src/ui/metrics/BarList.jsx"],"sourcesContent":["// Barras horizontales de UNA serie con su nombre a la izquierda y su valor en la punta (ventas por producto,\n// cuentas por organización), dibujadas con Recharts.\n//\n// Horizontales porque los nombres son largos (\"Empresa / Área de ventas\"): se leen completos sin rotarlos. Una serie → un\n// color (el del tono, vía currentColor: los atributos SVG no leen var(...) pero sí currentColor); el valor va en tinta,\n// nunca del color de la barra; y cada barra puede llevar a la pantalla que la explica.\n//\n// OJO: el número y el detalle de la punta salen del renglón de la barra (barListLabels.js), nunca de items[index]: Recharts\n// descarta las barras de ancho 0 y renumera las etiquetas, y el detalle se corría al renglón de arriba.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaBarList con defaultProps y\n// styleOverrides de sus partes: row, chart.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableRow from '@mui/material/TableRow';\nimport Typography from '@mui/material/Typography';\nimport {Bar, BarChart, LabelList, ResponsiveContainer, Tooltip, XAxis, YAxis} from 'recharts';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport ChartTooltip from '@/ui/metrics/ChartTooltip.jsx';\nimport TableToggle, {CHART_VIEW} from '@/ui/metrics/TableToggle.jsx';\nimport {BAR_MIN_POINT_SIZE, barLabelValueOf} from '@/ui/metrics/barListLabels.js';\nimport {useChartColors} from '@/ui/metrics/chartParts.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.CalcitaBarList)\nconst THEME_NAME = 'CalcitaBarList';\nconst BarListRow = piecePart(THEME_NAME, 'Row', TableRow);\nconst BarListChart = piecePart(THEME_NAME, 'Chart', Box);\n\nconst ROW_HEIGHT_PIXELS = 36;\n\n/**\n * El valor en la punta: el número fuerte y el detalle (\"de 8\") tenue; value es {value, detail} de barLabelValueOf. colors y\n * formatNumber: los de useChartColors y useFormatters (los da BarList: este pedazo lo pinta recharts por su cuenta).\n */\nfunction ValueLabel({x, y, width, height, value, colors, formatNumber}) {\n return (\n <text x={x + width + 8} y={y + height / 2} dominantBaseline=\"central\" fontSize={13}>\n <tspan fill={colors.text} fontWeight={600}>{formatNumber(value.value)}</tspan>\n {value.detail && <tspan fill={colors.muted} fontSize={12}>{` ${value.detail}`}</tspan>}\n </text>\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{key: string, label: string, value: number, detail?: string, tooltip?: string}>} props.items\n * @param {(item: any) => void} [props.onSelect] recibe el renglón de items que se picó\n * @param {string} props.emptyLabel ya traducido\n * @param {'primary'|'success'|'warning'|'error'|'info'} [props.tone]\n * @param {'chart'|'table'} [props.defaultView] cómo se ve al abrir (CHART_VIEW); por omisión dibujada\n * @param {(view: 'chart'|'table') => void} [props.onViewChange] la persona cambió a la tabla o a la gráfica\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction BarListContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaBarList.defaultProps) y encima lo que llega aquí\n const {items, onSelect, emptyLabel, tone = 'primary', texts, defaultView = CHART_VIEW.chart, onViewChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const [asTable, setAsTable] = useState(defaultView === CHART_VIEW.table);\n const toggleView = () => {\n setAsTable(!asTable);\n onViewChange?.(asTable ? CHART_VIEW.chart : CHART_VIEW.table);\n };\n const colors = useChartColors();\n const {formatNumber} = useFormatters();\n\n // guard clause: sin datos se dice, no se pinta un eje vacío\n if (!items.length) {\n return <Typography variant=\"body2\" color=\"text.secondary\">{emptyLabel}</Typography>;\n }\n\n // lo más largo de la etiqueta decide el ancho del eje: sin esto el nombre se corta o sobra medio contenedor\n // OJO: String(... ?? '') porque un renglón sin nombre (catálogo dado de baja) tumbaba toda la gráfica\n // OJO: 220 px de tope. Con 160 se cortaban etiquetas largas («Cuenta pendiente de activar») sin puntos suspensivos\n // ni forma de leerlas; el tooltip de la barra sigue mostrando el texto completo\n const labelWidth = Math.min(220, 16 + Math.max(...items.map((item) => String(item.label ?? '').length)) * 7);\n const longestValue = Math.max(...items.map((item) => `${formatNumber(item.value)} ${item.detail ?? ''}`.length));\n\n return (\n <Box>\n <TableToggle asTable={asTable} onToggle={toggleView} texts={texts} />\n {asTable ? (\n <Table size=\"small\">\n <TableBody>\n {items.map((item) => (\n <BarListRow key={item.key} hover={Boolean(onSelect)} onClick={onSelect ? () => onSelect(item) : undefined}\n ownSx={{cursor: onSelect ? 'pointer' : 'default'}}>\n <TableCell>{item.label}</TableCell>\n <TableCell align=\"right\">{formatNumber(item.value)} {item.detail}</TableCell>\n </BarListRow>\n ))}\n </TableBody>\n </Table>\n ) : (\n <BarListChart ownSx={{height: items.length * ROW_HEIGHT_PIXELS, color: `${tone}.main`}}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={items} layout=\"vertical\" margin={{top: 0, bottom: 0, left: 0, right: 16 + longestValue * 7}}>\n {/* OJO: con todo en 0 el dominio [0, 0] manda el 0 a la MITAD del eje (escala degenerada de d3) y la\n barra de 1 px con su «0 de 2» saldría a medio renglón; el tope mínimo de 1 lo deja en el origen */}\n <XAxis type=\"number\" hide domain={[0, (dataMax) => Math.max(dataMax, 1)]} />\n <YAxis type=\"category\" dataKey=\"label\" width={labelWidth} tickLine={false} axisLine={false}\n tick={{fill: colors.text, fontSize: 13}} />\n <Tooltip cursor={{fill: colors.hover}}\n content={<ChartTooltip render={(item) => item.tooltip ?? `${item.label}: ${formatNumber(item.value)}`} />} />\n <Bar dataKey=\"value\" fill=\"currentColor\" maxBarSize={16} radius={[0, 4, 4, 0]} isAnimationActive={false}\n minPointSize={BAR_MIN_POINT_SIZE} cursor={onSelect ? 'pointer' : 'default'}\n onClick={onSelect ? (entry) => onSelect(entry.payload) : undefined}>\n {/* OJO: SIN dataKey; con dataKey LabelList ignora valueAccessor y regresa el índice corrido */}\n <LabelList valueAccessor={barLabelValueOf} content={(labelProps) => <ValueLabel {...labelProps} colors={colors} formatNumber={formatNumber} />} />\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </BarListChart>\n )}\n </Box>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst BarList = withPieceSlots(BarListContent, THEME_NAME);\nexport default BarList;\n"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ import { useToolkitSettings } from "../../toolkit/toolkitContext.js";
|
|
|
15
15
|
import { useFormatters } from "../../toolkit/useFormatters.js";
|
|
16
16
|
import { calendarWeeksOf, calendarRangeOf, todayInZone, levelOf, HEATMAP_LEVELS } from "./heatmapScale.js";
|
|
17
17
|
import TableToggle, { CHART_VIEW } from "./TableToggle.js";
|
|
18
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
18
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
19
19
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
20
20
|
const THEME_NAME = "CalcitaCalendarHeatmap";
|
|
21
21
|
const HeatmapHeader = piecePart(THEME_NAME, "Header", Stack);
|
|
@@ -46,7 +46,7 @@ function levelFill(theme, tone, level) {
|
|
|
46
46
|
}
|
|
47
47
|
return `color-mix(in srgb, ${palette[tone].main} ${LEVEL_TONE_PERCENT[level]}%, transparent)`;
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function CalendarHeatmapContent(props) {
|
|
50
50
|
const { startsOn, endsOn, days = NO_DAYS, ariaLabel, valueLabel, describeValue, summary, emptyLabel, tone = "primary", texts, defaultView = CHART_VIEW.chart, onViewChange, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
51
51
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
52
52
|
const { t } = useToolkitTranslation("common", texts);
|
|
@@ -158,6 +158,7 @@ function CalendarHeatmap(props) {
|
|
|
158
158
|
] })
|
|
159
159
|
] });
|
|
160
160
|
}
|
|
161
|
+
const CalendarHeatmap = withPieceSlots(CalendarHeatmapContent, THEME_NAME);
|
|
161
162
|
export {
|
|
162
163
|
CalendarHeatmap as default
|
|
163
164
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarHeatmap.js","sources":["../../../src/ui/metrics/CalendarHeatmap.jsx"],"sourcesContent":["// Calendario de actividad: un cuadro por día, semanas en columnas (el de GitHub).\n//\n// Sirve para ver RITMO de un vistazo: qué días llegan cargas, si hubo semanas muertas, si la actividad crece. Las\n// reglas de visualización:\n// - es MAGNITUD, así que va un solo tono de claro a oscuro (el del tono que se pida), en cuatro niveles más \"sin\n// actividad\". Nunca un arcoíris. Se arma con color-mix sobre el color del tema (su variable CSS si el tema las usa),\n// sin hexadecimales: en modo oscuro los mismos niveles se ven sobre su propia superficie;\n// - los niveles se cortan por CUARTILES de los días con actividad (heatmapScale.js), no por valores fijos;\n// - leyenda \"Menos → Más\", tooltip por día con el número exacto (el color solo nunca dice cuánto) y VISTA DE TABLA\n// (para lector de pantalla, para quien no distingue el tono y para copiar los números).\n//\n// Sin librería a propósito: el Heatmap de MUI X Charts es de la edición Pro, que pide licencia.\n//\n// Textos por props y del paquete, y fechas con los formatos del paquete.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCalendarHeatmap con defaultProps y\n// styleOverrides de sus partes: header, toggle, tableArea, dateCell, valueCell, descriptionCell, gridArea, grid,\n// monthLabel, week, dayLabel, cell, legend, legendLess, legendCell, legendMore.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useMemo, useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Stack from '@mui/material/Stack';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\n\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {HEATMAP_LEVELS, calendarRangeOf, calendarWeeksOf, levelOf, todayInZone} from '@/ui/metrics/heatmapScale.js';\nimport TableToggle, {CHART_VIEW} from '@/ui/metrics/TableToggle.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.CalcitaCalendarHeatmap)\nconst THEME_NAME = 'CalcitaCalendarHeatmap';\nconst HeatmapHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst HeatmapToggle = piecePart(THEME_NAME, 'Toggle', Box);\nconst HeatmapTableArea = piecePart(THEME_NAME, 'TableArea', Box);\nconst HeatmapDateCell = piecePart(THEME_NAME, 'DateCell', TableCell);\nconst HeatmapValueCell = piecePart(THEME_NAME, 'ValueCell', TableCell);\nconst HeatmapDescriptionCell = piecePart(THEME_NAME, 'DescriptionCell', TableCell);\nconst HeatmapGridArea = piecePart(THEME_NAME, 'GridArea', Box);\nconst HeatmapGrid = piecePart(THEME_NAME, 'Grid', Box);\nconst HeatmapMonthLabel = piecePart(THEME_NAME, 'MonthLabel', Typography);\nconst HeatmapWeek = piecePart(THEME_NAME, 'Week', Box);\nconst HeatmapDayLabel = piecePart(THEME_NAME, 'DayLabel', Typography);\nconst HeatmapCell = piecePart(THEME_NAME, 'Cell', Box);\nconst HeatmapLegend = piecePart(THEME_NAME, 'Legend', Stack);\nconst HeatmapLegendLess = piecePart(THEME_NAME, 'LegendLess', Typography);\nconst HeatmapLegendCell = piecePart(THEME_NAME, 'LegendCell', Box);\nconst HeatmapLegendMore = piecePart(THEME_NAME, 'LegendMore', Typography);\n\n// cuadros de 12 px en teléfono (el calendario se desliza) y de 16 px desde md, donde el panel ocupa todo el ancho\nconst CELL_PIXELS = {xs: 12, md: 16};\nconst GAP_PIXELS = 3;\n// solo lunes, miércoles y viernes llevan rótulo: los siete encimados no se leen a 12 px\nconst LABELED_WEEKDAYS = new Set([1, 3, 5]);\n// porcentaje del tono en cada nivel; el nivel 0 es el gris de \"hover\" del tema\nconst LEVEL_TONE_PERCENT = {1: 30, 2: 55, 3: 78, 4: 100};\n// sin días: el calendario vacío (una lista fija para que no se vuelvan a contar las semanas en cada render)\nconst NO_DAYS = Object.freeze([]);\n\n/**\n * Relleno de un nivel con los colores del tema.\n *\n * @param {object} theme tema de MUI (con o sin variables CSS)\n * @param {string} tone primary, info, success...\n * @param {number} level 0 a 4\n * @returns {string} color CSS\n */\nfunction levelFill(theme, tone, level) {\n // un tema con variables CSS las trae en theme.vars; el tema por omisión de MUI, solo en theme.palette\n const {palette} = theme.vars ?? theme;\n if (level === 0) {\n return palette.action.hover;\n }\n return `color-mix(in srgb, ${palette[tone].main} ${LEVEL_TONE_PERCENT[level]}%, transparent)`;\n}\n\n/**\n * @param {object} props\n * @param {string} [props.startsOn] primer día del rango (\"2025-09-16\"), fecha de calendario; sin él, un año antes de endsOn\n * @param {string} [props.endsOn] último día del rango (\"2026-09-15\"); sin él, hoy en la zona del proveedor\n * @param {Array<{date: string, value: number, detail?: string}>} [props.days] solo los días con actividad; el resto vale\n * 0\n * @param {string} props.ariaLabel qué muestra el calendario, ya traducido\n * @param {string} props.valueLabel encabezado de la columna de valor en la tabla (\"Registros leídos\")\n * @param {(value: number) => string} [props.describeValue] el valor en palabras para el tooltip (\"120 registros leídos\");\n * sin ella, solo el número\n * @param {import('react').ReactNode} [props.summary] renglón de resumen arriba del calendario\n * @param {string} [props.emptyLabel] qué decir si ningún día tiene actividad\n * @param {'primary'|'info'|'success'|'warning'|'error'} [props.tone]\n * @param {'chart'|'table'} [props.defaultView] cómo se ve al abrir (CHART_VIEW); por omisión dibujada\n * @param {(view: 'chart'|'table') => void} [props.onViewChange] la persona cambió a la tabla o a la gráfica\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function CalendarHeatmap(props) {\n // lo que el proyecto puso en su tema (components.CalcitaCalendarHeatmap.defaultProps) y encima lo que llega aquí\n const {startsOn, endsOn, days = NO_DAYS, ariaLabel, valueLabel, describeValue, summary, emptyLabel, tone = 'primary', texts, defaultView = CHART_VIEW.chart, onViewChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {formatDate, formatMonthShortName, formatNumber, formatWeekdayShortName} = useFormatters();\n const [asTable, setAsTable] = useState(defaultView === CHART_VIEW.table);\n const toggleView = () => {\n setAsTable(!asTable);\n onViewChange?.(asTable ? CHART_VIEW.chart : CHART_VIEW.table);\n };\n\n const {timeZone} = useToolkitSettings();\n const {weeks, monthMarks, thresholds} = useMemo(\n () => calendarWeeksOf({...calendarRangeOf({startsOn, endsOn, today: todayInZone(timeZone)}), days}),\n [startsOn, endsOn, days, timeZone]);\n // el valor en palabras del globo de cada día; sin la del proyecto, el número solo\n const describe = describeValue ?? formatNumber;\n const activeDays = days.filter((day) => day.value > 0);\n\n return (\n <Box>\n <HeatmapHeader direction=\"row\" spacing={2} ownSx={{justifyContent: 'space-between', alignItems: 'center', mb: 1}}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {activeDays.length ? summary : emptyLabel}\n </Typography>\n <HeatmapToggle ownSx={{flexShrink: 0}}>\n <TableToggle asTable={asTable} onToggle={toggleView} texts={texts} />\n </HeatmapToggle>\n </HeatmapHeader>\n\n {asTable ? (\n <HeatmapTableArea ownSx={{maxHeight: 260, overflowY: 'auto'}}>\n <Table size=\"small\" aria-label={ariaLabel}>\n <TableHead>\n <TableRow>\n <TableCell>{t('charts.day')}</TableCell>\n <TableCell align=\"right\">{valueLabel}</TableCell>\n <TableCell />\n </TableRow>\n </TableHead>\n <TableBody>\n {[...activeDays].reverse().map((day) => (\n <TableRow key={day.date}>\n <HeatmapDateCell ownSx={{whiteSpace: 'nowrap'}}>{formatDate(day.date)}</HeatmapDateCell>\n <HeatmapValueCell align=\"right\" ownSx={{fontVariantNumeric: 'tabular-nums'}}>{formatNumber(day.value)}</HeatmapValueCell>\n <HeatmapDescriptionCell ownSx={{color: 'text.secondary'}}>{day.detail}</HeatmapDescriptionCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </HeatmapTableArea>\n ) : (\n // el calendario no se encoge: en pantallas angostas se desliza y arranca mostrando lo más reciente\n <HeatmapGridArea ownSx={{overflowX: 'auto', pb: 0.5}}\n ref={(node) => {\n if (node) {\n node.scrollLeft = node.scrollWidth;\n }\n }}>\n <HeatmapGrid role=\"img\" aria-label={ariaLabel}\n ownSx={{\n display: 'inline-grid',\n gridTemplateColumns: {\n xs: `auto repeat(${weeks.length}, ${CELL_PIXELS.xs}px)`,\n md: `auto repeat(${weeks.length}, ${CELL_PIXELS.md}px)`,\n },\n columnGap: `${GAP_PIXELS}px`,\n rowGap: `${GAP_PIXELS}px`,\n alignItems: 'center',\n }}>\n <Box />\n {monthMarks.map((month, column) => (\n <HeatmapMonthLabel key={`month-${column}`} variant=\"caption\" color=\"text.secondary\"\n ownSx={{fontSize: 10, lineHeight: 1, whiteSpace: 'nowrap', overflow: 'visible', width: CELL_PIXELS}}>\n {month ? formatMonthShortName(month) : ''}\n </HeatmapMonthLabel>\n ))}\n {[1, 2, 3, 4, 5, 6, 7].map((isoWeekday) => (\n <HeatmapWeek key={`weekday-${isoWeekday}`} ownSx={{display: 'contents'}}>\n <HeatmapDayLabel variant=\"caption\" color=\"text.secondary\"\n ownSx={{fontSize: 10, lineHeight: {xs: `${CELL_PIXELS.xs}px`, md: `${CELL_PIXELS.md}px`}, pr: 0.75}}>\n {LABELED_WEEKDAYS.has(isoWeekday) ? formatWeekdayShortName(isoWeekday) : ''}\n </HeatmapDayLabel>\n {weeks.map((week, column) => {\n const day = week[isoWeekday - 1];\n if (!day) {\n return <Box key={`outside-${column}-${isoWeekday}`} />;\n }\n const level = levelOf(day.value, thresholds);\n return (\n <Tooltip key={day.date} arrow disableInteractive\n title={`${formatDate(day.date)}: ${describe(day.value)}${day.detail ? ` · ${day.detail}` : ''}`}>\n <HeatmapCell ownSx={(theme) => ({width: CELL_PIXELS, height: CELL_PIXELS, borderRadius: '3px', bgcolor: levelFill(theme, tone, level)})} />\n </Tooltip>\n );\n })}\n </HeatmapWeek>\n ))}\n </HeatmapGrid>\n </HeatmapGridArea>\n )}\n\n {!asTable && (\n <HeatmapLegend direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center', justifyContent: 'flex-end', mt: 1}} aria-hidden=\"true\">\n <HeatmapLegendLess variant=\"caption\" color=\"text.secondary\" ownSx={{mr: 0.5}}>{t('charts.less')}</HeatmapLegendLess>\n {HEATMAP_LEVELS.map((level) => (\n <HeatmapLegendCell key={level} ownSx={(theme) => ({width: CELL_PIXELS, height: CELL_PIXELS, borderRadius: '3px', bgcolor: levelFill(theme, tone, level)})} />\n ))}\n <HeatmapLegendMore variant=\"caption\" color=\"text.secondary\" ownSx={{ml: 0.5}}>{t('charts.more')}</HeatmapLegendMore>\n </HeatmapLegend>\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CalendarHeatmap.js","sources":["../../../src/ui/metrics/CalendarHeatmap.jsx"],"sourcesContent":["// Calendario de actividad: un cuadro por día, semanas en columnas (el de GitHub).\n//\n// Sirve para ver RITMO de un vistazo: qué días llegan cargas, si hubo semanas muertas, si la actividad crece. Las\n// reglas de visualización:\n// - es MAGNITUD, así que va un solo tono de claro a oscuro (el del tono que se pida), en cuatro niveles más \"sin\n// actividad\". Nunca un arcoíris. Se arma con color-mix sobre el color del tema (su variable CSS si el tema las usa),\n// sin hexadecimales: en modo oscuro los mismos niveles se ven sobre su propia superficie;\n// - los niveles se cortan por CUARTILES de los días con actividad (heatmapScale.js), no por valores fijos;\n// - leyenda \"Menos → Más\", tooltip por día con el número exacto (el color solo nunca dice cuánto) y VISTA DE TABLA\n// (para lector de pantalla, para quien no distingue el tono y para copiar los números).\n//\n// Sin librería a propósito: el Heatmap de MUI X Charts es de la edición Pro, que pide licencia.\n//\n// Textos por props y del paquete, y fechas con los formatos del paquete.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCalendarHeatmap con defaultProps y\n// styleOverrides de sus partes: header, toggle, tableArea, dateCell, valueCell, descriptionCell, gridArea, grid,\n// monthLabel, week, dayLabel, cell, legend, legendLess, legendCell, legendMore.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useMemo, useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Stack from '@mui/material/Stack';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\n\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {HEATMAP_LEVELS, calendarRangeOf, calendarWeeksOf, levelOf, todayInZone} from '@/ui/metrics/heatmapScale.js';\nimport TableToggle, {CHART_VIEW} from '@/ui/metrics/TableToggle.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.CalcitaCalendarHeatmap)\nconst THEME_NAME = 'CalcitaCalendarHeatmap';\nconst HeatmapHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst HeatmapToggle = piecePart(THEME_NAME, 'Toggle', Box);\nconst HeatmapTableArea = piecePart(THEME_NAME, 'TableArea', Box);\nconst HeatmapDateCell = piecePart(THEME_NAME, 'DateCell', TableCell);\nconst HeatmapValueCell = piecePart(THEME_NAME, 'ValueCell', TableCell);\nconst HeatmapDescriptionCell = piecePart(THEME_NAME, 'DescriptionCell', TableCell);\nconst HeatmapGridArea = piecePart(THEME_NAME, 'GridArea', Box);\nconst HeatmapGrid = piecePart(THEME_NAME, 'Grid', Box);\nconst HeatmapMonthLabel = piecePart(THEME_NAME, 'MonthLabel', Typography);\nconst HeatmapWeek = piecePart(THEME_NAME, 'Week', Box);\nconst HeatmapDayLabel = piecePart(THEME_NAME, 'DayLabel', Typography);\nconst HeatmapCell = piecePart(THEME_NAME, 'Cell', Box);\nconst HeatmapLegend = piecePart(THEME_NAME, 'Legend', Stack);\nconst HeatmapLegendLess = piecePart(THEME_NAME, 'LegendLess', Typography);\nconst HeatmapLegendCell = piecePart(THEME_NAME, 'LegendCell', Box);\nconst HeatmapLegendMore = piecePart(THEME_NAME, 'LegendMore', Typography);\n\n// cuadros de 12 px en teléfono (el calendario se desliza) y de 16 px desde md, donde el panel ocupa todo el ancho\nconst CELL_PIXELS = {xs: 12, md: 16};\nconst GAP_PIXELS = 3;\n// solo lunes, miércoles y viernes llevan rótulo: los siete encimados no se leen a 12 px\nconst LABELED_WEEKDAYS = new Set([1, 3, 5]);\n// porcentaje del tono en cada nivel; el nivel 0 es el gris de \"hover\" del tema\nconst LEVEL_TONE_PERCENT = {1: 30, 2: 55, 3: 78, 4: 100};\n// sin días: el calendario vacío (una lista fija para que no se vuelvan a contar las semanas en cada render)\nconst NO_DAYS = Object.freeze([]);\n\n/**\n * Relleno de un nivel con los colores del tema.\n *\n * @param {object} theme tema de MUI (con o sin variables CSS)\n * @param {string} tone primary, info, success...\n * @param {number} level 0 a 4\n * @returns {string} color CSS\n */\nfunction levelFill(theme, tone, level) {\n // un tema con variables CSS las trae en theme.vars; el tema por omisión de MUI, solo en theme.palette\n const {palette} = theme.vars ?? theme;\n if (level === 0) {\n return palette.action.hover;\n }\n return `color-mix(in srgb, ${palette[tone].main} ${LEVEL_TONE_PERCENT[level]}%, transparent)`;\n}\n\n/**\n * @param {object} props\n * @param {string} [props.startsOn] primer día del rango (\"2025-09-16\"), fecha de calendario; sin él, un año antes de endsOn\n * @param {string} [props.endsOn] último día del rango (\"2026-09-15\"); sin él, hoy en la zona del proveedor\n * @param {Array<{date: string, value: number, detail?: string}>} [props.days] solo los días con actividad; el resto vale\n * 0\n * @param {string} props.ariaLabel qué muestra el calendario, ya traducido\n * @param {string} props.valueLabel encabezado de la columna de valor en la tabla (\"Registros leídos\")\n * @param {(value: number) => string} [props.describeValue] el valor en palabras para el tooltip (\"120 registros leídos\");\n * sin ella, solo el número\n * @param {import('react').ReactNode} [props.summary] renglón de resumen arriba del calendario\n * @param {string} [props.emptyLabel] qué decir si ningún día tiene actividad\n * @param {'primary'|'info'|'success'|'warning'|'error'} [props.tone]\n * @param {'chart'|'table'} [props.defaultView] cómo se ve al abrir (CHART_VIEW); por omisión dibujada\n * @param {(view: 'chart'|'table') => void} [props.onViewChange] la persona cambió a la tabla o a la gráfica\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction CalendarHeatmapContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaCalendarHeatmap.defaultProps) y encima lo que llega aquí\n const {startsOn, endsOn, days = NO_DAYS, ariaLabel, valueLabel, describeValue, summary, emptyLabel, tone = 'primary', texts, defaultView = CHART_VIEW.chart, onViewChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {formatDate, formatMonthShortName, formatNumber, formatWeekdayShortName} = useFormatters();\n const [asTable, setAsTable] = useState(defaultView === CHART_VIEW.table);\n const toggleView = () => {\n setAsTable(!asTable);\n onViewChange?.(asTable ? CHART_VIEW.chart : CHART_VIEW.table);\n };\n\n const {timeZone} = useToolkitSettings();\n const {weeks, monthMarks, thresholds} = useMemo(\n () => calendarWeeksOf({...calendarRangeOf({startsOn, endsOn, today: todayInZone(timeZone)}), days}),\n [startsOn, endsOn, days, timeZone]);\n // el valor en palabras del globo de cada día; sin la del proyecto, el número solo\n const describe = describeValue ?? formatNumber;\n const activeDays = days.filter((day) => day.value > 0);\n\n return (\n <Box>\n <HeatmapHeader direction=\"row\" spacing={2} ownSx={{justifyContent: 'space-between', alignItems: 'center', mb: 1}}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {activeDays.length ? summary : emptyLabel}\n </Typography>\n <HeatmapToggle ownSx={{flexShrink: 0}}>\n <TableToggle asTable={asTable} onToggle={toggleView} texts={texts} />\n </HeatmapToggle>\n </HeatmapHeader>\n\n {asTable ? (\n <HeatmapTableArea ownSx={{maxHeight: 260, overflowY: 'auto'}}>\n <Table size=\"small\" aria-label={ariaLabel}>\n <TableHead>\n <TableRow>\n <TableCell>{t('charts.day')}</TableCell>\n <TableCell align=\"right\">{valueLabel}</TableCell>\n <TableCell />\n </TableRow>\n </TableHead>\n <TableBody>\n {[...activeDays].reverse().map((day) => (\n <TableRow key={day.date}>\n <HeatmapDateCell ownSx={{whiteSpace: 'nowrap'}}>{formatDate(day.date)}</HeatmapDateCell>\n <HeatmapValueCell align=\"right\" ownSx={{fontVariantNumeric: 'tabular-nums'}}>{formatNumber(day.value)}</HeatmapValueCell>\n <HeatmapDescriptionCell ownSx={{color: 'text.secondary'}}>{day.detail}</HeatmapDescriptionCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </HeatmapTableArea>\n ) : (\n // el calendario no se encoge: en pantallas angostas se desliza y arranca mostrando lo más reciente\n <HeatmapGridArea ownSx={{overflowX: 'auto', pb: 0.5}}\n ref={(node) => {\n if (node) {\n node.scrollLeft = node.scrollWidth;\n }\n }}>\n <HeatmapGrid role=\"img\" aria-label={ariaLabel}\n ownSx={{\n display: 'inline-grid',\n gridTemplateColumns: {\n xs: `auto repeat(${weeks.length}, ${CELL_PIXELS.xs}px)`,\n md: `auto repeat(${weeks.length}, ${CELL_PIXELS.md}px)`,\n },\n columnGap: `${GAP_PIXELS}px`,\n rowGap: `${GAP_PIXELS}px`,\n alignItems: 'center',\n }}>\n <Box />\n {monthMarks.map((month, column) => (\n <HeatmapMonthLabel key={`month-${column}`} variant=\"caption\" color=\"text.secondary\"\n ownSx={{fontSize: 10, lineHeight: 1, whiteSpace: 'nowrap', overflow: 'visible', width: CELL_PIXELS}}>\n {month ? formatMonthShortName(month) : ''}\n </HeatmapMonthLabel>\n ))}\n {[1, 2, 3, 4, 5, 6, 7].map((isoWeekday) => (\n <HeatmapWeek key={`weekday-${isoWeekday}`} ownSx={{display: 'contents'}}>\n <HeatmapDayLabel variant=\"caption\" color=\"text.secondary\"\n ownSx={{fontSize: 10, lineHeight: {xs: `${CELL_PIXELS.xs}px`, md: `${CELL_PIXELS.md}px`}, pr: 0.75}}>\n {LABELED_WEEKDAYS.has(isoWeekday) ? formatWeekdayShortName(isoWeekday) : ''}\n </HeatmapDayLabel>\n {weeks.map((week, column) => {\n const day = week[isoWeekday - 1];\n if (!day) {\n return <Box key={`outside-${column}-${isoWeekday}`} />;\n }\n const level = levelOf(day.value, thresholds);\n return (\n <Tooltip key={day.date} arrow disableInteractive\n title={`${formatDate(day.date)}: ${describe(day.value)}${day.detail ? ` · ${day.detail}` : ''}`}>\n <HeatmapCell ownSx={(theme) => ({width: CELL_PIXELS, height: CELL_PIXELS, borderRadius: '3px', bgcolor: levelFill(theme, tone, level)})} />\n </Tooltip>\n );\n })}\n </HeatmapWeek>\n ))}\n </HeatmapGrid>\n </HeatmapGridArea>\n )}\n\n {!asTable && (\n <HeatmapLegend direction=\"row\" spacing={0.5} ownSx={{alignItems: 'center', justifyContent: 'flex-end', mt: 1}} aria-hidden=\"true\">\n <HeatmapLegendLess variant=\"caption\" color=\"text.secondary\" ownSx={{mr: 0.5}}>{t('charts.less')}</HeatmapLegendLess>\n {HEATMAP_LEVELS.map((level) => (\n <HeatmapLegendCell key={level} ownSx={(theme) => ({width: CELL_PIXELS, height: CELL_PIXELS, borderRadius: '3px', bgcolor: levelFill(theme, tone, level)})} />\n ))}\n <HeatmapLegendMore variant=\"caption\" color=\"text.secondary\" ownSx={{ml: 0.5}}>{t('charts.more')}</HeatmapLegendMore>\n </HeatmapLegend>\n )}\n </Box>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst CalendarHeatmap = withPieceSlots(CalendarHeatmapContent, THEME_NAME);\nexport default CalendarHeatmap;\n"],"names":[],"mappings":"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"}
|
|
@@ -3,17 +3,18 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import Paper from "@mui/material/Paper";
|
|
4
4
|
import Typography from "@mui/material/Typography";
|
|
5
5
|
import { isGlassTheme, glassStylesOf } from "../../theme/glassSurface.js";
|
|
6
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
6
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
7
7
|
const THEME_NAME = "CalcitaChartTooltip";
|
|
8
8
|
const TooltipRoot = piecePart(THEME_NAME, "Root", Paper);
|
|
9
9
|
const CHART_TOOLTIP_OPACITY = 0.92;
|
|
10
|
-
function
|
|
10
|
+
function ChartTooltipContent(props) {
|
|
11
11
|
const { active, payload, render } = usePieceProps(props, THEME_NAME);
|
|
12
12
|
if (!active || !payload?.length) {
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
15
|
return /* @__PURE__ */ jsx(TooltipRoot, { elevation: 3, ownSx: [{ px: 1.5, py: 1, pointerEvents: "none" }, (theme) => isGlassTheme(theme) ? glassStylesOf(theme, { opacity: CHART_TOOLTIP_OPACITY }) : {}], children: /* @__PURE__ */ jsx(Typography, { variant: "body2", component: "div", children: render(payload[0].payload) }) });
|
|
16
16
|
}
|
|
17
|
+
const ChartTooltip = withPieceSlots(ChartTooltipContent, THEME_NAME);
|
|
17
18
|
export {
|
|
18
19
|
ChartTooltip as default
|
|
19
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartTooltip.js","sources":["../../../src/ui/metrics/ChartTooltip.jsx"],"sourcesContent":["// El tooltip de las gráficas de Recharts con el look de la app. Se exporta para las gráficas propias del proyecto con\n// recharts (una de pastel, una de área): <Tooltip content={<ChartTooltip render={(row) => …} />} />.\n//\n// El de Recharts trae su propio estilo (fondo blanco, borde gris); este usa el Paper del tema y habla igual que los\n// tooltips del resto de la app (y se voltea solo cuando llegue el modo oscuro). Con el vidrio del tema\n// (createToolkitTheme({glass: true})) es de vidrio: flota sobre la gráfica.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaChartTooltip con defaultProps y\n// styleOverrides de sus partes: root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\n\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaChartTooltip)\nconst THEME_NAME = 'CalcitaChartTooltip';\nconst TooltipRoot = piecePart(THEME_NAME, 'Root', Paper);\n\n// el vidrio del cuadrito, casi opaco (el material «grueso»): es para leer una cifra encima de la gráfica; con el vidrio de\n// los controles (60 %) se veía la barra de atrás a través del texto (lo reportaron)\nconst CHART_TOOLTIP_OPACITY = 0.92;\n\n/**\n * @param {{active?: boolean, payload?: Array<{payload: any}>, render: (item: any) => import('react').ReactNode}} props\n * active y payload los pone recharts; render recibe el renglón de data del punto o la columna\n */\
|
|
1
|
+
{"version":3,"file":"ChartTooltip.js","sources":["../../../src/ui/metrics/ChartTooltip.jsx"],"sourcesContent":["// El tooltip de las gráficas de Recharts con el look de la app. Se exporta para las gráficas propias del proyecto con\n// recharts (una de pastel, una de área): <Tooltip content={<ChartTooltip render={(row) => …} />} />.\n//\n// El de Recharts trae su propio estilo (fondo blanco, borde gris); este usa el Paper del tema y habla igual que los\n// tooltips del resto de la app (y se voltea solo cuando llegue el modo oscuro). Con el vidrio del tema\n// (createToolkitTheme({glass: true})) es de vidrio: flota sobre la gráfica.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaChartTooltip con defaultProps y\n// styleOverrides de sus partes: root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\n\nimport {glassStylesOf, isGlassTheme} from '@/theme/glassSurface.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaChartTooltip)\nconst THEME_NAME = 'CalcitaChartTooltip';\nconst TooltipRoot = piecePart(THEME_NAME, 'Root', Paper);\n\n// el vidrio del cuadrito, casi opaco (el material «grueso»): es para leer una cifra encima de la gráfica; con el vidrio de\n// los controles (60 %) se veía la barra de atrás a través del texto (lo reportaron)\nconst CHART_TOOLTIP_OPACITY = 0.92;\n\n/**\n * @param {{active?: boolean, payload?: Array<{payload: any}>, render: (item: any) => import('react').ReactNode}} props\n * active y payload los pone recharts; render recibe el renglón de data del punto o la columna\n */\nfunction ChartTooltipContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaChartTooltip.defaultProps) y encima lo que llega aquí\n // OJO: sin aviso de opciones desconocidas (warnUnknownProps) a propósito: recharts le pasa al globo todas las suyas\n // (offset, wrapperStyle, coordinate…) y el aviso salía con unas veinte opciones que el globo no necesita\n const {active, payload, render} = usePieceProps(props, THEME_NAME);\n // guard clause: Recharts lo monta siempre; solo se pinta sobre una barra\n if (!active || !payload?.length) {\n return null;\n }\n return (\n <TooltipRoot elevation={3} ownSx={[{px: 1.5, py: 1, pointerEvents: 'none'}, (theme) => (isGlassTheme(theme) ? glassStylesOf(theme, {opacity: CHART_TOOLTIP_OPACITY}) : {})]}>\n {/* div: el globo puede llevar varios renglones (una serie por renglón) */}\n <Typography variant=\"body2\" component=\"div\">{render(payload[0].payload)}</Typography>\n </TooltipRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst ChartTooltip = withPieceSlots(ChartTooltipContent, THEME_NAME);\nexport default ChartTooltip;\n"],"names":[],"mappings":";;;;;;AAkBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,QAAQ,KAAK;AAIvD,MAAM,wBAAwB;AAM9B,SAAS,oBAAoB,OAAO;AAIhC,QAAM,EAAC,QAAQ,SAAS,WAAU,cAAc,OAAO,UAAU;AAEjE,MAAI,CAAC,UAAU,CAAC,SAAS,QAAQ;AAC7B,WAAO;AAAA,EACX;AACA,6BACK,aAAA,EAAY,WAAW,GAAG,OAAO,CAAC,EAAC,IAAI,KAAK,IAAI,GAAG,eAAe,UAAS,CAAC,UAAW,aAAa,KAAK,IAAI,cAAc,OAAO,EAAC,SAAS,sBAAA,CAAsB,IAAI,EAAG,GAEtK,UAAA,oBAAC,YAAA,EAAW,SAAQ,SAAQ,WAAU,OAAO,UAAA,OAAO,QAAQ,CAAC,EAAE,OAAO,GAAE,GAC5E;AAER;AAGA,MAAM,eAAe,eAAe,qBAAqB,UAAU;"}
|
|
@@ -9,12 +9,12 @@ import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
|
|
|
9
9
|
import ChartTooltip from "./ChartTooltip.js";
|
|
10
10
|
import TableToggle, { CHART_VIEW } from "./TableToggle.js";
|
|
11
11
|
import { useChartColors, resolvedSeriesOf, highestValueOf, ChartTable, valueAxisWidthOf, ChartLegend, ReferenceCaption } from "./chartParts.js";
|
|
12
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
12
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
13
13
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
14
14
|
const THEME_NAME = "CalcitaColumnChart";
|
|
15
15
|
const ColumnChartPart = piecePart(THEME_NAME, "Chart", Box);
|
|
16
16
|
const SINGLE_SERIES_KEY = "value";
|
|
17
|
-
function
|
|
17
|
+
function ColumnChartContent(props) {
|
|
18
18
|
const {
|
|
19
19
|
data,
|
|
20
20
|
periodLabel,
|
|
@@ -107,6 +107,7 @@ function ColumnChart(props) {
|
|
|
107
107
|
/* @__PURE__ */ jsx(ReferenceCaption, { referenceLine })
|
|
108
108
|
] });
|
|
109
109
|
}
|
|
110
|
+
const ColumnChart = withPieceSlots(ColumnChartContent, THEME_NAME);
|
|
110
111
|
export {
|
|
111
112
|
ColumnChart as default
|
|
112
113
|
};
|