diff --git a/src/flex/__tests__/__snapshots__/flex.test.tsx.snap b/src/flex/__tests__/__snapshots__/flex.test.tsx.snap
new file mode 100644
index 000000000..314def28d
--- /dev/null
+++ b/src/flex/__tests__/__snapshots__/flex.test.tsx.snap
@@ -0,0 +1,45 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Test Flex Button Match the snapshot 1`] = `
+
+
+
+ 123
+
+
+ 123
+
+
+ 123
+
+
+ 123
+
+
+
+`;
+
+exports[`Test Flex Button Match the snapshot: primary button 1`] = `
+
+
+
+ 123
+
+
+ 123
+
+
+ 123
+
+
+ 123
+
+
+
+`;
diff --git a/src/flex/__tests__/flex.test.tsx b/src/flex/__tests__/flex.test.tsx
new file mode 100644
index 000000000..153fd49f9
--- /dev/null
+++ b/src/flex/__tests__/flex.test.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { cleanup, render } from '@testing-library/react';
+
+import Flex from '..';
+
+const children = (
+ <>
+
123
+ 123
+ 123
+ 123
+ >
+);
+
+describe('Test Flex Button', () => {
+ beforeEach(() => cleanup());
+
+ it('Match the snapshot', () => {
+ expect(render({children}).asFragment()).toMatchSnapshot();
+
+ expect(render({children}).asFragment()).toMatchSnapshot(
+ 'primary button'
+ );
+ });
+});
diff --git a/src/flex/demos/align.tsx b/src/flex/demos/align.tsx
new file mode 100644
index 000000000..36a5d66b8
--- /dev/null
+++ b/src/flex/demos/align.tsx
@@ -0,0 +1,59 @@
+import React, { useState } from 'react';
+import { Button, Segmented, Slider } from 'antd';
+import { Flex } from 'dt-react-component';
+import type { IFlexProps } from 'dt-react-component/flex';
+
+const alignOptions = ['flex-start', 'center', 'flex-end'];
+const justifyOptions = [
+ 'flex-start',
+ 'center',
+ 'flex-end',
+ 'space-between',
+ 'space-around',
+ 'space-evenly',
+];
+
+export default () => {
+ const [align, setAlign] = useState('center');
+ const [justify, setJustify] = useState('center');
+ const [vertical, setVertical] = useState('false');
+ const [gap, setGap] = useState(4);
+ return (
+ <>
+ Select align :
+ setAlign(val as IFlexProps['align'])}
+ />
+ Select justify :
+ setJustify(val as IFlexProps['justify'])}
+ />
+ Select vertical :
+ setVertical(val as string)}
+ />
+ Select gap :
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/flex/demos/basic.tsx b/src/flex/demos/basic.tsx
new file mode 100644
index 000000000..9bb48d6c3
--- /dev/null
+++ b/src/flex/demos/basic.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import { Button } from 'antd';
+import { Flex } from 'dt-react-component';
+
+export default () => {
+ return (
+
+
+
+
+
+
+ );
+};
diff --git a/src/flex/index.md b/src/flex/index.md
new file mode 100644
index 000000000..f9f118afb
--- /dev/null
+++ b/src/flex/index.md
@@ -0,0 +1,28 @@
+---
+title: Flex 布局
+group: 组件
+toc: content
+---
+
+# Flex 布局
+
+## 何时使用
+
+- 需要 Flex 布局
+
+## 示例
+
+
+
+
+## API
+
+| 参数 | 说明 | 类型 | 默认值 |
+| -------- | ----------------------- | ----------------------------------------------------------------------------------- | -------- |
+| vertical | flex 主轴的方向是否垂直 | `boolean` | `false` |
+| wrap | 主轴换行 | [flex-wrap](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-wrap) | `nowrap` |
+| justify | `justify-content` | [justify-content](https://developer.mozilla.org/zh-CN/docs/Web/CSS/justify-content) | `normal` |
+| align | `align-items` | [align-items](https://developer.mozilla.org/zh-CN/docs/Web/CSS/align-items) | `normal` |
+| flex | `flex` | [flex](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex) | `normal` |
+| gap | `gap` | [gap](https://developer.mozilla.org/zh-CN/docs/Web/CSS/gap) | `0` |
+| children | 展示内容 | `React.ReactNode` | - |
diff --git a/src/flex/index.scss b/src/flex/index.scss
new file mode 100644
index 000000000..dec51838b
--- /dev/null
+++ b/src/flex/index.scss
@@ -0,0 +1,7 @@
+.dtc-flex {
+ display: flex;
+ flex-direction: row;
+ &__vertical {
+ flex-direction: column;
+ }
+}
diff --git a/src/flex/index.tsx b/src/flex/index.tsx
new file mode 100644
index 000000000..7522864dd
--- /dev/null
+++ b/src/flex/index.tsx
@@ -0,0 +1,53 @@
+import React, { CSSProperties, forwardRef } from 'react';
+import classNames from 'classnames';
+
+import './index.scss';
+
+export interface IFlexProps extends React.DOMAttributes {
+ vertical?: boolean;
+ wrap?: React.CSSProperties['flexWrap'];
+ justify?: React.CSSProperties['justifyContent'];
+ align?: React.CSSProperties['alignItems'];
+ flex?: React.CSSProperties['flex'];
+ gap?: React.CSSProperties['gap'];
+ children: React.ReactNode;
+ className?: string;
+ style?: CSSProperties;
+}
+
+/**
+ * 简单版本的 Ant Design 的 Flex 组件
+ */
+export default forwardRef(function Flex(
+ {
+ className,
+ vertical = false,
+ wrap = 'nowrap',
+ justify = 'normal',
+ align = 'normal',
+ flex = 'normal',
+ gap = 0,
+ style,
+ children,
+ ...rest
+ },
+ ref
+) {
+ return (
+
+ );
+});
diff --git a/src/index.ts b/src/index.ts
index 49c58448c..f85e27e19 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -13,6 +13,7 @@ export { default as Empty } from './empty';
export { default as ErrorBoundary } from './errorBoundary';
export { default as LoadError } from './errorBoundary/loadError';
export { default as FilterRules } from './filterRules';
+export { default as Flex } from './flex';
export { default as Form } from './form';
export { default as Fullscreen } from './fullscreen';
export { default as GlobalLoading } from './globalLoading';