From 5cd5c43837950cb0e2068fc7fcd80cf19882a603 Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Mon, 4 Aug 2025 11:29:46 +0800 Subject: [PATCH 1/2] feat(modal): change Modal.method to use dtinsightIcon and add Modal.delete --- src/index.ts | 2 +- src/modal/demos/method.tsx | 64 ++++++++++++++++++++++++++++++++++++++ src/modal/index.md | 9 ++++++ src/modal/index.scss | 17 ++++++++++ src/modal/index.tsx | 50 ++++++++++++++++++++++++----- 5 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 src/modal/demos/method.tsx diff --git a/src/index.ts b/src/index.ts index a035117f6..5e9fdb22f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,7 +29,7 @@ export { default as enUS } from './locale/en-US'; export { default as useLocale } from './locale/useLocale'; export { default as zhCN } from './locale/zh-CN'; export { default as MarkdownRender } from './markdownRender'; -export { default as Modal } from './modal/modal'; +export { default as Modal } from './modal'; export { default as NotFound } from './notFound'; export { default as ProgressBar } from './progressBar'; export { default as ProgressLine } from './progressLine'; diff --git a/src/modal/demos/method.tsx b/src/modal/demos/method.tsx new file mode 100644 index 000000000..b03f78394 --- /dev/null +++ b/src/modal/demos/method.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Button, Space } from 'antd'; +import { Modal } from 'dt-react-component'; + +const info = () => { + Modal.info({ + title: 'This is a notification message', + content: ( +
+

some messages...some messages...

+

some messages...some messages...

+
+ ), + onOk() {}, + }); +}; + +const success = () => { + Modal.success({ + title: 'This is an success message', + content: 'some messages...some messages...', + }); +}; + +const error = () => { + Modal.error({ + title: 'This is an error message', + content: 'some messages...some messages...', + }); +}; + +const warning = () => { + Modal.warning({ + title: 'This is a warning message', + content: 'some messages...some messages...', + }); +}; + +const confirm = () => { + Modal.confirm({ + title: 'This is a confirm message', + content: 'some messages...some messages...', + }); +}; + +const handleDelete = () => { + Modal.delete({ + title: 'This is a delete message', + content: 'some messages...some messages...', + }); +}; + +const Method: React.FC = () => ( + + + + + + + + +); + +export default Method; diff --git a/src/modal/index.md b/src/modal/index.md index 00309066b..71aa6d799 100644 --- a/src/modal/index.md +++ b/src/modal/index.md @@ -22,6 +22,7 @@ toc: content + ## API @@ -36,3 +37,11 @@ toc: content | onPositionChange | 位置变化时的回调 | `(data: { x: number; y: number}) => void` | | | onRectChange | 尺寸变化时的回调 | `(data: { width: number; height: number }) => void` | | | ...rest | 其他继承自 antd Modal 的属性 | [ModalProps](https://4x.ant.design/components/modal-cn/#API) | | + +## Modal.method + +新增: Modal.delete + +:::info +其余和 antd4.x 的 [Modal.method]() 一致 +::: diff --git a/src/modal/index.scss b/src/modal/index.scss index db75dff2e..1858ea414 100644 --- a/src/modal/index.scss +++ b/src/modal/index.scss @@ -40,4 +40,21 @@ $modal-max-height: 80vh; flex: 0 1 auto; } } + .ant-modal-confirm-body { + .dtstack-icon { + float: left; + margin-right: 8px; + font-size: 20px; + } + .ant-modal-confirm-title { + color: #3D446E; + line-height: 20px; + font-size: 14px; + } + .ant-modal-confirm-content { + margin: 8px 0 16px 30px; + color: #8B8FA8; + line-height: 20px; + } + } } diff --git a/src/modal/index.tsx b/src/modal/index.tsx index 000817bfa..c42392724 100644 --- a/src/modal/index.tsx +++ b/src/modal/index.tsx @@ -1,26 +1,60 @@ -import { Modal as AntdModal } from 'antd'; -import { ModalStaticFunctions } from 'antd/lib/modal/confirm'; +import React from 'react'; +import { CheckFilled, CloseFilled, InformationFilled, WarningFilled } from '@dtinsight/react-icons'; +import { Modal as AntdModal, ModalFuncProps } from 'antd'; +import { ModalFunc, ModalStaticFunctions } from 'antd/lib/modal/confirm'; import InternalModal from './modal'; +const OK_TEXT = '确认'; + type ModalType = typeof InternalModal & ModalStaticFunctions & { useModal: typeof AntdModal.useModal; destroyAll: () => void; config: typeof AntdModal.config; + delete: (props: ModalFuncProps) => void; }; const { useModal, info, success, error, warning, confirm, destroyAll, config } = AntdModal; -const Modal = InternalModal as ModalType; +const customProps: Record< + | keyof Pick + | 'delete', + ModalFuncProps +> = { + info: { icon: , okText: OK_TEXT }, + success: { icon: , okText: OK_TEXT }, + error: { + icon: , + okText: OK_TEXT, + okButtonProps: { danger: true }, + }, + warning: { icon: , okText: OK_TEXT }, + confirm: { icon: , okText: OK_TEXT, cancelText: '取消' }, + delete: { + icon: , + okButtonProps: { danger: true }, + okText: OK_TEXT, + cancelText: '暂不', + }, +}; + +function withCustomIcon(fn: ModalFunc, type: keyof typeof customProps) { + return (props: ModalFuncProps) => + fn({ ...customProps[type], wrapClassName: 'dtc-modal', ...props }); +} + +const Modal = InternalModal as unknown as ModalType; Object.assign(Modal, { + InternalModal, useModal, - info, - success, - error, - warning, - confirm, + info: withCustomIcon(info, 'info'), + success: withCustomIcon(success, 'success'), + error: withCustomIcon(error, 'error'), + warning: withCustomIcon(warning, 'warning'), + confirm: withCustomIcon(confirm, 'confirm'), + delete: withCustomIcon(confirm, 'delete'), destroyAll, config, }); From dc2004619583f617d1a75b463bff205913fd456a Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Thu, 21 Aug 2025 14:59:39 +0800 Subject: [PATCH 2/2] feat(modal): support modal locale --- src/configProvider/demos/basic.tsx | 38 ++++++++++++++++++++- src/configProvider/index.tsx | 8 ++++- src/locale/en-US.ts | 5 +++ src/locale/useLocale.tsx | 5 +++ src/locale/zh-CN.ts | 5 +++ src/modal/index.tsx | 54 ++++++++++++++++++------------ src/modal/locale.ts | 40 ++++++++++++++++++++++ 7 files changed, 131 insertions(+), 24 deletions(-) create mode 100644 src/modal/locale.ts diff --git a/src/configProvider/demos/basic.tsx b/src/configProvider/demos/basic.tsx index 54f83d555..4e67285a4 100644 --- a/src/configProvider/demos/basic.tsx +++ b/src/configProvider/demos/basic.tsx @@ -1,10 +1,39 @@ import React, { useState } from 'react'; import { Radio, Space } from 'antd'; -import { BlockHeader, ConfigProvider, Copy, enUS, Input, zhCN } from 'dt-react-component'; +import { + BlockHeader, + Button, + ConfigProvider, + Copy, + enUS, + Input, + Modal, + zhCN, +} from 'dt-react-component'; export default function Basic() { const [locale, setLocale] = useState(zhCN); + const info = () => { + Modal.info({ + title: 'This is a notification message', + content: ( +
+

some messages...some messages...

+

some messages...some messages...

+
+ ), + onOk() {}, + }); + }; + + const handleDelete = () => { + Modal.delete({ + title: 'This is a delete message', + content: 'some messages...some messages...', + }); + }; + return ( Input.Match 组件 +
+

Modal.method 组件

+ + +
diff --git a/src/configProvider/index.tsx b/src/configProvider/index.tsx index d24d70ab0..3ec2a5c69 100644 --- a/src/configProvider/index.tsx +++ b/src/configProvider/index.tsx @@ -1,8 +1,14 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { Locale, LocaleContext } from '../locale/useLocale'; +import { changeConfirmLocale } from '../modal/locale'; const ConfigProvider = ({ locale, children }: { locale: Locale; children: React.ReactNode }) => { + useEffect(() => { + const clearLocale = changeConfirmLocale(locale?.Modal); + return clearLocale; + }, [locale]); + return {children}; }; diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index d5e90024b..6f44cbf28 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -46,6 +46,11 @@ const localeValues: Locale = { front: 'Head match', tail: 'Tail match', }, + Modal: { + okText: 'Ok', + cancelText: 'Cancel', + notYetText: 'Not Now', + }, NotFound: { description: 'Sorry, the page you visited does not exist', }, diff --git a/src/locale/useLocale.tsx b/src/locale/useLocale.tsx index e4681d6e5..9d57f29e2 100644 --- a/src/locale/useLocale.tsx +++ b/src/locale/useLocale.tsx @@ -33,6 +33,11 @@ export interface Locale { NotFound: { description: string; }; + Modal: { + okText: string; + cancelText: string; + notYetText: string; + }; SpreadSheet: { description: string; copy: string; diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index 418ac6331..6e3e55449 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -42,6 +42,11 @@ const localeValues: Locale = { front: '头部匹配', tail: '尾部匹配', }, + Modal: { + okText: '确定', + cancelText: '取消', + notYetText: '暂不', + }, NotFound: { description: '抱歉,您访问的页面不存在', }, diff --git a/src/modal/index.tsx b/src/modal/index.tsx index c42392724..0bbbeb4dc 100644 --- a/src/modal/index.tsx +++ b/src/modal/index.tsx @@ -3,10 +3,9 @@ import { CheckFilled, CloseFilled, InformationFilled, WarningFilled } from '@dti import { Modal as AntdModal, ModalFuncProps } from 'antd'; import { ModalFunc, ModalStaticFunctions } from 'antd/lib/modal/confirm'; +import { getRunTimeLocale, ModalLocale } from './locale'; import InternalModal from './modal'; -const OK_TEXT = '确认'; - type ModalType = typeof InternalModal & ModalStaticFunctions & { useModal: typeof AntdModal.useModal; @@ -17,31 +16,42 @@ type ModalType = typeof InternalModal & const { useModal, info, success, error, warning, confirm, destroyAll, config } = AntdModal; -const customProps: Record< +const getCustomProps = ( + locale: ModalLocale +): Record< | keyof Pick | 'delete', ModalFuncProps -> = { - info: { icon: , okText: OK_TEXT }, - success: { icon: , okText: OK_TEXT }, - error: { - icon: , - okText: OK_TEXT, - okButtonProps: { danger: true }, - }, - warning: { icon: , okText: OK_TEXT }, - confirm: { icon: , okText: OK_TEXT, cancelText: '取消' }, - delete: { - icon: , - okButtonProps: { danger: true }, - okText: OK_TEXT, - cancelText: '暂不', - }, +> => { + return { + info: { icon: , okText: locale.okText }, + success: { icon: , okText: locale.okText }, + error: { + icon: , + okText: locale.okText, + okButtonProps: { danger: true }, + }, + warning: { icon: , okText: locale.okText }, + confirm: { + icon: , + okText: locale.okText, + cancelText: locale.cancelText, + }, + delete: { + icon: , + okButtonProps: { danger: true }, + okText: locale.okText, + cancelText: locale.notYetText, + }, + }; }; -function withCustomIcon(fn: ModalFunc, type: keyof typeof customProps) { - return (props: ModalFuncProps) => - fn({ ...customProps[type], wrapClassName: 'dtc-modal', ...props }); +function withCustomIcon(fn: ModalFunc, type: keyof ReturnType) { + return (props: ModalFuncProps) => { + const locale = getRunTimeLocale(); + const customProps = getCustomProps(locale); + return fn({ ...customProps[type], wrapClassName: 'dtc-modal', ...props }); + }; } const Modal = InternalModal as unknown as ModalType; diff --git a/src/modal/locale.ts b/src/modal/locale.ts new file mode 100644 index 000000000..12e2128a9 --- /dev/null +++ b/src/modal/locale.ts @@ -0,0 +1,40 @@ +import defaultLocale from '../locale/zh-CN'; + +export interface ModalLocale { + okText: string; + cancelText: string; + notYetText: string; +} + +let runtimeLocale: ModalLocale = { + ...(defaultLocale.Modal as ModalLocale), +}; + +let localeList: ModalLocale[] = []; + +const generateLocale = () => + localeList.reduce( + (merged, locale) => ({ ...merged, ...locale }), + defaultLocale.Modal! + ); + +export function changeConfirmLocale(newLocale?: ModalLocale) { + if (newLocale) { + const cloneLocale = { ...newLocale }; + localeList.push(cloneLocale); + runtimeLocale = generateLocale(); + + return () => { + localeList = localeList.filter((locale) => locale !== cloneLocale); + runtimeLocale = generateLocale(); + }; + } + + runtimeLocale = { + ...(defaultLocale.Modal as ModalLocale), + }; +} + +export const getRunTimeLocale = () => { + return runtimeLocale; +};