{
console.log("LABEL:", label);
diff --git a/package.json b/package.json
index 2c837a0..8d8cdf0 100644
--- a/package.json
+++ b/package.json
@@ -1,35 +1,37 @@
{
- "name": "rspress-doc-template",
+ "name": "@proformily/antd",
"version": "1.0.0",
"private": true,
"scripts": {
- "dev": "rspress dev",
+ "d4": "node scripts/switch.js antd dev && rspress dev",
+ "d5": "node scripts/switch.js antd dev && rspress dev",
"build:docs": "rspress build",
"preview": "rspress preview"
},
"dependencies": {
"@ant-design/icons": "^5.2.6",
- "@formily/antd": "^2.3.1",
"@formily/core": "^2.3.1",
"@formily/react": "^2.3.1",
"@formily/reactive": "^2.3.1",
"@formily/shared": "^2.3.1",
"ahooks": "^3.7.8",
- "antd": "^4.24.15",
"moment": "^2.30.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-resizable": "^3.0.5"
+ "react-resizable": "^3.0.5",
+ "@formily/antd": "^2.*.*",
+ "antd": "^4.*.*"
},
"devDependencies": {
- "rspress": "^1.9.3",
"@biomejs/biome": "^1.5.0",
+ "@faker-js/faker": "^8.3.1",
"@rsbuild/plugin-react": "^0.2.18",
"@rspress/plugin-preview": "^1.9.3",
+ "@types/node": "^16.18.70",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"@types/react-resizable": "^3.0.7",
- "@faker-js/faker": "^8.3.1",
- "@types/node": "^16.18.70"
+ "rimraf": "^5.0.5",
+ "rspress": "^1.9.3"
}
}
diff --git a/rsbuild.config.ts b/rsbuild.config.ts
index 7204815..90214d9 100644
--- a/rsbuild.config.ts
+++ b/rsbuild.config.ts
@@ -6,7 +6,7 @@ export default defineConfig({
plugins: [pluginReact()],
source: {
alias: {
- proformily: path.resolve(__dirname, "./src"),
+ // proformily: path.resolve(__dirname, "./src"),
},
},
tools: {
diff --git a/rspress.config.ts b/rspress.config.ts
index 5a1f485..f86460b 100644
--- a/rspress.config.ts
+++ b/rspress.config.ts
@@ -4,7 +4,7 @@ import { defineConfig } from "rspress/config";
import RsBuildConfig from "./rsbuild.config";
export default defineConfig({
- base: "/pro.formily/",
+ base: "/proformily-antd/",
root: path.join(__dirname, "docs"),
title: "ProFormily",
description: "Pro Formily, 启动!",
diff --git a/scripts/patch.js b/scripts/patch.js
new file mode 100644
index 0000000..d1931ad
--- /dev/null
+++ b/scripts/patch.js
@@ -0,0 +1,27 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+
+const cssPath = path.resolve(
+ __dirname,
+ "../node_modules/@rspress/theme-default/dist/bundle.css",
+);
+
+if (fs.existsSync(cssPath)) {
+ const css = fs.readFileSync(cssPath, "utf-8").toString();
+ const neo = css.replace(
+ `
+[type=submit] {
+ -webkit-appearance: button;
+ background-color: transparent;
+ background-image: none;
+}`.trim(),
+ `
+[type=submit] {
+ -webkit-appearance: button;
+ background-image: none;
+}
+`,
+ );
+ fs.writeFileSync(cssPath, neo, "utf-8");
+}
diff --git a/scripts/read.js b/scripts/read.js
new file mode 100644
index 0000000..56d83e2
--- /dev/null
+++ b/scripts/read.js
@@ -0,0 +1,28 @@
+const { execSync } = require("child_process");
+const fs = require("fs");
+const path = require("path");
+const argv = process.argv.slice(2);
+const adaptor = argv[0];
+const mode = argv[1];
+const rmrf = require("rimraf");
+
+const loop = (filepath, it) => {
+ if (fs.existsSync(filepath)) {
+ const isDir = fs.statSync(filepath).isDirectory();
+ if (isDir) {
+ fs.readdirSync(filepath).forEach((sub) => {
+ loop(path.join(filepath, sub), it);
+ });
+ } else {
+ it(path.join(filepath));
+ }
+ }
+};
+
+const docs = () => {
+ loop(path.join(__dirname, "../docs"), (item) => {
+ console.log(item);
+ });
+};
+
+docs();
diff --git a/scripts/switch.js b/scripts/switch.js
new file mode 100644
index 0000000..47a255b
--- /dev/null
+++ b/scripts/switch.js
@@ -0,0 +1,120 @@
+const { execSync } = require("child_process");
+const fs = require("fs");
+const path = require("path");
+const argv = process.argv.slice(2);
+const adaptor = argv[0];
+const mode = argv[1];
+const rmrf = require("rimraf");
+
+if (!/antd|antd-v5/.test(adaptor)) {
+ throw new Error(`适配库${adaptor}不存在`);
+}
+
+const rewite = (filePath, writer) => {
+ const old = fs.readFileSync(filePath).toString();
+ const neo = writer(old);
+ if (neo === old) return;
+ fs.writeFileSync(filePath, neo);
+};
+
+const files = ["tsconfig.json", "package.json", "rspress.config.ts"].map(
+ (item) => {
+ return path.resolve(__dirname, `../${item}`);
+ },
+);
+
+const loop = (filepath, it) => {
+ if (fs.existsSync(filepath)) {
+ const isDir = fs.statSync(filepath).isDirectory();
+ if (isDir) {
+ fs.readdirSync(filepath).forEach((sub) => {
+ loop(path.join(filepath, sub), it);
+ });
+ } else {
+ it(path.join(filepath));
+ }
+ }
+};
+
+const docs = () => {
+ const list = [];
+ loop(path.join(__dirname, "../docs"), (item) => {
+ list.push(item);
+ });
+ return list;
+};
+
+docs()
+ .filter((x) => /\.(mdx|md|tsx|ts|js|js)$/.test(x))
+ .forEach((item) => {
+ rewite(item, (c) => {
+ if (adaptor === "antd") {
+ return c
+ .replace("formily/antd-v5", "formily/antd")
+ .replace("antd/dist/reset.css", "antd/dist/antd.css");
+ } else {
+ return c
+ .replace("formily/antd", "formily/antd-v5")
+ .replace("antd/dist/antd.css", "antd/dist/reset.css");
+ }
+ });
+ });
+
+files.forEach((item) => {
+ rewite(item, (c) => {
+ if (adaptor === "antd") {
+ return c
+ .replace("formily/antd-v5", "formily/antd")
+ .replace("proformily-antd-v5", "proformily-antd");
+ } else {
+ return c
+ .replace("formily/antd", "formily/antd-v5")
+ .replace("proformily-antd", "proformily-antd-v5");
+ }
+ });
+});
+
+const shadow = path.resolve(__dirname, "../src/adaptor");
+const ui = path.resolve(__dirname, `../ui/${adaptor}`);
+
+rmrf.sync(shadow);
+
+// 开发用软连接就好了
+if (mode === "dev") {
+ execSync(`rm -rf ${shadow}`);
+ execSync(`ln -s ${ui} ${shadow}`);
+} else {
+ execSync(`rm -rf ${shadow}`);
+ execSync(`cp -R ${ui} ${shadow}`);
+}
+const pkgPath = path.resolve(__dirname, "../package.json");
+const pkg = JSON.parse(fs.readFileSync(pkgPath));
+const adaptorPkg = JSON.parse(fs.readFileSync(`${ui}/package.json`));
+
+const deps = {
+ "@ant-design/icons": "^5.2.6",
+ "@formily/core": "^2.3.1",
+ "@formily/react": "^2.3.1",
+ "@formily/reactive": "^2.3.1",
+ "@formily/shared": "^2.3.1",
+ ahooks: "^3.7.8",
+ moment: "^2.30.1",
+ react: "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-resizable": "^3.0.5",
+};
+
+// sed -i 's/@proformily\/antd/@proformily\/antd-v5/g' *
+fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), "utf-8");
+
+if (!pkg.dependencies[`@formily/${adaptor}`]) {
+ pkg.dependencies = {
+ ...deps,
+ ...adaptorPkg.dependencies,
+ };
+ rmrf.sync(path.resolve(__dirname, "../node_modules"));
+}
+
+rmrf.sync(path.resolve(__dirname, "../doc_build"));
+execSync("bun i");
+console.log("ready for --", adaptor);
diff --git a/src/adaptor b/src/adaptor
new file mode 120000
index 0000000..1bf5f86
--- /dev/null
+++ b/src/adaptor
@@ -0,0 +1 @@
+/Users/chao/Lab/proformily/ui/antd
\ No newline at end of file
diff --git a/src/array-table-pro/features/hooks.ts b/src/array-table-pro/features/hooks.ts
index bad29fb..c457ce5 100644
--- a/src/array-table-pro/features/hooks.ts
+++ b/src/array-table-pro/features/hooks.ts
@@ -26,7 +26,7 @@ type SupportedProps = {
expandable: IExpandableProps;
};
export const useArrayCompPropsOf =
(
- field: GeneralField,
+ field: GeneralField | undefined,
key: K,
) => {
const $props = (field?.componentProps as any)?.[key];
diff --git a/src/array-table-pro/features/pro-settings.tsx b/src/array-table-pro/features/pro-settings.tsx
index fb82e46..1856555 100644
--- a/src/array-table-pro/features/pro-settings.tsx
+++ b/src/array-table-pro/features/pro-settings.tsx
@@ -8,14 +8,6 @@ import {
import { toJS } from "@formily/reactive";
import useCreation from "ahooks/es/useCreation";
import React, { useMemo } from "react";
-import {
- Checkbox,
- FormItem,
- Input,
- NumberPicker,
- PreviewText,
- Radio,
-} from "../../deps/peer";
import {
Button,
ColumnHeightOutlined,
@@ -25,7 +17,15 @@ import {
SettingOutlined,
Slider,
Space,
-} from "../../deps/ui";
+} from "../../adaptor";
+import {
+ Checkbox,
+ FormItem,
+ Input,
+ NumberPicker,
+ PreviewText,
+ Radio,
+} from "../../adaptor/adaptor";
import { useArrayTableColumns } from "../hooks";
import { ArrayTablePro } from "../pro";
diff --git a/src/array-table-pro/features/sortable.tsx b/src/array-table-pro/features/sortable.tsx
index 7f17b7a..cfdcd32 100644
--- a/src/array-table-pro/features/sortable.tsx
+++ b/src/array-table-pro/features/sortable.tsx
@@ -1,4 +1,4 @@
-import { builtins } from "../../deps/peer";
+import { builtins } from "../../adaptor/adaptor";
const { SortableContainer, SortableElement, usePrefixCls } = builtins;
import { ReactFC, useFieldSchema } from "@formily/react";
import cls from "classnames";
diff --git a/src/array-table-pro/hooks.tsx b/src/array-table-pro/hooks.tsx
index 89540c4..db1413e 100644
--- a/src/array-table-pro/hooks.tsx
+++ b/src/array-table-pro/hooks.tsx
@@ -4,7 +4,7 @@ import { RecursionField, useField, useFieldSchema } from "@formily/react";
import { isArr } from "@formily/shared";
import { useState } from "react";
import type { ResizeCallbackData } from "react-resizable";
-import { ArrayBase, ColumnsType } from "../deps/peer";
+import { ArrayBase, ColumnsType } from "../adaptor/adaptor";
import {
isAdditionComponent,
isColumnComponent,
@@ -200,7 +200,10 @@ export const useExpandRender = (index: number) => {
return schema.reduceProperties((expand, schema, key) => {
if (isExpandComponent(schema)) {
return (
- array.field.value?.[index]}>
+ array?.field.value?.[index]}
+ >
);
diff --git a/src/array-table-pro/mixin.tsx b/src/array-table-pro/mixin.tsx
index 167f138..5ea820a 100644
--- a/src/array-table-pro/mixin.tsx
+++ b/src/array-table-pro/mixin.tsx
@@ -1,8 +1,7 @@
-import { ArrayBaseMixins } from "@formily/antd";
import { ReactFC, observer } from "@formily/react";
import React, { Fragment } from "react";
-import { ArrayBase, ColumnProps } from "../deps/peer";
-import { Alert, Button, Divider, Space } from "../deps/ui";
+import { Alert, Button, Divider, Space } from "../adaptor";
+import { ArrayBase, ArrayBaseMixins, ColumnProps } from "../adaptor/adaptor";
import { useArrayCompPropsOf } from "./features/hooks";
export const Column: ReactFC> = () => {
@@ -14,7 +13,7 @@ export const RowExpand: ReactFC> = () => {
export const Addition: ArrayBaseMixins["Addition"] = observer((props) => {
const array = ArrayBase.useArray();
- const [, $page] = useArrayCompPropsOf(array.field, "pagination");
+ const [, $page] = useArrayCompPropsOf(array?.field, "pagination");
return (
{
const { ds, rowKey } = props;
const array = ArrayBase.useArray();
- const [, $row] = useArrayCompPropsOf(array.field, "rowSelection");
+ const [, $row] = useArrayCompPropsOf(array?.field, "rowSelection");
return ds.length > 0 ? (
= observer((props) => {
const ref = useRef(null);
const field = useField();
const prefixCls = usePrefixCls("formily-array-table");
+ const [wrapSSR, hasId] = useStyle(prefixCls);
/**
* 优化笔记:
* 本来以为这个 slice 没什么用,直到我膝盖中了一箭
@@ -144,10 +146,10 @@ const ProArrayTable: ReactFC = observer((props) => {
);
- return (
+ return wrapSSR(
{_header}
-
+
= observer((props) => {
key,
});
})}
-
+ ,
);
});
diff --git a/src/array-table-pro/types.tsx b/src/array-table-pro/types.tsx
index 7f33ca0..c65e875 100644
--- a/src/array-table-pro/types.tsx
+++ b/src/array-table-pro/types.tsx
@@ -1,6 +1,6 @@
import { FieldDisplayTypes, GeneralField } from "@formily/core";
import { Schema } from "@formily/json-schema";
-import type { ColumnProps, TableProps } from "../deps/peer";
+import type { ColumnProps, TableProps } from "../adaptor/adaptor";
type TableChangeParams = Parameters>["onChange"]>;
diff --git a/src/index.ts b/src/index.ts
index 5068243..ad38292 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,7 +1,5 @@
-import "./style";
export * from "./array-table-pro";
+export * from "./array-table-pro/features/hooks";
+export * from "./query-list";
export * from "./query-form";
export * from "./query-table";
-export * from "./query-list";
-
-export { Overview } from "./overview";
diff --git a/src/query-form/index.tsx b/src/query-form/index.tsx
index e5603bf..d9fe35f 100644
--- a/src/query-form/index.tsx
+++ b/src/query-form/index.tsx
@@ -2,9 +2,9 @@ import { DownOutlined, UpOutlined } from "@ant-design/icons";
import type { ObjectField } from "@formily/core";
import { observer, useField } from "@formily/react";
import { clone } from "@formily/shared";
-import { Button } from "antd";
import React, { useEffect } from "react";
-import { FormButtonGroup, FormGrid, FormLayout } from "../deps/peer";
+import { Button } from "../adaptor";
+import { FormButtonGroup, FormGrid, FormLayout } from "../adaptor/adaptor";
import { useQueryListContext } from "../query-list";
import { useGrid } from "./useGrid";
diff --git a/src/query-form/useGrid.tsx b/src/query-form/useGrid.tsx
index a0b7254..b3c09e2 100644
--- a/src/query-form/useGrid.tsx
+++ b/src/query-form/useGrid.tsx
@@ -1,5 +1,5 @@
import React, { useMemo } from "react";
-import { FormGrid } from "../deps/peer";
+import { FormGrid } from "../adaptor/adaptor";
export const useGrid = (conf: React.ComponentProps = {}) => {
const maxRows = conf.maxRows || 2;
diff --git a/src/query-list/index.tsx b/src/query-list/index.tsx
index 37d902c..1e008a9 100644
--- a/src/query-list/index.tsx
+++ b/src/query-list/index.tsx
@@ -8,8 +8,8 @@ import React, {
useRef,
useState,
} from "react";
-import { noop } from "src/__builtins__";
-import type { TableProps } from "../deps/ui";
+import { noop } from "../__builtins__";
+import type { TableProps } from "../adaptor";
type TableChangeParams = Parameters>["onChange"]>;
diff --git a/src/query-table/index.tsx b/src/query-table/index.tsx
index de23583..0225ed1 100644
--- a/src/query-table/index.tsx
+++ b/src/query-table/index.tsx
@@ -2,10 +2,10 @@ import type { ArrayField } from "@formily/core";
import { observer, useField } from "@formily/react";
import { useEffect } from "react";
import { ArrayTableProProps } from "src/array-table-pro/types";
+import { TablePaginationConfig } from "../adaptor";
+import { ArrayBase } from "../adaptor/adaptor";
import { Addition, Column, RowExpand } from "../array-table-pro/mixin";
import { ArrayTablePro } from "../array-table-pro/pro";
-import { ArrayBase } from "../deps/peer";
-import { TablePaginationConfig } from "../deps/ui";
import { useQueryListContext } from "../query-list";
export const QueryTablePro = observer((overprops: ArrayTableProProps) => {
diff --git a/src/style.ts b/src/style.ts
index 255d9e9..7d3dc81 100644
--- a/src/style.ts
+++ b/src/style.ts
@@ -1 +1 @@
-import "./array-table-pro/style";
+import "./adaptor/themes/index";
diff --git a/tsconfig.json b/tsconfig.json
index 129c9bd..986efb2 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,8 +13,12 @@
"declaration": true,
"moduleResolution": "node",
"paths": {
- "proformily": ["./src"]
+ "@proformily/antd": ["src"]
}
},
- "include": ["src", "docs"]
+ "include": [
+ "src",
+ "docs",
+ "ui",
+ ]
}
diff --git a/src/deps/README.md b/ui/antd-v5/README.md
similarity index 100%
rename from src/deps/README.md
rename to ui/antd-v5/README.md
diff --git a/ui/antd-v5/adaptor.ts b/ui/antd-v5/adaptor.ts
new file mode 100644
index 0000000..7af89cf
--- /dev/null
+++ b/ui/antd-v5/adaptor.ts
@@ -0,0 +1,18 @@
+export * as builtins from "@formily/antd-v5/esm/__builtins__";
+export {
+ FormGrid,
+ FormButtonGroup,
+ FormLayout,
+ Checkbox,
+ FormItem,
+ Input,
+ NumberPicker,
+ PreviewText,
+ Radio,
+} from "@formily/antd-v5";
+
+import { ArrayBase as AntdArrayBase } from "@formily/antd-v5";
+export type { ArrayBaseMixins } from "@formily/antd-v5";
+// 类型fix
+export const ArrayBase = AntdArrayBase;
+export type { ColumnsType, ColumnProps, TableProps } from "antd/es/table";
diff --git a/src/deps/ui.ts b/ui/antd-v5/index.ts
similarity index 100%
rename from src/deps/ui.ts
rename to ui/antd-v5/index.ts
diff --git a/ui/antd-v5/package.json b/ui/antd-v5/package.json
new file mode 100644
index 0000000..2ced4a4
--- /dev/null
+++ b/ui/antd-v5/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "antd",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@formily/antd-v5": "^1.*.*",
+ "antd": "^5.*.*"
+ }
+}
diff --git a/ui/antd-v5/themes/array-table-pro/useStyle.ts b/ui/antd-v5/themes/array-table-pro/useStyle.ts
new file mode 100644
index 0000000..4af0622
--- /dev/null
+++ b/ui/antd-v5/themes/array-table-pro/useStyle.ts
@@ -0,0 +1,63 @@
+import { builtins } from "../../adaptor";
+
+export default builtins.genStyleHook("array-table", (token) => {
+ const {
+ componentCls,
+ antCls,
+ colorErrorBorder,
+ fontSizeSM,
+ colorBgBase,
+ colorBorder,
+ colorBgContainer,
+ } = token;
+ const itemCls = `${antCls}-formily-item`;
+
+ return {
+ [componentCls]: {
+ [`${componentCls}-pagination`]: {
+ display: "flex",
+ justifyContent: "center",
+
+ [`${componentCls}-status-select.has-error`]: {
+ [`${antCls}-select-selector`]: {
+ borderColor: `${colorErrorBorder} !important`,
+ },
+ },
+ },
+ [`${antCls}-table`]: {
+ td: {
+ visibility: "visible",
+ [`${itemCls}:not(${itemCls}-feedback-layout-popover)`]: {
+ marginBottom: "0 !important",
+
+ [`${itemCls}-help`]: {
+ position: "absolute",
+ fontSize: fontSizeSM,
+ top: "100%",
+ background: colorBgBase,
+ width: "100%",
+ marginTop: 3,
+ padding: 3,
+ zIndex: 1,
+ borderRadius: 3,
+ boxShadow: `0 0 10px ${colorBorder}`,
+ animation: "none",
+ transform: "translateY(0)",
+ opacity: 1,
+ },
+ },
+ },
+
+ table: {
+ overflow: "hidden",
+ },
+ },
+
+ [`${componentCls}-sort-helper`]: {
+ background: colorBgContainer,
+ border: `1px solid ${colorBorder}`,
+ zIndex: 10,
+ },
+ },
+ };
+});
diff --git a/ui/antd-v5/themes/index.ts b/ui/antd-v5/themes/index.ts
new file mode 100644
index 0000000..4b2a726
--- /dev/null
+++ b/ui/antd-v5/themes/index.ts
@@ -0,0 +1,2 @@
+// @ts-ignore
+// 什么都没有,为了适配 antd-v4 那个文件
diff --git a/ui/antd/README.md b/ui/antd/README.md
new file mode 100644
index 0000000..c1b1d1d
--- /dev/null
+++ b/ui/antd/README.md
@@ -0,0 +1 @@
+声明外部依赖, 方便迁移
diff --git a/src/deps/peer.ts b/ui/antd/adaptor.ts
similarity index 89%
rename from src/deps/peer.ts
rename to ui/antd/adaptor.ts
index 61959ce..ea78b91 100644
--- a/src/deps/peer.ts
+++ b/ui/antd/adaptor.ts
@@ -10,7 +10,9 @@ export {
PreviewText,
Radio,
} from "@formily/antd";
+
import { ArrayBase as AntdArrayBase } from "@formily/antd";
+export type { ArrayBaseMixins } from "@formily/antd";
// 类型fix
export const ArrayBase = AntdArrayBase as Required &
typeof AntdArrayBase;
diff --git a/ui/antd/index.ts b/ui/antd/index.ts
new file mode 100644
index 0000000..c866520
--- /dev/null
+++ b/ui/antd/index.ts
@@ -0,0 +1,16 @@
+export { ColumnHeightOutlined, SettingOutlined } from "@ant-design/icons";
+export {
+ Alert,
+ Divider,
+ Pagination,
+ Table,
+ Button,
+ ConfigProvider,
+ Popover,
+ Row,
+ Slider,
+ Space,
+ Typography,
+} from "antd";
+
+export type { TablePaginationConfig, TableProps } from "antd";
diff --git a/ui/antd/package.json b/ui/antd/package.json
new file mode 100644
index 0000000..194fac6
--- /dev/null
+++ b/ui/antd/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "antd",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@formily/antd": "^2.*.*",
+ "antd": "^4.*.*"
+ }
+}
diff --git a/src/array-table-pro/style.less b/ui/antd/themes/array-table-pro/style.less
similarity index 100%
rename from src/array-table-pro/style.less
rename to ui/antd/themes/array-table-pro/style.less
diff --git a/src/array-table-pro/style.ts b/ui/antd/themes/array-table-pro/style.ts
similarity index 100%
rename from src/array-table-pro/style.ts
rename to ui/antd/themes/array-table-pro/style.ts
diff --git a/ui/antd/themes/array-table-pro/useStyle.ts b/ui/antd/themes/array-table-pro/useStyle.ts
new file mode 100644
index 0000000..680522c
--- /dev/null
+++ b/ui/antd/themes/array-table-pro/useStyle.ts
@@ -0,0 +1 @@
+export default () => [(x: T) => x, ""] as const;
diff --git a/ui/antd/themes/index.ts b/ui/antd/themes/index.ts
new file mode 100644
index 0000000..255d9e9
--- /dev/null
+++ b/ui/antd/themes/index.ts
@@ -0,0 +1 @@
+import "./array-table-pro/style";
diff --git a/src/overview/index.tsx b/ui/overview/index.tsx
similarity index 100%
rename from src/overview/index.tsx
rename to ui/overview/index.tsx
diff --git a/src/overview/overview.less b/ui/overview/overview.less
similarity index 100%
rename from src/overview/overview.less
rename to ui/overview/overview.less