From 9b3c360fa3b081e69fec4030de7f1e98da55ec69 Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Sat, 18 Jan 2025 04:41:50 +0530 Subject: [PATCH 1/7] wip: LocalizationProvider v1 --- .../sign-in-page/ThemeSignInPage.tsx | 1 + packages/toolpad-core/src/Account/Account.tsx | 164 +++++++++--------- .../src/Account/AccountPreview.tsx | 8 +- .../toolpad-core/src/Account/SignInButton.tsx | 5 +- .../src/Account/SignOutButton.tsx | 5 +- .../src/AppProvider/AppProvider.tsx | 11 +- .../src/AppProvider/LocalizationProvider.tsx | 106 +++++++++++ .../toolpad-core/src/AppProvider/index.ts | 1 + .../src/SignInPage/SignInPage.tsx | 30 ++-- packages/toolpad-core/src/index.ts | 2 + packages/toolpad-core/src/locales/en.tsx | 41 +++++ .../src/locales/getLocalization.ts | 13 ++ packages/toolpad-core/src/locales/hiIN.tsx | 42 +++++ packages/toolpad-core/src/locales/index.ts | 2 + .../src/shared/locales/LocaleContext.tsx | 39 ----- .../toolpad-core/src/shared/locales/en.tsx | 9 - .../src/useDialogs/useDialogs.tsx | 20 ++- .../NotificationsProvider.tsx | 8 +- 18 files changed, 345 insertions(+), 162 deletions(-) create mode 100644 packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx create mode 100644 packages/toolpad-core/src/locales/en.tsx create mode 100644 packages/toolpad-core/src/locales/getLocalization.ts create mode 100644 packages/toolpad-core/src/locales/hiIN.tsx create mode 100644 packages/toolpad-core/src/locales/index.ts delete mode 100644 packages/toolpad-core/src/shared/locales/LocaleContext.tsx delete mode 100644 packages/toolpad-core/src/shared/locales/en.tsx diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx index d9ce9dc1702..7e826fe0c49 100644 --- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx +++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx @@ -6,6 +6,7 @@ import { type AuthResponse, } from '@toolpad/core/SignInPage'; import { createTheme } from '@mui/material/styles'; +import { hiIN } from '@toolpad/core/locales'; import { useColorSchemeShim } from 'docs/src/modules/components/ThemeContext'; import { getDesignTokens, inputsCustomizations } from './customTheme'; diff --git a/packages/toolpad-core/src/Account/Account.tsx b/packages/toolpad-core/src/Account/Account.tsx index c63be63b1ff..5dc602ab8f5 100644 --- a/packages/toolpad-core/src/Account/Account.tsx +++ b/packages/toolpad-core/src/Account/Account.tsx @@ -10,7 +10,7 @@ import { AccountPreview, AccountPreviewProps } from './AccountPreview'; import { AccountPopoverHeader } from './AccountPopoverHeader'; import { AccountPopoverFooter } from './AccountPopoverFooter'; import { SessionContext, AuthenticationContext } from '../AppProvider/AppProvider'; -import { LocaleProvider, useLocaleText } from '../shared/locales/LocaleContext'; +import { useLocaleText, type LocaleText } from '../AppProvider'; export interface AccountSlots { /** @@ -58,9 +58,11 @@ export interface AccountProps { /** * The labels for the account component. */ - localeText?: Partial>; + localeText?: LocaleText; } +export const AccountLocaleContext = React.createContext | null>(null); + /** * * Demos: @@ -74,7 +76,9 @@ export interface AccountProps { * - [Account API](https://mui.com/toolpad/core/api/account) */ function Account(props: AccountProps) { - const { localeText } = props; + const { localeText: propsLocaleText } = props; + const globalLocaleText = useLocaleText(); + const localeText = { ...globalLocaleText, ...propsLocaleText }; const { slots, slotProps } = props; const [anchorEl, setAnchorEl] = React.useState(null); const session = React.useContext(SessionContext); @@ -93,89 +97,89 @@ function Account(props: AccountProps) { return null; } + let accountContent = null; + if (!session?.user) { - return ( - - {slots?.signInButton ? ( - + accountContent = slots?.signInButton ? ( + + ) : ( + + ); + } else { + accountContent = ( + + {slots?.preview ? ( + ) : ( - + )} - + {slots?.popover ? ( + + ) : ( + + `drop-shadow(0px 2px 8px ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.32)'})`, + mt: 1, + '&::before': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + right: 14, + width: 10, + height: 10, + bgcolor: 'background.paper', + transform: 'translateY(-50%) rotate(45deg)', + zIndex: 0, + }, + }, + }, + ...slotProps?.popover?.slotProps, + }} + > + {slots?.popoverContent ? ( + + ) : ( + + + + + + + + + + )} + + )} + ); } - return ( - - {slots?.preview ? ( - - ) : ( - - )} - {slots?.popover ? ( - - ) : ( - - `drop-shadow(0px 2px 8px ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.32)'})`, - mt: 1, - '&::before': { - content: '""', - display: 'block', - position: 'absolute', - top: 0, - right: 14, - width: 10, - height: 10, - bgcolor: 'background.paper', - transform: 'translateY(-50%) rotate(45deg)', - zIndex: 0, - }, - }, - }, - ...slotProps?.popover?.slotProps, - }} - > - {slots?.popoverContent ? ( - - ) : ( - - - - - - - - - - )} - - )} - - ); + return {accountContent}; } Account.propTypes /* remove-proptypes */ = { diff --git a/packages/toolpad-core/src/Account/AccountPreview.tsx b/packages/toolpad-core/src/Account/AccountPreview.tsx index 0875eca70f4..034cad6c901 100644 --- a/packages/toolpad-core/src/Account/AccountPreview.tsx +++ b/packages/toolpad-core/src/Account/AccountPreview.tsx @@ -8,7 +8,7 @@ import Stack from '@mui/material/Stack'; import IconButton, { IconButtonProps } from '@mui/material/IconButton'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { SessionContext } from '../AppProvider'; -import { useLocaleText } from '../shared/locales/LocaleContext'; +import { AccountLocaleContext } from '../Account'; export type AccountPreviewVariant = 'condensed' | 'expanded'; @@ -79,7 +79,7 @@ export interface AccountPreviewProps { function AccountPreview(props: AccountPreviewProps) { const { slots, variant = 'condensed', slotProps, open, handleClick, sx } = props; const session = React.useContext(SessionContext); - const localeText = useLocaleText(); + const accountLocaleText = React.useContext(AccountLocaleContext); if (!session || !session.user) { return null; @@ -128,14 +128,14 @@ function AccountPreview(props: AccountPreviewProps) { } return ( - + {slots?.avatarIconButton ? ( ) : ( - {localeText?.signInLabel || 'Sign In'} + {localeText?.accountSignInLabel} ); } diff --git a/packages/toolpad-core/src/Account/SignOutButton.tsx b/packages/toolpad-core/src/Account/SignOutButton.tsx index e9d8e1701b8..657fd842a75 100644 --- a/packages/toolpad-core/src/Account/SignOutButton.tsx +++ b/packages/toolpad-core/src/Account/SignOutButton.tsx @@ -2,8 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Button, { ButtonProps } from '@mui/material/Button'; import LogoutIcon from '@mui/icons-material/Logout'; -import { AuthenticationContext } from '../AppProvider/AppProvider'; -import { useLocaleText } from '../shared/locales/LocaleContext'; +import { AuthenticationContext, useLocaleText } from '../AppProvider'; export type SignOutButtonProps = ButtonProps; @@ -40,7 +39,7 @@ function SignOutButton(props: SignOutButtonProps) { startIcon={} {...props} > - {localeText.signOutLabel} + {localeText.accountSignOutLabel} ); } diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index 0de8c74eec7..a587d8563a6 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -11,6 +11,8 @@ import { WindowContext, } from '../shared/context'; import { AppThemeProvider } from './AppThemeProvider'; +import { LocalizationProvider, type LocaleText } from './LocalizationProvider'; +import DEFAULT_LOCALE_TEXT from '../locales/en'; export interface NavigateOptions { history?: 'auto' | 'push' | 'replace'; @@ -103,6 +105,10 @@ export interface AppProviderProps { * @default null */ router?: Router; + /** + * Locale text for components + */ + localeText?: Partial; /** * Session info about the current user. * @default null @@ -147,6 +153,7 @@ function AppProvider(props: AppProviderProps) { theme = createTheme(), branding = null, navigation = [], + localeText = DEFAULT_LOCALE_TEXT.components.MuiLocalizationProvider.defaultProps.localeText, router = null, authentication = null, session = null, @@ -163,7 +170,9 @@ function AppProvider(props: AppProviderProps) { - {children} + + {children} + diff --git a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx new file mode 100644 index 00000000000..e0a0af5cb86 --- /dev/null +++ b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx @@ -0,0 +1,106 @@ +'use client'; +import * as React from 'react'; +import { useThemeProps } from '@mui/material/styles'; + +export type LocaleText = { + // Account + accountSignInLabel: string; + accountSignOutLabel: string; + // AccountPreview + accountTitle: string; + accountIconButtonLabel: string; + + // SignInPage + signInTitle: string; + signInSubtitle: string; + signInRememberMe: string; + + // Error messages + errorAccessDenied: string; + errorCallbackRoute: string; + errorMissingSecret: string; + errorAuthentication: string; + + // Common authentication labels + email: string; + passkey: string; + username: string; + password: string; + + // Common action labels + or: string; + to: string; + with: string; + save: string; + cancel: string; + ok: string; + close: string; + delete: string; + alert: string; + confirm: string; + loading: string; + error: string; + success: string; + warning: string; + info: string; + + // Navigation + goBack: string; + goHome: string; + + // Form validation + required: string; + invalid: string; + + // Account Preview + accountPreviewTitle: string; + accountPreviewEmail: string; + accountPreviewName: string; + + // Dashboard Layout + dashboardTitle: string; + dashboardWelcome: string; + dashboardSettings: string; + dashboardLogout: string; + + // Error boundaries + errorBoundaryTitle: string; + errorBoundaryDescription: string; + errorBoundaryRetry: string; +}; + +export interface LocalizationProviderProps { + children?: React.ReactNode; + /** + * Locale for components texts + */ + localeText?: Partial; +} + +export const LocalizationContext = React.createContext>({}); + +export const LocalizationProvider = function LocalizationProvider( + props: LocalizationProviderProps, +) { + const { localeText: propsLocaleText, ...otherInProps } = props; + + const themeProps: LocalizationProviderProps = useThemeProps({ + // We don't want to pass the `localeText` prop to the theme, that way it will always return the theme value, + // We will then merge this theme value with our value manually + props: otherInProps, + name: 'MuiLocalizationProvider', + }); + + const { children, localeText: themeLocaleText } = themeProps; + + const localeText = React.useMemo( + () => ({ ...themeLocaleText, ...propsLocaleText }), + [themeLocaleText, propsLocaleText], + ); + + return {children}; +}; + +export function useLocaleText() { + return React.useContext(LocalizationContext); +} diff --git a/packages/toolpad-core/src/AppProvider/index.ts b/packages/toolpad-core/src/AppProvider/index.ts index bd2c0cdccb2..007fe400d13 100644 --- a/packages/toolpad-core/src/AppProvider/index.ts +++ b/packages/toolpad-core/src/AppProvider/index.ts @@ -1 +1,2 @@ export * from './AppProvider'; +export * from './LocalizationProvider'; diff --git a/packages/toolpad-core/src/SignInPage/SignInPage.tsx b/packages/toolpad-core/src/SignInPage/SignInPage.tsx index 5a5c489d992..58f73ae8eb7 100644 --- a/packages/toolpad-core/src/SignInPage/SignInPage.tsx +++ b/packages/toolpad-core/src/SignInPage/SignInPage.tsx @@ -37,6 +37,7 @@ import KeycloakIcon from './icons/Keycloak'; import OktaIcon from './icons/Okta'; import FusionAuthIcon from './icons/FusionAuth'; import { BrandingContext, RouterContext } from '../shared/context'; +import { useLocaleText } from '../AppProvider'; const mergeSlotSx = (defaultSx: SxProps, slotProps?: { sx?: SxProps }) => { if (Array.isArray(slotProps?.sx)) { @@ -277,6 +278,7 @@ function SignInPage(props: SignInPageProps) { const theme = useTheme(); const branding = React.useContext(BrandingContext); const router = React.useContext(RouterContext); + const localeText = useLocaleText(); const passkeyProvider = providers?.find((provider) => provider.id === 'passkey'); const credentialsProvider = providers?.find((provider) => provider.id === 'credentials'); const emailProvider = providers?.find((provider) => provider.id === 'nodemailer'); @@ -339,14 +341,15 @@ function SignInPage(props: SignInPageProps) { fontWeight: 600, }} > - Sign in {branding?.title ? `to ${branding.title}` : null} + {localeText.signInTitle}{' '} + {branding?.title ? `${localeText.to?.toLocaleLowerCase()} ${branding.title}` : null} )} {slots?.subtitle ? ( ) : ( - Welcome, please sign in to continue + {localeText?.signInSubtitle} )} @@ -391,7 +394,10 @@ function SignInPage(props: SignInPageProps) { textTransform: 'capitalize', }} > - Sign in with {provider.name} + + {localeText.signInTitle} {localeText.with?.toLocaleLowerCase()}{' '} + {provider.name} + ); @@ -429,7 +435,7 @@ function SignInPage(props: SignInPageProps) { ) : ( - Sign in with {passkeyProvider.name || 'Passkey'} + {localeText.signInTitle} {localeText.with?.toLocaleLowerCase()}{' '} + {passkeyProvider.name || localeText.passkey} )} @@ -503,7 +510,7 @@ function SignInPage(props: SignInPageProps) { ) : ( - Sign in with Email + {localeText.signInTitle} {localeText.with?.toLocaleLowerCase()}{' '} + {localeText.email} )} @@ -576,7 +584,7 @@ function SignInPage(props: SignInPageProps) { ) : ( } - label="Remember me" + label={localeText.signInRememberMe} {...slotProps?.rememberMe} slotProps={{ typography: { @@ -657,7 +665,7 @@ function SignInPage(props: SignInPageProps) { }} {...slotProps?.submitButton} > - Sign in + {localeText.signInTitle} )} diff --git a/packages/toolpad-core/src/index.ts b/packages/toolpad-core/src/index.ts index 123c479d6c3..0769af5a05e 100644 --- a/packages/toolpad-core/src/index.ts +++ b/packages/toolpad-core/src/index.ts @@ -21,3 +21,5 @@ export * from './useSession'; export * from './useSessionStorageState'; export * from './persistence/codec'; + +export * from './locales'; diff --git a/packages/toolpad-core/src/locales/en.tsx b/packages/toolpad-core/src/locales/en.tsx new file mode 100644 index 00000000000..3fdfd1dbe27 --- /dev/null +++ b/packages/toolpad-core/src/locales/en.tsx @@ -0,0 +1,41 @@ +import type { LocaleText } from '../AppProvider'; +import { getLocalization } from './getLocalization'; + +const en: Partial = { + // Account + accountSignInLabel: 'Sign In', + accountSignOutLabel: 'Sign Out', + + // AccountPreview + accountTitle: 'Account', + accountIconButtonLabel: 'Current User', + // SignInPage + signInTitle: 'Sign In', + signInSubtitle: 'Welcome user, please sign in to continue', + signInRememberMe: 'Remember Me', + + // Common authentication labels + email: 'Email', + password: 'Password', + username: 'Username', + passkey: 'Passkey', + + // Common action labels + save: 'Save', + cancel: 'Cancel', + ok: 'Ok', + or: 'Or', + to: 'To', + with: 'With', + close: 'Close', + delete: 'Delete', + alert: 'Alert', + confirm: 'Confirm', + loading: 'Loading...', + error: 'Error', + success: 'Success', + warning: 'Warning', + info: 'Info', +}; + +export default getLocalization(en); diff --git a/packages/toolpad-core/src/locales/getLocalization.ts b/packages/toolpad-core/src/locales/getLocalization.ts new file mode 100644 index 00000000000..a99a3b5d418 --- /dev/null +++ b/packages/toolpad-core/src/locales/getLocalization.ts @@ -0,0 +1,13 @@ +import type { LocaleText } from '../AppProvider'; + +export const getLocalization = (translations: Partial) => { + return { + components: { + MuiLocalizationProvider: { + defaultProps: { + localeText: { ...translations }, + }, + }, + }, + }; +}; diff --git a/packages/toolpad-core/src/locales/hiIN.tsx b/packages/toolpad-core/src/locales/hiIN.tsx new file mode 100644 index 00000000000..269a5174d2b --- /dev/null +++ b/packages/toolpad-core/src/locales/hiIN.tsx @@ -0,0 +1,42 @@ +import type { LocaleText } from '../AppProvider'; +import { getLocalization } from './getLocalization'; + +const hiINLabels: Partial = { + // Account + accountSignInLabel: 'साइन इन करें', + accountSignOutLabel: 'साइन आउट करें', + + // AccountPreview + accountTitle: 'खाता', + accountIconButtonLabel: 'वर्तमान उपयोगकर्ता', + + // SignInPage + signInTitle: 'साइन इन करें', + signInSubtitle: 'स्वागत है उपयोगकर्ता, कृपया जारी रखने के लिए साइन इन करें', + signInRememberMe: 'मुझे याद रखें', + + // Common authentication labels + email: 'ईमेल', + password: 'पासवर्ड', + username: 'उपयोगकर्ता नाम', + passkey: 'पासकी', + + // Common action labels + save: 'सहेजें', + cancel: 'रद्द करें', + ok: 'ठीक है', + or: 'या', + to: 'को', + with: 'के साथ', + close: 'बंद करें', + delete: 'हटाएं', + alert: 'सूचना', + confirm: 'पुष्टि करें', + loading: 'लोड हो रहा है...', + error: 'त्रुटि', + success: 'सफल', + warning: 'चेतावनी', + info: 'जानकारी', +}; + +export const hiIN = getLocalization(hiINLabels); diff --git a/packages/toolpad-core/src/locales/index.ts b/packages/toolpad-core/src/locales/index.ts new file mode 100644 index 00000000000..ddf0aaeb937 --- /dev/null +++ b/packages/toolpad-core/src/locales/index.ts @@ -0,0 +1,2 @@ +export * from './en'; +export * from './hiIN'; diff --git a/packages/toolpad-core/src/shared/locales/LocaleContext.tsx b/packages/toolpad-core/src/shared/locales/LocaleContext.tsx deleted file mode 100644 index abfb38d6d5d..00000000000 --- a/packages/toolpad-core/src/shared/locales/LocaleContext.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client'; - -import * as React from 'react'; -import DEFAULT_LOCALE_TEXT from './en'; - -export type LocaleContextType = { - // Account - signInLabel?: string; - signOutLabel?: string; - // Account Preview - iconButtonAriaLabel?: string; -}; - -export const LocaleContext = React.createContext(DEFAULT_LOCALE_TEXT); - -export interface LocaleProviderProps { - localeText?: Partial; - children: React.ReactNode; -} - -/** - * @ignore - internal component. - */ -export function LocaleProvider({ localeText, children }: LocaleProviderProps) { - const mergedLocaleText = React.useMemo( - () => ({ ...DEFAULT_LOCALE_TEXT, ...localeText }), - [localeText], - ); - - return {children}; -} - -/** - * @ignore - internal hook. - */ - -export function useLocaleText() { - return React.useContext(LocaleContext); -} diff --git a/packages/toolpad-core/src/shared/locales/en.tsx b/packages/toolpad-core/src/shared/locales/en.tsx deleted file mode 100644 index 9717c8b3a3c..00000000000 --- a/packages/toolpad-core/src/shared/locales/en.tsx +++ /dev/null @@ -1,9 +0,0 @@ -const TOOLPAD_CORE_DEFAULT_LOCALE_TEXT = { - // Account - signInLabel: 'Sign In', - signOutLabel: 'Sign Out', - // Account Preview - iconButtonAriaLabel: 'Current User', -}; - -export default TOOLPAD_CORE_DEFAULT_LOCALE_TEXT; diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 192b20aac0a..86b1b509751 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -11,6 +11,7 @@ import { useNonNullableContext } from '@toolpad/utils/react'; import invariant from 'invariant'; import * as React from 'react'; import { DialogsContext } from './DialogsContext'; +import { useLocaleText } from '../AppProvider'; export interface OpenDialogOptions { /** @@ -192,14 +193,15 @@ export interface AlertDialogPayload extends AlertOptions { export interface AlertDialogProps extends DialogProps {} export function AlertDialog({ open, payload, onClose }: AlertDialogProps) { + const localeText = useLocaleText(); const okButtonProps = useDialogLoadingButton(() => onClose()); return ( onClose()}> - {payload.title ?? 'Alert'} + {payload.title ?? localeText?.alert} {payload.msg} - {payload.okText ?? 'Ok'} + {payload.okText ?? localeText?.ok} @@ -213,18 +215,19 @@ export interface ConfirmDialogPayload extends ConfirmOptions { export interface ConfirmDialogProps extends DialogProps {} export function ConfirmDialog({ open, payload, onClose }: ConfirmDialogProps) { + const localeText = useLocaleText(); const cancelButtonProps = useDialogLoadingButton(() => onClose(false)); const okButtonProps = useDialogLoadingButton(() => onClose(true)); return ( onClose(false)}> - {payload.title ?? 'Confirm'} + {payload.title ?? localeText?.confirm} {payload.msg} - {payload.cancelText ?? 'Cancel'} + {payload.cancelText ?? localeText?.cancel} - {payload.okText ?? 'Ok'} + {payload.okText ?? localeText?.ok} @@ -238,6 +241,7 @@ export interface PromptDialogPayload extends PromptOptions { export interface PromptDialogProps extends DialogProps {} export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { + const localeText = useLocaleText(); const [input, setInput] = React.useState(''); const cancelButtonProps = useDialogLoadingButton(() => onClose(null)); @@ -266,7 +270,7 @@ export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { }, }} > - {payload.title ?? 'Confirm'} + {payload.title ?? localeText?.confirm} {payload.msg} - {payload.cancelText ?? 'Cancel'} + {payload.cancelText ?? localeText?.cancel} - {payload.okText ?? 'Ok'} + {payload.okText ?? localeText?.ok} diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx index 8a7ab8cabb2..df9f976862d 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx @@ -19,8 +19,7 @@ import type { ShowNotification, ShowNotificationOptions, } from './useNotifications'; - -const closeText = 'Close'; +import { useLocaleText } from '../AppProvider'; export interface NotificationsProviderSlotProps { snackbar: SnackbarProps; @@ -45,6 +44,7 @@ interface NotificationProps { } function Notification({ notificationKey, open, message, options, badge }: NotificationProps) { + const localeText = useLocaleText(); const { close } = useNonNullableContext(NotificationsContext); const { severity, actionText, onAction, autoHideDuration } = options; @@ -68,8 +68,8 @@ function Notification({ notificationKey, open, message, options, badge }: Notifi ) : null} From c5212e1a66848efe287a0a3d20e6452fd7cad2bb Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Mon, 20 Jan 2025 15:46:38 +0530 Subject: [PATCH 2/7] feat: Add docs and a sample locale --- .../account/AccountCustomLocaleText.js | 24 ++-- .../account/AccountCustomLocaleText.tsx | 28 ++-- .../AccountCustomLocaleText.tsx.preview | 4 +- .../account/AccountCustomSlotProps.js | 56 ++++---- .../account/AccountCustomSlotProps.tsx | 60 ++++----- .../account/AccountCustomUserDetails.js | 22 ++-- .../account/AccountCustomUserDetails.tsx | 22 ++-- .../components/account/AccountDemoSignedIn.js | 14 +- .../account/AccountDemoSignedIn.tsx | 18 +-- .../account/AccountDemoSignedOut.js | 20 ++- .../account/AccountDemoSignedOut.tsx | 15 ++- .../account/AccountDemoSignedOut.tsx.preview | 12 +- .../account/AccountSlotsAccountSwitcher.js | 22 ++-- .../account/AccountSlotsAccountSwitcher.tsx | 26 ++-- .../core/components/account/account.md | 26 +++- .../sign-in-page/LocaleSignInPage.js | 36 +++++ .../sign-in-page/LocaleSignInPage.tsx | 42 ++++++ .../sign-in-page/LocaleSignInPage.tsx.preview | 9 ++ .../sign-in-page/ThemeSignInPage.tsx | 1 - .../components/sign-in-page/sign-in-page.md | 45 +++++++ .../core/introduction/base-concepts.md | 123 ++++++++++++++++++ packages/toolpad-core/src/Account/Account.tsx | 22 ++-- .../src/Account/AccountLocaleContext.tsx | 4 + .../src/Account/AccountPreview.tsx | 2 +- .../toolpad-core/src/Account/SignInButton.tsx | 7 +- .../src/Account/SignOutButton.tsx | 7 +- .../src/AppProvider/AppProvider.tsx | 23 ++-- .../src/AppProvider/LocalizationProvider.tsx | 30 +++-- .../src/SignInPage/SignInPage.tsx | 33 +++-- packages/toolpad-core/src/locales/hiIN.tsx | 5 +- packages/toolpad-core/src/locales/index.ts | 2 - .../src/useDialogs/useDialogs.tsx | 2 +- .../NotificationsProvider.tsx | 2 +- .../src/utils/getThemeLocaleText.ts | 1 + 34 files changed, 528 insertions(+), 237 deletions(-) create mode 100644 docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js create mode 100644 docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx create mode 100644 docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx.preview create mode 100644 packages/toolpad-core/src/Account/AccountLocaleContext.tsx delete mode 100644 packages/toolpad-core/src/locales/index.ts create mode 100644 packages/toolpad-core/src/utils/getThemeLocaleText.ts diff --git a/docs/data/toolpad/core/components/account/AccountCustomLocaleText.js b/docs/data/toolpad/core/components/account/AccountCustomLocaleText.js index 5ed35873c32..3074a0f94d2 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomLocaleText.js +++ b/docs/data/toolpad/core/components/account/AccountCustomLocaleText.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { AppProvider } from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; const demoSession = { @@ -31,17 +31,15 @@ export default function AccountCustomLocaleText() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx b/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx index c74db6789c7..9fd5e3f3783 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx +++ b/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx @@ -1,9 +1,5 @@ import * as React from 'react'; -import { - AuthenticationContext, - Session, - SessionContext, -} from '@toolpad/core/AppProvider'; +import { AppProvider, type Session } from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; const demoSession = { @@ -35,17 +31,15 @@ export default function AccountCustomLocaleText() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx.preview b/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx.preview index 882b98486be..1a812378926 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx.preview +++ b/docs/data/toolpad/core/components/account/AccountCustomLocaleText.tsx.preview @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/docs/data/toolpad/core/components/account/AccountCustomSlotProps.js b/docs/data/toolpad/core/components/account/AccountCustomSlotProps.js index 3995c7e1345..4c3544e3cec 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomSlotProps.js +++ b/docs/data/toolpad/core/components/account/AccountCustomSlotProps.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Logout from '@mui/icons-material/Logout'; import { Account } from '@toolpad/core/Account'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { AppProvider } from '@toolpad/core/AppProvider'; const demoSession = { user: { @@ -32,36 +32,34 @@ export default function AccountCustomSlotProps() { }, []); return ( - - - {/* preview-start */} - , - }, - preview: { - variant: 'expanded', - slotProps: { - avatarIconButton: { - sx: { - width: 'fit-content', - margin: 'auto', - }, - }, - avatar: { - variant: 'rounded', + + {/* preview-start */} + , + }, + preview: { + variant: 'expanded', + slotProps: { + avatarIconButton: { + sx: { + width: 'fit-content', + margin: 'auto', }, }, + avatar: { + variant: 'rounded', + }, }, - }} - /> - {/* preview-end */} - - + }, + }} + /> + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountCustomSlotProps.tsx b/docs/data/toolpad/core/components/account/AccountCustomSlotProps.tsx index fcfa8bd028c..abfcf8085fe 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomSlotProps.tsx +++ b/docs/data/toolpad/core/components/account/AccountCustomSlotProps.tsx @@ -1,11 +1,7 @@ import * as React from 'react'; import Logout from '@mui/icons-material/Logout'; import { Account } from '@toolpad/core/Account'; -import { - AuthenticationContext, - SessionContext, - Session, -} from '@toolpad/core/AppProvider'; +import { AppProvider, Session } from '@toolpad/core/AppProvider'; const demoSession = { user: { @@ -36,36 +32,34 @@ export default function AccountCustomSlotProps() { }, []); return ( - - - {/* preview-start */} - , - }, - preview: { - variant: 'expanded', - slotProps: { - avatarIconButton: { - sx: { - width: 'fit-content', - margin: 'auto', - }, - }, - avatar: { - variant: 'rounded', + + {/* preview-start */} + , + }, + preview: { + variant: 'expanded', + slotProps: { + avatarIconButton: { + sx: { + width: 'fit-content', + margin: 'auto', }, }, + avatar: { + variant: 'rounded', + }, }, - }} - /> - {/* preview-end */} - - + }, + }} + /> + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountCustomUserDetails.js b/docs/data/toolpad/core/components/account/AccountCustomUserDetails.js index f9ebd5d6e1a..b43327cd9d3 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomUserDetails.js +++ b/docs/data/toolpad/core/components/account/AccountCustomUserDetails.js @@ -1,6 +1,6 @@ import * as React from 'react'; import { Account } from '@toolpad/core/Account'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { AppProvider } from '@toolpad/core/AppProvider'; import { UserOrg } from '../UserOrg'; const demoSession = { @@ -30,16 +30,14 @@ export default function AccountCustomUserDetails() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountCustomUserDetails.tsx b/docs/data/toolpad/core/components/account/AccountCustomUserDetails.tsx index 11aecc9f557..b2fc8ee9705 100644 --- a/docs/data/toolpad/core/components/account/AccountCustomUserDetails.tsx +++ b/docs/data/toolpad/core/components/account/AccountCustomUserDetails.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { Account } from '@toolpad/core/Account'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { AppProvider } from '@toolpad/core/AppProvider'; import { UserOrg, CustomSession } from '../UserOrg'; const demoSession: CustomSession = { @@ -32,16 +32,14 @@ export default function AccountCustomUserDetails() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountDemoSignedIn.js b/docs/data/toolpad/core/components/account/AccountDemoSignedIn.js index 5f8ea177353..d9602d020d6 100644 --- a/docs/data/toolpad/core/components/account/AccountDemoSignedIn.js +++ b/docs/data/toolpad/core/components/account/AccountDemoSignedIn.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { AppProvider } from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; const demoSession = { @@ -24,12 +24,10 @@ export default function AccountDemoSignedIn() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountDemoSignedIn.tsx b/docs/data/toolpad/core/components/account/AccountDemoSignedIn.tsx index 718b4ed60fa..de5de86d2b5 100644 --- a/docs/data/toolpad/core/components/account/AccountDemoSignedIn.tsx +++ b/docs/data/toolpad/core/components/account/AccountDemoSignedIn.tsx @@ -1,9 +1,5 @@ import * as React from 'react'; -import { - AuthenticationContext, - SessionContext, - type Session, -} from '@toolpad/core/AppProvider'; +import { AppProvider, type Session } from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; const demoSession = { @@ -28,12 +24,10 @@ export default function AccountDemoSignedIn() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountDemoSignedOut.js b/docs/data/toolpad/core/components/account/AccountDemoSignedOut.js index c63ddabcf9a..673420426a4 100644 --- a/docs/data/toolpad/core/components/account/AccountDemoSignedOut.js +++ b/docs/data/toolpad/core/components/account/AccountDemoSignedOut.js @@ -1,5 +1,9 @@ import * as React from 'react'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { + AuthenticationContext, + LocalizationProvider, + SessionContext, +} from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; const demoSession = { @@ -24,10 +28,14 @@ export default function AccountDemoSignedOut() { }, []); return ( - - - - - + // preview-start + + + + + + + + // preview-end ); } diff --git a/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx b/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx index 1ca57c63430..a0a8d01e75e 100644 --- a/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx +++ b/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { AuthenticationContext, + LocalizationProvider, SessionContext, type Session, } from '@toolpad/core/AppProvider'; @@ -28,10 +29,14 @@ export default function AccountDemoSignedOut() { }, []); return ( - - - - - + // preview-start + + + + + + + + // preview-end ); } diff --git a/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx.preview b/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx.preview index b0489ce20ca..f3af4f1a296 100644 --- a/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx.preview +++ b/docs/data/toolpad/core/components/account/AccountDemoSignedOut.tsx.preview @@ -1,5 +1,7 @@ - - - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.js b/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.js index c938fa78e17..b0b354e8e8e 100644 --- a/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.js +++ b/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { AuthenticationContext, SessionContext } from '@toolpad/core/AppProvider'; +import { AppProvider } from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; import CustomMenu from './CustomMenu'; @@ -25,16 +25,14 @@ export default function AccountSlotsAccountSwitcher() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.tsx b/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.tsx index 7e89f9663a3..2558e0c1d22 100644 --- a/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.tsx +++ b/docs/data/toolpad/core/components/account/AccountSlotsAccountSwitcher.tsx @@ -1,9 +1,5 @@ import * as React from 'react'; -import { - AuthenticationContext, - SessionContext, - type Session, -} from '@toolpad/core/AppProvider'; +import { AppProvider, type Session } from '@toolpad/core/AppProvider'; import { Account } from '@toolpad/core/Account'; import CustomMenu from './CustomMenu'; @@ -29,16 +25,14 @@ export default function AccountSlotsAccountSwitcher() { }, []); return ( - - - {/* preview-start */} - - {/* preview-end */} - - + + {/* preview-start */} + + {/* preview-end */} + ); } diff --git a/docs/data/toolpad/core/components/account/account.md b/docs/data/toolpad/core/components/account/account.md index c506aca73b7..6a4bb5acd95 100644 --- a/docs/data/toolpad/core/components/account/account.md +++ b/docs/data/toolpad/core/components/account/account.md @@ -12,7 +12,29 @@ components: Account, AccountPreview, AccountPopoverHeader, AccountPopoverFooter, If this is your first time using Toolpad Core, it's recommended to read about the [basic concepts](/toolpad/core/introduction/base-concepts/) first. ::: -The `Account` component is a quick and easy way to display an account management menu for authenticated users. It is deeply integrated with the `SignInPage` and `DashboardLayout` components, meaning that it automatically appears in the top navigation bar inside `DashboardLayout` once your users have signed in through the `SignInPage`. +The `Account` component is a quick and easy way to display an account management menu for authenticated users. + +## Basic Usage + +`Account` is deeply integrated with the `SignInPage` and `DashboardLayout` components, meaning that it automatically appears in the top navigation bar inside `DashboardLayout` once your users have signed in through the `SignInPage`. + +:::warning +If you are using it standalone without the `AppProvider`, wrap it with `LocalizationProvider` at minimum to get proper labels: + +```tsx +import { LocalizationProvider } from '@toolpad/core/AppProvider'; +import { Account } from '@toolpad/core/Account'; + +export default function App() { + return ( + + + + ); +} +``` + +::: ## States @@ -26,7 +48,7 @@ If a `session` object is present, the component is rendered as a dropdown contai When signed out, the component renders as an inline sign in button within the dashboard layout. -{{"demo": "AccountDemoSignedOut.js", "bg": "outlined", "defaultCodeOpen": false }} +{{"demo": "AccountDemoSignedOut.js", "bg": "outlined", "defaultCodeOpen": false}} ## Customization diff --git a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js new file mode 100644 index 00000000000..0e5ff86e899 --- /dev/null +++ b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js @@ -0,0 +1,36 @@ +import * as React from 'react'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { SignInPage } from '@toolpad/core/SignInPage'; +import hiIN from '@toolpad/core/locales/hiIN'; + +const providers = [ + { id: 'github', name: 'GitHub' }, + { id: 'google', name: 'Google' }, + { id: 'credentials', name: 'Email and Password' }, +]; + +const signIn = async (provider) => { + const promise = new Promise((resolve) => { + setTimeout(() => { + console.log(`Sign in with ${provider.id}`); + resolve({ error: 'This is a mock error message.' }); + }, 500); + }); + return promise; +}; + +export default function LocaleSignInPage() { + return ( + // preview-start + + + + // preview-end + ); +} diff --git a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx new file mode 100644 index 00000000000..cc64d7cc187 --- /dev/null +++ b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import { AppProvider } from '@toolpad/core/AppProvider'; +import { + SignInPage, + type AuthProvider, + type AuthResponse, +} from '@toolpad/core/SignInPage'; +import hiIN from '@toolpad/core/locales/hiIN'; + +const providers = [ + { id: 'github', name: 'GitHub' }, + { id: 'google', name: 'Google' }, + { id: 'credentials', name: 'Email and Password' }, +]; + +const signIn: (provider: AuthProvider) => void | Promise = async ( + provider, +) => { + const promise = new Promise((resolve) => { + setTimeout(() => { + console.log(`Sign in with ${provider.id}`); + resolve({ error: 'This is a mock error message.' }); + }, 500); + }); + return promise; +}; + +export default function LocaleSignInPage() { + return ( + // preview-start + + + + // preview-end + ); +} diff --git a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx.preview new file mode 100644 index 00000000000..49d7fc1ee6f --- /dev/null +++ b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx.preview @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx index 7e826fe0c49..d9ce9dc1702 100644 --- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx +++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx @@ -6,7 +6,6 @@ import { type AuthResponse, } from '@toolpad/core/SignInPage'; import { createTheme } from '@mui/material/styles'; -import { hiIN } from '@toolpad/core/locales'; import { useColorSchemeShim } from 'docs/src/modules/components/ThemeContext'; import { getDesignTokens, inputsCustomizations } from './customTheme'; diff --git a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md index 9abf4d7bef6..a37290b7e17 100644 --- a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md +++ b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md @@ -14,6 +14,45 @@ If this is your first time using Toolpad Core, it's recommended to read about th The `SignInPage` component is a quick way to generate a ready-to-use authentication page with multiple OAuth providers, or a credentials form. +## Basic Usage + +```tsx +import { AppProvider } from '@toolpad/core/AppProvider'; +import { SignInPage } from '@toolpad/core/SignInPage'; + +export default function App() { + return ( + + { + // Your sign in logic + }} + /> + + ); +} +``` + +:::warning + +If you're using the component standalone without `AppProvider`, wrap it with `LocalizationProvider` at minimum to get proper labels: + +```tsx +import { LocalizationProvider } from '@toolpad/core/AppProvider'; +import { SignInPage } from '@toolpad/core/SignInPage'; + +export default function App() { + return ( + + + + ); +} +``` + +::: + ## OAuth The `SignInPage` component can be set up with an OAuth provider by passing in a list of providers in the `providers` prop, along with a `signIn` function that accepts the `provider` as a parameter. @@ -264,6 +303,12 @@ You can use the `slotProps` prop to pass props to the underlying components of e {{"demo": "SlotPropsSignIn.js", "iframe": true, "height": 600 }} +### Localization + +Beyond the [global localization options](/toolpad/core/introduction/base-concepts/#localization) possible, you can customize the labels of the `SignInPage` using the `localeText` prop: + +{{"demo": "LocaleSignInPage.js", "iframe": true, "height": 700 }} + ### 🚧 Layouts The `SignInPage` component has versions with different layouts for authentication - one column, two column and others such. The APIs of these components are identical. This is in progress. diff --git a/docs/data/toolpad/core/introduction/base-concepts.md b/docs/data/toolpad/core/introduction/base-concepts.md index ae008ad48dc..be9a2b0f4de 100644 --- a/docs/data/toolpad/core/introduction/base-concepts.md +++ b/docs/data/toolpad/core/introduction/base-concepts.md @@ -105,3 +105,126 @@ In this example: - The `slots` prop allows you to replace entire parts of the component. - The `slotProps` prop lets you pass additional props to specific slots. + +## Localization + +Toolpad components support translations between languages. You can modify text and translations inside Toolpad components in several ways. + +The default locale is English (United States). To use other locales, follow the instructions below. + +### Set translations globally + +#### Using the theme + +To translate all your Toolpad components, you can provide translations through the theme: + +```tsx +import { createTheme, ThemeProvider } from '@mui/material/styles'; +import hiIN from '@toolpad/core/locales/hiIN'; + +const theme = createTheme({ + { + palette: { + primary: { main: '#1976d2' }, + }, + }, + hiIN, +}); + + // ... + {children}; + +``` + +#### Using the `localeText` prop + +If you want to pass language translations without using `createTheme`, you can directly provide them through the `localeText` prop on the `AppProvider`: + +```tsx +import { AppProvider } from '@toolpad/core/AppProvider'; +import hiIN from '@toolpad/core/locales/hiIN'; + +function App({ children }) { + return ( + + {children} + + ); +} +``` + +If you are not using the `AppProvider` in your app, you can also use the `LocalizationProvider` only: + +```tsx +import { LocalizationProvider } from '@toolpad/core/AppProvider'; +import hiIN from '@toolpad/core/locales/hiIN'; + +function App({ children }) { + return ( + + {children} + + ); +} +``` + +### Set translations locally + +You can also customize the translations of a single component. + +If you want to customize some translations on specific component, you can use the `localeText` prop exposed by all components. + +```tsx + +``` + +### Priority order + +The localization system follows a specific priority order when applying translations: + +1. `localeText` prop provided directly to a specific component (highest priority) +2. `localeText` prop provided directly to `AppProvider` +3. Translations provided through the theme +4. Default English translations (lowest priority) + +:::info +If you pass a localization through the `AppProvider` or the theme, and you provide translation keys through the `localeText` prop of a component at the same time, then the latter keys will be overridden: + +  + +```tsx + + + +``` + +  + +This will produce the following result: + +- `SignInPage` title with text **Sign In** taken from the `AppProvider` `localeText` prop +- `Account` with title **Compte** overridden by the `Account` `localeText` prop + +::: + +### Access localization keys + +You can access your localization keys in custom components using the `useLocaleText()` hook. + +```tsx +import { useLocaleText } from '@toolpad/core/AppProvider'; + +function CustomMenu() { + // ... + const localeText = useLocaleText(); + // ... +} +``` diff --git a/packages/toolpad-core/src/Account/Account.tsx b/packages/toolpad-core/src/Account/Account.tsx index 5dc602ab8f5..25a4dae4ec0 100644 --- a/packages/toolpad-core/src/Account/Account.tsx +++ b/packages/toolpad-core/src/Account/Account.tsx @@ -10,7 +10,8 @@ import { AccountPreview, AccountPreviewProps } from './AccountPreview'; import { AccountPopoverHeader } from './AccountPopoverHeader'; import { AccountPopoverFooter } from './AccountPopoverFooter'; import { SessionContext, AuthenticationContext } from '../AppProvider/AppProvider'; -import { useLocaleText, type LocaleText } from '../AppProvider'; +import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvider'; +import { AccountLocaleContext } from './AccountLocaleContext'; export interface AccountSlots { /** @@ -58,11 +59,9 @@ export interface AccountProps { /** * The labels for the account component. */ - localeText?: LocaleText; + localeText?: Partial; } -export const AccountLocaleContext = React.createContext | null>(null); - /** * * Demos: @@ -78,7 +77,10 @@ export const AccountLocaleContext = React.createContext | nu function Account(props: AccountProps) { const { localeText: propsLocaleText } = props; const globalLocaleText = useLocaleText(); - const localeText = { ...globalLocaleText, ...propsLocaleText }; + const localeText = React.useMemo( + () => ({ ...globalLocaleText, ...propsLocaleText }), + [globalLocaleText, propsLocaleText], + ); const { slots, slotProps } = props; const [anchorEl, setAnchorEl] = React.useState(null); const session = React.useContext(SessionContext); @@ -179,7 +181,11 @@ function Account(props: AccountProps) { ); } - return {accountContent}; + return ( + + {accountContent} + + ); } Account.propTypes /* remove-proptypes */ = { @@ -191,9 +197,9 @@ Account.propTypes /* remove-proptypes */ = { * The labels for the account component. */ localeText: PropTypes.shape({ + accountSignInLabel: PropTypes.string, + accountSignOutLabel: PropTypes.string, iconButtonAriaLabel: PropTypes.string, - signInLabel: PropTypes.string, - signOutLabel: PropTypes.string, }), /** * The props used for each slot inside. diff --git a/packages/toolpad-core/src/Account/AccountLocaleContext.tsx b/packages/toolpad-core/src/Account/AccountLocaleContext.tsx new file mode 100644 index 00000000000..19c591b046c --- /dev/null +++ b/packages/toolpad-core/src/Account/AccountLocaleContext.tsx @@ -0,0 +1,4 @@ +import * as React from 'react'; +import type { LocaleText } from '../AppProvider/LocalizationProvider'; + +export const AccountLocaleContext = React.createContext | null>(null); diff --git a/packages/toolpad-core/src/Account/AccountPreview.tsx b/packages/toolpad-core/src/Account/AccountPreview.tsx index 034cad6c901..7b3965ff8a7 100644 --- a/packages/toolpad-core/src/Account/AccountPreview.tsx +++ b/packages/toolpad-core/src/Account/AccountPreview.tsx @@ -8,7 +8,7 @@ import Stack from '@mui/material/Stack'; import IconButton, { IconButtonProps } from '@mui/material/IconButton'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { SessionContext } from '../AppProvider'; -import { AccountLocaleContext } from '../Account'; +import { AccountLocaleContext } from './AccountLocaleContext'; export type AccountPreviewVariant = 'condensed' | 'expanded'; diff --git a/packages/toolpad-core/src/Account/SignInButton.tsx b/packages/toolpad-core/src/Account/SignInButton.tsx index b39223a7830..63bdc156bb2 100644 --- a/packages/toolpad-core/src/Account/SignInButton.tsx +++ b/packages/toolpad-core/src/Account/SignInButton.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Button, { ButtonProps } from '@mui/material/Button'; -import { AuthenticationContext, useLocaleText } from '../AppProvider'; +import { AuthenticationContext } from '../AppProvider'; +import { AccountLocaleContext } from './AccountLocaleContext'; /** * @@ -15,7 +16,7 @@ import { AuthenticationContext, useLocaleText } from '../AppProvider'; */ function SignInButton(props: ButtonProps) { const authentication = React.useContext(AuthenticationContext); - const localeText = useLocaleText(); + const accountLocaleText = React.useContext(AccountLocaleContext); return ( ); } diff --git a/packages/toolpad-core/src/Account/SignOutButton.tsx b/packages/toolpad-core/src/Account/SignOutButton.tsx index 657fd842a75..d99d16aaefa 100644 --- a/packages/toolpad-core/src/Account/SignOutButton.tsx +++ b/packages/toolpad-core/src/Account/SignOutButton.tsx @@ -2,7 +2,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Button, { ButtonProps } from '@mui/material/Button'; import LogoutIcon from '@mui/icons-material/Logout'; -import { AuthenticationContext, useLocaleText } from '../AppProvider'; +import { AuthenticationContext } from '../AppProvider'; +import { AccountLocaleContext } from './AccountLocaleContext'; export type SignOutButtonProps = ButtonProps; @@ -18,7 +19,7 @@ export type SignOutButtonProps = ButtonProps; */ function SignOutButton(props: SignOutButtonProps) { const authentication = React.useContext(AuthenticationContext); - const localeText = useLocaleText(); + const accountLocaleText = React.useContext(AccountLocaleContext); return ( ); } diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index a587d8563a6..8409c69282b 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -12,7 +12,6 @@ import { } from '../shared/context'; import { AppThemeProvider } from './AppThemeProvider'; import { LocalizationProvider, type LocaleText } from './LocalizationProvider'; -import DEFAULT_LOCALE_TEXT from '../locales/en'; export interface NavigateOptions { history?: 'auto' | 'push' | 'replace'; @@ -153,7 +152,7 @@ function AppProvider(props: AppProviderProps) { theme = createTheme(), branding = null, navigation = [], - localeText = DEFAULT_LOCALE_TEXT.components.MuiLocalizationProvider.defaultProps.localeText, + localeText, router = null, authentication = null, session = null, @@ -166,17 +165,17 @@ function AppProvider(props: AppProviderProps) { - - - - - + + + + + {children} - - - - - + + + + + diff --git a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx index e0a0af5cb86..c2fdd77e2d7 100644 --- a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; -import { useThemeProps } from '@mui/material/styles'; +import { useTheme } from '@mui/material/styles'; +import DEFAULT_LOCALE from '../locales/en'; export type LocaleText = { // Account @@ -13,6 +14,9 @@ export type LocaleText = { // SignInPage signInTitle: string; signInSubtitle: string; + oauthSignInTitle: string; + passkeySignInTitle: string; + magicLinkSignInTitle: string; signInRememberMe: string; // Error messages @@ -82,20 +86,24 @@ export const LocalizationContext = React.createContext>({}); export const LocalizationProvider = function LocalizationProvider( props: LocalizationProviderProps, ) { - const { localeText: propsLocaleText, ...otherInProps } = props; + const { localeText: propsLocaleText, children } = props; - const themeProps: LocalizationProviderProps = useThemeProps({ - // We don't want to pass the `localeText` prop to the theme, that way it will always return the theme value, - // We will then merge this theme value with our value manually - props: otherInProps, - name: 'MuiLocalizationProvider', - }); + const theme = useTheme(); + // @ts-ignore + const themeLocaleText = theme?.components?.MuiLocalizationProvider?.defaultProps?.localeText; - const { children, localeText: themeLocaleText } = themeProps; + const defaultLocaleText = + DEFAULT_LOCALE.components.MuiLocalizationProvider.defaultProps.localeText; + + /* The order of overrides is: + * 1. The `localeText` prop of the `AppProvider` supersedes + * 2. The localeText provided as an argument to the `createTheme` function, which supersedes + * 3. The default locale text + */ const localeText = React.useMemo( - () => ({ ...themeLocaleText, ...propsLocaleText }), - [themeLocaleText, propsLocaleText], + () => ({ ...defaultLocaleText, ...themeLocaleText, ...propsLocaleText }), + [defaultLocaleText, themeLocaleText, propsLocaleText], ); return {children}; diff --git a/packages/toolpad-core/src/SignInPage/SignInPage.tsx b/packages/toolpad-core/src/SignInPage/SignInPage.tsx index 58f73ae8eb7..9f88b84ba45 100644 --- a/packages/toolpad-core/src/SignInPage/SignInPage.tsx +++ b/packages/toolpad-core/src/SignInPage/SignInPage.tsx @@ -37,7 +37,7 @@ import KeycloakIcon from './icons/Keycloak'; import OktaIcon from './icons/Okta'; import FusionAuthIcon from './icons/FusionAuth'; import { BrandingContext, RouterContext } from '../shared/context'; -import { useLocaleText } from '../AppProvider'; +import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvider'; const mergeSlotSx = (defaultSx: SxProps, slotProps?: { sx?: SxProps }) => { if (Array.isArray(slotProps?.sx)) { @@ -261,6 +261,10 @@ export interface SignInPageProps { * The prop used to customize the styles on the `SignInPage` container */ sx?: SxProps; + /** + * The labels for the account component. + */ + localeText?: Partial; } /** @@ -274,11 +278,13 @@ export interface SignInPageProps { * - [SignInPage API](https://mui.com/toolpad/core/api/sign-in-page) */ function SignInPage(props: SignInPageProps) { - const { providers, signIn, slots, slotProps, sx } = props; + const { providers, signIn, slots, slotProps, sx, localeText: propsLocaleText } = props; const theme = useTheme(); const branding = React.useContext(BrandingContext); const router = React.useContext(RouterContext); - const localeText = useLocaleText(); + const globalLocaleText = useLocaleText(); + const localeText = { ...globalLocaleText, ...propsLocaleText }; + const passkeyProvider = providers?.find((provider) => provider.id === 'passkey'); const credentialsProvider = providers?.find((provider) => provider.id === 'credentials'); const emailProvider = providers?.find((provider) => provider.id === 'nodemailer'); @@ -395,7 +401,8 @@ function SignInPage(props: SignInPageProps) { }} > - {localeText.signInTitle} {localeText.with?.toLocaleLowerCase()}{' '} + {localeText.oauthSignInTitle || + `${localeText.signInTitle} ${localeText.with}`}{' '} {provider.name} @@ -406,7 +413,9 @@ function SignInPage(props: SignInPageProps) { {passkeyProvider ? ( - {singleProvider ? null : or} + {singleProvider ? null : ( + {localeText.or} + )} {error && selectedProviderId === 'passkey' ? ( {error} @@ -465,7 +474,8 @@ function SignInPage(props: SignInPageProps) { }} {...slotProps?.submitButton} > - {localeText.signInTitle} {localeText.with?.toLocaleLowerCase()}{' '} + {localeText.passkeySignInTitle || + `${localeText.signInTitle} ${localeText.with}`} {passkeyProvider.name || localeText.passkey} )} @@ -475,7 +485,9 @@ function SignInPage(props: SignInPageProps) { {emailProvider ? ( - {singleProvider ? null : or} + {singleProvider ? null : ( + {localeText.or} + )} {error && selectedProviderId === 'nodemailer' ? ( {error} @@ -540,7 +552,8 @@ function SignInPage(props: SignInPageProps) { }} {...slotProps?.submitButton} > - {localeText.signInTitle} {localeText.with?.toLocaleLowerCase()}{' '} + {localeText.magicLinkSignInTitle || + `${localeText.signInTitle} ${localeText.with}`}{' '} {localeText.email} )} @@ -550,7 +563,9 @@ function SignInPage(props: SignInPageProps) { {credentialsProvider ? ( - {singleProvider ? null : or} + {singleProvider ? null : ( + {localeText.or} + )} {error && selectedProviderId === 'credentials' ? ( {error} diff --git a/packages/toolpad-core/src/locales/hiIN.tsx b/packages/toolpad-core/src/locales/hiIN.tsx index 269a5174d2b..7637ea93433 100644 --- a/packages/toolpad-core/src/locales/hiIN.tsx +++ b/packages/toolpad-core/src/locales/hiIN.tsx @@ -12,6 +12,9 @@ const hiINLabels: Partial = { // SignInPage signInTitle: 'साइन इन करें', + oauthSignInTitle: 'साइन इन विकल्प', + passkeySignInTitle: 'साइन इन विकल्प', + magicLinkSignInTitle: 'साइन इन विकल्प', signInSubtitle: 'स्वागत है उपयोगकर्ता, कृपया जारी रखने के लिए साइन इन करें', signInRememberMe: 'मुझे याद रखें', @@ -39,4 +42,4 @@ const hiINLabels: Partial = { info: 'जानकारी', }; -export const hiIN = getLocalization(hiINLabels); +export default getLocalization(hiINLabels); diff --git a/packages/toolpad-core/src/locales/index.ts b/packages/toolpad-core/src/locales/index.ts deleted file mode 100644 index ddf0aaeb937..00000000000 --- a/packages/toolpad-core/src/locales/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './en'; -export * from './hiIN'; diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 86b1b509751..ed55a6ddcfb 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -11,7 +11,7 @@ import { useNonNullableContext } from '@toolpad/utils/react'; import invariant from 'invariant'; import * as React from 'react'; import { DialogsContext } from './DialogsContext'; -import { useLocaleText } from '../AppProvider'; +import { useLocaleText } from '../AppProvider/LocalizationProvider'; export interface OpenDialogOptions { /** diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx index df9f976862d..75a11367cfe 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx @@ -19,7 +19,7 @@ import type { ShowNotification, ShowNotificationOptions, } from './useNotifications'; -import { useLocaleText } from '../AppProvider'; +import { useLocaleText } from '../AppProvider/LocalizationProvider'; export interface NotificationsProviderSlotProps { snackbar: SnackbarProps; diff --git a/packages/toolpad-core/src/utils/getThemeLocaleText.ts b/packages/toolpad-core/src/utils/getThemeLocaleText.ts new file mode 100644 index 00000000000..0519ecba6ea --- /dev/null +++ b/packages/toolpad-core/src/utils/getThemeLocaleText.ts @@ -0,0 +1 @@ + \ No newline at end of file From 7678f8c0480503b14f72c0d1298805d33efa656e Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Mon, 20 Jan 2025 16:00:22 +0530 Subject: [PATCH 3/7] fix: eslint, prettier --- packages/toolpad-core/src/index.ts | 2 -- packages/toolpad-core/src/utils/getThemeLocaleText.ts | 1 - pnpm-lock.yaml | 8 ++++---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/toolpad-core/src/index.ts b/packages/toolpad-core/src/index.ts index 0769af5a05e..123c479d6c3 100644 --- a/packages/toolpad-core/src/index.ts +++ b/packages/toolpad-core/src/index.ts @@ -21,5 +21,3 @@ export * from './useSession'; export * from './useSessionStorageState'; export * from './persistence/codec'; - -export * from './locales'; diff --git a/packages/toolpad-core/src/utils/getThemeLocaleText.ts b/packages/toolpad-core/src/utils/getThemeLocaleText.ts index 0519ecba6ea..e69de29bb2d 100644 --- a/packages/toolpad-core/src/utils/getThemeLocaleText.ts +++ b/packages/toolpad-core/src/utils/getThemeLocaleText.ts @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36d95d798b6..8e1959acad5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -201,7 +201,7 @@ importers: version: 7.37.3(eslint@8.57.1) eslint-plugin-react-compiler: specifier: latest - version: 19.0.0-beta-e552027-20250112(eslint@8.57.1) + version: 19.0.0-beta-decd7b8-20250118(eslint@8.57.1) eslint-plugin-react-hooks: specifier: 5.1.0 version: 5.1.0(eslint@8.57.1) @@ -6090,8 +6090,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-react-compiler@19.0.0-beta-e552027-20250112: - resolution: {integrity: sha512-VjkIXHouCYyJHgk5HmZ1LH+fAK5CX+ULRX9iNYtwYJ+ljbivFhIT+JJyxNT/USQpCeS2Dt5ahjFeeMv0RRwTww==} + eslint-plugin-react-compiler@19.0.0-beta-decd7b8-20250118: + resolution: {integrity: sha512-qfs+Xo+VcYPbbVLI2tCP+KBGwm0oksAhjFJO1GwOvP+4b18LLcPZu7xopRhUTOaNd+nn1vOp9EQLZC1wMNxSrQ==} engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} peerDependencies: eslint: '>=7' @@ -16276,7 +16276,7 @@ snapshots: globals: 13.24.0 rambda: 7.5.0 - eslint-plugin-react-compiler@19.0.0-beta-e552027-20250112(eslint@8.57.1): + eslint-plugin-react-compiler@19.0.0-beta-decd7b8-20250118(eslint@8.57.1): dependencies: '@babel/core': 7.26.0 '@babel/parser': 7.26.2 From 784c9921574fb0aa67b981e68ce1b6b0e887a1c7 Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Mon, 20 Jan 2025 19:20:57 +0530 Subject: [PATCH 4/7] fix: CI --- .../core/components/account/account.md | 26 +---- .../components/sign-in-page/sign-in-page.md | 21 +--- .../core/introduction/base-concepts.md | 12 +- docs/data/toolpad/core/pagesApi.js | 1 + docs/pages/toolpad/core/api/account.json | 2 +- docs/pages/toolpad/core/api/app-provider.json | 6 + .../toolpad/core/api/dashboard-layout.json | 2 +- .../toolpad/core/api/localization-provider.js | 23 ++++ .../core/api/localization-provider.json | 18 +++ docs/pages/toolpad/core/api/sign-in-page.json | 6 + .../api-docs/app-provider/app-provider.json | 1 + .../localization-provider.json | 5 + .../api-docs/sign-in-page/sign-in-page.json | 1 + packages/toolpad-core/src/Account/Account.tsx | 27 ++++- .../src/Account/AccountLocaleContext.tsx | 3 + .../src/Account/AccountPreview.tsx | 7 +- .../toolpad-core/src/Account/SignInButton.tsx | 5 +- .../src/Account/SignOutButton.tsx | 5 +- .../src/AppProvider/AppProvider.tsx | 32 ++++++ .../src/AppProvider/LocalizationProvider.tsx | 104 +++++++++++------- .../src/DashboardLayout/DashboardLayout.tsx | 9 +- .../src/SignInPage/SignInPage.tsx | 44 +++++++- packages/toolpad-core/src/locales/en.tsx | 16 +-- packages/toolpad-core/src/locales/hiIN.tsx | 14 +-- .../src/useDialogs/useDialogs.tsx | 41 +++++-- .../NotificationsProvider.tsx | 13 ++- 26 files changed, 308 insertions(+), 136 deletions(-) create mode 100644 docs/pages/toolpad/core/api/localization-provider.js create mode 100644 docs/pages/toolpad/core/api/localization-provider.json create mode 100644 docs/translations/api-docs/localization-provider/localization-provider.json diff --git a/docs/data/toolpad/core/components/account/account.md b/docs/data/toolpad/core/components/account/account.md index 6a4bb5acd95..cfc30537fbd 100644 --- a/docs/data/toolpad/core/components/account/account.md +++ b/docs/data/toolpad/core/components/account/account.md @@ -12,29 +12,7 @@ components: Account, AccountPreview, AccountPopoverHeader, AccountPopoverFooter, If this is your first time using Toolpad Core, it's recommended to read about the [basic concepts](/toolpad/core/introduction/base-concepts/) first. ::: -The `Account` component is a quick and easy way to display an account management menu for authenticated users. - -## Basic Usage - -`Account` is deeply integrated with the `SignInPage` and `DashboardLayout` components, meaning that it automatically appears in the top navigation bar inside `DashboardLayout` once your users have signed in through the `SignInPage`. - -:::warning -If you are using it standalone without the `AppProvider`, wrap it with `LocalizationProvider` at minimum to get proper labels: - -```tsx -import { LocalizationProvider } from '@toolpad/core/AppProvider'; -import { Account } from '@toolpad/core/Account'; - -export default function App() { - return ( - - - - ); -} -``` - -::: +The `Account` component is a quick and easy way to display an account management menu for authenticated users. It is deeply integrated with the `SignInPage` and `DashboardLayout` components, meaning that it automatically appears in the top navigation bar inside `DashboardLayout` once your users have signed in through the `SignInPage`. ## States @@ -83,7 +61,7 @@ You can build advanced menus – such as a tenant switcher – by passing in a c {{"demo": "AccountSlotsAccountSwitcher.js", "bg": "outlined"}} -### Labels +### Localization You can pass in custom labels – including of different languages – using the `localeText` prop. diff --git a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md index a37290b7e17..32fffc5edea 100644 --- a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md +++ b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md @@ -1,7 +1,7 @@ --- productId: toolpad-core title: Sign-in Page -components: SignInPage, Account, NotificationsProvider +components: SignInPage, Account, NotificationsProvider, LocalizationProvider --- # Sign-in Page @@ -34,25 +34,6 @@ export default function App() { } ``` -:::warning - -If you're using the component standalone without `AppProvider`, wrap it with `LocalizationProvider` at minimum to get proper labels: - -```tsx -import { LocalizationProvider } from '@toolpad/core/AppProvider'; -import { SignInPage } from '@toolpad/core/SignInPage'; - -export default function App() { - return ( - - - - ); -} -``` - -::: - ## OAuth The `SignInPage` component can be set up with an OAuth provider by passing in a list of providers in the `providers` prop, along with a `signIn` function that accepts the `provider` as a parameter. diff --git a/docs/data/toolpad/core/introduction/base-concepts.md b/docs/data/toolpad/core/introduction/base-concepts.md index be9a2b0f4de..72602c3c2ba 100644 --- a/docs/data/toolpad/core/introduction/base-concepts.md +++ b/docs/data/toolpad/core/introduction/base-concepts.md @@ -155,7 +155,7 @@ function App({ children }) { } ``` -If you are not using the `AppProvider` in your app, you can also use the `LocalizationProvider` only: +If you are not using the `AppProvider` in your app, you can just use the `LocalizationProvider`: ```tsx import { LocalizationProvider } from '@toolpad/core/AppProvider'; @@ -174,9 +174,7 @@ function App({ children }) { ### Set translations locally -You can also customize the translations of a single component. - -If you want to customize some translations on specific component, you can use the `localeText` prop exposed by all components. +If you want to customize some translations on a specific component, you can use the `localeText` prop exposed by all components. ```tsx @@ -192,15 +190,15 @@ The localization system follows a specific priority order when applying translat 4. Default English translations (lowest priority) :::info -If you pass a localization through the `AppProvider` or the theme, and you provide translation keys through the `localeText` prop of a component at the same time, then the latter keys will be overridden: +If you pass a locale text through the `AppProvider` or the theme, and you provide translation keys through the `localeText` prop of a component at the same time, then the latter will override the former to the extent of the keys which it has available:   ```tsx - + diff --git a/docs/data/toolpad/core/pagesApi.js b/docs/data/toolpad/core/pagesApi.js index c36b8e189db..94f6be469bd 100644 --- a/docs/data/toolpad/core/pagesApi.js +++ b/docs/data/toolpad/core/pagesApi.js @@ -6,6 +6,7 @@ module.exports = [ { pathname: '/toolpad/core/api/app-provider' }, { pathname: '/toolpad/core/api/dashboard-layout' }, { pathname: '/toolpad/core/api/dialogs-provider' }, + { pathname: '/toolpad/core/api/localization-provider' }, { pathname: '/toolpad/core/api/notifications-provider' }, { pathname: '/toolpad/core/api/page-container' }, { pathname: '/toolpad/core/api/page-header' }, diff --git a/docs/pages/toolpad/core/api/account.json b/docs/pages/toolpad/core/api/account.json index b762be1d771..2677ac98d42 100644 --- a/docs/pages/toolpad/core/api/account.json +++ b/docs/pages/toolpad/core/api/account.json @@ -3,7 +3,7 @@ "localeText": { "type": { "name": "shape", - "description": "{ iconButtonAriaLabel?: string, signInLabel?: string, signOutLabel?: string }" + "description": "{ accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string }" } }, "slotProps": { diff --git a/docs/pages/toolpad/core/api/app-provider.json b/docs/pages/toolpad/core/api/app-provider.json index 6918852f106..30d444f4bcd 100644 --- a/docs/pages/toolpad/core/api/app-provider.json +++ b/docs/pages/toolpad/core/api/app-provider.json @@ -12,6 +12,12 @@ }, "default": "null" }, + "localeText": { + "type": { + "name": "shape", + "description": "{ accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string, alert?: string, cancel?: string, close?: string, confirm?: string, delete?: string, email?: string, loading?: string, magicLinkSignInTitle?: string, oauthSignInTitle?: string, ok?: string, or?: string, passkey?: string, passkeySignInTitle?: string, password?: string, save?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, username?: string, with?: string }" + } + }, "navigation": { "type": { "name": "arrayOf", diff --git a/docs/pages/toolpad/core/api/dashboard-layout.json b/docs/pages/toolpad/core/api/dashboard-layout.json index 6cb95c85aa3..954ac3ac023 100644 --- a/docs/pages/toolpad/core/api/dashboard-layout.json +++ b/docs/pages/toolpad/core/api/dashboard-layout.json @@ -25,7 +25,7 @@ "slotProps": { "type": { "name": "shape", - "description": "{ appTitle?: { branding?: { homeUrl?: string, logo?: node, title?: string } }, sidebarFooter?: { mini: bool }, toolbarAccount?: { localeText?: { iconButtonAriaLabel?: string, signInLabel?: string, signOutLabel?: string }, slotProps?: { popover?: object, popoverContent?: object, preview?: object, signInButton?: object, signOutButton?: object }, slots?: { popover?: elementType, popoverContent?: elementType, preview?: elementType, signInButton?: elementType, signOutButton?: elementType } }, toolbarActions?: object }" + "description": "{ appTitle?: { branding?: { homeUrl?: string, logo?: node, title?: string } }, sidebarFooter?: { mini: bool }, toolbarAccount?: { localeText?: { accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string }, slotProps?: { popover?: object, popoverContent?: object, preview?: object, signInButton?: object, signOutButton?: object }, slots?: { popover?: elementType, popoverContent?: elementType, preview?: elementType, signInButton?: elementType, signOutButton?: elementType } }, toolbarActions?: object }" }, "default": "{}" }, diff --git a/docs/pages/toolpad/core/api/localization-provider.js b/docs/pages/toolpad/core/api/localization-provider.js new file mode 100644 index 00000000000..0c8377e375e --- /dev/null +++ b/docs/pages/toolpad/core/api/localization-provider.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './localization-provider.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docs-toolpad/translations/api-docs/localization-provider', + false, + /\.\/localization-provider.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/toolpad/core/api/localization-provider.json b/docs/pages/toolpad/core/api/localization-provider.json new file mode 100644 index 00000000000..2c4393fd6d2 --- /dev/null +++ b/docs/pages/toolpad/core/api/localization-provider.json @@ -0,0 +1,18 @@ +{ + "props": { + "localeText": { + "type": { + "name": "shape", + "description": "{ accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string, alert?: string, cancel?: string, close?: string, confirm?: string, delete?: string, email?: string, loading?: string, magicLinkSignInTitle?: string, oauthSignInTitle?: string, ok?: string, or?: string, passkey?: string, passkeySignInTitle?: string, password?: string, save?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, username?: string, with?: string }" + } + } + }, + "name": "LocalizationProvider", + "imports": ["import { LocalizationProvider } from '@toolpad/core/AppProvider';"], + "classes": [], + "muiName": "LocalizationProvider", + "filename": "/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/toolpad/core/api/sign-in-page.json b/docs/pages/toolpad/core/api/sign-in-page.json index 132fb1607bc..e4b378b3898 100644 --- a/docs/pages/toolpad/core/api/sign-in-page.json +++ b/docs/pages/toolpad/core/api/sign-in-page.json @@ -1,5 +1,11 @@ { "props": { + "localeText": { + "type": { + "name": "shape", + "description": "{ email?: string, or?: string, passkey?: string, password?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, with?: string }" + } + }, "providers": { "type": { "name": "arrayOf", "description": "Array<{ id: string, name: string }>" }, "default": "[]" diff --git a/docs/translations/api-docs/app-provider/app-provider.json b/docs/translations/api-docs/app-provider/app-provider.json index 7450a9fa118..7e60f68b465 100644 --- a/docs/translations/api-docs/app-provider/app-provider.json +++ b/docs/translations/api-docs/app-provider/app-provider.json @@ -4,6 +4,7 @@ "authentication": { "description": "Authentication methods." }, "branding": { "description": "Branding options for the app." }, "children": { "description": "The content of the app provider." }, + "localeText": { "description": "Locale text for components" }, "navigation": { "description": "Navigation definition for the app." }, "router": { "description": "Router implementation used inside Toolpad components." }, "session": { "description": "Session info about the current user." }, diff --git a/docs/translations/api-docs/localization-provider/localization-provider.json b/docs/translations/api-docs/localization-provider/localization-provider.json new file mode 100644 index 00000000000..4b8c01172af --- /dev/null +++ b/docs/translations/api-docs/localization-provider/localization-provider.json @@ -0,0 +1,5 @@ +{ + "componentDescription": "", + "propDescriptions": { "localeText": { "description": "Locale for components texts" } }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/sign-in-page/sign-in-page.json b/docs/translations/api-docs/sign-in-page/sign-in-page.json index de36472fb55..d72225d77de 100644 --- a/docs/translations/api-docs/sign-in-page/sign-in-page.json +++ b/docs/translations/api-docs/sign-in-page/sign-in-page.json @@ -1,6 +1,7 @@ { "componentDescription": "", "propDescriptions": { + "localeText": { "description": "The labels for the account component." }, "providers": { "description": "The list of authentication providers to display." }, "signIn": { "description": "Callback fired when a user signs in.", diff --git a/packages/toolpad-core/src/Account/Account.tsx b/packages/toolpad-core/src/Account/Account.tsx index 25a4dae4ec0..b1174b83f54 100644 --- a/packages/toolpad-core/src/Account/Account.tsx +++ b/packages/toolpad-core/src/Account/Account.tsx @@ -13,6 +13,15 @@ import { SessionContext, AuthenticationContext } from '../AppProvider/AppProvide import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvider'; import { AccountLocaleContext } from './AccountLocaleContext'; +interface AccountLocaleText { + accountPreviewIconButtonLabel: string; + accountPreviewEmail: string; + accountPreviewName: string; + accountPreviewTitle: string; + accountSignInLabel: string; + accountSignOutLabel: string; +} + export interface AccountSlots { /** * The component used for the account preview @@ -59,9 +68,18 @@ export interface AccountProps { /** * The labels for the account component. */ - localeText?: Partial; + localeText?: Partial; } +const defaultAccountLocaleText: Pick = { + accountPreviewIconButtonLabel: 'Current User', + accountPreviewEmail: 'Email', + accountPreviewName: 'Name', + accountPreviewTitle: 'Account', + accountSignInLabel: 'Sign in', + accountSignOutLabel: 'Sign out', +}; + /** * * Demos: @@ -78,7 +96,7 @@ function Account(props: AccountProps) { const { localeText: propsLocaleText } = props; const globalLocaleText = useLocaleText(); const localeText = React.useMemo( - () => ({ ...globalLocaleText, ...propsLocaleText }), + () => ({ ...defaultAccountLocaleText, ...globalLocaleText, ...propsLocaleText }), [globalLocaleText, propsLocaleText], ); const { slots, slotProps } = props; @@ -197,9 +215,12 @@ Account.propTypes /* remove-proptypes */ = { * The labels for the account component. */ localeText: PropTypes.shape({ + accountIconButtonLabel: PropTypes.string, + accountPreviewEmail: PropTypes.string, + accountPreviewName: PropTypes.string, + accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, accountSignOutLabel: PropTypes.string, - iconButtonAriaLabel: PropTypes.string, }), /** * The props used for each slot inside. diff --git a/packages/toolpad-core/src/Account/AccountLocaleContext.tsx b/packages/toolpad-core/src/Account/AccountLocaleContext.tsx index 19c591b046c..4479c4b2b66 100644 --- a/packages/toolpad-core/src/Account/AccountLocaleContext.tsx +++ b/packages/toolpad-core/src/Account/AccountLocaleContext.tsx @@ -1,4 +1,7 @@ import * as React from 'react'; import type { LocaleText } from '../AppProvider/LocalizationProvider'; +/** + * @ignore - internal component. + */ export const AccountLocaleContext = React.createContext | null>(null); diff --git a/packages/toolpad-core/src/Account/AccountPreview.tsx b/packages/toolpad-core/src/Account/AccountPreview.tsx index 7b3965ff8a7..a5f41386680 100644 --- a/packages/toolpad-core/src/Account/AccountPreview.tsx +++ b/packages/toolpad-core/src/Account/AccountPreview.tsx @@ -8,6 +8,7 @@ import Stack from '@mui/material/Stack'; import IconButton, { IconButtonProps } from '@mui/material/IconButton'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { SessionContext } from '../AppProvider'; +import { useLocaleText } from '../AppProvider/LocalizationProvider'; import { AccountLocaleContext } from './AccountLocaleContext'; export type AccountPreviewVariant = 'condensed' | 'expanded'; @@ -79,7 +80,9 @@ export interface AccountPreviewProps { function AccountPreview(props: AccountPreviewProps) { const { slots, variant = 'condensed', slotProps, open, handleClick, sx } = props; const session = React.useContext(SessionContext); + const globalLocaleText = useLocaleText(); const accountLocaleText = React.useContext(AccountLocaleContext); + const localeText = { ...globalLocaleText, ...accountLocaleText }; if (!session || !session.user) { return null; @@ -128,14 +131,14 @@ function AccountPreview(props: AccountPreviewProps) { } return ( - + {slots?.avatarIconButton ? ( ) : ( - {accountLocaleText?.accountSignInLabel} + {localeText?.accountSignInLabel} ); } diff --git a/packages/toolpad-core/src/Account/SignOutButton.tsx b/packages/toolpad-core/src/Account/SignOutButton.tsx index d99d16aaefa..45add1b6fec 100644 --- a/packages/toolpad-core/src/Account/SignOutButton.tsx +++ b/packages/toolpad-core/src/Account/SignOutButton.tsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import Button, { ButtonProps } from '@mui/material/Button'; import LogoutIcon from '@mui/icons-material/Logout'; import { AuthenticationContext } from '../AppProvider'; +import { useLocaleText } from '../AppProvider/LocalizationProvider'; import { AccountLocaleContext } from './AccountLocaleContext'; export type SignOutButtonProps = ButtonProps; @@ -19,7 +20,9 @@ export type SignOutButtonProps = ButtonProps; */ function SignOutButton(props: SignOutButtonProps) { const authentication = React.useContext(AuthenticationContext); + const globalLocaleText = useLocaleText(); const accountLocaleText = React.useContext(AccountLocaleContext); + const localeText = { ...globalLocaleText, ...accountLocaleText }; return ( ); } diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index 8409c69282b..0d6627205d2 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -210,6 +210,38 @@ AppProvider.propTypes /* remove-proptypes */ = { * The content of the app provider. */ children: PropTypes.node, + /** + * Locale text for components + */ + localeText: PropTypes.shape({ + accountIconButtonLabel: PropTypes.string, + accountPreviewEmail: PropTypes.string, + accountPreviewName: PropTypes.string, + accountPreviewTitle: PropTypes.string, + accountSignInLabel: PropTypes.string, + accountSignOutLabel: PropTypes.string, + alert: PropTypes.string, + cancel: PropTypes.string, + close: PropTypes.string, + confirm: PropTypes.string, + delete: PropTypes.string, + email: PropTypes.string, + loading: PropTypes.string, + magicLinkSignInTitle: PropTypes.string, + oauthSignInTitle: PropTypes.string, + ok: PropTypes.string, + or: PropTypes.string, + passkey: PropTypes.string, + passkeySignInTitle: PropTypes.string, + password: PropTypes.string, + save: PropTypes.string, + signInRememberMe: PropTypes.string, + signInSubtitle: PropTypes.string, + signInTitle: PropTypes.string, + to: PropTypes.string, + username: PropTypes.string, + with: PropTypes.string, + }), /** * Navigation definition for the app. * @default [] diff --git a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx index c2fdd77e2d7..73289ddd259 100644 --- a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx @@ -1,15 +1,19 @@ 'use client'; import * as React from 'react'; +import PropTypes from 'prop-types'; import { useTheme } from '@mui/material/styles'; import DEFAULT_LOCALE from '../locales/en'; -export type LocaleText = { +export interface LocaleText { // Account accountSignInLabel: string; accountSignOutLabel: string; + // AccountPreview - accountTitle: string; - accountIconButtonLabel: string; + accountPreviewIconButtonLabel: string; + accountPreviewTitle: string; + accountPreviewEmail: string; + accountPreviewName: string; // SignInPage signInTitle: string; @@ -19,12 +23,6 @@ export type LocaleText = { magicLinkSignInTitle: string; signInRememberMe: string; - // Error messages - errorAccessDenied: string; - errorCallbackRoute: string; - errorMissingSecret: string; - errorAuthentication: string; - // Common authentication labels email: string; passkey: string; @@ -43,35 +41,7 @@ export type LocaleText = { alert: string; confirm: string; loading: string; - error: string; - success: string; - warning: string; - info: string; - - // Navigation - goBack: string; - goHome: string; - - // Form validation - required: string; - invalid: string; - - // Account Preview - accountPreviewTitle: string; - accountPreviewEmail: string; - accountPreviewName: string; - - // Dashboard Layout - dashboardTitle: string; - dashboardWelcome: string; - dashboardSettings: string; - dashboardLogout: string; - - // Error boundaries - errorBoundaryTitle: string; - errorBoundaryDescription: string; - errorBoundaryRetry: string; -}; +} export interface LocalizationProviderProps { children?: React.ReactNode; @@ -83,9 +53,7 @@ export interface LocalizationProviderProps { export const LocalizationContext = React.createContext>({}); -export const LocalizationProvider = function LocalizationProvider( - props: LocalizationProviderProps, -) { +const LocalizationProvider = function LocalizationProvider(props: LocalizationProviderProps) { const { localeText: propsLocaleText, children } = props; const theme = useTheme(); @@ -109,6 +77,60 @@ export const LocalizationProvider = function LocalizationProvider( return {children}; }; +LocalizationProvider.propTypes /* remove-proptypes */ = { + // ┌────────────────────────────── Warning ──────────────────────────────┐ + // │ These PropTypes are generated from the TypeScript type definitions. │ + // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │ + // └─────────────────────────────────────────────────────────────────────┘ + /** + * @ignore + */ + children: PropTypes.node, + /** + * Locale for components texts + */ + localeText: PropTypes.shape({ + accountIconButtonLabel: PropTypes.string, + accountPreviewEmail: PropTypes.string, + accountPreviewName: PropTypes.string, + accountPreviewTitle: PropTypes.string, + accountSignInLabel: PropTypes.string, + accountSignOutLabel: PropTypes.string, + alert: PropTypes.string, + cancel: PropTypes.string, + close: PropTypes.string, + confirm: PropTypes.string, + delete: PropTypes.string, + email: PropTypes.string, + loading: PropTypes.string, + magicLinkSignInTitle: PropTypes.string, + oauthSignInTitle: PropTypes.string, + ok: PropTypes.string, + or: PropTypes.string, + passkey: PropTypes.string, + passkeySignInTitle: PropTypes.string, + password: PropTypes.string, + save: PropTypes.string, + signInRememberMe: PropTypes.string, + signInSubtitle: PropTypes.string, + signInTitle: PropTypes.string, + to: PropTypes.string, + username: PropTypes.string, + with: PropTypes.string, + }), +} as any; + +export { LocalizationProvider }; +/** + * + * Demos: + * + * - [Sign-in Page](https://mui.com/toolpad/core/react-sign-in-page/) + * + * API: + * + * - [LocalizationProvider API](https://mui.com/toolpad/core/api/localization-provider) + */ export function useLocaleText() { return React.useContext(LocalizationContext); } diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx index 9146f9a53b0..e9b1cfd8f3f 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx @@ -546,9 +546,12 @@ DashboardLayout.propTypes /* remove-proptypes */ = { }), toolbarAccount: PropTypes.shape({ localeText: PropTypes.shape({ - iconButtonAriaLabel: PropTypes.string, - signInLabel: PropTypes.string, - signOutLabel: PropTypes.string, + accountIconButtonLabel: PropTypes.string, + accountPreviewEmail: PropTypes.string, + accountPreviewName: PropTypes.string, + accountPreviewTitle: PropTypes.string, + accountSignInLabel: PropTypes.string, + accountSignOutLabel: PropTypes.string, }), slotProps: PropTypes.shape({ popover: PropTypes.object, diff --git a/packages/toolpad-core/src/SignInPage/SignInPage.tsx b/packages/toolpad-core/src/SignInPage/SignInPage.tsx index 9f88b84ba45..ea865d530e9 100644 --- a/packages/toolpad-core/src/SignInPage/SignInPage.tsx +++ b/packages/toolpad-core/src/SignInPage/SignInPage.tsx @@ -136,6 +136,18 @@ const IconProviderMap = new Map([ ['fusionauth', ], ]); +interface SignInPageLocaleText { + signInTitle: string; + signInSubtitle: string; + signInRememberMe: string; + email: string; + password: string; + or: string; + with: string; + passkey: string; + to: string; +} + export interface AuthProvider { /** * The unique identifier of the authentication provider. @@ -264,9 +276,21 @@ export interface SignInPageProps { /** * The labels for the account component. */ - localeText?: Partial; + localeText?: Partial; } +const defaultLocaleText: Pick = { + signInTitle: 'Sign in', + signInSubtitle: 'Please sign in to continue', + signInRememberMe: 'Remember me', + email: 'Email', + password: 'Password', + or: 'or', + with: 'with', + passkey: 'Passkey', + to: 'to', +}; + /** * * Demos: @@ -283,7 +307,7 @@ function SignInPage(props: SignInPageProps) { const branding = React.useContext(BrandingContext); const router = React.useContext(RouterContext); const globalLocaleText = useLocaleText(); - const localeText = { ...globalLocaleText, ...propsLocaleText }; + const localeText = { ...defaultLocaleText, ...globalLocaleText, ...propsLocaleText }; const passkeyProvider = providers?.find((provider) => provider.id === 'passkey'); const credentialsProvider = providers?.find((provider) => provider.id === 'credentials'); @@ -475,7 +499,7 @@ function SignInPage(props: SignInPageProps) { {...slotProps?.submitButton} > {localeText.passkeySignInTitle || - `${localeText.signInTitle} ${localeText.with}`} + `${localeText.signInTitle} ${localeText.with}`}{' '} {passkeyProvider.name || localeText.passkey} )} @@ -704,6 +728,20 @@ SignInPage.propTypes /* remove-proptypes */ = { // │ These PropTypes are generated from the TypeScript type definitions. │ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │ // └─────────────────────────────────────────────────────────────────────┘ + /** + * The labels for the account component. + */ + localeText: PropTypes.shape({ + email: PropTypes.string, + or: PropTypes.string, + passkey: PropTypes.string, + password: PropTypes.string, + signInRememberMe: PropTypes.string, + signInSubtitle: PropTypes.string, + signInTitle: PropTypes.string, + to: PropTypes.string, + with: PropTypes.string, + }), /** * The list of authentication providers to display. * @default [] diff --git a/packages/toolpad-core/src/locales/en.tsx b/packages/toolpad-core/src/locales/en.tsx index 3fdfd1dbe27..4533fb20143 100644 --- a/packages/toolpad-core/src/locales/en.tsx +++ b/packages/toolpad-core/src/locales/en.tsx @@ -1,18 +1,24 @@ import type { LocaleText } from '../AppProvider'; import { getLocalization } from './getLocalization'; -const en: Partial = { +const en: LocaleText = { // Account accountSignInLabel: 'Sign In', accountSignOutLabel: 'Sign Out', // AccountPreview - accountTitle: 'Account', - accountIconButtonLabel: 'Current User', + accountPreviewEmail: 'Email', + accountPreviewName: 'User', + accountPreviewTitle: 'Account', + accountPreviewIconButtonLabel: 'Current User', + // SignInPage signInTitle: 'Sign In', signInSubtitle: 'Welcome user, please sign in to continue', signInRememberMe: 'Remember Me', + oauthSignInTitle: 'Sign in with OAuth', + passkeySignInTitle: 'Sign in with Passkey', + magicLinkSignInTitle: 'Sign in with Magic Link', // Common authentication labels email: 'Email', @@ -32,10 +38,6 @@ const en: Partial = { alert: 'Alert', confirm: 'Confirm', loading: 'Loading...', - error: 'Error', - success: 'Success', - warning: 'Warning', - info: 'Info', }; export default getLocalization(en); diff --git a/packages/toolpad-core/src/locales/hiIN.tsx b/packages/toolpad-core/src/locales/hiIN.tsx index 7637ea93433..d0561459b9e 100644 --- a/packages/toolpad-core/src/locales/hiIN.tsx +++ b/packages/toolpad-core/src/locales/hiIN.tsx @@ -7,16 +7,18 @@ const hiINLabels: Partial = { accountSignOutLabel: 'साइन आउट करें', // AccountPreview - accountTitle: 'खाता', - accountIconButtonLabel: 'वर्तमान उपयोगकर्ता', + accountPreviewEmail: 'ईमेल', + accountPreviewName: 'उपयोगकर्ता', + accountPreviewTitle: 'खाता', + accountPreviewIconButtonLabel: 'वर्तमान उपयोगकर्ता', // SignInPage signInTitle: 'साइन इन करें', + signInSubtitle: 'स्वागत है उपयोगकर्ता, कृपया जारी रखने के लिए साइन इन करें', + signInRememberMe: 'मुझे याद रखें', oauthSignInTitle: 'साइन इन विकल्प', passkeySignInTitle: 'साइन इन विकल्प', magicLinkSignInTitle: 'साइन इन विकल्प', - signInSubtitle: 'स्वागत है उपयोगकर्ता, कृपया जारी रखने के लिए साइन इन करें', - signInRememberMe: 'मुझे याद रखें', // Common authentication labels email: 'ईमेल', @@ -36,10 +38,6 @@ const hiINLabels: Partial = { alert: 'सूचना', confirm: 'पुष्टि करें', loading: 'लोड हो रहा है...', - error: 'त्रुटि', - success: 'सफल', - warning: 'चेतावनी', - info: 'जानकारी', }; export default getLocalization(hiINLabels); diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index ed55a6ddcfb..f84417c42c0 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -11,7 +11,21 @@ import { useNonNullableContext } from '@toolpad/utils/react'; import invariant from 'invariant'; import * as React from 'react'; import { DialogsContext } from './DialogsContext'; -import { useLocaleText } from '../AppProvider/LocalizationProvider'; +import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvider'; + +interface DialogsProviderLocaleText { + alert: string; + confirm: string; + cancel: string; + ok: string; +} + +const defaultLocaleText: Pick = { + alert: 'Alert', + confirm: 'Confirm', + cancel: 'Cancel', + ok: 'Ok', +}; export interface OpenDialogOptions { /** @@ -193,15 +207,16 @@ export interface AlertDialogPayload extends AlertOptions { export interface AlertDialogProps extends DialogProps {} export function AlertDialog({ open, payload, onClose }: AlertDialogProps) { - const localeText = useLocaleText(); + const globalLocaleText = useLocaleText(); + const localeText = { ...defaultLocaleText, ...globalLocaleText }; const okButtonProps = useDialogLoadingButton(() => onClose()); return ( onClose()}> - {payload.title ?? localeText?.alert} + {payload.title ?? localeText.alert} {payload.msg} - {payload.okText ?? localeText?.ok} + {payload.okText ?? localeText.ok} @@ -215,19 +230,20 @@ export interface ConfirmDialogPayload extends ConfirmOptions { export interface ConfirmDialogProps extends DialogProps {} export function ConfirmDialog({ open, payload, onClose }: ConfirmDialogProps) { - const localeText = useLocaleText(); + const globalLocaleText = useLocaleText(); + const localeText = { ...defaultLocaleText, ...globalLocaleText }; const cancelButtonProps = useDialogLoadingButton(() => onClose(false)); const okButtonProps = useDialogLoadingButton(() => onClose(true)); return ( onClose(false)}> - {payload.title ?? localeText?.confirm} + {payload.title ?? localeText.confirm} {payload.msg} - {payload.cancelText ?? localeText?.cancel} + {payload.cancelText ?? localeText.cancel} - {payload.okText ?? localeText?.ok} + {payload.okText ?? localeText.ok} @@ -241,7 +257,8 @@ export interface PromptDialogPayload extends PromptOptions { export interface PromptDialogProps extends DialogProps {} export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { - const localeText = useLocaleText(); + const globalLocaleText = useLocaleText(); + const localeText = { ...defaultLocaleText, ...globalLocaleText }; const [input, setInput] = React.useState(''); const cancelButtonProps = useDialogLoadingButton(() => onClose(null)); @@ -270,7 +287,7 @@ export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { }, }} > - {payload.title ?? localeText?.confirm} + {payload.title ?? localeText.confirm} {payload.msg} - {payload.cancelText ?? localeText?.cancel} + {payload.cancelText ?? localeText.cancel} - {payload.okText ?? localeText?.ok} + {payload.okText ?? localeText.ok} diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx index 75a11367cfe..12a35999c42 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx @@ -19,7 +19,7 @@ import type { ShowNotification, ShowNotificationOptions, } from './useNotifications'; -import { useLocaleText } from '../AppProvider/LocalizationProvider'; +import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvider'; export interface NotificationsProviderSlotProps { snackbar: SnackbarProps; @@ -35,6 +35,14 @@ export interface NotificationsProviderSlots { const RootPropsContext = React.createContext(null); +interface NotificationsProviderLocaleText { + close: string; +} + +const defaultLocaleText: Pick = { + close: 'Close', +}; + interface NotificationProps { notificationKey: string; badge: string | null; @@ -44,7 +52,8 @@ interface NotificationProps { } function Notification({ notificationKey, open, message, options, badge }: NotificationProps) { - const localeText = useLocaleText(); + const globalLocaleText = useLocaleText(); + const localeText = { ...defaultLocaleText, ...globalLocaleText }; const { close } = useNonNullableContext(NotificationsContext); const { severity, actionText, onAction, autoHideDuration } = options; From af39d47c29e700c92d9099f3f988ddbfcc49d6be Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Thu, 23 Jan 2025 13:41:31 +0530 Subject: [PATCH 5/7] fix: proptypes --- packages/toolpad-core/src/Account/Account.tsx | 2 +- packages/toolpad-core/src/AppProvider/AppProvider.tsx | 2 +- packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx | 2 +- packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/toolpad-core/src/Account/Account.tsx b/packages/toolpad-core/src/Account/Account.tsx index b1174b83f54..ad1656fb55c 100644 --- a/packages/toolpad-core/src/Account/Account.tsx +++ b/packages/toolpad-core/src/Account/Account.tsx @@ -215,8 +215,8 @@ Account.propTypes /* remove-proptypes */ = { * The labels for the account component. */ localeText: PropTypes.shape({ - accountIconButtonLabel: PropTypes.string, accountPreviewEmail: PropTypes.string, + accountPreviewIconButtonLabel: PropTypes.string, accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index 0d6627205d2..9d7615799c6 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -214,8 +214,8 @@ AppProvider.propTypes /* remove-proptypes */ = { * Locale text for components */ localeText: PropTypes.shape({ - accountIconButtonLabel: PropTypes.string, accountPreviewEmail: PropTypes.string, + accountPreviewIconButtonLabel: PropTypes.string, accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx index 73289ddd259..079532ae608 100644 --- a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx @@ -90,8 +90,8 @@ LocalizationProvider.propTypes /* remove-proptypes */ = { * Locale for components texts */ localeText: PropTypes.shape({ - accountIconButtonLabel: PropTypes.string, accountPreviewEmail: PropTypes.string, + accountPreviewIconButtonLabel: PropTypes.string, accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx index e9b1cfd8f3f..ed9e5204644 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx @@ -546,8 +546,8 @@ DashboardLayout.propTypes /* remove-proptypes */ = { }), toolbarAccount: PropTypes.shape({ localeText: PropTypes.shape({ - accountIconButtonLabel: PropTypes.string, accountPreviewEmail: PropTypes.string, + accountPreviewIconButtonLabel: PropTypes.string, accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, From b6efdb1fdd7522d59d2c22ddb9c3461d219653ed Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Thu, 23 Jan 2025 13:51:17 +0530 Subject: [PATCH 6/7] fix: Prune localization keys --- docs/pages/toolpad/core/api/account.json | 2 +- docs/pages/toolpad/core/api/app-provider.json | 2 +- docs/pages/toolpad/core/api/dashboard-layout.json | 2 +- .../pages/toolpad/core/api/localization-provider.json | 2 +- packages/toolpad-core/src/Account/Account.tsx | 11 +++-------- packages/toolpad-core/src/AppProvider/AppProvider.tsx | 2 -- .../src/AppProvider/LocalizationProvider.tsx | 4 ---- .../src/DashboardLayout/DashboardLayout.tsx | 2 -- packages/toolpad-core/src/locales/en.tsx | 2 -- packages/toolpad-core/src/locales/hiIN.tsx | 2 -- 10 files changed, 7 insertions(+), 24 deletions(-) diff --git a/docs/pages/toolpad/core/api/account.json b/docs/pages/toolpad/core/api/account.json index 2677ac98d42..0abec963639 100644 --- a/docs/pages/toolpad/core/api/account.json +++ b/docs/pages/toolpad/core/api/account.json @@ -3,7 +3,7 @@ "localeText": { "type": { "name": "shape", - "description": "{ accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string }" + "description": "{ accountPreviewIconButtonLabel?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string }" } }, "slotProps": { diff --git a/docs/pages/toolpad/core/api/app-provider.json b/docs/pages/toolpad/core/api/app-provider.json index 30d444f4bcd..a1d5185667b 100644 --- a/docs/pages/toolpad/core/api/app-provider.json +++ b/docs/pages/toolpad/core/api/app-provider.json @@ -15,7 +15,7 @@ "localeText": { "type": { "name": "shape", - "description": "{ accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string, alert?: string, cancel?: string, close?: string, confirm?: string, delete?: string, email?: string, loading?: string, magicLinkSignInTitle?: string, oauthSignInTitle?: string, ok?: string, or?: string, passkey?: string, passkeySignInTitle?: string, password?: string, save?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, username?: string, with?: string }" + "description": "{ accountPreviewIconButtonLabel?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string, alert?: string, cancel?: string, close?: string, confirm?: string, delete?: string, email?: string, loading?: string, magicLinkSignInTitle?: string, oauthSignInTitle?: string, ok?: string, or?: string, passkey?: string, passkeySignInTitle?: string, password?: string, save?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, username?: string, with?: string }" } }, "navigation": { diff --git a/docs/pages/toolpad/core/api/dashboard-layout.json b/docs/pages/toolpad/core/api/dashboard-layout.json index 954ac3ac023..77c901b54ae 100644 --- a/docs/pages/toolpad/core/api/dashboard-layout.json +++ b/docs/pages/toolpad/core/api/dashboard-layout.json @@ -25,7 +25,7 @@ "slotProps": { "type": { "name": "shape", - "description": "{ appTitle?: { branding?: { homeUrl?: string, logo?: node, title?: string } }, sidebarFooter?: { mini: bool }, toolbarAccount?: { localeText?: { accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string }, slotProps?: { popover?: object, popoverContent?: object, preview?: object, signInButton?: object, signOutButton?: object }, slots?: { popover?: elementType, popoverContent?: elementType, preview?: elementType, signInButton?: elementType, signOutButton?: elementType } }, toolbarActions?: object }" + "description": "{ appTitle?: { branding?: { homeUrl?: string, logo?: node, title?: string } }, sidebarFooter?: { mini: bool }, toolbarAccount?: { localeText?: { accountPreviewIconButtonLabel?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string }, slotProps?: { popover?: object, popoverContent?: object, preview?: object, signInButton?: object, signOutButton?: object }, slots?: { popover?: elementType, popoverContent?: elementType, preview?: elementType, signInButton?: elementType, signOutButton?: elementType } }, toolbarActions?: object }" }, "default": "{}" }, diff --git a/docs/pages/toolpad/core/api/localization-provider.json b/docs/pages/toolpad/core/api/localization-provider.json index 2c4393fd6d2..fc9e679f9e5 100644 --- a/docs/pages/toolpad/core/api/localization-provider.json +++ b/docs/pages/toolpad/core/api/localization-provider.json @@ -3,7 +3,7 @@ "localeText": { "type": { "name": "shape", - "description": "{ accountIconButtonLabel?: string, accountPreviewEmail?: string, accountPreviewName?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string, alert?: string, cancel?: string, close?: string, confirm?: string, delete?: string, email?: string, loading?: string, magicLinkSignInTitle?: string, oauthSignInTitle?: string, ok?: string, or?: string, passkey?: string, passkeySignInTitle?: string, password?: string, save?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, username?: string, with?: string }" + "description": "{ accountPreviewIconButtonLabel?: string, accountPreviewTitle?: string, accountSignInLabel?: string, accountSignOutLabel?: string, alert?: string, cancel?: string, close?: string, confirm?: string, delete?: string, email?: string, loading?: string, magicLinkSignInTitle?: string, oauthSignInTitle?: string, ok?: string, or?: string, passkey?: string, passkeySignInTitle?: string, password?: string, save?: string, signInRememberMe?: string, signInSubtitle?: string, signInTitle?: string, to?: string, username?: string, with?: string }" } } }, diff --git a/packages/toolpad-core/src/Account/Account.tsx b/packages/toolpad-core/src/Account/Account.tsx index ad1656fb55c..3f09101dba2 100644 --- a/packages/toolpad-core/src/Account/Account.tsx +++ b/packages/toolpad-core/src/Account/Account.tsx @@ -14,12 +14,11 @@ import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvi import { AccountLocaleContext } from './AccountLocaleContext'; interface AccountLocaleText { - accountPreviewIconButtonLabel: string; - accountPreviewEmail: string; - accountPreviewName: string; - accountPreviewTitle: string; accountSignInLabel: string; accountSignOutLabel: string; + + accountPreviewIconButtonLabel: string; + accountPreviewTitle: string; } export interface AccountSlots { @@ -73,8 +72,6 @@ export interface AccountProps { const defaultAccountLocaleText: Pick = { accountPreviewIconButtonLabel: 'Current User', - accountPreviewEmail: 'Email', - accountPreviewName: 'Name', accountPreviewTitle: 'Account', accountSignInLabel: 'Sign in', accountSignOutLabel: 'Sign out', @@ -215,9 +212,7 @@ Account.propTypes /* remove-proptypes */ = { * The labels for the account component. */ localeText: PropTypes.shape({ - accountPreviewEmail: PropTypes.string, accountPreviewIconButtonLabel: PropTypes.string, - accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, accountSignOutLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index 9d7615799c6..da4be530390 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -214,9 +214,7 @@ AppProvider.propTypes /* remove-proptypes */ = { * Locale text for components */ localeText: PropTypes.shape({ - accountPreviewEmail: PropTypes.string, accountPreviewIconButtonLabel: PropTypes.string, - accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, accountSignOutLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx index 079532ae608..dc05312cae3 100644 --- a/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/LocalizationProvider.tsx @@ -12,8 +12,6 @@ export interface LocaleText { // AccountPreview accountPreviewIconButtonLabel: string; accountPreviewTitle: string; - accountPreviewEmail: string; - accountPreviewName: string; // SignInPage signInTitle: string; @@ -90,9 +88,7 @@ LocalizationProvider.propTypes /* remove-proptypes */ = { * Locale for components texts */ localeText: PropTypes.shape({ - accountPreviewEmail: PropTypes.string, accountPreviewIconButtonLabel: PropTypes.string, - accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, accountSignOutLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx index ed9e5204644..8661491a1c8 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx @@ -546,9 +546,7 @@ DashboardLayout.propTypes /* remove-proptypes */ = { }), toolbarAccount: PropTypes.shape({ localeText: PropTypes.shape({ - accountPreviewEmail: PropTypes.string, accountPreviewIconButtonLabel: PropTypes.string, - accountPreviewName: PropTypes.string, accountPreviewTitle: PropTypes.string, accountSignInLabel: PropTypes.string, accountSignOutLabel: PropTypes.string, diff --git a/packages/toolpad-core/src/locales/en.tsx b/packages/toolpad-core/src/locales/en.tsx index 4533fb20143..0f55d82cd64 100644 --- a/packages/toolpad-core/src/locales/en.tsx +++ b/packages/toolpad-core/src/locales/en.tsx @@ -7,8 +7,6 @@ const en: LocaleText = { accountSignOutLabel: 'Sign Out', // AccountPreview - accountPreviewEmail: 'Email', - accountPreviewName: 'User', accountPreviewTitle: 'Account', accountPreviewIconButtonLabel: 'Current User', diff --git a/packages/toolpad-core/src/locales/hiIN.tsx b/packages/toolpad-core/src/locales/hiIN.tsx index d0561459b9e..16175c45125 100644 --- a/packages/toolpad-core/src/locales/hiIN.tsx +++ b/packages/toolpad-core/src/locales/hiIN.tsx @@ -7,8 +7,6 @@ const hiINLabels: Partial = { accountSignOutLabel: 'साइन आउट करें', // AccountPreview - accountPreviewEmail: 'ईमेल', - accountPreviewName: 'उपयोगकर्ता', accountPreviewTitle: 'खाता', accountPreviewIconButtonLabel: 'वर्तमान उपयोगकर्ता', From dfeff2e932dc42b4c125234cf093d3d50ed76bdf Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Thu, 23 Jan 2025 13:59:16 +0530 Subject: [PATCH 7/7] fix: Missed --- packages/toolpad-core/src/utils/getThemeLocaleText.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/toolpad-core/src/utils/getThemeLocaleText.ts diff --git a/packages/toolpad-core/src/utils/getThemeLocaleText.ts b/packages/toolpad-core/src/utils/getThemeLocaleText.ts deleted file mode 100644 index e69de29bb2d..00000000000