diff --git a/.dumirc.ts b/.dumirc.ts index e4bd0b0f4..de621ad94 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -12,7 +12,9 @@ export default defineConfig({ }, // 默认重定向到子包的 src 文件夹 // ref: https://d.umijs.org/config#monoreporedirect - monorepoRedirect: {}, + monorepoRedirect: { + useRootProject: true, + }, // umi.server.js build error, disable it for now // ssr: process.env.NODE_ENV === 'production' ? {} : false, hash: true, @@ -109,9 +111,10 @@ export default defineConfig({ codeBlockMode: 'passive', }, alias: { - '@oceanbase/design': path.join(__dirname, 'packages/design/src'), + // 需要将子路径前移,否则会优先匹配到父路径导致子路径匹配异常 '@oceanbase/design/es': path.join(__dirname, 'packages/design/src'), '@oceanbase/design/locale': path.join(__dirname, 'packages/design/src/locale'), + '@oceanbase/design': path.join(__dirname, 'packages/design/src'), // for @import in less '~@oceanbase/design/es': path.join(__dirname, 'packages/design/src'), '@oceanbase/icons': path.join(__dirname, 'packages/icons/src'), diff --git a/packages/ui/src/DateRanger/Ranger.tsx b/packages/ui/src/DateRanger/Ranger.tsx index 546034c2c..a8abd6410 100644 --- a/packages/ui/src/DateRanger/Ranger.tsx +++ b/packages/ui/src/DateRanger/Ranger.tsx @@ -9,15 +9,8 @@ import { Tooltip, theme, } from '@oceanbase/design'; -import type { TooltipProps, FormItemProps } from '@oceanbase/design'; -import { - LeftOutlined, - PauseOutlined, - CaretRightOutlined, - RightOutlined, - ZoomOutOutlined, - SyncOutlined, -} from '@oceanbase/icons'; +import type { TooltipProps } from '@oceanbase/design'; +import { LeftOutlined, RightOutlined, ZoomOutOutlined, SyncOutlined } from '@oceanbase/icons'; import type { RangePickerProps } from '@oceanbase/design/es/date-picker'; import type { Dayjs } from 'dayjs'; import dayjs from 'dayjs'; @@ -139,7 +132,8 @@ const Ranger = React.forwardRef((props: DateRangerProps, ref) => { } = props; const { token } = theme.useToken(); - const isCn = locale.locale === 'zh_CN'; + const isCn = locale.antLocale === 'zh-cn'; + const isEN = locale.antLocale === 'en'; // 是否为 moment 时间对象 const isMoment = @@ -271,34 +265,26 @@ const Ranger = React.forwardRef((props: DateRangerProps, ref) => { const getCustomizeLabel = () => { if (differenceYears > 0) { - return `近 ${differenceYears} 年`; + return isEN ? `Nearly ${differenceYears} years` : `近 ${differenceYears} 年`; } - // if (differenceQuarters > 0) { - // return `近 ${differenceQuarters} 季度`; - // } - if (differenceMonths > 0) { - return `近 ${differenceMonths} 月`; + return isEN ? `Nearly ${differenceMonths} months` : `近 ${differenceMonths} 月`; } if (differenceWeeks > 0) { - return `近 ${differenceWeeks} 周`; - } - - if (differenceDays > 0) { - return `近 ${differenceDays} 天`; + return isEN ? `Nearly ${differenceWeeks} weeks` : `近 ${differenceWeeks} 周`; } if (differenceHours > 0) { - return `近 ${differenceHours} 时`; + return isEN ? `Nearly ${differenceHours} hours` : `近 ${differenceHours} 小时`; } if (differenceMinutes > 0) { - return `近 ${differenceMinutes} 分`; + return isEN ? `Nearly ${differenceMinutes} minutes` : `近 ${differenceMinutes} 分`; } - return `近 ${differenceSeconds} 秒`; + return isEN ? `Nearly ${differenceSeconds} seconds` : `近 ${differenceSeconds} 秒`; }; const setNow = () => { @@ -316,15 +302,15 @@ const Ranger = React.forwardRef((props: DateRangerProps, ref) => { updateCurrentTime: setNow, })); - const rangeLabel = - rangeName === CUSTOMIZE - ? getCustomizeRangeLabel() - : selects.find(_item => _item.name === rangeName)?.rangeLabel; + const currentRange = selects.find(_item => _item.name === rangeName); + const rangeLabel = rangeName === CUSTOMIZE ? getCustomizeRangeLabel() : currentRange?.rangeLabel; const label = rangeName === CUSTOMIZE ? getCustomizeLabel() - : selects.find(_item => _item.name === rangeName)?.label; + : isEN + ? currentRange.enLabel || currentRange.label + : currentRange.label; const thisYear = new Date().getFullYear(); const isThisYear = startTime?.year() === thisYear && endTime?.year() === thisYear; @@ -428,8 +414,7 @@ const Ranger = React.forwardRef((props: DateRangerProps, ref) => { {hasTagInPicker && ( {item.rangeLabel} )} - {/* @ts-ignore */} - {locale[item.label] || item.label} + {isEN ? item.enLabel || item.label : item.label} ), }; diff --git a/packages/ui/src/DateRanger/constant/index.ts b/packages/ui/src/DateRanger/constant/index.ts index c09c54669..d1a3a8297 100644 --- a/packages/ui/src/DateRanger/constant/index.ts +++ b/packages/ui/src/DateRanger/constant/index.ts @@ -26,6 +26,7 @@ export const DATE_TIME_FORMAT_CN = 'MM-DD HH:mm'; export const NEAR_1_MINUTES: RangeOption = { label: '近 1 分钟', + enLabel: 'Nearly 1 minute', rangeLabel: '1m', name: 'NEAR_1_MINUTES', range: (current: Moment | Dayjs = moment()) => [ @@ -36,6 +37,7 @@ export const NEAR_1_MINUTES: RangeOption = { export const NEAR_5_MINUTES: RangeOption = { label: '近 5 分钟', + enLabel: 'Nearly 5 minutes', rangeLabel: '5m', name: 'NEAR_5_MINUTES', range: (current: Moment | Dayjs = moment()) => [ @@ -46,6 +48,7 @@ export const NEAR_5_MINUTES: RangeOption = { export const NEAR_10_MINUTES: RangeOption = { label: '近 10 分钟', + enLabel: 'Nearly 10 minutes', rangeLabel: '10m', name: 'NEAR_10_MINUTES', range: (current: Moment | Dayjs = moment()) => [ @@ -56,6 +59,7 @@ export const NEAR_10_MINUTES: RangeOption = { export const NEAR_20_MINUTES: RangeOption = { label: '近 20 分钟', + enLabel: 'Nearly 20 minutes', rangeLabel: '20m', name: 'NEAR_20_MINUTES', range: (current: Moment | Dayjs = moment()) => [ @@ -66,6 +70,7 @@ export const NEAR_20_MINUTES: RangeOption = { export const NEAR_30_MINUTES: RangeOption = { label: '近 30 分钟', + enLabel: 'Nearly 30 minutes', rangeLabel: '30m', name: 'NEAR_30_MINUTES', range: (current: Moment | Dayjs = moment()) => [ @@ -76,6 +81,7 @@ export const NEAR_30_MINUTES: RangeOption = { export const NEAR_1_HOURS: RangeOption = { label: '近 1 小时', + enLabel: 'Nearly 1 hour', rangeLabel: '1h', name: 'NEAR_1_HOURS', range: (current: Moment | Dayjs = moment()) => [ @@ -86,6 +92,7 @@ export const NEAR_1_HOURS: RangeOption = { export const NEAR_2_HOURS: RangeOption = { label: '近 2 小时', + enLabel: 'Nearly 2 hours', rangeLabel: '2h', name: 'NEAR_2_HOURS', range: (current: Moment | Dayjs = moment()) => [ @@ -96,6 +103,7 @@ export const NEAR_2_HOURS: RangeOption = { export const NEAR_3_HOURS: RangeOption = { label: '近 3 小时', + enLabel: 'Nearly 3 hours', rangeLabel: '3h', name: 'NEAR_3_HOURS', range: (current: Moment | Dayjs = moment()) => [ @@ -106,6 +114,7 @@ export const NEAR_3_HOURS: RangeOption = { export const NEAR_6_HOURS: RangeOption = { label: '近 6 小时', + enLabel: 'Nearly 6 hours', rangeLabel: '6h', name: 'NEAR_6_HOURS', range: (current: Moment | Dayjs = moment()) => [ @@ -116,6 +125,7 @@ export const NEAR_6_HOURS: RangeOption = { export const TODAY: RangeOption = { label: '今天', + enLabel: 'Today', rangeLabel: '1d', name: 'TODAY', range: (current: Moment | Dayjs = moment()) => [ @@ -126,6 +136,7 @@ export const TODAY: RangeOption = { export const YESTERDAY: RangeOption = { label: '昨天', + enLabel: 'Yesterday', rangeLabel: '1d', name: 'YESTERDAY', range: (current: Moment | Dayjs = moment()) => [ @@ -136,6 +147,7 @@ export const YESTERDAY: RangeOption = { export const LAST_3_DAYS: RangeOption = { label: '近 3 天', + enLabel: 'Nearly 3 days', rangeLabel: '3d', name: 'LAST_3_DAYS', range: (current: Moment | Dayjs = moment()) => [ @@ -146,6 +158,7 @@ export const LAST_3_DAYS: RangeOption = { export const THIS_WEEK: RangeOption = { label: '近一周', + enLabel: 'Nearly a week', rangeLabel: '1w', name: 'THIS_WEEK', range: (current: Moment | Dayjs = moment()) => [ @@ -156,6 +169,7 @@ export const THIS_WEEK: RangeOption = { export const LAST_WEEK: RangeOption = { label: '上周', + enLabel: 'Last week', rangeLabel: 'last week', name: 'LAST_WEEK', range: (current: Moment | Dayjs = moment()) => [ @@ -166,6 +180,7 @@ export const LAST_WEEK: RangeOption = { export const THIS_MONTH: RangeOption = { label: '本月', + enLabel: 'This month', rangeLabel: '1mo', name: 'THIS_MONTH', range: (current: Moment | Dayjs = moment()) => [ @@ -176,6 +191,7 @@ export const THIS_MONTH: RangeOption = { export const LAST_MONTH: RangeOption = { label: '上月', + enLabel: 'Last month', rangeLabel: '1mo', name: 'LAST_MONTH', range: (current: Moment | Dayjs = moment()) => [ @@ -186,6 +202,7 @@ export const LAST_MONTH: RangeOption = { export const THIS_YEAR: RangeOption = { label: '今年', + enLabel: 'This year', rangeLabel: '1y', name: 'THIS_YEAR', range: (current: Moment | Dayjs = moment()) => [ @@ -196,6 +213,7 @@ export const THIS_YEAR: RangeOption = { export const LAST_YEAR: RangeOption = { label: '去年', + enLabel: 'Last year', rangeLabel: '1y', name: 'LAST_YEAR', range: (current: Moment | Dayjs = moment()) => [ @@ -206,6 +224,7 @@ export const LAST_YEAR: RangeOption = { export const NEXT_YEAR: RangeOption = { label: '明年', + enLabel: 'Next year', rangeLabel: '1y', name: 'NEXT_YEAR', range: (current: Moment | Dayjs = moment()) => [ @@ -227,6 +246,8 @@ export const NEAR_TIME_LIST = [ LAST_3_DAYS, TODAY, YESTERDAY, + THIS_WEEK, + LAST_WEEK, THIS_MONTH, LAST_MONTH, THIS_YEAR, diff --git a/packages/ui/src/DateRanger/demo/locale.tsx b/packages/ui/src/DateRanger/demo/locale.tsx new file mode 100644 index 000000000..91ce60ef3 --- /dev/null +++ b/packages/ui/src/DateRanger/demo/locale.tsx @@ -0,0 +1,42 @@ +import React, { useState } from 'react'; +import { DateRanger } from '@oceanbase/ui'; +import { ConfigProvider, Radio, RadioChangeEvent, Space } from '@oceanbase/design'; +import dayjs from 'dayjs'; +import enUS from '@oceanbase/ui/locale/en-US'; +import zhCN from '@oceanbase/ui/locale/zh-CN'; + +export default () => { + const [locale, setLocal] = useState(enUS); + + const changeLocale = (e: RadioChangeEvent) => { + const localeValue = e.target.value; + setLocal(localeValue); + if (!localeValue) { + dayjs.locale('en'); + } else { + dayjs.locale('zh-cn'); + } + }; + + return ( +
+
+ Change locale of components: + + + English + + + 中文 + + +
+ + + + + + +
+ ); +}; diff --git a/packages/ui/src/DateRanger/index.md b/packages/ui/src/DateRanger/index.md index f9d20b9e1..8cd6c0234 100644 --- a/packages/ui/src/DateRanger/index.md +++ b/packages/ui/src/DateRanger/index.md @@ -15,6 +15,8 @@ nav: + + ## API @@ -26,6 +28,7 @@ nav: | onChange | value 变化时的回调函数 | (range: Dayjs[] \| Moment[]) => void | noop | - | | defaultValue | DatePicker 控件的默认值 | Dayjs[] \| Moment[] | - | - | | defaultQuickValue | 快速选择的默认值(优先级低于 value/defaultValue) | string | - | - | +| isMoment | 是否使用 moment.js 作为时间插件 | boolean | - | - | | hasRewind | 后退按钮 | boolean | true | - | | hasForward | 前进按钮 | boolean | true | - | | hasSync | 刷新按钮 | boolean | true | - | diff --git a/packages/ui/src/DateRanger/typing.ts b/packages/ui/src/DateRanger/typing.ts index 602c7ba53..3f5dab8e7 100644 --- a/packages/ui/src/DateRanger/typing.ts +++ b/packages/ui/src/DateRanger/typing.ts @@ -6,6 +6,10 @@ export interface RangeOption { * @description 选项展示名称 */ label: string; + /** + * @description 选项英文展示名称,用来兼容内部国际化,外部传入的选项直接对 label 做国际化即可 + */ + enLabel?: string; /** * @description 选项 key */ diff --git a/packages/ui/src/locale/LocaleWrapper.tsx b/packages/ui/src/locale/LocaleWrapper.tsx index fa6c87505..c162aa41a 100644 --- a/packages/ui/src/locale/LocaleWrapper.tsx +++ b/packages/ui/src/locale/LocaleWrapper.tsx @@ -29,6 +29,8 @@ export default ({ componentName, defaultLocale }: LocaleWrapperInput) => const localeData = { ...defaultLocale, ...(localeFromContext || {}), + // 这里使用 antLocale,不能直接顶掉 locale 属性,有些组件内部会维护一个 locale 去做特殊判断 + antLocale: antLocale?.locale || 'zh-cn', }; return (