diff --git a/src/BloodNode/demos/DataViewList.tsx b/src/BloodNode/demos/DataViewList.tsx
new file mode 100644
index 0000000..a0de5d6
--- /dev/null
+++ b/src/BloodNode/demos/DataViewList.tsx
@@ -0,0 +1,8 @@
+import { memo } from 'react';
+import BloodNode from '..';
+
+const NodeList = memo(() => {
+ return ;
+});
+
+export default NodeList;
diff --git a/src/BloodNode/index.md b/src/BloodNode/index.md
new file mode 100644
index 0000000..c291fc7
--- /dev/null
+++ b/src/BloodNode/index.md
@@ -0,0 +1,51 @@
+---
+group: 节点
+title: BloodNode 血缘图节点
+description: 血缘图中的基础节点
+---
+
+我们在 ProFlow 中提供了 BloodMap 的基础节点,方便定制样式。
+
+## 基础节点
+
+## 预览模式
+
+BasicNode 组件提供了 `Preview` 子组件用于画布之外的预览。
+
+
+
+## 搭配 Field 组件使用
+
+pro-flow-editor 提供 NodeField 组件,可以搭配 BasicNode 使用,两者关系就像 antd 的 Form 和 Form.Item。
+
+
+
+## collapsedKeys 受控折叠与展开
+
+搭配 Field 使用时,可以通过 collapsedKeys 和 onCollapsedKeysChange 控制折叠的字段。
+
+
+
+## APIs
+
+### BasicNode.Preview 预览组件
+
+| 属性名 | 类型 | 描述 | 默认值 | 必选 |
+| --------------------- | ----------------------------------- | -------------------------- | ------ | ---- |
+| title | `string` | 标题 | - | - |
+| onTitleChange | `(title: string) => void` | 标题变化时的回调函数 | - | - |
+| extra | `ReactNode` | 标题右侧区域 | - | - |
+| children | `ReactNode` | 子元素 ReactNode | - | - |
+| active | `boolean` | 是否激活状态 | - | - |
+| collapsedKeys | `string[]` | 折叠的键数组 | `[]` | - |
+| onCollapsedKeysChange | `(collapsedKeys: string[]) => void` | 折叠键数组变化时的回调函数 | - | - |
+| style | `CSSProperties` | 自定义样式 | - | - |
+| className | `string` | 自定义类名 | - | - |
+
+### BasicNode 组件
+
+在 Preview 基础上:
+
+| 属性名 | 类型 | 描述 | 默认值 | 必选 |
+| ------ | -------- | ------- | ------ | ---- |
+| id | `string` | 节点 Id | - | 是 |
diff --git a/src/BloodNode/index.tsx b/src/BloodNode/index.tsx
new file mode 100644
index 0000000..f692deb
--- /dev/null
+++ b/src/BloodNode/index.tsx
@@ -0,0 +1,107 @@
+import { createStyles } from 'antd-style';
+
+const useStyles = createStyles(({ css }) => ({
+ nodeWrap: css`
+ width: 320px;
+ height: 85px;
+ display: flex;
+ z-index: 10 !important;
+ position: absolute;
+ border-radius: 12px;
+ padding: 16px 12px;
+ background-color: white;
+ box-sizing: border-box;
+ /* border: 3px solid white; */
+ flex: 1;
+
+ .img {
+ width: 48px;
+ height: 48px;
+ }
+
+ .content {
+ width: 230px;
+ margin-left: 13px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: flex-start;
+
+ .title {
+ width: 100%;
+ display: flex;
+ flex: 1;
+
+ span {
+ font-size: 16px;
+ color: rgba(0, 0, 0, 85%);
+ line-height: 22px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-align: left;
+ }
+
+ .dangerLogo {
+ width: 28px;
+ height: 16px;
+ background: #ffeef1;
+ border-radius: 7px;
+ margin-left: 8px;
+ margin-top: 3px;
+ img {
+ width: 8px;
+ height: 9px;
+ }
+ }
+ }
+
+ .des {
+ font-size: 14px;
+ color: rgba(0, 0, 0, 45%);
+ line-height: 20px;
+ white-space: nowrap;
+ width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-align: left;
+ }
+ }
+ `,
+}));
+
+interface BloodNodeProps {
+ logo: string;
+ title: string;
+ titleFlex: string;
+ description: string;
+ showIcon: boolean;
+ icon: string;
+}
+
+const BloodNode: React.FC> = ({
+ logo,
+ title,
+ // titleFlex,
+ description,
+ // showIcon,
+ // icon,
+}) => {
+ const { styles } = useStyles();
+
+ return (
+
+
+
+
+
{title}
+ {/* {mainDanger &&
}
+ {qualityScore &&
} */}
+
+
{description}
+
+
+ );
+};
+
+export default BloodNode;