diff --git a/src/index.ts b/src/index.ts
index a4df49c0d..6ec201249 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -32,6 +32,7 @@ export { default as MarkdownRender } from './markdownRender';
export { default as Modal } from './modal';
export { default as NotFound } from './notFound';
export { default as Popconfirm } from './popConfirm';
+export { default as Popover } from './popover';
export { default as ProgressBar } from './progressBar';
export { default as ProgressLine } from './progressLine';
export { default as Resize } from './resize';
diff --git a/src/popover/__tests__/index.test.tsx b/src/popover/__tests__/index.test.tsx
new file mode 100644
index 000000000..c306d84b6
--- /dev/null
+++ b/src/popover/__tests__/index.test.tsx
@@ -0,0 +1,57 @@
+import React from 'react';
+import { render, screen, waitFor } from '@testing-library/react';
+import '@testing-library/jest-dom/extend-expect';
+
+import Popover from '..';
+
+describe('Popover', () => {
+ it('should render popover with default overlay className', async () => {
+ render(
+
+ Hover me
+
+ );
+
+ await waitFor(() => expect(screen.getByText('Popover content')).toBeInTheDocument());
+
+ expect(document.querySelector('.dtc-popover')).toBeInTheDocument();
+ });
+
+ it('should merge custom overlayClassName', async () => {
+ render(
+
+ Hover me
+
+ );
+
+ await waitFor(() => expect(document.querySelector('.dtc-popover')).toBeInTheDocument());
+
+ expect(document.querySelector('.dtc-popover')).toHaveClass('custom-popover');
+ });
+
+ it('should pass overlayInnerStyle to antd Popover', async () => {
+ render(
+
+ Hover me
+
+ );
+
+ await waitFor(() =>
+ expect(document.querySelector('.ant-popover-inner')).toBeInTheDocument()
+ );
+
+ expect(document.querySelector('.ant-popover-inner')).toHaveStyle({
+ color: 'red',
+ });
+ });
+});
diff --git a/src/popover/demos/basic.tsx b/src/popover/demos/basic.tsx
new file mode 100644
index 000000000..5206513af
--- /dev/null
+++ b/src/popover/demos/basic.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import { Button } from 'antd';
+import { Popover } from 'dt-react-component';
+
+export default function Basic() {
+ return (
+
+
+
+ );
+}
diff --git a/src/popover/demos/customHeight.tsx b/src/popover/demos/customHeight.tsx
new file mode 100644
index 000000000..cfc8aff7f
--- /dev/null
+++ b/src/popover/demos/customHeight.tsx
@@ -0,0 +1,20 @@
+import React, { CSSProperties } from 'react';
+import { Button } from 'antd';
+import { Popover } from 'dt-react-component';
+
+const content = Array.from({ length: 12 }, (_, index) => (
+
这是第 {index + 1} 行自定义高度的 Popover 内容
+));
+
+export default function CustomHeight() {
+ return (
+ {content}}
+ trigger="click"
+ overlayStyle={{ '--max-height': '160px' } as CSSProperties}
+ >
+
+
+ );
+}
diff --git a/src/popover/demos/maxWidth.tsx b/src/popover/demos/maxWidth.tsx
new file mode 100644
index 000000000..4f56ae1bb
--- /dev/null
+++ b/src/popover/demos/maxWidth.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import { Button } from 'antd';
+import { Popover } from 'dt-react-component';
+
+export default function MaxWidth() {
+ return (
+
+
+
+ );
+}
diff --git a/src/popover/demos/noTitle.tsx b/src/popover/demos/noTitle.tsx
new file mode 100644
index 000000000..6de0d9cc7
--- /dev/null
+++ b/src/popover/demos/noTitle.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import { Button } from 'antd';
+import { Popover } from 'dt-react-component';
+
+export default function NoTitle() {
+ return (
+
+
+
+ );
+}
diff --git a/src/popover/demos/scroll.tsx b/src/popover/demos/scroll.tsx
new file mode 100644
index 000000000..a05ff5230
--- /dev/null
+++ b/src/popover/demos/scroll.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import { Button } from 'antd';
+import { Popover } from 'dt-react-component';
+
+const content = Array.from({ length: 30 }, (_, index) => (
+ 这是第 {index + 1} 行较长的 Popover 内容
+));
+
+export default function Scroll() {
+ return (
+ {content}} trigger="click">
+
+
+ );
+}
diff --git a/src/popover/index.md b/src/popover/index.md
new file mode 100644
index 000000000..703b4ddb2
--- /dev/null
+++ b/src/popover/index.md
@@ -0,0 +1,27 @@
+---
+title: Popover 气泡卡片
+group: 组件
+toc: content
+demo:
+ cols: 2
+---
+
+# Popover 气泡卡片
+
+## 何时使用
+
+用于展示更丰富的气泡内容。组件基于 antd Popover 封装,浮层内容最大高度为 400px,超过后可滚动查看。
+
+## 代码演示
+
+
+
+
+
+
+
+## API
+
+### Popover
+
+Popover 组件支持 antd Popover 组件的所有属性,详见 [Ant Design Popover API](https://ant.design/components/popover-cn/#API)。
diff --git a/src/popover/index.scss b/src/popover/index.scss
new file mode 100644
index 000000000..a6b2eadce
--- /dev/null
+++ b/src/popover/index.scss
@@ -0,0 +1,24 @@
+.dtc-popover {
+ min-width: 220px;
+ max-width: 400px;
+ .ant-popover-inner {
+ border-radius: 4px;
+ }
+ .ant-popover-title {
+ padding: 16px 16px 0;
+ border-bottom: 0;
+ font-weight: 500;
+ font-size: 14px;
+ color: #3D446E;
+ }
+ .ant-popover-inner-content {
+ padding: 16px;
+ max-height: var(--max-height, 400px);
+ overflow-y: auto;
+ font-size: 12px;
+ color: #8B8FA8;
+ }
+ .ant-popover-title + .ant-popover-inner-content {
+ padding-top: 4px;
+ }
+}
diff --git a/src/popover/index.tsx b/src/popover/index.tsx
new file mode 100644
index 000000000..677c89a1c
--- /dev/null
+++ b/src/popover/index.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import { Popover as AntdPopover, PopoverProps as AntdPopoverProps } from 'antd';
+import classNames from 'classnames';
+
+import './index.scss';
+
+export type PopoverProps = AntdPopoverProps;
+
+const Popover = ({ overlayClassName, ...rest }: PopoverProps) => {
+ return ;
+};
+
+export default Popover;