diff --git a/packages/x-markdown/src/plugins/HighlightCode/__test__/index.test.tsx b/packages/x-markdown/src/plugins/HighlightCode/__test__/index.test.tsx index b2eff1bb1..9eacb43a9 100644 --- a/packages/x-markdown/src/plugins/HighlightCode/__test__/index.test.tsx +++ b/packages/x-markdown/src/plugins/HighlightCode/__test__/index.test.tsx @@ -1,4 +1,4 @@ -import { render } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import React from 'react'; import XMarkdown from '../../../XMarkdown'; import HighlightCode from '..'; @@ -177,4 +177,38 @@ plain text expect(container.querySelector('pre')).toBeInTheDocument(); expect(container.textContent).toContain('plain text'); }); + + it('should handle copy action click', async () => { + const content = `\`\`\`javascript +console.log("test copy"); +\`\`\``; + const mockClipboard = { + writeText: jest.fn().mockResolvedValue(undefined), + }; + + Object.defineProperty(navigator, 'clipboard', { + writable: true, + value: mockClipboard, + }); + + render( + ) => { + const { class: className, children } = props; + const lang = className?.match(/language-(\w+)/)?.[1] || ''; + return {children}; + }, + }} + />, + ); + + const copyButton = screen.getByRole('img', { name: 'copy' }); + fireEvent.click(copyButton); + + await waitFor(() => { + expect(mockClipboard.writeText).toHaveBeenCalledWith('console.log("test copy");'); + }); + }); }); diff --git a/packages/x-markdown/src/plugins/HighlightCode/index.tsx b/packages/x-markdown/src/plugins/HighlightCode/index.tsx index 9fabe4428..ea53277ea 100644 --- a/packages/x-markdown/src/plugins/HighlightCode/index.tsx +++ b/packages/x-markdown/src/plugins/HighlightCode/index.tsx @@ -1,9 +1,11 @@ import { CopyOutlined } from '@ant-design/icons'; import useXComponentConfig from '@ant-design/x/es/_util/hooks/use-x-component-config'; +import Actions from '@ant-design/x/es/actions'; +import type { ActionsProps } from '@ant-design/x/es/actions/interface'; import useLocale from '@ant-design/x/es/locale/useLocale'; import useXProviderContext from '@ant-design/x/es/x-provider/hooks/use-x-provider-context'; import locale_EN from '@ant-design/x/locale/en_US'; -import { Button, message, Tooltip } from 'antd'; +import { message } from 'antd'; import classnames from 'classnames'; import React from 'react'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; @@ -74,6 +76,22 @@ const HighlightCode: React.FC = (props) => { } }; + const handleActionsClick: ActionsProps['onClick'] = ({ keyPath }) => { + switch (keyPath[0]) { + case 'copy': + handleCopyCode(); + break; + } + }; + + const actionItems = [ + { + key: 'copy', + label: contextLocale.copy, + icon: , + }, + ]; + const renderTitle = () => { if (header === null) return null; @@ -99,9 +117,7 @@ const HighlightCode: React.FC = (props) => { > {lang} - - - - -