@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
|
@@ -21,8 +21,15 @@ const LARGEST_CHUNK_KILOBYTES = 1000;
|
|
|
21
21
|
// misma línea que lleva el .env del servidor. Vite pide sus archivos con el prefijo, se lo pone a las rutas de index.html y lo
|
|
22
22
|
// deja en import.meta.env.BASE_URL, de donde lo toman el router, las imágenes y version.json (src/core/publicPaths.js). Sin
|
|
23
23
|
// ella, todo en la raíz. Con otro prefijo hay que volver a construir.
|
|
24
|
+
// ASSET_URL=./ : los archivos relativos a la página, para cuando el prefijo lo pone el servidor al servirla (<base href>):
|
|
25
|
+
// una sola compilación sirve detrás de cualquier prefijo (src/core/publicPaths.js)
|
|
26
|
+
const RELATIVE_BASE = './';
|
|
24
27
|
const basePathOf = (assetUrl) => {
|
|
25
|
-
const
|
|
28
|
+
const trimmed = (assetUrl ?? '').trim();
|
|
29
|
+
if (trimmed === '.' || trimmed === RELATIVE_BASE) {
|
|
30
|
+
return RELATIVE_BASE;
|
|
31
|
+
}
|
|
32
|
+
const prefix = trimmed.replace(/^\/+|\/+$/g, '');
|
|
26
33
|
return prefix ? `/${prefix}/` : '/';
|
|
27
34
|
};
|
|
28
35
|
|
|
@@ -50,4 +57,16 @@ export default defineConfig({
|
|
|
50
57
|
dedupe: SINGLE_COPY_PACKAGES,
|
|
51
58
|
},
|
|
52
59
|
build: {chunkSizeWarningLimit: LARGEST_CHUNK_KILOBYTES},
|
|
60
|
+
// Las pruebas de pantalla (pnpm test, src/**/*.test.jsx): jsdom hace de navegador y src/testing/setup.js lo prepara.
|
|
61
|
+
// Toman todo lo de arriba (el alias @/, React, import.meta.glob de los módulos): una prueba carga los archivos igual que
|
|
62
|
+
// el build, sin una segunda configuración que se desfase
|
|
63
|
+
test: {
|
|
64
|
+
environment: 'jsdom',
|
|
65
|
+
setupFiles: ['./src/testing/setup.js'],
|
|
66
|
+
// una prueba de pantalla abre la app completa (rutas lazy, servidor de mentira con su demora): unos segundos
|
|
67
|
+
testTimeout: 30_000,
|
|
68
|
+
// OJO: Calcita pasa por Vite como la app. Si no, Node la carga aparte y le da OTRA copia del router y de MUI: sus
|
|
69
|
+
// pantallas no encuentran el router de la app («useRouteError must be used within a data router»)
|
|
70
|
+
server: {deps: {inline: ['@stackcraftmx/calcita']}},
|
|
71
|
+
},
|
|
53
72
|
});
|
|
@@ -3,11 +3,11 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import Typography from "@mui/material/Typography";
|
|
4
4
|
import AuditTrailTable from "./AuditTrailTable.js";
|
|
5
5
|
import ContentDialog from "../ui/layout/ContentDialog.js";
|
|
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 = "CalcitaAuditTrailDialog";
|
|
9
9
|
const AuditDescription = piecePart(THEME_NAME, "Description", Typography);
|
|
10
|
-
function
|
|
10
|
+
function AuditTrailDialogContent(props) {
|
|
11
11
|
const {
|
|
12
12
|
open,
|
|
13
13
|
onClose,
|
|
@@ -41,6 +41,7 @@ function AuditTrailDialog(props) {
|
|
|
41
41
|
)
|
|
42
42
|
] });
|
|
43
43
|
}
|
|
44
|
+
const AuditTrailDialog = withPieceSlots(AuditTrailDialogContent, THEME_NAME);
|
|
44
45
|
export {
|
|
45
46
|
AuditTrailDialog as default
|
|
46
47
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditTrailDialog.js","sources":["../../src/DataTable/AuditTrailDialog.jsx"],"sourcesContent":["// Diálogo de auditoría de un renglón: su historia de eventos, paginada y filtrada EN EL SERVIDOR (AuditTrailTable).\n//\n// Sirve para el historial de cualquier registro (un pedido, una cuenta).\n// Solo abre una vista: no ejecuta nada y por eso no lleva confirmación.\n//\n// Se abre como diálogo de contenido (ContentDialog): sube desde abajo y ocupa la pantalla debajo de la barra superior. Una\n// tabla con su historia se lee mejor a todo lo ancho que en un recuadro al centro, también en el teléfono.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAuditTrailDialog con defaultProps y\n// styleOverrides de sus partes: description.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Typography from '@mui/material/Typography';\n\nimport AuditTrailTable from '@/DataTable/AuditTrailTable.jsx';\nimport ContentDialog from '@/ui/layout/ContentDialog.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.CalcitaAuditTrailDialog)\nconst THEME_NAME = 'CalcitaAuditTrailDialog';\nconst AuditDescription = piecePart(THEME_NAME, 'Description', Typography);\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {string} props.title ya traducido («Historial de Q3 · ago 2026»)\n * @param {import('react').ReactNode} [props.subtitle]\n * @param {string} props.subjectKey\n * @param {(tableRequest: object, signal: AbortSignal) => Promise<{rows: Array, total: number, facets?: object}>} props.fetchPage\n * @param {Record<string, object>} props.eventDictionary\n * @param {Record<string, object>} [props.resultDictionary]\n * @param {Array<object>} [props.extraColumns]\n * @param {import('react').ReactNode} [props.header] va entre el subtítulo y la tabla (p. ej. pestañas que cambian lo que se\n * consulta)\n * @param {(row: any) => string|null} [props.eventSuffixOf] complemento del evento de un renglón (AuditTrailTable)\n */\
|
|
1
|
+
{"version":3,"file":"AuditTrailDialog.js","sources":["../../src/DataTable/AuditTrailDialog.jsx"],"sourcesContent":["// Diálogo de auditoría de un renglón: su historia de eventos, paginada y filtrada EN EL SERVIDOR (AuditTrailTable).\n//\n// Sirve para el historial de cualquier registro (un pedido, una cuenta).\n// Solo abre una vista: no ejecuta nada y por eso no lleva confirmación.\n//\n// Se abre como diálogo de contenido (ContentDialog): sube desde abajo y ocupa la pantalla debajo de la barra superior. Una\n// tabla con su historia se lee mejor a todo lo ancho que en un recuadro al centro, también en el teléfono.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaAuditTrailDialog con defaultProps y\n// styleOverrides de sus partes: description.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Typography from '@mui/material/Typography';\n\nimport AuditTrailTable from '@/DataTable/AuditTrailTable.jsx';\nimport ContentDialog from '@/ui/layout/ContentDialog.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.CalcitaAuditTrailDialog)\nconst THEME_NAME = 'CalcitaAuditTrailDialog';\nconst AuditDescription = piecePart(THEME_NAME, 'Description', Typography);\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {string} props.title ya traducido («Historial de Q3 · ago 2026»)\n * @param {import('react').ReactNode} [props.subtitle]\n * @param {string} props.subjectKey\n * @param {(tableRequest: object, signal: AbortSignal) => Promise<{rows: Array, total: number, facets?: object}>} props.fetchPage\n * @param {Record<string, object>} props.eventDictionary\n * @param {Record<string, object>} [props.resultDictionary]\n * @param {Array<object>} [props.extraColumns]\n * @param {import('react').ReactNode} [props.header] va entre el subtítulo y la tabla (p. ej. pestañas que cambian lo que se\n * consulta)\n * @param {(row: any) => string|null} [props.eventSuffixOf] complemento del evento de un renglón (AuditTrailTable)\n */\nfunction AuditTrailDialogContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaAuditTrailDialog.defaultProps) y encima lo que llega aquí\n const {\n open, onClose, title, subtitle, subjectKey, fetchPage, eventDictionary, resultDictionary, extraColumns = [], header = null, eventSuffixOf = null,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n return (\n <ContentDialog open={open} onClose={onClose} title={title}>\n {subtitle && (\n <AuditDescription variant=\"body2\" color=\"text.secondary\" ownSx={{mb: 2}}>{subtitle}</AuditDescription>\n )}\n {header}\n <AuditTrailTable\n subjectKey={open ? subjectKey : ''}\n fetchPage={fetchPage}\n eventDictionary={eventDictionary}\n resultDictionary={resultDictionary}\n extraColumns={extraColumns}\n eventSuffixOf={eventSuffixOf}\n ariaLabel={title}\n maxGridHeight={null}\n />\n </ContentDialog>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst AuditTrailDialog = withPieceSlots(AuditTrailDialogContent, THEME_NAME);\nexport default AuditTrailDialog;\n"],"names":[],"mappings":";;;;;;;AAoBA,MAAM,aAAa;AACnB,MAAM,mBAAmB,UAAU,YAAY,eAAe,UAAU;AAiBxE,SAAS,wBAAwB,OAAO;AAEpC,QAAM;AAAA,IACN;AAAA,IAAM;AAAA,IAAS;AAAA,IAAO;AAAA,IAAU;AAAA,IAAY;AAAA,IAAW;AAAA,IAAiB;AAAA,IAAkB,eAAe,CAAA;AAAA,IAAI,SAAS;AAAA,IAAM,gBAAgB;AAAA,IAC5I,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AAC/B,mBAAiB,YAAY,YAAY;AACzC,SACI,qBAAC,eAAA,EAAc,MAAY,SAAkB,OACxC,UAAA;AAAA,IAAA,YACG,oBAAC,kBAAA,EAAiB,SAAQ,SAAQ,OAAM,kBAAiB,OAAO,EAAC,IAAI,EAAA,GAAK,UAAA,SAAA,CAAS;AAAA,IAEtF;AAAA,IACD;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,YAAY,OAAO,aAAa;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,eAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EACnB,GACJ;AAER;AAGA,MAAM,mBAAmB,eAAe,yBAAyB,UAAU;"}
|
|
@@ -11,13 +11,13 @@ import Stack from "@mui/material/Stack";
|
|
|
11
11
|
import Tooltip from "@mui/material/Tooltip";
|
|
12
12
|
import FilterAltIcon from "@mui/icons-material/FilterAlt";
|
|
13
13
|
import FilterAltOutlinedIcon from "@mui/icons-material/FilterAltOutlined";
|
|
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 = "CalcitaHeaderFilter";
|
|
17
17
|
const FilterButton = piecePart(THEME_NAME, "Button", IconButton);
|
|
18
18
|
const FilterBadge = piecePart(THEME_NAME, "Badge", Badge);
|
|
19
19
|
const FilterPanel = piecePart(THEME_NAME, "Panel", Box);
|
|
20
|
-
function
|
|
20
|
+
function HeaderFilterPopoverContent(props) {
|
|
21
21
|
const { activeCount = 0, onClear, children, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
22
22
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
23
23
|
const { t } = useToolkitTranslation("table");
|
|
@@ -73,6 +73,7 @@ function HeaderFilterPopover(props) {
|
|
|
73
73
|
)
|
|
74
74
|
] });
|
|
75
75
|
}
|
|
76
|
+
const HeaderFilterPopover = withPieceSlots(HeaderFilterPopoverContent, THEME_NAME);
|
|
76
77
|
export {
|
|
77
78
|
HeaderFilterPopover as default
|
|
78
79
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeaderFilterPopover.js","sources":["../../../src/DataTable/ColumnFilters/HeaderFilterPopover.jsx"],"sourcesContent":["// El icono de filtro del encabezado, con su globo.\n//\n// El badge trae el NÚMERO de valores activos en esa columna, no un punto: así se sabe sin abrir nada si se filtró por\n// uno o por seis.\n//\n// OJO: stopPropagation en el clic no es adorno. El título del encabezado ordena, y sin eso abrir el filtro también\n// cambiaría el orden.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaHeaderFilter con defaultProps y\n// styleOverrides de sus partes: button, badge, panel.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Badge from '@mui/material/Badge';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Popover from '@mui/material/Popover';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport FilterAltIcon from '@mui/icons-material/FilterAlt';\nimport FilterAltOutlinedIcon from '@mui/icons-material/FilterAltOutlined';\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.CalcitaHeaderFilter)\nconst THEME_NAME = 'CalcitaHeaderFilter';\nconst FilterButton = piecePart(THEME_NAME, 'Button', IconButton);\nconst FilterBadge = piecePart(THEME_NAME, 'Badge', Badge);\nconst FilterPanel = piecePart(THEME_NAME, 'Panel', Box);\n\n/**\n * @param {{activeCount?: number, onClear: () => void, children: import('react').ReactNode}} props children = el filtro\n */\
|
|
1
|
+
{"version":3,"file":"HeaderFilterPopover.js","sources":["../../../src/DataTable/ColumnFilters/HeaderFilterPopover.jsx"],"sourcesContent":["// El icono de filtro del encabezado, con su globo.\n//\n// El badge trae el NÚMERO de valores activos en esa columna, no un punto: así se sabe sin abrir nada si se filtró por\n// uno o por seis.\n//\n// OJO: stopPropagation en el clic no es adorno. El título del encabezado ordena, y sin eso abrir el filtro también\n// cambiaría el orden.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaHeaderFilter con defaultProps y\n// styleOverrides de sus partes: button, badge, panel.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Badge from '@mui/material/Badge';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Popover from '@mui/material/Popover';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport FilterAltIcon from '@mui/icons-material/FilterAlt';\nimport FilterAltOutlinedIcon from '@mui/icons-material/FilterAltOutlined';\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.CalcitaHeaderFilter)\nconst THEME_NAME = 'CalcitaHeaderFilter';\nconst FilterButton = piecePart(THEME_NAME, 'Button', IconButton);\nconst FilterBadge = piecePart(THEME_NAME, 'Badge', Badge);\nconst FilterPanel = piecePart(THEME_NAME, 'Panel', Box);\n\n/**\n * @param {{activeCount?: number, onClear: () => void, children: import('react').ReactNode}} props children = el filtro\n */\nfunction HeaderFilterPopoverContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaHeaderFilter.defaultProps) y encima lo que llega aquí\n const {activeCount = 0, onClear, children, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table');\n const [anchorElement, setAnchorElement] = useState(null);\n const isActive = activeCount > 0;\n const tooltip = isActive ? t('columnFilter.activeTooltip', {count: activeCount}) : t('columnFilter.tooltip');\n\n return (\n <>\n <Tooltip title={tooltip}>\n <FilterButton size=\"small\" aria-label={tooltip}\n ownSx={{color: isActive ? 'primary.main' : 'action.active', opacity: isActive ? 1 : 0.45, overflow: 'visible'}}\n onClick={(event) => {\n event.stopPropagation();\n setAnchorElement(event.currentTarget);\n }}>\n {/* sin filtros NO se monta el Badge: MUI lo esconde con scale(0) y deja un artefacto en la esquina */}\n {isActive ? (\n <FilterBadge badgeContent={activeCount} color=\"primary\" overlap=\"circular\"\n ownSx={{'& .MuiBadge-badge': {fontSize: 10, fontWeight: 700, minWidth: 16, height: 16}}}>\n <FilterAltIcon fontSize=\"inherit\" />\n </FilterBadge>\n ) : <FilterAltOutlinedIcon fontSize=\"inherit\" />}\n </FilterButton>\n </Tooltip>\n\n <Popover open={Boolean(anchorElement)} anchorEl={anchorElement} onClose={() => setAnchorElement(null)}\n anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}>\n <FilterPanel ownSx={{p: 2, minWidth: 280}}>\n <Stack spacing={1}>\n {children}\n <Button size=\"small\" disabled={!isActive}\n onClick={() => {\n onClear();\n setAnchorElement(null);\n }}>\n {t('columnFilter.clear')}\n </Button>\n </Stack>\n </FilterPanel>\n </Popover>\n </>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst HeaderFilterPopover = withPieceSlots(HeaderFilterPopoverContent, THEME_NAME);\nexport default HeaderFilterPopover;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA2BA,MAAM,aAAa;AACnB,MAAM,eAAe,UAAU,YAAY,UAAU,UAAU;AAC/D,MAAM,cAAc,UAAU,YAAY,SAAS,KAAK;AACxD,MAAM,cAAc,UAAU,YAAY,SAAS,GAAG;AAKtD,SAAS,2BAA2B,OAAO;AAEvC,QAAM,EAAC,cAAc,GAAG,SAAS,UAAU,GAAG,iBAAgB,cAAc,OAAO,UAAU;AAC7F,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,OAAO;AACzC,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,IAAI;AACvD,QAAM,WAAW,cAAc;AAC/B,QAAM,UAAU,WAAW,EAAE,8BAA8B,EAAC,OAAO,YAAA,CAAY,IAAI,EAAE,sBAAsB;AAE3G,SACI,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA,oBAAC,SAAA,EAAQ,OAAO,SACZ,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,MAAK;AAAA,QAAQ,cAAY;AAAA,QAC3B,OAAO,EAAC,OAAO,WAAW,iBAAiB,iBAAiB,SAAS,WAAW,IAAI,MAAM,UAAU,UAAA;AAAA,QACpG,SAAS,CAAC,UAAU;AAChB,gBAAM,gBAAA;AACN,2BAAiB,MAAM,aAAa;AAAA,QACxC;AAAA,QAEP,UAAA,WACG;AAAA,UAAC;AAAA,UAAA;AAAA,YAAY,cAAc;AAAA,YAAa,OAAM;AAAA,YAAU,SAAQ;AAAA,YACzD,OAAO,EAAC,qBAAqB,EAAC,UAAU,IAAI,YAAY,KAAK,UAAU,IAAI,QAAQ,GAAA,EAAE;AAAA,YACxF,UAAA,oBAAC,eAAA,EAAc,UAAS,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA,IAEtC,oBAAC,uBAAA,EAAsB,UAAS,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA,GAEtD;AAAA,IAEA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAQ,MAAM,QAAQ,aAAa;AAAA,QAAG,UAAU;AAAA,QAAe,SAAS,MAAM,iBAAiB,IAAI;AAAA,QAC3F,cAAc,EAAC,UAAU,UAAU,YAAY,OAAA;AAAA,QACpD,UAAA,oBAAC,aAAA,EAAY,OAAO,EAAC,GAAG,GAAG,UAAU,IAAA,GACjC,UAAA,qBAAC,OAAA,EAAM,SAAS,GACX,UAAA;AAAA,UAAA;AAAA,UACD;AAAA,YAAC;AAAA,YAAA;AAAA,cAAO,MAAK;AAAA,cAAQ,UAAU,CAAC;AAAA,cACxB,SAAS,MAAM;AACX,wBAAA;AACA,iCAAiB,IAAI;AAAA,cACzB;AAAA,cACH,YAAE,oBAAoB;AAAA,YAAA;AAAA,UAAA;AAAA,QAC3B,EAAA,CACJ,EAAA,CACJ;AAAA,MAAA;AAAA,IAAA;AAAA,EACJ,GACJ;AAER;AAGA,MAAM,sBAAsB,eAAe,4BAA4B,UAAU;"}
|
|
@@ -8,13 +8,13 @@ import Stack from "@mui/material/Stack";
|
|
|
8
8
|
import TextField from "@mui/material/TextField";
|
|
9
9
|
import Typography from "@mui/material/Typography";
|
|
10
10
|
import { useFormatters } from "../../toolkit/useFormatters.js";
|
|
11
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
11
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
12
12
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
13
13
|
const THEME_NAME = "CalcitaMultiSelectFilter";
|
|
14
14
|
const MultiList = piecePart(THEME_NAME, "List", Stack);
|
|
15
15
|
const MultiOption = piecePart(THEME_NAME, "Option", Stack);
|
|
16
16
|
const SEARCHABLE_FROM_OPTIONS = 8;
|
|
17
|
-
function
|
|
17
|
+
function MultiSelectColumnFilterContent(props) {
|
|
18
18
|
const { value = [], onChange, options = [], renderOption, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
19
19
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
20
20
|
const { t } = useToolkitTranslation("table");
|
|
@@ -52,6 +52,7 @@ function MultiSelectColumnFilter(props) {
|
|
|
52
52
|
] })
|
|
53
53
|
] });
|
|
54
54
|
}
|
|
55
|
+
const MultiSelectColumnFilter = withPieceSlots(MultiSelectColumnFilterContent, THEME_NAME);
|
|
55
56
|
export {
|
|
56
57
|
MultiSelectColumnFilter as default
|
|
57
58
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiSelectColumnFilter.js","sources":["../../../src/DataTable/ColumnFilters/MultiSelectColumnFilter.jsx"],"sourcesContent":["// Filtro de opciones de una columna.\n//\n// Dos cosas lo separan de un multi-select cualquiera:\n// - las opciones NO salen de las filas visibles: salen de las FACETAS que el servidor calcula sobre el resultado\n// COMPLETO (ofrecer solo lo que aparece en las primeras 25 filas convierte el filtro en adorno);\n// - cada opción trae su conteo, que es lo que deja decidir si vale la pena filtrar.\n//\n// Desde ocho opciones aparece una caja para buscar entre ellas.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaMultiSelectFilter con defaultProps y\n// styleOverrides de sus partes: list, option.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Checkbox from '@mui/material/Checkbox';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaMultiSelectFilter)\nconst THEME_NAME = 'CalcitaMultiSelectFilter';\nconst MultiList = piecePart(THEME_NAME, 'List', Stack);\nconst MultiOption = piecePart(THEME_NAME, 'Option', Stack);\n\nconst SEARCHABLE_FROM_OPTIONS = 8;\n\n/**\n * @param {object} props\n * @param {string[]} [props.value]\n * @param {(value: string[]) => void} props.onChange\n * @param {Array<{value: string, total: number}>} [props.options] faceta del servidor\n * @param {(value: string) => import('react').ReactNode} [props.renderOption] cómo se lee el valor (diccionario)\n */\
|
|
1
|
+
{"version":3,"file":"MultiSelectColumnFilter.js","sources":["../../../src/DataTable/ColumnFilters/MultiSelectColumnFilter.jsx"],"sourcesContent":["// Filtro de opciones de una columna.\n//\n// Dos cosas lo separan de un multi-select cualquiera:\n// - las opciones NO salen de las filas visibles: salen de las FACETAS que el servidor calcula sobre el resultado\n// COMPLETO (ofrecer solo lo que aparece en las primeras 25 filas convierte el filtro en adorno);\n// - cada opción trae su conteo, que es lo que deja decidir si vale la pena filtrar.\n//\n// Desde ocho opciones aparece una caja para buscar entre ellas.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaMultiSelectFilter con defaultProps y\n// styleOverrides de sus partes: list, option.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Checkbox from '@mui/material/Checkbox';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaMultiSelectFilter)\nconst THEME_NAME = 'CalcitaMultiSelectFilter';\nconst MultiList = piecePart(THEME_NAME, 'List', Stack);\nconst MultiOption = piecePart(THEME_NAME, 'Option', Stack);\n\nconst SEARCHABLE_FROM_OPTIONS = 8;\n\n/**\n * @param {object} props\n * @param {string[]} [props.value]\n * @param {(value: string[]) => void} props.onChange\n * @param {Array<{value: string, total: number}>} [props.options] faceta del servidor\n * @param {(value: string) => import('react').ReactNode} [props.renderOption] cómo se lee el valor (diccionario)\n */\nfunction MultiSelectColumnFilterContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaMultiSelectFilter.defaultProps) y encima lo que llega aquí\n const {value = [], onChange, options = [], renderOption, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table');\n const {formatNumber} = useFormatters();\n const [searchText, setSearchText] = useState('');\n\n const toggleOption = (optionValue) => onChange(value.includes(optionValue)\n ? value.filter((currentValue) => currentValue !== optionValue)\n : [...value, optionValue]);\n\n const isSearchable = options.length >= SEARCHABLE_FROM_OPTIONS;\n const visibleOptions = isSearchable && searchText\n ? options.filter((option) => String(option.value).toLowerCase().includes(searchText.toLowerCase()))\n : options;\n\n return (\n <Stack spacing={1}>\n {isSearchable && (\n <TextField size=\"small\" autoFocus fullWidth placeholder={t('options.searchPlaceholder')} value={searchText}\n onChange={(event) => setSearchText(event.target.value)} />\n )}\n <MultiList ownSx={{maxHeight: 300, overflowY: 'auto'}}>\n {options.length === 0 && (\n <Typography variant=\"caption\" color=\"text.secondary\">{t('options.empty')}</Typography>\n )}\n {options.length > 0 && visibleOptions.length === 0 && (\n <Typography variant=\"caption\" color=\"text.secondary\">{t('options.noMatch', {text: searchText})}</Typography>\n )}\n {visibleOptions.map((option) => (\n <FormControlLabel\n key={option.value}\n control={<Checkbox size=\"small\" checked={value.includes(option.value)} onChange={() => toggleOption(option.value)} />}\n label={(\n <MultiOption direction=\"row\" spacing={0.75} ownSx={{alignItems: 'center'}}>\n {renderOption ? renderOption(option.value) : <Typography variant=\"body2\">{option.value}</Typography>}\n <Typography variant=\"caption\" color=\"text.secondary\">{formatNumber(option.total)}</Typography>\n </MultiOption>\n )}\n />\n ))}\n </MultiList>\n </Stack>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst MultiSelectColumnFilter = withPieceSlots(MultiSelectColumnFilterContent, THEME_NAME);\nexport default MultiSelectColumnFilter;\n"],"names":[],"mappings":";;;;;;;;;;;;AA0BA,MAAM,aAAa;AACnB,MAAM,YAAY,UAAU,YAAY,QAAQ,KAAK;AACrD,MAAM,cAAc,UAAU,YAAY,UAAU,KAAK;AAEzD,MAAM,0BAA0B;AAShC,SAAS,+BAA+B,OAAO;AAE3C,QAAM,EAAC,QAAQ,IAAI,UAAU,UAAU,CAAA,GAAI,cAAc,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC3G,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,OAAO;AACzC,QAAM,EAAC,aAAA,IAAgB,cAAA;AACvB,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,EAAE;AAE/C,QAAM,eAAe,CAAC,gBAAgB,SAAS,MAAM,SAAS,WAAW,IACnE,MAAM,OAAO,CAAC,iBAAiB,iBAAiB,WAAW,IAC3D,CAAC,GAAG,OAAO,WAAW,CAAC;AAE7B,QAAM,eAAe,QAAQ,UAAU;AACvC,QAAM,iBAAiB,gBAAgB,aACjC,QAAQ,OAAO,CAAC,WAAW,OAAO,OAAO,KAAK,EAAE,cAAc,SAAS,WAAW,YAAA,CAAa,CAAC,IAChG;AAEN,SACI,qBAAC,OAAA,EAAM,SAAS,GACX,UAAA;AAAA,IAAA,gBACG;AAAA,MAAC;AAAA,MAAA;AAAA,QAAU,MAAK;AAAA,QAAQ,WAAS;AAAA,QAAC,WAAS;AAAA,QAAC,aAAa,EAAE,2BAA2B;AAAA,QAAG,OAAO;AAAA,QACrF,UAAU,CAAC,UAAU,cAAc,MAAM,OAAO,KAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAEpE,qBAAC,aAAU,OAAO,EAAC,WAAW,KAAK,WAAW,UACzC,UAAA;AAAA,MAAA,QAAQ,WAAW,KAChB,oBAAC,YAAA,EAAW,SAAQ,WAAU,OAAM,kBAAkB,UAAA,EAAE,eAAe,EAAA,CAAE;AAAA,MAE5E,QAAQ,SAAS,KAAK,eAAe,WAAW,yBAC5C,YAAA,EAAW,SAAQ,WAAU,OAAM,kBAAkB,UAAA,EAAE,mBAAmB,EAAC,MAAM,WAAA,CAAW,GAAE;AAAA,MAElG,eAAe,IAAI,CAAC,WACjB;AAAA,QAAC;AAAA,QAAA;AAAA,UAEG,SAAS,oBAAC,UAAA,EAAS,MAAK,SAAQ,SAAS,MAAM,SAAS,OAAO,KAAK,GAAG,UAAU,MAAM,aAAa,OAAO,KAAK,GAAG;AAAA,UACnH,OACI,qBAAC,aAAA,EAAY,WAAU,OAAM,SAAS,MAAM,OAAO,EAAC,YAAY,SAAA,GAC3D,UAAA;AAAA,YAAA,eAAe,aAAa,OAAO,KAAK,wBAAK,YAAA,EAAW,SAAQ,SAAS,UAAA,OAAO,MAAA,CAAM;AAAA,YACvF,oBAAC,cAAW,SAAQ,WAAU,OAAM,kBAAkB,UAAA,aAAa,OAAO,KAAK,EAAA,CAAE;AAAA,UAAA,EAAA,CACrF;AAAA,QAAA;AAAA,QANC,OAAO;AAAA,MAAA,CASnB;AAAA,IAAA,EAAA,CACL;AAAA,EAAA,GACJ;AAER;AAGA,MAAM,0BAA0B,eAAe,gCAAgC,UAAU;"}
|
|
@@ -7,7 +7,7 @@ import Stack from "@mui/material/Stack";
|
|
|
7
7
|
import Tooltip from "@mui/material/Tooltip";
|
|
8
8
|
import Typography from "@mui/material/Typography";
|
|
9
9
|
import HeaderFilterPopover from "./HeaderFilterPopover.js";
|
|
10
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
10
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
11
11
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
12
12
|
const THEME_NAME = "CalcitaSortableFilterHeader";
|
|
13
13
|
const SortableTitle = piecePart(THEME_NAME, "Title", Typography);
|
|
@@ -15,7 +15,7 @@ const SortableRoot = piecePart(THEME_NAME, "Root", Stack);
|
|
|
15
15
|
const SortableSortButton = piecePart(THEME_NAME, "SortButton", ButtonBase);
|
|
16
16
|
const SortableSortIndicator = piecePart(THEME_NAME, "SortIndicator", Box);
|
|
17
17
|
const SortableClearButton = piecePart(THEME_NAME, "ClearButton", ButtonBase);
|
|
18
|
-
function
|
|
18
|
+
function SortableFilterHeaderContent(props) {
|
|
19
19
|
const {
|
|
20
20
|
label,
|
|
21
21
|
sortable = true,
|
|
@@ -59,6 +59,7 @@ function SortableFilterHeader(props) {
|
|
|
59
59
|
filterable && /* @__PURE__ */ jsx(HeaderFilterPopover, { activeCount, onClear, children })
|
|
60
60
|
] });
|
|
61
61
|
}
|
|
62
|
+
const SortableFilterHeader = withPieceSlots(SortableFilterHeaderContent, THEME_NAME);
|
|
62
63
|
export {
|
|
63
64
|
SortableFilterHeader as default
|
|
64
65
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SortableFilterHeader.js","sources":["../../../src/DataTable/ColumnFilters/SortableFilterHeader.jsx"],"sourcesContent":["// Encabezado con orden y filtro.\n//\n// El que ordena es el TÍTULO, no un botón aparte: es el gesto que ya tiene aprendido quien usa tablas. La flecha solo\n// aparece cuando la columna está ordenando, y su × quita ese orden sin tener que ciclar hasta el tercer clic.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSortableFilterHeader con defaultProps y\n// styleOverrides de sus partes: title, root, sortButton, sortIndicator, clearButton.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\n\nimport HeaderFilterPopover from '@/DataTable/ColumnFilters/HeaderFilterPopover.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.CalcitaSortableFilterHeader)\nconst THEME_NAME = 'CalcitaSortableFilterHeader';\nconst SortableTitle = piecePart(THEME_NAME, 'Title', Typography);\nconst SortableRoot = piecePart(THEME_NAME, 'Root', Stack);\nconst SortableSortButton = piecePart(THEME_NAME, 'SortButton', ButtonBase);\nconst SortableSortIndicator = piecePart(THEME_NAME, 'SortIndicator', Box);\nconst SortableClearButton = piecePart(THEME_NAME, 'ClearButton', ButtonBase);\n\n/**\n * @param {object} props\n * @param {string} props.label\n * @param {boolean} [props.sortable]\n * @param {{column: string, direction: 'asc'|'desc'}} [props.sortEntry]\n * @param {() => void} [props.onSort]\n * @param {() => void} [props.onClearSort]\n * @param {boolean} [props.filterable]\n * @param {number} [props.activeCount]\n * @param {() => void} [props.onClear]\n * @param {import('react').ReactNode} [props.children] el filtro de la columna\n */\
|
|
1
|
+
{"version":3,"file":"SortableFilterHeader.js","sources":["../../../src/DataTable/ColumnFilters/SortableFilterHeader.jsx"],"sourcesContent":["// Encabezado con orden y filtro.\n//\n// El que ordena es el TÍTULO, no un botón aparte: es el gesto que ya tiene aprendido quien usa tablas. La flecha solo\n// aparece cuando la columna está ordenando, y su × quita ese orden sin tener que ciclar hasta el tercer clic.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaSortableFilterHeader con defaultProps y\n// styleOverrides de sus partes: title, root, sortButton, sortIndicator, clearButton.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\n\nimport HeaderFilterPopover from '@/DataTable/ColumnFilters/HeaderFilterPopover.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.CalcitaSortableFilterHeader)\nconst THEME_NAME = 'CalcitaSortableFilterHeader';\nconst SortableTitle = piecePart(THEME_NAME, 'Title', Typography);\nconst SortableRoot = piecePart(THEME_NAME, 'Root', Stack);\nconst SortableSortButton = piecePart(THEME_NAME, 'SortButton', ButtonBase);\nconst SortableSortIndicator = piecePart(THEME_NAME, 'SortIndicator', Box);\nconst SortableClearButton = piecePart(THEME_NAME, 'ClearButton', ButtonBase);\n\n/**\n * @param {object} props\n * @param {string} props.label\n * @param {boolean} [props.sortable]\n * @param {{column: string, direction: 'asc'|'desc'}} [props.sortEntry]\n * @param {() => void} [props.onSort]\n * @param {() => void} [props.onClearSort]\n * @param {boolean} [props.filterable]\n * @param {number} [props.activeCount]\n * @param {() => void} [props.onClear]\n * @param {import('react').ReactNode} [props.children] el filtro de la columna\n */\nfunction SortableFilterHeaderContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaSortableFilterHeader.defaultProps) y encima lo que llega aquí\n const {\n label, sortable = true, sortEntry, onSort, onClearSort, filterable = true, activeCount, onClear, children,\n ...unknownProps\n} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table');\n const title = <SortableTitle variant=\"caption\" ownSx={{fontWeight: 700, whiteSpace: 'nowrap'}}>{label}</SortableTitle>;\n\n return (\n <SortableRoot direction=\"row\" spacing={0.25} ownSx={{alignItems: 'center'}}>\n {sortable ? (\n <Tooltip title={t('sort.tooltip')}>\n <SortableSortButton onClick={onSort} ownSx={{gap: 0.25, borderRadius: 0.5}}>\n {title}\n {sortEntry && (\n <SortableSortIndicator component=\"span\" ownSx={{display: 'inline-flex', alignItems: 'center', color: 'primary.main', fontWeight: 700}}\n aria-label={sortEntry.direction === 'asc' ? t('sort.ascending') : t('sort.descending')}>\n {sortEntry.direction === 'asc' ? '↑' : '↓'}\n </SortableSortIndicator>\n )}\n </SortableSortButton>\n </Tooltip>\n ) : title}\n\n {sortEntry && onClearSort && (\n <Tooltip title={t('sort.clear')}>\n <SortableClearButton aria-label={t('sort.clear')}\n // sin opacidad: la × es un control y al 70% daba 2.90:1 sobre el encabezado de la tabla\n ownSx={{fontSize: 12, lineHeight: 1, color: 'primary.main', '&:hover': {color: 'primary.dark'}}}\n onClick={(event) => {\n event.stopPropagation();\n onClearSort();\n }}>\n ×\n </SortableClearButton>\n </Tooltip>\n )}\n\n {filterable && (\n <HeaderFilterPopover activeCount={activeCount} onClear={onClear}>{children}</HeaderFilterPopover>\n )}\n </SortableRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst SortableFilterHeader = withPieceSlots(SortableFilterHeaderContent, THEME_NAME);\nexport default SortableFilterHeader;\n"],"names":[],"mappings":";;;;;;;;;;;AAqBA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,SAAS,UAAU;AAC/D,MAAM,eAAe,UAAU,YAAY,QAAQ,KAAK;AACxD,MAAM,qBAAqB,UAAU,YAAY,cAAc,UAAU;AACzE,MAAM,wBAAwB,UAAU,YAAY,iBAAiB,GAAG;AACxE,MAAM,sBAAsB,UAAU,YAAY,eAAe,UAAU;AAc3E,SAAS,4BAA4B,OAAO;AAExC,QAAM;AAAA,IACN;AAAA,IAAO,WAAW;AAAA,IAAM;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAa,aAAa;AAAA,IAAM;AAAA,IAAa;AAAA,IAAS;AAAA,IACjG,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AAC/B,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,OAAO;AACzC,QAAM,QAAQ,oBAAC,eAAA,EAAc,SAAQ,WAAU,OAAO,EAAC,YAAY,KAAK,YAAY,SAAA,GAAY,UAAA,MAAA,CAAM;AAEtG,SACI,qBAAC,cAAA,EAAa,WAAU,OAAM,SAAS,MAAM,OAAO,EAAC,YAAY,SAAA,GAC5D,UAAA;AAAA,IAAA,+BACI,SAAA,EAAQ,OAAO,EAAE,cAAc,GAC5B,UAAA,qBAAC,oBAAA,EAAmB,SAAS,QAAQ,OAAO,EAAC,KAAK,MAAM,cAAc,OACjE,UAAA;AAAA,MAAA;AAAA,MACA,aACG;AAAA,QAAC;AAAA,QAAA;AAAA,UAAsB,WAAU;AAAA,UAAO,OAAO,EAAC,SAAS,eAAe,YAAY,UAAU,OAAO,gBAAgB,YAAY,IAAA;AAAA,UAC5H,cAAY,UAAU,cAAc,QAAQ,EAAE,gBAAgB,IAAI,EAAE,iBAAiB;AAAA,UACrF,UAAA,UAAU,cAAc,QAAQ,MAAM;AAAA,QAAA;AAAA,MAAA;AAAA,IAC3C,EAAA,CAER,GACJ,IACA;AAAA,IAEH,aAAa,eACV,oBAAC,WAAQ,OAAO,EAAE,YAAY,GAC1B,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAoB,cAAY,EAAE,YAAY;AAAA,QAEnC,OAAO,EAAC,UAAU,IAAI,YAAY,GAAG,OAAO,gBAAgB,WAAW,EAAC,OAAO,eAAA,EAAc;AAAA,QAC7F,SAAS,CAAC,UAAU;AAChB,gBAAM,gBAAA;AACN,sBAAA;AAAA,QACJ;AAAA,QAAG,UAAA;AAAA,MAAA;AAAA,IAAA,GAGnB;AAAA,IAGH,cACG,oBAAC,qBAAA,EAAoB,aAA0B,SAAmB,SAAA,CAAS;AAAA,EAAA,GAEnF;AAER;AAGA,MAAM,uBAAuB,eAAe,6BAA6B,UAAU;"}
|
|
@@ -7,12 +7,12 @@ import Stack from "@mui/material/Stack";
|
|
|
7
7
|
import Typography from "@mui/material/Typography";
|
|
8
8
|
import FilterListOffIcon from "@mui/icons-material/FilterListOff";
|
|
9
9
|
import InboxOutlinedIcon from "@mui/icons-material/InboxOutlined";
|
|
10
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
10
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
11
11
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
12
12
|
const THEME_NAME = "CalcitaEmptyState";
|
|
13
13
|
const EmptyRoot = piecePart(THEME_NAME, "Root", Stack);
|
|
14
14
|
const EmptyIcon = piecePart(THEME_NAME, "Icon", Box);
|
|
15
|
-
function
|
|
15
|
+
function EmptyStateContent(props) {
|
|
16
16
|
const { filtered = false, label, onClearFilters, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
17
17
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
18
18
|
const { t } = useToolkitTranslation("table", texts);
|
|
@@ -23,6 +23,7 @@ function EmptyState(props) {
|
|
|
23
23
|
filtered && onClearFilters && /* @__PURE__ */ jsx(Button, { size: "small", onClick: onClearFilters, children: t("empty.clearFilters") })
|
|
24
24
|
] });
|
|
25
25
|
}
|
|
26
|
+
const EmptyState = withPieceSlots(EmptyStateContent, THEME_NAME);
|
|
26
27
|
export {
|
|
27
28
|
EmptyState as default
|
|
28
29
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.js","sources":["../../src/DataTable/EmptyState.jsx"],"sourcesContent":["// Qué decir cuando la tabla no tiene filas.\n//\n// Son dos situaciones distintas y confundirlas hace daño:\n// - sin filtros puestos, la lista vacía es el RESULTADO y se dice tal cual (label);\n// - con filtros puestos, la lista vacía NO dice nada del conjunto: dice que lo filtrado no existe dentro de él. Ahí\n// sí hay algo que hacer, y el botón lo hace.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaEmptyState con defaultProps y\n// styleOverrides de sus partes: root, icon.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport FilterListOffIcon from '@mui/icons-material/FilterListOff';\nimport InboxOutlinedIcon from '@mui/icons-material/InboxOutlined';\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.CalcitaEmptyState)\nconst THEME_NAME = 'CalcitaEmptyState';\nconst EmptyRoot = piecePart(THEME_NAME, 'Root', Stack);\nconst EmptyIcon = piecePart(THEME_NAME, 'Icon', Box);\n\n/**\n * @param {object} [props]\n * @param {boolean} [props.filtered]\n * @param {string} [props.label] ya traducido\n * @param {() => void} [props.onClearFilters]\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"EmptyState.js","sources":["../../src/DataTable/EmptyState.jsx"],"sourcesContent":["// Qué decir cuando la tabla no tiene filas.\n//\n// Son dos situaciones distintas y confundirlas hace daño:\n// - sin filtros puestos, la lista vacía es el RESULTADO y se dice tal cual (label);\n// - con filtros puestos, la lista vacía NO dice nada del conjunto: dice que lo filtrado no existe dentro de él. Ahí\n// sí hay algo que hacer, y el botón lo hace.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaEmptyState con defaultProps y\n// styleOverrides de sus partes: root, icon.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport FilterListOffIcon from '@mui/icons-material/FilterListOff';\nimport InboxOutlinedIcon from '@mui/icons-material/InboxOutlined';\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.CalcitaEmptyState)\nconst THEME_NAME = 'CalcitaEmptyState';\nconst EmptyRoot = piecePart(THEME_NAME, 'Root', Stack);\nconst EmptyIcon = piecePart(THEME_NAME, 'Icon', Box);\n\n/**\n * @param {object} [props]\n * @param {boolean} [props.filtered]\n * @param {string} [props.label] ya traducido\n * @param {() => void} [props.onClearFilters]\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nfunction EmptyStateContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaEmptyState.defaultProps) y encima lo que llega aquí\n const {filtered = false, label, onClearFilters, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const Icon = filtered ? FilterListOffIcon : InboxOutlinedIcon;\n\n return (\n <EmptyRoot spacing={1} ownSx={{height: '100%', px: 3, textAlign: 'center', alignItems: 'center', justifyContent: 'center'}}>\n <EmptyIcon ownSx={{color: 'text.disabled', display: 'flex'}}>\n <Icon fontSize=\"large\" />\n </EmptyIcon>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {filtered ? t('empty.filtered') : (label ?? t('empty.default'))}\n </Typography>\n {filtered && onClearFilters && (\n <Button size=\"small\" onClick={onClearFilters}>{t('empty.clearFilters')}</Button>\n )}\n </EmptyRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst EmptyState = withPieceSlots(EmptyStateContent, THEME_NAME);\nexport default EmptyState;\n"],"names":[],"mappings":";;;;;;;;;;;AAsBA,MAAM,aAAa;AACnB,MAAM,YAAY,UAAU,YAAY,QAAQ,KAAK;AACrD,MAAM,YAAY,UAAU,YAAY,QAAQ,GAAG;AASnD,SAAS,kBAAkB,OAAO;AAE9B,QAAM,EAAC,WAAW,OAAO,OAAO,gBAAgB,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AACzG,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS,KAAK;AAChD,QAAM,OAAO,WAAW,oBAAoB;AAE5C,8BACK,WAAA,EAAU,SAAS,GAAG,OAAO,EAAC,QAAQ,QAAQ,IAAI,GAAG,WAAW,UAAU,YAAY,UAAU,gBAAgB,YAC7G,UAAA;AAAA,IAAA,oBAAC,WAAA,EAAU,OAAO,EAAC,OAAO,iBAAiB,SAAS,OAAA,GAChD,UAAA,oBAAC,MAAA,EAAK,UAAS,QAAA,CAAQ,GAC3B;AAAA,IACA,oBAAC,YAAA,EAAW,SAAQ,SAAQ,OAAM,kBAC7B,UAAA,WAAW,EAAE,gBAAgB,IAAK,SAAS,EAAE,eAAe,GACjE;AAAA,IACC,YAAY,kBACT,oBAAC,QAAA,EAAO,MAAK,SAAQ,SAAS,gBAAiB,UAAA,EAAE,oBAAoB,EAAA,CAAE;AAAA,EAAA,GAE/E;AAER;AAGA,MAAM,aAAa,eAAe,mBAAmB,UAAU;"}
|
|
@@ -8,13 +8,13 @@ import Typography from "@mui/material/Typography";
|
|
|
8
8
|
import ClearAllIcon from "@mui/icons-material/ClearAll";
|
|
9
9
|
import ScrollableRow from "../ui/layout/ScrollableRow.js";
|
|
10
10
|
import Tag from "../ui/labels/Tag.js";
|
|
11
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
11
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
12
12
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
13
13
|
const THEME_NAME = "CalcitaFilterChips";
|
|
14
14
|
const ChipsRoot = piecePart(THEME_NAME, "Root", Box);
|
|
15
15
|
const ChipsHeader = piecePart(THEME_NAME, "Header", Stack);
|
|
16
16
|
const ChipsClearButton = piecePart(THEME_NAME, "ClearButton", Button);
|
|
17
|
-
function
|
|
17
|
+
function FilterChipsContent(props) {
|
|
18
18
|
const { chipConfig, filters, onSetFilter, onClearAll, quickActiveCount = 0, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
19
19
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
20
20
|
const { t } = useToolkitTranslation("table", texts);
|
|
@@ -41,6 +41,7 @@ function FilterChips(props) {
|
|
|
41
41
|
chips.length > 0 && /* @__PURE__ */ jsx(ScrollableRow, { children: chips.map(({ id, label, onDelete }) => /* @__PURE__ */ jsx(Tag, { label, color: "primary", onDelete, sx: { flex: "0 0 auto" } }, id)) })
|
|
42
42
|
] });
|
|
43
43
|
}
|
|
44
|
+
const FilterChips = withPieceSlots(FilterChipsContent, THEME_NAME);
|
|
44
45
|
export {
|
|
45
46
|
FilterChips as default
|
|
46
47
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterChips.js","sources":["../../src/DataTable/FilterChips.jsx"],"sourcesContent":["// Los filtros activos, a la vista y desarmables de a uno.\n//\n// Un filtro que solo se ve como un icono encendido en el encabezado se olvida: alguien filtra, se va al detalle,\n// regresa y lee el total como si fuera el de todo. Por eso los filtros puestos se dicen con todas sus letras arriba de\n// la tabla.\n//\n// Van en UNA tira que se desliza (ScrollableRow), no envolviéndose en renglones que empujan la tabla fuera de la\n// pantalla. La cuenta y \"Limpiar todo\" van en su propio renglón, arriba, para no tener que deslizar hasta encontrarlo.\n// Sin filtros activos no se pinta nada (ni el hueco).\n//\n// Los accesos rápidos cuentan aunque no tengan chip aquí: su propio chip encendido ya dice qué está elegido.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaFilterChips con defaultProps y\n// styleOverrides de sus partes: root, header, clearButton.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport ClearAllIcon from '@mui/icons-material/ClearAll';\n\nimport ScrollableRow from '@/ui/layout/ScrollableRow.jsx';\nimport Tag from '@/ui/labels/Tag.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.CalcitaFilterChips)\nconst THEME_NAME = 'CalcitaFilterChips';\nconst ChipsRoot = piecePart(THEME_NAME, 'Root', Box);\nconst ChipsHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst ChipsClearButton = piecePart(THEME_NAME, 'ClearButton', Button);\n\n/**\n * @param {object} props\n * @param {Array<object>} props.chipConfig lo que arma buildChipConfig\n * @param {object} props.filters\n * @param {(field: string, value: unknown) => void} props.onSetFilter\n * @param {() => void} props.onClearAll\n * @param {number} [props.quickActiveCount] accesos rápidos puestos que no tienen chip aquí\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"FilterChips.js","sources":["../../src/DataTable/FilterChips.jsx"],"sourcesContent":["// Los filtros activos, a la vista y desarmables de a uno.\n//\n// Un filtro que solo se ve como un icono encendido en el encabezado se olvida: alguien filtra, se va al detalle,\n// regresa y lee el total como si fuera el de todo. Por eso los filtros puestos se dicen con todas sus letras arriba de\n// la tabla.\n//\n// Van en UNA tira que se desliza (ScrollableRow), no envolviéndose en renglones que empujan la tabla fuera de la\n// pantalla. La cuenta y \"Limpiar todo\" van en su propio renglón, arriba, para no tener que deslizar hasta encontrarlo.\n// Sin filtros activos no se pinta nada (ni el hueco).\n//\n// Los accesos rápidos cuentan aunque no tengan chip aquí: su propio chip encendido ya dice qué está elegido.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaFilterChips con defaultProps y\n// styleOverrides de sus partes: root, header, clearButton.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport ClearAllIcon from '@mui/icons-material/ClearAll';\n\nimport ScrollableRow from '@/ui/layout/ScrollableRow.jsx';\nimport Tag from '@/ui/labels/Tag.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.CalcitaFilterChips)\nconst THEME_NAME = 'CalcitaFilterChips';\nconst ChipsRoot = piecePart(THEME_NAME, 'Root', Box);\nconst ChipsHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst ChipsClearButton = piecePart(THEME_NAME, 'ClearButton', Button);\n\n/**\n * @param {object} props\n * @param {Array<object>} props.chipConfig lo que arma buildChipConfig\n * @param {object} props.filters\n * @param {(field: string, value: unknown) => void} props.onSetFilter\n * @param {() => void} props.onClearAll\n * @param {number} [props.quickActiveCount] accesos rápidos puestos que no tienen chip aquí\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nfunction FilterChipsContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaFilterChips.defaultProps) y encima lo que llega aquí\n const {chipConfig, filters, onSetFilter, onClearAll, quickActiveCount = 0, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const chips = chipConfig\n .filter((chipDeclaration) => chipDeclaration.isActive(filters[chipDeclaration.key]))\n .flatMap((chipDeclaration) => chipDeclaration.chipsFor(filters[chipDeclaration.key], onSetFilter));\n\n const activeCount = chips.length + quickActiveCount;\n // guard clause: sin filtros no se pinta nada\n if (activeCount === 0) {\n return null;\n }\n\n return (\n <ChipsRoot ownSx={{mb: 1.5, minWidth: 0}}>\n <ChipsHeader direction=\"row\" spacing={1} ownSx={{px: 0.25, alignItems: 'center', justifyContent: 'space-between'}}>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {t('chips.applied', {count: activeCount})}\n </Typography>\n <ChipsClearButton size=\"small\" color=\"error\" startIcon={<ClearAllIcon fontSize=\"small\" />} onClick={onClearAll}\n ownSx={{flexShrink: 0}}>\n {t('chips.clearAll')}\n </ChipsClearButton>\n </ChipsHeader>\n\n {chips.length > 0 && (\n <ScrollableRow>\n {chips.map(({id, label, onDelete}) => (\n <Tag key={id} label={label} color=\"primary\" onDelete={onDelete} sx={{flex: '0 0 auto'}} />\n ))}\n </ScrollableRow>\n )}\n </ChipsRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst FilterChips = withPieceSlots(FilterChipsContent, THEME_NAME);\nexport default FilterChips;\n"],"names":[],"mappings":";;;;;;;;;;;;AA6BA,MAAM,aAAa;AACnB,MAAM,YAAY,UAAU,YAAY,QAAQ,GAAG;AACnD,MAAM,cAAc,UAAU,YAAY,UAAU,KAAK;AACzD,MAAM,mBAAmB,UAAU,YAAY,eAAe,MAAM;AAWpE,SAAS,mBAAmB,OAAO;AAE/B,QAAM,EAAC,YAAY,SAAS,aAAa,YAAY,mBAAmB,GAAG,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AACpI,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS,KAAK;AAChD,QAAM,QAAQ,WACT,OAAO,CAAC,oBAAoB,gBAAgB,SAAS,QAAQ,gBAAgB,GAAG,CAAC,CAAC,EAClF,QAAQ,CAAC,oBAAoB,gBAAgB,SAAS,QAAQ,gBAAgB,GAAG,GAAG,WAAW,CAAC;AAErG,QAAM,cAAc,MAAM,SAAS;AAEnC,MAAI,gBAAgB,GAAG;AACnB,WAAO;AAAA,EACX;AAEA,SACI,qBAAC,aAAU,OAAO,EAAC,IAAI,KAAK,UAAU,KAClC,UAAA;AAAA,IAAA,qBAAC,aAAA,EAAY,WAAU,OAAM,SAAS,GAAG,OAAO,EAAC,IAAI,MAAM,YAAY,UAAU,gBAAgB,mBAC7F,UAAA;AAAA,MAAA,oBAAC,YAAA,EAAW,SAAQ,WAAU,OAAM,kBAAiB,QAAM,MACtD,UAAA,EAAE,iBAAiB,EAAC,OAAO,YAAA,CAAY,GAC5C;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UAAiB,MAAK;AAAA,UAAQ,OAAM;AAAA,UAAQ,WAAW,oBAAC,cAAA,EAAa,UAAS,QAAA,CAAQ;AAAA,UAAI,SAAS;AAAA,UAC5F,OAAO,EAAC,YAAY,EAAA;AAAA,UACvB,YAAE,gBAAgB;AAAA,QAAA;AAAA,MAAA;AAAA,IACvB,GACJ;AAAA,IAEC,MAAM,SAAS,KACZ,oBAAC,eAAA,EACI,UAAA,MAAM,IAAI,CAAC,EAAC,IAAI,OAAO,SAAA,0BACnB,KAAA,EAAa,OAAc,OAAM,WAAU,UAAoB,IAAI,EAAC,MAAM,WAAA,KAAjE,EAA8E,CAC3F,EAAA,CACL;AAAA,EAAA,GAER;AAER;AAGA,MAAM,cAAc,eAAe,oBAAoB,UAAU;"}
|
|
@@ -1,35 +1,88 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useRef, useEffect } from "react";
|
|
4
4
|
import Autocomplete from "@mui/material/Autocomplete";
|
|
5
5
|
import Stack from "@mui/material/Stack";
|
|
6
6
|
import TextField from "@mui/material/TextField";
|
|
7
7
|
import Typography from "@mui/material/Typography";
|
|
8
|
+
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
9
|
+
import { List } from "react-window";
|
|
10
|
+
import { pageNumbersOf, filterPages } from "./goToPageOptions.js";
|
|
11
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
8
12
|
import { useFormatters } from "../toolkit/useFormatters.js";
|
|
9
|
-
import {
|
|
13
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
10
14
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
11
15
|
const THEME_NAME = "CalcitaGoToPage";
|
|
12
16
|
const GoToRoot = piecePart(THEME_NAME, "Root", Stack);
|
|
13
17
|
const GoToField = piecePart(THEME_NAME, "Field", Autocomplete);
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
const OPTION_HEIGHT = 36;
|
|
19
|
+
const PHONE_OPTION_HEIGHT = 48;
|
|
20
|
+
const LISTBOX_MAX_HEIGHT = 240;
|
|
21
|
+
const LISTBOX_PADDING = 8;
|
|
22
|
+
const OVERSCAN_ROWS = 5;
|
|
23
|
+
function PageOption({ index, style, pageOptions }) {
|
|
24
|
+
const [{ key, ...optionProps }, pageNumber] = pageOptions[index];
|
|
25
|
+
return /* @__PURE__ */ jsx(Typography, { component: "li", ...optionProps, noWrap: true, style: { ...style, top: (style.top ?? 0) + LISTBOX_PADDING }, children: pageNumber }, key);
|
|
26
|
+
}
|
|
27
|
+
function PageListbox({ children: pageOptions, ref, pageCount, pageListRef, pageIndexesRef, className, style, ...listboxProps }) {
|
|
28
|
+
const isWideScreen = useMediaQuery((theme) => theme.breakpoints.up("sm"), { noSsr: true });
|
|
29
|
+
const optionHeight = isWideScreen ? OPTION_HEIGHT : PHONE_OPTION_HEIGHT;
|
|
30
|
+
const listHeight = Math.min(pageOptions.length * optionHeight, LISTBOX_MAX_HEIGHT);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const pageIndexes = /* @__PURE__ */ new Map();
|
|
33
|
+
pageOptions.forEach(([, pageNumber], pageIndex) => pageIndexes.set(pageNumber, pageIndex));
|
|
34
|
+
pageIndexesRef.current = pageIndexes;
|
|
35
|
+
}, [pageOptions, pageIndexesRef]);
|
|
36
|
+
const placedListElementsRef = useRef(/* @__PURE__ */ new WeakSet());
|
|
37
|
+
const keepListApi = (listApi) => {
|
|
38
|
+
pageListRef.current = listApi;
|
|
39
|
+
const listElement = listApi?.element;
|
|
40
|
+
if (!listElement || placedListElementsRef.current.has(listElement)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
placedListElementsRef.current.add(listElement);
|
|
44
|
+
if (pageOptions.length !== pageCount) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const selectedIndex = pageOptions.findIndex(([optionProps]) => optionProps["aria-selected"] === true);
|
|
48
|
+
if (selectedIndex >= 0) {
|
|
49
|
+
listApi.scrollToRow({ index: selectedIndex, align: "center" });
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
return /* @__PURE__ */ jsx("div", { ref, ...listboxProps, children: /* @__PURE__ */ jsx(
|
|
53
|
+
List,
|
|
54
|
+
{
|
|
55
|
+
role: "none",
|
|
56
|
+
className,
|
|
57
|
+
listRef: keepListApi,
|
|
58
|
+
rowCount: pageOptions.length,
|
|
59
|
+
rowHeight: optionHeight,
|
|
60
|
+
rowComponent: PageOption,
|
|
61
|
+
rowProps: { pageOptions },
|
|
62
|
+
style: { height: listHeight + 2 * LISTBOX_PADDING, width: "100%", boxSizing: "border-box" },
|
|
63
|
+
overscanCount: OVERSCAN_ROWS,
|
|
64
|
+
tagName: "ul"
|
|
65
|
+
},
|
|
66
|
+
pageOptions.length
|
|
67
|
+
) });
|
|
23
68
|
}
|
|
24
|
-
function
|
|
69
|
+
function GoToPageContent(props) {
|
|
25
70
|
const { page, pageCount, onChange, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
26
71
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
27
72
|
const { t } = useToolkitTranslation("table", texts);
|
|
28
73
|
const { formatNumber } = useFormatters();
|
|
74
|
+
const pageNumbers = useMemo(() => pageNumbersOf(pageCount), [pageCount]);
|
|
75
|
+
const pageListRef = useRef(null);
|
|
76
|
+
const pageIndexesRef = useRef(/* @__PURE__ */ new Map());
|
|
29
77
|
if (pageCount <= 1) {
|
|
30
78
|
return null;
|
|
31
79
|
}
|
|
32
|
-
const
|
|
80
|
+
const scrollToHighlightedPage = (event, highlightedPageNumber) => {
|
|
81
|
+
const highlightedIndex = pageIndexesRef.current.get(highlightedPageNumber);
|
|
82
|
+
if (highlightedIndex !== void 0) {
|
|
83
|
+
pageListRef.current?.scrollToRow({ index: highlightedIndex, align: "auto" });
|
|
84
|
+
}
|
|
85
|
+
};
|
|
33
86
|
return /* @__PURE__ */ jsxs(GoToRoot, { direction: "row", spacing: 0.75, ownSx: { alignItems: "baseline" }, children: [
|
|
34
87
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", noWrap: true, children: t("goToPage.page") }),
|
|
35
88
|
/* @__PURE__ */ jsx(
|
|
@@ -37,6 +90,7 @@ function GoToPage(props) {
|
|
|
37
90
|
{
|
|
38
91
|
size: "small",
|
|
39
92
|
disableClearable: true,
|
|
93
|
+
disableListWrap: true,
|
|
40
94
|
openOnFocus: true,
|
|
41
95
|
autoHighlight: true,
|
|
42
96
|
options: pageNumbers,
|
|
@@ -44,13 +98,15 @@ function GoToPage(props) {
|
|
|
44
98
|
value: page + 1,
|
|
45
99
|
isOptionEqualToValue: (option, selectedValue) => option === selectedValue,
|
|
46
100
|
getOptionLabel: (option) => String(option),
|
|
101
|
+
renderOption: (optionProps, pageNumber) => [optionProps, pageNumber],
|
|
102
|
+
onHighlightChange: scrollToHighlightedPage,
|
|
47
103
|
onChange: (event, selectedPageNumber) => {
|
|
48
104
|
if (selectedPageNumber !== null && selectedPageNumber - 1 !== page) {
|
|
49
105
|
onChange(selectedPageNumber - 1);
|
|
50
106
|
}
|
|
51
107
|
},
|
|
52
108
|
ownSx: { width: 78, "& .MuiAutocomplete-endAdornment": { right: 0 } },
|
|
53
|
-
slotProps: { listbox: {
|
|
109
|
+
slotProps: { listbox: { component: PageListbox, pageCount, pageListRef, pageIndexesRef } },
|
|
54
110
|
renderInput: (params) => /* @__PURE__ */ jsx(
|
|
55
111
|
TextField,
|
|
56
112
|
{
|
|
@@ -64,6 +120,7 @@ function GoToPage(props) {
|
|
|
64
120
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", noWrap: true, children: t("goToPage.of", { count: pageCount, total: formatNumber(pageCount) }) })
|
|
65
121
|
] });
|
|
66
122
|
}
|
|
123
|
+
const GoToPage = withPieceSlots(GoToPageContent, THEME_NAME);
|
|
67
124
|
export {
|
|
68
125
|
GoToPage as default
|
|
69
126
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoToPage.js","sources":["../../src/DataTable/GoToPage.jsx"],"sourcesContent":["// \"Ir a la página N\", como un selector con búsqueda.\n//\n// Con cientos de páginas, llegar a la 137 a punta de flechita no es navegar. Un Autocomplete dice las tres cosas sin\n// explicarlas: se abre y se ve la lista, se teclea y se filtra, se elige y ya.\n//\n// Tres detalles:\n// 1. la lista se recorta a RENDER_LIMIT opciones en el DOM; lo demás se alcanza tecleando;\n// 2. filtra por PREFIJO primero (teclear 13 da 13, 130, 131...) y luego por \"contiene\";\n// 3. con una sola página no se pinta: sería un control que no lleva a ningún lado.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaGoToPage con defaultProps y\n// styleOverrides de sus partes: root, field.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaGoToPage)\nconst THEME_NAME = 'CalcitaGoToPage';\nconst GoToRoot = piecePart(THEME_NAME, 'Root', Stack);\nconst GoToField = piecePart(THEME_NAME, 'Field', Autocomplete);\n\n// tope del DOM, no de la navegación\nconst RENDER_LIMIT = 100;\n\nfunction filterPages(pageNumbers, {inputValue}) {\n const typedText = inputValue.trim();\n if (!typedText) {\n return pageNumbers.slice(0, RENDER_LIMIT);\n }\n const startingWith = pageNumbers.filter((pageNumber) => String(pageNumber).startsWith(typedText));\n const containing = pageNumbers.filter((pageNumber) => !String(pageNumber).startsWith(typedText) && String(pageNumber).includes(typedText));\n return [...startingWith, ...containing].slice(0, RENDER_LIMIT);\n}\n\n/**\n * @param {object} props\n * @param {number} props.page cuenta desde 0\n * @param {number} props.pageCount\n * @param {(page: number) => void} props.onChange\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nexport default function GoToPage(props) {\n // lo que el proyecto puso en su tema (components.CalcitaGoToPage.defaultProps) y encima lo que llega aquí\n const {page, pageCount, onChange, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const {formatNumber} = useFormatters();\n\n // guard clause: con una página no hay a dónde ir\n if (pageCount <= 1) {\n return null;\n }\n\n // la persona cuenta desde 1 y el estado de la tabla desde 0: la conversión vive AQUÍ y en ningún otro lado\n const pageNumbers = Array.from({length: pageCount}, (unused, position) => position + 1);\n\n return (\n <GoToRoot direction=\"row\" spacing={0.75} ownSx={{alignItems: 'baseline'}}>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>{t('goToPage.page')}</Typography>\n <GoToField\n size=\"small\"\n disableClearable\n openOnFocus\n autoHighlight\n options={pageNumbers}\n filterOptions={filterPages}\n value={page + 1}\n isOptionEqualToValue={(option, selectedValue) => option === selectedValue}\n getOptionLabel={(option) => String(option)}\n onChange={(event, selectedPageNumber) => {\n if (selectedPageNumber !== null && selectedPageNumber - 1 !== page) {\n onChange(selectedPageNumber - 1);\n }\n }}\n ownSx={{width: 78, '& .MuiAutocomplete-endAdornment': {right: 0}}}\n slotProps={{listbox: {sx: {maxHeight: 240}}}}\n renderInput={(params) => (\n <TextField {...params} variant=\"standard\"\n slotProps={{htmlInput: {...params.inputProps, inputMode: 'numeric', 'aria-label': t('goToPage.ariaLabel')}}} />\n )}\n />\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {t('goToPage.of', {count: pageCount, total: formatNumber(pageCount)})}\n </Typography>\n </GoToRoot>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,WAAW,UAAU,YAAY,QAAQ,KAAK;AACpD,MAAM,YAAY,UAAU,YAAY,SAAS,YAAY;AAG7D,MAAM,eAAe;AAErB,SAAS,YAAY,aAAa,EAAC,cAAa;AAC5C,QAAM,YAAY,WAAW,KAAA;AAC7B,MAAI,CAAC,WAAW;AACZ,WAAO,YAAY,MAAM,GAAG,YAAY;AAAA,EAC5C;AACA,QAAM,eAAe,YAAY,OAAO,CAAC,eAAe,OAAO,UAAU,EAAE,WAAW,SAAS,CAAC;AAChG,QAAM,aAAa,YAAY,OAAO,CAAC,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,SAAS,KAAK,OAAO,UAAU,EAAE,SAAS,SAAS,CAAC;AACzI,SAAO,CAAC,GAAG,cAAc,GAAG,UAAU,EAAE,MAAM,GAAG,YAAY;AACjE;AASA,SAAwB,SAAS,OAAO;AAEpC,QAAM,EAAC,MAAM,WAAW,UAAU,OAAO,GAAG,iBAAgB,cAAc,OAAO,UAAU;AAC3F,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS,KAAK;AAChD,QAAM,EAAC,aAAA,IAAgB,cAAA;AAGvB,MAAI,aAAa,GAAG;AAChB,WAAO;AAAA,EACX;AAGA,QAAM,cAAc,MAAM,KAAK,EAAC,QAAQ,UAAA,GAAY,CAAC,QAAQ,aAAa,WAAW,CAAC;AAEtF,SACI,qBAAC,UAAA,EAAS,WAAU,OAAM,SAAS,MAAM,OAAO,EAAC,YAAY,WAAA,GACzD,UAAA;AAAA,IAAA,oBAAC,YAAA,EAAW,SAAQ,SAAQ,OAAM,kBAAiB,QAAM,MAAE,UAAA,EAAE,eAAe,EAAA,CAAE;AAAA,IAC9E;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,MAAK;AAAA,QACL,kBAAgB;AAAA,QAChB,aAAW;AAAA,QACX,eAAa;AAAA,QACb,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,OAAO;AAAA,QACd,sBAAsB,CAAC,QAAQ,kBAAkB,WAAW;AAAA,QAC5D,gBAAgB,CAAC,WAAW,OAAO,MAAM;AAAA,QACzC,UAAU,CAAC,OAAO,uBAAuB;AACrC,cAAI,uBAAuB,QAAQ,qBAAqB,MAAM,MAAM;AAChE,qBAAS,qBAAqB,CAAC;AAAA,UACnC;AAAA,QACJ;AAAA,QACA,OAAO,EAAC,OAAO,IAAI,mCAAmC,EAAC,OAAO,IAAC;AAAA,QAC/D,WAAW,EAAC,SAAS,EAAC,IAAI,EAAC,WAAW,IAAA,IAAI;AAAA,QAC1C,aAAa,CAAC,WACV;AAAA,UAAC;AAAA,UAAA;AAAA,YAAW,GAAG;AAAA,YAAQ,SAAQ;AAAA,YACpB,WAAW,EAAC,WAAW,EAAC,GAAG,OAAO,YAAY,WAAW,WAAW,cAAc,EAAE,oBAAoB,IAAC;AAAA,UAAC;AAAA,QAAA;AAAA,MAAG;AAAA,IAAA;AAAA,wBAG/H,YAAA,EAAW,SAAQ,SAAQ,OAAM,kBAAiB,QAAM,MACpD,UAAA,EAAE,eAAe,EAAC,OAAO,WAAW,OAAO,aAAa,SAAS,EAAA,CAAE,EAAA,CACxE;AAAA,EAAA,GACJ;AAER;"}
|
|
1
|
+
{"version":3,"file":"GoToPage.js","sources":["../../src/DataTable/GoToPage.jsx"],"sourcesContent":["// \"Ir a la página N\", como un selector con búsqueda.\n//\n// Con cientos de páginas, llegar a la 137 a punta de flechita no es navegar. Un Autocomplete dice las tres cosas sin\n// explicarlas: se abre y se ve la lista, se teclea y se filtra, se elige y ya.\n//\n// Cuatro detalles:\n// 1. la lista trae TODAS las páginas, pero pinta solo las que se ven (react-window, el «Virtualization» de la\n// documentación del Autocomplete de MUI): con decenas de miles de páginas abre igual de rápido y se desliza hasta la\n// última. Antes se cortaba en 100 y la 101 solo se alcanzaba tecleando;\n// 2. abre en la página donde está la tabla, no en la 1;\n// 3. filtra por PREFIJO primero (teclear 13 da 13, 130, 131...) y luego por \"contiene\" (goToPageOptions.js);\n// 4. con una sola página no se pinta: sería un control que no lleva a ningún lado.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaGoToPage con defaultProps y\n// styleOverrides de sus partes: root, field.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useMemo, useRef} from 'react';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\nimport {List} from 'react-window';\n\nimport {filterPages, pageNumbersOf} from '@/DataTable/goToPageOptions.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaGoToPage)\nconst THEME_NAME = 'CalcitaGoToPage';\nconst GoToRoot = piecePart(THEME_NAME, 'Root', Stack);\nconst GoToField = piecePart(THEME_NAME, 'Field', Autocomplete);\n\n// alto de cada página en la lista: el de una opción de MUI, 36 px desde «sm» y 48 en el teléfono (MUI les da 48 de alto\n// mínimo ahí). OJO: react-window acomoda cada renglón con este número; si no es el alto real, se encimarían\nconst OPTION_HEIGHT = 36;\nconst PHONE_OPTION_HEIGHT = 48;\n// lo más alto que crece la lista y el margen de arriba y abajo que MUI les da a sus listas\nconst LISTBOX_MAX_HEIGHT = 240;\nconst LISTBOX_PADDING = 8;\n// renglones de más que se pintan arriba y abajo de lo visible, para que no parpadee al deslizar\nconst OVERSCAN_ROWS = 5;\n\n/**\n * Un renglón de la lista: la opción que armó MUI (role=\"option\", resaltado, clic) acomodada donde dice react-window.\n *\n * @param {{index: number, style: object, pageOptions: Array<[object, number]>}} props\n */\nfunction PageOption({index, style, pageOptions}) {\n const [{key, ...optionProps}, pageNumber] = pageOptions[index];\n\n return (\n <Typography key={key} component=\"li\" {...optionProps} noWrap style={{...style, top: (style.top ?? 0) + LISTBOX_PADDING}}>\n {pageNumber}\n </Typography>\n );\n}\n\n/**\n * La lista del Autocomplete con react-window (el adaptador de la documentación de MUI).\n *\n * MUI le pasa sus props de lista (role=\"listbox\", id, eventos) y cada opción ya armada como [props, página] (ver\n * renderOption en GoToPage). Al abrir, se acomoda en la página elegida.\n *\n * @param {object} props\n * @param {Array<[object, number]>} props.children las opciones ya armadas por MUI\n * @param {import('react').Ref<HTMLDivElement>} [props.ref]\n * @param {number} props.pageCount cuántas páginas tiene la tabla: con todas en la lista, nadie ha tecleado\n * @param {{current: object|null}} props.pageListRef la API de react-window, para deslizar hasta una página\n * @param {{current: Map<number, number>}} props.pageIndexesRef se llena con página → lugar en la lista, para seguir con el\n * teclado a la resaltada\n * @param {string} [props.className]\n */\nfunction PageListbox({children: pageOptions, ref, pageCount, pageListRef, pageIndexesRef, className, style, ...listboxProps}) {\n const isWideScreen = useMediaQuery((theme) => theme.breakpoints.up('sm'), {noSsr: true});\n const optionHeight = isWideScreen ? OPTION_HEIGHT : PHONE_OPTION_HEIGHT;\n const listHeight = Math.min(pageOptions.length * optionHeight, LISTBOX_MAX_HEIGHT);\n\n // dónde quedó cada página en la lista filtrada\n useEffect(() => {\n const pageIndexes = new Map();\n pageOptions.forEach(([, pageNumber], pageIndex) => pageIndexes.set(pageNumber, pageIndex));\n pageIndexesRef.current = pageIndexes;\n }, [pageOptions, pageIndexesRef]);\n\n // al abrir sin teclear (la lista trae TODAS las páginas) se acomoda en la página elegida, la opción que MUI marca como\n // seleccionada; tecleando se queda arriba, en la primera que coincide.\n // OJO: no va en un useEffect al montar: en ese momento react-window todavía no guarda su contenedor y scrollToRow no\n // hace nada. Se hace cuando react-window entrega su API ya con el contenedor (listRef como función), una sola vez por\n // lista armada: después no pelea con quien desliza\n const placedListElementsRef = useRef(new WeakSet());\n const keepListApi = (listApi) => {\n pageListRef.current = listApi;\n const listElement = listApi?.element;\n if (!listElement || placedListElementsRef.current.has(listElement)) {\n return;\n }\n placedListElementsRef.current.add(listElement);\n if (pageOptions.length !== pageCount) {\n return;\n }\n const selectedIndex = pageOptions.findIndex(([optionProps]) => optionProps['aria-selected'] === true);\n if (selectedIndex >= 0) {\n listApi.scrollToRow({index: selectedIndex, align: 'center'});\n }\n };\n\n return (\n <div ref={ref} {...listboxProps}>\n <List\n // OJO: react-window le pone role=\"list\" a su contenedor; las opciones tienen que ser de la lista de MUI\n // (role=\"listbox\", el div de afuera) para que un lector de pantalla las anuncie como opciones del selector\n role=\"none\"\n className={className}\n listRef={keepListApi}\n // OJO: otra cantidad de páginas (al teclear) arma la lista de nuevo y la regresa arriba\n key={pageOptions.length}\n rowCount={pageOptions.length}\n rowHeight={optionHeight}\n rowComponent={PageOption}\n rowProps={{pageOptions}}\n style={{height: listHeight + 2 * LISTBOX_PADDING, width: '100%', boxSizing: 'border-box'}}\n overscanCount={OVERSCAN_ROWS}\n tagName=\"ul\"\n />\n </div>\n );\n}\n\n/**\n * @param {object} props\n * @param {number} props.page cuenta desde 0\n * @param {number} props.pageCount\n * @param {(page: number) => void} props.onChange\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nfunction GoToPageContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaGoToPage.defaultProps) y encima lo que llega aquí\n const {page, pageCount, onChange, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const {formatNumber} = useFormatters();\n // la persona cuenta desde 1 y el estado de la tabla desde 0: la conversión vive AQUÍ y en ningún otro lado\n const pageNumbers = useMemo(() => pageNumbersOf(pageCount), [pageCount]);\n const pageListRef = useRef(null);\n const pageIndexesRef = useRef(new Map());\n\n // guard clause: con una página no hay a dónde ir\n if (pageCount <= 1) {\n return null;\n }\n\n // con las flechas del teclado, la lista desliza hasta la página resaltada (react-window no la tiene pintada)\n const scrollToHighlightedPage = (event, highlightedPageNumber) => {\n const highlightedIndex = pageIndexesRef.current.get(highlightedPageNumber);\n if (highlightedIndex !== undefined) {\n pageListRef.current?.scrollToRow({index: highlightedIndex, align: 'auto'});\n }\n };\n\n return (\n <GoToRoot direction=\"row\" spacing={0.75} ownSx={{alignItems: 'baseline'}}>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>{t('goToPage.page')}</Typography>\n <GoToField\n size=\"small\"\n disableClearable\n disableListWrap\n openOnFocus\n autoHighlight\n options={pageNumbers}\n filterOptions={filterPages}\n value={page + 1}\n isOptionEqualToValue={(option, selectedValue) => option === selectedValue}\n getOptionLabel={(option) => String(option)}\n // cada opción viaja armada a PageListbox, que pinta solo las que se ven\n renderOption={(optionProps, pageNumber) => [optionProps, pageNumber]}\n onHighlightChange={scrollToHighlightedPage}\n onChange={(event, selectedPageNumber) => {\n if (selectedPageNumber !== null && selectedPageNumber - 1 !== page) {\n onChange(selectedPageNumber - 1);\n }\n }}\n ownSx={{width: 78, '& .MuiAutocomplete-endAdornment': {right: 0}}}\n slotProps={{listbox: {component: PageListbox, pageCount, pageListRef, pageIndexesRef}}}\n renderInput={(params) => (\n <TextField {...params} variant=\"standard\"\n slotProps={{htmlInput: {...params.inputProps, inputMode: 'numeric', 'aria-label': t('goToPage.ariaLabel')}}} />\n )}\n />\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {t('goToPage.of', {count: pageCount, total: formatNumber(pageCount)})}\n </Typography>\n </GoToRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst GoToPage = withPieceSlots(GoToPageContent, THEME_NAME);\nexport default GoToPage;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAgCA,MAAM,aAAa;AACnB,MAAM,WAAW,UAAU,YAAY,QAAQ,KAAK;AACpD,MAAM,YAAY,UAAU,YAAY,SAAS,YAAY;AAI7D,MAAM,gBAAgB;AACtB,MAAM,sBAAsB;AAE5B,MAAM,qBAAqB;AAC3B,MAAM,kBAAkB;AAExB,MAAM,gBAAgB;AAOtB,SAAS,WAAW,EAAC,OAAO,OAAO,eAAc;AAC7C,QAAM,CAAC,EAAC,KAAK,GAAG,eAAc,UAAU,IAAI,YAAY,KAAK;AAE7D,6BACK,YAAA,EAAqB,WAAU,MAAM,GAAG,aAAa,QAAM,MAAC,OAAO,EAAC,GAAG,OAAO,MAAM,MAAM,OAAO,KAAK,gBAAA,GAClG,wBADY,GAEjB;AAER;AAiBA,SAAS,YAAY,EAAC,UAAU,aAAa,KAAK,WAAW,aAAa,gBAAgB,WAAW,OAAO,GAAG,aAAA,GAAe;AAC1H,QAAM,eAAe,cAAc,CAAC,UAAU,MAAM,YAAY,GAAG,IAAI,GAAG,EAAC,OAAO,KAAA,CAAK;AACvF,QAAM,eAAe,eAAe,gBAAgB;AACpD,QAAM,aAAa,KAAK,IAAI,YAAY,SAAS,cAAc,kBAAkB;AAGjF,YAAU,MAAM;AACZ,UAAM,kCAAkB,IAAA;AACxB,gBAAY,QAAQ,CAAC,CAAA,EAAG,UAAU,GAAG,cAAc,YAAY,IAAI,YAAY,SAAS,CAAC;AACzF,mBAAe,UAAU;AAAA,EAC7B,GAAG,CAAC,aAAa,cAAc,CAAC;AAOhC,QAAM,wBAAwB,OAAO,oBAAI,SAAS;AAClD,QAAM,cAAc,CAAC,YAAY;AAC7B,gBAAY,UAAU;AACtB,UAAM,cAAc,SAAS;AAC7B,QAAI,CAAC,eAAe,sBAAsB,QAAQ,IAAI,WAAW,GAAG;AAChE;AAAA,IACJ;AACA,0BAAsB,QAAQ,IAAI,WAAW;AAC7C,QAAI,YAAY,WAAW,WAAW;AAClC;AAAA,IACJ;AACA,UAAM,gBAAgB,YAAY,UAAU,CAAC,CAAC,WAAW,MAAM,YAAY,eAAe,MAAM,IAAI;AACpG,QAAI,iBAAiB,GAAG;AACpB,cAAQ,YAAY,EAAC,OAAO,eAAe,OAAO,UAAS;AAAA,IAC/D;AAAA,EACJ;AAEA,SACI,oBAAC,OAAA,EAAI,KAAW,GAAG,cACf,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MAGG,MAAK;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MAGT,UAAU,YAAY;AAAA,MACtB,WAAW;AAAA,MACX,cAAc;AAAA,MACd,UAAU,EAAC,YAAA;AAAA,MACX,OAAO,EAAC,QAAQ,aAAa,IAAI,iBAAiB,OAAO,QAAQ,WAAW,aAAA;AAAA,MAC5E,eAAe;AAAA,MACf,SAAQ;AAAA,IAAA;AAAA,IAPH,YAAY;AAAA,EAAA,GASzB;AAER;AASA,SAAS,gBAAgB,OAAO;AAE5B,QAAM,EAAC,MAAM,WAAW,UAAU,OAAO,GAAG,iBAAgB,cAAc,OAAO,UAAU;AAC3F,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,SAAS,KAAK;AAChD,QAAM,EAAC,aAAA,IAAgB,cAAA;AAEvB,QAAM,cAAc,QAAQ,MAAM,cAAc,SAAS,GAAG,CAAC,SAAS,CAAC;AACvE,QAAM,cAAc,OAAO,IAAI;AAC/B,QAAM,iBAAiB,OAAO,oBAAI,KAAK;AAGvC,MAAI,aAAa,GAAG;AAChB,WAAO;AAAA,EACX;AAGA,QAAM,0BAA0B,CAAC,OAAO,0BAA0B;AAC9D,UAAM,mBAAmB,eAAe,QAAQ,IAAI,qBAAqB;AACzE,QAAI,qBAAqB,QAAW;AAChC,kBAAY,SAAS,YAAY,EAAC,OAAO,kBAAkB,OAAO,QAAO;AAAA,IAC7E;AAAA,EACJ;AAEA,SACI,qBAAC,UAAA,EAAS,WAAU,OAAM,SAAS,MAAM,OAAO,EAAC,YAAY,WAAA,GACzD,UAAA;AAAA,IAAA,oBAAC,YAAA,EAAW,SAAQ,SAAQ,OAAM,kBAAiB,QAAM,MAAE,UAAA,EAAE,eAAe,EAAA,CAAE;AAAA,IAC9E;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,MAAK;AAAA,QACL,kBAAgB;AAAA,QAChB,iBAAe;AAAA,QACf,aAAW;AAAA,QACX,eAAa;AAAA,QACb,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,OAAO;AAAA,QACd,sBAAsB,CAAC,QAAQ,kBAAkB,WAAW;AAAA,QAC5D,gBAAgB,CAAC,WAAW,OAAO,MAAM;AAAA,QAEzC,cAAc,CAAC,aAAa,eAAe,CAAC,aAAa,UAAU;AAAA,QACnE,mBAAmB;AAAA,QACnB,UAAU,CAAC,OAAO,uBAAuB;AACrC,cAAI,uBAAuB,QAAQ,qBAAqB,MAAM,MAAM;AAChE,qBAAS,qBAAqB,CAAC;AAAA,UACnC;AAAA,QACJ;AAAA,QACA,OAAO,EAAC,OAAO,IAAI,mCAAmC,EAAC,OAAO,IAAC;AAAA,QAC/D,WAAW,EAAC,SAAS,EAAC,WAAW,aAAa,WAAW,aAAa,iBAAc;AAAA,QACpF,aAAa,CAAC,WACV;AAAA,UAAC;AAAA,UAAA;AAAA,YAAW,GAAG;AAAA,YAAQ,SAAQ;AAAA,YACpB,WAAW,EAAC,WAAW,EAAC,GAAG,OAAO,YAAY,WAAW,WAAW,cAAc,EAAE,oBAAoB,IAAC;AAAA,UAAC;AAAA,QAAA;AAAA,MAAG;AAAA,IAAA;AAAA,wBAG/H,YAAA,EAAW,SAAQ,SAAQ,OAAM,kBAAiB,QAAM,MACpD,UAAA,EAAE,eAAe,EAAC,OAAO,WAAW,OAAO,aAAa,SAAS,EAAA,CAAE,EAAA,CACxE;AAAA,EAAA,GACJ;AAER;AAGA,MAAM,WAAW,eAAe,iBAAiB,UAAU;"}
|