From 220dbfbfb0707302aff3f7e1718a55545864f6b5 Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Mon, 3 Mar 2025 11:30:25 +0800 Subject: [PATCH 1/4] feat(configprovider): support provider for RC --- package.json | 3 +- src/blockHeader/index.tsx | 5 ++- src/configProvider/index.tsx | 53 +++++++++++++++++++++++++++++++ src/copy/index.tsx | 6 ++-- src/dropdown/select.tsx | 9 ++++-- src/errorBoundary/loadError.tsx | 12 ++++--- src/fullscreen/index.tsx | 7 ++++- src/globalLoading/index.tsx | 5 ++- src/index.ts | 3 ++ src/input/match.tsx | 45 ++++++++++++++------------ src/locale/en-US.ts | 56 +++++++++++++++++++++++++++++++++ src/locale/useLocale.tsx | 26 +++++++++++++++ src/locale/zh-CN.ts | 50 +++++++++++++++++++++++++++++ src/modal/form.tsx | 7 +++-- src/mxGraph/index.tsx | 5 ++- src/notFound/index.tsx | 4 ++- src/spreadSheet/index.tsx | 9 ++++-- 17 files changed, 264 insertions(+), 41 deletions(-) create mode 100644 src/configProvider/index.tsx create mode 100644 src/locale/en-US.ts create mode 100644 src/locale/useLocale.tsx create mode 100644 src/locale/zh-CN.ts diff --git a/package.json b/package.json index e2e14dab8..4c44191c6 100644 --- a/package.json +++ b/package.json @@ -133,5 +133,6 @@ }, "resolutions": { "rc-motion": "2.6.2" - } + }, + "packageManager": "pnpm@6.32.12" } diff --git a/src/blockHeader/index.tsx b/src/blockHeader/index.tsx index aa022e15b..72813b6f4 100644 --- a/src/blockHeader/index.tsx +++ b/src/blockHeader/index.tsx @@ -3,6 +3,7 @@ import { QuestionCircleOutlined, UpOutlined } from '@ant-design/icons'; import { Tooltip } from 'antd'; import classNames from 'classnames'; +import useLocale from '../locale/useLocale'; import './style.scss'; export declare type SizeType = 'small' | 'middle' | undefined; @@ -59,6 +60,8 @@ const BlockHeader: React.FC = function (props) { const [expand, setExpand] = useState(defaultExpand); + const locale = useLocale('BlockHeader'); + const preTitleRowCls = `${prefixCls}-title-row`; const questionTooltip = tooltip && ( @@ -103,7 +106,7 @@ const BlockHeader: React.FC = function (props) { {addonAfter &&
{addonAfter}
} {children && (
-
{expand ? '收起' : '展开'}
+
{expand ? locale.collapse : locale.expand}
)} diff --git a/src/configProvider/index.tsx b/src/configProvider/index.tsx new file mode 100644 index 000000000..c54c22463 --- /dev/null +++ b/src/configProvider/index.tsx @@ -0,0 +1,53 @@ +import React, { createContext } from 'react'; + +export interface Locale { + locale: string; + BlockHeader: { expand: string; collapse: string }; + Copy: { copied: string; copy: string }; + Dropdown: { selectAll: string; resetText: string; okText: string }; + Fullscreen: { exitFull: string; full: string }; + GlobalLoading: { loading: string }; + Input: { + case: string; + precise: string; + front: string; + tail: string; + }; + LoadError: { + please: string; + get: string; + refresh: string; + title: string; + }; + Modal: { + okText: string; + cancelText: string; + }; + MxGraph: { newNode: string }; + NotFound: { + description: string; + }; + SpreadSheet: { + description: string; + copy: string; + copyAll: string; + }; +} + +export interface LocaleContextProps { + locale: Locale; +} + +export const LocaleContext = createContext({ locale: {} as Locale }); + +const ConfigProvider = ({ + locale, + children, +}: { + locale: LocaleContextProps; + children: React.ReactNode; +}) => { + return {children}; +}; + +export default ConfigProvider; diff --git a/src/copy/index.tsx b/src/copy/index.tsx index 9622e930e..b7b85f792 100644 --- a/src/copy/index.tsx +++ b/src/copy/index.tsx @@ -4,6 +4,7 @@ import { message, Tooltip } from 'antd'; import classNames from 'classnames'; import useClippy from 'use-clippy'; +import useLocale from '../locale/useLocale'; import './style.scss'; export interface ICopyProps { @@ -17,14 +18,15 @@ export interface ICopyProps { } const Copy: React.FC = (props) => { + const locale = useLocale('Copy'); const { button = , text, - title = '复制', + title = locale.copy, hideTooltip, style, className, - onCopy = () => message.success('复制成功'), + onCopy = () => message.success(locale.copied), } = props; const [_, setClipboard] = useClippy(); diff --git a/src/dropdown/select.tsx b/src/dropdown/select.tsx index b0b6323a1..8b420894a 100644 --- a/src/dropdown/select.tsx +++ b/src/dropdown/select.tsx @@ -6,6 +6,7 @@ import classNames from 'classnames'; import { isEqual } from 'lodash'; import List from 'rc-virtual-list'; +import useLocale from '../locale/useLocale'; import './style.scss'; interface IDropdownSelectProps @@ -31,6 +32,8 @@ export default function Select({ }: IDropdownSelectProps) { const [visible, setVisible] = useState(false); + const locale = useLocale('Dropdown'); + const handleCheckedAll = (e: CheckboxChangeEvent) => { if (e.target.checked) { onChange?.(options?.map((i) => i.value) || []); @@ -119,7 +122,7 @@ export default function Select({ checked={checkAll} indeterminate={indeterminate} > - 全选 + {locale.selectAll} @@ -158,10 +161,10 @@ export default function Select({ diff --git a/src/errorBoundary/loadError.tsx b/src/errorBoundary/loadError.tsx index 8d75380d2..b10fbd491 100644 --- a/src/errorBoundary/loadError.tsx +++ b/src/errorBoundary/loadError.tsx @@ -1,22 +1,24 @@ import React from 'react'; +import useLocale from '../locale/useLocale'; + const LoadError: React.FC = function () { + const locale = useLocale('LoadError'); return (
- 

- 发现新版本,请 + {locale.please} { location.reload(); }} > - 刷新 + {locale.refresh} - 获取新版本。 + {locale.get}

-

若该提示长时间存在,请联系管理员。

+

{locale.title}

); diff --git a/src/fullscreen/index.tsx b/src/fullscreen/index.tsx index ece3b7502..97b5ea09f 100644 --- a/src/fullscreen/index.tsx +++ b/src/fullscreen/index.tsx @@ -2,6 +2,7 @@ import React, { CSSProperties, HTMLAttributes, ReactNode, useEffect, useState } import { Button } from 'antd'; import KeyEventListener from '../keyEventListener'; +import useLocale from '../locale/useLocale'; import MyIcon from './icon'; const { KeyCombiner } = KeyEventListener; @@ -44,7 +45,11 @@ export default function Fullscreen({ ...other }: IFullscreenProps) { const [isFullScreen, setIsFullScreen] = useState(false); + + const locale = useLocale('Fullscreen'); + const customIcon = isFullScreen ? exitFullIcon : fullIcon; + useEffect(() => { const propsDom = document.getElementById(target); const domEle = propsDom || document.body; @@ -188,7 +193,7 @@ export default function Fullscreen({ ) : ( )} diff --git a/src/globalLoading/index.tsx b/src/globalLoading/index.tsx index 1269cf757..9cc2ff50b 100644 --- a/src/globalLoading/index.tsx +++ b/src/globalLoading/index.tsx @@ -1,6 +1,7 @@ import React from 'react'; import classNames from 'classnames'; +import useLocale from '../locale/useLocale'; import './style.scss'; export interface IGlobalLoadingProps { @@ -12,8 +13,10 @@ export interface IGlobalLoadingProps { } const GlobalLoading: React.FC = function (props) { + const locale = useLocale('GlobalLoading'); + const { - loadingTitle = '应用加载中,请等候~', + loadingTitle = locale.loading, mainBackground = '#F2F7FA', circleBackground = '#1D78FF', titleColor = '#3D446E', diff --git a/src/index.ts b/src/index.ts index e284f6601..5c0822dde 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ export { default as BlockHeader } from './blockHeader'; export { default as CollapsibleActionItems } from './collapsibleActionItems'; +export { default as ConfigProvider } from './configProvider'; export { default as ContextMenu } from './contextMenu'; export { default as useCookieListener } from './cookies'; export { default as Copy } from './copy'; @@ -13,6 +14,8 @@ export { default as Fullscreen } from './fullscreen'; export { default as GlobalLoading } from './globalLoading'; export { default as Input } from './input'; export { default as KeyEventListener } from './keyEventListener'; +export { default as enUS } from './locale/en-US'; +export { default as zhCN } from './locale/zh-CN'; export { default as MarkdownRender } from './markdownRender'; export { default as Modal } from './modal'; export { default as MxGraphContainer, WIDGETS_PREFIX } from './mxGraph'; diff --git a/src/input/match.tsx b/src/input/match.tsx index a13c1c176..020ee844e 100644 --- a/src/input/match.tsx +++ b/src/input/match.tsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import { Input, type InputProps, Tooltip } from 'antd'; import classNames from 'classnames'; +import useLocale from '../locale/useLocale'; import { CaseSensitiveIcon, FrontIcon, PreciseIcon, TailIcon } from './icons'; import './match.scss'; @@ -29,30 +30,11 @@ interface IMatchProps extends Omit { onSearch?: (value: string, searchType: SearchType) => void; } -const searchTypeList = [ - { - key: 'caseSensitive', - tip: '区分大小写匹配', - }, - { - key: 'precise', - tip: '精确匹配', - }, - { - key: 'front', - tip: '头部匹配', - }, - { - key: 'tail', - tip: '尾部匹配', - }, -] as const; - export default function Match({ className, value, searchType, - filterOptions = searchTypeList.map((i) => i.key), + filterOptions: propFilterOptions, onTypeChange, onSearch, onChange, @@ -62,12 +44,35 @@ export default function Match({ const [internalValue, setValue] = useState(''); const [internalSearchType, setSearchType] = useState('fuzzy'); + const locale = useLocale('Input'); + const handleTypeChange = (key: SearchType) => { const next = realSearchType === key ? 'fuzzy' : key; onTypeChange?.(next); setSearchType(next); }; + const searchTypeList = [ + { + key: 'caseSensitive', + tip: locale.case, + }, + { + key: 'precise', + tip: locale.precise, + }, + { + key: 'front', + tip: locale.front, + }, + { + key: 'tail', + tip: locale.tail, + }, + ] as const; + + const filterOptions = propFilterOptions || searchTypeList.map((i) => i.key); + const options = searchTypeList.filter((i) => filterOptions.includes(i.key)); const realSearchType = searchType || internalSearchType; diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts new file mode 100644 index 000000000..6bce717b5 --- /dev/null +++ b/src/locale/en-US.ts @@ -0,0 +1,56 @@ +import { Locale } from '../configProvider'; + +const localeValues: Locale = { + locale: 'en-US', + BlockHeader: { + expand: 'Expand', + collapse: 'Collapse', + }, + + Copy: { + copied: 'Copied', + + copy: 'Copy', + }, + Fullscreen: { + exitFull: 'Exit Full Screen', + full: 'Full Screen', + }, + GlobalLoading: { + loading: 'The application is loading, please wait~', + }, + LoadError: { + please: 'A new version has been found. Please', + get: 'to get the new version.', + refresh: 'refresh', + title: 'If this prompt persists for a long time, please contact the administrator.', + }, + Modal: { + okText: 'Ok', + cancelText: 'Cancel', + }, + Dropdown: { + resetText: 'Cancel', + okText: 'Ok', + selectAll: 'Select All', + }, + Input: { + case: 'Case-sensitive match', + precise: 'Exact match', + front: 'Head match', + tail: 'Tail match', + }, + MxGraph: { + newNode: 'New node', + }, + NotFound: { + description: 'Dear, did you go to the wrong place?', + }, + SpreadSheet: { + description: 'No Data', + copy: 'Copy', + copyAll: 'Copy values ​​and column names', + }, +}; + +export default localeValues; diff --git a/src/locale/useLocale.tsx b/src/locale/useLocale.tsx new file mode 100644 index 000000000..01828c633 --- /dev/null +++ b/src/locale/useLocale.tsx @@ -0,0 +1,26 @@ +import { useContext, useMemo } from 'react'; + +import type { Locale, LocaleContextProps } from '../configProvider'; +import { LocaleContext } from '../configProvider'; +import defaultLocaleData from './zh-CN'; + +export type LocaleComponentName = keyof Locale; + +const useLocale = ( + componentName: C +): NonNullable => { + const fullLocale = useContext(LocaleContext); + + const getLocale = useMemo(() => { + const locale = defaultLocaleData[componentName] ?? {}; + const localeFromContext = fullLocale?.[componentName as keyof LocaleContextProps] ?? {}; + return { + ...(locale as unknown as object), + ...(localeFromContext as unknown as object), + } as NonNullable; + }, [componentName, fullLocale]); + + return getLocale; +}; + +export default useLocale; diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts new file mode 100644 index 000000000..f2d5f5d96 --- /dev/null +++ b/src/locale/zh-CN.ts @@ -0,0 +1,50 @@ +import { Locale } from '../configProvider'; + +const localeValues: Locale = { + locale: 'zh-CN', + BlockHeader: { + expand: '展开', + collapse: '收起', + }, + Copy: { + copied: '复制成功', + copy: '复制', + }, + Dropdown: { selectAll: '全选', resetText: '重置', okText: '确定' }, + Fullscreen: { + exitFull: '退出全屏', + full: '全屏', + }, + GlobalLoading: { + loading: '应用加载中,请等候~', + }, + LoadError: { + please: '发现新版本,请', + get: '获取新版本。', + refresh: '刷新', + title: '若该提示长时间存在,请联系管理员。', + }, + Input: { + case: '区分大小写匹配', + precise: '精确匹配', + front: '头部匹配', + tail: '尾部匹配', + }, + Modal: { + okText: '确定', + cancelText: '取消', + }, + MxGraph: { + newNode: '新节点', + }, + NotFound: { + description: '亲,是不是走错地方了?', + }, + SpreadSheet: { + description: '暂无数据', + copy: '复制', + copyAll: '复制值以及列名', + }, +}; + +export default localeValues; diff --git a/src/modal/form.tsx b/src/modal/form.tsx index f0dfcf518..885e2efd0 100644 --- a/src/modal/form.tsx +++ b/src/modal/form.tsx @@ -2,6 +2,7 @@ import React, { ReactElement, useMemo } from 'react'; import { FormProps, Modal, ModalProps } from 'antd'; import Form from '../form'; +import useLocale from '../locale/useLocale'; import Utils from '../utils'; import { FORM_PROPS, MODAL_PROPS } from '../utils/antdProps'; @@ -23,9 +24,11 @@ export interface IModalFormProps } const ModalForm = (props: IModalFormProps) => { + const locale = useLocale('Modal'); + const { - okText = '确定', - cancelText = '取消', + okText = locale.okText, + cancelText = locale.cancelText, layout = 'vertical', maskClosable = false, children, diff --git a/src/mxGraph/index.tsx b/src/mxGraph/index.tsx index 2822141fd..38ee86fc6 100644 --- a/src/mxGraph/index.tsx +++ b/src/mxGraph/index.tsx @@ -20,6 +20,7 @@ import { mxPopupMenuHandler, } from 'mxgraph'; +import useLocale from '../locale/useLocale'; import MxFactory from './factory'; import './style.scss'; @@ -293,6 +294,8 @@ function MxGraphContainer( const keybindingsRef = useRef([]); const [current, setCurrent] = useState(null); + const locale = useLocale('MxGraph'); + useImperativeHandle(ref, () => ({ /** * 在某一位置插入节点 @@ -427,7 +430,7 @@ function MxGraphContainer( onGetPreview?.(node) || (() => { const dom = document.createElement('div'); - dom.innerHTML = `新节点`; + dom.innerHTML = `${locale.newNode}`; return dom; })(); diff --git a/src/notFound/index.tsx b/src/notFound/index.tsx index 67fb6d00c..08cd61952 100644 --- a/src/notFound/index.tsx +++ b/src/notFound/index.tsx @@ -1,13 +1,15 @@ import React from 'react'; import { FrownOutlined } from '@ant-design/icons'; +import useLocale from '../locale/useLocale'; import './style.scss'; const NotFound: React.FC = function () { + const locale = useLocale('NotFound'); return (

- 亲,是不是走错地方了? + {locale.description}

); diff --git a/src/spreadSheet/index.tsx b/src/spreadSheet/index.tsx index 6086683f9..1487922de 100644 --- a/src/spreadSheet/index.tsx +++ b/src/spreadSheet/index.tsx @@ -4,6 +4,7 @@ import { HotTable } from '@handsontable/react'; import classNames from 'classnames'; import 'handsontable/languages/zh-CN.js'; +import useLocale from '../locale/useLocale'; import CopyUtils from '../utils/copy'; import 'handsontable/dist/handsontable.full.css'; import './style.scss'; @@ -33,6 +34,8 @@ const SpreadSheet: React.FC = forwardRef( const tableRef = useRef(null); const copyUtils = new CopyUtils(); const _timer = useRef(); + const locale = useLocale('SpreadSheet'); + const { showCopyWithHeader, ...restProps } = options || {}; useImperativeHandle(ref, () => ({ tableRef, @@ -57,7 +60,7 @@ const SpreadSheet: React.FC = forwardRef( let showData = data; if (!showData?.length) { const emptyArr = new Array(columns.length).fill('', 0, columns.length); - emptyArr[0] = '暂无数据'; + emptyArr[0] = locale.description; showData = [emptyArr]; } return showData; @@ -91,7 +94,7 @@ const SpreadSheet: React.FC = forwardRef( const getContextMenu = () => { const items: Record = { copy: { - name: '复制', + name: locale.copy, callback: function (this: any, _key: any) { const indexArr = this.getSelected(); // eslint-disable-next-line prefer-spread @@ -102,7 +105,7 @@ const SpreadSheet: React.FC = forwardRef( }; if (showCopyWithHeader) { const copyWithHeaderItem = { - name: '复制值以及列名', + name: locale.copyAll, callback: function (this: any, _key: any, selection: any) { const indexArr = this.getSelected(); // eslint-disable-next-line prefer-spread From 9e6ec7a2dda2e821b870d1cf68a244bcb1fce2c9 Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Mon, 6 Jan 2025 19:12:10 +0800 Subject: [PATCH 2/4] feat(configprovider): migrate locale type to useLocale --- src/configProvider/index.tsx | 42 ++-------------------------------- src/locale/useLocale.tsx | 44 +++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/configProvider/index.tsx b/src/configProvider/index.tsx index c54c22463..45430d7ad 100644 --- a/src/configProvider/index.tsx +++ b/src/configProvider/index.tsx @@ -1,44 +1,6 @@ -import React, { createContext } from 'react'; +import React from 'react'; -export interface Locale { - locale: string; - BlockHeader: { expand: string; collapse: string }; - Copy: { copied: string; copy: string }; - Dropdown: { selectAll: string; resetText: string; okText: string }; - Fullscreen: { exitFull: string; full: string }; - GlobalLoading: { loading: string }; - Input: { - case: string; - precise: string; - front: string; - tail: string; - }; - LoadError: { - please: string; - get: string; - refresh: string; - title: string; - }; - Modal: { - okText: string; - cancelText: string; - }; - MxGraph: { newNode: string }; - NotFound: { - description: string; - }; - SpreadSheet: { - description: string; - copy: string; - copyAll: string; - }; -} - -export interface LocaleContextProps { - locale: Locale; -} - -export const LocaleContext = createContext({ locale: {} as Locale }); +import { LocaleContext, LocaleContextProps } from '../locale/useLocale'; const ConfigProvider = ({ locale, diff --git a/src/locale/useLocale.tsx b/src/locale/useLocale.tsx index 01828c633..2209e1cf1 100644 --- a/src/locale/useLocale.tsx +++ b/src/locale/useLocale.tsx @@ -1,9 +1,47 @@ -import { useContext, useMemo } from 'react'; +import { createContext, useContext, useMemo } from 'react'; -import type { Locale, LocaleContextProps } from '../configProvider'; -import { LocaleContext } from '../configProvider'; import defaultLocaleData from './zh-CN'; +export interface Locale { + locale: string; + BlockHeader: { expand: string; collapse: string }; + Copy: { copied: string; copy: string }; + Dropdown: { selectAll: string; resetText: string; okText: string }; + Fullscreen: { exitFull: string; full: string }; + GlobalLoading: { loading: string }; + Input: { + case: string; + precise: string; + front: string; + tail: string; + }; + LoadError: { + please: string; + get: string; + refresh: string; + title: string; + }; + Modal: { + okText: string; + cancelText: string; + }; + MxGraph: { newNode: string }; + NotFound: { + description: string; + }; + SpreadSheet: { + description: string; + copy: string; + copyAll: string; + }; +} + +export interface LocaleContextProps { + locale: Locale; +} + +export const LocaleContext = createContext({ locale: {} as Locale }); + export type LocaleComponentName = keyof Locale; const useLocale = ( From 598da5227f23be98bf84e8e3958d4bf81b3ebc3d Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Mon, 3 Mar 2025 14:17:08 +0800 Subject: [PATCH 3/4] fix(configprovider): fix unit test error --- src/locale/en-US.ts | 2 +- src/locale/zh-CN.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index 6bce717b5..96a909173 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -1,4 +1,4 @@ -import { Locale } from '../configProvider'; +import { Locale } from './useLocale'; const localeValues: Locale = { locale: 'en-US', diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index f2d5f5d96..6790c5de5 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../configProvider'; +import { Locale } from './useLocale'; const localeValues: Locale = { locale: 'zh-CN', From 1bdc5ac1c874e24ae6c03e670dfe04389c0426ad Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Thu, 3 Apr 2025 15:48:55 +0800 Subject: [PATCH 4/4] fix(configprovier): update ConfigProvider ts and en locale text --- src/configProvider/index.tsx | 12 +++--------- src/locale/en-US.ts | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/configProvider/index.tsx b/src/configProvider/index.tsx index 45430d7ad..d24d70ab0 100644 --- a/src/configProvider/index.tsx +++ b/src/configProvider/index.tsx @@ -1,15 +1,9 @@ import React from 'react'; -import { LocaleContext, LocaleContextProps } from '../locale/useLocale'; +import { Locale, LocaleContext } from '../locale/useLocale'; -const ConfigProvider = ({ - locale, - children, -}: { - locale: LocaleContextProps; - children: React.ReactNode; -}) => { - return {children}; +const ConfigProvider = ({ locale, children }: { locale: Locale; children: React.ReactNode }) => { + return {children}; }; export default ConfigProvider; diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index 96a909173..22fd944b9 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -22,7 +22,7 @@ const localeValues: Locale = { LoadError: { please: 'A new version has been found. Please', get: 'to get the new version.', - refresh: 'refresh', + refresh: ' refresh ', title: 'If this prompt persists for a long time, please contact the administrator.', }, Modal: {