@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,91 @@
|
|
|
1
|
+
const RFC_PATTERN = /^([A-ZÑ&]{3,4})(\d{2})(\d{2})(\d{2})([A-Z\d]{2})([A\d])$/;
|
|
2
|
+
const GENERIC_RFCS = Object.freeze(["XAXX010101000", "XEXX010101000"]);
|
|
3
|
+
const RFC_CHECK_TABLE = "0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ Ñ";
|
|
4
|
+
const RFC_CHECK_MODULUS = 11;
|
|
5
|
+
const RFC_CHECK_LENGTH = 12;
|
|
6
|
+
const CURP_PATTERN = /^[A-Z][AEIOUX][A-Z]{2}(\d{2})(\d{2})(\d{2})[HMX](AS|BC|BS|CC|CL|CM|CS|CH|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)[B-DF-HJ-NP-TV-Z]{3}[A-Z\d]\d$/;
|
|
7
|
+
const CURP_CHECK_TABLE = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ";
|
|
8
|
+
const CURP_BODY_LENGTH = 17;
|
|
9
|
+
const CLABE_PATTERN = /^\d{18}$/;
|
|
10
|
+
const CLABE_WEIGHTS = Object.freeze([3, 7, 1]);
|
|
11
|
+
const DECIMAL_BASE = 10;
|
|
12
|
+
const RFC_KIND = Object.freeze({ company: "company", person: "person", generic: "generic" });
|
|
13
|
+
function isRealShortDate(year, month, day) {
|
|
14
|
+
const date = new Date(Date.UTC(2e3 + Number(year), Number(month) - 1, Number(day)));
|
|
15
|
+
return date.getUTCMonth() === Number(month) - 1 && date.getUTCDate() === Number(day);
|
|
16
|
+
}
|
|
17
|
+
function rfcCheckDigitOf(rfc) {
|
|
18
|
+
const body = rfc.slice(0, -1).toUpperCase();
|
|
19
|
+
const padded = body.padStart(RFC_CHECK_LENGTH, " ");
|
|
20
|
+
let sum = 0;
|
|
21
|
+
for (let position = 0; position < RFC_CHECK_LENGTH; position += 1) {
|
|
22
|
+
sum += RFC_CHECK_TABLE.indexOf(padded[position]) * (RFC_CHECK_LENGTH + 1 - position);
|
|
23
|
+
}
|
|
24
|
+
const rest = sum % RFC_CHECK_MODULUS;
|
|
25
|
+
if (rest === 0) {
|
|
26
|
+
return "0";
|
|
27
|
+
}
|
|
28
|
+
return rest === 1 ? "A" : String(RFC_CHECK_MODULUS - rest);
|
|
29
|
+
}
|
|
30
|
+
function rfcKindOf(rfc) {
|
|
31
|
+
const clean = (rfc ?? "").trim().toUpperCase();
|
|
32
|
+
if (GENERIC_RFCS.includes(clean)) {
|
|
33
|
+
return RFC_KIND.generic;
|
|
34
|
+
}
|
|
35
|
+
const match = RFC_PATTERN.exec(clean);
|
|
36
|
+
if (!match) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return match[1].length === 3 ? RFC_KIND.company : RFC_KIND.person;
|
|
40
|
+
}
|
|
41
|
+
function isValidRfc(rfc, { strict = false } = {}) {
|
|
42
|
+
const clean = (rfc ?? "").trim().toUpperCase();
|
|
43
|
+
if (GENERIC_RFCS.includes(clean)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
const match = RFC_PATTERN.exec(clean);
|
|
47
|
+
if (!match || !isRealShortDate(match[2], match[3], match[4])) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return !strict || rfcCheckDigitOf(clean) === clean.at(-1);
|
|
51
|
+
}
|
|
52
|
+
function curpCheckDigitOf(curp) {
|
|
53
|
+
const body = curp.slice(0, CURP_BODY_LENGTH).toUpperCase();
|
|
54
|
+
let sum = 0;
|
|
55
|
+
for (let position = 0; position < CURP_BODY_LENGTH; position += 1) {
|
|
56
|
+
sum += CURP_CHECK_TABLE.indexOf(body[position]) * (CURP_BODY_LENGTH + 1 - position);
|
|
57
|
+
}
|
|
58
|
+
return String((DECIMAL_BASE - sum % DECIMAL_BASE) % DECIMAL_BASE);
|
|
59
|
+
}
|
|
60
|
+
function isValidCurp(curp) {
|
|
61
|
+
const clean = (curp ?? "").trim().toUpperCase();
|
|
62
|
+
const match = CURP_PATTERN.exec(clean);
|
|
63
|
+
return Boolean(match) && isRealShortDate(match[1], match[2], match[3]) && curpCheckDigitOf(clean) === clean.at(-1);
|
|
64
|
+
}
|
|
65
|
+
function clabeCheckDigitOf(clabe) {
|
|
66
|
+
let sum = 0;
|
|
67
|
+
for (let position = 0; position < 17; position += 1) {
|
|
68
|
+
sum += Number(clabe[position]) * CLABE_WEIGHTS[position % CLABE_WEIGHTS.length] % DECIMAL_BASE;
|
|
69
|
+
}
|
|
70
|
+
return String((DECIMAL_BASE - sum % DECIMAL_BASE) % DECIMAL_BASE);
|
|
71
|
+
}
|
|
72
|
+
function isValidClabe(clabe) {
|
|
73
|
+
const clean = (clabe ?? "").replace(/\s/g, "");
|
|
74
|
+
return CLABE_PATTERN.test(clean) && clabeCheckDigitOf(clean) === clean.at(-1);
|
|
75
|
+
}
|
|
76
|
+
const POSTAL_CODE_PATTERN = /^(?!00)\d{5}$/;
|
|
77
|
+
function isValidPostalCode(postalCode) {
|
|
78
|
+
return POSTAL_CODE_PATTERN.test((postalCode ?? "").replace(/\s/g, ""));
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
RFC_KIND,
|
|
82
|
+
clabeCheckDigitOf,
|
|
83
|
+
curpCheckDigitOf,
|
|
84
|
+
isValidClabe,
|
|
85
|
+
isValidCurp,
|
|
86
|
+
isValidPostalCode,
|
|
87
|
+
isValidRfc,
|
|
88
|
+
rfcCheckDigitOf,
|
|
89
|
+
rfcKindOf
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=mexicoIdentifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mexicoIdentifiers.js","sources":["../../src/mexico/mexicoIdentifiers.js"],"sourcesContent":["// Las claves de México que se escriben en casi cualquier sistema: el RFC (SAT), la CURP (RENAPO) y la CLABE (Banxico). Revisan\n// la forma de cada una y su dígito verificador, para avisar ANTES de mandar algo mal escrito. Lo que de verdad vale (que el\n// RFC exista, que la CLABE sea de esa persona) lo dice el SAT o el banco, del lado del servidor.\n//\n// Son estándares nacionales, no reglas de un cliente.\n//\n// Puro (sin React): se prueba con node (mexicoIdentifiers.test.js).\n//\n// Genérico del paquete: function (regla de la casa).\n\n// RFC: 3 letras (persona moral) o 4 (persona física), la fecha AAMMDD y la homoclave de 3 (la última es el dígito)\nconst RFC_PATTERN = /^([A-ZÑ&]{3,4})(\\d{2})(\\d{2})(\\d{2})([A-Z\\d]{2})([A\\d])$/;\n// los genéricos del SAT: público en general (nacional) y extranjero\nconst GENERIC_RFCS = Object.freeze(['XAXX010101000', 'XEXX010101000']);\nconst RFC_CHECK_TABLE = '0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ Ñ';\nconst RFC_CHECK_MODULUS = 11;\nconst RFC_CHECK_LENGTH = 12;\n\n// CURP: 4 letras, la fecha AAMMDD, el sexo (H, M o X), el estado (o NE: nacido en el extranjero), 3 consonantes, el carácter\n// que distingue al siglo y el dígito\nconst CURP_PATTERN = /^[A-Z][AEIOUX][A-Z]{2}(\\d{2})(\\d{2})(\\d{2})[HMX](AS|BC|BS|CC|CL|CM|CS|CH|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)[B-DF-HJ-NP-TV-Z]{3}[A-Z\\d]\\d$/;\nconst CURP_CHECK_TABLE = '0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ';\nconst CURP_BODY_LENGTH = 17;\n\n// CLABE: 18 dígitos; los pesos 3, 7, 1 se repiten sobre los primeros 17\nconst CLABE_PATTERN = /^\\d{18}$/;\nconst CLABE_WEIGHTS = Object.freeze([3, 7, 1]);\nconst DECIMAL_BASE = 10;\n\n/** De qué tipo es un RFC. */\nexport const RFC_KIND = Object.freeze({company: 'company', person: 'person', generic: 'generic'});\n\n/**\n * ¿La fecha AAMMDD existe? (el 31 de febrero no).\n *\n * @param {string} year dos dígitos\n * @param {string} month\n * @param {string} day\n * @returns {boolean}\n */\nfunction isRealShortDate(year, month, day) {\n // el siglo no importa para saber si el día existe, salvo el 29 de febrero: 2000 fue bisiesto y 1900 no, y las dos se\n // escriben «00». Se toma el 2000 (el de cualquier persona viva nacida un 29 de febrero «00»)\n const date = new Date(Date.UTC(2000 + Number(year), Number(month) - 1, Number(day)));\n return date.getUTCMonth() === Number(month) - 1 && date.getUTCDate() === Number(day);\n}\n\n/**\n * El dígito verificador de un RFC (el último carácter), calculado con el resto de 11 del SAT.\n *\n * @param {string} rfc el RFC completo (se ignora su último carácter)\n * @returns {string} '0'-'9' o 'A'\n */\nexport function rfcCheckDigitOf(rfc) {\n const body = rfc.slice(0, -1).toUpperCase();\n // la persona moral (11 sin el dígito) se rellena a 12 con un espacio al frente\n const padded = body.padStart(RFC_CHECK_LENGTH, ' ');\n let sum = 0;\n for (let position = 0; position < RFC_CHECK_LENGTH; position += 1) {\n sum += RFC_CHECK_TABLE.indexOf(padded[position]) * (RFC_CHECK_LENGTH + 1 - position);\n }\n const rest = sum % RFC_CHECK_MODULUS;\n if (rest === 0) {\n return '0';\n }\n return rest === 1 ? 'A' : String(RFC_CHECK_MODULUS - rest);\n}\n\n/**\n * De qué tipo es un RFC bien formado; null si no tiene la forma.\n *\n * @param {string|null|undefined} rfc\n * @returns {string|null} RFC_KIND\n */\nexport function rfcKindOf(rfc) {\n const clean = (rfc ?? '').trim().toUpperCase();\n if (GENERIC_RFCS.includes(clean)) {\n return RFC_KIND.generic;\n }\n const match = RFC_PATTERN.exec(clean);\n if (!match) {\n return null;\n }\n return match[1].length === 3 ? RFC_KIND.company : RFC_KIND.person;\n}\n\n/**\n * ¿El RFC está bien escrito? Revisa su forma (persona moral, física o genérico) y que la fecha exista.\n *\n * El dígito verificador va aparte (strict) y no por omisión: si un RFC real no lo cumpliera, la persona se quedaría sin poder\n * seguir, y quien dice si un RFC existe es el SAT.\n *\n * @param {string|null|undefined} rfc\n * @param {{strict?: boolean}} [options] strict: además, el dígito verificador\n * @returns {boolean}\n */\nexport function isValidRfc(rfc, {strict = false} = {}) {\n const clean = (rfc ?? '').trim().toUpperCase();\n if (GENERIC_RFCS.includes(clean)) {\n return true;\n }\n const match = RFC_PATTERN.exec(clean);\n if (!match || !isRealShortDate(match[2], match[3], match[4])) {\n return false;\n }\n return !strict || rfcCheckDigitOf(clean) === clean.at(-1);\n}\n\n/**\n * El dígito verificador de una CURP (el último).\n *\n * @param {string} curp la CURP completa (se ignora su último carácter)\n * @returns {string}\n */\nexport function curpCheckDigitOf(curp) {\n const body = curp.slice(0, CURP_BODY_LENGTH).toUpperCase();\n let sum = 0;\n for (let position = 0; position < CURP_BODY_LENGTH; position += 1) {\n sum += CURP_CHECK_TABLE.indexOf(body[position]) * (CURP_BODY_LENGTH + 1 - position);\n }\n return String((DECIMAL_BASE - (sum % DECIMAL_BASE)) % DECIMAL_BASE);\n}\n\n/**\n * ¿La CURP está bien escrita? Su forma (con el estado y el sexo), que la fecha exista y su dígito verificador.\n *\n * @param {string|null|undefined} curp\n * @returns {boolean}\n */\nexport function isValidCurp(curp) {\n const clean = (curp ?? '').trim().toUpperCase();\n const match = CURP_PATTERN.exec(clean);\n return Boolean(match) && isRealShortDate(match[1], match[2], match[3]) && curpCheckDigitOf(clean) === clean.at(-1);\n}\n\n/**\n * El dígito verificador de una CLABE (el 18.º).\n *\n * @param {string} clabe la CLABE completa o sus primeros 17 dígitos\n * @returns {string}\n */\nexport function clabeCheckDigitOf(clabe) {\n let sum = 0;\n for (let position = 0; position < 17; position += 1) {\n sum += (Number(clabe[position]) * CLABE_WEIGHTS[position % CLABE_WEIGHTS.length]) % DECIMAL_BASE;\n }\n return String((DECIMAL_BASE - (sum % DECIMAL_BASE)) % DECIMAL_BASE);\n}\n\n/**\n * ¿La CLABE está bien escrita? 18 dígitos (los espacios no cuentan) y su dígito verificador.\n *\n * @param {string|null|undefined} clabe\n * @returns {boolean}\n */\nexport function isValidClabe(clabe) {\n const clean = (clabe ?? '').replace(/\\s/g, '');\n return CLABE_PATTERN.test(clean) && clabeCheckDigitOf(clean) === clean.at(-1);\n}\n\n// el código postal de México: 5 dígitos; no hay códigos que empiecen con 00 (los estados van del 01 al 99)\nconst POSTAL_CODE_PATTERN = /^(?!00)\\d{5}$/;\n\n/**\n * ¿El código postal está bien escrito? 5 dígitos (los espacios no cuentan) que no empiezan con 00.\n *\n * @param {string|null|undefined} postalCode\n * @returns {boolean}\n */\nexport function isValidPostalCode(postalCode) {\n return POSTAL_CODE_PATTERN.test((postalCode ?? '').replace(/\\s/g, ''));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ruleMessageOf } from "../forms/validationMessages.js";
|
|
2
|
+
import { isValidClabe, isValidCurp, isValidPostalCode, isValidRfc } from "./mexicoIdentifiers.js";
|
|
3
|
+
function rfcRule({ strict = false } = {}) {
|
|
4
|
+
return { name: "rfc", message: ruleMessageOf("validation:rfc", "rfc"), test: (value) => !value || isValidRfc(String(value), { strict }) };
|
|
5
|
+
}
|
|
6
|
+
function curpRule() {
|
|
7
|
+
return { name: "curp", message: ruleMessageOf("validation:curp", "curp"), test: (value) => !value || isValidCurp(String(value)) };
|
|
8
|
+
}
|
|
9
|
+
function clabeRule() {
|
|
10
|
+
return { name: "clabe", message: ruleMessageOf("validation:clabe", "clabe"), test: (value) => !value || isValidClabe(String(value)) };
|
|
11
|
+
}
|
|
12
|
+
function postalCodeRule() {
|
|
13
|
+
return { name: "postalCode", message: ruleMessageOf("validation:postalCode", "postalCode"), test: (value) => !value || isValidPostalCode(String(value)) };
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
clabeRule,
|
|
17
|
+
curpRule,
|
|
18
|
+
postalCodeRule,
|
|
19
|
+
rfcRule
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=mexicoRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mexicoRules.js","sources":["../../src/mexico/mexicoRules.js"],"sourcesContent":["// Las reglas de yup para el RFC, la CURP, la CLABE y el código postal, con sus mensajes en el idioma activo (validation:rfc,\n// validation:curp, validation:clabe, validation:postalCode). Un campo vacío pasa: que sea obligatorio lo dice required().\n// Cada mensaje lleva su regla: la pantalla (messages del campo) o los textos del proyecto pueden poner el suyo sin tocar el esquema.\n//\n// Yup.object({rfc: Yup.string().required().test(rfcRule()), clabe: Yup.string().test(clabeRule())})\n//\n// Son objetos de .test() y no un Yup propio: el proyecto usa su copia de yup y aquí no se importa.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {ruleMessageOf} from '@/forms/validationMessages.js';\nimport {isValidClabe, isValidCurp, isValidPostalCode, isValidRfc} from '@/mexico/mexicoIdentifiers.js';\n\n/**\n * @param {{strict?: boolean}} [options] strict: también el dígito verificador (ver isValidRfc)\n * @returns {{name: string, message: {key: string, values: object, rule: string}, test: (value: unknown) => boolean}}\n */\nexport function rfcRule({strict = false} = {}) {\n return {name: 'rfc', message: ruleMessageOf('validation:rfc', 'rfc'), test: (value) => !value || isValidRfc(String(value), {strict})};\n}\n\n/** @returns {{name: string, message: {key: string, values: object, rule: string}, test: (value: unknown) => boolean}} */\nexport function curpRule() {\n return {name: 'curp', message: ruleMessageOf('validation:curp', 'curp'), test: (value) => !value || isValidCurp(String(value))};\n}\n\n/** @returns {{name: string, message: {key: string, values: object, rule: string}, test: (value: unknown) => boolean}} */\nexport function clabeRule() {\n return {name: 'clabe', message: ruleMessageOf('validation:clabe', 'clabe'), test: (value) => !value || isValidClabe(String(value))};\n}\n\n/** @returns {{name: string, message: {key: string, values: object, rule: string}, test: (value: unknown) => boolean}} */\nexport function postalCodeRule() {\n return {name: 'postalCode', message: ruleMessageOf('validation:postalCode', 'postalCode'), test: (value) => !value || isValidPostalCode(String(value))};\n}\n"],"names":[],"mappings":";;AAgBO,SAAS,QAAQ,EAAC,SAAS,MAAK,IAAI,CAAA,GAAI;AAC3C,SAAO,EAAC,MAAM,OAAO,SAAS,cAAc,kBAAkB,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,WAAW,OAAO,KAAK,GAAG,EAAC,OAAM,CAAC,EAAC;AACxI;AAGO,SAAS,WAAW;AACvB,SAAO,EAAC,MAAM,QAAQ,SAAS,cAAc,mBAAmB,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,YAAY,OAAO,KAAK,CAAC,EAAC;AAClI;AAGO,SAAS,YAAY;AACxB,SAAO,EAAC,MAAM,SAAS,SAAS,cAAc,oBAAoB,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,aAAa,OAAO,KAAK,CAAC,EAAC;AACtI;AAGO,SAAS,iBAAiB;AAC7B,SAAO,EAAC,MAAM,cAAc,SAAS,cAAc,yBAAyB,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,kBAAkB,OAAO,KAAK,CAAC,EAAC;AAC1J;"}
|
package/dist/mexico.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { RFC_KIND, clabeCheckDigitOf, curpCheckDigitOf, isValidClabe, isValidCurp, isValidPostalCode, isValidRfc, rfcCheckDigitOf, rfcKindOf } from "./mexico/mexicoIdentifiers.js";
|
|
2
|
+
import { clabeRule, curpRule, postalCodeRule, rfcRule } from "./mexico/mexicoRules.js";
|
|
3
|
+
import { CERTIFICATE_STATUS, certificateStatusOf, readCertificate } from "./mexico/certificateReader.js";
|
|
4
|
+
import { CFDI_VOUCHER_TYPE, readCfdi, readCfdiFile } from "./mexico/cfdiReader.js";
|
|
5
|
+
import { EFIRMA_KEY_PROBLEM, EfirmaKeyError, verifyEfirmaKey } from "./mexico/efirmaKey.js";
|
|
6
|
+
import { default as default2 } from "./mexico/CfdiSummary.js";
|
|
7
|
+
import { default as default3 } from "./mexico/EfirmaFields.js";
|
|
8
|
+
export {
|
|
9
|
+
CERTIFICATE_STATUS,
|
|
10
|
+
CFDI_VOUCHER_TYPE,
|
|
11
|
+
default2 as CfdiSummary,
|
|
12
|
+
EFIRMA_KEY_PROBLEM,
|
|
13
|
+
default3 as EfirmaFields,
|
|
14
|
+
EfirmaKeyError,
|
|
15
|
+
RFC_KIND,
|
|
16
|
+
certificateStatusOf,
|
|
17
|
+
clabeCheckDigitOf,
|
|
18
|
+
clabeRule,
|
|
19
|
+
curpCheckDigitOf,
|
|
20
|
+
curpRule,
|
|
21
|
+
isValidClabe,
|
|
22
|
+
isValidCurp,
|
|
23
|
+
isValidPostalCode,
|
|
24
|
+
isValidRfc,
|
|
25
|
+
postalCodeRule,
|
|
26
|
+
readCertificate,
|
|
27
|
+
readCfdi,
|
|
28
|
+
readCfdiFile,
|
|
29
|
+
rfcCheckDigitOf,
|
|
30
|
+
rfcKindOf,
|
|
31
|
+
rfcRule,
|
|
32
|
+
verifyEfirmaKey
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=mexico.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mexico.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
|
@@ -9,11 +9,11 @@ import { INSTALL_VARIANT } from "./installInstructions.js";
|
|
|
9
9
|
import InstallInstructionsDialog from "./InstallInstructionsDialog.js";
|
|
10
10
|
import { useInstallPrompt } from "./useInstallPrompt.js";
|
|
11
11
|
import ComponentTexts from "../toolkit/ComponentTexts.js";
|
|
12
|
-
import { piecePart } from "../theme/themePieces.js";
|
|
12
|
+
import { piecePart, withPieceSlots } from "../theme/themePieces.js";
|
|
13
13
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
14
14
|
const THEME_NAME = "CalcitaInstallAppSetting";
|
|
15
15
|
const InstallRoot = piecePart(THEME_NAME, "Root", Box);
|
|
16
|
-
function
|
|
16
|
+
function InstallAppSettingContent({ texts, ...unknownProps } = {}) {
|
|
17
17
|
warnUnknownProps("InstallAppSetting", unknownProps);
|
|
18
18
|
const { t } = useToolkitTranslation("common", texts);
|
|
19
19
|
const { variant, promptInstall } = useInstallPrompt();
|
|
@@ -33,6 +33,7 @@ function InstallAppSetting({ texts, ...unknownProps } = {}) {
|
|
|
33
33
|
/* @__PURE__ */ jsx(InstallInstructionsDialog, { variant, open: stepsOpen, onClose: () => setStepsOpen(false) })
|
|
34
34
|
] }) });
|
|
35
35
|
}
|
|
36
|
+
const InstallAppSetting = withPieceSlots(InstallAppSettingContent, THEME_NAME);
|
|
36
37
|
export {
|
|
37
38
|
InstallAppSetting as default
|
|
38
39
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstallAppSetting.js","sources":["../../src/pwa/InstallAppSetting.jsx"],"sourcesContent":["// «Instalar la app» dentro del menú de la cuenta (accountSettings de AppLayout): para quien dijo «Ahora no» a la invitación\n// y después sí la quiere. No respeta el «Ahora no» (aquí la persona la busca a propósito). Ya instalada o sin manera de\n// instalar en ese equipo, no pinta nada.\n//\n// El diálogo de los pasos va aquí mismo: el menú de la cuenta se queda abierto mientras se ve, y al cerrarlo se regresa al\n// menú.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaInstallAppSetting con defaultProps y\n// styleOverrides de sus partes: root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport InstallMobileRoundedIcon from '@mui/icons-material/InstallMobileRounded';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\nimport InstallInstructionsDialog from '@/pwa/InstallInstructionsDialog.jsx';\nimport {useInstallPrompt} from '@/pwa/useInstallPrompt.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport {piecePart} 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.CalcitaInstallAppSetting)\nconst THEME_NAME = 'CalcitaInstallAppSetting';\nconst InstallRoot = piecePart(THEME_NAME, 'Root', Box);\n\n/**\n * @param {object} [props]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"InstallAppSetting.js","sources":["../../src/pwa/InstallAppSetting.jsx"],"sourcesContent":["// «Instalar la app» dentro del menú de la cuenta (accountSettings de AppLayout): para quien dijo «Ahora no» a la invitación\n// y después sí la quiere. No respeta el «Ahora no» (aquí la persona la busca a propósito). Ya instalada o sin manera de\n// instalar en ese equipo, no pinta nada.\n//\n// El diálogo de los pasos va aquí mismo: el menú de la cuenta se queda abierto mientras se ve, y al cerrarlo se regresa al\n// menú.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaInstallAppSetting con defaultProps y\n// styleOverrides de sus partes: root.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport InstallMobileRoundedIcon from '@mui/icons-material/InstallMobileRounded';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\nimport InstallInstructionsDialog from '@/pwa/InstallInstructionsDialog.jsx';\nimport {useInstallPrompt} from '@/pwa/useInstallPrompt.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport {piecePart, 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.CalcitaInstallAppSetting)\nconst THEME_NAME = 'CalcitaInstallAppSetting';\nconst InstallRoot = piecePart(THEME_NAME, 'Root', Box);\n\n/**\n * @param {object} [props]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction InstallAppSettingContent({texts, ...unknownProps} = {}) {\n warnUnknownProps('InstallAppSetting', unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {variant, promptInstall} = useInstallPrompt();\n const [stepsOpen, setStepsOpen] = useState(false);\n\n if (!variant) {\n return null;\n }\n\n const handleClick = () => {\n if (variant === INSTALL_VARIANT.native) {\n promptInstall();\n } else {\n setStepsOpen(true);\n }\n };\n\n return (\n <ComponentTexts namespace=\"common\" texts={texts}>\n <InstallRoot ownSx={{px: 1, py: 0.5}}>\n <Button fullWidth variant=\"outlined\" startIcon={<InstallMobileRoundedIcon />} onClick={handleClick}>\n {t('install.menuLabel')}\n </Button>\n <InstallInstructionsDialog variant={variant} open={stepsOpen} onClose={() => setStepsOpen(false)} />\n </InstallRoot>\n </ComponentTexts>\n );\n}\n\nconst InstallAppSetting = withPieceSlots(InstallAppSettingContent, THEME_NAME);\nexport default InstallAppSetting;\n"],"names":[],"mappings":";;;;;;;;;;;;;AAyBA,MAAM,aAAa;AACnB,MAAM,cAAc,UAAU,YAAY,QAAQ,GAAG;AAMrD,SAAS,yBAAyB,EAAC,OAAO,GAAG,aAAA,IAAgB,CAAA,GAAI;AAC7D,mBAAiB,qBAAqB,YAAY;AAClD,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,SAAS,cAAA,IAAiB,iBAAA;AACjC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,MAAI,CAAC,SAAS;AACV,WAAO;AAAA,EACX;AAEA,QAAM,cAAc,MAAM;AACtB,QAAI,YAAY,gBAAgB,QAAQ;AACpC,oBAAA;AAAA,IACJ,OAAO;AACH,mBAAa,IAAI;AAAA,IACrB;AAAA,EACJ;AAEA,SACI,oBAAC,gBAAA,EAAe,WAAU,UAAS,OAC/B,UAAA,qBAAC,aAAA,EAAY,OAAO,EAAC,IAAI,GAAG,IAAI,OAC5B,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAO,WAAS,MAAC,SAAQ,YAAW,WAAW,oBAAC,0BAAA,CAAA,CAAyB,GAAI,SAAS,aAClF,UAAA,EAAE,mBAAmB,GAC1B;AAAA,IACA,oBAAC,6BAA0B,SAAkB,MAAM,WAAW,SAAS,MAAM,aAAa,KAAK,EAAA,CAAG;AAAA,EAAA,EAAA,CACtG,EAAA,CACJ;AAER;AAEA,MAAM,oBAAoB,eAAe,0BAA0B,UAAU;"}
|
|
@@ -8,7 +8,7 @@ import DialogTitle from "@mui/material/DialogTitle";
|
|
|
8
8
|
import Typography from "@mui/material/Typography";
|
|
9
9
|
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
10
10
|
import { INSTALL_VARIANT } from "./installInstructions.js";
|
|
11
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
11
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
12
12
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
13
13
|
const THEME_NAME = "CalcitaInstallInstructions";
|
|
14
14
|
const InstructionsSteps = piecePart(THEME_NAME, "Steps", Typography);
|
|
@@ -20,7 +20,7 @@ const STEPS_BY_VARIANT = Object.freeze({
|
|
|
20
20
|
function variantHasInstructions(variant) {
|
|
21
21
|
return Boolean(STEPS_BY_VARIANT[variant]);
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function InstallInstructionsDialogContent(props) {
|
|
24
24
|
const { variant, open, onClose, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
25
25
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
26
26
|
const { t } = useToolkitTranslation("common", texts);
|
|
@@ -34,6 +34,7 @@ function InstallInstructionsDialog(props) {
|
|
|
34
34
|
/* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(Button, { variant: "contained", onClick: onClose, children: t("install.gotIt") }) })
|
|
35
35
|
] });
|
|
36
36
|
}
|
|
37
|
+
const InstallInstructionsDialog = withPieceSlots(InstallInstructionsDialogContent, THEME_NAME);
|
|
37
38
|
export {
|
|
38
39
|
InstallInstructionsDialog as default,
|
|
39
40
|
variantHasInstructions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstallInstructionsDialog.js","sources":["../../src/pwa/InstallInstructionsDialog.jsx"],"sourcesContent":["// Los pasos para instalar la app a mano, según el equipo (iOS 26 cambió el camino; Firefox usa su propio menú). Lo usan la\n// invitación (InstallPromptBanner) y la entrada del menú de la cuenta (InstallAppSetting): los dos abren el mismo diálogo.\n// Si la variante no lleva pasos (el navegador tiene su propio diálogo, o no hay nada que ofrecer) no pinta nada.\n//\n// OJO, para quien lo monte: NO dentro de un Menu de MUI que se cierra; el Menu quita a sus hijos al cerrarse y el diálogo\n// nunca aparecería. Va junto al Menu o en un lugar que se quede pintado.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaInstallInstructions con defaultProps y\n// styleOverrides de sus partes: steps.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Typography from '@mui/material/Typography';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.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.CalcitaInstallInstructions)\nconst THEME_NAME = 'CalcitaInstallInstructions';\nconst InstructionsSteps = piecePart(THEME_NAME, 'Steps', Typography);\n\n// cada variante con pasos a mano → su título y sus pasos en los textos del paquete (common:install.<variante>)\nconst STEPS_BY_VARIANT = Object.freeze({\n [INSTALL_VARIANT.iosModern]: ['step1', 'step2', 'step3', 'step4'],\n [INSTALL_VARIANT.iosClassic]: ['step1', 'step2', 'step3'],\n [INSTALL_VARIANT.androidFirefox]: ['step1', 'step2', 'step3'],\n});\n\n/**\n * ¿Esta variante se instala con pasos a mano (y no con el diálogo del navegador)?\n *\n * @param {string|null} variant\n * @returns {boolean}\n */\nexport function variantHasInstructions(variant) {\n return Boolean(STEPS_BY_VARIANT[variant]);\n}\n\n/**\n * @param {object} props\n * @param {string|null} props.variant una de INSTALL_VARIANT (useInstallPrompt)\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"InstallInstructionsDialog.js","sources":["../../src/pwa/InstallInstructionsDialog.jsx"],"sourcesContent":["// Los pasos para instalar la app a mano, según el equipo (iOS 26 cambió el camino; Firefox usa su propio menú). Lo usan la\n// invitación (InstallPromptBanner) y la entrada del menú de la cuenta (InstallAppSetting): los dos abren el mismo diálogo.\n// Si la variante no lleva pasos (el navegador tiene su propio diálogo, o no hay nada que ofrecer) no pinta nada.\n//\n// OJO, para quien lo monte: NO dentro de un Menu de MUI que se cierra; el Menu quita a sus hijos al cerrarse y el diálogo\n// nunca aparecería. Va junto al Menu o en un lugar que se quede pintado.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaInstallInstructions con defaultProps y\n// styleOverrides de sus partes: steps.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Typography from '@mui/material/Typography';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.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.CalcitaInstallInstructions)\nconst THEME_NAME = 'CalcitaInstallInstructions';\nconst InstructionsSteps = piecePart(THEME_NAME, 'Steps', Typography);\n\n// cada variante con pasos a mano → su título y sus pasos en los textos del paquete (common:install.<variante>)\nconst STEPS_BY_VARIANT = Object.freeze({\n [INSTALL_VARIANT.iosModern]: ['step1', 'step2', 'step3', 'step4'],\n [INSTALL_VARIANT.iosClassic]: ['step1', 'step2', 'step3'],\n [INSTALL_VARIANT.androidFirefox]: ['step1', 'step2', 'step3'],\n});\n\n/**\n * ¿Esta variante se instala con pasos a mano (y no con el diálogo del navegador)?\n *\n * @param {string|null} variant\n * @returns {boolean}\n */\nexport function variantHasInstructions(variant) {\n return Boolean(STEPS_BY_VARIANT[variant]);\n}\n\n/**\n * @param {object} props\n * @param {string|null} props.variant una de INSTALL_VARIANT (useInstallPrompt)\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction InstallInstructionsDialogContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaInstallInstructions.defaultProps) y encima lo que llega aquí\n const {variant, open, onClose, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const steps = STEPS_BY_VARIANT[variant];\n if (!steps) {\n return null;\n }\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{t(`install.${variant}.title`)}</DialogTitle>\n <DialogContent>\n {/* pasos numerados con palabras, sin dibujar los íconos del sistema: cambian entre versiones */}\n <InstructionsSteps component=\"ol\" ownSx={{m: 0, pl: 3, display: 'grid', gap: 1.25}}>\n {steps.map((step) => (\n <Typography key={step} component=\"li\" variant=\"body1\">{t(`install.${variant}.${step}`)}</Typography>\n ))}\n </InstructionsSteps>\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" onClick={onClose}>{t('install.gotIt')}</Button>\n </DialogActions>\n </Dialog>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst InstallInstructionsDialog = withPieceSlots(InstallInstructionsDialogContent, THEME_NAME);\nexport default InstallInstructionsDialog;\n"],"names":[],"mappings":";;;;;;;;;;;;AAwBA,MAAM,aAAa;AACnB,MAAM,oBAAoB,UAAU,YAAY,SAAS,UAAU;AAGnE,MAAM,mBAAmB,OAAO,OAAO;AAAA,EACnC,CAAC,gBAAgB,SAAS,GAAG,CAAC,SAAS,SAAS,SAAS,OAAO;AAAA,EAChE,CAAC,gBAAgB,UAAU,GAAG,CAAC,SAAS,SAAS,OAAO;AAAA,EACxD,CAAC,gBAAgB,cAAc,GAAG,CAAC,SAAS,SAAS,OAAO;AAChE,CAAC;AAQM,SAAS,uBAAuB,SAAS;AAC5C,SAAO,QAAQ,iBAAiB,OAAO,CAAC;AAC5C;AASA,SAAS,iCAAiC,OAAO;AAE7C,QAAM,EAAC,SAAS,MAAM,SAAS,OAAO,GAAG,iBAAgB,cAAc,OAAO,UAAU;AACxF,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,QAAQ,iBAAiB,OAAO;AACtC,MAAI,CAAC,OAAO;AACR,WAAO;AAAA,EACX;AAEA,8BACK,QAAA,EAAO,MAAY,SAAkB,UAAS,MAAK,WAAS,MACzD,UAAA;AAAA,IAAA,oBAAC,aAAA,EAAa,UAAA,EAAE,WAAW,OAAO,QAAQ,GAAE;AAAA,wBAC3C,eAAA,EAEG,UAAA,oBAAC,mBAAA,EAAkB,WAAU,MAAK,OAAO,EAAC,GAAG,GAAG,IAAI,GAAG,SAAS,QAAQ,KAAK,QACxE,UAAA,MAAM,IAAI,CAAC,SACR,oBAAC,YAAA,EAAsB,WAAU,MAAK,SAAQ,SAAS,UAAA,EAAE,WAAW,OAAO,IAAI,IAAI,EAAE,KAApE,IAAsE,CAC1F,GACL,GACJ;AAAA,IACA,oBAAC,eAAA,EACG,UAAA,oBAAC,QAAA,EAAO,SAAQ,aAAY,SAAS,SAAU,UAAA,EAAE,eAAe,EAAA,CAAE,EAAA,CACtE;AAAA,EAAA,GACJ;AAER;AAGA,MAAM,4BAA4B,eAAe,kCAAkC,UAAU;"}
|
|
@@ -14,13 +14,13 @@ import { INSTALL_VARIANT } from "./installInstructions.js";
|
|
|
14
14
|
import InstallInstructionsDialog from "./InstallInstructionsDialog.js";
|
|
15
15
|
import { useInstallPrompt } from "./useInstallPrompt.js";
|
|
16
16
|
import ComponentTexts from "../toolkit/ComponentTexts.js";
|
|
17
|
-
import { piecePart, usePieceProps } from "../theme/themePieces.js";
|
|
17
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
18
18
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
19
19
|
const THEME_NAME = "CalcitaInstallPromptBanner";
|
|
20
20
|
const PromptRoot = piecePart(THEME_NAME, "Root", Snackbar);
|
|
21
21
|
const PromptAlert = piecePart(THEME_NAME, "Alert", Alert);
|
|
22
22
|
const TAB_BAR_GAP_PIXELS = 8;
|
|
23
|
-
function
|
|
23
|
+
function InstallPromptBannerContent(props) {
|
|
24
24
|
const { message, onInstallChoice, onShowSteps, onDismiss, texts, ...unknownProps } = usePieceProps(props, THEME_NAME);
|
|
25
25
|
warnUnknownProps(THEME_NAME, unknownProps);
|
|
26
26
|
const { t } = useToolkitTranslation("common", texts);
|
|
@@ -71,6 +71,7 @@ function InstallPromptBanner(props) {
|
|
|
71
71
|
/* @__PURE__ */ jsx(InstallInstructionsDialog, { variant, open: stepsOpen, onClose: handleStepsClose })
|
|
72
72
|
] }) });
|
|
73
73
|
}
|
|
74
|
+
const InstallPromptBanner = withPieceSlots(InstallPromptBannerContent, THEME_NAME);
|
|
74
75
|
export {
|
|
75
76
|
InstallPromptBanner as default
|
|
76
77
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstallPromptBanner.js","sources":["../../src/pwa/InstallPromptBanner.jsx"],"sourcesContent":["// La invitación a instalar la app, abajo al centro. Según el equipo (useInstallPrompt): con el diálogo del navegador, el\n// botón «Instalar»; en iPhone, iPad y Firefox de Android, «Cómo instalar» abre los pasos (InstallInstructionsDialog).\n// Ya instalada, sin manera de instalar o después de «Ahora no», no pinta nada; quien se arrepienta la encuentra en el menú\n// de la cuenta (InstallAppSetting).\n//\n// Color de información, no de advertencia: instalar es una sugerencia, no un problema. En el teléfono con vidrio va encima\n// de la barra de pestañas; sin ella, respeta la zona del gesto de inicio del iPhone.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaInstallPromptBanner con defaultProps y\n// styleOverrides de sus partes: root, alert.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Alert from '@mui/material/Alert';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Snackbar from '@mui/material/Snackbar';\nimport CloseRoundedIcon from '@mui/icons-material/CloseRounded';\nimport InstallMobileRoundedIcon from '@mui/icons-material/InstallMobileRounded';\n\nimport {aboveMobileTabBarOf} from '@/appShell/shellSizes.js';\nimport {usesMobileTabBar} from '@/appShell/tabBarRule.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\nimport InstallInstructionsDialog from '@/pwa/InstallInstructionsDialog.jsx';\nimport {useInstallPrompt} from '@/pwa/useInstallPrompt.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport {piecePart, usePieceProps} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaInstallPromptBanner)\nconst THEME_NAME = 'CalcitaInstallPromptBanner';\nconst PromptRoot = piecePart(THEME_NAME, 'Root', Snackbar);\nconst PromptAlert = piecePart(THEME_NAME, 'Alert', Alert);\n\n// lo que se separa de la barra de pestañas (px)\nconst TAB_BAR_GAP_PIXELS = 8;\n\n/**\n * @param {object} [props]\n * @param {string} [props.message] ya traducido; por omisión el del paquete con el nombre de la app (appName de ToolkitProvider)\n * @param {(outcome: 'accepted'|'dismissed'|null) => void} [props.onInstallChoice] lo que contestó la persona al diálogo de\n * instalar del navegador (Chrome, Edge, Android)\n * @param {() => void} [props.onShowSteps] abrió los pasos para instalar (iPhone, iPad, Firefox de Android)\n * @param {() => void} [props.onDismiss] dijo «Ahora no» (o cerró los pasos): no se le vuelve a ofrecer en este navegador\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\
|
|
1
|
+
{"version":3,"file":"InstallPromptBanner.js","sources":["../../src/pwa/InstallPromptBanner.jsx"],"sourcesContent":["// La invitación a instalar la app, abajo al centro. Según el equipo (useInstallPrompt): con el diálogo del navegador, el\n// botón «Instalar»; en iPhone, iPad y Firefox de Android, «Cómo instalar» abre los pasos (InstallInstructionsDialog).\n// Ya instalada, sin manera de instalar o después de «Ahora no», no pinta nada; quien se arrepienta la encuentra en el menú\n// de la cuenta (InstallAppSetting).\n//\n// Color de información, no de advertencia: instalar es una sugerencia, no un problema. En el teléfono con vidrio va encima\n// de la barra de pestañas; sin ella, respeta la zona del gesto de inicio del iPhone.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaInstallPromptBanner con defaultProps y\n// styleOverrides de sus partes: root, alert.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Alert from '@mui/material/Alert';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Snackbar from '@mui/material/Snackbar';\nimport CloseRoundedIcon from '@mui/icons-material/CloseRounded';\nimport InstallMobileRoundedIcon from '@mui/icons-material/InstallMobileRounded';\n\nimport {aboveMobileTabBarOf} from '@/appShell/shellSizes.js';\nimport {usesMobileTabBar} from '@/appShell/tabBarRule.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\nimport InstallInstructionsDialog from '@/pwa/InstallInstructionsDialog.jsx';\nimport {useInstallPrompt} from '@/pwa/useInstallPrompt.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaInstallPromptBanner)\nconst THEME_NAME = 'CalcitaInstallPromptBanner';\nconst PromptRoot = piecePart(THEME_NAME, 'Root', Snackbar);\nconst PromptAlert = piecePart(THEME_NAME, 'Alert', Alert);\n\n// lo que se separa de la barra de pestañas (px)\nconst TAB_BAR_GAP_PIXELS = 8;\n\n/**\n * @param {object} [props]\n * @param {string} [props.message] ya traducido; por omisión el del paquete con el nombre de la app (appName de ToolkitProvider)\n * @param {(outcome: 'accepted'|'dismissed'|null) => void} [props.onInstallChoice] lo que contestó la persona al diálogo de\n * instalar del navegador (Chrome, Edge, Android)\n * @param {() => void} [props.onShowSteps] abrió los pasos para instalar (iPhone, iPad, Firefox de Android)\n * @param {() => void} [props.onDismiss] dijo «Ahora no» (o cerró los pasos): no se le vuelve a ofrecer en este navegador\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nfunction InstallPromptBannerContent(props) {\n // lo que el proyecto puso en su tema (components.CalcitaInstallPromptBanner.defaultProps) y encima lo que llega aquí\n const {message, onInstallChoice, onShowSteps, onDismiss, texts, ...unknownProps} = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('common', texts);\n const {variant, dismissed, promptInstall, dismiss} = useInstallPrompt();\n const [stepsOpen, setStepsOpen] = useState(false);\n\n // nada que ofrecer o ya dijo «Ahora no»\n if (!variant || dismissed) {\n return null;\n }\n\n const isNative = variant === INSTALL_VARIANT.native;\n\n const handleAction = async () => {\n if (isNative) {\n onInstallChoice?.(await promptInstall());\n } else {\n setStepsOpen(true);\n onShowSteps?.();\n }\n };\n const handleDismiss = () => {\n dismiss();\n onDismiss?.();\n };\n\n // si ya vio los pasos, no se le vuelven a ofrecer en cada visita\n const handleStepsClose = () => {\n setStepsOpen(false);\n handleDismiss();\n };\n\n return (\n <ComponentTexts namespace=\"common\" texts={texts}>\n <>\n <PromptRoot open anchorOrigin={{vertical: 'bottom', horizontal: 'center'}}\n ownSx={(theme) => (usesMobileTabBar(theme)\n ? aboveMobileTabBarOf(TAB_BAR_GAP_PIXELS)\n : {mb: 'env(safe-area-inset-bottom)'})}>\n <PromptAlert severity=\"info\" icon={<InstallMobileRoundedIcon />} ownSx={{width: '100%', alignItems: 'center'}}\n action={(\n <>\n <Button color=\"inherit\" size=\"small\" onClick={handleAction}>\n {isNative ? t('install.action') : t('install.howTo')}\n </Button>\n <IconButton size=\"small\" color=\"inherit\" aria-label={t('install.dismiss')} onClick={handleDismiss}>\n <CloseRoundedIcon fontSize=\"small\" />\n </IconButton>\n </>\n )}>\n {message ?? t('install.banner')}\n </PromptAlert>\n </PromptRoot>\n <InstallInstructionsDialog variant={variant} open={stepsOpen} onClose={handleStepsClose} />\n </>\n </ComponentTexts>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst InstallPromptBanner = withPieceSlots(InstallPromptBannerContent, THEME_NAME);\nexport default InstallPromptBanner;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AA+BA,MAAM,aAAa;AACnB,MAAM,aAAa,UAAU,YAAY,QAAQ,QAAQ;AACzD,MAAM,cAAc,UAAU,YAAY,SAAS,KAAK;AAGxD,MAAM,qBAAqB;AAW3B,SAAS,2BAA2B,OAAO;AAEvC,QAAM,EAAC,SAAS,iBAAiB,aAAa,WAAW,OAAO,GAAG,aAAA,IAAgB,cAAc,OAAO,UAAU;AAClH,mBAAiB,YAAY,YAAY;AACzC,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,SAAS,WAAW,eAAe,QAAA,IAAW,iBAAA;AACrD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAGhD,MAAI,CAAC,WAAW,WAAW;AACvB,WAAO;AAAA,EACX;AAEA,QAAM,WAAW,YAAY,gBAAgB;AAE7C,QAAM,eAAe,YAAY;AAC7B,QAAI,UAAU;AACV,wBAAkB,MAAM,eAAe;AAAA,IAC3C,OAAO;AACH,mBAAa,IAAI;AACjB,oBAAA;AAAA,IACJ;AAAA,EACJ;AACA,QAAM,gBAAgB,MAAM;AACxB,YAAA;AACA,gBAAA;AAAA,EACJ;AAGA,QAAM,mBAAmB,MAAM;AAC3B,iBAAa,KAAK;AAClB,kBAAA;AAAA,EACJ;AAEA,SACI,oBAAC,gBAAA,EAAe,WAAU,UAAS,OAC/B,UAAA,qBAAA,UAAA,EACI,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QAAW,MAAI;AAAA,QAAC,cAAc,EAAC,UAAU,UAAU,YAAY,SAAA;AAAA,QACtD,OAAO,CAAC,UAAW,iBAAiB,KAAK,IACnC,oBAAoB,kBAAkB,IACtC,EAAC,IAAI,8BAAA;AAAA,QACjB,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YAAY,UAAS;AAAA,YAAO,0BAAO,0BAAA,EAAyB;AAAA,YAAI,OAAO,EAAC,OAAO,QAAQ,YAAY,SAAA;AAAA,YAC7F,QACI,qBAAA,UAAA,EACI,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAO,OAAM,WAAU,MAAK,SAAQ,SAAS,cACzC,UAAA,WAAW,EAAE,gBAAgB,IAAI,EAAE,eAAe,GACvD;AAAA,kCACC,YAAA,EAAW,MAAK,SAAQ,OAAM,WAAU,cAAY,EAAE,iBAAiB,GAAG,SAAS,eAChF,UAAA,oBAAC,kBAAA,EAAiB,UAAS,SAAQ,EAAA,CACvC;AAAA,YAAA,GACJ;AAAA,YAEN,UAAA,WAAW,EAAE,gBAAgB;AAAA,UAAA;AAAA,QAAA;AAAA,MAClC;AAAA,IAAA;AAAA,wBAEH,2BAAA,EAA0B,SAAkB,MAAM,WAAW,SAAS,iBAAA,CAAkB;AAAA,EAAA,EAAA,CAC7F,EAAA,CACJ;AAER;AAGA,MAAM,sBAAsB,eAAe,4BAA4B,UAAU;"}
|
package/dist/react-hook-form.js
CHANGED
|
@@ -1,32 +1,58 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { Controller, FormProvider, useForm, useFormContext } from "react-hook-form";
|
|
2
|
+
import { Controller, FormProvider, useFieldArray, useForm, useFormContext, useWatch } from "react-hook-form";
|
|
3
3
|
import { yupResolver } from "@hookform/resolvers/yup";
|
|
4
|
-
import { default as default2 } from "./hookForm/
|
|
5
|
-
import { default as default3 } from "./hookForm/
|
|
6
|
-
import { default as default4 } from "./hookForm/
|
|
7
|
-
import { default as default5 } from "./hookForm/
|
|
8
|
-
import { default as default6 } from "./hookForm/
|
|
9
|
-
import { default as default7 } from "./hookForm/
|
|
10
|
-
import { default as default8 } from "./hookForm/
|
|
11
|
-
import { default as default9 } from "./hookForm/
|
|
4
|
+
import { default as default2 } from "./hookForm/FormAttachmentsField.js";
|
|
5
|
+
import { default as default3 } from "./hookForm/FormCatalogField.js";
|
|
6
|
+
import { default as default4 } from "./hookForm/FormCheckboxGroupField.js";
|
|
7
|
+
import { default as default5 } from "./hookForm/FormColorField.js";
|
|
8
|
+
import { default as default6 } from "./hookForm/FormFileField.js";
|
|
9
|
+
import { default as default7 } from "./hookForm/FormFileUploadField.js";
|
|
10
|
+
import { default as default8 } from "./hookForm/FormImageField.js";
|
|
11
|
+
import { default as default9 } from "./hookForm/FormMaskedField.js";
|
|
12
|
+
import { default as default10 } from "./hookForm/FormNumberField.js";
|
|
13
|
+
import { default as default11 } from "./hookForm/FormProblemAlert.js";
|
|
14
|
+
import { default as default12 } from "./hookForm/FormRepeatingFields.js";
|
|
15
|
+
import { default as default13 } from "./hookForm/FormTransferListField.js";
|
|
16
|
+
import { listTotalAtMostRule, listTotalOf, orderedInListRule, uniqueInListRule } from "./forms/listRules.js";
|
|
17
|
+
import { percentRule, sameAsFieldRule } from "./forms/fieldRules.js";
|
|
18
|
+
import { default as default14 } from "./hookForm/FormSelectField.js";
|
|
19
|
+
import { default as default15 } from "./hookForm/FormWizard.js";
|
|
20
|
+
import { default as default16 } from "./hookForm/FormTextField.js";
|
|
21
|
+
import { default as default17 } from "./hookForm/SubmitButton.js";
|
|
12
22
|
import { SERVER_PROBLEM_ROOT, applyServerProblem } from "./hookForm/applyServerProblem.js";
|
|
13
23
|
import { useHookFormField } from "./hookForm/useHookFormField.js";
|
|
14
24
|
export {
|
|
15
25
|
Controller,
|
|
16
|
-
default2 as
|
|
17
|
-
default3 as
|
|
18
|
-
default4 as
|
|
19
|
-
default5 as
|
|
26
|
+
default2 as FormAttachmentsField,
|
|
27
|
+
default3 as FormCatalogField,
|
|
28
|
+
default4 as FormCheckboxGroupField,
|
|
29
|
+
default5 as FormColorField,
|
|
30
|
+
default6 as FormFileField,
|
|
31
|
+
default7 as FormFileUploadField,
|
|
32
|
+
default8 as FormImageField,
|
|
33
|
+
default9 as FormMaskedField,
|
|
34
|
+
default10 as FormNumberField,
|
|
35
|
+
default11 as FormProblemAlert,
|
|
20
36
|
FormProvider,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
37
|
+
default12 as FormRepeatingFields,
|
|
38
|
+
default14 as FormSelectField,
|
|
39
|
+
default16 as FormTextField,
|
|
40
|
+
default13 as FormTransferListField,
|
|
41
|
+
default15 as FormWizard,
|
|
24
42
|
SERVER_PROBLEM_ROOT,
|
|
25
|
-
|
|
43
|
+
default17 as SubmitButton,
|
|
26
44
|
applyServerProblem,
|
|
45
|
+
listTotalAtMostRule,
|
|
46
|
+
listTotalOf,
|
|
47
|
+
orderedInListRule,
|
|
48
|
+
percentRule,
|
|
49
|
+
sameAsFieldRule,
|
|
50
|
+
uniqueInListRule,
|
|
51
|
+
useFieldArray,
|
|
27
52
|
useForm,
|
|
28
53
|
useFormContext,
|
|
29
54
|
useHookFormField,
|
|
55
|
+
useWatch,
|
|
30
56
|
yupResolver
|
|
31
57
|
};
|
|
32
58
|
//# sourceMappingURL=react-hook-form.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-hook-form.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"react-hook-form.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { default as default2 } from "./richText/FormRichTextField.js";
|
|
2
|
+
import { default as default3 } from "./richText/RichTextEditor.js";
|
|
3
|
+
import { default as default4 } from "./richText/RichTextView.js";
|
|
4
|
+
import { DEFAULT_RICH_TEXT_FEATURES, RICH_TEXT_FEATURE, SAFE_LINK_PROTOCOLS, isSafeLinkUrl, linkUrlOf, normalizedHtmlOf } from "./richText/richTextRules.js";
|
|
5
|
+
import { RICH_TEXT_HEADING_LEVELS, richTextExtensionsOf } from "./richText/richTextExtensions.js";
|
|
6
|
+
export {
|
|
7
|
+
DEFAULT_RICH_TEXT_FEATURES,
|
|
8
|
+
default2 as FormRichTextField,
|
|
9
|
+
RICH_TEXT_FEATURE,
|
|
10
|
+
RICH_TEXT_HEADING_LEVELS,
|
|
11
|
+
default3 as RichTextEditor,
|
|
12
|
+
default4 as RichTextView,
|
|
13
|
+
SAFE_LINK_PROTOCOLS,
|
|
14
|
+
isSafeLinkUrl,
|
|
15
|
+
linkUrlOf,
|
|
16
|
+
normalizedHtmlOf,
|
|
17
|
+
richTextExtensionsOf
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=rich-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-text.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useFormikField } from "../forms/useFormikField.js";
|
|
4
|
+
import RichTextEditor from "./RichTextEditor.js";
|
|
5
|
+
function FormRichTextField({ name, ...editorProps }) {
|
|
6
|
+
const fieldProps = useFormikField(name);
|
|
7
|
+
return /* @__PURE__ */ jsx(RichTextEditor, { ...editorProps, ...fieldProps });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FormRichTextField as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=FormRichTextField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRichTextField.js","sources":["../../src/richText/FormRichTextField.jsx"],"sourcesContent":["// Campo de texto con formato de formik: RichTextEditor conectado a su campo. Al formulario llega el HTML ('' si no hay nada\n// escrito).\n//\n// Con react-hook-form no hay uno listo (esta puerta no pide react-hook-form): RichTextEditor va dentro de un Controller.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useFormikField} from '@/forms/useFormikField.js';\nimport RichTextEditor from '@/richText/RichTextEditor.jsx';\n\n/**\n * @param {{name: string} & Omit<Parameters<typeof import('@/richText/RichTextEditor.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las de\n * RichTextEditor (features, maxLength, placeholder…), sin value / onChange / onBlur / error\n */\nexport default function FormRichTextField({name, ...editorProps}) {\n const fieldProps = useFormikField(name);\n return <RichTextEditor {...editorProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAaA,SAAwB,kBAAkB,EAAC,MAAM,GAAG,eAAc;AAC9D,QAAM,aAAa,eAAe,IAAI;AACtC,SAAO,oBAAC,gBAAA,EAAgB,GAAG,aAAc,GAAG,WAAA,CAAY;AAC5D;"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useRef, useEffect } from "react";
|
|
4
|
+
import { useEditor, useEditorState, EditorContent } from "@tiptap/react";
|
|
5
|
+
import FormHelperText from "@mui/material/FormHelperText";
|
|
6
|
+
import Paper from "@mui/material/Paper";
|
|
7
|
+
import Stack from "@mui/material/Stack";
|
|
8
|
+
import Box from "@mui/material/Box";
|
|
9
|
+
import { useValidationText } from "../forms/useValidationText.js";
|
|
10
|
+
import FieldFrame from "../inputs/FieldFrame.js";
|
|
11
|
+
import { richTextContentSxOf } from "./richTextContentSx.js";
|
|
12
|
+
import { richTextExtensionsOf } from "./richTextExtensions.js";
|
|
13
|
+
import { DEFAULT_RICH_TEXT_FEATURES, normalizedHtmlOf } from "./richTextRules.js";
|
|
14
|
+
import RichTextToolbar from "./RichTextToolbar.js";
|
|
15
|
+
import { piecePart, withPieceSlots, usePieceProps } from "../theme/themePieces.js";
|
|
16
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
17
|
+
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
18
|
+
const THEME_NAME = "CalcitaRichTextEditor";
|
|
19
|
+
const EditorRoot = piecePart(THEME_NAME, "Root", Paper);
|
|
20
|
+
const EditorToolbar = piecePart(THEME_NAME, "Toolbar", Stack);
|
|
21
|
+
const EditorContentArea = piecePart(THEME_NAME, "Content", Box);
|
|
22
|
+
const EditorFooter = piecePart(THEME_NAME, "Footer", Stack);
|
|
23
|
+
const DEFAULT_MIN_HEIGHT = 160;
|
|
24
|
+
function RichTextEditorContent(props) {
|
|
25
|
+
const {
|
|
26
|
+
name,
|
|
27
|
+
label,
|
|
28
|
+
value,
|
|
29
|
+
onChange,
|
|
30
|
+
onBlur,
|
|
31
|
+
placeholder,
|
|
32
|
+
error,
|
|
33
|
+
helperText = " ",
|
|
34
|
+
maxLength,
|
|
35
|
+
features = DEFAULT_RICH_TEXT_FEATURES,
|
|
36
|
+
extensions,
|
|
37
|
+
toolbarActions,
|
|
38
|
+
onEditorReady,
|
|
39
|
+
minHeight = DEFAULT_MIN_HEIGHT,
|
|
40
|
+
disabled = false,
|
|
41
|
+
sx,
|
|
42
|
+
messages,
|
|
43
|
+
texts,
|
|
44
|
+
...unknownProps
|
|
45
|
+
} = usePieceProps(props, THEME_NAME);
|
|
46
|
+
warnUnknownProps(THEME_NAME, unknownProps);
|
|
47
|
+
const { t } = useToolkitTranslation("richText", texts);
|
|
48
|
+
const validationTextOf = useValidationText({ name, label, messages });
|
|
49
|
+
const generatedId = useId();
|
|
50
|
+
const contentId = `${name ?? "rich-text"}-${generatedId}`;
|
|
51
|
+
const labelId = `${contentId}-label`;
|
|
52
|
+
const errorText = validationTextOf(error);
|
|
53
|
+
const latest = useRef({ onChange, onBlur, onEditorReady });
|
|
54
|
+
latest.current = { onChange, onBlur, onEditorReady };
|
|
55
|
+
const editor = useEditor({
|
|
56
|
+
extensions: richTextExtensionsOf({ features, placeholder, maxLength, extensions }),
|
|
57
|
+
content: value ?? "",
|
|
58
|
+
editable: !disabled,
|
|
59
|
+
// OJO: sin esto, al pintar en el servidor (Next) el editor avisa que no hay documento todavía
|
|
60
|
+
immediatelyRender: false,
|
|
61
|
+
editorProps: {
|
|
62
|
+
attributes: { id: contentId, role: "textbox", "aria-multiline": "true", "aria-labelledby": labelId, ...errorText && { "aria-invalid": "true" } }
|
|
63
|
+
},
|
|
64
|
+
onUpdate: ({ editor: current }) => latest.current.onChange(normalizedHtmlOf(current.getHTML())),
|
|
65
|
+
onBlur: () => latest.current.onBlur?.(),
|
|
66
|
+
onCreate: ({ editor: current }) => latest.current.onEditorReady?.(current)
|
|
67
|
+
}, [features.join(","), placeholder, maxLength, Boolean(errorText)]);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (editor && normalizedHtmlOf(editor.getHTML()) !== (value ?? "")) {
|
|
70
|
+
editor.commands.setContent(value ?? "", { emitUpdate: false });
|
|
71
|
+
}
|
|
72
|
+
}, [editor, value]);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
editor?.setEditable(!disabled);
|
|
75
|
+
}, [editor, disabled]);
|
|
76
|
+
const characters = useEditorState({ editor, selector: ({ editor: current }) => current?.storage.characterCount?.characters() ?? 0 });
|
|
77
|
+
return /* @__PURE__ */ jsx(FieldFrame, { inputId: contentId, labelId, label, children: /* @__PURE__ */ jsxs("div", { children: [
|
|
78
|
+
/* @__PURE__ */ jsxs(EditorRoot, { variant: "outlined", ownSx: (theme) => ({
|
|
79
|
+
borderRadius: 2,
|
|
80
|
+
overflow: "hidden",
|
|
81
|
+
opacity: disabled ? 0.6 : 1,
|
|
82
|
+
borderColor: errorText ? "error.main" : "divider",
|
|
83
|
+
"&:focus-within": { borderColor: errorText ? "error.main" : "primary.main", boxShadow: `0 0 0 1px ${(theme.vars ?? theme).palette[errorText ? "error" : "primary"].main}` }
|
|
84
|
+
}), sx, children: [
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
EditorToolbar,
|
|
87
|
+
{
|
|
88
|
+
role: "toolbar",
|
|
89
|
+
"aria-label": t("toolbar.label"),
|
|
90
|
+
"aria-controls": contentId,
|
|
91
|
+
direction: "row",
|
|
92
|
+
ownSx: { alignItems: "center", flexWrap: "wrap", gap: 0.25, px: 0.5, py: 0.5, borderBottom: 1, borderColor: "divider" },
|
|
93
|
+
children: /* @__PURE__ */ jsx(RichTextToolbar, { editor, features, disabled, t, actions: toolbarActions })
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
/* @__PURE__ */ jsx(EditorContentArea, { ownSx: (theme) => {
|
|
97
|
+
const content = richTextContentSxOf(theme);
|
|
98
|
+
return { ...content, px: 2, py: 1.5, cursor: "text", "& .tiptap": { ...content["& .tiptap"], minHeight } };
|
|
99
|
+
}, onClick: () => editor?.commands.focus(), children: /* @__PURE__ */ jsx(EditorContent, { editor }) })
|
|
100
|
+
] }),
|
|
101
|
+
/* @__PURE__ */ jsxs(EditorFooter, { direction: "row", ownSx: { justifyContent: "space-between", gap: 2 }, children: [
|
|
102
|
+
/* @__PURE__ */ jsx(FormHelperText, { error: Boolean(errorText), children: errorText ?? helperText }),
|
|
103
|
+
maxLength && /* @__PURE__ */ jsx(FormHelperText, { sx: { fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" }, children: t("counter", { count: characters, max: maxLength }) })
|
|
104
|
+
] })
|
|
105
|
+
] }) });
|
|
106
|
+
}
|
|
107
|
+
const RichTextEditor = withPieceSlots(RichTextEditorContent, THEME_NAME);
|
|
108
|
+
export {
|
|
109
|
+
RichTextEditor as default
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=RichTextEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichTextEditor.js","sources":["../../src/richText/RichTextEditor.jsx"],"sourcesContent":["// El editor de texto con formato (Tiptap), con la etiqueta arriba como los demás campos del paquete: negrita, cursiva,\n// títulos, listas, cita, código, ligas seguras, alineación, deshacer y rehacer, y el contador de caracteres si hay tope.\n//\n// Viaja HTML ('<p>Hola <strong>mundo</strong></p>'); '' si no hay nada escrito (así required() funciona). Para ENSEÑAR lo\n// guardado va RichTextView, que solo deja pasar lo que el editor entiende: un <script> o un onclick pegado no llegan a la\n// página.\n//\n// Extensible sin tocar el paquete: features (qué botones trae; lo que no se pide tampoco entra al documento), extensions\n// (extensiones de Tiptap del proyecto: menciones, tablas…), toolbarActions (botones propios al final de la barra) y\n// onEditorReady (el editor de Tiptap, para lo que la barra no trae). Con formik: FormRichTextField; con react-hook-form, dentro\n// de un Controller.\n//\n// Se cambia desde el tema del proyecto, como las piezas de MUI: components.CalcitaRichTextEditor con defaultProps y\n// styleOverrides de sus partes: root, toolbar, content, footer.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useId, useRef} from 'react';\nimport {EditorContent, useEditor, useEditorState} from '@tiptap/react';\nimport FormHelperText from '@mui/material/FormHelperText';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Box from '@mui/material/Box';\n\nimport {useValidationText} from '@/forms/useValidationText.js';\nimport FieldFrame from '@/inputs/FieldFrame.jsx';\nimport {richTextContentSxOf} from '@/richText/richTextContentSx.js';\nimport {richTextExtensionsOf} from '@/richText/richTextExtensions.js';\nimport {DEFAULT_RICH_TEXT_FEATURES, normalizedHtmlOf} from '@/richText/richTextRules.js';\nimport RichTextToolbar from '@/richText/RichTextToolbar.jsx';\nimport {piecePart, usePieceProps, withPieceSlots} from '@/theme/themePieces.js';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n// el nombre de la pieza en el tema y sus partes (theme.components.CalcitaRichTextEditor)\nconst THEME_NAME = 'CalcitaRichTextEditor';\nconst EditorRoot = piecePart(THEME_NAME, 'Root', Paper);\nconst EditorToolbar = piecePart(THEME_NAME, 'Toolbar', Stack);\nconst EditorContentArea = piecePart(THEME_NAME, 'Content', Box);\nconst EditorFooter = piecePart(THEME_NAME, 'Footer', Stack);\n\nconst DEFAULT_MIN_HEIGHT = 160;\n\n/**\n * @param {object} props\n * @param {string} [props.name]\n * @param {import('react').ReactNode} props.label ya traducida\n * @param {string|null|undefined} props.value el HTML guardado ('' sin texto)\n * @param {(html: string) => void} props.onChange recibe el HTML ('' si se borra todo)\n * @param {() => void} [props.onBlur]\n * @param {string} [props.placeholder] ya traducido: lo que se ve con el editor vacío\n * @param {string|{key: string, values?: object}} [props.error]\n * @param {string} [props.helperText] ya traducida\n * @param {number} [props.maxLength] el tope de caracteres (con su contador abajo)\n * @param {string[]} [props.features] los botones de la barra (RICH_TEXT_FEATURE); por omisión todos\n * @param {Array<object>} [props.extensions] extensiones de Tiptap del proyecto\n * @param {import('react').ReactNode} [props.toolbarActions] botones propios al final de la barra\n * @param {(editor: import('@tiptap/react').Editor) => void} [props.onEditorReady] el editor de Tiptap, al estar listo\n * @param {number} [props.minHeight] el alto mínimo del texto en px; por omisión 160\n * @param {boolean} [props.disabled]\n * @param {object} [props.sx]\n * @param {Record<string, string|object>} [props.messages] el texto del error de este campo, por regla de validación\n * ({required: 'Escriba el RFC', matches: 'El RFC lleva 12 o 13 caracteres'}): gana al de Calcita y al de los textos\n * @param {object} [props.texts] los textos que cambian, con la forma de `richText` en los textos del paquete\n */\nfunction RichTextEditorContent(props) {\n const {\n name, label, value, onChange, onBlur, placeholder, error, helperText = ' ', maxLength, features = DEFAULT_RICH_TEXT_FEATURES, extensions,\n toolbarActions, onEditorReady, minHeight = DEFAULT_MIN_HEIGHT, disabled = false, sx, messages, texts,\n ...unknownProps\n } = usePieceProps(props, THEME_NAME);\n warnUnknownProps(THEME_NAME, unknownProps);\n const {t} = useToolkitTranslation('richText', texts);\n // el texto del error: el de la pantalla (messages), el del proyecto para este campo o el de Calcita\n const validationTextOf = useValidationText({name, label, messages});\n const generatedId = useId();\n const contentId = `${name ?? 'rich-text'}-${generatedId}`;\n const labelId = `${contentId}-label`;\n const errorText = validationTextOf(error);\n // lo último de afuera, sin rearmar el editor cada vez que la pantalla pinta otra función\n const latest = useRef({onChange, onBlur, onEditorReady});\n latest.current = {onChange, onBlur, onEditorReady};\n\n const editor = useEditor({\n extensions: richTextExtensionsOf({features, placeholder, maxLength, extensions}),\n content: value ?? '',\n editable: !disabled,\n // OJO: sin esto, al pintar en el servidor (Next) el editor avisa que no hay documento todavía\n immediatelyRender: false,\n editorProps: {\n attributes: {id: contentId, role: 'textbox', 'aria-multiline': 'true', 'aria-labelledby': labelId, ...(errorText && {'aria-invalid': 'true'})},\n },\n onUpdate: ({editor: current}) => latest.current.onChange(normalizedHtmlOf(current.getHTML())),\n onBlur: () => latest.current.onBlur?.(),\n onCreate: ({editor: current}) => latest.current.onEditorReady?.(current),\n }, [features.join(','), placeholder, maxLength, Boolean(errorText)]);\n\n // lo que llega de afuera (el formulario se reinició, llegó del servidor) entra sin avisar otro cambio\n useEffect(() => {\n if (editor && normalizedHtmlOf(editor.getHTML()) !== (value ?? '')) {\n editor.commands.setContent(value ?? '', {emitUpdate: false});\n }\n }, [editor, value]);\n useEffect(() => {\n editor?.setEditable(!disabled);\n }, [editor, disabled]);\n\n const characters = useEditorState({editor, selector: ({editor: current}) => current?.storage.characterCount?.characters() ?? 0});\n\n return (\n <FieldFrame inputId={contentId} labelId={labelId} label={label}>\n <div>\n <EditorRoot variant=\"outlined\" ownSx={(theme) => ({\n borderRadius: 2, overflow: 'hidden', opacity: disabled ? 0.6 : 1,\n borderColor: errorText ? 'error.main' : 'divider',\n '&:focus-within': {borderColor: errorText ? 'error.main' : 'primary.main', boxShadow: `0 0 0 1px ${(theme.vars ?? theme).palette[errorText ? 'error' : 'primary'].main}`},\n })} sx={sx}>\n <EditorToolbar role=\"toolbar\" aria-label={t('toolbar.label')} aria-controls={contentId} direction=\"row\"\n ownSx={{alignItems: 'center', flexWrap: 'wrap', gap: 0.25, px: 0.5, py: 0.5, borderBottom: 1, borderColor: 'divider'}}>\n <RichTextToolbar editor={editor} features={features} disabled={disabled} t={t} actions={toolbarActions} />\n </EditorToolbar>\n <EditorContentArea ownSx={(theme) => {\n const content = richTextContentSxOf(theme);\n return {...content, px: 2, py: 1.5, cursor: 'text', '& .tiptap': {...content['& .tiptap'], minHeight}};\n }} onClick={() => editor?.commands.focus()}>\n <EditorContent editor={editor} />\n </EditorContentArea>\n </EditorRoot>\n <EditorFooter direction=\"row\" ownSx={{justifyContent: 'space-between', gap: 2}}>\n <FormHelperText error={Boolean(errorText)}>{errorText ?? helperText}</FormHelperText>\n {maxLength && (\n <FormHelperText sx={{fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap'}}>\n {t('counter', {count: characters, max: maxLength})}\n </FormHelperText>\n )}\n </EditorFooter>\n </div>\n </FieldFrame>\n );\n}\n\n// lo que se exporta: la pieza con slots y slotProps para cambiar sus partes (themePieces.js)\nconst RichTextEditor = withPieceSlots(RichTextEditorContent, THEME_NAME);\nexport default RichTextEditor;\n"],"names":[],"mappings":"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"}
|