@stackcraftmx/calcita 0.0.0-stage → 0.23.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/LICENSE +110 -0
- package/README.md +611 -2
- package/cli/askQuestions.js +63 -0
- package/cli/calcita.js +150 -0
- package/cli/makeComponent.js +50 -0
- package/cli/makeForm.js +68 -0
- package/cli/makeModule.js +78 -0
- package/cli/makePage.js +62 -0
- package/cli/names.js +64 -0
- package/cli/newProject.js +103 -0
- package/cli/packageVersions.js +38 -0
- package/cli/projectAnswers.js +145 -0
- package/cli/projectConfig.js +38 -0
- package/cli/projectFiles.js +126 -0
- package/cli/screenLabels.js +41 -0
- package/cli/templateFiles.js +186 -0
- package/cli/templates/component/core/__ComponentName__.jsx.tpl +23 -0
- package/cli/templates/component/module/__ComponentName__.jsx.tpl +21 -0
- package/cli/templates/form/formik/__FormName__.jsx.tpl +50 -0
- package/cli/templates/form/hookForm/__FormName__.jsx.tpl +53 -0
- package/cli/templates/form/shared/__formName__Schema.js.tpl +20 -0
- package/cli/templates/form/shared/__formName__Texts.js.tpl +6 -0
- package/cli/templates/module/__Name__Page.jsx.tpl +75 -0
- package/cli/templates/module/__name__Api.js.tpl +39 -0
- package/cli/templates/module/__name__Texts.js.tpl +27 -0
- package/cli/templates/module/menu.js.tpl +21 -0
- package/cli/templates/module/routes.js.tpl +7 -0
- package/cli/templates/moduleServer/__name__Server.js.tpl +68 -0
- package/cli/templates/page/__PageName__Page.jsx.tpl +22 -0
- package/cli/templates/page/__pageName__PageTexts.js.tpl +23 -0
- package/cli/templates/project/README.md.tpl +55 -0
- package/cli/templates/project/dot-gitignore.tpl +11 -0
- package/cli/templates/project/index.html.tpl +20 -0
- package/cli/templates/project/jsconfig.json.tpl +16 -0
- package/cli/templates/project/pnpm-workspace.yaml.tpl +5 -0
- package/cli/templates/project/public/favicon.svg +1 -0
- package/cli/templates/project/public/icons/apple-touch-icon.png +0 -0
- package/cli/templates/project/public/icons/icon-192.png +0 -0
- package/cli/templates/project/public/icons/icon-512-maskable.png +0 -0
- package/cli/templates/project/public/icons/icon-512.png +0 -0
- package/cli/templates/project/public/manifest.webmanifest.tpl +17 -0
- package/cli/templates/project/src/app/AppProviders.jsx.tpl +102 -0
- package/cli/templates/project/src/app/AppShell.jsx.tpl +87 -0
- package/cli/templates/project/src/app/appRouter.jsx.tpl +49 -0
- package/cli/templates/project/src/app/appSettings.js.tpl +13 -0
- package/cli/templates/project/src/app/appTexts.js.tpl +15 -0
- package/cli/templates/project/src/app/combineTexts.js.tpl +31 -0
- package/cli/templates/project/src/app/i18n.js.tpl +19 -0
- package/cli/templates/project/src/app/shellTexts.js.tpl +16 -0
- package/cli/templates/project/src/core/AppLogo.jsx.tpl +12 -0
- package/cli/templates/project/src/core/accountConnector.js.tpl +36 -0
- package/cli/templates/project/src/core/apiClient.js.tpl +15 -0
- package/cli/templates/project/src/core/appPaths.js.tpl +11 -0
- package/cli/templates/project/src/core/index.js.tpl +8 -0
- package/cli/templates/project/src/fakeServer/networkDelay.js.tpl +40 -0
- package/cli/templates/project/src/fakeServer/serverText.js.tpl +20 -0
- package/cli/templates/project/src/main.jsx.tpl +24 -0
- package/cli/templates/project/src/modules/auth/ForgotPasswordPage.jsx.tpl +14 -0
- package/cli/templates/project/src/modules/auth/ResetPasswordPage.jsx.tpl +15 -0
- package/cli/templates/project/src/modules/auth/SignInPage.jsx.tpl +29 -0
- package/cli/templates/project/src/modules/auth/authTexts.js.tpl +6 -0
- package/cli/templates/project/src/modules/auth/routes.js.tpl +11 -0
- package/cli/templates/project/src/modules/home/HomePage.jsx.tpl +38 -0
- package/cli/templates/project/src/modules/home/homeTexts.js.tpl +29 -0
- package/cli/templates/project/src/modules/home/menu.js.tpl +17 -0
- package/cli/templates/project/src/modules/home/routes.js.tpl +4 -0
- package/cli/templates/project/src/modules/profile/ProfilePage.jsx.tpl +13 -0
- package/cli/templates/project/src/modules/profile/routes.js.tpl +6 -0
- package/cli/templates/project/vite.config.js.tpl +27 -0
- package/dist/DataTable/AuditTrailDialog.js +40 -0
- package/dist/DataTable/AuditTrailDialog.js.map +1 -0
- package/dist/DataTable/AuditTrailTable.js +87 -0
- package/dist/DataTable/AuditTrailTable.js.map +1 -0
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js +71 -0
- package/dist/DataTable/ColumnFilters/HeaderFilterPopover.js.map +1 -0
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +50 -0
- package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -0
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js +54 -0
- package/dist/DataTable/ColumnFilters/SortableFilterHeader.js.map +1 -0
- package/dist/DataTable/ColumnFilters/TextColumnFilter.js +24 -0
- package/dist/DataTable/ColumnFilters/TextColumnFilter.js.map +1 -0
- package/dist/DataTable/EmptyState.js +22 -0
- package/dist/DataTable/EmptyState.js.map +1 -0
- package/dist/DataTable/FilterChips.js +39 -0
- package/dist/DataTable/FilterChips.js.map +1 -0
- package/dist/DataTable/GoToPage.js +62 -0
- package/dist/DataTable/GoToPage.js.map +1 -0
- package/dist/DataTable/ServerTable.js +407 -0
- package/dist/DataTable/ServerTable.js.map +1 -0
- package/dist/DataTable/buildChipConfig.js +27 -0
- package/dist/DataTable/buildChipConfig.js.map +1 -0
- package/dist/DataTable/columns.js +122 -0
- package/dist/DataTable/columns.js.map +1 -0
- package/dist/DataTable/filterContext.js +15 -0
- package/dist/DataTable/filterContext.js.map +1 -0
- package/dist/DataTable/serverTableParams.js +19 -0
- package/dist/DataTable/serverTableParams.js.map +1 -0
- package/dist/DataTable/tableMachine.js +87 -0
- package/dist/DataTable/tableMachine.js.map +1 -0
- package/dist/DataTable/useDebouncedFilter.js +29 -0
- package/dist/DataTable/useDebouncedFilter.js.map +1 -0
- package/dist/DataTable/useTableState.js +132 -0
- package/dist/DataTable/useTableState.js.map +1 -0
- package/dist/access/Can.js +9 -0
- package/dist/access/Can.js.map +1 -0
- package/dist/access/PermissionMatrix.js +83 -0
- package/dist/access/PermissionMatrix.js.map +1 -0
- package/dist/access/RequireAccess.js +14 -0
- package/dist/access/RequireAccess.js.map +1 -0
- package/dist/access/accessRules.js +49 -0
- package/dist/access/accessRules.js.map +1 -0
- package/dist/access/permissionGroups.js +43 -0
- package/dist/access/permissionGroups.js.map +1 -0
- package/dist/access/useCan.js +12 -0
- package/dist/access/useCan.js.map +1 -0
- package/dist/account/AccountProvider.js +58 -0
- package/dist/account/AccountProvider.js.map +1 -0
- package/dist/account/AccountSecuritySection.js +81 -0
- package/dist/account/AccountSecuritySection.js.map +1 -0
- package/dist/account/DemoTotpCodeButton.js +26 -0
- package/dist/account/DemoTotpCodeButton.js.map +1 -0
- package/dist/account/ForgotPasswordScreen.js +26 -0
- package/dist/account/ForgotPasswordScreen.js.map +1 -0
- package/dist/account/ProfileScreen.js +108 -0
- package/dist/account/ProfileScreen.js.map +1 -0
- package/dist/account/ResetPasswordScreen.js +57 -0
- package/dist/account/ResetPasswordScreen.js.map +1 -0
- package/dist/account/SignInScreen.js +101 -0
- package/dist/account/SignInScreen.js.map +1 -0
- package/dist/account/accountConnector.js +31 -0
- package/dist/account/accountConnector.js.map +1 -0
- package/dist/account/demo/createDemoAccountConnector.js +368 -0
- package/dist/account/demo/createDemoAccountConnector.js.map +1 -0
- package/dist/account/demo/totp.js +61 -0
- package/dist/account/demo/totp.js.map +1 -0
- package/dist/account/restAccountConnector.js +117 -0
- package/dist/account/restAccountConnector.js.map +1 -0
- package/dist/account-demo.js +12 -0
- package/dist/account-demo.js.map +1 -0
- package/dist/account.js +25 -0
- package/dist/account.js.map +1 -0
- package/dist/adapters/i18next.js +7 -0
- package/dist/adapters/i18next.js.map +1 -0
- package/dist/adapters/nextNavigation.js +36 -0
- package/dist/adapters/nextNavigation.js.map +1 -0
- package/dist/adapters/reactRouter.js +7 -0
- package/dist/adapters/reactRouter.js.map +1 -0
- package/dist/adapters/reactRouterRoutes.js +48 -0
- package/dist/adapters/reactRouterRoutes.js.map +1 -0
- package/dist/api/ApiError.js +58 -0
- package/dist/api/ApiError.js.map +1 -0
- package/dist/api/createApiClient.js +226 -0
- package/dist/api/createApiClient.js.map +1 -0
- package/dist/api/staleChunks.js +47 -0
- package/dist/api/staleChunks.js.map +1 -0
- package/dist/appShell/AccountMenu.js +86 -0
- package/dist/appShell/AccountMenu.js.map +1 -0
- package/dist/appShell/AppLayout.js +493 -0
- package/dist/appShell/AppLayout.js.map +1 -0
- package/dist/appShell/AppearanceSettings.js +93 -0
- package/dist/appShell/AppearanceSettings.js.map +1 -0
- package/dist/appShell/AuthLayout.js +44 -0
- package/dist/appShell/AuthLayout.js.map +1 -0
- package/dist/appShell/BarActionButton.js +31 -0
- package/dist/appShell/BarActionButton.js.map +1 -0
- package/dist/appShell/BarActions.js +94 -0
- package/dist/appShell/BarActions.js.map +1 -0
- package/dist/appShell/BarCapsule.js +35 -0
- package/dist/appShell/BarCapsule.js.map +1 -0
- package/dist/appShell/HeaderTools.js +53 -0
- package/dist/appShell/HeaderTools.js.map +1 -0
- package/dist/appShell/MobileTabBar.js +346 -0
- package/dist/appShell/MobileTabBar.js.map +1 -0
- package/dist/appShell/SettingsMenu.js +41 -0
- package/dist/appShell/SettingsMenu.js.map +1 -0
- package/dist/appShell/SideMenu.js +217 -0
- package/dist/appShell/SideMenu.js.map +1 -0
- package/dist/appShell/SideMenuEntry.js +140 -0
- package/dist/appShell/SideMenuEntry.js.map +1 -0
- package/dist/appShell/SubmenuActionsMenu.js +71 -0
- package/dist/appShell/SubmenuActionsMenu.js.map +1 -0
- package/dist/appShell/TabBarEditor.js +55 -0
- package/dist/appShell/TabBarEditor.js.map +1 -0
- package/dist/appShell/TopMenu.js +80 -0
- package/dist/appShell/TopMenu.js.map +1 -0
- package/dist/appShell/appMenuContext.js +11 -0
- package/dist/appShell/appMenuContext.js.map +1 -0
- package/dist/appShell/barActionsSlot.js +26 -0
- package/dist/appShell/barActionsSlot.js.map +1 -0
- package/dist/appShell/barMenuPlacement.js +33 -0
- package/dist/appShell/barMenuPlacement.js.map +1 -0
- package/dist/appShell/menuItemText.js +33 -0
- package/dist/appShell/menuItemText.js.map +1 -0
- package/dist/appShell/pageTitle.js +45 -0
- package/dist/appShell/pageTitle.js.map +1 -0
- package/dist/appShell/shellSizes.js +38 -0
- package/dist/appShell/shellSizes.js.map +1 -0
- package/dist/appShell/tabBarRule.js +12 -0
- package/dist/appShell/tabBarRule.js.map +1 -0
- package/dist/appShell/tabBarScroll.js +23 -0
- package/dist/appShell/tabBarScroll.js.map +1 -0
- package/dist/appShell/useDrawerCollapsed.js +29 -0
- package/dist/appShell/useDrawerCollapsed.js.map +1 -0
- package/dist/appShell/useFittingActionCount.js +45 -0
- package/dist/appShell/useFittingActionCount.js.map +1 -0
- package/dist/appShell/usePinnedMobileTabs.js +32 -0
- package/dist/appShell/usePinnedMobileTabs.js.map +1 -0
- package/dist/appShell/useTabBarMinimized.js +33 -0
- package/dist/appShell/useTabBarMinimized.js.map +1 -0
- package/dist/auth/PasswordChecklist.js +44 -0
- package/dist/auth/PasswordChecklist.js.map +1 -0
- package/dist/auth/passwordRules.js +43 -0
- package/dist/auth/passwordRules.js.map +1 -0
- package/dist/calendar/EventCalendar.js +138 -0
- package/dist/calendar/EventCalendar.js.map +1 -0
- package/dist/calendar.js +6 -0
- package/dist/calendar.js.map +1 -0
- package/dist/charts.js +7 -0
- package/dist/charts.js.map +1 -0
- package/dist/date-pickers.js +8 -0
- package/dist/date-pickers.js.map +1 -0
- package/dist/datePickers/DateInput.js +75 -0
- package/dist/datePickers/DateInput.js.map +1 -0
- package/dist/datePickers/FormDateField.js +12 -0
- package/dist/datePickers/FormDateField.js.map +1 -0
- package/dist/dates.js +25 -0
- package/dist/dates.js.map +1 -0
- package/dist/dictionaries/dictionaries.js +48 -0
- package/dist/dictionaries/dictionaries.js.map +1 -0
- package/dist/downloads/DownloadManager.js +201 -0
- package/dist/downloads/DownloadManager.js.map +1 -0
- package/dist/downloads/downloadQueue.js +54 -0
- package/dist/downloads/downloadQueue.js.map +1 -0
- package/dist/downloads/downloadsMachine.js +77 -0
- package/dist/downloads/downloadsMachine.js.map +1 -0
- package/dist/excel/reportWorkbook.js +299 -0
- package/dist/excel/reportWorkbook.js.map +1 -0
- package/dist/excel.js +13 -0
- package/dist/excel.js.map +1 -0
- package/dist/feedback/ConfirmDialog.js +72 -0
- package/dist/feedback/ConfirmDialog.js.map +1 -0
- package/dist/feedback/ModalWaiting.js +23 -0
- package/dist/feedback/ModalWaiting.js.map +1 -0
- package/dist/feedback/NewBuildNotice.js +79 -0
- package/dist/feedback/NewBuildNotice.js.map +1 -0
- package/dist/feedback/StaleBuildBoundary.js +36 -0
- package/dist/feedback/StaleBuildBoundary.js.map +1 -0
- package/dist/feedback/Toaster.js +20 -0
- package/dist/feedback/Toaster.js.map +1 -0
- package/dist/feedback/confirmActionMachine.js +67 -0
- package/dist/feedback/confirmActionMachine.js.map +1 -0
- package/dist/feedback/toast.js +88 -0
- package/dist/feedback/toast.js.map +1 -0
- package/dist/feedback/useConfirmAction.js +40 -0
- package/dist/feedback/useConfirmAction.js.map +1 -0
- package/dist/filepond/FileDropzone.js +254 -0
- package/dist/filepond/FileDropzone.js.map +1 -0
- package/dist/filepond/pondServer.js +48 -0
- package/dist/filepond/pondServer.js.map +1 -0
- package/dist/filepond.js +10 -0
- package/dist/filepond.js.map +1 -0
- package/dist/files.js +43 -0
- package/dist/files.js.map +1 -0
- package/dist/formatting.js +177 -0
- package/dist/formatting.js.map +1 -0
- package/dist/forms/FormCatalogField.js +12 -0
- package/dist/forms/FormCatalogField.js.map +1 -0
- package/dist/forms/FormColorField.js +12 -0
- package/dist/forms/FormColorField.js.map +1 -0
- package/dist/forms/FormNumberField.js +12 -0
- package/dist/forms/FormNumberField.js.map +1 -0
- package/dist/forms/FormProblemAlert.js +15 -0
- package/dist/forms/FormProblemAlert.js.map +1 -0
- package/dist/forms/FormSelectField.js +12 -0
- package/dist/forms/FormSelectField.js.map +1 -0
- package/dist/forms/FormServerProblem.js +23 -0
- package/dist/forms/FormServerProblem.js.map +1 -0
- package/dist/forms/FormTextField.js +12 -0
- package/dist/forms/FormTextField.js.map +1 -0
- package/dist/forms/FormWizard.js +90 -0
- package/dist/forms/FormWizard.js.map +1 -0
- package/dist/forms/SubmitButton.js +14 -0
- package/dist/forms/SubmitButton.js.map +1 -0
- package/dist/forms/applyServerProblem.js +15 -0
- package/dist/forms/applyServerProblem.js.map +1 -0
- package/dist/forms/auth/ChangePasswordForm.js +46 -0
- package/dist/forms/auth/ChangePasswordForm.js.map +1 -0
- package/dist/forms/auth/ForgotPasswordForm.js +50 -0
- package/dist/forms/auth/ForgotPasswordForm.js.map +1 -0
- package/dist/forms/auth/SignInForm.js +48 -0
- package/dist/forms/auth/SignInForm.js.map +1 -0
- package/dist/forms/security/SecondStepForm.js +122 -0
- package/dist/forms/security/SecondStepForm.js.map +1 -0
- package/dist/forms/security/TwoStepVerificationCard.js +336 -0
- package/dist/forms/security/TwoStepVerificationCard.js.map +1 -0
- package/dist/forms/security/securityRules.js +28 -0
- package/dist/forms/security/securityRules.js.map +1 -0
- package/dist/forms/serverProblemFields.js +25 -0
- package/dist/forms/serverProblemFields.js.map +1 -0
- package/dist/forms/useFormikField.js +16 -0
- package/dist/forms/useFormikField.js.map +1 -0
- package/dist/forms/validation.js +55 -0
- package/dist/forms/validation.js.map +1 -0
- package/dist/forms/validationMessages.js +16 -0
- package/dist/forms/validationMessages.js.map +1 -0
- package/dist/forms.js +57 -0
- package/dist/forms.js.map +1 -0
- package/dist/hookForm/FormCatalogField.js +12 -0
- package/dist/hookForm/FormCatalogField.js.map +1 -0
- package/dist/hookForm/FormColorField.js +12 -0
- package/dist/hookForm/FormColorField.js.map +1 -0
- package/dist/hookForm/FormNumberField.js +12 -0
- package/dist/hookForm/FormNumberField.js.map +1 -0
- package/dist/hookForm/FormProblemAlert.js +17 -0
- package/dist/hookForm/FormProblemAlert.js.map +1 -0
- package/dist/hookForm/FormSelectField.js +12 -0
- package/dist/hookForm/FormSelectField.js.map +1 -0
- package/dist/hookForm/FormTextField.js +12 -0
- package/dist/hookForm/FormTextField.js.map +1 -0
- package/dist/hookForm/SubmitButton.js +15 -0
- package/dist/hookForm/SubmitButton.js.map +1 -0
- package/dist/hookForm/applyServerProblem.js +21 -0
- package/dist/hookForm/applyServerProblem.js.map +1 -0
- package/dist/hookForm/useHookFormField.js +19 -0
- package/dist/hookForm/useHookFormField.js.map +1 -0
- package/dist/i18next.js +5 -0
- package/dist/i18next.js.map +1 -0
- package/dist/identifiers.js +8 -0
- package/dist/identifiers.js.map +1 -0
- package/dist/inbox/InboxLayout.js +68 -0
- package/dist/inbox/InboxLayout.js.map +1 -0
- package/dist/inbox/MessageList.js +64 -0
- package/dist/inbox/MessageList.js.map +1 -0
- package/dist/inbox/MessageView.js +53 -0
- package/dist/inbox/MessageView.js.map +1 -0
- package/dist/inbox/inboxDates.js +8 -0
- package/dist/inbox/inboxDates.js.map +1 -0
- package/dist/index.js +383 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs/CatalogInput.js +62 -0
- package/dist/inputs/CatalogInput.js.map +1 -0
- package/dist/inputs/ColorInput.js +108 -0
- package/dist/inputs/ColorInput.js.map +1 -0
- package/dist/inputs/FieldFrame.js +20 -0
- package/dist/inputs/FieldFrame.js.map +1 -0
- package/dist/inputs/FormSection.js +105 -0
- package/dist/inputs/FormSection.js.map +1 -0
- package/dist/inputs/NumberInput.js +69 -0
- package/dist/inputs/NumberInput.js.map +1 -0
- package/dist/inputs/SelectInput.js +66 -0
- package/dist/inputs/SelectInput.js.map +1 -0
- package/dist/inputs/TextInput.js +97 -0
- package/dist/inputs/TextInput.js.map +1 -0
- package/dist/inputs/colorContrast.js +46 -0
- package/dist/inputs/colorContrast.js.map +1 -0
- package/dist/inputs/formLayoutContext.js +9 -0
- package/dist/inputs/formLayoutContext.js.map +1 -0
- package/dist/inputs/numberText.js +48 -0
- package/dist/inputs/numberText.js.map +1 -0
- package/dist/kanban/KanbanBoard.js +113 -0
- package/dist/kanban/KanbanBoard.js.map +1 -0
- package/dist/kanban/kanbanMoves.js +29 -0
- package/dist/kanban/kanbanMoves.js.map +1 -0
- package/dist/kanban.js +9 -0
- package/dist/kanban.js.map +1 -0
- package/dist/laravel/csrfRetry.js +18 -0
- package/dist/laravel/csrfRetry.js.map +1 -0
- package/dist/laravel.js +6 -0
- package/dist/laravel.js.map +1 -0
- package/dist/lastListUrl.js +35 -0
- package/dist/lastListUrl.js.map +1 -0
- package/dist/locales/en.js +714 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/es.js +714 -0
- package/dist/locales/es.js.map +1 -0
- package/dist/maps/MapView.js +96 -0
- package/dist/maps/MapView.js.map +1 -0
- package/dist/maps/mapMarkers.js +19 -0
- package/dist/maps/mapMarkers.js.map +1 -0
- package/dist/maps.js +10 -0
- package/dist/maps.js.map +1 -0
- package/dist/money/money.js +380 -0
- package/dist/money/money.js.map +1 -0
- package/dist/money.js +6 -0
- package/dist/money.js.map +1 -0
- package/dist/navigation/appMenu.js +93 -0
- package/dist/navigation/appMenu.js.map +1 -0
- package/dist/navigation/useMenuBadges.js +45 -0
- package/dist/navigation/useMenuBadges.js.map +1 -0
- package/dist/navigation.js +30 -0
- package/dist/navigation.js.map +1 -0
- package/dist/navigationTrail.js +82 -0
- package/dist/navigationTrail.js.map +1 -0
- package/dist/next.js +5 -0
- package/dist/next.js.map +1 -0
- package/dist/observability/buildWatch.js +19 -0
- package/dist/observability/buildWatch.js.map +1 -0
- package/dist/observability/logger.js +43 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/publishedBuild.js +39 -0
- package/dist/observability/publishedBuild.js.map +1 -0
- package/dist/observability/usePublishedBuildWatch.js +76 -0
- package/dist/observability/usePublishedBuildWatch.js.map +1 -0
- package/dist/passkeys.js +7 -0
- package/dist/passkeys.js.map +1 -0
- package/dist/periodRanges.js +33 -0
- package/dist/periodRanges.js.map +1 -0
- package/dist/problems.js +51 -0
- package/dist/problems.js.map +1 -0
- package/dist/pwa/InstallAppSetting.js +33 -0
- package/dist/pwa/InstallAppSetting.js.map +1 -0
- package/dist/pwa/InstallInstructionsDialog.js +35 -0
- package/dist/pwa/InstallInstructionsDialog.js.map +1 -0
- package/dist/pwa/InstallPromptBanner.js +64 -0
- package/dist/pwa/InstallPromptBanner.js.map +1 -0
- package/dist/pwa/installInstructions.js +60 -0
- package/dist/pwa/installInstructions.js.map +1 -0
- package/dist/pwa/useInstallPrompt.js +70 -0
- package/dist/pwa/useInstallPrompt.js.map +1 -0
- package/dist/react-hook-form.js +30 -0
- package/dist/react-hook-form.js.map +1 -0
- package/dist/react-router.js +10 -0
- package/dist/react-router.js.map +1 -0
- package/dist/security/ActivityLog.js +79 -0
- package/dist/security/ActivityLog.js.map +1 -0
- package/dist/security/RecoveryCodesDialog.js +84 -0
- package/dist/security/RecoveryCodesDialog.js.map +1 -0
- package/dist/security/SessionsCard.js +81 -0
- package/dist/security/SessionsCard.js.map +1 -0
- package/dist/security/passkeys.js +39 -0
- package/dist/security/passkeys.js.map +1 -0
- package/dist/table.js +35 -0
- package/dist/table.js.map +1 -0
- package/dist/theme/androidDevice.js +16 -0
- package/dist/theme/androidDevice.js.map +1 -0
- package/dist/theme/appleTracking.js +34 -0
- package/dist/theme/appleTracking.js.map +1 -0
- package/dist/theme/components/MuiAppBar.js +27 -0
- package/dist/theme/components/MuiAppBar.js.map +1 -0
- package/dist/theme/components/MuiBackdrop.js +13 -0
- package/dist/theme/components/MuiBackdrop.js.map +1 -0
- package/dist/theme/components/MuiButton.js +25 -0
- package/dist/theme/components/MuiButton.js.map +1 -0
- package/dist/theme/components/MuiButtonBase.js +16 -0
- package/dist/theme/components/MuiButtonBase.js.map +1 -0
- package/dist/theme/components/MuiChip.js +30 -0
- package/dist/theme/components/MuiChip.js.map +1 -0
- package/dist/theme/components/MuiDataGrid.js +30 -0
- package/dist/theme/components/MuiDataGrid.js.map +1 -0
- package/dist/theme/components/MuiDrawer.js +18 -0
- package/dist/theme/components/MuiDrawer.js.map +1 -0
- package/dist/theme/components/MuiMenuItem.js +17 -0
- package/dist/theme/components/MuiMenuItem.js.map +1 -0
- package/dist/theme/components/MuiTypography.js +22 -0
- package/dist/theme/components/MuiTypography.js.map +1 -0
- package/dist/theme/components/glassComponents.js +885 -0
- package/dist/theme/components/glassComponents.js.map +1 -0
- package/dist/theme/components/minimalComponents.js +146 -0
- package/dist/theme/components/minimalComponents.js.map +1 -0
- package/dist/theme/components/paletteOf.js +7 -0
- package/dist/theme/components/paletteOf.js.map +1 -0
- package/dist/theme/createToolkitTheme.js +100 -0
- package/dist/theme/createToolkitTheme.js.map +1 -0
- package/dist/theme/glassSurface.js +328 -0
- package/dist/theme/glassSurface.js.map +1 -0
- package/dist/theme/glassToasterStyles.js +50 -0
- package/dist/theme/glassToasterStyles.js.map +1 -0
- package/dist/theme/mergeComponents.js +42 -0
- package/dist/theme/mergeComponents.js.map +1 -0
- package/dist/theme/stackcraftPalette.js +59 -0
- package/dist/theme/stackcraftPalette.js.map +1 -0
- package/dist/theme/toolkitComponents.js +26 -0
- package/dist/theme/toolkitComponents.js.map +1 -0
- package/dist/timeline.js +8 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toolkit/ToolkitProvider.js +49 -0
- package/dist/toolkit/ToolkitProvider.js.map +1 -0
- package/dist/toolkit/browserNavigation.js +34 -0
- package/dist/toolkit/browserNavigation.js.map +1 -0
- package/dist/toolkit/toolkitContext.js +19 -0
- package/dist/toolkit/toolkitContext.js.map +1 -0
- package/dist/toolkit/toolkitSettings.js +87 -0
- package/dist/toolkit/toolkitSettings.js.map +1 -0
- package/dist/toolkit/useToolkitTranslation.js +18 -0
- package/dist/toolkit/useToolkitTranslation.js.map +1 -0
- package/dist/types/DataTable/AuditTrailDialog.d.ts +32 -0
- package/dist/types/DataTable/AuditTrailTable.d.ts +28 -0
- package/dist/types/DataTable/ColumnFilters/HeaderFilterPopover.d.ts +8 -0
- package/dist/types/DataTable/ColumnFilters/MultiSelectColumnFilter.d.ts +16 -0
- package/dist/types/DataTable/ColumnFilters/SortableFilterHeader.d.ts +26 -0
- package/dist/types/DataTable/ColumnFilters/TextColumnFilter.d.ts +8 -0
- package/dist/types/DataTable/ColumnFilters/index.d.ts +4 -0
- package/dist/types/DataTable/EmptyState.d.ts +8 -0
- package/dist/types/DataTable/FilterChips.d.ts +15 -0
- package/dist/types/DataTable/GoToPage.d.ts +8 -0
- package/dist/types/DataTable/ServerTable.d.ts +110 -0
- package/dist/types/DataTable/buildChipConfig.d.ts +22 -0
- package/dist/types/DataTable/columns.d.ts +93 -0
- package/dist/types/DataTable/filterContext.d.ts +13 -0
- package/dist/types/DataTable/index.d.ts +13 -0
- package/dist/types/DataTable/serverTableParams.d.ts +16 -0
- package/dist/types/DataTable/tableMachine.d.ts +41 -0
- package/dist/types/DataTable/useDebouncedFilter.d.ts +8 -0
- package/dist/types/DataTable/useTableState.d.ts +93 -0
- package/dist/types/access/Can.d.ts +11 -0
- package/dist/types/access/PermissionMatrix.d.ts +21 -0
- package/dist/types/access/RequireAccess.d.ts +11 -0
- package/dist/types/access/accessRules.d.ts +24 -0
- package/dist/types/access/permissionGroups.d.ts +56 -0
- package/dist/types/access/useCan.d.ts +11 -0
- package/dist/types/account/AccountProvider.d.ts +27 -0
- package/dist/types/account/AccountSecuritySection.d.ts +7 -0
- package/dist/types/account/DemoTotpCodeButton.d.ts +6 -0
- package/dist/types/account/ForgotPasswordScreen.d.ts +15 -0
- package/dist/types/account/ProfileScreen.d.ts +13 -0
- package/dist/types/account/ResetPasswordScreen.d.ts +19 -0
- package/dist/types/account/SignInScreen.d.ts +25 -0
- package/dist/types/account/accountConnector.d.ts +263 -0
- package/dist/types/account/demo/createDemoAccountConnector.d.ts +30 -0
- package/dist/types/account/demo/totp.d.ts +45 -0
- package/dist/types/account/restAccountConnector.d.ts +49 -0
- package/dist/types/account-demo.d.ts +2 -0
- package/dist/types/account.d.ts +16 -0
- package/dist/types/adapters/i18next.d.ts +11 -0
- package/dist/types/adapters/nextNavigation.d.ts +33 -0
- package/dist/types/adapters/reactRouter.d.ts +6 -0
- package/dist/types/adapters/reactRouterRoutes.d.ts +30 -0
- package/dist/types/api/ApiError.d.ts +42 -0
- package/dist/types/api/createApiClient.d.ts +146 -0
- package/dist/types/api/staleChunks.d.ts +15 -0
- package/dist/types/appShell/AccountMenu.d.ts +28 -0
- package/dist/types/appShell/AppLayout.d.ts +66 -0
- package/dist/types/appShell/AppearanceSettings.d.ts +34 -0
- package/dist/types/appShell/AuthLayout.d.ts +21 -0
- package/dist/types/appShell/BarActionButton.d.ts +15 -0
- package/dist/types/appShell/BarActions.d.ts +18 -0
- package/dist/types/appShell/BarCapsule.d.ts +12 -0
- package/dist/types/appShell/HeaderTools.d.ts +27 -0
- package/dist/types/appShell/MobileTabBar.d.ts +17 -0
- package/dist/types/appShell/SettingsMenu.d.ts +13 -0
- package/dist/types/appShell/SideMenu.d.ts +31 -0
- package/dist/types/appShell/SideMenuEntry.d.ts +17 -0
- package/dist/types/appShell/SubmenuActionsMenu.d.ts +24 -0
- package/dist/types/appShell/TabBarEditor.d.ts +13 -0
- package/dist/types/appShell/TopMenu.d.ts +7 -0
- package/dist/types/appShell/appMenuContext.d.ts +9 -0
- package/dist/types/appShell/barActionsSlot.d.ts +35 -0
- package/dist/types/appShell/barMenuPlacement.d.ts +9 -0
- package/dist/types/appShell/menuItemText.d.ts +55 -0
- package/dist/types/appShell/pageTitle.d.ts +26 -0
- package/dist/types/appShell/shellSizes.d.ts +45 -0
- package/dist/types/appShell/tabBarRule.d.ts +5 -0
- package/dist/types/appShell/tabBarScroll.d.ts +26 -0
- package/dist/types/appShell/useDrawerCollapsed.d.ts +8 -0
- package/dist/types/appShell/useFittingActionCount.d.ts +7 -0
- package/dist/types/appShell/usePinnedMobileTabs.d.ts +7 -0
- package/dist/types/appShell/useTabBarMinimized.d.ts +8 -0
- package/dist/types/auth/PasswordChecklist.d.ts +11 -0
- package/dist/types/auth/passwordRules.d.ts +34 -0
- package/dist/types/calendar/EventCalendar.d.ts +46 -0
- package/dist/types/calendar.d.ts +1 -0
- package/dist/types/charts.d.ts +2 -0
- package/dist/types/date-pickers.d.ts +2 -0
- package/dist/types/datePickers/DateInput.d.ts +39 -0
- package/dist/types/datePickers/FormDateField.d.ts +7 -0
- package/dist/types/dates.d.ts +18 -0
- package/dist/types/dictionaries/dictionaries.d.ts +54 -0
- package/dist/types/downloads/DownloadManager.d.ts +1 -0
- package/dist/types/downloads/downloadQueue.d.ts +45 -0
- package/dist/types/downloads/downloadsMachine.d.ts +10 -0
- package/dist/types/downloads/index.d.ts +3 -0
- package/dist/types/excel/reportWorkbook.d.ts +157 -0
- package/dist/types/excel.d.ts +1 -0
- package/dist/types/feedback/ConfirmDialog.d.ts +29 -0
- package/dist/types/feedback/ModalWaiting.d.ts +8 -0
- package/dist/types/feedback/NewBuildNotice.d.ts +18 -0
- package/dist/types/feedback/StaleBuildBoundary.d.ts +21 -0
- package/dist/types/feedback/Toaster.d.ts +1 -0
- package/dist/types/feedback/confirmActionMachine.d.ts +19 -0
- package/dist/types/feedback/index.d.ts +8 -0
- package/dist/types/feedback/toast.d.ts +100 -0
- package/dist/types/feedback/useConfirmAction.d.ts +33 -0
- package/dist/types/filepond/FileDropzone.d.ts +59 -0
- package/dist/types/filepond/pondServer.d.ts +17 -0
- package/dist/types/filepond.d.ts +3 -0
- package/dist/types/files.d.ts +29 -0
- package/dist/types/formatting.d.ts +106 -0
- package/dist/types/forms/FormCatalogField.d.ts +6 -0
- package/dist/types/forms/FormColorField.d.ts +6 -0
- package/dist/types/forms/FormNumberField.d.ts +6 -0
- package/dist/types/forms/FormProblemAlert.d.ts +6 -0
- package/dist/types/forms/FormSelectField.d.ts +6 -0
- package/dist/types/forms/FormServerProblem.d.ts +8 -0
- package/dist/types/forms/FormTextField.d.ts +6 -0
- package/dist/types/forms/FormWizard.d.ts +20 -0
- package/dist/types/forms/SubmitButton.d.ts +9 -0
- package/dist/types/forms/applyServerProblem.d.ts +9 -0
- package/dist/types/forms/auth/ChangePasswordForm.d.ts +15 -0
- package/dist/types/forms/auth/ForgotPasswordForm.d.ts +12 -0
- package/dist/types/forms/auth/SignInForm.d.ts +18 -0
- package/dist/types/forms/index.d.ts +19 -0
- package/dist/types/forms/security/SecondStepForm.d.ts +28 -0
- package/dist/types/forms/security/TwoStepVerificationCard.d.ts +81 -0
- package/dist/types/forms/security/securityRules.d.ts +24 -0
- package/dist/types/forms/serverProblemFields.d.ts +19 -0
- package/dist/types/forms/useFormikField.d.ts +11 -0
- package/dist/types/forms/validation.d.ts +251 -0
- package/dist/types/forms/validationMessages.d.ts +12 -0
- package/dist/types/forms.d.ts +2 -0
- package/dist/types/hookForm/FormCatalogField.d.ts +8 -0
- package/dist/types/hookForm/FormColorField.d.ts +8 -0
- package/dist/types/hookForm/FormNumberField.d.ts +8 -0
- package/dist/types/hookForm/FormProblemAlert.d.ts +7 -0
- package/dist/types/hookForm/FormSelectField.d.ts +8 -0
- package/dist/types/hookForm/FormTextField.d.ts +8 -0
- package/dist/types/hookForm/SubmitButton.d.ts +21 -0
- package/dist/types/hookForm/applyServerProblem.d.ts +10 -0
- package/dist/types/hookForm/useHookFormField.d.ts +13 -0
- package/dist/types/i18next.d.ts +1 -0
- package/dist/types/identifiers.d.ts +2 -0
- package/dist/types/inbox/InboxLayout.d.ts +26 -0
- package/dist/types/inbox/MessageList.d.ts +27 -0
- package/dist/types/inbox/MessageView.d.ts +23 -0
- package/dist/types/inbox/inboxDates.d.ts +6 -0
- package/dist/types/index.d.ts +84 -0
- package/dist/types/inputs/CatalogInput.d.ts +41 -0
- package/dist/types/inputs/ColorInput.d.ts +28 -0
- package/dist/types/inputs/FieldFrame.d.ts +14 -0
- package/dist/types/inputs/FormSection.d.ts +29 -0
- package/dist/types/inputs/NumberInput.d.ts +36 -0
- package/dist/types/inputs/SelectInput.d.ts +34 -0
- package/dist/types/inputs/TextInput.d.ts +60 -0
- package/dist/types/inputs/colorContrast.d.ts +18 -0
- package/dist/types/inputs/formLayoutContext.d.ts +3 -0
- package/dist/types/inputs/numberText.d.ts +25 -0
- package/dist/types/kanban/KanbanBoard.d.ts +33 -0
- package/dist/types/kanban/kanbanMoves.d.ts +38 -0
- package/dist/types/kanban.d.ts +2 -0
- package/dist/types/laravel/csrfRetry.d.ts +21 -0
- package/dist/types/laravel.d.ts +1 -0
- package/dist/types/lastListUrl.d.ts +20 -0
- package/dist/types/locales/en.d.ts +711 -0
- package/dist/types/locales/es.d.ts +711 -0
- package/dist/types/maps/MapView.d.ts +32 -0
- package/dist/types/maps/mapMarkers.d.ts +23 -0
- package/dist/types/maps.d.ts +2 -0
- package/dist/types/money/money.d.ts +203 -0
- package/dist/types/money.d.ts +1 -0
- package/dist/types/navigation/appMenu.d.ts +92 -0
- package/dist/types/navigation/useMenuBadges.d.ts +16 -0
- package/dist/types/navigation.d.ts +22 -0
- package/dist/types/navigationTrail.d.ts +49 -0
- package/dist/types/next.d.ts +1 -0
- package/dist/types/observability/buildWatch.d.ts +28 -0
- package/dist/types/observability/logger.d.ts +19 -0
- package/dist/types/observability/publishedBuild.d.ts +35 -0
- package/dist/types/observability/usePublishedBuildWatch.d.ts +16 -0
- package/dist/types/passkeys.d.ts +1 -0
- package/dist/types/periodRanges.d.ts +32 -0
- package/dist/types/problems.d.ts +31 -0
- package/dist/types/pwa/InstallAppSetting.d.ts +1 -0
- package/dist/types/pwa/InstallInstructionsDialog.d.ts +18 -0
- package/dist/types/pwa/InstallPromptBanner.d.ts +7 -0
- package/dist/types/pwa/installInstructions.d.ts +52 -0
- package/dist/types/pwa/useInstallPrompt.d.ts +12 -0
- package/dist/types/react-hook-form.d.ts +11 -0
- package/dist/types/react-router.d.ts +2 -0
- package/dist/types/security/ActivityLog.d.ts +31 -0
- package/dist/types/security/RecoveryCodesDialog.d.ts +11 -0
- package/dist/types/security/SessionsCard.d.ts +22 -0
- package/dist/types/security/passkeys.d.ts +18 -0
- package/dist/types/table.d.ts +1 -0
- package/dist/types/theme/androidDevice.d.ts +11 -0
- package/dist/types/theme/appleTracking.d.ts +17 -0
- package/dist/types/theme/components/MuiAppBar.d.ts +13 -0
- package/dist/types/theme/components/MuiBackdrop.d.ts +11 -0
- package/dist/types/theme/components/MuiButton.d.ts +27 -0
- package/dist/types/theme/components/MuiButtonBase.d.ts +14 -0
- package/dist/types/theme/components/MuiChip.d.ts +29 -0
- package/dist/types/theme/components/MuiDataGrid.d.ts +45 -0
- package/dist/types/theme/components/MuiDrawer.d.ts +13 -0
- package/dist/types/theme/components/MuiMenuItem.d.ts +17 -0
- package/dist/types/theme/components/MuiTypography.d.ts +20 -0
- package/dist/types/theme/components/glassComponents.d.ts +8 -0
- package/dist/types/theme/components/minimalComponents.d.ts +22 -0
- package/dist/types/theme/components/paletteOf.d.ts +5 -0
- package/dist/types/theme/createToolkitTheme.d.ts +48 -0
- package/dist/types/theme/glassSurface.d.ts +247 -0
- package/dist/types/theme/glassToasterStyles.d.ts +7 -0
- package/dist/types/theme/mergeComponents.d.ts +15 -0
- package/dist/types/theme/stackcraftPalette.d.ts +142 -0
- package/dist/types/theme/toolkitComponents.d.ts +4 -0
- package/dist/types/timeline.d.ts +2 -0
- package/dist/types/toolkit/ToolkitProvider.d.ts +31 -0
- package/dist/types/toolkit/browserNavigation.d.ts +32 -0
- package/dist/types/toolkit/toolkitContext.d.ts +28 -0
- package/dist/types/toolkit/toolkitSettings.d.ts +68 -0
- package/dist/types/toolkit/useToolkitTranslation.d.ts +10 -0
- package/dist/types/ui/actions/CopyButton.d.ts +13 -0
- package/dist/types/ui/actions/DownloadMenu.d.ts +50 -0
- package/dist/types/ui/actions/SecretField.d.ts +13 -0
- package/dist/types/ui/filters/DateRangeFilter.d.ts +16 -0
- package/dist/types/ui/filters/PeriodRangeSelector.d.ts +28 -0
- package/dist/types/ui/filters/QuickFilters.d.ts +21 -0
- package/dist/types/ui/filters/SegmentedControl.d.ts +44 -0
- package/dist/types/ui/index.d.ts +33 -0
- package/dist/types/ui/labels/DictionaryText.d.ts +7 -0
- package/dist/types/ui/labels/StatusChip.d.ts +21 -0
- package/dist/types/ui/labels/Tag.d.ts +19 -0
- package/dist/types/ui/layout/CollapsibleSection.d.ts +15 -0
- package/dist/types/ui/layout/ContentDialog.d.ts +13 -0
- package/dist/types/ui/layout/DefinitionList.d.ts +15 -0
- package/dist/types/ui/layout/DetailHeader.d.ts +15 -0
- package/dist/types/ui/layout/ErrorPage.d.ts +22 -0
- package/dist/types/ui/layout/FullPageLoader.d.ts +1 -0
- package/dist/types/ui/layout/GlassLensFilter.d.ts +1 -0
- package/dist/types/ui/layout/GlassPanel.d.ts +11 -0
- package/dist/types/ui/layout/PageHeader.d.ts +15 -0
- package/dist/types/ui/layout/PageHeading.d.ts +18 -0
- package/dist/types/ui/layout/ProfileHeader.d.ts +17 -0
- package/dist/types/ui/layout/ScrollableRow.d.ts +33 -0
- package/dist/types/ui/layout/SectionCard.d.ts +11 -0
- package/dist/types/ui/layout/appBarHeight.d.ts +13 -0
- package/dist/types/ui/metrics/BarList.d.ts +19 -0
- package/dist/types/ui/metrics/CalendarHeatmap.d.ts +28 -0
- package/dist/types/ui/metrics/ChartTooltip.d.ts +5 -0
- package/dist/types/ui/metrics/ColumnChart.d.ts +35 -0
- package/dist/types/ui/metrics/MetricCard.d.ts +31 -0
- package/dist/types/ui/metrics/TableToggle.d.ts +7 -0
- package/dist/types/ui/metrics/barListLabels.d.ts +17 -0
- package/dist/types/ui/metrics/heatmapScale.d.ts +45 -0
- package/dist/types/ui/navigation/BackButton.d.ts +11 -0
- package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +7 -0
- package/dist/types/ui/navigation/DocumentTitle.d.ts +6 -0
- package/dist/types/ui/navigation/FontSizeToggle.d.ts +6 -0
- package/dist/types/ui/navigation/LanguageToggle.d.ts +8 -0
- package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +9 -0
- package/dist/types/ui/navigation/colorMode.d.ts +18 -0
- package/dist/types/ui/navigation/fontSizeLevels.d.ts +25 -0
- package/dist/types/ui/navigation/useFontSize.d.ts +10 -0
- package/dist/types/ui/timeline/GroupedTimeline.d.ts +38 -0
- package/dist/types/ui/timeline/timelineDot.d.ts +19 -0
- package/dist/types/upload/FileDropzone.d.ts +34 -0
- package/dist/types/upload/fileRules.d.ts +51 -0
- package/dist/types/upload/uploadMachine.d.ts +23 -0
- package/dist/types/upload/uploadWithProgress.d.ts +16 -0
- package/dist/ui/actions/CopyButton.js +28 -0
- package/dist/ui/actions/CopyButton.js.map +1 -0
- package/dist/ui/actions/DownloadMenu.js +163 -0
- package/dist/ui/actions/DownloadMenu.js.map +1 -0
- package/dist/ui/actions/SecretField.js +57 -0
- package/dist/ui/actions/SecretField.js.map +1 -0
- package/dist/ui/filters/DateRangeFilter.js +86 -0
- package/dist/ui/filters/DateRangeFilter.js.map +1 -0
- package/dist/ui/filters/PeriodRangeSelector.js +56 -0
- package/dist/ui/filters/PeriodRangeSelector.js.map +1 -0
- package/dist/ui/filters/QuickFilters.js +91 -0
- package/dist/ui/filters/QuickFilters.js.map +1 -0
- package/dist/ui/filters/SegmentedControl.js +80 -0
- package/dist/ui/filters/SegmentedControl.js.map +1 -0
- package/dist/ui/labels/DictionaryText.js +11 -0
- package/dist/ui/labels/DictionaryText.js.map +1 -0
- package/dist/ui/labels/StatusChip.js +52 -0
- package/dist/ui/labels/StatusChip.js.map +1 -0
- package/dist/ui/labels/Tag.js +26 -0
- package/dist/ui/labels/Tag.js.map +1 -0
- package/dist/ui/layout/CollapsibleSection.js +48 -0
- package/dist/ui/layout/CollapsibleSection.js.map +1 -0
- package/dist/ui/layout/ContentDialog.js +97 -0
- package/dist/ui/layout/ContentDialog.js.map +1 -0
- package/dist/ui/layout/DefinitionList.js +30 -0
- package/dist/ui/layout/DefinitionList.js.map +1 -0
- package/dist/ui/layout/DetailHeader.js +27 -0
- package/dist/ui/layout/DetailHeader.js.map +1 -0
- package/dist/ui/layout/ErrorPage.js +40 -0
- package/dist/ui/layout/ErrorPage.js.map +1 -0
- package/dist/ui/layout/FullPageLoader.js +13 -0
- package/dist/ui/layout/FullPageLoader.js.map +1 -0
- package/dist/ui/layout/GlassLensFilter.js +53 -0
- package/dist/ui/layout/GlassLensFilter.js.map +1 -0
- package/dist/ui/layout/GlassPanel.js +18 -0
- package/dist/ui/layout/GlassPanel.js.map +1 -0
- package/dist/ui/layout/PageHeader.js +23 -0
- package/dist/ui/layout/PageHeader.js.map +1 -0
- package/dist/ui/layout/PageHeading.js +51 -0
- package/dist/ui/layout/PageHeading.js.map +1 -0
- package/dist/ui/layout/ProfileHeader.js +64 -0
- package/dist/ui/layout/ProfileHeader.js.map +1 -0
- package/dist/ui/layout/ScrollableRow.js +156 -0
- package/dist/ui/layout/ScrollableRow.js.map +1 -0
- package/dist/ui/layout/SectionCard.js +18 -0
- package/dist/ui/layout/SectionCard.js.map +1 -0
- package/dist/ui/layout/appBarHeight.js +42 -0
- package/dist/ui/layout/appBarHeight.js.map +1 -0
- package/dist/ui/metrics/BarList.js +89 -0
- package/dist/ui/metrics/BarList.js.map +1 -0
- package/dist/ui/metrics/CalendarHeatmap.js +131 -0
- package/dist/ui/metrics/CalendarHeatmap.js.map +1 -0
- package/dist/ui/metrics/ChartTooltip.js +16 -0
- package/dist/ui/metrics/ChartTooltip.js.map +1 -0
- package/dist/ui/metrics/ColumnChart.js +110 -0
- package/dist/ui/metrics/ColumnChart.js.map +1 -0
- package/dist/ui/metrics/MetricCard.js +64 -0
- package/dist/ui/metrics/MetricCard.js.map +1 -0
- package/dist/ui/metrics/TableToggle.js +13 -0
- package/dist/ui/metrics/TableToggle.js.map +1 -0
- package/dist/ui/metrics/barListLabels.js +9 -0
- package/dist/ui/metrics/barListLabels.js.map +1 -0
- package/dist/ui/metrics/heatmapScale.js +67 -0
- package/dist/ui/metrics/heatmapScale.js.map +1 -0
- package/dist/ui/navigation/BackButton.js +28 -0
- package/dist/ui/navigation/BackButton.js.map +1 -0
- package/dist/ui/navigation/ColorSchemeToggle.js +37 -0
- package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -0
- package/dist/ui/navigation/DocumentTitle.js +11 -0
- package/dist/ui/navigation/DocumentTitle.js.map +1 -0
- package/dist/ui/navigation/FontSizeToggle.js +40 -0
- package/dist/ui/navigation/FontSizeToggle.js.map +1 -0
- package/dist/ui/navigation/LanguageToggle.js +27 -0
- package/dist/ui/navigation/LanguageToggle.js.map +1 -0
- package/dist/ui/navigation/PageBreadcrumbs.js +51 -0
- package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -0
- package/dist/ui/navigation/colorMode.js +13 -0
- package/dist/ui/navigation/colorMode.js.map +1 -0
- package/dist/ui/navigation/fontSizeLevels.js +24 -0
- package/dist/ui/navigation/fontSizeLevels.js.map +1 -0
- package/dist/ui/navigation/useFontSize.js +44 -0
- package/dist/ui/navigation/useFontSize.js.map +1 -0
- package/dist/ui/timeline/GroupedTimeline.js +104 -0
- package/dist/ui/timeline/GroupedTimeline.js.map +1 -0
- package/dist/ui/timeline/timelineDot.js +20 -0
- package/dist/ui/timeline/timelineDot.js.map +1 -0
- package/dist/upload/FileDropzone.js +143 -0
- package/dist/upload/FileDropzone.js.map +1 -0
- package/dist/upload/fileRules.js +62 -0
- package/dist/upload/fileRules.js.map +1 -0
- package/dist/upload/uploadMachine.js +73 -0
- package/dist/upload/uploadMachine.js.map +1 -0
- package/dist/upload/uploadWithProgress.js +45 -0
- package/dist/upload/uploadWithProgress.js.map +1 -0
- package/package.json +303 -5
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { problemTitle } from "../problems.js";
|
|
2
|
+
import { toolkitSettings } from "../toolkit/toolkitSettings.js";
|
|
3
|
+
const OFFLINE_STATUS = 0;
|
|
4
|
+
function problemTitleOf(request) {
|
|
5
|
+
let problem = null;
|
|
6
|
+
try {
|
|
7
|
+
problem = JSON.parse(request.responseText);
|
|
8
|
+
} catch {
|
|
9
|
+
}
|
|
10
|
+
return problemTitle(problem, request.status);
|
|
11
|
+
}
|
|
12
|
+
function createPondServer({ url, fieldName, headers = {}, withCredentials = false }) {
|
|
13
|
+
return {
|
|
14
|
+
process: (pondFieldName, file, metadata, load, error, progress, abort) => {
|
|
15
|
+
const request = new XMLHttpRequest();
|
|
16
|
+
request.open("POST", url);
|
|
17
|
+
request.withCredentials = withCredentials;
|
|
18
|
+
for (const [headerName, headerValue] of Object.entries({ "Accept-Language": toolkitSettings().language, ...headers })) {
|
|
19
|
+
request.setRequestHeader(headerName, headerValue);
|
|
20
|
+
}
|
|
21
|
+
request.upload.onprogress = (event) => progress(event.lengthComputable, event.loaded, event.total);
|
|
22
|
+
request.onload = () => {
|
|
23
|
+
if (request.status >= 200 && request.status < 300) {
|
|
24
|
+
load(request.responseText || file.name);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
error(problemTitleOf(request));
|
|
28
|
+
};
|
|
29
|
+
request.onerror = () => error(problemTitle(null, OFFLINE_STATUS));
|
|
30
|
+
const formData = new FormData();
|
|
31
|
+
formData.append(fieldName ?? pondFieldName, file, file.name);
|
|
32
|
+
request.send(formData);
|
|
33
|
+
return {
|
|
34
|
+
abort: () => {
|
|
35
|
+
request.abort();
|
|
36
|
+
abort();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
// sin nada que deshacer en el servidor: el «deshacer» de la tarjeta es local. Si el backend guarda el archivo,
|
|
41
|
+
// aquí iría su DELETE con el id que regresó
|
|
42
|
+
revert: (serverId, load) => load()
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
createPondServer
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=pondServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pondServer.js","sources":["../../src/filepond/pondServer.js"],"sourcesContent":["// El «server» de FilePond con lo de la casa: cada archivo se sube en su propio POST con su barra de avance dentro de su\n// tarjeta, el idioma activo en Accept-Language, el error RFC 9457 del backend escrito en la tarjeta y la ✕ que cancela la\n// petición de verdad (no solo la pantalla).\n//\n// Cuándo SÍ: archivos que valen cada uno por su cuenta (adjuntos sueltos, una galería).\n// Cuándo NO: el envío de siempre, «todos los archivos y los campos en UN solo envío»: ahí la zona solo elige y la\n// pantalla arma su FormData. OJO: aquí el backend ve UN archivo por petición; las reglas del lote completo (cuántos,\n// cuánto pesan juntos) ya no las puede revisar por petición.\n//\n// <FileDropzone multiple server={createPondServer({url: '/api/v1/adjuntos', headers: {Authorization: `Bearer ${token}`}})} />\n//\n// Funciones del navegador, sin React: function (regla de la casa).\nimport {problemTitle} from '@/problems.js';\nimport {toolkitSettings} from '@/toolkit/toolkitSettings.js';\n\n// status de «no hubo respuesta» para los textos del paquete (problems: offline)\nconst OFFLINE_STATUS = 0;\n\n/**\n * El título del problema RFC 9457 de una respuesta (o el genérico del paquete, ya traducido).\n *\n * @param {XMLHttpRequest} request\n * @returns {string}\n */\nfunction problemTitleOf(request) {\n let problem = null;\n try {\n problem = JSON.parse(request.responseText);\n } catch {\n // la respuesta no era JSON (un 502 del proxy en HTML): va el título genérico de su status\n }\n return problemTitle(problem, request.status);\n}\n\n/**\n * @param {object} options\n * @param {string} options.url a dónde va cada archivo\n * @param {string} [options.fieldName] el campo del archivo en el FormData; por omisión el name de la zona\n * @param {Record<string, string>} [options.headers] p. ej. Authorization\n * @param {boolean} [options.withCredentials] manda las cookies a otro dominio\n * @returns {{process: (...args: any[]) => any, revert: (...args: any[]) => any}} lo que recibe la prop server de FileDropzone\n */\nexport function createPondServer({url, fieldName, headers = {}, withCredentials = false}) {\n return {\n process: (pondFieldName, file, metadata, load, error, progress, abort) => {\n const request = new XMLHttpRequest();\n request.open('POST', url);\n request.withCredentials = withCredentials;\n for (const [headerName, headerValue] of Object.entries({'Accept-Language': toolkitSettings().language, ...headers})) {\n request.setRequestHeader(headerName, headerValue);\n }\n\n request.upload.onprogress = (event) => progress(event.lengthComputable, event.loaded, event.total);\n request.onload = () => {\n if (request.status >= 200 && request.status < 300) {\n // lo que responda el servidor es el id del archivo (FilePond lo guarda para deshacer)\n load(request.responseText || file.name);\n return;\n }\n error(problemTitleOf(request));\n };\n request.onerror = () => error(problemTitle(null, OFFLINE_STATUS));\n\n const formData = new FormData();\n formData.append(fieldName ?? pondFieldName, file, file.name);\n request.send(formData);\n\n // la ✕ de la tarjeta cancela la petición de verdad\n return {\n abort: () => {\n request.abort();\n abort();\n },\n };\n },\n // sin nada que deshacer en el servidor: el «deshacer» de la tarjeta es local. Si el backend guarda el archivo,\n // aquí iría su DELETE con el id que regresó\n revert: (serverId, load) => load(),\n };\n}\n"],"names":[],"mappings":";;AAgBA,MAAM,iBAAiB;AAQvB,SAAS,eAAe,SAAS;AAC7B,MAAI,UAAU;AACd,MAAI;AACA,cAAU,KAAK,MAAM,QAAQ,YAAY;AAAA,EAC7C,QAAQ;AAAA,EAER;AACA,SAAO,aAAa,SAAS,QAAQ,MAAM;AAC/C;AAUO,SAAS,iBAAiB,EAAC,KAAK,WAAW,UAAU,IAAI,kBAAkB,MAAK,GAAG;AACtF,SAAO;AAAA,IACH,SAAS,CAAC,eAAe,MAAM,UAAU,MAAM,OAAO,UAAU,UAAU;AACtE,YAAM,UAAU,IAAI,eAAc;AAClC,cAAQ,KAAK,QAAQ,GAAG;AACxB,cAAQ,kBAAkB;AAC1B,iBAAW,CAAC,YAAY,WAAW,KAAK,OAAO,QAAQ,EAAC,mBAAmB,gBAAe,EAAG,UAAU,GAAG,QAAO,CAAC,GAAG;AACjH,gBAAQ,iBAAiB,YAAY,WAAW;AAAA,MACpD;AAEA,cAAQ,OAAO,aAAa,CAAC,UAAU,SAAS,MAAM,kBAAkB,MAAM,QAAQ,MAAM,KAAK;AACjG,cAAQ,SAAS,MAAM;AACnB,YAAI,QAAQ,UAAU,OAAO,QAAQ,SAAS,KAAK;AAE/C,eAAK,QAAQ,gBAAgB,KAAK,IAAI;AACtC;AAAA,QACJ;AACA,cAAM,eAAe,OAAO,CAAC;AAAA,MACjC;AACA,cAAQ,UAAU,MAAM,MAAM,aAAa,MAAM,cAAc,CAAC;AAEhE,YAAM,WAAW,IAAI,SAAQ;AAC7B,eAAS,OAAO,aAAa,eAAe,MAAM,KAAK,IAAI;AAC3D,cAAQ,KAAK,QAAQ;AAGrB,aAAO;AAAA,QACH,OAAO,MAAM;AACT,kBAAQ,MAAK;AACb,gBAAK;AAAA,QACT;AAAA,MAChB;AAAA,IACQ;AAAA;AAAA;AAAA,IAGA,QAAQ,CAAC,UAAU,SAAS,KAAI;AAAA,EACxC;AACA;"}
|
package/dist/filepond.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as default2 } from "./filepond/FileDropzone.js";
|
|
2
|
+
import { createPondServer } from "./filepond/pondServer.js";
|
|
3
|
+
import { FILE_ACCEPT_PRESETS, FILE_REJECTION } from "./upload/fileRules.js";
|
|
4
|
+
export {
|
|
5
|
+
FILE_ACCEPT_PRESETS,
|
|
6
|
+
FILE_REJECTION,
|
|
7
|
+
default2 as FileDropzone,
|
|
8
|
+
createPondServer
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=filepond.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filepond.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const XLSX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
2
|
+
const ZIP_END_RECORD_SIGNATURE = 101010256;
|
|
3
|
+
const ZIP_END_RECORD_LENGTH = 22;
|
|
4
|
+
const ZIP_END_RECORD_COMMENT_LENGTH_POSITION = 20;
|
|
5
|
+
function fileNameFromContentDisposition(contentDisposition, fallbackFileName) {
|
|
6
|
+
if (!contentDisposition) {
|
|
7
|
+
return fallbackFileName;
|
|
8
|
+
}
|
|
9
|
+
const encodedMatch = contentDisposition.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
|
|
10
|
+
if (encodedMatch) {
|
|
11
|
+
try {
|
|
12
|
+
return decodeURIComponent(encodedMatch[1].trim());
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const plainMatch = contentDisposition.match(/filename\s*=\s*"?([^";]+)"?/i);
|
|
17
|
+
return plainMatch ? plainMatch[1].trim() : fallbackFileName;
|
|
18
|
+
}
|
|
19
|
+
function saveBlob(blob, fileName) {
|
|
20
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
21
|
+
const link = document.createElement("a");
|
|
22
|
+
link.href = objectUrl;
|
|
23
|
+
link.download = fileName;
|
|
24
|
+
link.rel = "noopener";
|
|
25
|
+
document.body.appendChild(link);
|
|
26
|
+
link.click();
|
|
27
|
+
link.remove();
|
|
28
|
+
setTimeout(() => URL.revokeObjectURL(objectUrl), 1e3);
|
|
29
|
+
}
|
|
30
|
+
async function isCompleteZip(blob) {
|
|
31
|
+
if (blob.size < ZIP_END_RECORD_LENGTH) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const endRecord = new DataView(await blob.slice(blob.size - ZIP_END_RECORD_LENGTH).arrayBuffer());
|
|
35
|
+
return endRecord.getUint32(0, true) === ZIP_END_RECORD_SIGNATURE && endRecord.getUint16(ZIP_END_RECORD_COMMENT_LENGTH_POSITION, true) === 0;
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
XLSX_CONTENT_TYPE,
|
|
39
|
+
fileNameFromContentDisposition,
|
|
40
|
+
isCompleteZip,
|
|
41
|
+
saveBlob
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sources":["../src/files.js"],"sourcesContent":["// Guardar en disco un archivo que llegó como Blob (CSV de renglones descartados, logs, salidas).\n//\n// La descarga va por el cliente HTTP y no por un <a href> directo a la API a propósito: así un 401 o un 409\n// llegan al manejador de siempre (sesión vencida, problema RFC 9457) en lugar de dejar un JSON crudo en una\n// pestaña nueva.\n//\n// Funciones puras, no renderizan: function (regla de la casa).\n\n/** Tipo de contenido de un Excel (XLSX): el mismo que manda el servidor (IngestionDictionary::XLSX_CONTENT_TYPE). */\nexport const XLSX_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n\n// Un XLSX es un zip, y un zip completo termina con su registro de cierre (End of Central Directory): 22 bytes que\n// empiezan con la firma «PK\\x05\\x06» y terminan con el largo del comentario del zip. El servidor arma sus Excel al vuelo\n// y sin comentario, así que ese registro son sus últimos 22 bytes; si la escritura falla a la mitad, nunca se escribe.\n// La firma se lee como entero de 4 bytes con el byte menos significativo primero (así la guarda el zip).\nconst ZIP_END_RECORD_SIGNATURE = 0x06054b50;\nconst ZIP_END_RECORD_LENGTH = 22;\nconst ZIP_END_RECORD_COMMENT_LENGTH_POSITION = 20;\n\n/**\n * Nombre de archivo del header Content-Disposition. Prefiere filename*=UTF-8'' (acentos) sobre filename=.\n *\n * @param {string|null|undefined} contentDisposition\n * @param {string} fallbackFileName si el header no trae nombre\n */\nexport function fileNameFromContentDisposition(contentDisposition, fallbackFileName) {\n if (!contentDisposition) {\n return fallbackFileName;\n }\n const encodedMatch = contentDisposition.match(/filename\\*\\s*=\\s*UTF-8''([^;]+)/i);\n if (encodedMatch) {\n try {\n return decodeURIComponent(encodedMatch[1].trim());\n } catch {\n // nombre mal codificado: seguimos con filename=\n }\n }\n const plainMatch = contentDisposition.match(/filename\\s*=\\s*\"?([^\";]+)\"?/i);\n return plainMatch ? plainMatch[1].trim() : fallbackFileName;\n}\n\n/**\n * Dispara la descarga de un Blob con el nombre dado.\n *\n * @param {Blob} blob\n * @param {string} fileName\n */\nexport function saveBlob(blob, fileName) {\n const objectUrl = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = objectUrl;\n link.download = fileName;\n link.rel = 'noopener';\n document.body.appendChild(link);\n link.click();\n link.remove();\n // OJO: liberamos la URL un momento después; revocarla en el mismo tick cancela la descarga en Safari\n setTimeout(() => URL.revokeObjectURL(objectUrl), 1000);\n}\n\n/**\n * ¿Llegó completo el zip (un XLSX)? Sí, si termina con su registro de cierre.\n *\n * Por qué hace falta: el servidor manda los Excel por partes y con 200 desde el primer pedazo. Si algo falla a media\n * escritura (p. ej. llegan más renglones de los que se contaron), ya no puede cambiar la respuesta a un error: el archivo\n * llega cortado y Excel no lo abre. Esta revisión es lo que evita guardarlo como si estuviera bien.\n *\n * OJO: supone un zip sin comentario, como los que escribe el servidor (zipstream sin comentario).\n *\n * @param {Blob} blob el archivo descargado\n * @returns {Promise<boolean>}\n */\nexport async function isCompleteZip(blob) {\n // guard clause: ni siquiera cabe el registro de cierre\n if (blob.size < ZIP_END_RECORD_LENGTH) {\n return false;\n }\n\n const endRecord = new DataView(await blob.slice(blob.size - ZIP_END_RECORD_LENGTH).arrayBuffer());\n return endRecord.getUint32(0, true) === ZIP_END_RECORD_SIGNATURE\n && endRecord.getUint16(ZIP_END_RECORD_COMMENT_LENGTH_POSITION, true) === 0;\n}\n"],"names":[],"mappings":"AASY,MAAC,oBAAoB;AAMjC,MAAM,2BAA2B;AACjC,MAAM,wBAAwB;AAC9B,MAAM,yCAAyC;AAQxC,SAAS,+BAA+B,oBAAoB,kBAAkB;AACjF,MAAI,CAAC,oBAAoB;AACrB,WAAO;AAAA,EACX;AACA,QAAM,eAAe,mBAAmB,MAAM,kCAAkC;AAChF,MAAI,cAAc;AACd,QAAI;AACA,aAAO,mBAAmB,aAAa,CAAC,EAAE,KAAI,CAAE;AAAA,IACpD,QAAQ;AAAA,IAER;AAAA,EACJ;AACA,QAAM,aAAa,mBAAmB,MAAM,8BAA8B;AAC1E,SAAO,aAAa,WAAW,CAAC,EAAE,KAAI,IAAK;AAC/C;AAQO,SAAS,SAAS,MAAM,UAAU;AACrC,QAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,QAAM,OAAO,SAAS,cAAc,GAAG;AACvC,OAAK,OAAO;AACZ,OAAK,WAAW;AAChB,OAAK,MAAM;AACX,WAAS,KAAK,YAAY,IAAI;AAC9B,OAAK,MAAK;AACV,OAAK,OAAM;AAEX,aAAW,MAAM,IAAI,gBAAgB,SAAS,GAAG,GAAI;AACzD;AAcO,eAAe,cAAc,MAAM;AAEtC,MAAI,KAAK,OAAO,uBAAuB;AACnC,WAAO;AAAA,EACX;AAEA,QAAM,YAAY,IAAI,SAAS,MAAM,KAAK,MAAM,KAAK,OAAO,qBAAqB,EAAE,aAAa;AAChG,SAAO,UAAU,UAAU,GAAG,IAAI,MAAM,4BACjC,UAAU,UAAU,wCAAwC,IAAI,MAAM;AACjF;"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { parseInstant, parsePlainDate } from "./dates.js";
|
|
2
|
+
import { toolkitSettings, intlLocaleOf } from "./toolkit/toolkitSettings.js";
|
|
3
|
+
const formatterCache = /* @__PURE__ */ new Map();
|
|
4
|
+
function activeLocale() {
|
|
5
|
+
return intlLocaleOf(toolkitSettings().language);
|
|
6
|
+
}
|
|
7
|
+
function cachedFormatter(kind, options, createFormatter) {
|
|
8
|
+
const locale = activeLocale();
|
|
9
|
+
const cacheKey = `${kind}|${locale}|${JSON.stringify(options)}`;
|
|
10
|
+
if (!formatterCache.has(cacheKey)) {
|
|
11
|
+
formatterCache.set(cacheKey, createFormatter(locale, options));
|
|
12
|
+
}
|
|
13
|
+
return formatterCache.get(cacheKey);
|
|
14
|
+
}
|
|
15
|
+
function formatNumber(value, fallback = "—") {
|
|
16
|
+
if (value === null || value === void 0 || value === "" || Number.isNaN(Number(value))) {
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
const formatter = cachedFormatter(
|
|
20
|
+
"number",
|
|
21
|
+
{ maximumFractionDigits: 0 },
|
|
22
|
+
(locale, options) => new Intl.NumberFormat(locale, options)
|
|
23
|
+
);
|
|
24
|
+
return formatter.format(Number(value));
|
|
25
|
+
}
|
|
26
|
+
function formatList(items) {
|
|
27
|
+
const formatter = cachedFormatter(
|
|
28
|
+
"list",
|
|
29
|
+
{ style: "long", type: "conjunction" },
|
|
30
|
+
(locale, options) => new Intl.ListFormat(locale, options)
|
|
31
|
+
);
|
|
32
|
+
return formatter.format(items);
|
|
33
|
+
}
|
|
34
|
+
function formatCurrency(value, fallback = "—") {
|
|
35
|
+
if (value === null || value === void 0 || value === "" || Number.isNaN(Number(value))) {
|
|
36
|
+
return fallback;
|
|
37
|
+
}
|
|
38
|
+
const formatter = cachedFormatter("currency", {
|
|
39
|
+
style: "currency",
|
|
40
|
+
currency: toolkitSettings().currency,
|
|
41
|
+
currencyDisplay: "narrowSymbol",
|
|
42
|
+
minimumFractionDigits: 2,
|
|
43
|
+
maximumFractionDigits: 2
|
|
44
|
+
}, (locale, options) => new Intl.NumberFormat(locale, options));
|
|
45
|
+
return formatter.format(Number(value));
|
|
46
|
+
}
|
|
47
|
+
function formatFileSize(bytes, fallback = "—") {
|
|
48
|
+
if (bytes === null || bytes === void 0 || Number.isNaN(Number(bytes))) {
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
const units = [["gigabyte", 1e9], ["megabyte", 1e6], ["kilobyte", 1e3]];
|
|
52
|
+
for (const [unit, unitBytes] of units) {
|
|
53
|
+
if (Number(bytes) >= unitBytes) {
|
|
54
|
+
const formatter2 = cachedFormatter(
|
|
55
|
+
`fileSize-${unit}`,
|
|
56
|
+
{ style: "unit", unit, maximumFractionDigits: 1 },
|
|
57
|
+
(locale, options) => new Intl.NumberFormat(locale, options)
|
|
58
|
+
);
|
|
59
|
+
return formatter2.format(Number(bytes) / unitBytes);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const formatter = cachedFormatter(
|
|
63
|
+
"fileSize-byte",
|
|
64
|
+
{ style: "unit", unit: "byte", unitDisplay: "long", maximumFractionDigits: 0 },
|
|
65
|
+
(locale, options) => new Intl.NumberFormat(locale, options)
|
|
66
|
+
);
|
|
67
|
+
return formatter.format(Number(bytes));
|
|
68
|
+
}
|
|
69
|
+
function formatPercent(value, { fractionDigits = 2, isRatio = false, fallback = "—" } = {}) {
|
|
70
|
+
if (value === null || value === void 0 || Number.isNaN(Number(value))) {
|
|
71
|
+
return fallback;
|
|
72
|
+
}
|
|
73
|
+
const ratio = isRatio ? Number(value) : Number(value) / 100;
|
|
74
|
+
const formatter = cachedFormatter(
|
|
75
|
+
"percent",
|
|
76
|
+
{ style: "percent", minimumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits },
|
|
77
|
+
(locale, options) => new Intl.NumberFormat(locale, options)
|
|
78
|
+
);
|
|
79
|
+
return formatter.format(ratio);
|
|
80
|
+
}
|
|
81
|
+
function formatDateTime(value, { fallback = "—" } = {}) {
|
|
82
|
+
const instant = parseInstant(value);
|
|
83
|
+
if (!instant) {
|
|
84
|
+
return fallback;
|
|
85
|
+
}
|
|
86
|
+
const options = {
|
|
87
|
+
timeZone: toolkitSettings().timeZone,
|
|
88
|
+
day: "numeric",
|
|
89
|
+
month: "short",
|
|
90
|
+
year: "numeric",
|
|
91
|
+
hour: "2-digit",
|
|
92
|
+
minute: "2-digit",
|
|
93
|
+
hourCycle: "h23"
|
|
94
|
+
};
|
|
95
|
+
const formatter = cachedFormatter("dateTime", options, (locale, formatOptions) => new Intl.DateTimeFormat(locale, formatOptions));
|
|
96
|
+
return formatter.format(instant);
|
|
97
|
+
}
|
|
98
|
+
function formatDate(value, { fallback = "—" } = {}) {
|
|
99
|
+
const calendarDate = parsePlainDate(value);
|
|
100
|
+
if (calendarDate) {
|
|
101
|
+
const formatter2 = cachedFormatter(
|
|
102
|
+
"plainDate",
|
|
103
|
+
{ timeZone: "UTC", day: "numeric", month: "short", year: "numeric" },
|
|
104
|
+
(locale, options) => new Intl.DateTimeFormat(locale, options)
|
|
105
|
+
);
|
|
106
|
+
return formatter2.format(new Date(Date.UTC(calendarDate.year, calendarDate.month - 1, calendarDate.day, 12)));
|
|
107
|
+
}
|
|
108
|
+
const instant = parseInstant(value);
|
|
109
|
+
if (!instant) {
|
|
110
|
+
return fallback;
|
|
111
|
+
}
|
|
112
|
+
const formatter = cachedFormatter(
|
|
113
|
+
"date",
|
|
114
|
+
{ timeZone: toolkitSettings().timeZone, day: "numeric", month: "short", year: "numeric" },
|
|
115
|
+
(locale, options) => new Intl.DateTimeFormat(locale, options)
|
|
116
|
+
);
|
|
117
|
+
return formatter.format(instant);
|
|
118
|
+
}
|
|
119
|
+
function formatTime(value, { fallback = "—" } = {}) {
|
|
120
|
+
const instant = parseInstant(value);
|
|
121
|
+
if (!instant) {
|
|
122
|
+
return fallback;
|
|
123
|
+
}
|
|
124
|
+
const formatter = cachedFormatter(
|
|
125
|
+
"time",
|
|
126
|
+
{ timeZone: toolkitSettings().timeZone, hour: "2-digit", minute: "2-digit", hourCycle: "h23" },
|
|
127
|
+
(locale, options) => new Intl.DateTimeFormat(locale, options)
|
|
128
|
+
);
|
|
129
|
+
return formatter.format(instant);
|
|
130
|
+
}
|
|
131
|
+
function formatMonthName(year, month, { style = "long", capitalize = false } = {}) {
|
|
132
|
+
if (!Number.isInteger(Number(year)) || !Number.isInteger(Number(month))) {
|
|
133
|
+
return "—";
|
|
134
|
+
}
|
|
135
|
+
const formatter = cachedFormatter(
|
|
136
|
+
"monthName",
|
|
137
|
+
{ timeZone: "UTC", month: style },
|
|
138
|
+
(locale, options) => new Intl.DateTimeFormat(locale, options)
|
|
139
|
+
);
|
|
140
|
+
const monthName = formatter.format(new Date(Date.UTC(Number(year), Number(month) - 1, 15, 12))).replace(/\.$/, "");
|
|
141
|
+
const label = `${monthName} ${year}`;
|
|
142
|
+
return capitalize ? label.charAt(0).toUpperCase() + label.slice(1) : label;
|
|
143
|
+
}
|
|
144
|
+
function formatMonthShortName(month) {
|
|
145
|
+
const formatter = cachedFormatter(
|
|
146
|
+
"monthShortName",
|
|
147
|
+
{ timeZone: "UTC", month: "short" },
|
|
148
|
+
(locale, options) => new Intl.DateTimeFormat(locale, options)
|
|
149
|
+
);
|
|
150
|
+
return formatter.format(new Date(Date.UTC(2024, Number(month) - 1, 15, 12))).replace(/\.$/, "");
|
|
151
|
+
}
|
|
152
|
+
function formatWeekdayShortName(isoWeekday) {
|
|
153
|
+
const formatter = cachedFormatter(
|
|
154
|
+
"weekdayShortName",
|
|
155
|
+
{ timeZone: "UTC", weekday: "short" },
|
|
156
|
+
(locale, options) => new Intl.DateTimeFormat(locale, options)
|
|
157
|
+
);
|
|
158
|
+
return formatter.format(new Date(Date.UTC(2024, 0, Number(isoWeekday), 12))).replace(/\.$/, "");
|
|
159
|
+
}
|
|
160
|
+
function dayOfPlainDate(value) {
|
|
161
|
+
return parsePlainDate(value)?.day ?? null;
|
|
162
|
+
}
|
|
163
|
+
export {
|
|
164
|
+
dayOfPlainDate,
|
|
165
|
+
formatCurrency,
|
|
166
|
+
formatDate,
|
|
167
|
+
formatDateTime,
|
|
168
|
+
formatFileSize,
|
|
169
|
+
formatList,
|
|
170
|
+
formatMonthName,
|
|
171
|
+
formatMonthShortName,
|
|
172
|
+
formatNumber,
|
|
173
|
+
formatPercent,
|
|
174
|
+
formatTime,
|
|
175
|
+
formatWeekdayShortName
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=formatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.js","sources":["../src/formatting.js"],"sourcesContent":["// Cómo se escriben números, porcentajes y fechas en pantalla.\n//\n// Siempre en el idioma activo (es-MX o en-US), las fechas en la zona y los montos en la moneda del proveedor\n// (ToolkitProvider). Cuando una hora necesita rótulo, la pantalla lo escribe con su propio texto («hora del centro de\n// México») y no con la abreviatura de Intl (GMT-6), que no le dice nada a la persona.\n//\n// Los Intl.* se memorizan por idioma: crear un formateador por celda en una tabla de cientos de filas se nota.\n//\n// Funciones puras, no renderizan: function (regla de la casa).\nimport {parseInstant, parsePlainDate} from '@/dates.js';\nimport {intlLocaleOf, toolkitSettings} from '@/toolkit/toolkitSettings.js';\n\nconst formatterCache = new Map();\n\nfunction activeLocale() {\n return intlLocaleOf(toolkitSettings().language);\n}\n\nfunction cachedFormatter(kind, options, createFormatter) {\n const locale = activeLocale();\n const cacheKey = `${kind}|${locale}|${JSON.stringify(options)}`;\n if (!formatterCache.has(cacheKey)) {\n formatterCache.set(cacheKey, createFormatter(locale, options));\n }\n return formatterCache.get(cacheKey);\n}\n\n/**\n * Número con separador de miles: 321,540.\n *\n * @param {number|string|null|undefined} value\n * @param {string} [fallback] lo que se pinta si no hay dato\n */\nexport function formatNumber(value, fallback = '—') {\n if (value === null || value === undefined || value === '' || Number.isNaN(Number(value))) {\n return fallback;\n }\n const formatter = cachedFormatter('number', {maximumFractionDigits: 0},\n (locale, options) => new Intl.NumberFormat(locale, options));\n return formatter.format(Number(value));\n}\n\n/**\n * Una lista en una frase, con su «y» antes de la última parte: «resumen, motivos de rechazo y descargas».\n *\n * @param {string[]} items las partes de la lista, ya traducidas\n * @returns {string} la frase; '' si la lista viene vacía\n */\nexport function formatList(items) {\n const formatter = cachedFormatter('list', {style: 'long', type: 'conjunction'},\n (locale, options) => new Intl.ListFormat(locale, options));\n return formatter.format(items);\n}\n\n\n/**\n * Monto en la moneda del proveedor con dos decimales: $2,567,951.00. Recibe el texto que manda el API (numeric de la base) o un número;\n * solo pinta, nunca suma (las sumas las hace el backend al centavo).\n *\n * @param {number|string|null|undefined} value\n * @param {string} [fallback] lo que se pinta si no hay dato\n */\nexport function formatCurrency(value, fallback = '—') {\n if (value === null || value === undefined || value === '' || Number.isNaN(Number(value))) {\n return fallback;\n }\n const formatter = cachedFormatter('currency', {\n style: 'currency', currency: toolkitSettings().currency, currencyDisplay: 'narrowSymbol', minimumFractionDigits: 2, maximumFractionDigits: 2,\n }, (locale, options) => new Intl.NumberFormat(locale, options));\n return formatter.format(Number(value));\n}\n\n/**\n * Tamaño de un archivo en la unidad que se lee mejor: 950 B, 12.4 kB, 60.1 MB, 2.3 GB.\n *\n * @param {number|null|undefined} bytes\n * @param {string} [fallback] lo que se pinta si no hay dato\n */\nexport function formatFileSize(bytes, fallback = '—') {\n if (bytes === null || bytes === undefined || Number.isNaN(Number(bytes))) {\n return fallback;\n }\n // unidades de Intl en base 1000, igual que las que enseña el navegador en sus descargas\n const units = [['gigabyte', 1e9], ['megabyte', 1e6], ['kilobyte', 1e3]];\n for (const [unit, unitBytes] of units) {\n if (Number(bytes) >= unitBytes) {\n const formatter = cachedFormatter(`fileSize-${unit}`, {style: 'unit', unit, maximumFractionDigits: 1},\n (locale, options) => new Intl.NumberFormat(locale, options));\n return formatter.format(Number(bytes) / unitBytes);\n }\n }\n // OJO: con la forma corta Intl no pone plural («74 byte», y «1 B» con el uno); la larga dice «74 bytes» y «1 byte»,\n // como lo enseña la Mac. Las demás unidades se quedan cortas (kB, MB): ahí la abreviatura sí se lee bien.\n const formatter = cachedFormatter('fileSize-byte', {style: 'unit', unit: 'byte', unitDisplay: 'long', maximumFractionDigits: 0},\n (locale, options) => new Intl.NumberFormat(locale, options));\n return formatter.format(Number(bytes));\n}\n\n/**\n * Porcentaje a partir de una proporción o de un número ya en porcentaje.\n *\n * @param {number|null|undefined} value 99.58 (con isRatio false) o 0.9958 (con isRatio true)\n * @param {{fractionDigits?: number, isRatio?: boolean, fallback?: string}} [options]\n */\nexport function formatPercent(value, {fractionDigits = 2, isRatio = false, fallback = '—'} = {}) {\n if (value === null || value === undefined || Number.isNaN(Number(value))) {\n return fallback;\n }\n const ratio = isRatio ? Number(value) : Number(value) / 100;\n const formatter = cachedFormatter('percent', {style: 'percent', minimumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits},\n (locale, options) => new Intl.NumberFormat(locale, options));\n return formatter.format(ratio);\n}\n\n/**\n * Fecha y hora de un instante ISO en la zona del negocio.\n *\n * @param {string|null|undefined} value instante ISO con desfase\n * @param {{fallback?: string}} [options]\n */\nexport function formatDateTime(value, {fallback = '—'} = {}) {\n const instant = parseInstant(value);\n if (!instant) {\n return fallback;\n }\n const options = {\n timeZone: toolkitSettings().timeZone,\n day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', hourCycle: 'h23',\n };\n const formatter = cachedFormatter('dateTime', options, (locale, formatOptions) => new Intl.DateTimeFormat(locale, formatOptions));\n return formatter.format(instant);\n}\n\n/**\n * Solo la fecha. Acepta un instante ISO (se pasa a la zona del negocio) o una fecha de calendario \"2026-08-16\"\n * (se pinta tal cual, sin moverla de día).\n *\n * @param {string|null|undefined} value\n * @param {{fallback?: string}} [options]\n */\nexport function formatDate(value, {fallback = '—'} = {}) {\n const calendarDate = parsePlainDate(value);\n if (calendarDate) {\n const formatter = cachedFormatter('plainDate', {timeZone: 'UTC', day: 'numeric', month: 'short', year: 'numeric'},\n (locale, options) => new Intl.DateTimeFormat(locale, options));\n // mediodía UTC y Intl en UTC: el mismo día en cualquier zona\n return formatter.format(new Date(Date.UTC(calendarDate.year, calendarDate.month - 1, calendarDate.day, 12)));\n }\n const instant = parseInstant(value);\n if (!instant) {\n return fallback;\n }\n const formatter = cachedFormatter('date', {timeZone: toolkitSettings().timeZone, day: 'numeric', month: 'short', year: 'numeric'},\n (locale, options) => new Intl.DateTimeFormat(locale, options));\n return formatter.format(instant);\n}\n\n/**\n * Solo la hora (24 h) de un instante ISO en la zona del negocio: \"07:00\".\n *\n * Existe aparte de formatDateTime porque las pantallas escriben \"16 ago 2026 · 07:00\" con punto medio, y Intl une\n * fecha y hora con coma: se arma formatDate + formatTime.\n *\n * @param {string|null|undefined} value instante ISO con desfase\n * @param {{fallback?: string}} [options]\n */\nexport function formatTime(value, {fallback = '—'} = {}) {\n const instant = parseInstant(value);\n if (!instant) {\n return fallback;\n }\n const formatter = cachedFormatter('time', {timeZone: toolkitSettings().timeZone, hour: '2-digit', minute: '2-digit', hourCycle: 'h23'},\n (locale, options) => new Intl.DateTimeFormat(locale, options));\n return formatter.format(instant);\n}\n\n/**\n * Nombre de un mes de calendario: \"agosto 2026\" (long) o \"ago 2026\" (short).\n *\n * OJO: no se usa Intl con {month, year} juntos porque en español sale \"agosto de 2026\" y las pantallas dicen\n * \"agosto 2026\"; se pide solo el mes y se pega el año.\n *\n * @param {number} year\n * @param {number} month 1 a 12\n * @param {{style?: 'long'|'short', capitalize?: boolean}} [options] capitalize: \"Agosto 2026\" (fila de mes)\n */\nexport function formatMonthName(year, month, {style = 'long', capitalize = false} = {}) {\n if (!Number.isInteger(Number(year)) || !Number.isInteger(Number(month))) {\n return '—';\n }\n const formatter = cachedFormatter('monthName', {timeZone: 'UTC', month: style},\n (locale, options) => new Intl.DateTimeFormat(locale, options));\n // día 15 a mediodía UTC: el mismo mes en cualquier zona\n const monthName = formatter.format(new Date(Date.UTC(Number(year), Number(month) - 1, 15, 12))).replace(/\\.$/, '');\n const label = `${monthName} ${year}`;\n return capitalize ? label.charAt(0).toUpperCase() + label.slice(1) : label;\n}\n\n/**\n * Nombre corto de un mes sin año: \"ene\", \"feb\" (rótulos de columnas de calendario y rejillas por periodo).\n *\n * @param {number} month 1 a 12\n * @returns {string}\n */\nexport function formatMonthShortName(month) {\n const formatter = cachedFormatter('monthShortName', {timeZone: 'UTC', month: 'short'},\n (locale, options) => new Intl.DateTimeFormat(locale, options));\n // 2024 empieza en lunes y es bisiesto: da igual, solo se pide el mes a mediodía UTC\n return formatter.format(new Date(Date.UTC(2024, Number(month) - 1, 15, 12))).replace(/\\.$/, '');\n}\n\n/**\n * Nombre corto de un día de la semana: \"lun\", \"mié\" (renglones del calendario de actividad).\n *\n * @param {number} isoWeekday 1 = lunes ... 7 = domingo\n * @returns {string}\n */\nexport function formatWeekdayShortName(isoWeekday) {\n const formatter = cachedFormatter('weekdayShortName', {timeZone: 'UTC', weekday: 'short'},\n (locale, options) => new Intl.DateTimeFormat(locale, options));\n // el 1 de enero de 2024 fue lunes: lunes + (isoWeekday - 1) días\n return formatter.format(new Date(Date.UTC(2024, 0, Number(isoWeekday), 12))).replace(/\\.$/, '');\n}\n\n/**\n * Día del mes de una fecha de calendario (\"2026-08-16\" → 16), sin moverla de zona.\n *\n * @param {string|null|undefined} value\n * @returns {number|null}\n */\nexport function dayOfPlainDate(value) {\n return parsePlainDate(value)?.day ?? null;\n}\n"],"names":["formatter"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import CatalogInput from "../inputs/CatalogInput.js";
|
|
4
|
+
import { useFormikField } from "./useFormikField.js";
|
|
5
|
+
function FormCatalogField({ name, ...catalogInputProps }) {
|
|
6
|
+
const fieldProps = useFormikField(name);
|
|
7
|
+
return /* @__PURE__ */ jsx(CatalogInput, { ...catalogInputProps, ...fieldProps });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FormCatalogField as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=FormCatalogField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormCatalogField.js","sources":["../../src/forms/FormCatalogField.jsx"],"sourcesContent":["// Campo de catálogo de formik: CatalogInput (inputs/) conectado a su campo. Al formulario llega solo la clave.\n//\n// Genérico del paquete: function (regla de la casa).\nimport CatalogInput from '@/inputs/CatalogInput.jsx';\nimport {useFormikField} from '@/forms/useFormikField.js';\n\n/**\n * @param {{name: string} & Omit<Parameters<typeof import('@/inputs/CatalogInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las de CatalogInput (options, formatLabel, loading…), sin value / onChange / onBlur / error\n */\nexport default function FormCatalogField({name, ...catalogInputProps}) {\n const fieldProps = useFormikField(name);\n return <CatalogInput {...catalogInputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AASA,SAAwB,iBAAiB,EAAC,MAAM,GAAG,qBAAoB;AACnE,QAAM,aAAa,eAAe,IAAI;AACtC,SAAO,oBAAC,cAAA,EAAc,GAAG,mBAAoB,GAAG,WAAA,CAAY;AAChE;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import ColorInput from "../inputs/ColorInput.js";
|
|
4
|
+
import { useFormikField } from "./useFormikField.js";
|
|
5
|
+
function FormColorField({ name, ...colorInputProps }) {
|
|
6
|
+
const fieldProps = useFormikField(name);
|
|
7
|
+
return /* @__PURE__ */ jsx(ColorInput, { ...colorInputProps, ...fieldProps });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FormColorField as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=FormColorField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormColorField.js","sources":["../../src/forms/FormColorField.jsx"],"sourcesContent":["// Campo de color de formik: ColorInput (inputs/) conectado a su campo. Al formulario llega '#RRGGBB' en mayúsculas.\n//\n// Genérico del paquete: function (regla de la casa).\nimport ColorInput from '@/inputs/ColorInput.jsx';\nimport {useFormikField} from '@/forms/useFormikField.js';\n\n/**\n * @param {{name: string} & Omit<Parameters<typeof import('@/inputs/ColorInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las de ColorInput (checkContrast…), sin value / onChange / onBlur / error\n */\nexport default function FormColorField({name, ...colorInputProps}) {\n const fieldProps = useFormikField(name);\n return <ColorInput {...colorInputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AASA,SAAwB,eAAe,EAAC,MAAM,GAAG,mBAAkB;AAC/D,QAAM,aAAa,eAAe,IAAI;AACtC,SAAO,oBAAC,YAAA,EAAY,GAAG,iBAAkB,GAAG,WAAA,CAAY;AAC5D;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import NumberInput from "../inputs/NumberInput.js";
|
|
4
|
+
import { useFormikField } from "./useFormikField.js";
|
|
5
|
+
function FormNumberField({ name, ...numberInputProps }) {
|
|
6
|
+
const fieldProps = useFormikField(name);
|
|
7
|
+
return /* @__PURE__ */ jsx(NumberInput, { ...numberInputProps, ...fieldProps });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FormNumberField as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=FormNumberField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormNumberField.js","sources":["../../src/forms/FormNumberField.jsx"],"sourcesContent":["// Campo de número de formik: NumberInput (inputs/) conectado a su campo. Al formulario llega el texto limpio\n// ('2850000.50'), listo para Money.fromString o para el servidor.\n//\n// Genérico del paquete: function (regla de la casa).\nimport NumberInput from '@/inputs/NumberInput.jsx';\nimport {useFormikField} from '@/forms/useFormikField.js';\n\n/**\n * @param {{name: string} & Omit<Parameters<typeof import('@/inputs/NumberInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las de NumberInput (decimals, prefix, suffix, allowNegative…), sin value / onChange / onBlur / error\n */\nexport default function FormNumberField({name, ...numberInputProps}) {\n const fieldProps = useFormikField(name);\n return <NumberInput {...numberInputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAUA,SAAwB,gBAAgB,EAAC,MAAM,GAAG,oBAAmB;AACjE,QAAM,aAAa,eAAe,IAAI;AACtC,SAAO,oBAAC,aAAA,EAAa,GAAG,kBAAmB,GAAG,WAAA,CAAY;AAC9D;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useFormikContext } from "formik";
|
|
4
|
+
import Alert from "@mui/material/Alert";
|
|
5
|
+
function FormProblemAlert({ sx }) {
|
|
6
|
+
const { status } = useFormikContext();
|
|
7
|
+
if (!status) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return /* @__PURE__ */ jsx(Alert, { severity: "error", role: "alert", sx, children: status });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
FormProblemAlert as default
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=FormProblemAlert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormProblemAlert.js","sources":["../../src/forms/FormProblemAlert.jsx"],"sourcesContent":["// El aviso de arriba del formulario de formik: lo que el servidor dijo que no es de un campo (sin conexión, un 409, un 500)\n// o el error de un campo que el formulario no tiene. applyServerProblem lo deja en el status de formik; aquí se pinta.\n//\n// Sin mensaje no pinta nada ni ocupa lugar.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useFormikContext} from 'formik';\nimport Alert from '@mui/material/Alert';\n\n/**\n * @param {{sx?: object}} props\n */\nexport default function FormProblemAlert({sx}) {\n const {status} = useFormikContext();\n\n // guard clause: sin aviso del servidor\n if (!status) {\n return null;\n }\n return <Alert severity=\"error\" role=\"alert\" sx={sx}>{status}</Alert>;\n}\n"],"names":[],"mappings":";;;;AAYA,SAAwB,iBAAiB,EAAC,MAAK;AAC3C,QAAM,EAAC,OAAA,IAAU,iBAAA;AAGjB,MAAI,CAAC,QAAQ;AACT,WAAO;AAAA,EACX;AACA,6BAAQ,OAAA,EAAM,UAAS,SAAQ,MAAK,SAAQ,IAAS,UAAA,QAAO;AAChE;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import SelectInput from "../inputs/SelectInput.js";
|
|
4
|
+
import { useFormikField } from "./useFormikField.js";
|
|
5
|
+
function FormSelectField({ name, ...selectInputProps }) {
|
|
6
|
+
const fieldProps = useFormikField(name);
|
|
7
|
+
return /* @__PURE__ */ jsx(SelectInput, { ...selectInputProps, ...fieldProps });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FormSelectField as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=FormSelectField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSelectField.js","sources":["../../src/forms/FormSelectField.jsx"],"sourcesContent":["// Lista desplegable de formik: SelectInput (inputs/) conectada a su campo.\n//\n// Genérico del paquete: function (regla de la casa).\nimport SelectInput from '@/inputs/SelectInput.jsx';\nimport {useFormikField} from '@/forms/useFormikField.js';\n\n/**\n * @param {{name: string} & Omit<Parameters<typeof import('@/inputs/SelectInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las de SelectInput, sin value / onChange / onBlur / error\n */\nexport default function FormSelectField({name, ...selectInputProps}) {\n const fieldProps = useFormikField(name);\n return <SelectInput {...selectInputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AASA,SAAwB,gBAAgB,EAAC,MAAM,GAAG,oBAAmB;AACjE,QAAM,aAAa,eAAe,IAAI;AACtC,SAAO,oBAAC,aAAA,EAAa,GAAG,kBAAmB,GAAG,WAAA,CAAY;AAC9D;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { useFormikContext } from "formik";
|
|
4
|
+
import { splitServerFieldErrors } from "./serverProblemFields.js";
|
|
5
|
+
import { fieldErrorsOf } from "../problems.js";
|
|
6
|
+
function FormServerProblem({ error }) {
|
|
7
|
+
const { setFieldError, setFieldTouched, values } = useFormikContext();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!error) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const { fieldErrors } = splitServerFieldErrors(fieldErrorsOf(error.problem), Object.keys(values));
|
|
13
|
+
for (const [fieldName, message] of Object.entries(fieldErrors)) {
|
|
14
|
+
setFieldTouched(fieldName, true, false);
|
|
15
|
+
setFieldError(fieldName, message);
|
|
16
|
+
}
|
|
17
|
+
}, [error]);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
FormServerProblem as default
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=FormServerProblem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormServerProblem.js","sources":["../../src/forms/FormServerProblem.jsx"],"sourcesContent":["// Puente entre una máquina de estados y Formik: pinta en sus campos los errores 422 que trae el error del servidor.\n//\n// Por qué existe: con XState el envío lo hace la máquina (no el onSubmit de Formik), así que el error llega en el\n// contexto de la máquina y no en los helpers de Formik. Este componente vive DENTRO del <Formik> y, cada vez que\n// llega un error nuevo, lo reparte en los campos que existen. El aviso de arriba lo pinta la pantalla desde el estado\n// de la máquina (formLevelMessageOf).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect} from 'react';\nimport {useFormikContext} from 'formik';\n\nimport {splitServerFieldErrors} from '@/forms/serverProblemFields.js';\nimport {fieldErrorsOf} from '@/problems.js';\n\n/**\n * @param {{error: (Error & {problem?: object})|null}} props el error del contexto de la máquina (null = sin error)\n */\nexport default function FormServerProblem({error}) {\n const {setFieldError, setFieldTouched, values} = useFormikContext();\n\n useEffect(() => {\n // guard clause: sin error nuevo no hay nada que pintar\n if (!error) {\n return;\n }\n const {fieldErrors} = splitServerFieldErrors(fieldErrorsOf(error.problem), Object.keys(values));\n for (const [fieldName, message] of Object.entries(fieldErrors)) {\n // tocado primero y sin validar: si no, la validación de yup borraría el error del servidor al instante\n setFieldTouched(fieldName, true, false);\n setFieldError(fieldName, message);\n }\n // OJO: solo cuando cambia el error; values cambia con cada tecla y no debe volver a pintar el error viejo\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [error]);\n\n return null;\n}\n"],"names":[],"mappings":";;;;;AAiBA,SAAwB,kBAAkB,EAAC,SAAQ;AAC/C,QAAM,EAAC,eAAe,iBAAiB,OAAA,IAAU,iBAAA;AAEjD,YAAU,MAAM;AAEZ,QAAI,CAAC,OAAO;AACR;AAAA,IACJ;AACA,UAAM,EAAC,YAAA,IAAe,uBAAuB,cAAc,MAAM,OAAO,GAAG,OAAO,KAAK,MAAM,CAAC;AAC9F,eAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAQ,WAAW,GAAG;AAE5D,sBAAgB,WAAW,MAAM,KAAK;AACtC,oBAAc,WAAW,OAAO;AAAA,IACpC;AAAA,EAGJ,GAAG,CAAC,KAAK,CAAC;AAEV,SAAO;AACX;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import TextInput from "../inputs/TextInput.js";
|
|
4
|
+
import { useFormikField } from "./useFormikField.js";
|
|
5
|
+
function FormTextField({ name, ...textInputProps }) {
|
|
6
|
+
const fieldProps = useFormikField(name);
|
|
7
|
+
return /* @__PURE__ */ jsx(TextInput, { ...textInputProps, ...fieldProps });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FormTextField as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=FormTextField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormTextField.js","sources":["../../src/forms/FormTextField.jsx"],"sourcesContent":["// Campo de texto de formik: TextInput (inputs/) conectado a su campo. Lo visual y sus reglas (etiqueta arriba, ojo de las\n// contraseñas, mayúsculas, normalizar al salir, el error en el idioma activo) viven en TextInput.\n//\n// Genérico del paquete: function (regla de la casa).\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {useFormikField} from '@/forms/useFormikField.js';\n\n/**\n * @param {{name: string} & Omit<Parameters<typeof import('@/inputs/TextInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las de TextInput, sin value / onChange / onBlur / error\n */\nexport default function FormTextField({name, ...textInputProps}) {\n const fieldProps = useFormikField(name);\n return <TextInput {...textInputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAUA,SAAwB,cAAc,EAAC,MAAM,GAAG,kBAAiB;AAC7D,QAAM,aAAa,eAAe,IAAI;AACtC,SAAO,oBAAC,WAAA,EAAW,GAAG,gBAAiB,GAAG,WAAA,CAAY;AAC1D;"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useRef, useEffect } from "react";
|
|
4
|
+
import { useFormikContext, getIn } from "formik";
|
|
5
|
+
import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
|
|
6
|
+
import Box from "@mui/material/Box";
|
|
7
|
+
import Button from "@mui/material/Button";
|
|
8
|
+
import Stack from "@mui/material/Stack";
|
|
9
|
+
import Step from "@mui/material/Step";
|
|
10
|
+
import StepLabel from "@mui/material/StepLabel";
|
|
11
|
+
import Stepper from "@mui/material/Stepper";
|
|
12
|
+
import Typography from "@mui/material/Typography";
|
|
13
|
+
import FormProblemAlert from "./FormProblemAlert.js";
|
|
14
|
+
import SubmitButton from "./SubmitButton.js";
|
|
15
|
+
function firstStepWithErrorOf(steps, errors) {
|
|
16
|
+
return steps.findIndex((step) => (step.fields ?? []).some((field) => getIn(errors, field)));
|
|
17
|
+
}
|
|
18
|
+
function FormWizard({ steps, submitLabel }) {
|
|
19
|
+
const { t } = useToolkitTranslation("common");
|
|
20
|
+
const { validateForm, setFieldTouched, setFieldValue, initialValues, errors, isSubmitting } = useFormikContext();
|
|
21
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
22
|
+
const [skippedKeys, setSkippedKeys] = useState(() => /* @__PURE__ */ new Set());
|
|
23
|
+
const wasSubmitting = useRef(false);
|
|
24
|
+
const activeStep = steps[activeIndex];
|
|
25
|
+
const isLastStep = activeIndex === steps.length - 1;
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (wasSubmitting.current && !isSubmitting) {
|
|
28
|
+
const errorStepIndex = firstStepWithErrorOf(steps, errors);
|
|
29
|
+
if (errorStepIndex >= 0) {
|
|
30
|
+
setActiveIndex(errorStepIndex);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
wasSubmitting.current = isSubmitting;
|
|
34
|
+
}, [isSubmitting, errors, steps]);
|
|
35
|
+
const goNext = async () => {
|
|
36
|
+
const stepFields = activeStep.fields ?? [];
|
|
37
|
+
const formErrors = await validateForm();
|
|
38
|
+
stepFields.forEach((field) => setFieldTouched(field, true, false));
|
|
39
|
+
if (stepFields.some((field) => getIn(formErrors, field))) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setSkippedKeys((currentKeys) => new Set([...currentKeys].filter((key) => key !== activeStep.key)));
|
|
43
|
+
setActiveIndex((currentIndex) => currentIndex + 1);
|
|
44
|
+
};
|
|
45
|
+
const skipStep = () => {
|
|
46
|
+
for (const field of activeStep.fields ?? []) {
|
|
47
|
+
setFieldValue(field, getIn(initialValues, field), false);
|
|
48
|
+
setFieldTouched(field, false, false);
|
|
49
|
+
}
|
|
50
|
+
setSkippedKeys((currentKeys) => /* @__PURE__ */ new Set([...currentKeys, activeStep.key]));
|
|
51
|
+
setActiveIndex((currentIndex) => currentIndex + 1);
|
|
52
|
+
};
|
|
53
|
+
return /* @__PURE__ */ jsxs(Stack, { spacing: 3, children: [
|
|
54
|
+
/* @__PURE__ */ jsx(Stepper, { activeStep: activeIndex, alternativeLabel: true, sx: { display: { xs: "none", sm: "flex" } }, children: steps.map((step) => {
|
|
55
|
+
let caption;
|
|
56
|
+
if (skippedKeys.has(step.key)) {
|
|
57
|
+
caption = t("wizard.skipped");
|
|
58
|
+
} else if (step.optional) {
|
|
59
|
+
caption = t("wizard.optional");
|
|
60
|
+
}
|
|
61
|
+
return /* @__PURE__ */ jsx(Step, { completed: skippedKeys.has(step.key) ? false : void 0, children: /* @__PURE__ */ jsx(StepLabel, { optional: caption && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: caption }), children: step.label }) }, step.key);
|
|
62
|
+
}) }),
|
|
63
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: { xs: "block", sm: "none" } }, children: [
|
|
64
|
+
/* @__PURE__ */ jsx(Typography, { variant: "overline", color: "text.secondary", children: t("wizard.stepOf", { current: activeIndex + 1, total: steps.length }) }),
|
|
65
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", children: activeStep.label })
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ jsx(Box, { children: activeStep.content }),
|
|
68
|
+
isLastStep && /* @__PURE__ */ jsx(FormProblemAlert, {}),
|
|
69
|
+
/* @__PURE__ */ jsxs(Stack, { direction: { xs: "column-reverse", sm: "row" }, spacing: 1.5, sx: { justifyContent: "space-between" }, children: [
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
Button,
|
|
72
|
+
{
|
|
73
|
+
variant: "text",
|
|
74
|
+
color: "inherit",
|
|
75
|
+
disabled: activeIndex === 0 || isSubmitting,
|
|
76
|
+
onClick: () => setActiveIndex((currentIndex) => currentIndex - 1),
|
|
77
|
+
children: t("wizard.back")
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ jsxs(Stack, { direction: { xs: "column-reverse", sm: "row" }, spacing: 1.5, children: [
|
|
81
|
+
activeStep.optional && !isLastStep && /* @__PURE__ */ jsx(Button, { variant: "text", onClick: skipStep, children: t("wizard.skip") }),
|
|
82
|
+
isLastStep ? /* @__PURE__ */ jsx(SubmitButton, { children: submitLabel }) : /* @__PURE__ */ jsx(Button, { variant: "contained", size: "large", onClick: goNext, children: t("wizard.next") })
|
|
83
|
+
] })
|
|
84
|
+
] })
|
|
85
|
+
] });
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
FormWizard as default
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=FormWizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormWizard.js","sources":["../../src/forms/FormWizard.jsx"],"sourcesContent":["// Formulario por pasos (wizard) con formik: un solo formulario partido en pasos, con pasos opcionales que se pueden omitir.\n//\n// Cómo se porta, para que la pantalla solo declare sus pasos:\n// - «Siguiente» revisa SOLO los campos del paso (fields) y no avanza si alguno tiene error; los marca como tocados para\n// que se vea por qué;\n// - «Omitir este paso» (solo en los opcionales) regresa sus campos a como empezaron: omitir es no dar ese dato, no dejar\n// lo que se escribió a medias;\n// - el último paso envía TODO el formulario (el esquema de yup completo vale para todos los pasos);\n// - si el envío falla por un campo de un paso anterior (yup o el 422 del servidor con applyServerProblem), el wizard\n// regresa solo a ese paso: un error que no se ve no se puede corregir.\n//\n// Va DENTRO de <Formik> y <Form>:\n// <Formik initialValues={…} validationSchema={…} onSubmit={…}>\n// <Form noValidate>\n// <FormWizard submitLabel=\"Enviar solicitud\" steps={[\n// {key: 'datos', label: 'Sus datos', fields: ['name', 'email'], content: <>…campos…</>},\n// {key: 'aval', label: 'Aval', optional: true, fields: ['guarantor'], content: <>…</>},\n// ]} />\n// </Form>\n// </Formik>\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\nimport {getIn, useFormikContext} from 'formik';\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Stack from '@mui/material/Stack';\nimport Step from '@mui/material/Step';\nimport StepLabel from '@mui/material/StepLabel';\nimport Stepper from '@mui/material/Stepper';\nimport Typography from '@mui/material/Typography';\n\nimport FormProblemAlert from '@/forms/FormProblemAlert.jsx';\nimport SubmitButton from '@/forms/SubmitButton.jsx';\n\n/**\n * El primer paso que tiene un campo con error; -1 si ninguno.\n *\n * @param {Array<{fields?: string[]}>} steps\n * @param {object} errors los de formik\n * @returns {number}\n */\nfunction firstStepWithErrorOf(steps, errors) {\n return steps.findIndex((step) => (step.fields ?? []).some((field) => getIn(errors, field)));\n}\n\n/**\n * @param {object} props\n * @param {Object[]} props.steps en orden\n * @param {string} props.steps[].key\n * @param {string} props.steps[].label ya traducido\n * @param {string[]} [props.steps[].fields] los campos del paso (los que revisa «Siguiente»)\n * @param {boolean} [props.steps[].optional] se puede omitir\n * @param {import('react').ReactNode} props.steps[].content los campos del paso\n * @param {string} props.submitLabel ya traducido: el botón del último paso\n */\nexport default function FormWizard({steps, submitLabel}) {\n const {t} = useToolkitTranslation('common');\n const {validateForm, setFieldTouched, setFieldValue, initialValues, errors, isSubmitting} = useFormikContext();\n const [activeIndex, setActiveIndex] = useState(0);\n const [skippedKeys, setSkippedKeys] = useState(() => new Set());\n const wasSubmitting = useRef(false);\n const activeStep = steps[activeIndex];\n const isLastStep = activeIndex === steps.length - 1;\n\n // al terminar un envío fallido, regresa al paso con el primer error (solo en ese momento: escribir en otro paso no\n // debe jalar a la persona de regreso)\n useEffect(() => {\n if (wasSubmitting.current && !isSubmitting) {\n const errorStepIndex = firstStepWithErrorOf(steps, errors);\n if (errorStepIndex >= 0) {\n setActiveIndex(errorStepIndex);\n }\n }\n wasSubmitting.current = isSubmitting;\n }, [isSubmitting, errors, steps]);\n\n const goNext = async () => {\n const stepFields = activeStep.fields ?? [];\n const formErrors = await validateForm();\n stepFields.forEach((field) => setFieldTouched(field, true, false));\n // guard clause: el paso tiene errores; se queda para que se corrijan\n if (stepFields.some((field) => getIn(formErrors, field))) {\n return;\n }\n setSkippedKeys((currentKeys) => new Set([...currentKeys].filter((key) => key !== activeStep.key)));\n setActiveIndex((currentIndex) => currentIndex + 1);\n };\n\n const skipStep = () => {\n for (const field of activeStep.fields ?? []) {\n setFieldValue(field, getIn(initialValues, field), false);\n setFieldTouched(field, false, false);\n }\n setSkippedKeys((currentKeys) => new Set([...currentKeys, activeStep.key]));\n setActiveIndex((currentIndex) => currentIndex + 1);\n };\n\n return (\n <Stack spacing={3}>\n {/* en el teléfono los nombres de los pasos no caben: se dice en qué paso va */}\n <Stepper activeStep={activeIndex} alternativeLabel sx={{display: {xs: 'none', sm: 'flex'}}}>\n {steps.map((step) => {\n let caption;\n if (skippedKeys.has(step.key)) {\n caption = t('wizard.skipped');\n } else if (step.optional) {\n caption = t('wizard.optional');\n }\n return (\n <Step key={step.key} completed={skippedKeys.has(step.key) ? false : undefined}>\n <StepLabel optional={caption && <Typography variant=\"caption\" color=\"text.secondary\">{caption}</Typography>}>\n {step.label}\n </StepLabel>\n </Step>\n );\n })}\n </Stepper>\n <Box sx={{display: {xs: 'block', sm: 'none'}}}>\n <Typography variant=\"overline\" color=\"text.secondary\">{t('wizard.stepOf', {current: activeIndex + 1, total: steps.length})}</Typography>\n <Typography variant=\"h6\">{activeStep.label}</Typography>\n </Box>\n\n <Box>{activeStep.content}</Box>\n\n {isLastStep && <FormProblemAlert />}\n\n <Stack direction={{xs: 'column-reverse', sm: 'row'}} spacing={1.5} sx={{justifyContent: 'space-between'}}>\n <Button variant=\"text\" color=\"inherit\" disabled={activeIndex === 0 || isSubmitting}\n onClick={() => setActiveIndex((currentIndex) => currentIndex - 1)}>\n {t('wizard.back')}\n </Button>\n <Stack direction={{xs: 'column-reverse', sm: 'row'}} spacing={1.5}>\n {activeStep.optional && !isLastStep && (\n <Button variant=\"text\" onClick={skipStep}>{t('wizard.skip')}</Button>\n )}\n {isLastStep\n ? <SubmitButton>{submitLabel}</SubmitButton>\n : <Button variant=\"contained\" size=\"large\" onClick={goNext}>{t('wizard.next')}</Button>}\n </Stack>\n </Stack>\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useFormikContext } from "formik";
|
|
4
|
+
import Button from "@mui/material/Button";
|
|
5
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
6
|
+
function SubmitButton({ children, disabled, isPending, ...buttonProps }) {
|
|
7
|
+
const { isSubmitting } = useFormikContext();
|
|
8
|
+
const isBusy = Boolean(isPending ?? isSubmitting);
|
|
9
|
+
return /* @__PURE__ */ jsx(Button, { type: "submit", variant: "contained", size: "large", disabled: disabled || isBusy, "aria-busy": isBusy, ...buttonProps, children: isBusy ? /* @__PURE__ */ jsx(CircularProgress, { size: 22, color: "inherit" }) : children });
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
SubmitButton as default
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=SubmitButton.js.map
|