diff --git a/content/basic/typography/index-en-US.md b/content/basic/typography/index-en-US.md index 68535f2652..309b979200 100644 --- a/content/basic/typography/index-en-US.md +++ b/content/basic/typography/index-en-US.md @@ -292,10 +292,11 @@ Copying of text can be supported by configuring the `copyable` property. When copyable is configured as true, the default copied content is children itself. Note that at this time, children only support string type. When copyable is configured as object, you can specify the content copied to the clipboard through `copyable.content`, which is no longer strongly associated with children. At this time, children will no longer limit the type, but `copyable.content` still needs to be a string. +You can use the `copyable.render` attribute to customize the copyable button render. ```jsx live=true import React from 'react'; -import { Typography, TextArea } from '@douyinfe/semi-ui'; +import { Typography, TextArea, Button } from '@douyinfe/semi-ui'; import { IconSetting } from '@douyinfe/semi-icons'; function Demo() { @@ -308,6 +309,18 @@ function Demo() { Toast.success({ content: 'Successfully copied.' }) }}>Click the right icon to copy. Timestamp: {new Date().getTime()/1000}s }}>Custom Copy Node + { + return ( + + ); + } + }}> + Custom Copy Render +

Paste here: diff --git a/content/basic/typography/index.md b/content/basic/typography/index.md index 962ee22f87..9ecefbaee7 100644 --- a/content/basic/typography/index.md +++ b/content/basic/typography/index.md @@ -280,10 +280,11 @@ function Demo() { 可通过配置 copyable 属性支持文本的复制。 当 copyable 配置为 true时,默认复制内容为 children 本身,注意,此时 children 只支持 string类型传入 当 copyable 配置为 object 时,可通过 `copyable.content` 指定复制至粘贴板的内容,与 children 不再强关联, 此时 children 将不再限定类型,但 `copyable.content` 仍需要为 string +可以通过 `copyable.render` 属性,自定义复制按钮的渲染逻辑 ```jsx live=true import React from 'react'; -import { Typography, TextArea } from '@douyinfe/semi-ui'; +import { Typography, TextArea, Button } from '@douyinfe/semi-ui'; import { IconSetting } from '@douyinfe/semi-icons'; function Demo() { @@ -296,6 +297,18 @@ function Demo() { Toast.success({ content: '复制文本成功' }) }}>点击右边的图标复制文本。 时间戳: {new Date().getTime()/1000}s }}>自定义复制节点 + { + return ( + + ); + } + }}> + 自定义复制渲染 +

粘贴区域: diff --git a/packages/semi-ui/typography/__test__/typography.test.js b/packages/semi-ui/typography/__test__/typography.test.js index ab288b809d..2975b4b781 100644 --- a/packages/semi-ui/typography/__test__/typography.test.js +++ b/packages/semi-ui/typography/__test__/typography.test.js @@ -124,4 +124,39 @@ describe(`Typography`, () => { expect(typographyParagraph.find('.semi-typography').children().at(0).text()).toEqual('Key: code'); }); + it('custom copy render', () => { + const { Text } = Typography; + const code = 'code'; + + const typographyParagraph = mount( + { + return ( + + {String(copied)} + {config.content} + + ); + } + }} + > + Key: {code} + + ); + + // test basic render + expect(typographyParagraph.find('.test-copied').text()).toEqual('false'); + expect(typographyParagraph.find('.test-copy-content').text()).toEqual(code); + + // test copy + const trigger = typographyParagraph.find('.test-copy-button'); + expect(trigger.length).toEqual(1); + trigger.at(0).simulate('click'); + expect(typographyParagraph.find('.test-copied').text()).toEqual('true'); + }); + }); diff --git a/packages/semi-ui/typography/copyable.tsx b/packages/semi-ui/typography/copyable.tsx index 8ad9206d7b..6d44c44883 100644 --- a/packages/semi-ui/typography/copyable.tsx +++ b/packages/semi-ui/typography/copyable.tsx @@ -10,6 +10,7 @@ import { IconCopy, IconTick } from '@douyinfe/semi-icons'; import { BaseProps } from '../_base/baseComponent'; import { Locale } from '../locale/interface'; import isEnterPress from '@douyinfe/semi-foundation/utils/isEnterPress'; +import { CopyableConfig } from './title'; const prefixCls = cssClasses.PREFIX; @@ -20,7 +21,8 @@ export interface CopyableProps extends BaseProps { forwardRef?: React.RefObject; successTip?: React.ReactNode; icon?: React.ReactNode; - onCopy?: (e: React.MouseEvent, content: string, res: boolean) => void + onCopy?: (e: React.MouseEvent, content: string, res: boolean) => void; + render?: (copied: boolean, doCopy: (e: React.MouseEvent) => void, configs: CopyableConfig) => React.ReactNode } interface CopyableState { copied: boolean; @@ -133,13 +135,17 @@ export class Copyable extends React.PureComponent } render() { - const { style, className, forwardRef, copyTip } = this.props; + const { style, className, forwardRef, copyTip, render } = this.props; const { copied } = this.state; const finalCls = cls(className, { [`${prefixCls}-action-copy`]: !copied, [`${prefixCls}-action-copied`]: copied, }); + if (render) { + return render(copied, this.copy, this.props); + } + return ( {(locale: Locale['Typography']) => ( diff --git a/packages/semi-ui/typography/title.tsx b/packages/semi-ui/typography/title.tsx index fb1f72ec0f..926d63580e 100644 --- a/packages/semi-ui/typography/title.tsx +++ b/packages/semi-ui/typography/title.tsx @@ -13,7 +13,9 @@ export interface CopyableConfig { successTip?: React.ReactNode; icon?: React.ReactNode; - onCopy?(e: React.MouseEvent, content: string, res: boolean): void + onCopy?: (e: React.MouseEvent, content: string, res: boolean) => void; + + render?: (copied: boolean, doCopy: (e: React.MouseEvent) => void, configs: CopyableConfig) => React.ReactNode } export type LinkType = React.AnchorHTMLAttributes | boolean;