diff --git a/.changeset/famous-glasses-sleep.md b/.changeset/famous-glasses-sleep.md index 3bb7edd5..17015af9 100644 --- a/.changeset/famous-glasses-sleep.md +++ b/.changeset/famous-glasses-sleep.md @@ -2,4 +2,4 @@ "@treasure-dev/tdk-react": minor --- -Removed `tailwind-merge` dependency for ~70Kb savings in gzipped package +Removed `tailwind-merge` dependency for ~7Kb savings in gzipped package diff --git a/.changeset/kind-mails-agree.md b/.changeset/kind-mails-agree.md new file mode 100644 index 00000000..c89d77f2 --- /dev/null +++ b/.changeset/kind-mails-agree.md @@ -0,0 +1,5 @@ +--- +"@treasure-dev/tdk-react": minor +--- + +Removed `react-i18n` dependency for ~20Kb savings in gzipped package diff --git a/packages/react/.storybook/preview.tsx b/packages/react/.storybook/preview.tsx index ec4db5a1..767cfd51 100644 --- a/packages/react/.storybook/preview.tsx +++ b/packages/react/.storybook/preview.tsx @@ -3,7 +3,7 @@ import type { Preview } from "@storybook/react"; import React from "react"; import { ThirdwebProvider } from "thirdweb/react"; -import { TreasureProvider } from "../src/contexts/treasure"; +import { TreasureProvider } from "../src/providers/treasure"; import "../src/globals.css"; diff --git a/packages/react/package.json b/packages/react/package.json index 0bd1011b..ca3608fe 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -47,10 +47,7 @@ "@treasure-dev/launcher": "workspace:*", "class-variance-authority": "catalog:", "clsx": "catalog:", - "i18next": "catalog:", - "i18next-browser-languagedetector": "catalog:", - "input-otp": "catalog:", - "react-i18next": "catalog:" + "input-otp": "catalog:" }, "devDependencies": { "@storybook/addon-essentials": "catalog:", diff --git a/packages/react/src/components/ui/Dialog.tsx b/packages/react/src/components/ui/Dialog.tsx deleted file mode 100644 index 0ba0f98a..00000000 --- a/packages/react/src/components/ui/Dialog.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import * as DialogPrimitive from "@radix-ui/react-dialog"; -import clsx from "clsx"; -import * as React from "react"; -import { useTranslation } from "react-i18next"; - -import { CloseIcon } from "../../icons/CloseIcon"; - -const Dialog = DialogPrimitive.Root; - -const DialogPortal = DialogPrimitive.Portal; - -const DialogTitle = DialogPrimitive.Title; - -const DialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; - -const DialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => { - const { t } = useTranslation(); - return ( - - - -
- - - {t("common.close")} - - {children} -
-
-
- ); -}); -DialogContent.displayName = DialogPrimitive.Content.displayName; - -export { Dialog, DialogContent, DialogTitle }; diff --git a/packages/react/src/hooks/useContractAddress.ts b/packages/react/src/hooks/useContractAddress.ts index 6e5f3ba4..48aea07f 100644 --- a/packages/react/src/hooks/useContractAddress.ts +++ b/packages/react/src/hooks/useContractAddress.ts @@ -3,7 +3,8 @@ import { getContractAddress, getContractAddresses, } from "@treasure-dev/tdk-core"; -import { useTreasure } from "../contexts/treasure"; + +import { useTreasure } from "../providers/treasure"; export const useContractAddress = ({ chainId, diff --git a/packages/react/src/i18n.ts b/packages/react/src/i18n.ts deleted file mode 100644 index fa8ec629..00000000 --- a/packages/react/src/i18n.ts +++ /dev/null @@ -1,38 +0,0 @@ -import i18n from "i18next"; -import LanguageDetector from "i18next-browser-languagedetector"; -import { initReactI18next } from "react-i18next"; - -import type { LocaleId } from "thirdweb/react"; -import { en } from "./translations/en"; -import { es } from "./translations/es"; -import { ja } from "./translations/ja"; -import { ru } from "./translations/ru"; - -export type SupportedLanguage = "en" | "es" | "ja" | "ru"; - -i18n - .use(LanguageDetector) - .use(initReactI18next) - .init({ - resources: { en, es, ja, ru }, - fallbackLng: "en", - cleanCode: true, - interpolation: { - escapeValue: false, - }, - }); - -export const getLocaleId = (): LocaleId | undefined => { - switch (i18n.language) { - case "en": - return "en_US"; - case "es": - return "es_ES"; - case "ja": - return "ja_JP"; - default: - return undefined; - } -}; - -export { i18n }; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 308c8a64..45eb3202 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -2,11 +2,11 @@ import "./globals.css"; export type * from "@treasure-dev/tdk-core"; -export { ConnectButton } from "./components/connect/ConnectButton"; -export { ConnectModal } from "./components/connect/ConnectModal"; -export { Button } from "./components/ui/Button"; -export { TreasureProvider, useTreasure } from "./contexts/treasure"; -export { useConnect } from "./hooks/useConnect"; +export { ConnectButton } from "./ui/ConnectButton/ConnectButton"; +export { ConnectModal } from "./ui/ConnectModal/ConnectModal"; +export { Button } from "./ui/components/Button"; +export { TreasureProvider, useTreasure } from "./providers/treasure"; +export { useConnect } from "./ui/hooks/useConnect"; export { useContractAddress, useContractAddresses, diff --git a/packages/react/src/contexts/treasure.tsx b/packages/react/src/providers/treasure.tsx similarity index 95% rename from packages/react/src/contexts/treasure.tsx rename to packages/react/src/providers/treasure.tsx index e30df90a..795481d6 100644 --- a/packages/react/src/contexts/treasure.tsx +++ b/packages/react/src/providers/treasure.tsx @@ -26,7 +26,6 @@ import { useMemo, useState, } from "react"; -import { I18nextProvider } from "react-i18next"; import { ZERO_ADDRESS, defineChain } from "thirdweb"; import { useActiveWallet, @@ -39,9 +38,8 @@ import { import { isZkSyncChain } from "thirdweb/utils"; import { type Wallet, ecosystemWallet } from "thirdweb/wallets"; -import { useLauncher } from "../hooks/useLauncher"; -import { i18n } from "../i18n"; import type { AnalyticsEvent, Config, ContextValues } from "../types"; +import { useLauncher } from "../ui/hooks/useLauncher"; import { EVT_TREASURECONNECT_CONNECTED, EVT_TREASURECONNECT_DISCONNECTED, @@ -68,8 +66,9 @@ export const useTreasure = () => { type Props = PropsWithChildren; -const TreasureProviderInner = ({ +export const TreasureProvider = ({ children, + language, appName, appIconUri, apiUri = DEFAULT_TDK_API_BASE_URI, @@ -360,6 +359,7 @@ const TreasureProviderInner = ({ return ( ); }; - -export const TreasureProvider = (props: Props) => { - useEffect(() => { - if (props.language) { - i18n.changeLanguage(props.language); - } - }, [props.language]); - - return ( - - - - ); -}; diff --git a/packages/react/src/translations/en.ts b/packages/react/src/translations/en.ts deleted file mode 100644 index 1a273a99..00000000 --- a/packages/react/src/translations/en.ts +++ /dev/null @@ -1,42 +0,0 @@ -export const en = { - translation: { - common: { - or: "or", - close: "Close", - emailLabel: "Email address", - }, - connect: { - action: "Connect", - header: "Connect to <1>{{appName}}", - footer: "Powered by Thirdweb", - option: { - apple: "Apple", - discord: "Discord", - google: "Google", - passkey: "Passkey", - wallet: "Wallet", - x: "X", - }, - verify: { - header: "Verify code", - description: - "We have sent a verification code to <2>{{recipient}}. You will be automatically logged in after entering your code.", - inputLabel: "Enter verification code:", - action: "Confirm", - resend: { - prompt: "Didn't get a code?", - action: "Resend", - countdown: "Resend available in {{resendAvailableInSec}}s...", - }, - }, - migrate: { - header: "Migrate existing account", - description: - "It looks like you have several existing Treasure profiles. Please choose one you would like to use moving forward as your identity across the Treasure ecosystem.", - approve: "Use this account", - reject: "Start fresh", - disclaimer: "NOTE: This is irreversible, so please choose carefully.", - }, - }, - }, -}; diff --git a/packages/react/src/translations/en.tsx b/packages/react/src/translations/en.tsx new file mode 100644 index 00000000..4aaf57e5 --- /dev/null +++ b/packages/react/src/translations/en.tsx @@ -0,0 +1,50 @@ +import type { ReactNode } from "react"; + +const translation = { + connect: { + action: "Connect", + header: ({ appName }: { appName: ReactNode }) => <>Connect to {appName}, + footer: ({ thirdweb }: { thirdweb: ReactNode }) => ( + <>Powered by {thirdweb} + ), + option: { + email: "Email address", + or: "or", + apple: "Apple", + discord: "Discord", + google: "Google", + passkey: "Passkey", + wallet: "Wallet", + x: "X", + }, + verify: { + header: "Verify code", + description: ({ recipient }: { recipient: ReactNode }) => ( + <> + We have sent a verification code to {recipient}. You will be + automatically logged in after entering your code. + + ), + inputLabel: "Enter verification code:", + action: "Confirm", + resend: { + prompt: "Didn't get a code?", + action: "Resend", + countdown: ({ seconds }: { seconds: number }) => + `Resend available in ${seconds}s...`, + }, + }, + migrate: { + header: "Migrate existing account", + description: + "It looks like you have several existing Treasure profiles. Please choose one you would like to use moving forward as your identity across the Treasure ecosystem.", + approve: "Use this account", + reject: "Start fresh", + disclaimer: "NOTE: This is irreversible, so please choose carefully.", + }, + }, +}; + +export type Translation = typeof translation; + +export default translation; diff --git a/packages/react/src/translations/es.ts b/packages/react/src/translations/es.ts deleted file mode 100644 index b6ea4d6d..00000000 --- a/packages/react/src/translations/es.ts +++ /dev/null @@ -1,34 +0,0 @@ -export const es = { - translation: { - common: { - or: "o", - close: "Cerrar", - emailLabel: "Correo electrónico", - }, - connect: { - action: "Conectar", - header: "Conectarse a <1>{{appName}}", - footer: "Con tecnología de Thirdweb", - option: { - apple: "Apple", - discord: "Discord", - google: "Google", - passkey: "Clave de paso", - wallet: "Cartera", - x: "X", - }, - verify: { - header: "Verificar código", - description: - "Se envió un código de verificación a <2>{{recipient}}. Iniciará sesión automáticamente después de ingresar su código.", - inputLabel: "Ingresar código de verificación:", - action: "Confirmar", - resend: { - prompt: "¿No recibió un código?", - action: "Reenviar", - countdown: "Reenvío disponsible en {{resendAvailableInSec}}s...", - }, - }, - }, - }, -}; diff --git a/packages/react/src/translations/es.tsx b/packages/react/src/translations/es.tsx new file mode 100644 index 00000000..911a7596 --- /dev/null +++ b/packages/react/src/translations/es.tsx @@ -0,0 +1,46 @@ +import type { Translation } from "./en"; + +const translation: Translation = { + connect: { + action: "Conectar", + header: ({ appName }) => <>Conectarse a {appName}, + footer: ({ thirdweb }) => <>Con tecnología de {thirdweb}, + option: { + email: "Correo electrónico", + or: "o", + apple: "Apple", + discord: "Discord", + google: "Google", + passkey: "Clave de paso", + wallet: "Cartera", + x: "X", + }, + verify: { + header: "Verificar código", + description: ({ recipient }) => ( + <> + Se envió un código de verificación a {recipient}. Iniciará sesión + automáticamente después de ingresar su código. + + ), + inputLabel: "Ingresar código de verificación:", + action: "Confirmar", + resend: { + prompt: "¿No recibió un código?", + action: "Reenviar", + countdown: ({ seconds }: { seconds: number }) => + `Reenvío disponsible en ${seconds}s...`, + }, + }, + migrate: { + header: "Migrate existing account", + description: + "It looks like you have several existing Treasure profiles. Please choose one you would like to use moving forward as your identity across the Treasure ecosystem.", + approve: "Use this account", + reject: "Start fresh", + disclaimer: "NOTE: This is irreversible, so please choose carefully.", + }, + }, +}; + +export default translation; diff --git a/packages/react/src/translations/ja.ts b/packages/react/src/translations/ja.ts deleted file mode 100644 index d94a7393..00000000 --- a/packages/react/src/translations/ja.ts +++ /dev/null @@ -1,34 +0,0 @@ -export const ja = { - translation: { - common: { - or: "または", - close: "閉じる", - emailLabel: "メールアドレス", - }, - connect: { - action: "接続", - header: "<1>{{appName}} に接続する", - footer: "提供元:Thirdweb", - option: { - apple: "Apple", - discord: "Discord", - google: "Google", - passkey: "パスキー", - wallet: "ウォレット", - x: "X", - }, - verify: { - header: "コードを確認", - description: - "<2>{{recipient}} に確認コードを送信しました。コードを入力すると自動的にログインされます。", - inputLabel: "確認コードを入力してください:", - action: "確認", - resend: { - prompt: "コードが届かない場合は?", - action: "再送信", - countdown: "{{resendAvailableInSec}}秒後に再送信可能...", - }, - }, - }, - }, -}; diff --git a/packages/react/src/translations/ja.tsx b/packages/react/src/translations/ja.tsx new file mode 100644 index 00000000..4559522c --- /dev/null +++ b/packages/react/src/translations/ja.tsx @@ -0,0 +1,46 @@ +import type { Translation } from "./en"; + +const translation: Translation = { + connect: { + action: "接続", + header: ({ appName }) => <>{appName} に接続する, + footer: ({ thirdweb }) => <>提供元:{thirdweb}, + option: { + email: "メールアドレス", + or: "または", + apple: "Apple", + discord: "Discord", + google: "Google", + passkey: "パスキー", + wallet: "ウォレット", + x: "X", + }, + verify: { + header: "コードを確認", + description: ({ recipient }) => ( + <> + {recipient}{" "} + に確認コードを送信しました。コードを入力すると自動的にログインされます。 + + ), + inputLabel: "確認コードを入力してください:", + action: "確認", + resend: { + prompt: "コードが届かない場合は?", + action: "再送信", + countdown: ({ seconds }: { seconds: number }) => + `${seconds}秒後に再送信可能...`, + }, + }, + migrate: { + header: "Migrate existing account", + description: + "It looks like you have several existing Treasure profiles. Please choose one you would like to use moving forward as your identity across the Treasure ecosystem.", + approve: "Use this account", + reject: "Start fresh", + disclaimer: "NOTE: This is irreversible, so please choose carefully.", + }, + }, +}; + +export default translation; diff --git a/packages/react/src/translations/ru.ts b/packages/react/src/translations/ru.ts deleted file mode 100644 index 2c3515e9..00000000 --- a/packages/react/src/translations/ru.ts +++ /dev/null @@ -1,35 +0,0 @@ -export const ru = { - translation: { - common: { - or: "или", - close: "Закрыть", - emailLabel: "Электронный адрес", - }, - connect: { - action: "Подключиться", - header: "Подключиться к <1>{{appName}}", - footer: "На платформе Thirdweb", - option: { - apple: "Apple", - discord: "Discord", - google: "Google", - passkey: "Ключ доступа", - wallet: "Кошелёк", - x: "X", - }, - verify: { - header: "Проверить код", - description: - "Отправили код проверки на <2>{{recipient}}. После ввода кода, Вы будете автоматически авторизованы.", - inputLabel: "Введите код проверки:", - action: "Подтвердить", - resend: { - prompt: "Не получили код?", - action: "Отправить повторно", - countdown: - "Повторная отправка возможна через {{resendAvailableInSec}} сек...", - }, - }, - }, - }, -}; diff --git a/packages/react/src/translations/ru.tsx b/packages/react/src/translations/ru.tsx new file mode 100644 index 00000000..44bfce4d --- /dev/null +++ b/packages/react/src/translations/ru.tsx @@ -0,0 +1,46 @@ +import type { Translation } from "./en"; + +const translation: Translation = { + connect: { + action: "Подключиться", + header: ({ appName }) => <>Подключиться к {appName}, + footer: ({ thirdweb }) => <>На платформе {thirdweb}, + option: { + email: "Электронный адрес", + or: "или", + apple: "Apple", + discord: "Discord", + google: "Google", + passkey: "Ключ доступа", + wallet: "Кошелёк", + x: "X", + }, + verify: { + header: "Проверить код", + description: ({ recipient }) => ( + <> + Отправили код проверки на {recipient}. После ввода кода, Вы будете + автоматически авторизованы. + + ), + inputLabel: "Введите код проверки:", + action: "Подтвердить", + resend: { + prompt: "Не получили код?", + action: "Отправить повторно", + countdown: ({ seconds }: { seconds: number }) => + `Повторная отправка возможна через ${seconds} сек...`, + }, + }, + migrate: { + header: "Migrate existing account", + description: + "It looks like you have several existing Treasure profiles. Please choose one you would like to use moving forward as your identity across the Treasure ecosystem.", + approve: "Use this account", + reject: "Start fresh", + disclaimer: "NOTE: This is irreversible, so please choose carefully.", + }, + }, +}; + +export default translation; diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts index 8ebed328..dd184fac 100644 --- a/packages/react/src/types.ts +++ b/packages/react/src/types.ts @@ -15,7 +15,7 @@ import type { import type { ReactNode } from "react"; import type { Chain } from "thirdweb"; import type { Wallet } from "thirdweb/dist/types/exports/wallets"; -import type { SupportedLanguage } from "./i18n"; +import type { Language } from "./ui/hooks/useTranslation"; export type AnalyticsEvent = { name: string; @@ -39,7 +39,7 @@ type AnalyticsOptions = { }; export type Config = { - language?: SupportedLanguage; + language?: Language; appName: string; appIconUri?: string; apiUri?: string; @@ -56,6 +56,7 @@ export type Config = { }; export type ContextValues = { + language?: Language; appName: string; appIconUri?: string; chain: Chain; diff --git a/packages/react/src/components/launcher/AccountModal.tsx b/packages/react/src/ui/AccountModal.tsx similarity index 86% rename from packages/react/src/components/launcher/AccountModal.tsx rename to packages/react/src/ui/AccountModal.tsx index 2957884f..7218c2df 100644 --- a/packages/react/src/components/launcher/AccountModal.tsx +++ b/packages/react/src/ui/AccountModal.tsx @@ -1,12 +1,12 @@ import * as VisuallyHidden from "@radix-ui/react-visually-hidden"; import { DEFAULT_TDK_APP_ICON_URI } from "@treasure-dev/tdk-core"; import clsx from "clsx"; -import { Trans } from "react-i18next"; import { MediaRenderer, useWalletImage } from "thirdweb/react"; import { shortenAddress } from "thirdweb/utils"; -import { useTreasure } from "../../contexts/treasure"; -import { Dialog, DialogContent, DialogTitle } from "../ui/Dialog"; +import { useTreasure } from "../providers/treasure"; +import { Dialog, DialogContent, DialogTitle } from "./components/Dialog"; +import { useTranslation } from "./hooks/useTranslation"; type Props = { open: boolean; @@ -23,6 +23,7 @@ export const AccountModal = ({ open, size = "lg", onOpenChange }: Props) => { appIconUri = DEFAULT_TDK_APP_ICON_URI, ecosystemId, } = useTreasure(); + const { t } = useTranslation(); const { data: walletImage } = useWalletImage(ecosystemId); @@ -44,12 +45,7 @@ export const AccountModal = ({ open, size = "lg", onOpenChange }: Props) => { aria-describedby={undefined} > - - - Connect to - {appName} - - + {t.connect.header({ appName })}
diff --git a/packages/react/src/components/connect/ConnectButton.stories.tsx b/packages/react/src/ui/ConnectButton/ConnectButton.stories.tsx similarity index 100% rename from packages/react/src/components/connect/ConnectButton.stories.tsx rename to packages/react/src/ui/ConnectButton/ConnectButton.stories.tsx diff --git a/packages/react/src/components/connect/ConnectButton.tsx b/packages/react/src/ui/ConnectButton/ConnectButton.tsx similarity index 77% rename from packages/react/src/components/connect/ConnectButton.tsx rename to packages/react/src/ui/ConnectButton/ConnectButton.tsx index 1e5e9101..66314b4b 100644 --- a/packages/react/src/components/connect/ConnectButton.tsx +++ b/packages/react/src/ui/ConnectButton/ConnectButton.tsx @@ -1,12 +1,11 @@ -import { useTranslation } from "react-i18next"; - -import { useTreasure } from "../../contexts/treasure"; +import { useTreasure } from "../../providers/treasure"; +import { Button } from "../components/Button"; import { type Options as UseConnectOptions, useConnect, -} from "../../hooks/useConnect"; -import { TreasureIcon } from "../../icons/TreasureIcon"; -import { Button } from "../ui/Button"; +} from "../hooks/useConnect"; +import { useTranslation } from "../hooks/useTranslation"; +import { TreasureIcon } from "../icons/TreasureIcon"; import { ConnectButtonAuthenticatedView } from "./ConnectButtonAuthenticatedView"; type Props = UseConnectOptions; @@ -34,7 +33,7 @@ export const ConnectButton = (props?: Props) => { className="tdk-w-5 tdk-h-5 tdk-text-cream" starsFill="#C62222" /> - {t("connect.action")} + {t.connect.action} )} diff --git a/packages/react/src/components/connect/ConnectButtonAuthenticatedView.stories.tsx b/packages/react/src/ui/ConnectButton/ConnectButtonAuthenticatedView.stories.tsx similarity index 100% rename from packages/react/src/components/connect/ConnectButtonAuthenticatedView.stories.tsx rename to packages/react/src/ui/ConnectButton/ConnectButtonAuthenticatedView.stories.tsx diff --git a/packages/react/src/components/connect/ConnectButtonAuthenticatedView.tsx b/packages/react/src/ui/ConnectButton/ConnectButtonAuthenticatedView.tsx similarity index 89% rename from packages/react/src/components/connect/ConnectButtonAuthenticatedView.tsx rename to packages/react/src/ui/ConnectButton/ConnectButtonAuthenticatedView.tsx index 1839a030..f4860996 100644 --- a/packages/react/src/components/connect/ConnectButtonAuthenticatedView.tsx +++ b/packages/react/src/ui/ConnectButton/ConnectButtonAuthenticatedView.tsx @@ -1,8 +1,8 @@ import clsx from "clsx"; import type { ButtonHTMLAttributes } from "react"; -import { UserAvatar } from "../user/UserAvatar"; -import { UserDisplayName } from "../user/UserDisplayName"; +import { UserAvatar } from "../User/UserAvatar"; +import { UserDisplayName } from "../User/UserDisplayName"; type Props = ButtonHTMLAttributes & { address: string; diff --git a/packages/react/src/components/connect/ConnectFooter.tsx b/packages/react/src/ui/ConnectModal/ConnectFooter.tsx similarity index 64% rename from packages/react/src/components/connect/ConnectFooter.tsx rename to packages/react/src/ui/ConnectModal/ConnectFooter.tsx index 22e3a3d8..d2e14ac0 100644 --- a/packages/react/src/components/connect/ConnectFooter.tsx +++ b/packages/react/src/ui/ConnectModal/ConnectFooter.tsx @@ -1,7 +1,8 @@ -import { Trans } from "react-i18next"; -import { ThirdwebTextIcon } from "../../icons/ThirdwebTextIcon"; +import { useTranslation } from "../hooks/useTranslation"; +import { ThirdwebTextIcon } from "../icons/ThirdwebTextIcon"; export const ConnectFooter = () => { + const { t } = useTranslation(); return ( ); diff --git a/packages/react/src/components/connect/ConnectMethodSelectionView.stories.tsx b/packages/react/src/ui/ConnectModal/ConnectMethodSelectionView.stories.tsx similarity index 100% rename from packages/react/src/components/connect/ConnectMethodSelectionView.stories.tsx rename to packages/react/src/ui/ConnectModal/ConnectMethodSelectionView.stories.tsx diff --git a/packages/react/src/components/connect/ConnectMethodSelectionView.tsx b/packages/react/src/ui/ConnectModal/ConnectMethodSelectionView.tsx similarity index 81% rename from packages/react/src/components/connect/ConnectMethodSelectionView.tsx rename to packages/react/src/ui/ConnectModal/ConnectMethodSelectionView.tsx index 48ffb520..7a672a20 100644 --- a/packages/react/src/components/connect/ConnectMethodSelectionView.tsx +++ b/packages/react/src/ui/ConnectModal/ConnectMethodSelectionView.tsx @@ -5,15 +5,15 @@ import { } from "@treasure-dev/tdk-core"; import clsx from "clsx"; import { type ButtonHTMLAttributes, useRef, useState } from "react"; -import { Trans, useTranslation } from "react-i18next"; -import { AppleIcon } from "../../icons/AppleIcon"; -import { DiscordIcon } from "../../icons/DiscordIcon"; -import { GoogleIcon } from "../../icons/GoogleIcon"; -import { PasskeyIcon } from "../../icons/PasskeyIcon"; -import { WalletIcon } from "../../icons/WalletIcon"; -import { XIcon } from "../../icons/XIcon"; -import { Button } from "../ui/Button"; +import { Button } from "../components/Button"; +import { useTranslation } from "../hooks/useTranslation"; +import { AppleIcon } from "../icons/AppleIcon"; +import { DiscordIcon } from "../icons/DiscordIcon"; +import { GoogleIcon } from "../icons/GoogleIcon"; +import { PasskeyIcon } from "../icons/PasskeyIcon"; +import { WalletIcon } from "../icons/WalletIcon"; +import { XIcon } from "../icons/XIcon"; import { ConnectFooter } from "./ConnectFooter"; export type Options = { @@ -49,15 +49,13 @@ export const ConnectMethodSelectionView = ({
{/* Screen reader title is in ConnectModal */}
{error ? ( @@ -79,7 +77,7 @@ export const ConnectMethodSelectionView = ({ >
- {t("common.or")} + {t.connect.option.or}
onConnect("google")} disabled={isLoading} > onConnect("x")} disabled={isLoading} > onConnect("discord")} disabled={isLoading} > onConnect("apple")} disabled={isLoading} > @@ -136,7 +134,7 @@ export const ConnectMethodSelectionView = ({ disabled={isLoading} > - {t("connect.option.passkey")} + {t.connect.option.passkey} ) : null} {!disableWallet ? ( @@ -146,7 +144,7 @@ export const ConnectMethodSelectionView = ({ disabled={isLoading} > - {t("connect.option.wallet")} + {t.connect.option.wallet} ) : null}
diff --git a/packages/react/src/components/connect/ConnectMigrateUserView.stories.tsx b/packages/react/src/ui/ConnectModal/ConnectMigrateUserView.stories.tsx similarity index 100% rename from packages/react/src/components/connect/ConnectMigrateUserView.stories.tsx rename to packages/react/src/ui/ConnectModal/ConnectMigrateUserView.stories.tsx diff --git a/packages/react/src/components/connect/ConnectMigrateUserView.tsx b/packages/react/src/ui/ConnectModal/ConnectMigrateUserView.tsx similarity index 92% rename from packages/react/src/components/connect/ConnectMigrateUserView.tsx rename to packages/react/src/ui/ConnectModal/ConnectMigrateUserView.tsx index 8aef91ca..9d3fbb62 100644 --- a/packages/react/src/components/connect/ConnectMigrateUserView.tsx +++ b/packages/react/src/ui/ConnectModal/ConnectMigrateUserView.tsx @@ -1,12 +1,12 @@ import type { LegacyProfile } from "@treasure-dev/tdk-core"; import clsx from "clsx"; import { useState } from "react"; -import { useTranslation } from "react-i18next"; import { ZERO_ADDRESS } from "thirdweb"; import { shortenAddress } from "thirdweb/utils"; -import { TreasureSparklesIcon } from "../../icons/TreasureSparklesIcon"; -import { Button } from "../ui/Button"; +import { Button } from "../components/Button"; +import { useTranslation } from "../hooks/useTranslation"; +import { TreasureSparklesIcon } from "../icons/TreasureSparklesIcon"; type Props = { legacyProfiles: Pick< @@ -38,10 +38,10 @@ export const ConnectMigrateUserView = ({ className="tdk-text-lg tdk-font-semibold tdk-text-white tdk-m-0" aria-hidden="true" > - {t("connect.migrate.header")} + {t.connect.migrate.header}

- {t("connect.migrate.description")} + {t.connect.migrate.description}

@@ -113,7 +113,7 @@ export const ConnectMigrateUserView = ({ selectedProfileId ? () => onApprove(selectedProfileId) : undefined } > - {t("connect.migrate.approve")} + {t.connect.migrate.approve}

- {t("connect.migrate.disclaimer")} + {t.connect.migrate.disclaimer}

diff --git a/packages/react/src/components/connect/ConnectModal.stories.tsx b/packages/react/src/ui/ConnectModal/ConnectModal.stories.tsx similarity index 100% rename from packages/react/src/components/connect/ConnectModal.stories.tsx rename to packages/react/src/ui/ConnectModal/ConnectModal.stories.tsx diff --git a/packages/react/src/components/connect/ConnectModal.tsx b/packages/react/src/ui/ConnectModal/ConnectModal.tsx similarity index 94% rename from packages/react/src/components/connect/ConnectModal.tsx rename to packages/react/src/ui/ConnectModal/ConnectModal.tsx index 22263370..a0746f2e 100644 --- a/packages/react/src/components/connect/ConnectModal.tsx +++ b/packages/react/src/ui/ConnectModal/ConnectModal.tsx @@ -15,11 +15,10 @@ import { useEffect, useState } from "react"; import { useConnect, useConnectModal } from "thirdweb/react"; import { type Wallet, authenticateWithRedirect } from "thirdweb/wallets"; -import { Trans, useTranslation } from "react-i18next"; -import { useTreasure } from "../../contexts/treasure"; -import { getLocaleId } from "../../i18n"; +import { useTreasure } from "../../providers/treasure"; import { getErrorMessage } from "../../utils/error"; -import { Dialog, DialogContent, DialogTitle } from "../ui/Dialog"; +import { Dialog, DialogContent, DialogTitle } from "../components/Dialog"; +import { useTranslation } from "../hooks/useTranslation"; import { type Options as ConnectMethodSelectionOptions, ConnectMethodSelectionView, @@ -63,7 +62,7 @@ export const ConnectModal = ({ onConnectError, ...methodSelectionProps }: Props) => { - const { t } = useTranslation(); + const { t, thirdwebLocale } = useTranslation(); const { appName, appIconUri = DEFAULT_TDK_APP_ICON_URI, @@ -188,7 +187,7 @@ export const ConnectModal = ({ try { const web3Wallet = await connectWeb3Wallet({ client, - locale: getLocaleId(), + locale: thirdwebLocale, wallets: SUPPORTED_WEB3_WALLETS, appMetadata: { name: appName, @@ -360,16 +359,11 @@ export const ConnectModal = ({ > - {isMigrating ? ( - t("connect.migrate.header") - ) : email ? ( - t("connect.verify.header") - ) : ( - - Connect to - {appName} - - )} + {isMigrating + ? t.connect.migrate.header + : email + ? t.connect.verify.header + : t.connect.header({ appName })}
diff --git a/packages/react/src/components/connect/ConnectVerifyCodeView.stories.tsx b/packages/react/src/ui/ConnectModal/ConnectVerifyCodeView.stories.tsx similarity index 100% rename from packages/react/src/components/connect/ConnectVerifyCodeView.stories.tsx rename to packages/react/src/ui/ConnectModal/ConnectVerifyCodeView.stories.tsx diff --git a/packages/react/src/components/connect/ConnectVerifyCodeView.tsx b/packages/react/src/ui/ConnectModal/ConnectVerifyCodeView.tsx similarity index 81% rename from packages/react/src/components/connect/ConnectVerifyCodeView.tsx rename to packages/react/src/ui/ConnectModal/ConnectVerifyCodeView.tsx index 619113e4..592b7713 100644 --- a/packages/react/src/components/connect/ConnectVerifyCodeView.tsx +++ b/packages/react/src/ui/ConnectModal/ConnectVerifyCodeView.tsx @@ -1,9 +1,9 @@ import { REGEXP_ONLY_DIGITS } from "input-otp"; import { useRef, useState } from "react"; -import { Trans, useTranslation } from "react-i18next"; -import { Button } from "../ui/Button"; -import { InputOTP, InputOTPGroup, InputOTPSlot } from "../ui/InputOTP"; +import { Button } from "../components/Button"; +import { InputOTP, InputOTPGroup, InputOTPSlot } from "../components/InputOTP"; +import { useTranslation } from "../hooks/useTranslation"; import { ConnectFooter } from "./ConnectFooter"; type Props = { @@ -55,14 +55,12 @@ export const ConnectVerifyCodeView = ({ className="tdk-text-lg tdk-font-semibold tdk-text-white tdk-m-0" aria-hidden="true" > - {t("connect.verify.header")} + {t.connect.verify.header}

- - We have sent a verification code to{" "} - {recipient}. You will - be automatically logged in after entering your code. - + {t.connect.verify.description({ + recipient: {recipient}, + })}

@@ -74,7 +72,7 @@ export const ConnectVerifyCodeView = ({

- {t("connect.verify.inputLabel")} + {t.connect.verify.inputLabel}

onConfirm(code)} > - {t("connect.verify.action")} + {t.connect.verify.action}

- {t("connect.verify.resend.prompt")}{" "} + {t.connect.verify.resend.prompt}{" "} {resendAvailableInSec > 0 ? ( - {t("connect.verify.resend.countdown", { resendAvailableInSec })} + {t.connect.verify.resend.countdown({ + seconds: resendAvailableInSec, + })} ) : ( )}

diff --git a/packages/react/src/components/user/UserAvatar.stories.tsx b/packages/react/src/ui/User/UserAvatar.stories.tsx similarity index 100% rename from packages/react/src/components/user/UserAvatar.stories.tsx rename to packages/react/src/ui/User/UserAvatar.stories.tsx diff --git a/packages/react/src/components/user/UserAvatar.tsx b/packages/react/src/ui/User/UserAvatar.tsx similarity index 100% rename from packages/react/src/components/user/UserAvatar.tsx rename to packages/react/src/ui/User/UserAvatar.tsx diff --git a/packages/react/src/components/user/UserDisplayName.stories.tsx b/packages/react/src/ui/User/UserDisplayName.stories.tsx similarity index 100% rename from packages/react/src/components/user/UserDisplayName.stories.tsx rename to packages/react/src/ui/User/UserDisplayName.stories.tsx diff --git a/packages/react/src/components/user/UserDisplayName.tsx b/packages/react/src/ui/User/UserDisplayName.tsx similarity index 88% rename from packages/react/src/components/user/UserDisplayName.tsx rename to packages/react/src/ui/User/UserDisplayName.tsx index 6d153b93..f703fea2 100644 --- a/packages/react/src/components/user/UserDisplayName.tsx +++ b/packages/react/src/ui/User/UserDisplayName.tsx @@ -1,7 +1,7 @@ import clsx from "clsx"; import { shortenAddress } from "thirdweb/utils"; -import { TreasureSparklesIcon } from "../../icons/TreasureSparklesIcon"; +import { TreasureSparklesIcon } from "../icons/TreasureSparklesIcon"; type Props = { address: string; diff --git a/packages/react/src/components/ui/Button.stories.tsx b/packages/react/src/ui/components/Button.stories.tsx similarity index 100% rename from packages/react/src/components/ui/Button.stories.tsx rename to packages/react/src/ui/components/Button.stories.tsx diff --git a/packages/react/src/components/ui/Button.tsx b/packages/react/src/ui/components/Button.tsx similarity index 100% rename from packages/react/src/components/ui/Button.tsx rename to packages/react/src/ui/components/Button.tsx diff --git a/packages/react/src/ui/components/Dialog.tsx b/packages/react/src/ui/components/Dialog.tsx new file mode 100644 index 00000000..cc0a6e9f --- /dev/null +++ b/packages/react/src/ui/components/Dialog.tsx @@ -0,0 +1,51 @@ +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import clsx from "clsx"; +import * as React from "react"; + +import { CloseIcon } from "../icons/CloseIcon"; + +const Dialog = DialogPrimitive.Root; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogTitle = DialogPrimitive.Title; + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + +
+ + + Close + + {children} +
+
+
+)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +export { Dialog, DialogContent, DialogTitle }; diff --git a/packages/react/src/components/ui/InputOTP.tsx b/packages/react/src/ui/components/InputOTP.tsx similarity index 100% rename from packages/react/src/components/ui/InputOTP.tsx rename to packages/react/src/ui/components/InputOTP.tsx diff --git a/packages/react/src/components/ui/Spinner.tsx b/packages/react/src/ui/components/Spinner.tsx similarity index 100% rename from packages/react/src/components/ui/Spinner.tsx rename to packages/react/src/ui/components/Spinner.tsx diff --git a/packages/react/src/hooks/useConnect.tsx b/packages/react/src/ui/hooks/useConnect.tsx similarity index 90% rename from packages/react/src/hooks/useConnect.tsx rename to packages/react/src/ui/hooks/useConnect.tsx index b3437602..4a790996 100644 --- a/packages/react/src/hooks/useConnect.tsx +++ b/packages/react/src/ui/hooks/useConnect.tsx @@ -7,23 +7,23 @@ import { } from "thirdweb/react"; import { ecosystemWallet } from "thirdweb/wallets"; +import { useTreasure } from "../../providers/treasure"; +import { + EVT_TREASURECONNECT_UI_ACCOUNT, + EVT_TREASURECONNECT_UI_LOGIN, +} from "../../utils/defaultAnalytics"; import { ConnectModal, type Options as ConnectModalOptions, type Props as ConnectModalProps, -} from "../components/connect/ConnectModal"; -import { UserDisplayName } from "../components/user/UserDisplayName"; -import { useTreasure } from "../contexts/treasure"; -import { getLocaleId } from "../i18n"; -import { - EVT_TREASURECONNECT_UI_ACCOUNT, - EVT_TREASURECONNECT_UI_LOGIN, -} from "../utils/defaultAnalytics"; +} from "../ConnectModal/ConnectModal"; +import { UserDisplayName } from "../User/UserDisplayName"; import { CONNECT_MODAL_SUPPORTED_TOKENS, CONNECT_MODAL_THEME, -} from "../constants"; +} from "../../constants"; +import { useTranslation } from "./useTranslation"; export type Options = ConnectModalOptions & { supportedChainIds?: number[]; @@ -45,6 +45,7 @@ export const useConnect = (options?: Options) => { openLauncherAccountModal, trackCustomEvent, } = useTreasure(); + const { thirdwebLocale } = useTranslation(); const activeWallet = useActiveWallet(); const { open: openWalletDetailsModal } = useWalletDetailsModal(); const { @@ -98,7 +99,7 @@ export const useConnect = (options?: Options) => { client, chains, theme: CONNECT_MODAL_THEME, - locale: getLocaleId(), + locale: thirdwebLocale, connectOptions: { chain, wallets: [ diff --git a/packages/react/src/hooks/useLauncher.tsx b/packages/react/src/ui/hooks/useLauncher.tsx similarity index 94% rename from packages/react/src/hooks/useLauncher.tsx rename to packages/react/src/ui/hooks/useLauncher.tsx index f871337b..14a00777 100644 --- a/packages/react/src/hooks/useLauncher.tsx +++ b/packages/react/src/ui/hooks/useLauncher.tsx @@ -1,6 +1,7 @@ import { getTreasureLauncherAuthToken } from "@treasure-dev/launcher"; import { type ReactNode, useEffect } from "react"; -import { AccountModal } from "../components/launcher/AccountModal"; + +import { AccountModal } from "../AccountModal"; type Props = { getAuthTokenOverride?: () => string | undefined; diff --git a/packages/react/src/ui/hooks/useTranslation.ts b/packages/react/src/ui/hooks/useTranslation.ts new file mode 100644 index 00000000..d3e76511 --- /dev/null +++ b/packages/react/src/ui/hooks/useTranslation.ts @@ -0,0 +1,67 @@ +import { useEffect, useMemo, useState } from "react"; +import type { LocaleId } from "thirdweb/react"; + +import { useTreasure } from "../../providers/treasure"; +import type { Translation } from "../../translations/en"; +import en from "../../translations/en"; + +const SUPPORTED_LANGUAGES = ["en", "es", "ja", "ru"] as const; +export type Language = (typeof SUPPORTED_LANGUAGES)[number]; + +const isSupportedLanguage = (language: string): language is Language => + SUPPORTED_LANGUAGES.includes(language as Language); + +const getTranslation = async (language: Language): Promise => { + switch (language) { + case "es": { + return (await import("../../translations/es")).default; + } + case "ja": { + return (await import("../../translations/ja")).default; + } + case "ru": { + return (await import("../../translations/ru")).default; + } + default: + return en; + } +}; + +type Options = { + language?: Language; +}; + +export const useTranslation = (options?: Options) => { + const treasure = useTreasure(); + const [translation, setTranslation] = useState(en); + + const browserLanguage = navigator?.language.slice(0, 2).toLowerCase(); + const language = + options?.language ?? + treasure.language ?? + (browserLanguage && isSupportedLanguage(browserLanguage) + ? browserLanguage + : undefined) ?? + "en"; + + useEffect(() => { + (async () => { + setTranslation(await getTranslation(language)); + })(); + }, [language]); + + const thirdwebLocale: LocaleId | undefined = useMemo(() => { + switch (language) { + case "en": + return "en_US"; + case "es": + return "es_ES"; + case "ja": + return "ja_JP"; + default: + return undefined; + } + }, [language]); + + return { language, thirdwebLocale, t: translation }; +}; diff --git a/packages/react/src/icons/AppleIcon.tsx b/packages/react/src/ui/icons/AppleIcon.tsx similarity index 100% rename from packages/react/src/icons/AppleIcon.tsx rename to packages/react/src/ui/icons/AppleIcon.tsx diff --git a/packages/react/src/icons/CloseIcon.tsx b/packages/react/src/ui/icons/CloseIcon.tsx similarity index 100% rename from packages/react/src/icons/CloseIcon.tsx rename to packages/react/src/ui/icons/CloseIcon.tsx diff --git a/packages/react/src/icons/DiscordIcon.tsx b/packages/react/src/ui/icons/DiscordIcon.tsx similarity index 100% rename from packages/react/src/icons/DiscordIcon.tsx rename to packages/react/src/ui/icons/DiscordIcon.tsx diff --git a/packages/react/src/icons/GoogleIcon.tsx b/packages/react/src/ui/icons/GoogleIcon.tsx similarity index 100% rename from packages/react/src/icons/GoogleIcon.tsx rename to packages/react/src/ui/icons/GoogleIcon.tsx diff --git a/packages/react/src/icons/PasskeyIcon.tsx b/packages/react/src/ui/icons/PasskeyIcon.tsx similarity index 100% rename from packages/react/src/icons/PasskeyIcon.tsx rename to packages/react/src/ui/icons/PasskeyIcon.tsx diff --git a/packages/react/src/icons/ThirdwebTextIcon.tsx b/packages/react/src/ui/icons/ThirdwebTextIcon.tsx similarity index 100% rename from packages/react/src/icons/ThirdwebTextIcon.tsx rename to packages/react/src/ui/icons/ThirdwebTextIcon.tsx diff --git a/packages/react/src/icons/TreasureIcon.tsx b/packages/react/src/ui/icons/TreasureIcon.tsx similarity index 100% rename from packages/react/src/icons/TreasureIcon.tsx rename to packages/react/src/ui/icons/TreasureIcon.tsx diff --git a/packages/react/src/icons/TreasureSparklesIcon.tsx b/packages/react/src/ui/icons/TreasureSparklesIcon.tsx similarity index 100% rename from packages/react/src/icons/TreasureSparklesIcon.tsx rename to packages/react/src/ui/icons/TreasureSparklesIcon.tsx diff --git a/packages/react/src/icons/WalletIcon.tsx b/packages/react/src/ui/icons/WalletIcon.tsx similarity index 100% rename from packages/react/src/icons/WalletIcon.tsx rename to packages/react/src/ui/icons/WalletIcon.tsx diff --git a/packages/react/src/icons/XIcon.tsx b/packages/react/src/ui/icons/XIcon.tsx similarity index 100% rename from packages/react/src/icons/XIcon.tsx rename to packages/react/src/ui/icons/XIcon.tsx diff --git a/packages/react/src/icons/types.ts b/packages/react/src/ui/icons/types.ts similarity index 100% rename from packages/react/src/icons/types.ts rename to packages/react/src/ui/icons/types.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70f3d88e..fbf5fc80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,12 +138,6 @@ catalogs: husky: specifier: ^9.1.7 version: 9.1.7 - i18next: - specifier: ^24.2.2 - version: 24.2.2 - i18next-browser-languagedetector: - specifier: ^8.0.2 - version: 8.0.2 input-otp: specifier: ^1.4.2 version: 1.4.2 @@ -186,9 +180,6 @@ catalogs: react-dom: specifier: ^18.2.0 version: 18.3.1 - react-i18next: - specifier: ^15.4.0 - version: 15.4.0 storybook: specifier: ^8.5.3 version: 8.5.3 @@ -211,8 +202,8 @@ catalogs: specifier: ^4.19.2 version: 4.19.2 turbo: - specifier: ^2.3.4 - version: 2.3.4 + specifier: ^2.4.0 + version: 2.4.0 typescript: specifier: ^5.7.3 version: 5.7.3 @@ -278,7 +269,7 @@ importers: version: 15.4.3 turbo: specifier: 'catalog:' - version: 2.3.4 + version: 2.4.0 typescript: specifier: 'catalog:' version: 5.7.3 @@ -648,21 +639,12 @@ importers: clsx: specifier: 'catalog:' version: 2.1.1 - i18next: - specifier: 'catalog:' - version: 24.2.2(typescript@5.7.3) - i18next-browser-languagedetector: - specifier: 'catalog:' - version: 8.0.2 input-otp: specifier: 'catalog:' version: 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 'catalog:' version: 18.3.1 - react-i18next: - specifier: 'catalog:' - version: 15.4.0(i18next@24.2.2(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) thirdweb: specifier: 'catalog:' version: 5.86.6(@aws-sdk/client-kms@3.734.0)(@types/react-dom@18.3.1)(@types/react@18.3.13)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)(zod@3.23.8) @@ -4802,9 +4784,6 @@ packages: resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} engines: {node: '>=18'} - html-parse-stringify@3.0.1: - resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} - http-assert@1.5.0: resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} engines: {node: '>= 0.8'} @@ -4867,17 +4846,6 @@ packages: engines: {node: '>=18'} hasBin: true - i18next-browser-languagedetector@8.0.2: - resolution: {integrity: sha512-shBvPmnIyZeD2VU5jVGIOWP7u9qNG3Lj7mpaiPFpbJ3LVfHZJvVzKR4v1Cb91wAOFpNw442N+LGPzHOHsten2g==} - - i18next@24.2.2: - resolution: {integrity: sha512-NE6i86lBCKRYZa5TaUDkU5S4HFgLIEJRLr3Whf2psgaxBleQ2LC1YW1Vc+SCgkAW7VEzndT6al6+CzegSUHcTQ==} - peerDependencies: - typescript: ^5 - peerDependenciesMeta: - typescript: - optional: true - iconv-corefoundation@1.1.7: resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} engines: {node: ^8.11.2 || >=10} @@ -6170,19 +6138,6 @@ packages: peerDependencies: react: ^18.3.1 - react-i18next@15.4.0: - resolution: {integrity: sha512-Py6UkX3zV08RTvL6ZANRoBh9sL/ne6rQq79XlkHEdd82cZr2H9usbWpUNVadJntIZP2pu3M2rL1CN+5rQYfYFw==} - peerDependencies: - i18next: '>= 23.2.3' - react: '>= 16.8.0' - react-dom: '*' - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -6928,38 +6883,38 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.3.4: - resolution: {integrity: sha512-uOi/cUIGQI7uakZygH+cZQ5D4w+aMLlVCN2KTGot+cmefatps2ZmRRufuHrEM0Rl63opdKD8/JIu+54s25qkfg==} + turbo-darwin-64@2.4.0: + resolution: {integrity: sha512-kVMScnPUa3R4n7woNmkR15kOY0aUwCLJcUyH5UC59ggKqr5HIHwweKYK8N1pwBQso0LQF4I9i93hIzfJguCcwQ==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.3.4: - resolution: {integrity: sha512-IIM1Lq5R+EGMtM1YFGl4x8Xkr0MWb4HvyU8N4LNoQ1Be5aycrOE+VVfH+cDg/Q4csn+8bxCOxhRp5KmUflrVTQ==} + turbo-darwin-arm64@2.4.0: + resolution: {integrity: sha512-8JObIpfun1guA7UlFR5jC/SOVm49lRscxMxfg5jZ5ABft79rhFC+ygN9AwAhGKv6W2DUhIh2xENkSgu4EDmUyg==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.3.4: - resolution: {integrity: sha512-1aD2EfR7NfjFXNH3mYU5gybLJEFi2IGOoKwoPLchAFRQ6OEJQj201/oNo9CDL75IIrQo64/NpEgVyZtoPlfhfA==} + turbo-linux-64@2.4.0: + resolution: {integrity: sha512-xWDGGcRlBuGV7HXWAVuTY6vsQi4aZxGMAnuiuNDg8Ij1aHGohOM0RUsWMXjxz4vuJmjk9+/D6NQqHH3AJEXezg==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.3.4: - resolution: {integrity: sha512-MxTpdKwxCaA5IlybPxgGLu54fT2svdqTIxRd0TQmpRJIjM0s4kbM+7YiLk0mOh6dGqlWPUsxz/A0Mkn8Xr5o7Q==} + turbo-linux-arm64@2.4.0: + resolution: {integrity: sha512-c3En99xMguc/Pdtk/rZP53LnDdw0W6lgUc04he8r8F+UHYSNvgzHh0WGXXmCC6lGbBH72kPhhGx4bAwyvi7dug==} cpu: [arm64] os: [linux] - turbo-windows-64@2.3.4: - resolution: {integrity: sha512-yyCrWqcRGu1AOOlrYzRnizEtdkqi+qKP0MW9dbk9OsMDXaOI5jlWtTY/AtWMkLw/czVJ7yS9Ex1vi9DB6YsFvw==} + turbo-windows-64@2.4.0: + resolution: {integrity: sha512-/gOORuOlyA8JDPzyA16CD3wvyRcuBFePa1URAnFUof9hXQmKxK0VvSDO79cYZFsJSchCKNJpckUS0gYxGsWwoA==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.3.4: - resolution: {integrity: sha512-PggC3qH+njPfn1PDVwKrQvvQby8X09ufbqZ2Ha4uSu+5TvPorHHkAbZVHKYj2Y+tvVzxRzi4Sv6NdHXBS9Be5w==} + turbo-windows-arm64@2.4.0: + resolution: {integrity: sha512-/DJIdTFijEMM5LSiEpSfarDOMOlYqJV+EzmppqWtHqDsOLF4hbbIBH9sJR6OOp5dURAu5eURBYdmvBRz9Lo6TA==} cpu: [arm64] os: [win32] - turbo@2.3.4: - resolution: {integrity: sha512-1kiLO5C0Okh5ay1DbHsxkPsw9Sjsbjzm6cF85CpWjR0BIyBFNDbKqtUyqGADRS1dbbZoQanJZVj4MS5kk8J42Q==} + turbo@2.4.0: + resolution: {integrity: sha512-ah/yQp2oMif1X0u7fBJ4MLMygnkbKnW5O8SG6pJvloPCpHfFoZctkSVQiJ3VnvNTq71V2JJIdwmOeu1i34OQyg==} hasBin: true type-fest@0.13.1: @@ -7233,10 +7188,6 @@ packages: jsdom: optional: true - void-elements@3.1.0: - resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} - engines: {node: '>=0.10.0'} - w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -12707,10 +12658,6 @@ snapshots: dependencies: whatwg-encoding: 3.1.1 - html-parse-stringify@3.0.1: - dependencies: - void-elements: 3.1.0 - http-assert@1.5.0: dependencies: deep-equal: 1.0.1 @@ -12789,16 +12736,6 @@ snapshots: husky@9.1.7: {} - i18next-browser-languagedetector@8.0.2: - dependencies: - '@babel/runtime': 7.26.0 - - i18next@24.2.2(typescript@5.7.3): - dependencies: - '@babel/runtime': 7.26.0 - optionalDependencies: - typescript: 5.7.3 - iconv-corefoundation@1.1.7: dependencies: cli-truncate: 2.1.0 @@ -14101,15 +14038,6 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-i18next@15.4.0(i18next@24.2.2(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.26.0 - html-parse-stringify: 3.0.1 - i18next: 24.2.2(typescript@5.7.3) - react: 18.3.1 - optionalDependencies: - react-dom: 18.3.1(react@18.3.1) - react-is@16.13.1: {} react-refresh@0.14.2: {} @@ -14912,32 +14840,32 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@2.3.4: + turbo-darwin-64@2.4.0: optional: true - turbo-darwin-arm64@2.3.4: + turbo-darwin-arm64@2.4.0: optional: true - turbo-linux-64@2.3.4: + turbo-linux-64@2.4.0: optional: true - turbo-linux-arm64@2.3.4: + turbo-linux-arm64@2.4.0: optional: true - turbo-windows-64@2.3.4: + turbo-windows-64@2.4.0: optional: true - turbo-windows-arm64@2.3.4: + turbo-windows-arm64@2.4.0: optional: true - turbo@2.3.4: + turbo@2.4.0: optionalDependencies: - turbo-darwin-64: 2.3.4 - turbo-darwin-arm64: 2.3.4 - turbo-linux-64: 2.3.4 - turbo-linux-arm64: 2.3.4 - turbo-windows-64: 2.3.4 - turbo-windows-arm64: 2.3.4 + turbo-darwin-64: 2.4.0 + turbo-darwin-arm64: 2.4.0 + turbo-linux-64: 2.4.0 + turbo-linux-arm64: 2.4.0 + turbo-windows-64: 2.4.0 + turbo-windows-arm64: 2.4.0 type-fest@0.13.1: optional: true @@ -15167,8 +15095,6 @@ snapshots: - tsx - yaml - void-elements@3.1.0: {} - w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 21efc552..20ee270f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -48,8 +48,6 @@ catalog: express: ^4.21.2 fastify: ^5.2.1 husky: ^9.1.7 - i18next: ^24.2.2 - "i18next-browser-languagedetector": ^8.0.2 "input-otp": ^1.4.2 jsdom: ^25.0.1 jsonwebtoken: ^9.0.2 @@ -64,7 +62,6 @@ catalog: prisma: ^6.3.0 react: ^18.2.0 "react-dom": ^18.2.0 - "react-i18next": ^15.4.0 storybook: ^8.5.3 tailwindcss: ^3.4.17 "tailwind-config-viewer": ^2.0.4 @@ -72,7 +69,7 @@ catalog: thirdweb: 5.86.6 # check ox and viem versions if upgrading tsup: 8.3.0 # --watch mode broken with Fastify in later versions tsx: ^4.19.2 - turbo: ^2.3.4 + turbo: ^2.4.0 typescript: ^5.7.3 uuid: ^11.0.5 viem: 2.22.15 # matches Thirdweb version to satisfy getAwsKmsAccount types