diff --git a/packages/app/package.json b/packages/app/package.json index 16fd889fd7..aece2897f9 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@affine/datacenter": "workspace:*", + "@affine/i18n": "workspace:*", "@blocksuite/blocks": "0.3.1-20230109032243-37ad3ba", "@blocksuite/editor": "0.3.1-20230109032243-37ad3ba", "@blocksuite/icons": "^2.0.2", @@ -27,7 +28,6 @@ "cmdk": "^0.1.20", "css-spring": "^4.1.0", "dayjs": "^1.11.7", - "i18next": "^21.9.1", "lit": "^2.3.1", "next": "13.1.0", "next-debug-local": "^0.1.5", @@ -36,7 +36,6 @@ "quill-cursors": "^4.0.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-i18next": "^11.18.4", "yjs": "^13.5.44" }, "devDependencies": { diff --git a/packages/app/src/components/404/index.tsx b/packages/app/src/components/404/index.tsx index 7df644bbfe..8ed4232807 100644 --- a/packages/app/src/components/404/index.tsx +++ b/packages/app/src/components/404/index.tsx @@ -1,5 +1,5 @@ import { NotFoundTitle, PageContainer } from './styles'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const NotfoundPage = () => { const { t } = useTranslation(); return ( diff --git a/packages/app/src/components/contact-modal/index.tsx b/packages/app/src/components/contact-modal/index.tsx index 0cb97f1176..3cd4d04f85 100644 --- a/packages/app/src/components/contact-modal/index.tsx +++ b/packages/app/src/components/contact-modal/index.tsx @@ -23,7 +23,7 @@ import { StyledModalFooter, } from './style'; import bg from '@/components/contact-modal/bg.png'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; const linkList = [ { icon: , diff --git a/packages/app/src/components/editor-mode-switch/index.tsx b/packages/app/src/components/editor-mode-switch/index.tsx index 2e8ccfdcf2..5fe4217c3e 100644 --- a/packages/app/src/components/editor-mode-switch/index.tsx +++ b/packages/app/src/components/editor-mode-switch/index.tsx @@ -15,7 +15,7 @@ import { useTheme } from '@/providers/ThemeProvider'; import { EdgelessIcon, PaperIcon } from './Icons'; import useCurrentPageMeta from '@/hooks/use-current-page-meta'; import { usePageHelper } from '@/hooks/use-page-helper'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; const PaperItem = ({ active }: { active?: boolean }) => { const { theme: { diff --git a/packages/app/src/components/header/QuickSearchButton.tsx b/packages/app/src/components/header/QuickSearchButton.tsx index 0c1732adb1..0b28e43b09 100644 --- a/packages/app/src/components/header/QuickSearchButton.tsx +++ b/packages/app/src/components/header/QuickSearchButton.tsx @@ -3,7 +3,7 @@ import { IconButton, IconButtonProps } from '@/ui/button'; import { Tooltip } from '@/ui/tooltip'; import { ArrowDownIcon } from '@blocksuite/icons'; import { useModal } from '@/providers/GlobalModalProvider'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const QuickSearchButton = ({ onClick, ...props diff --git a/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx b/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx index db3e1751f4..b4eef4ebfc 100644 --- a/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx +++ b/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx @@ -16,7 +16,7 @@ import { usePageHelper } from '@/hooks/use-page-helper'; import { useConfirm } from '@/providers/ConfirmProvider'; import useCurrentPageMeta from '@/hooks/use-current-page-meta'; import { toast } from '@/ui/toast'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; const PopoverContent = () => { const { editor } = useAppState(); const { toggleFavoritePage, toggleDeletePage } = usePageHelper(); diff --git a/packages/app/src/components/help-island/index.tsx b/packages/app/src/components/help-island/index.tsx index b904cefb5c..d6aad0c891 100644 --- a/packages/app/src/components/help-island/index.tsx +++ b/packages/app/src/components/help-island/index.tsx @@ -8,7 +8,7 @@ import { import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './Icons'; import Grow from '@mui/material/Grow'; import { Tooltip } from '@/ui/tooltip'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; import { useModal } from '@/providers/GlobalModalProvider'; import { useTheme } from '@/providers/ThemeProvider'; import useCurrentPageMeta from '@/hooks/use-current-page-meta'; diff --git a/packages/app/src/components/import/index.tsx b/packages/app/src/components/import/index.tsx index e296a7a0b9..df621a9c9e 100644 --- a/packages/app/src/components/import/index.tsx +++ b/packages/app/src/components/import/index.tsx @@ -6,7 +6,7 @@ import Loading from '@/components/loading'; import { usePageHelper } from '@/hooks/use-page-helper'; import { useAppState } from '@/providers/app-state-provider'; import { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; // import { Tooltip } from '@/ui/tooltip'; type ImportModalProps = { open: boolean; diff --git a/packages/app/src/components/page-list/OperationCell.tsx b/packages/app/src/components/page-list/OperationCell.tsx index d72b99b518..ca59efa60a 100644 --- a/packages/app/src/components/page-list/OperationCell.tsx +++ b/packages/app/src/components/page-list/OperationCell.tsx @@ -14,7 +14,7 @@ import { } from '@blocksuite/icons'; import { toast } from '@/ui/toast'; import { usePageHelper } from '@/hooks/use-page-helper'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { const { id, favorite } = pageMeta; const { openPage } = usePageHelper(); diff --git a/packages/app/src/components/page-list/index.tsx b/packages/app/src/components/page-list/index.tsx index 429ee6bbb9..2501f13bac 100644 --- a/packages/app/src/components/page-list/index.tsx +++ b/packages/app/src/components/page-list/index.tsx @@ -24,7 +24,7 @@ import { useAppState } from '@/providers/app-state-provider'; import { toast } from '@/ui/toast'; import { usePageHelper } from '@/hooks/use-page-helper'; import { useTheme } from '@/providers/ThemeProvider'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; const FavoriteTag = ({ pageMeta: { favorite, id }, }: { diff --git a/packages/app/src/components/quick-search/Footer.tsx b/packages/app/src/components/quick-search/Footer.tsx index 59680216f8..14b37561b6 100644 --- a/packages/app/src/components/quick-search/Footer.tsx +++ b/packages/app/src/components/quick-search/Footer.tsx @@ -4,7 +4,7 @@ import { StyledModalFooterContent } from './style'; import { useModal } from '@/providers/GlobalModalProvider'; import { Command } from 'cmdk'; import { usePageHelper } from '@/hooks/use-page-helper'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const Footer = (props: { query: string }) => { const { triggerQuickSearchModal } = useModal(); const { openPage, createPage } = usePageHelper(); diff --git a/packages/app/src/components/quick-search/Results.tsx b/packages/app/src/components/quick-search/Results.tsx index fc22e97136..a11206f339 100644 --- a/packages/app/src/components/quick-search/Results.tsx +++ b/packages/app/src/components/quick-search/Results.tsx @@ -7,7 +7,7 @@ import { useAppState } from '@/providers/app-state-provider'; import { useRouter } from 'next/router'; import { useSwitchToConfig } from './config'; import { NoResultSVG } from './NoResultSVG'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; import usePageHelper from '@/hooks/use-page-helper'; import usePageMetaList from '@/hooks/use-page-meta-list'; export const Results = (props: { diff --git a/packages/app/src/components/quick-search/config.ts b/packages/app/src/components/quick-search/config.ts index c35636c3cc..ce99ad5627 100644 --- a/packages/app/src/components/quick-search/config.ts +++ b/packages/app/src/components/quick-search/config.ts @@ -1,5 +1,5 @@ import { AllPagesIcon, FavouritesIcon, TrashIcon } from '@blocksuite/icons'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const useSwitchToConfig = ( currentWorkspaceId: string diff --git a/packages/app/src/components/shortcuts-modal/config.ts b/packages/app/src/components/shortcuts-modal/config.ts index 95dd4c5b63..02759297eb 100644 --- a/packages/app/src/components/shortcuts-modal/config.ts +++ b/packages/app/src/components/shortcuts-modal/config.ts @@ -1,4 +1,4 @@ -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; interface ShortcutTip { [x: string]: string; } @@ -13,7 +13,7 @@ export const useMacKeyboardShortcuts = (): ShortcutTip => { [t('Strikethrough')]: '⌘+⇧+S', [t('Inline code')]: ' ⌘+E', [t('Code block')]: '⌘+⌥+C', - [t('Hyperlink(with selected text)')]: '⌘+K', + [t('Link')]: '⌘+K', [t('Quick search')]: '⌘+K', [t('Body text')]: '⌘+⌥+0', [t('Heading', { number: '1' })]: '⌘+⌥+1', @@ -57,7 +57,7 @@ export const useWindowsKeyboardShortcuts = (): ShortcutTip => { [t('Strikethrough')]: 'Ctrl+Shift+S', [t('Inline code')]: ' Ctrl+E', [t('Code block')]: 'Ctrl+Alt+C', - [t('Hyperlink(with selected text)')]: 'Ctrl+K', + [t('Link')]: 'Ctrl+K', [t('Quick search')]: 'Ctrl+K', [t('Body text')]: 'Ctrl+Shift+0', [t('Heading', { number: '1' })]: 'Ctrl+Shift+1', diff --git a/packages/app/src/components/shortcuts-modal/index.tsx b/packages/app/src/components/shortcuts-modal/index.tsx index 980f281d78..280adeb7e6 100644 --- a/packages/app/src/components/shortcuts-modal/index.tsx +++ b/packages/app/src/components/shortcuts-modal/index.tsx @@ -16,7 +16,7 @@ import { import Slide from '@mui/material/Slide'; import { ModalCloseButton } from '@/ui/modal'; import { getUaHelper } from '@/utils'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; type ModalProps = { open: boolean; onClose: () => void; diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index a8a4ecb762..c6cb2f6e6a 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -20,7 +20,7 @@ import { useEffect } from 'react'; import { useAppState } from '@/providers/app-state-provider'; import { PageLoading } from '@/components/loading'; import Head from 'next/head'; -import '@/libs/i18n'; +import '@affine/i18n'; import TemporaryHelperProvider from '@/providers/temporary-helper-provider'; const ThemeProvider = dynamic(() => import('@/providers/ThemeProvider'), { diff --git a/packages/app/src/pages/workspace/[workspaceId]/all.tsx b/packages/app/src/pages/workspace/[workspaceId]/all.tsx index 18f6e2a64b..155a4303e5 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/all.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/all.tsx @@ -4,7 +4,7 @@ import usePageMetaList from '@/hooks/use-page-meta-list'; import { PageListHeader } from '@/components/header'; import { ReactElement } from 'react'; import WorkspaceLayout from '@/components/workspace-layout'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; const All = () => { const pageMetaList = usePageMetaList(); const { t } = useTranslation(); diff --git a/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx b/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx index d787f34e1b..bc64db309a 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx @@ -4,7 +4,7 @@ import { FavouritesIcon } from '@blocksuite/icons'; import usePageMetaList from '@/hooks/use-page-meta-list'; import { ReactElement } from 'react'; import WorkspaceLayout from '@/components/workspace-layout'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const Favorite = () => { const pageMetaList = usePageMetaList(); const { t } = useTranslation(); diff --git a/packages/app/src/pages/workspace/[workspaceId]/trash.tsx b/packages/app/src/pages/workspace/[workspaceId]/trash.tsx index 2343b39138..07fa7ea1f4 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/trash.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/trash.tsx @@ -4,7 +4,7 @@ import { TrashIcon } from '@blocksuite/icons'; import usePageMetaList from '@/hooks/use-page-meta-list'; import { ReactElement } from 'react'; import WorkspaceLayout from '@/components/workspace-layout'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export const Trash = () => { const pageMetaList = usePageMetaList(); const { t } = useTranslation(); diff --git a/packages/app/src/ui/confirm/Confirm.tsx b/packages/app/src/ui/confirm/Confirm.tsx index dee4953812..1c22e16021 100644 --- a/packages/app/src/ui/confirm/Confirm.tsx +++ b/packages/app/src/ui/confirm/Confirm.tsx @@ -7,7 +7,7 @@ import { StyledModalWrapper, } from '@/ui/confirm/styles'; import { Button } from '@/ui/button'; -import { useTranslation } from 'react-i18next'; +import { useTranslation } from '@affine/i18n'; export type ConfirmProps = { title?: string; content?: string; diff --git a/packages/i18n/package.json b/packages/i18n/package.json new file mode 100644 index 0000000000..cc559528e3 --- /dev/null +++ b/packages/i18n/package.json @@ -0,0 +1,29 @@ +{ + "name": "@affine/i18n", + "version": "0.1.0", + "description": "", + "main": "dist/src/index.js", + "type": "module", + "types": "dist/src/index.d.ts", + "exports": { + "./src/*": "./dist/src/*.js", + ".": "./dist/src/index.js" + }, + "scripts": { + "build": "tsc --project ./tsconfig.json" + }, + "keywords": [], + "repository": { + "type": "git", + "url": "git+https://github.com/toeverything/AFFiNE.git" + }, + "dependencies": { + "i18next": "^21.9.1", + "prettier": "^2.7.1", + "react-i18next": "^11.18.4" + }, + "devDependencies": { + "@types/prettier": "^2.7.2", + "typescript": "^4.8.4" + } +} diff --git a/packages/app/src/libs/i18n/index.ts b/packages/i18n/src/index.ts similarity index 86% rename from packages/app/src/libs/i18n/index.ts rename to packages/i18n/src/index.ts index fe6d76ab41..a3fd46a1d2 100644 --- a/packages/app/src/libs/i18n/index.ts +++ b/packages/i18n/src/index.ts @@ -1,10 +1,6 @@ import i18next, { Resource } from 'i18next'; -import { - I18nextProvider, - initReactI18next, - useTranslation, -} from 'react-i18next'; -import { LOCALES } from './resources'; +import { initReactI18next, useTranslation } from 'react-i18next'; +import { LOCALES } from './resources/index.js'; import type en_US from './resources/en.json'; // const localStorage = { @@ -27,7 +23,7 @@ declare module 'react-i18next' { // const STORAGE_KEY = 'i18n_lng'; -export { i18n, useTranslation, I18nProvider, LOCALES }; +export { i18n, useTranslation, LOCALES }; const resources = LOCALES.reduce( (acc, { tag, res }) => ({ ...acc, [tag]: { translation: res } }), @@ -63,4 +59,4 @@ i18n.on('languageChanged', () => { // localStorage.setItem(STORAGE_KEY, lng); }); -const I18nProvider = I18nextProvider; +// const I18nProvider = I18nextProvider; diff --git a/packages/app/src/libs/i18n/resources/bn.json b/packages/i18n/src/resources/bn.json similarity index 100% rename from packages/app/src/libs/i18n/resources/bn.json rename to packages/i18n/src/resources/bn.json diff --git a/packages/app/src/libs/i18n/resources/en.json b/packages/i18n/src/resources/en.json similarity index 97% rename from packages/app/src/libs/i18n/resources/en.json rename to packages/i18n/src/resources/en.json index a72a198ace..78dcb2fb28 100644 --- a/packages/app/src/libs/i18n/resources/en.json +++ b/packages/i18n/src/resources/en.json @@ -54,7 +54,7 @@ "Strikethrough": "Strikethrough", "Inline code": "Inline code", "Code block": "Code block", - "Hyperlink(with selected text)": "Hyperlink(with selected text)", + "Link": "Hyperlink(with selected text)", "Body text": "Body text", "Heading": "Heading {{number}}", "Increase indent": "Increase indent", diff --git a/packages/app/src/libs/i18n/resources/fr.json b/packages/i18n/src/resources/fr.json similarity index 100% rename from packages/app/src/libs/i18n/resources/fr.json rename to packages/i18n/src/resources/fr.json diff --git a/packages/app/src/libs/i18n/resources/index.ts b/packages/i18n/src/resources/index.ts similarity index 100% rename from packages/app/src/libs/i18n/resources/index.ts rename to packages/i18n/src/resources/index.ts diff --git a/packages/app/src/libs/i18n/resources/sr.json b/packages/i18n/src/resources/sr.json similarity index 100% rename from packages/app/src/libs/i18n/resources/sr.json rename to packages/i18n/src/resources/sr.json diff --git a/packages/app/src/libs/i18n/resources/zh-Hans.json b/packages/i18n/src/resources/zh-Hans.json similarity index 100% rename from packages/app/src/libs/i18n/resources/zh-Hans.json rename to packages/i18n/src/resources/zh-Hans.json diff --git a/packages/app/src/libs/i18n/resources/zh-Hant.json b/packages/i18n/src/resources/zh-Hant.json similarity index 100% rename from packages/app/src/libs/i18n/resources/zh-Hant.json rename to packages/i18n/src/resources/zh-Hant.json diff --git a/scripts/i18n/api.ts b/packages/i18n/src/script/api.ts similarity index 85% rename from scripts/i18n/api.ts rename to packages/i18n/src/script/api.ts index 0cd1a156b4..ae286fe584 100644 --- a/scripts/i18n/api.ts +++ b/packages/i18n/src/script/api.ts @@ -43,7 +43,19 @@ import { fetchTolgee } from './request'; * ] * ``` */ -export const getAllProjectLanguages = async (size = 1000) => { + +export const getAllProjectLanguages = async ( + size = 1000 +): Promise< + { + id: number; + name: string; + tag: string; + originalName: string; + flagEmoji: string; + base: boolean; + }[] +> => { const url = `/languages?size=${size}`; const resp = await fetchTolgee(url); if (resp.status < 200 || resp.status >= 300) { @@ -70,7 +82,7 @@ export const getAllProjectLanguages = async (size = 1000) => { * * See https://tolgee.io/api#operation/getTranslations_ */ -export const getTranslations = async () => { +export const getTranslations = async (): Promise => { const url = '/translations'; const resp = await fetchTolgee(url); if (resp.status < 200 || resp.status >= 300) { @@ -87,17 +99,19 @@ export const getTranslations = async () => { */ export const getLanguagesTranslations = async ( languages: T -) => { +): Promise<{ [key in T]?: Record }> => { const url = `/translations/${languages}`; const resp = await fetchTolgee(url); if (resp.status < 200 || resp.status >= 300) { throw new Error(url + ' ' + resp.status + '\n' + (await resp.text())); } - const json: { [key in T]?: Record } = await resp.json(); + const json = await resp.json(); return json; }; -export const getRemoteTranslations = async (languages: string) => { +export const getRemoteTranslations = async ( + languages: string +): Promise> => { const translations = await getLanguagesTranslations(languages); if (!(languages in translations)) { return {}; @@ -115,7 +129,7 @@ export const getRemoteTranslations = async (languages: string) => { export const createsNewKey = async ( key: string, translations: Record -) => { +): Promise => { const url = '/translations/keys/create'; const resp = await fetchTolgee(url, { method: 'POST', @@ -133,7 +147,10 @@ export const createsNewKey = async ( * * See https://tolgee.io/api#operation/tagKey_1 */ -export const addTag = async (keyId: string, tagName: string) => { +export const addTag = async ( + keyId: string, + tagName: string +): Promise => { const url = `/keys/${keyId}/tags`; const resp = await fetchTolgee(url, { method: 'PUT', @@ -151,7 +168,10 @@ export const addTag = async (keyId: string, tagName: string) => { * * See https://tolgee.io/api#operation/tagKey_1 */ -export const removeTag = async (keyId: string, tagId: number) => { +export const removeTag = async ( + keyId: string, + tagId: number +): Promise => { const url = `/keys/${keyId}/tags/${tagId}`; const resp = await fetchTolgee(url, { method: 'DELETE', @@ -174,7 +194,7 @@ export const removeTag = async (keyId: string, tagId: number) => { * * See https://tolgee.io/api#operation/export_1 */ -export const exportResources = async () => { +export const exportResources = async (): Promise => { const url = `/export`; const resp = await fetchTolgee(url); diff --git a/scripts/i18n/download.ts b/packages/i18n/src/script/download.ts similarity index 100% rename from scripts/i18n/download.ts rename to packages/i18n/src/script/download.ts diff --git a/scripts/i18n/request.ts b/packages/i18n/src/script/request.ts similarity index 100% rename from scripts/i18n/request.ts rename to packages/i18n/src/script/request.ts diff --git a/scripts/i18n/sync.ts b/packages/i18n/src/script/sync.ts similarity index 100% rename from scripts/i18n/sync.ts rename to packages/i18n/src/script/sync.ts diff --git a/scripts/i18n/utils.ts b/packages/i18n/src/script/utils.ts similarity index 100% rename from scripts/i18n/utils.ts rename to packages/i18n/src/script/utils.ts diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json new file mode 100644 index 0000000000..e13f7340ab --- /dev/null +++ b/packages/i18n/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": false, + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "experimentalDecorators": true, + "declaration": true, + "baseUrl": ".", + "rootDir": ".", + "outDir": "./dist" + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ffe15f76e..fbcb7ea1dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,7 @@ importers: packages/app: specifiers: '@affine/datacenter': workspace:* + '@affine/i18n': workspace:* '@blocksuite/blocks': 0.3.1-20230109032243-37ad3ba '@blocksuite/editor': 0.3.1-20230109032243-37ad3ba '@blocksuite/icons': ^2.0.2 @@ -71,7 +72,6 @@ importers: eslint-config-next: 12.3.1 eslint-config-prettier: ^8.5.0 eslint-plugin-prettier: ^4.2.1 - i18next: ^21.9.1 lit: ^2.3.1 next: 13.1.0 next-debug-local: ^0.1.5 @@ -82,11 +82,11 @@ importers: raw-loader: ^4.0.2 react: 18.2.0 react-dom: 18.2.0 - react-i18next: ^11.18.4 typescript: 4.8.3 yjs: ^13.5.44 dependencies: '@affine/datacenter': link:../data-center + '@affine/i18n': link:../i18n '@blocksuite/blocks': 0.3.1-20230109032243-37ad3ba_yjs@13.5.44 '@blocksuite/editor': 0.3.1-20230109032243-37ad3ba_yjs@13.5.44 '@blocksuite/icons': 2.0.4_w5j4k42lgipnm43s3brx6h3c34 @@ -104,7 +104,6 @@ importers: cmdk: 0.1.21_7ey2zzynotv32rpkwno45fsx4e css-spring: 4.1.0 dayjs: 1.11.7 - i18next: 21.10.0 lit: 2.4.0 next: 13.1.0_biqbaboplfbrettd7655fr4n2y next-debug-local: 0.1.5 @@ -113,7 +112,6 @@ importers: quill-cursors: 4.0.0 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-i18next: 11.18.6_vfm63zmruocgezzfl2v26zlzpy yjs: 13.5.44 devDependencies: '@types/node': 18.7.18 @@ -168,6 +166,21 @@ importers: fake-indexeddb: 4.0.1 typescript: 4.9.3 + packages/i18n: + specifiers: + '@types/prettier': ^2.7.2 + i18next: ^21.9.1 + prettier: ^2.7.1 + react-i18next: ^11.18.4 + typescript: ^4.8.4 + dependencies: + i18next: 21.10.0 + prettier: 2.7.1 + react-i18next: 11.18.6_i18next@21.10.0 + devDependencies: + '@types/prettier': 2.7.2 + typescript: 4.9.3 + packages/logger: specifiers: '@types/react': ^18.0.21 @@ -1407,6 +1420,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.9 + dev: false /@babel/runtime/7.20.7: resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} @@ -1754,7 +1768,7 @@ packages: dependencies: '@babel/helper-module-imports': 7.18.6 '@babel/plugin-syntax-jsx': 7.18.6 - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@emotion/hash': 0.9.0 '@emotion/memoize': 0.8.0 '@emotion/serialize': 1.1.0 @@ -3063,7 +3077,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@mui/utils': 5.10.9_react@18.2.0 '@types/react': 18.0.20 prop-types: 15.8.1 @@ -3083,7 +3097,7 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@emotion/cache': 11.10.3 '@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34 '@emotion/styled': 11.10.4_yiaqs725o7pcd7rteavrnhgj4y @@ -3108,7 +3122,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34 '@emotion/styled': 11.10.4_yiaqs725o7pcd7rteavrnhgj4y '@mui/private-theming': 5.10.9_w5j4k42lgipnm43s3brx6h3c34 @@ -3139,7 +3153,7 @@ packages: peerDependencies: react: ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@types/prop-types': 15.7.5 '@types/react-is': 17.0.3 prop-types: 15.8.1 @@ -4300,7 +4314,7 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@babel/runtime-corejs3': 7.19.1 dev: true @@ -4450,7 +4464,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 cosmiconfig: 7.0.1 resolve: 1.22.1 dev: false @@ -5116,7 +5130,7 @@ packages: /dom-helpers/5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 csstype: 3.1.1 dev: false @@ -5523,7 +5537,7 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 aria-query: 4.2.2 array-includes: 3.1.5 ast-types-flow: 0.0.7 @@ -5545,7 +5559,7 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 aria-query: 4.2.2 array-includes: 3.1.5 ast-types-flow: 0.0.7 @@ -6431,7 +6445,7 @@ packages: /i18next/21.10.0: resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==} dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 dev: false /iconv-lite/0.4.24: @@ -8270,6 +8284,7 @@ packages: /prettier/2.7.1: resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} engines: {node: '>=10.13.0'} + hasBin: true /pretty-bytes/5.6.0: resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} @@ -8413,7 +8428,7 @@ packages: react: 18.2.0 scheduler: 0.23.0 - /react-i18next/11.18.6_vfm63zmruocgezzfl2v26zlzpy: + /react-i18next/11.18.6_i18next@21.10.0: resolution: {integrity: sha512-yHb2F9BiT0lqoQDt8loZ5gWP331GwctHz9tYQ8A2EIEUu+CcEdjBLQWli1USG3RdWQt3W+jqQLg/d4rrQR96LA==} peerDependencies: i18next: '>= 19.0.0' @@ -8426,11 +8441,9 @@ packages: react-native: optional: true dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 html-parse-stringify: 3.0.1 i18next: 21.10.0 - react: 18.2.0 - react-dom: 18.2.0_react@18.2.0 dev: false /react-is/16.13.1: @@ -8497,7 +8510,7 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -9893,7 +9906,7 @@ packages: '@apideck/better-ajv-errors': 0.3.6_ajv@8.11.2 '@babel/core': 7.20.5 '@babel/preset-env': 7.20.2_@babel+core@7.20.5 - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@rollup/plugin-babel': 5.3.1_opjstonlpkhafnz76jsxdwq25a '@rollup/plugin-node-resolve': 11.2.1_rollup@2.79.1 '@rollup/plugin-replace': 2.4.2_rollup@2.79.1