@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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import Typography from "@mui/material/Typography";
|
|
4
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
5
|
+
import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
|
|
6
|
+
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
7
|
+
import { countdownClockOf } from "./countdownParts.js";
|
|
8
|
+
import { useCountdown } from "./useCountdown.js";
|
|
9
|
+
const THEME_NAME = "CalcitaCountdown";
|
|
10
|
+
const CountdownRoot = piecePart(THEME_NAME, "Root", Typography);
|
|
11
|
+
function CountdownContent(props) {
|
|
12
|
+
const {
|
|
13
|
+
until,
|
|
14
|
+
label,
|
|
15
|
+
onComplete,
|
|
16
|
+
completedText,
|
|
17
|
+
showSeconds = true,
|
|
18
|
+
children,
|
|
19
|
+
variant = "body1",
|
|
20
|
+
sx,
|
|
21
|
+
texts,
|
|
22
|
+
...unknownProps
|
|
23
|
+
} = usePieceProps(props, THEME_NAME);
|
|
24
|
+
warnUnknownProps(THEME_NAME, unknownProps);
|
|
25
|
+
const { t } = useToolkitTranslation("common", texts);
|
|
26
|
+
const { parts, isOver } = useCountdown(until, { onComplete });
|
|
27
|
+
if (typeof children === "function") {
|
|
28
|
+
return children(parts);
|
|
29
|
+
}
|
|
30
|
+
if (isOver) {
|
|
31
|
+
return /* @__PURE__ */ jsx(CountdownRoot, { variant, role: "status", ownSx: { fontVariantNumeric: "tabular-nums" }, sx, children: completedText ?? t("countdown.done") });
|
|
32
|
+
}
|
|
33
|
+
return /* @__PURE__ */ jsx(CountdownRoot, { variant, role: "timer", "aria-label": label, ownSx: { fontVariantNumeric: "tabular-nums" }, sx, children: countdownClockOf(parts, { daysLabel: t("countdown.daysShort"), showSeconds }) });
|
|
34
|
+
}
|
|
35
|
+
const Countdown = withPieceSlots(CountdownContent, THEME_NAME);
|
|
36
|
+
export {
|
|
37
|
+
Countdown as default
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=Countdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Countdown.js","sources":["../../../src/ui/countdown/Countdown.jsx"],"sourcesContent":["// La cuenta regresiva ya pintada: «02:14:30» hasta un momento (el cierre de unas inscripciones, el inicio de una cita, el fin de\n// una oferta), con días cuando faltan («3 d 02:14:30»), y lo que dice al llegar a cero («Ya terminó»). Avisa con onComplete\n// una sola vez.\n//\n// Para un lector de pantalla es un temporizador (role=\"timer\"): no anuncia cada segundo, sí el final (role=\"status\").\n// Con children como función se pinta a su manera: children(parts) recibe {days, hours, minutes, seconds, isOver}.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaCountdown con defaultProps y\n// styleOverrides de su parte root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Typography from '@mui/material/Typography';\n\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {countdownClockOf} from '@/ui/countdown/countdownParts.js';\nimport {useCountdown} from '@/ui/countdown/useCountdown.js';\n\n// el nombre de la pieza en el tema y su parte (theme.components.CalcitaCountdown)\nconst THEME_NAME = 'CalcitaCountdown';\nconst CountdownRoot = piecePart(THEME_NAME, 'Root', Typography);\n\n/**\n * @param {object} props\n * @param {string|number|Date} props.until el momento: un instante en texto, un Date o milisegundos\n * @param {string} [props.label] ya traducido: qué se cuenta («Tiempo para que cierren las inscripciones»), para un lector de pantalla\n * @param {() => void} [props.onComplete] al llegar a cero (una vez)\n * @param {import('react').ReactNode} [props.completedText] lo que dice al terminar; por omisión «Ya terminó»\n * @param {boolean} [props.showSeconds] por omisión, sí\n * @param {(parts: {days: number, hours: number, minutes: number, seconds: number, totalSeconds: number, isOver: boolean}) => import('react').ReactNode} [props.children]\n * para pintarla a su manera\n * @param {import('@mui/material/Typography').TypographyProps['variant']} [props.variant] por omisión body1\n * @param {object} [props.sx]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction CountdownContent(props) {\n const {\n until, label, onComplete, completedText, showSeconds = true, children, variant = 'body1', sx, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {parts, isOver} = useCountdown(until, {onComplete});\n\n if (typeof children === 'function') {\n return children(parts);\n }\n if (isOver) {\n return (\n <CountdownRoot variant={variant} role=\"status\" ownSx={{fontVariantNumeric: 'tabular-nums'}} sx={sx}>\n {completedText ?? t('countdown.done')}\n </CountdownRoot>\n );\n }\n return (\n <CountdownRoot variant={variant} role=\"timer\" aria-label={label} ownSx={{fontVariantNumeric: 'tabular-nums'}} sx={sx}>\n {countdownClockOf(parts, {daysLabel: t('countdown.daysShort'), showSeconds})}\n </CountdownRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst Countdown = withPieceSlots(CountdownContent, THEME_NAME);\nexport default Countdown;\n"],"names":[],"mappings":";;;;;;;;AAoBA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,QAAQ,UAAU;AAe9D,SAAS,iBAAiB,OAAO;AAC7B,QAAM;AAAA,IACF;AAAA,IAAO;AAAA,IAAO;AAAA,IAAY;AAAA,IAAe,cAAc;AAAA,IAAM;AAAA,IAAU,UAAU;AAAA,IAAS;AAAA,IAAI;AAAA,IAC9F,GAAG;AAAA,EAAA,IACH,cAAc,OAAO,UAAU;AACnC,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,OAAO,OAAA,IAAU,aAAa,OAAO,EAAC,YAAW;AAExD,MAAI,OAAO,aAAa,YAAY;AAChC,WAAO,SAAS,KAAK;AAAA,EACzB;AACA,MAAI,QAAQ;AACR,WACI,oBAAC,eAAA,EAAc,SAAkB,MAAK,UAAS,OAAO,EAAC,oBAAoB,eAAA,GAAiB,IACvF,UAAA,iBAAiB,EAAE,gBAAgB,GACxC;AAAA,EAER;AACA,SACI,oBAAC,iBAAc,SAAkB,MAAK,SAAQ,cAAY,OAAO,OAAO,EAAC,oBAAoB,kBAAiB,IACzG,UAAA,iBAAiB,OAAO,EAAC,WAAW,EAAE,qBAAqB,GAAG,YAAA,CAAY,GAC/E;AAER;AAGA,MAAM,YAAY,eAAe,kBAAkB,UAAU;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const MILLISECONDS_PER_SECOND = 1e3;
|
|
2
|
+
const SECONDS_PER_MINUTE = 60;
|
|
3
|
+
const SECONDS_PER_HOUR = 3600;
|
|
4
|
+
const SECONDS_PER_DAY = 86400;
|
|
5
|
+
const TWO_DIGITS = 2;
|
|
6
|
+
function instantMillisecondsOf(until) {
|
|
7
|
+
if (until instanceof Date) {
|
|
8
|
+
return until.getTime();
|
|
9
|
+
}
|
|
10
|
+
return typeof until === "number" ? until : Date.parse(until);
|
|
11
|
+
}
|
|
12
|
+
function countdownPartsOf(until, now) {
|
|
13
|
+
const remainingMilliseconds = instantMillisecondsOf(until) - now;
|
|
14
|
+
const totalSeconds = Number.isFinite(remainingMilliseconds) && remainingMilliseconds > 0 ? Math.ceil(remainingMilliseconds / MILLISECONDS_PER_SECOND) : 0;
|
|
15
|
+
return {
|
|
16
|
+
days: Math.floor(totalSeconds / SECONDS_PER_DAY),
|
|
17
|
+
hours: Math.floor(totalSeconds % SECONDS_PER_DAY / SECONDS_PER_HOUR),
|
|
18
|
+
minutes: Math.floor(totalSeconds % SECONDS_PER_HOUR / SECONDS_PER_MINUTE),
|
|
19
|
+
seconds: totalSeconds % SECONDS_PER_MINUTE,
|
|
20
|
+
totalSeconds,
|
|
21
|
+
isOver: totalSeconds === 0
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function countdownClockOf({ days, hours, minutes, seconds }, { daysLabel = "d", showSeconds = true } = {}) {
|
|
25
|
+
const twoDigits = (value) => String(value).padStart(TWO_DIGITS, "0");
|
|
26
|
+
const clock = [hours, minutes, ...showSeconds ? [seconds] : []].map(twoDigits).join(":");
|
|
27
|
+
return days > 0 ? `${days} ${daysLabel} ${clock}` : clock;
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
countdownClockOf,
|
|
31
|
+
countdownPartsOf,
|
|
32
|
+
instantMillisecondsOf
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=countdownParts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"countdownParts.js","sources":["../../../src/ui/countdown/countdownParts.js"],"sourcesContent":["// Cuánto falta para un momento (el cierre de unas inscripciones, el inicio de una cita, el fin de una oferta), en días, horas,\n// minutos y segundos, y cómo se escribe como reloj. Lo usan useCountdown y Countdown.\n//\n// Puro (sin React): se prueba con node (countdownParts.test.js).\n//\n// Genérico del paquete: function (regla de la casa).\n\nconst MILLISECONDS_PER_SECOND = 1000;\nconst SECONDS_PER_MINUTE = 60;\nconst SECONDS_PER_HOUR = 3600;\nconst SECONDS_PER_DAY = 86_400;\nconst TWO_DIGITS = 2;\n\n/**\n * El momento en milisegundos: un instante en texto ('2026-11-01T18:30:00Z'), un Date o milisegundos.\n *\n * @param {string|number|Date} until\n * @returns {number} NaN si no se entiende\n */\nexport function instantMillisecondsOf(until) {\n if (until instanceof Date) {\n return until.getTime();\n }\n return typeof until === 'number' ? until : Date.parse(until);\n}\n\n/**\n * Lo que falta, partido. Ya pasado (o un momento que no se entiende) es todo en cero con isOver.\n *\n * @param {string|number|Date} until\n * @param {number} now milisegundos de ahora (Date.now())\n * @returns {{days: number, hours: number, minutes: number, seconds: number, totalSeconds: number, isOver: boolean}}\n */\nexport function countdownPartsOf(until, now) {\n const remainingMilliseconds = instantMillisecondsOf(until) - now;\n // se redondea hacia arriba: con 0.4 s por delante todavía dice 00:00:01 y no «ya terminó» antes de tiempo\n const totalSeconds = Number.isFinite(remainingMilliseconds) && remainingMilliseconds > 0\n ? Math.ceil(remainingMilliseconds / MILLISECONDS_PER_SECOND)\n : 0;\n return {\n days: Math.floor(totalSeconds / SECONDS_PER_DAY),\n hours: Math.floor((totalSeconds % SECONDS_PER_DAY) / SECONDS_PER_HOUR),\n minutes: Math.floor((totalSeconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE),\n seconds: totalSeconds % SECONDS_PER_MINUTE,\n totalSeconds,\n isOver: totalSeconds === 0,\n };\n}\n\n/**\n * Lo que falta como reloj: «02:14:30»; con días, «3 d 02:14:30» (la letra del día la da el idioma); sin segundos,\n * «02:14».\n *\n * @param {{days: number, hours: number, minutes: number, seconds: number}} parts\n * @param {{daysLabel?: string, showSeconds?: boolean}} [options] daysLabel: la abreviatura de días ya traducida ('d')\n * @returns {string}\n */\nexport function countdownClockOf({days, hours, minutes, seconds}, {daysLabel = 'd', showSeconds = true} = {}) {\n const twoDigits = (value) => String(value).padStart(TWO_DIGITS, '0');\n const clock = [hours, minutes, ...(showSeconds ? [seconds] : [])].map(twoDigits).join(':');\n return days > 0 ? `${days} ${daysLabel} ${clock}` : clock;\n}\n"],"names":[],"mappings":"AAOA,MAAM,0BAA0B;AAChC,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,aAAa;AAQZ,SAAS,sBAAsB,OAAO;AACzC,MAAI,iBAAiB,MAAM;AACvB,WAAO,MAAM,QAAO;AAAA,EACxB;AACA,SAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,MAAM,KAAK;AAC/D;AASO,SAAS,iBAAiB,OAAO,KAAK;AACzC,QAAM,wBAAwB,sBAAsB,KAAK,IAAI;AAE7D,QAAM,eAAe,OAAO,SAAS,qBAAqB,KAAK,wBAAwB,IACjF,KAAK,KAAK,wBAAwB,uBAAuB,IACzD;AACN,SAAO;AAAA,IACH,MAAM,KAAK,MAAM,eAAe,eAAe;AAAA,IAC/C,OAAO,KAAK,MAAO,eAAe,kBAAmB,gBAAgB;AAAA,IACrE,SAAS,KAAK,MAAO,eAAe,mBAAoB,kBAAkB;AAAA,IAC1E,SAAS,eAAe;AAAA,IACxB;AAAA,IACA,QAAQ,iBAAiB;AAAA,EACjC;AACA;AAUO,SAAS,iBAAiB,EAAC,MAAM,OAAO,SAAS,QAAO,GAAG,EAAC,YAAY,KAAK,cAAc,KAAI,IAAI,CAAA,GAAI;AAC1G,QAAM,YAAY,CAAC,UAAU,OAAO,KAAK,EAAE,SAAS,YAAY,GAAG;AACnE,QAAM,QAAQ,CAAC,OAAO,SAAS,GAAI,cAAc,CAAC,OAAO,IAAI,CAAA,CAAG,EAAE,IAAI,SAAS,EAAE,KAAK,GAAG;AACzF,SAAO,OAAO,IAAI,GAAG,IAAI,IAAI,SAAS,IAAI,KAAK,KAAK;AACxD;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useRef, useEffect } from "react";
|
|
3
|
+
import { countdownPartsOf } from "./countdownParts.js";
|
|
4
|
+
const TICK_MILLISECONDS = 1e3;
|
|
5
|
+
function useCountdown(until, { onComplete, now = Date.now } = {}) {
|
|
6
|
+
const [parts, setParts] = useState(() => countdownPartsOf(until, now()));
|
|
7
|
+
const latest = useRef({ onComplete, now });
|
|
8
|
+
latest.current = { onComplete, now };
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
let hasCompleted = false;
|
|
11
|
+
const tick = () => {
|
|
12
|
+
const current = countdownPartsOf(until, latest.current.now());
|
|
13
|
+
setParts(current);
|
|
14
|
+
if (current.isOver && !hasCompleted) {
|
|
15
|
+
hasCompleted = true;
|
|
16
|
+
latest.current.onComplete?.();
|
|
17
|
+
}
|
|
18
|
+
return current.isOver;
|
|
19
|
+
};
|
|
20
|
+
if (tick()) {
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
23
|
+
const timer = setInterval(() => {
|
|
24
|
+
if (tick()) {
|
|
25
|
+
clearInterval(timer);
|
|
26
|
+
}
|
|
27
|
+
}, TICK_MILLISECONDS);
|
|
28
|
+
return () => clearInterval(timer);
|
|
29
|
+
}, [until]);
|
|
30
|
+
return { parts, isOver: parts.isOver };
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
useCountdown
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=useCountdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCountdown.js","sources":["../../../src/ui/countdown/useCountdown.js"],"sourcesContent":["// Cuánto falta para un momento, al día cada segundo, y avisar una sola vez al llegar a cero (onComplete). Para pintar la\n// cuenta a su manera; Countdown es la que ya viene pintada.\n//\n// const {parts, isOver} = useCountdown(registration.closes_at, {onComplete: reloadRegistration});\n//\n// Mientras ya terminó no corre ningún reloj de fondo, y al desmontar se apaga.\n//\n// Hook genérico: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\n\nimport {countdownPartsOf} from '@/ui/countdown/countdownParts.js';\n\nconst TICK_MILLISECONDS = 1000;\n\n/**\n * @param {string|number|Date} until el momento: un instante en texto, un Date o milisegundos\n * @param {{onComplete?: () => void, now?: () => number}} [options] onComplete: al llegar a cero (una vez); now: el reloj\n * (para probar con una hora fija)\n * @returns {{parts: ReturnType<typeof countdownPartsOf>, isOver: boolean}}\n */\nexport function useCountdown(until, {onComplete, now = Date.now} = {}) {\n const [parts, setParts] = useState(() => countdownPartsOf(until, now()));\n // lo último de afuera, sin rearmar el reloj cada vez que la pantalla pinta otra función\n const latest = useRef({onComplete, now});\n latest.current = {onComplete, now};\n\n useEffect(() => {\n let hasCompleted = false;\n const tick = () => {\n const current = countdownPartsOf(until, latest.current.now());\n setParts(current);\n if (current.isOver && !hasCompleted) {\n hasCompleted = true;\n latest.current.onComplete?.();\n }\n return current.isOver;\n };\n // ya terminó al llegar: se avisa y no se arma el reloj\n if (tick()) {\n return undefined;\n }\n const timer = setInterval(() => {\n if (tick()) {\n clearInterval(timer);\n }\n }, TICK_MILLISECONDS);\n return () => clearInterval(timer);\n }, [until]);\n\n return {parts, isOver: parts.isOver};\n}\n"],"names":[],"mappings":";;;AAYA,MAAM,oBAAoB;AAQnB,SAAS,aAAa,OAAO,EAAC,YAAY,MAAM,KAAK,IAAG,IAAI,IAAI;AACnE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,MAAM,iBAAiB,OAAO,IAAG,CAAE,CAAC;AAEvE,QAAM,SAAS,OAAO,EAAC,YAAY,IAAG,CAAC;AACvC,SAAO,UAAU,EAAC,YAAY,IAAG;AAEjC,YAAU,MAAM;AACZ,QAAI,eAAe;AACnB,UAAM,OAAO,MAAM;AACf,YAAM,UAAU,iBAAiB,OAAO,OAAO,QAAQ,KAAK;AAC5D,eAAS,OAAO;AAChB,UAAI,QAAQ,UAAU,CAAC,cAAc;AACjC,uBAAe;AACf,eAAO,QAAQ,aAAU;AAAA,MAC7B;AACA,aAAO,QAAQ;AAAA,IACnB;AAEA,QAAI,KAAI,GAAI;AACR,aAAO;AAAA,IACX;AACA,UAAM,QAAQ,YAAY,MAAM;AAC5B,UAAI,KAAI,GAAI;AACR,sBAAc,KAAK;AAAA,MACvB;AAAA,IACJ,GAAG,iBAAiB;AACpB,WAAO,MAAM,cAAc,KAAK;AAAA,EACpC,GAAG,CAAC,KAAK,CAAC;AAEV,SAAO,EAAC,OAAO,QAAQ,MAAM,OAAM;AACvC;"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import Button from "@mui/material/Button";
|
|
5
|
+
import Stack from "@mui/material/Stack";
|
|
6
|
+
import Box from "@mui/material/Box";
|
|
7
|
+
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
|
|
8
|
+
import OpenInNewRoundedIcon from "@mui/icons-material/OpenInNewRounded";
|
|
9
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
10
|
+
import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
|
|
11
|
+
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
12
|
+
import ContentDialog from "../layout/ContentDialog.js";
|
|
13
|
+
const THEME_NAME = "CalcitaPdfViewerDialog";
|
|
14
|
+
const ViewerActions = piecePart(THEME_NAME, "Actions", Stack);
|
|
15
|
+
const ViewerFrame = piecePart(THEME_NAME, "Frame", "iframe");
|
|
16
|
+
function usePdfUrl(src) {
|
|
17
|
+
const [blobUrl, setBlobUrl] = useState(null);
|
|
18
|
+
const isBlob = typeof Blob !== "undefined" && src instanceof Blob;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!isBlob) {
|
|
21
|
+
setBlobUrl(null);
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
const url = URL.createObjectURL(src);
|
|
25
|
+
setBlobUrl(url);
|
|
26
|
+
return () => URL.revokeObjectURL(url);
|
|
27
|
+
}, [isBlob, src]);
|
|
28
|
+
if (isBlob) {
|
|
29
|
+
return blobUrl;
|
|
30
|
+
}
|
|
31
|
+
return typeof src === "string" && src ? src : null;
|
|
32
|
+
}
|
|
33
|
+
function PdfViewerDialogContent(props) {
|
|
34
|
+
const { open, onClose, title, src, fileName, actions, onDownload, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
35
|
+
warnUnknownProps(THEME_NAME, unknownProps);
|
|
36
|
+
const { t } = useToolkitTranslation("common", texts);
|
|
37
|
+
const pdfUrl = usePdfUrl(open ? src : null);
|
|
38
|
+
return /* @__PURE__ */ jsxs(ContentDialog, { open, onClose, title, texts, children: [
|
|
39
|
+
/* @__PURE__ */ jsxs(ViewerActions, { direction: "row", ownSx: { gap: 1, flexWrap: "wrap", mb: 2 }, children: [
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
Button,
|
|
42
|
+
{
|
|
43
|
+
size: "small",
|
|
44
|
+
variant: "outlined",
|
|
45
|
+
startIcon: /* @__PURE__ */ jsx(OpenInNewRoundedIcon, {}),
|
|
46
|
+
href: pdfUrl ?? void 0,
|
|
47
|
+
target: "_blank",
|
|
48
|
+
rel: "noopener noreferrer",
|
|
49
|
+
disabled: !pdfUrl,
|
|
50
|
+
children: t("pdfViewer.openInTab")
|
|
51
|
+
}
|
|
52
|
+
),
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
Button,
|
|
55
|
+
{
|
|
56
|
+
size: "small",
|
|
57
|
+
variant: "outlined",
|
|
58
|
+
startIcon: /* @__PURE__ */ jsx(FileDownloadOutlinedIcon, {}),
|
|
59
|
+
href: pdfUrl ?? void 0,
|
|
60
|
+
download: fileName ?? `${title}.pdf`,
|
|
61
|
+
disabled: !pdfUrl,
|
|
62
|
+
onClick: onDownload,
|
|
63
|
+
children: t("pdfViewer.download")
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
actions
|
|
67
|
+
] }),
|
|
68
|
+
pdfUrl ? /* @__PURE__ */ jsx(
|
|
69
|
+
ViewerFrame,
|
|
70
|
+
{
|
|
71
|
+
src: pdfUrl,
|
|
72
|
+
title,
|
|
73
|
+
ownSx: { display: "block", width: "100%", height: { xs: "62vh", md: "72vh" }, border: 0, borderRadius: 1, bgcolor: "action.hover" }
|
|
74
|
+
}
|
|
75
|
+
) : /* @__PURE__ */ jsx(Box, { sx: { height: { xs: "62vh", md: "72vh" }, borderRadius: 1, bgcolor: "action.hover" } })
|
|
76
|
+
] });
|
|
77
|
+
}
|
|
78
|
+
const PdfViewerDialog = withPieceSlots(PdfViewerDialogContent, THEME_NAME);
|
|
79
|
+
export {
|
|
80
|
+
PdfViewerDialog as default
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=PdfViewerDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PdfViewerDialog.js","sources":["../../../src/ui/documents/PdfViewerDialog.jsx"],"sourcesContent":["// Un PDF en una ventana: el aviso de privacidad, un contrato, un estado de cuenta. Lo pinta el visor del navegador (sin\n// librerías: nada que descargar ni que actualizar) en la hoja de lectura de la casa (ContentDialog), con «Abrir en otra\n// pestaña» y «Descargar» arriba.\n//\n// OJO: en el iPhone el visor dentro de la página enseña solo la primera hoja y en algunos navegadores no se pinta; por eso\n// los dos botones siempre están a la vista: abrirlo aparte o bajarlo funciona en todos.\n//\n// src es la dirección del PDF o el archivo mismo (un Blob que mandó el API, un File elegido): del archivo se arma una\n// dirección en el navegador, sin subirlo, y se libera al cerrar.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPdfViewerDialog con defaultProps y\n// styleOverrides de sus partes: actions, frame.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useState} from 'react';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Box from '@mui/material/Box';\nimport FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';\nimport OpenInNewRoundedIcon from '@mui/icons-material/OpenInNewRounded';\n\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport ContentDialog from '@/ui/layout/ContentDialog.jsx';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPdfViewerDialog)\nconst THEME_NAME = 'CalcitaPdfViewerDialog';\nconst ViewerActions = piecePart(THEME_NAME, 'Actions', Stack);\nconst ViewerFrame = piecePart(THEME_NAME, 'Frame', 'iframe');\n\n/**\n * La dirección del PDF: la que llega tal cual, o una del navegador para un archivo (se libera al cambiarlo o al cerrar).\n *\n * @param {string|Blob|null|undefined} src\n * @returns {string|null}\n */\nfunction usePdfUrl(src) {\n const [blobUrl, setBlobUrl] = useState(null);\n const isBlob = typeof Blob !== 'undefined' && src instanceof Blob;\n\n useEffect(() => {\n if (!isBlob) {\n setBlobUrl(null);\n return undefined;\n }\n const url = URL.createObjectURL(src);\n setBlobUrl(url);\n return () => URL.revokeObjectURL(url);\n }, [isBlob, src]);\n\n if (isBlob) {\n return blobUrl;\n }\n return typeof src === 'string' && src ? src : null;\n}\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {string} props.title ya traducido: qué documento es\n * @param {string|Blob|null} props.src la dirección del PDF o el archivo (Blob o File)\n * @param {string} [props.fileName] con qué nombre se descarga (por omisión, el título con .pdf)\n * @param {import('react').ReactNode} [props.actions] botones suyos junto a «Abrir en otra pestaña» y «Descargar»\n * @param {() => void} [props.onDownload] al descargar (para registrarlo, por ejemplo)\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction PdfViewerDialogContent(props) {\n const {open, onClose, title, src, fileName, actions, onDownload, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const pdfUrl = usePdfUrl(open ? src : null);\n\n return (\n <ContentDialog open={open} onClose={onClose} title={title} texts={texts}>\n <ViewerActions direction=\"row\" ownSx={{gap: 1, flexWrap: 'wrap', mb: 2}}>\n <Button size=\"small\" variant=\"outlined\" startIcon={<OpenInNewRoundedIcon />} href={pdfUrl ?? undefined} target=\"_blank\"\n rel=\"noopener noreferrer\" disabled={!pdfUrl}>\n {t('pdfViewer.openInTab')}\n </Button>\n <Button size=\"small\" variant=\"outlined\" startIcon={<FileDownloadOutlinedIcon />} href={pdfUrl ?? undefined}\n download={fileName ?? `${title}.pdf`} disabled={!pdfUrl} onClick={onDownload}>\n {t('pdfViewer.download')}\n </Button>\n {actions}\n </ViewerActions>\n {pdfUrl ? (\n <ViewerFrame src={pdfUrl} title={title}\n ownSx={{display: 'block', width: '100%', height: {xs: '62vh', md: '72vh'}, border: 0, borderRadius: 1, bgcolor: 'action.hover'}} />\n ) : (\n <Box sx={{height: {xs: '62vh', md: '72vh'}, borderRadius: 1, bgcolor: 'action.hover'}} />\n )}\n </ContentDialog>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst PdfViewerDialog = withPieceSlots(PdfViewerDialogContent, THEME_NAME);\nexport default PdfViewerDialog;\n"],"names":[],"mappings":";;;;;;;;;;;;AA2BA,MAAM,aAAa;AACnB,MAAM,gBAAgB,UAAU,YAAY,WAAW,KAAK;AAC5D,MAAM,cAAc,UAAU,YAAY,SAAS,QAAQ;AAQ3D,SAAS,UAAU,KAAK;AACpB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,SAAS,OAAO,SAAS,eAAe,eAAe;AAE7D,YAAU,MAAM;AACZ,QAAI,CAAC,QAAQ;AACT,iBAAW,IAAI;AACf,aAAO;AAAA,IACX;AACA,UAAM,MAAM,IAAI,gBAAgB,GAAG;AACnC,eAAW,GAAG;AACd,WAAO,MAAM,IAAI,gBAAgB,GAAG;AAAA,EACxC,GAAG,CAAC,QAAQ,GAAG,CAAC;AAEhB,MAAI,QAAQ;AACR,WAAO;AAAA,EACX;AACA,SAAO,OAAO,QAAQ,YAAY,MAAM,MAAM;AAClD;AAaA,SAAS,uBAAuB,OAAO;AACnC,QAAM,EAAC,MAAM,SAAS,OAAO,KAAK,UAAU,SAAS,YAAY,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC1H,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,SAAS,UAAU,OAAO,MAAM,IAAI;AAE1C,SACI,qBAAC,eAAA,EAAc,MAAY,SAAkB,OAAc,OACvD,UAAA;AAAA,IAAA,qBAAC,eAAA,EAAc,WAAU,OAAM,OAAO,EAAC,KAAK,GAAG,UAAU,QAAQ,IAAI,EAAA,GACjE,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UAAO,MAAK;AAAA,UAAQ,SAAQ;AAAA,UAAW,+BAAY,sBAAA,EAAqB;AAAA,UAAI,MAAM,UAAU;AAAA,UAAW,QAAO;AAAA,UACvG,KAAI;AAAA,UAAsB,UAAU,CAAC;AAAA,UACxC,YAAE,qBAAqB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE5B;AAAA,QAAC;AAAA,QAAA;AAAA,UAAO,MAAK;AAAA,UAAQ,SAAQ;AAAA,UAAW,+BAAY,0BAAA,EAAyB;AAAA,UAAI,MAAM,UAAU;AAAA,UACzF,UAAU,YAAY,GAAG,KAAK;AAAA,UAAQ,UAAU,CAAC;AAAA,UAAQ,SAAS;AAAA,UACrE,YAAE,oBAAoB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE1B;AAAA,IAAA,GACL;AAAA,IACC,SACG;AAAA,MAAC;AAAA,MAAA;AAAA,QAAY,KAAK;AAAA,QAAQ;AAAA,QACb,OAAO,EAAC,SAAS,SAAS,OAAO,QAAQ,QAAQ,EAAC,IAAI,QAAQ,IAAI,UAAS,QAAQ,GAAG,cAAc,GAAG,SAAS,eAAA;AAAA,MAAc;AAAA,IAAA,IAE3I,oBAAC,KAAA,EAAI,IAAI,EAAC,QAAQ,EAAC,IAAI,QAAQ,IAAI,UAAS,cAAc,GAAG,SAAS,iBAAc,CAAG;AAAA,EAAA,GAE/F;AAER;AAGA,MAAM,kBAAkB,eAAe,wBAAwB,UAAU;"}
|
|
@@ -10,13 +10,13 @@ import TextField from "@mui/material/TextField";
|
|
|
10
10
|
import Typography from "@mui/material/Typography";
|
|
11
11
|
import DateRangeOutlinedIcon from "@mui/icons-material/DateRangeOutlined";
|
|
12
12
|
import { useFormatters } from "../../toolkit/useFormatters.js";
|
|
13
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
13
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
14
14
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
15
15
|
const THEME_NAME = "CalcitaDateRangeFilter";
|
|
16
16
|
const RangeChip = piecePart(THEME_NAME, "Chip", Chip);
|
|
17
17
|
const RangePanel = piecePart(THEME_NAME, "Panel", Stack);
|
|
18
18
|
const RangeActions = piecePart(THEME_NAME, "Actions", Stack);
|
|
19
|
-
function
|
|
19
|
+
function DateRangeFilterContent(props) {
|
|
20
20
|
const { from = "", to = "", onChange, label, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
21
21
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
22
22
|
const { t } = useToolkitTranslation("table", texts);
|
|
@@ -89,6 +89,7 @@ function DateRangeFilter(props) {
|
|
|
89
89
|
] }) })
|
|
90
90
|
] });
|
|
91
91
|
}
|
|
92
|
+
const DateRangeFilter = withPieceSlots(DateRangeFilterContent, THEME_NAME);
|
|
92
93
|
export {
|
|
93
94
|
DateRangeFilter as default
|
|
94
95
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateRangeFilter.js","sources":["../../../src/ui/filters/DateRangeFilter.jsx"],"sourcesContent":["// Un rango de fechas personalizado, como chip al lado de los accesos rápidos.\n//\n// Viaja como AAAA-MM-DD (día, no instante). Convertirlo a \"inicio del día\" y \"fin del día\" lo hace el SERVIDOR con la\n// zona del negocio: si lo hiciera el navegador con la suya, alguien en otra zona pediría otro rango sin saberlo.\n//\n// El calendario es el <input type=\"date\"> del TextField de MUI y no el DatePicker de @mui/x-date-pickers con moment,\n// para no sumar dos dependencias (x-date-pickers y moment) que ninguna\n// pantalla del 22-sep necesita. Si el calendario nativo estorba (Safari de escritorio), se cambia SOLO este archivo.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaDateRangeFilter con defaultProps y\n// styleOverrides de sus partes: chip, panel, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Popover from '@mui/material/Popover';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport DateRangeOutlinedIcon from '@mui/icons-material/DateRangeOutlined';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaDateRangeFilter)\nconst THEME_NAME = 'CalcitaDateRangeFilter';\nconst RangeChip = piecePart(THEME_NAME, 'Chip', Chip);\nconst RangePanel = piecePart(THEME_NAME, 'Panel', Stack);\nconst RangeActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/**\n * @param {object} props\n * @param {string} [props.from] AAAA-MM-DD o '' si no hay\n * @param {string} [props.to] AAAA-MM-DD o '' si no hay\n * @param {(range: {from: string, to: string}) => void} props.onChange '' para quitar\n * @param {string} [props.label] ya traducido; por defecto \"Personalizado\"\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"DateRangeFilter.js","sources":["../../../src/ui/filters/DateRangeFilter.jsx"],"sourcesContent":["// Un rango de fechas personalizado, como chip al lado de los accesos rápidos.\n//\n// Viaja como AAAA-MM-DD (día, no instante). Convertirlo a \"inicio del día\" y \"fin del día\" lo hace el SERVIDOR con la\n// zona del negocio: si lo hiciera el navegador con la suya, alguien en otra zona pediría otro rango sin saberlo.\n//\n// El calendario es el <input type=\"date\"> del TextField de MUI y no el DatePicker de @mui/x-date-pickers con moment,\n// para no sumar dos dependencias (x-date-pickers y moment) que ninguna\n// pantalla del 22-sep necesita. Si el calendario nativo estorba (Safari de escritorio), se cambia SOLO este archivo.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaDateRangeFilter con defaultProps y\n// styleOverrides de sus partes: chip, panel, actions.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Popover from '@mui/material/Popover';\nimport Stack from '@mui/material/Stack';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport DateRangeOutlinedIcon from '@mui/icons-material/DateRangeOutlined';\n\nimport {useFormatters} from '@/toolkit/useFormatters.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaDateRangeFilter)\nconst THEME_NAME = 'CalcitaDateRangeFilter';\nconst RangeChip = piecePart(THEME_NAME, 'Chip', Chip);\nconst RangePanel = piecePart(THEME_NAME, 'Panel', Stack);\nconst RangeActions = piecePart(THEME_NAME, 'Actions', Stack);\n\n/**\n * @param {object} props\n * @param {string} [props.from] AAAA-MM-DD o '' si no hay\n * @param {string} [props.to] AAAA-MM-DD o '' si no hay\n * @param {(range: {from: string, to: string}) => void} props.onChange '' para quitar\n * @param {string} [props.label] ya traducido; por defecto \"Personalizado\"\n * @param {object} [props.texts] los textos que cambian, con la forma de `table` en los textos del paquete\n */\nfunction DateRangeFilterContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaDateRangeFilter.defaultProps) y encima lo que llega aquí\n const {from = '', to = '', onChange, label, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('table', texts);\n const {formatDate} = useFormatters();\n const [anchorElement, setAnchorElement] = useState(null);\n const [draft, setDraft] = useState({from, to});\n const isActive = Boolean(from || to);\n // AAAA-MM-DD se compara bien como texto\n const isInvalid = Boolean(draft.from && draft.to && draft.from > draft.to);\n\n const open = (event) => {\n setDraft({from, to});\n setAnchorElement(event.currentTarget);\n };\n const close = () => setAnchorElement(null);\n const apply = () => {\n onChange(draft);\n close();\n };\n const clear = () => {\n onChange({from: '', to: ''});\n close();\n };\n\n const summary = isActive\n ? t('dateRange.summary', {from: from ? formatDate(from) : '…', to: to ? formatDate(to) : t('dateRange.today')})\n : (label ?? t('dateRange.label'));\n\n return (\n <>\n <RangeChip icon={<DateRangeOutlinedIcon />} label={summary} clickable onClick={open}\n variant={isActive ? 'filled' : 'outlined'} color={isActive ? 'primary' : 'default'}\n onDelete={isActive ? clear : undefined} ownSx={{flex: '0 0 auto', height: 32}} />\n <Popover open={Boolean(anchorElement)} anchorEl={anchorElement} onClose={close} anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}>\n <RangePanel spacing={2} ownSx={{p: 2, width: 280}}>\n <Typography variant=\"subtitle2\">{t('dateRange.title')}</Typography>\n <TextField type=\"date\" size=\"small\" fullWidth label={t('dateRange.from')} value={draft.from}\n helperText={t('dateRange.fromHelp')}\n onChange={(event) => setDraft((currentDraft) => ({...currentDraft, from: event.target.value}))}\n slotProps={{inputLabel: {shrink: true}, htmlInput: {max: draft.to || undefined}}} />\n <TextField type=\"date\" size=\"small\" fullWidth label={t('dateRange.to')} value={draft.to} error={isInvalid}\n helperText={isInvalid ? t('dateRange.invalid') : t('dateRange.toHelp')}\n onChange={(event) => setDraft((currentDraft) => ({...currentDraft, to: event.target.value}))}\n slotProps={{inputLabel: {shrink: true}, htmlInput: {min: draft.from || undefined}}} />\n <RangeActions direction=\"row\" spacing={1} ownSx={{justifyContent: 'flex-end'}}>\n {isActive && <Button onClick={clear}>{t('dateRange.clear')}</Button>}\n <Button variant=\"contained\" onClick={apply} disabled={isInvalid || !(draft.from || draft.to)}>\n {t('dateRange.apply')}\n </Button>\n </RangeActions>\n </RangePanel>\n </Popover>\n </>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst DateRangeFilter = withPieceSlots(DateRangeFilterContent, THEME_NAME);\nexport default DateRangeFilter;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useState, useEffect } from "react";
|
|
4
|
+
import Box from "@mui/material/Box";
|
|
5
|
+
import Button from "@mui/material/Button";
|
|
6
|
+
import Drawer from "@mui/material/Drawer";
|
|
7
|
+
import IconButton from "@mui/material/IconButton";
|
|
8
|
+
import Stack from "@mui/material/Stack";
|
|
9
|
+
import Typography from "@mui/material/Typography";
|
|
10
|
+
import CloseRoundedIcon from "@mui/icons-material/CloseRounded";
|
|
11
|
+
import CatalogInput from "../../inputs/CatalogInput.js";
|
|
12
|
+
import CheckboxGroupInput from "../../inputs/CheckboxGroupInput.js";
|
|
13
|
+
import FieldFrame from "../../inputs/FieldFrame.js";
|
|
14
|
+
import NumberInput from "../../inputs/NumberInput.js";
|
|
15
|
+
import SelectInput from "../../inputs/SelectInput.js";
|
|
16
|
+
import TextInput from "../../inputs/TextInput.js";
|
|
17
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
18
|
+
import { useToolkitTranslation } from "../../toolkit/useToolkitTranslation.js";
|
|
19
|
+
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
20
|
+
import { drawerValuesOf, invalidRangesOf, emptyDrawerValuesOf, filterKeysOf, FILTER_FIELD_KIND, comparisonOf, COMPARISON_OPERATOR, comparisonTextOf } from "./filterDrawerFields.js";
|
|
21
|
+
const FILTER_DRAWER_ANCHOR = Object.freeze({ left: "left", right: "right" });
|
|
22
|
+
const DEFAULT_WIDTH = 380;
|
|
23
|
+
const ANY_OPTION = "__calcita_any__";
|
|
24
|
+
const THEME_NAME = "CalcitaFilterDrawer";
|
|
25
|
+
const FilterDrawerHeader = piecePart(THEME_NAME, "Header", Stack);
|
|
26
|
+
const FilterDrawerBody = piecePart(THEME_NAME, "Body", Stack);
|
|
27
|
+
const FilterDrawerFooter = piecePart(THEME_NAME, "Footer", Stack);
|
|
28
|
+
function PairedField({ label, inputId, children, template = "1fr 1fr" }) {
|
|
29
|
+
return /* @__PURE__ */ jsx(FieldFrame, { inputId, label, children: /* @__PURE__ */ jsx(Box, { sx: { display: "grid", gridTemplateColumns: template, gap: 1.5, alignItems: "start" }, children }) });
|
|
30
|
+
}
|
|
31
|
+
function DrawerField({ field, values, setValue, invalidRanges, t }) {
|
|
32
|
+
const fieldId = useId();
|
|
33
|
+
const [key] = filterKeysOf(field);
|
|
34
|
+
switch (field.kind) {
|
|
35
|
+
case FILTER_FIELD_KIND.text:
|
|
36
|
+
return /* @__PURE__ */ jsx(TextInput, { label: field.label, value: values[key], onChange: (text) => setValue(key, text), placeholder: field.placeholder });
|
|
37
|
+
case FILTER_FIELD_KIND.select:
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
SelectInput,
|
|
40
|
+
{
|
|
41
|
+
label: field.label,
|
|
42
|
+
value: values[key] || ANY_OPTION,
|
|
43
|
+
onChange: (chosen) => setValue(key, chosen === ANY_OPTION ? "" : chosen),
|
|
44
|
+
options: [{ value: ANY_OPTION, label: t("filterDrawer.any") }, ...field.options]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
case FILTER_FIELD_KIND.multiSelect:
|
|
48
|
+
return /* @__PURE__ */ jsx(SelectInput, { label: field.label, value: values[key], onChange: (chosen) => setValue(key, chosen), options: field.options, multiple: true, selectAll: true, checkboxes: true });
|
|
49
|
+
case FILTER_FIELD_KIND.catalog:
|
|
50
|
+
return /* @__PURE__ */ jsx(
|
|
51
|
+
CatalogInput,
|
|
52
|
+
{
|
|
53
|
+
label: field.label,
|
|
54
|
+
value: values[key],
|
|
55
|
+
onChange: (chosen) => setValue(key, chosen),
|
|
56
|
+
options: field.options,
|
|
57
|
+
multiple: field.multiple,
|
|
58
|
+
selectAll: field.multiple,
|
|
59
|
+
checkboxes: field.multiple,
|
|
60
|
+
formatLabel: field.formatLabel,
|
|
61
|
+
placeholder: field.placeholder
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
case FILTER_FIELD_KIND.checkboxes:
|
|
65
|
+
return /* @__PURE__ */ jsx(CheckboxGroupInput, { label: field.label, value: values[key], onChange: (chosen) => setValue(key, chosen), options: field.options, selectAll: field.selectAll });
|
|
66
|
+
case FILTER_FIELD_KIND.numberRange: {
|
|
67
|
+
const [fromKey, toKey] = filterKeysOf(field);
|
|
68
|
+
const numberProps = { decimals: field.decimals ?? 0, prefix: field.prefix, suffix: field.suffix, helperText: "" };
|
|
69
|
+
return /* @__PURE__ */ jsxs(PairedField, { label: field.label, inputId: `${fieldId}-from`, children: [
|
|
70
|
+
/* @__PURE__ */ jsx(NumberInput, { label: t("filterDrawer.from"), value: values[fromKey], onChange: (number) => setValue(fromKey, number), ...numberProps }),
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
NumberInput,
|
|
73
|
+
{
|
|
74
|
+
label: t("filterDrawer.to"),
|
|
75
|
+
value: values[toKey],
|
|
76
|
+
onChange: (number) => setValue(toKey, number),
|
|
77
|
+
...numberProps,
|
|
78
|
+
error: invalidRanges[toKey] ? t("filterDrawer.rangeBackwards") : void 0
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
case FILTER_FIELD_KIND.dateRange: {
|
|
84
|
+
const [fromKey, toKey] = filterKeysOf(field);
|
|
85
|
+
return /* @__PURE__ */ jsxs(PairedField, { label: field.label, inputId: `${fieldId}-from`, children: [
|
|
86
|
+
/* @__PURE__ */ jsx(TextInput, { type: "date", label: t("filterDrawer.from"), value: values[fromKey], onChange: (date) => setValue(fromKey, date), clearable: false, helperText: "" }),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
TextInput,
|
|
89
|
+
{
|
|
90
|
+
type: "date",
|
|
91
|
+
label: t("filterDrawer.to"),
|
|
92
|
+
value: values[toKey],
|
|
93
|
+
onChange: (date) => setValue(toKey, date),
|
|
94
|
+
clearable: false,
|
|
95
|
+
error: invalidRanges[toKey] ? t("filterDrawer.rangeBackwards") : void 0
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
] });
|
|
99
|
+
}
|
|
100
|
+
case FILTER_FIELD_KIND.comparison: {
|
|
101
|
+
const parts = comparisonOf(values[key]);
|
|
102
|
+
const operators = field.operators ?? Object.values(COMPARISON_OPERATOR);
|
|
103
|
+
const operator = parts?.operator ?? field.defaultOperator ?? operators[0];
|
|
104
|
+
return /* @__PURE__ */ jsxs(PairedField, { label: field.label, inputId: `${fieldId}-value`, template: "minmax(0, 1fr) minmax(0, 1.2fr)", children: [
|
|
105
|
+
/* @__PURE__ */ jsx(
|
|
106
|
+
SelectInput,
|
|
107
|
+
{
|
|
108
|
+
label: t("filterDrawer.operator"),
|
|
109
|
+
value: operator,
|
|
110
|
+
helperText: "",
|
|
111
|
+
options: operators.map((option) => ({ value: option, label: t(`filterDrawer.operators.${option}`) })),
|
|
112
|
+
onChange: (chosen) => setValue(key, comparisonTextOf(chosen, parts?.value ?? ""))
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
NumberInput,
|
|
117
|
+
{
|
|
118
|
+
label: t("filterDrawer.value"),
|
|
119
|
+
value: parts?.value ?? "",
|
|
120
|
+
decimals: field.decimals ?? 2,
|
|
121
|
+
prefix: field.prefix,
|
|
122
|
+
suffix: field.suffix,
|
|
123
|
+
helperText: "",
|
|
124
|
+
onChange: (number) => setValue(key, comparisonTextOf(operator, number))
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
case FILTER_FIELD_KIND.custom:
|
|
130
|
+
return field.render({ value: values[key], onChange: (next) => setValue(key, next), values, setValue });
|
|
131
|
+
default:
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function FilterDrawerContent(props) {
|
|
136
|
+
const {
|
|
137
|
+
open,
|
|
138
|
+
onClose,
|
|
139
|
+
fields,
|
|
140
|
+
values,
|
|
141
|
+
onApply,
|
|
142
|
+
anchor = FILTER_DRAWER_ANCHOR.right,
|
|
143
|
+
width = DEFAULT_WIDTH,
|
|
144
|
+
title,
|
|
145
|
+
applyLabel,
|
|
146
|
+
closeOnApply = true,
|
|
147
|
+
children,
|
|
148
|
+
texts,
|
|
149
|
+
...unknownProps
|
|
150
|
+
} = usePieceProps(props, THEME_NAME);
|
|
151
|
+
warnUnknownProps(THEME_NAME, unknownProps);
|
|
152
|
+
const { t } = useToolkitTranslation("common", texts);
|
|
153
|
+
const titleId = useId();
|
|
154
|
+
const [draft, setDraft] = useState(() => drawerValuesOf(fields, values));
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (open) {
|
|
157
|
+
setDraft(drawerValuesOf(fields, values));
|
|
158
|
+
}
|
|
159
|
+
}, [open]);
|
|
160
|
+
const invalidRanges = invalidRangesOf(fields, draft);
|
|
161
|
+
const hasInvalidRange = Object.keys(invalidRanges).length > 0;
|
|
162
|
+
const setValue = (key, value) => setDraft((current) => ({ ...current, [key]: value }));
|
|
163
|
+
const apply = () => {
|
|
164
|
+
onApply(draft);
|
|
165
|
+
if (closeOnApply) {
|
|
166
|
+
onClose();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return /* @__PURE__ */ jsx(
|
|
170
|
+
Drawer,
|
|
171
|
+
{
|
|
172
|
+
anchor,
|
|
173
|
+
open,
|
|
174
|
+
onClose,
|
|
175
|
+
slotProps: { paper: { "aria-labelledby": titleId, className: `${THEME_NAME}-paper`, sx: { width: { xs: "100%", sm: width }, maxWidth: "100%" } } },
|
|
176
|
+
children: /* @__PURE__ */ jsxs(
|
|
177
|
+
Box,
|
|
178
|
+
{
|
|
179
|
+
component: "form",
|
|
180
|
+
noValidate: true,
|
|
181
|
+
sx: { display: "flex", flexDirection: "column", height: "100%" },
|
|
182
|
+
onSubmit: (event) => {
|
|
183
|
+
event.preventDefault();
|
|
184
|
+
if (!hasInvalidRange) {
|
|
185
|
+
apply();
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
children: [
|
|
189
|
+
/* @__PURE__ */ jsxs(FilterDrawerHeader, { direction: "row", ownSx: { alignItems: "center", gap: 1, px: 2, py: 1.5, borderBottom: 1, borderColor: "divider" }, children: [
|
|
190
|
+
/* @__PURE__ */ jsx(IconButton, { "aria-label": t("filterDrawer.close"), onClick: onClose, edge: "start", children: /* @__PURE__ */ jsx(CloseRoundedIcon, {}) }),
|
|
191
|
+
/* @__PURE__ */ jsx(Typography, { id: titleId, variant: "h6", component: "h2", sx: { flexGrow: 1 }, children: title ?? t("filterDrawer.title") })
|
|
192
|
+
] }),
|
|
193
|
+
/* @__PURE__ */ jsxs(FilterDrawerBody, { spacing: 1, ownSx: { flex: 1, overflowY: "auto", px: 2.5, py: 2 }, children: [
|
|
194
|
+
fields.map((field) => /* @__PURE__ */ jsx(DrawerField, { field, values: draft, setValue, invalidRanges, t }, field.name)),
|
|
195
|
+
children
|
|
196
|
+
] }),
|
|
197
|
+
/* @__PURE__ */ jsxs(FilterDrawerFooter, { direction: "row", ownSx: { gap: 1, justifyContent: "flex-end", px: 2.5, py: 1.5, borderTop: 1, borderColor: "divider" }, children: [
|
|
198
|
+
/* @__PURE__ */ jsx(Button, { onClick: () => setDraft(emptyDrawerValuesOf(fields)), children: t("filterDrawer.clear") }),
|
|
199
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", variant: "contained", disabled: hasInvalidRange, children: applyLabel ?? t("filterDrawer.apply") })
|
|
200
|
+
] })
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
const FilterDrawer = withPieceSlots(FilterDrawerContent, THEME_NAME);
|
|
208
|
+
export {
|
|
209
|
+
FILTER_DRAWER_ANCHOR,
|
|
210
|
+
FilterDrawer as default
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=FilterDrawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterDrawer.js","sources":["../../../src/ui/filters/FilterDrawer.jsx"],"sourcesContent":["// El cajón de búsqueda: un panel que sale de un lado con los campos que filtran una lista (las listas, un rango\n// «desde-hasta», unas fechas, un monto con su operador), para cuando los filtros ya no caben arriba de la tabla.\n//\n// Lo que se cambia adentro es un BORRADOR: la lista no se mueve hasta «Buscar» (no se consulta al servidor con cada tecla).\n// «Limpiar» vacía los campos del cajón; «Buscar» manda todos juntos (onApply) y cierra. Un rango al revés («hasta» menor que\n// «desde») se dice en su campo y no deja buscar.\n//\n// Los campos se declaran (filterDrawerFields.js dice cómo viaja cada uno); con kind 'custom' va uno propio (render). Para\n// conectarlo a ServerTable con su botón y sus chips: ServerTableFilterDrawer de /table.\n//\n// Configurable: de qué lado sale (anchor), su ancho, su título y los textos de sus botones. En el teléfono ocupa todo el\n// ancho.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaFilterDrawer con defaultProps y\n// styleOverrides de sus partes: paper, header, body, footer.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useId, useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Drawer from '@mui/material/Drawer';\nimport IconButton from '@mui/material/IconButton';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport CloseRoundedIcon from '@mui/icons-material/CloseRounded';\n\nimport CatalogInput from '@/inputs/CatalogInput.jsx';\nimport CheckboxGroupInput from '@/inputs/CheckboxGroupInput.jsx';\nimport FieldFrame from '@/inputs/FieldFrame.jsx';\nimport NumberInput from '@/inputs/NumberInput.jsx';\nimport SelectInput from '@/inputs/SelectInput.jsx';\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\nimport {\n COMPARISON_OPERATOR, FILTER_FIELD_KIND, comparisonOf, comparisonTextOf, drawerValuesOf, emptyDrawerValuesOf, filterKeysOf,\n invalidRangesOf,\n} from '@/ui/filters/filterDrawerFields.js';\n\n/** De qué lado sale el cajón. */\nexport const FILTER_DRAWER_ANCHOR = Object.freeze({left: 'left', right: 'right'});\nconst DEFAULT_WIDTH = 380;\n// «Cualquiera» de una lista de una sola opción: no es una opción y viaja como '' (sin filtro)\nconst ANY_OPTION = '__calcita_any__';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaFilterDrawer)\nconst THEME_NAME = 'CalcitaFilterDrawer';\nconst FilterDrawerHeader = piecePart(THEME_NAME, 'Header', Stack);\nconst FilterDrawerBody = piecePart(THEME_NAME, 'Body', Stack);\nconst FilterDrawerFooter = piecePart(THEME_NAME, 'Footer', Stack);\n\n/**\n * Dos campos lado a lado (desde y hasta, operador y número); en un cajón angosto se ven bien juntos.\n *\n * @param {{label: import('react').ReactNode, inputId: string, children: import('react').ReactNode, template?: string}} props\n */\nfunction PairedField({label, inputId, children, template = '1fr 1fr'}) {\n return (\n <FieldFrame inputId={inputId} label={label}>\n <Box sx={{display: 'grid', gridTemplateColumns: template, gap: 1.5, alignItems: 'start'}}>{children}</Box>\n </FieldFrame>\n );\n}\n\n/**\n * Un campo del cajón según su tipo, con las piezas de la casa.\n *\n * @param {object} props\n */\nfunction DrawerField({field, values, setValue, invalidRanges, t}) {\n const fieldId = useId();\n const [key] = filterKeysOf(field);\n switch (field.kind) {\n case FILTER_FIELD_KIND.text:\n return <TextInput label={field.label} value={values[key]} onChange={(text) => setValue(key, text)} placeholder={field.placeholder} />;\n case FILTER_FIELD_KIND.select:\n return (\n <SelectInput label={field.label} value={values[key] || ANY_OPTION} onChange={(chosen) => setValue(key, chosen === ANY_OPTION ? '' : chosen)}\n options={[{value: ANY_OPTION, label: t('filterDrawer.any')}, ...field.options]} />\n );\n case FILTER_FIELD_KIND.multiSelect:\n return <SelectInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options} multiple selectAll checkboxes />;\n case FILTER_FIELD_KIND.catalog:\n return (\n <CatalogInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options}\n multiple={field.multiple} selectAll={field.multiple} checkboxes={field.multiple} formatLabel={field.formatLabel}\n placeholder={field.placeholder} />\n );\n case FILTER_FIELD_KIND.checkboxes:\n return <CheckboxGroupInput label={field.label} value={values[key]} onChange={(chosen) => setValue(key, chosen)} options={field.options} selectAll={field.selectAll} />;\n case FILTER_FIELD_KIND.numberRange: {\n const [fromKey, toKey] = filterKeysOf(field);\n const numberProps = {decimals: field.decimals ?? 0, prefix: field.prefix, suffix: field.suffix, helperText: ''};\n return (\n <PairedField label={field.label} inputId={`${fieldId}-from`}>\n <NumberInput label={t('filterDrawer.from')} value={values[fromKey]} onChange={(number) => setValue(fromKey, number)} {...numberProps} />\n <NumberInput label={t('filterDrawer.to')} value={values[toKey]} onChange={(number) => setValue(toKey, number)} {...numberProps}\n error={invalidRanges[toKey] ? t('filterDrawer.rangeBackwards') : undefined} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.dateRange: {\n const [fromKey, toKey] = filterKeysOf(field);\n // el calendario del navegador (como DateRangeFilter): viaja AAAA-MM-DD, sin pedir MUI X\n return (\n <PairedField label={field.label} inputId={`${fieldId}-from`}>\n <TextInput type=\"date\" label={t('filterDrawer.from')} value={values[fromKey]} onChange={(date) => setValue(fromKey, date)} clearable={false} helperText=\"\" />\n <TextInput type=\"date\" label={t('filterDrawer.to')} value={values[toKey]} onChange={(date) => setValue(toKey, date)} clearable={false}\n error={invalidRanges[toKey] ? t('filterDrawer.rangeBackwards') : undefined} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.comparison: {\n const parts = comparisonOf(values[key]);\n const operators = field.operators ?? Object.values(COMPARISON_OPERATOR);\n const operator = parts?.operator ?? field.defaultOperator ?? operators[0];\n return (\n <PairedField label={field.label} inputId={`${fieldId}-value`} template=\"minmax(0, 1fr) minmax(0, 1.2fr)\">\n <SelectInput label={t('filterDrawer.operator')} value={operator} helperText=\"\"\n options={operators.map((option) => ({value: option, label: t(`filterDrawer.operators.${option}`)}))}\n onChange={(chosen) => setValue(key, comparisonTextOf(chosen, parts?.value ?? ''))} />\n <NumberInput label={t('filterDrawer.value')} value={parts?.value ?? ''} decimals={field.decimals ?? 2} prefix={field.prefix} suffix={field.suffix}\n helperText=\"\" onChange={(number) => setValue(key, comparisonTextOf(operator, number))} />\n </PairedField>\n );\n }\n case FILTER_FIELD_KIND.custom:\n return field.render({value: values[key], onChange: (next) => setValue(key, next), values, setValue});\n default:\n return null;\n }\n}\n\n/**\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {object[]} props.fields los campos (filterDrawerFields.js): {name, label, kind, options?, keys?, prefix?, suffix?, decimals?, operators?, render?…}\n * @param {Record<string, unknown>} props.values los filtros puestos hoy (de ahí sale el borrador al abrir)\n * @param {(values: Record<string, unknown>) => void} props.onApply todos los campos del cajón juntos, al picar «Buscar»\n * @param {'left'|'right'} [props.anchor] de qué lado sale (FILTER_DRAWER_ANCHOR); por omisión la derecha\n * @param {number} [props.width] su ancho en escritorio, en px\n * @param {string} [props.title] ya traducido; por omisión «Filtros»\n * @param {string} [props.applyLabel] ya traducido; por omisión «Buscar»\n * @param {boolean} [props.closeOnApply] por omisión sí\n * @param {import('react').ReactNode} [props.children] algo más abajo de los campos (una nota, un enlace)\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction FilterDrawerContent(props) {\n const {\n open, onClose, fields, values, onApply, anchor = FILTER_DRAWER_ANCHOR.right, width = DEFAULT_WIDTH, title, applyLabel,\n closeOnApply = true, children, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const titleId = useId();\n const [draft, setDraft] = useState(() => drawerValuesOf(fields, values));\n // cada vez que se abre, el borrador empieza de lo que hay puesto (lo de la vez pasada sin buscar no se queda)\n useEffect(() => {\n if (open) {\n setDraft(drawerValuesOf(fields, values));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n const invalidRanges = invalidRangesOf(fields, draft);\n const hasInvalidRange = Object.keys(invalidRanges).length > 0;\n const setValue = (key, value) => setDraft((current) => ({...current, [key]: value}));\n const apply = () => {\n onApply(draft);\n if (closeOnApply) {\n onClose();\n }\n };\n\n return (\n <Drawer\n anchor={anchor}\n open={open}\n onClose={onClose}\n slotProps={{paper: {'aria-labelledby': titleId, className: `${THEME_NAME}-paper`, sx: {width: {xs: '100%', sm: width}, maxWidth: '100%'}}}}\n >\n <Box component=\"form\" noValidate sx={{display: 'flex', flexDirection: 'column', height: '100%'}}\n onSubmit={(event) => {\n event.preventDefault();\n if (!hasInvalidRange) {\n apply();\n }\n }}>\n <FilterDrawerHeader direction=\"row\" ownSx={{alignItems: 'center', gap: 1, px: 2, py: 1.5, borderBottom: 1, borderColor: 'divider'}}>\n <IconButton aria-label={t('filterDrawer.close')} onClick={onClose} edge=\"start\"><CloseRoundedIcon /></IconButton>\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{flexGrow: 1}}>{title ?? t('filterDrawer.title')}</Typography>\n </FilterDrawerHeader>\n <FilterDrawerBody spacing={1} ownSx={{flex: 1, overflowY: 'auto', px: 2.5, py: 2}}>\n {fields.map((field) => (\n <DrawerField key={field.name} field={field} values={draft} setValue={setValue} invalidRanges={invalidRanges} t={t} />\n ))}\n {children}\n </FilterDrawerBody>\n <FilterDrawerFooter direction=\"row\" ownSx={{gap: 1, justifyContent: 'flex-end', px: 2.5, py: 1.5, borderTop: 1, borderColor: 'divider'}}>\n <Button onClick={() => setDraft(emptyDrawerValuesOf(fields))}>{t('filterDrawer.clear')}</Button>\n <Button type=\"submit\" variant=\"contained\" disabled={hasInvalidRange}>{applyLabel ?? t('filterDrawer.apply')}</Button>\n </FilterDrawerFooter>\n </Box>\n </Drawer>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst FilterDrawer = withPieceSlots(FilterDrawerContent, THEME_NAME);\nexport default FilterDrawer;\n"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import MenuItem from "@mui/material/MenuItem";
|
|
|
7
7
|
import Select from "@mui/material/Select";
|
|
8
8
|
import Stack from "@mui/material/Stack";
|
|
9
9
|
import { rangeEndOptionsOf, rangeEndAfterStartChange } from "../../periodRanges.js";
|
|
10
|
-
import { piecePart, usePieceProps } from "../../theme/themePieces.js";
|
|
10
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../../theme/themePieces.js";
|
|
11
11
|
import { warnUnknownProps } from "../../toolkit/unknownProps.js";
|
|
12
12
|
const THEME_NAME = "CalcitaPeriodRangeSelector";
|
|
13
13
|
const PeriodField = piecePart(THEME_NAME, "Field", FormControl);
|
|
@@ -31,7 +31,7 @@ function PeriodSelect({ id, label, value, options, onChange }) {
|
|
|
31
31
|
)
|
|
32
32
|
] });
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function PeriodRangeSelectorContent(props) {
|
|
35
35
|
const { id, options, from, to, fromLabel, toLabel, onChange, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
36
36
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
37
37
|
const endOptions = rangeEndOptionsOf(options, from);
|
|
@@ -58,6 +58,7 @@ function PeriodRangeSelector(props) {
|
|
|
58
58
|
)
|
|
59
59
|
] });
|
|
60
60
|
}
|
|
61
|
+
const PeriodRangeSelector = withPieceSlots(PeriodRangeSelectorContent, THEME_NAME);
|
|
61
62
|
export {
|
|
62
63
|
PeriodRangeSelector as default
|
|
63
64
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PeriodRangeSelector.js","sources":["../../../src/ui/filters/PeriodRangeSelector.jsx"],"sourcesContent":["// Un rango de periodos: «desde» y «hasta», cada uno una lista para elegir (de tal quincena a tal quincena, de tal mes a\n// tal mes). Se usa en lugar de un calendario porque los periodos no son días: solo se ofrecen los que existen, y los que no\n// se pueden elegir salen apagados con su razón.\n//\n// «Hasta» solo ofrece lo que hace un rango válido con «desde»: nada de antes y nada que salte un periodo apagado\n// (periodRanges.js). Al cambiar «desde», si el «hasta» que había ya no vale, se iguala a «desde».\n//\n// No sabe de quincenas ni de productos: recibe las opciones ya ordenadas y con sus textos traducidos.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPeriodRangeSelector con defaultProps y\n// styleOverrides de sus partes: field, select, root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport FormControl from '@mui/material/FormControl';\nimport InputLabel from '@mui/material/InputLabel';\nimport ListItemText from '@mui/material/ListItemText';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport Stack from '@mui/material/Stack';\n\nimport {rangeEndAfterStartChange, rangeEndOptionsOf} from '@/periodRanges.js';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPeriodRangeSelector)\nconst THEME_NAME = 'CalcitaPeriodRangeSelector';\nconst PeriodField = piecePart(THEME_NAME, 'Field', FormControl);\nconst PeriodSelectPart = piecePart(THEME_NAME, 'Select', Select);\nconst PeriodRoot = piecePart(THEME_NAME, 'Root', Stack);\n\n// ancho de cada lista: cabe «septiembre 2026 · Q2» sin cortarse\nconst SELECT_MINIMUM_WIDTH = 210;\n\n/**\n * Una lista del rango.\n *\n * @param {object} props\n * @param {string} props.id\n * @param {string} props.label\n * @param {string} props.value\n * @param {(value: string) => void} props.onChange\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options\n */\nfunction PeriodSelect({id, label, value, options, onChange}) {\n return (\n <PeriodField size=\"small\" ownSx={{minWidth: SELECT_MINIMUM_WIDTH, flex: '0 0 auto'}}>\n <InputLabel id={`${id}-label`}>{label}</InputLabel>\n <PeriodSelectPart labelId={`${id}-label`} label={label} value={value ?? ''} onChange={(event) => onChange(event.target.value)}\n ownSx={{bgcolor: 'background.paper'}}\n renderValue={(selectedValue) => options.find((option) => option.value === selectedValue)?.label ?? ''}>\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value} disabled={option.disabled}>\n {/* la razón de una opción apagada va debajo de su nombre: «sin validar» se lee sin tooltip */}\n <ListItemText primary={option.label} secondary={option.disabled ? option.hint : undefined} />\n </MenuItem>\n ))}\n </PeriodSelectPart>\n </PeriodField>\n );\n}\n\n/**\n * @param {object} props\n * @param {string} props.id prefijo de los id de las dos listas (accesibilidad)\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options en orden; ya\n * traducidas\n * @param {string|null} props.from\n * @param {string|null} props.to\n * @param {string} props.fromLabel ya traducido\n * @param {string} props.toLabel ya traducido\n * @param {(range: {from: string, to: string}) => void} props.onChange\n */\
|
|
1
|
+
{"version":3,"file":"PeriodRangeSelector.js","sources":["../../../src/ui/filters/PeriodRangeSelector.jsx"],"sourcesContent":["// Un rango de periodos: «desde» y «hasta», cada uno una lista para elegir (de tal quincena a tal quincena, de tal mes a\n// tal mes). Se usa en lugar de un calendario porque los periodos no son días: solo se ofrecen los que existen, y los que no\n// se pueden elegir salen apagados con su razón.\n//\n// «Hasta» solo ofrece lo que hace un rango válido con «desde»: nada de antes y nada que salte un periodo apagado\n// (periodRanges.js). Al cambiar «desde», si el «hasta» que había ya no vale, se iguala a «desde».\n//\n// No sabe de quincenas ni de productos: recibe las opciones ya ordenadas y con sus textos traducidos.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaPeriodRangeSelector con defaultProps y\n// styleOverrides de sus partes: field, select, root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport FormControl from '@mui/material/FormControl';\nimport InputLabel from '@mui/material/InputLabel';\nimport ListItemText from '@mui/material/ListItemText';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport Stack from '@mui/material/Stack';\n\nimport {rangeEndAfterStartChange, rangeEndOptionsOf} from '@/periodRanges.js';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaPeriodRangeSelector)\nconst THEME_NAME = 'CalcitaPeriodRangeSelector';\nconst PeriodField = piecePart(THEME_NAME, 'Field', FormControl);\nconst PeriodSelectPart = piecePart(THEME_NAME, 'Select', Select);\nconst PeriodRoot = piecePart(THEME_NAME, 'Root', Stack);\n\n// ancho de cada lista: cabe «septiembre 2026 · Q2» sin cortarse\nconst SELECT_MINIMUM_WIDTH = 210;\n\n/**\n * Una lista del rango.\n *\n * @param {object} props\n * @param {string} props.id\n * @param {string} props.label\n * @param {string} props.value\n * @param {(value: string) => void} props.onChange\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options\n */\nfunction PeriodSelect({id, label, value, options, onChange}) {\n return (\n <PeriodField size=\"small\" ownSx={{minWidth: SELECT_MINIMUM_WIDTH, flex: '0 0 auto'}}>\n <InputLabel id={`${id}-label`}>{label}</InputLabel>\n <PeriodSelectPart labelId={`${id}-label`} label={label} value={value ?? ''} onChange={(event) => onChange(event.target.value)}\n ownSx={{bgcolor: 'background.paper'}}\n renderValue={(selectedValue) => options.find((option) => option.value === selectedValue)?.label ?? ''}>\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value} disabled={option.disabled}>\n {/* la razón de una opción apagada va debajo de su nombre: «sin validar» se lee sin tooltip */}\n <ListItemText primary={option.label} secondary={option.disabled ? option.hint : undefined} />\n </MenuItem>\n ))}\n </PeriodSelectPart>\n </PeriodField>\n );\n}\n\n/**\n * @param {object} props\n * @param {string} props.id prefijo de los id de las dos listas (accesibilidad)\n * @param {Array<{value: string, label: string, disabled: boolean, hint?: string}>} props.options en orden; ya\n * traducidas\n * @param {string|null} props.from\n * @param {string|null} props.to\n * @param {string} props.fromLabel ya traducido\n * @param {string} props.toLabel ya traducido\n * @param {(range: {from: string, to: string}) => void} props.onChange\n */\nfunction PeriodRangeSelectorContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaPeriodRangeSelector.defaultProps) y encima lo que llega aquí\n const {id, options, from, to, fromLabel, toLabel, onChange, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const endOptions = rangeEndOptionsOf(options, from);\n\n return (\n <PeriodRoot direction=\"row\" spacing={1.5} useFlexGap ownSx={{alignItems: 'center', flexWrap: 'wrap'}}>\n <PeriodSelect id={`${id}-from`} label={fromLabel} value={from} options={options}\n onChange={(nextFrom) => onChange({from: nextFrom, to: rangeEndAfterStartChange(options, nextFrom, to)})} />\n <PeriodSelect id={`${id}-to`} label={toLabel} value={to} options={endOptions}\n onChange={(nextTo) => onChange({from, to: nextTo})} />\n </PeriodRoot>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst PeriodRangeSelector = withPieceSlots(PeriodRangeSelectorContent, THEME_NAME);\nexport default PeriodRangeSelector;\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,SAAS,WAAW;AAC9D,MAAM,mBAAmB,UAAU,YAAY,UAAU,MAAM;AAC/D,MAAM,aAAa,UAAU,YAAY,QAAQ,KAAK;AAGtD,MAAM,uBAAuB;AAY7B,SAAS,aAAa,EAAC,IAAI,OAAO,OAAO,SAAS,YAAW;AACzD,SACI,qBAAC,aAAA,EAAY,MAAK,SAAQ,OAAO,EAAC,UAAU,sBAAsB,MAAM,WAAA,GACpE,UAAA;AAAA,IAAA,oBAAC,YAAA,EAAW,IAAI,GAAG,EAAE,UAAW,UAAA,OAAM;AAAA,IACtC;AAAA,MAAC;AAAA,MAAA;AAAA,QAAiB,SAAS,GAAG,EAAE;AAAA,QAAU;AAAA,QAAc,OAAO,SAAS;AAAA,QAAI,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,QACpH,OAAO,EAAC,SAAS,mBAAA;AAAA,QACjB,aAAa,CAAC,kBAAkB,QAAQ,KAAK,CAAC,WAAW,OAAO,UAAU,aAAa,GAAG,SAAS;AAAA,QACtG,UAAA,QAAQ,IAAI,CAAC,WACV,oBAAC,UAAA,EAA4B,OAAO,OAAO,OAAO,UAAU,OAAO,UAE/D,UAAA,oBAAC,gBAAa,SAAS,OAAO,OAAO,WAAW,OAAO,WAAW,OAAO,OAAO,OAAA,CAAW,EAAA,GAFhF,OAAO,KAGtB,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EACL,GACJ;AAER;AAaA,SAAS,2BAA2B,OAAO;AAEvC,QAAM,EAAC,IAAI,SAAS,MAAM,IAAI,WAAW,SAAS,UAAU,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAC9G,mBAAiB,YAAY,YAAY;AACzC,QAAM,aAAa,kBAAkB,SAAS,IAAI;AAElD,SACI,qBAAC,YAAA,EAAW,WAAU,OAAM,SAAS,KAAK,YAAU,MAAC,OAAO,EAAC,YAAY,UAAU,UAAU,UACzF,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,IAAI,GAAG,EAAE;AAAA,QAAS,OAAO;AAAA,QAAW,OAAO;AAAA,QAAM;AAAA,QACjD,UAAU,CAAC,aAAa,SAAS,EAAC,MAAM,UAAU,IAAI,yBAAyB,SAAS,UAAU,EAAE,GAAE;AAAA,MAAA;AAAA,IAAA;AAAA,IACpH;AAAA,MAAC;AAAA,MAAA;AAAA,QAAa,IAAI,GAAG,EAAE;AAAA,QAAO,OAAO;AAAA,QAAS,OAAO;AAAA,QAAI,SAAS;AAAA,QACpD,UAAU,CAAC,WAAW,SAAS,EAAC,MAAM,IAAI,QAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EAAG,GACtE;AAER;AAGA,MAAM,sBAAsB,eAAe,4BAA4B,UAAU;"}
|