├── .dumirc.ts ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .husky └── pre-commit ├── .prettierrc ├── README.md ├── docs ├── functions │ ├── cartesian │ │ ├── index.en-US.md │ │ ├── index.zh-CN.md │ │ └── nearestPoint │ │ │ ├── index.en-US.md │ │ │ └── index.zh-CN.md │ ├── dataType │ │ ├── demos │ │ │ ├── demo.tsx │ │ │ └── demo1.tsx │ │ ├── index.en-US.md │ │ └── index.zh-CN.md │ ├── index.en-US.md │ └── index.zh-CN.md ├── guide │ └── introduce │ │ ├── index.en-US.md │ │ └── index.zh-CN.md ├── hooks │ └── useEcharts.ts ├── index.en-US.md ├── index.zh-CN.md └── siteIndexStyle.ts ├── index.html ├── package.json ├── packages ├── data-design │ ├── cartesian │ │ ├── index.ts │ │ └── minDistancePoint.ts │ ├── dataDesign.ts │ ├── dataType │ │ ├── builtIn.ts │ │ └── index.ts │ ├── geo │ │ ├── index.ts │ │ ├── isPointInCircle.ts │ │ └── isPtInPoly.ts │ ├── index.ts │ ├── register.ts │ ├── transforms │ │ ├── array │ │ │ ├── filter.ts │ │ │ ├── map.ts │ │ │ ├── partition.ts │ │ │ ├── pick.ts │ │ │ ├── rename.ts │ │ │ ├── reverse.ts │ │ │ ├── sort-by.ts │ │ │ └── sort.ts │ │ ├── index.ts │ │ ├── tree │ │ │ ├── flatTree.ts │ │ │ └── toTree.ts │ │ └── utils │ │ │ ├── partition.ts │ │ │ └── simple-sort-by.ts │ └── type.ts └── share │ └── index.ts ├── pnpm-lock.yaml ├── src ├── App.tsx ├── main.tsx └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.dumirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'dumi' 2 | import style from './docs/siteIndexStyle' 3 | import path from 'path' 4 | // import { version } from './package.json' 5 | 6 | export default defineConfig({ 7 | favicons: [ 8 | 'https://gw.alipayobjects.com/zos/bmw-prod/d3e3eb39-1cd7-4aa5-827c-877deced6b7e/lalxt4g3_w256_h256.png', 9 | ], 10 | autoAlias: false, 11 | outputPath: 'docs-dist', 12 | history: { 13 | type: 'hash', 14 | }, 15 | resolve: { 16 | codeBlockMode: 'passive', 17 | }, 18 | alias: { 19 | 'data-design': path.join(__dirname, 'packages/data-design'), 20 | }, 21 | locales: [ 22 | { id: 'en-US', name: 'English', suffix: '' }, 23 | { id: 'zh-CN', name: '中文', suffix: '/zh-CN' }, 24 | ], 25 | themeConfig: { 26 | name: 'Data-Design', 27 | // carrier: 'dumi', // 设备状态栏左侧的文本内容 28 | hd: { rules: [] }, 29 | rtl: true, 30 | logo: 'https://gw.alipayobjects.com/zos/bmw-prod/d3e3eb39-1cd7-4aa5-827c-877deced6b7e/lalxt4g3_w256_h256.png', 31 | searchHotKey: { 32 | macos: '⌘+K', 33 | windows: 'ctrl+k', 34 | }, 35 | footer: '', 36 | nav: [ 37 | { 38 | title: 'Introduce', 39 | link: '/guide/introduce', 40 | }, 41 | { 42 | title: 'Functions', 43 | link: '/functions', 44 | }, 45 | ], 46 | }, 47 | styles: [style], 48 | }) 49 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules 3 | node_modules/ 4 | patches/ 5 | types/ 6 | !packages/.vitepress 7 | !/.eslintrc.js 8 | !/rollup.config.js 9 | !.test 10 | .temp -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true, 6 | es6: true, 7 | }, 8 | parserOptions: { 9 | ecmaVersion: 6, 10 | sourceType: 'module', 11 | impliedStrict: true, 12 | }, 13 | parser: '@typescript-eslint/parser', 14 | extends: [ 15 | 'eslint:recommended', 16 | 'plugin:@typescript-eslint/eslint-recommended', 17 | 'plugin:@typescript-eslint/recommended', 18 | ], 19 | plugins: ['@typescript-eslint'], 20 | rules: { 21 | 'no-sparse-arrays': 0, 22 | 'no-inner-declarations': 0, 23 | '@typescript-eslint/indent': 0, 24 | 'no-constant-condition': 0, 25 | '@typescript-eslint/no-empty-function': 0, 26 | '@typescript-eslint/explicit-member-accessibility': [2, { accessibility: 'no-public' }], 27 | '@typescript-eslint/no-non-null-assertion': 0, 28 | // '@typescript-eslint/explicit-function-return-type': [1, { allowExpressions: true }], 29 | '@typescript-eslint/no-use-before-define': [2, { functions: false }], 30 | '@typescript-eslint/no-namespace': 0, 31 | '@typescript-eslint/ban-ts-ignore': 0, 32 | '@typescript-eslint/no-empty-interface': 1, 33 | '@typescript-eslint/camelcase': 0, 34 | '@typescript-eslint/no-explicit-any': 0, 35 | '@typescript-eslint/no-var-requires': 0, 36 | // eslint-disable-next-line no-dupe-keys 37 | '@typescript-eslint/explicit-function-return-type': 'off', 38 | 'no-unused-vars': [ 39 | 2, 40 | { 41 | // 允许声明未使用变量 42 | vars: 'local', 43 | // 参数不检查 44 | args: 'none', 45 | }, 46 | ], 47 | 'node/no-callback-literal': 'off', 48 | 'import/namespace': 'off', 49 | 'import/default': 'off', 50 | 'import/no-named-as-default': 'off', 51 | 'import/no-named-as-default-member': 'off', 52 | }, 53 | } 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | .dumi 10 | 11 | node_modules 12 | dist 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "semi": false, 4 | "vueIndentScriptAndStyle": true, 5 | "singleQuote": true, 6 | "trailingComma": "all", 7 | "proseWrap": "never", 8 | "htmlWhitespaceSensitivity": "strict", 9 | "endOfLine": "auto" 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data-design 2 | 用于构建标准数据处理的库 3 | 4 | ## 📚 Documentation 5 | - 6 | ## ✨ Features 7 | 8 | - Easy to learn and use 9 | - Supports SSR 10 | - Written in TypeScript with predictable static types 11 | - Support the on-demand load, and reduce the packing volume 12 | 13 | ## 📦 Install 14 | 15 | ``` 16 | $ npm install --save data-design 17 | # or 18 | $ yarn add data-design 19 | ``` 20 | 21 | ## 🔨 Usage 22 | 23 | ```typescript 24 | import { transform, dataType } from 'data-design' 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/functions/cartesian/index.en-US.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: Cartesian 4 | --- 5 | 6 | # Cartesian 7 | 8 | 123 9 | -------------------------------------------------------------------------------- /docs/functions/cartesian/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: Cartesian 4 | --- 5 | 6 | # DataType 7 | -------------------------------------------------------------------------------- /docs/functions/cartesian/nearestPoint/index.en-US.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: Cartesian 3 | group: 4 | title: Basic 5 | order: 0 6 | order: 0 7 | --- 8 | 9 | 123 10 | -------------------------------------------------------------------------------- /docs/functions/cartesian/nearestPoint/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: Cartesian 3 | group: 4 | title: 基础 5 | order: 0 6 | order: 0 7 | --- 8 | 9 | 312 10 | -------------------------------------------------------------------------------- /docs/functions/dataType/demos/demo.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react' 2 | 3 | import { dataType } from 'data-design' 4 | 5 | const Demo = () => { 6 | const target = 'test' 7 | 8 | const result = useMemo(() => dataType({ target, type: 'isArray' }), []) 9 | // dataGeo({type:"isPointInCircle",}) 10 | 11 | return ( 12 |
13 |
Target: {target}
14 |
Resul: {result ? 'yes' : 'no'}
15 |
16 | ) 17 | } 18 | 19 | export default Demo 20 | -------------------------------------------------------------------------------- /docs/functions/dataType/demos/demo1.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react' 2 | 3 | import { dataType } from 'data-design' 4 | 5 | const Demo = () => { 6 | const target = 'test' 7 | 8 | const result = useMemo(() => dataType({ target, type: 'isObject' }), []) 9 | 10 | return ( 11 |
12 |
Target: {target}
13 |
Resul: {result ? 'yes' : 'no'}
14 |
15 | ) 16 | } 17 | 18 | export default Demo 19 | -------------------------------------------------------------------------------- /docs/functions/dataType/index.en-US.md: -------------------------------------------------------------------------------- 1 | # DataType 2 | 3 | ## isArray 4 | 5 | 6 | 7 |
8 | 9 | ## isObject 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/functions/dataType/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | # Cartesian 2 | 3 | ## isArray 4 | 5 | 6 | 7 |
8 | 9 | ## isObject 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/functions/index.en-US.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | - [DataType](./dataType) 4 | -------------------------------------------------------------------------------- /docs/functions/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | - [DataType](./dataType) 4 | -------------------------------------------------------------------------------- /docs/guide/introduce/index.en-US.md: -------------------------------------------------------------------------------- 1 | # Introduce 2 | -------------------------------------------------------------------------------- /docs/guide/introduce/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | -------------------------------------------------------------------------------- /docs/hooks/useEcharts.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react' 2 | import { useEventListener } from 'ahooks' 3 | 4 | import * as echarts from 'echarts' 5 | import type { EChartsOption, EChartsType } from 'echarts' 6 | 7 | /** 8 | * 调用 echarts hook 9 | */ 10 | function useEcharts(options?: { defaultOptions?: EChartsOption }): { 11 | chart: React.MutableRefObject 12 | container: React.RefObject 13 | } { 14 | const { defaultOptions } = options ?? {} 15 | const container = useRef(null) 16 | const chart = useRef() 17 | const optionsRef = useRef(defaultOptions) 18 | 19 | useEffect(() => { 20 | if (!container.current) { 21 | return 22 | } 23 | 24 | const myEcharts = echarts.init(container.current) 25 | chart.current = myEcharts 26 | 27 | if (optionsRef.current) { 28 | myEcharts.setOption(optionsRef.current) 29 | } 30 | }, []) 31 | 32 | useEffect(() => { 33 | return () => { 34 | chart.current?.dispose?.() 35 | chart.current?.off?.('*') 36 | chart.current = undefined 37 | } 38 | }, []) 39 | 40 | useEventListener('resize', () => { 41 | requestAnimationFrame(() => { 42 | chart?.current?.resize?.() 43 | }) 44 | }) 45 | return { chart, container } 46 | } 47 | 48 | export default useEcharts 49 | -------------------------------------------------------------------------------- /docs/index.en-US.md: -------------------------------------------------------------------------------- 1 |
2 | 用于构建标准数据处理的库 3 | 4 | ## 📚 Documentation 5 | 6 | - 7 | 8 | ## ✨ Features 9 | 10 | - Easy to learn and use 11 | - Supports SSR 12 | - Written in TypeScript with predictable static types 13 | - Support the on-demand load, and reduce the packing volume 14 | 15 | ## 📦 Install 16 | 17 | ``` 18 | $ npm install --save data-design 19 | # or 20 | $ yarn add data-design 21 | ``` 22 | 23 | ## 🔨 Usage 24 | 25 | ```typescript 26 | import { transform, dataType } from 'data-design' 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/index.zh-CN.md: -------------------------------------------------------------------------------- 1 |
2 | 用于构建标准数据处理的库 3 | 4 | ## 📚 Documentation 5 | 6 | - 7 | 8 | ## ✨ Features 9 | 10 | - Easy to learn and use 11 | - Supports SSR 12 | - Written in TypeScript with predictable static types 13 | - Support the on-demand load, and reduce the packing volume 14 | 15 | ## 📦 Install 16 | 17 | ``` 18 | $ npm install --save data-design 19 | # or 20 | $ yarn add data-design 21 | ``` 22 | 23 | ## 🔨 Usage 24 | 25 | ```typescript 26 | import { transform, dataType } from 'data-design' 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/siteIndexStyle.ts: -------------------------------------------------------------------------------- 1 | const style = ` 2 | html[data-prefers-color="dark"] .__dumi-default-layout-hero, html[data-prefers-color="light"] .__dumi-default-layout-hero { 3 | padding: 140px 0; 4 | background-image: linear-gradient( 5 | 140deg, 6 | #322c7a, 7 | #37327a, 8 | #ba7db5, 9 | #bf83b6, 10 | #472e6c, 11 | #4038a8 12 | ) 13 | } 14 | html[data-prefers-color="dark"] .__dumi-default-layout-hero h1, html[data-prefers-color="light"] .__dumi-default-layout-hero h1 { 15 | color: #f3f3f3; 16 | text-shadow: 0 4px 15px rgb(0 0 0 / 30%); 17 | font-size: 150px; 18 | margin-bottom: 50px; 19 | } 20 | @media screen and (max-width:767px) { 21 | html[data-prefers-color="dark"] .__dumi-default-layout-hero h1, html[data-prefers-color="light"] .__dumi-default-layout-hero h1 { 22 | font-size: 100px; 23 | } 24 | } 25 | html[data-prefers-color="dark"] .__dumi-default-layout-hero .markdown, html[data-prefers-color="light"] .__dumi-default-layout-hero .markdown { 26 | margin-top: 40px; 27 | color: #eee; 28 | text-shadow: 0 2px 5px rgba(0,0,0,.3); 29 | } 30 | html[data-prefers-color="dark"] .__dumi-default-layout-hero { 31 | background-color: hsla(0,0%,100%,.08); 32 | } 33 | .__dumi-default-layout-content { 34 | max-width: 100% !important; 35 | } 36 | html[data-perfers-color="dark"] .__dumi-default-previewer{ 37 | border-color: #504f4f !important; 38 | background-color: #2b2b2b !important; 39 | } 40 | html[data-perfers-color="dark"] .__dumi-default-previewer .__dumi-default-previewer-actions { 41 | border-top: none !important; 42 | } 43 | .dumi-default-sidebar::-webkit-scrollbar { 44 | width: 4px; 45 | /*height: 4px;*/ 46 | } 47 | .dumi-default-sidebar::-webkit-scrollbar-thumb { 48 | border-radius: 10px; 49 | -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2); 50 | background: rgba(0,0,0,0.2); 51 | } 52 | .dumi-default-sidebar::-webkit-scrollbar-track { 53 | -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2); 54 | border-radius: 0; 55 | background: rgba(0,0,0,0.1); 56 | } 57 | .__dumi-default-menu-list li { 58 | font-size: 14px; 59 | } 60 | .__dumi-default-navbar-logo { 61 | height: 60px !important; 62 | line-height: 60px !important; 63 | } 64 | .__dumi-default-navbar-logo:not([data-plaintext]) { 65 | padding-left: 66px !important; 66 | } 67 | .dumi-default-hero { 68 | margin: -96px auto -300px auto !important; 69 | } 70 | .dumi-default-sidebar > dl > dd { 71 | padding: 20px 0 !important; 72 | } 73 | .dumi-default-sidebar > dl > dd a { 74 | font-size: 14px !important; 75 | } 76 | .dumi-default-sidebar { 77 | width: 280px !important; 78 | } 79 | .dumi-default-header-left { 80 | width: 304px !important; 81 | } 82 | .dumi-default-navbar > li > a { 83 | font-size: 14px !important; 84 | } 85 | .dumi-default-logo img { 86 | height: 60px !important; 87 | } 88 | .dumi-default-doc-layout > main > .dumi-default-doc-layout-toc-wrapper { 89 | position: fixed !important; 90 | right: 0; 91 | } 92 | ` 93 | 94 | export default style 95 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "data-design", 3 | "private": false, 4 | "version": "1.2.0", 5 | "module": "dist/data-design.cjs.js", 6 | "main": "dist/data-design.es.js", 7 | "types": "dist/packages/index.d.ts", 8 | "keywords": [ 9 | "data-design", 10 | "typeScript" 11 | ], 12 | "scripts": { 13 | "dev": "vite", 14 | "build": "vite build", 15 | "docs:dev": "dumi dev", 16 | "docs:build": "dumi build", 17 | "preview": "vite preview" 18 | }, 19 | "lint-staged": { 20 | "*.{js,ts,tsx,vue,md}": [ 21 | "eslint --fix" 22 | ] 23 | }, 24 | "dependencies": { 25 | "js-utils-pro": "^0.0.7", 26 | "lodash": "^4.17.21" 27 | }, 28 | "devDependencies": { 29 | "@types/lodash": "^4.14.191", 30 | "@types/md5": "^2.3.2", 31 | "@types/node": "^18.7.3", 32 | "@types/prettier": "^2.6.3", 33 | "@types/react": "^18.0.17", 34 | "@types/react-dom": "^18.0.6", 35 | "@typescript-eslint/eslint-plugin": "^5.33.0", 36 | "@typescript-eslint/parser": "^5.33.0", 37 | "@vitejs/plugin-react": "^2.0.1", 38 | "ahooks": "^3.7.4", 39 | "dumi": "^2.1.5", 40 | "echarts": "^5.4.1", 41 | "eslint": "^8.20.0", 42 | "eslint-config-prettier": "^8.5.0", 43 | "eslint-plugin-prettier": "^4.2.1", 44 | "husky": "^8.0.1", 45 | "lint-staged": "^13.0.3", 46 | "prettier": "^2.7.1", 47 | "react": "^18.2.0", 48 | "react-dom": "^18.2.0", 49 | "typescript": "^4.6.4", 50 | "vite": "^3.0.7", 51 | "vite-plugin-dts": "^1.4.1", 52 | "vitepress": "1.0.0-alpha.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/data-design/cartesian/index.ts: -------------------------------------------------------------------------------- 1 | import { CartesianType } from "../type"; 2 | 3 | type CartesianFunction = (options: CartesianType[K]) => void; 4 | export class Cartesian { 5 | static cartesians: Record = {}; 6 | 7 | static register( 8 | name: K, 9 | fn: (options: CartesianType[K]) => void 10 | ): void { 11 | Cartesian.cartesians[name] = fn; 12 | } 13 | 14 | static get(name: keyof CartesianType): CartesianFunction { 15 | return Cartesian.cartesians[name] || Cartesian.cartesians.default; 16 | } 17 | static Cartesian: typeof Cartesian = Cartesian; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /packages/data-design/cartesian/minDistancePoint.ts: -------------------------------------------------------------------------------- 1 | import { Cartesian } from "."; 2 | 3 | export type NearestPointType = { 4 | dyadicArray: ({ x: number; y: number } | [number, number])[] 5 | targetPoint: [number, number] 6 | step: Partial 7 | keep: number 8 | } 9 | 10 | export function minDistancePoint({ 11 | dyadicArray, 12 | targetPoint, 13 | step = 1000, 14 | keep = -1, 15 | }: NearestPointType): any { 16 | const [targetX = null, targetY = null] = targetPoint ?? [] 17 | if (keep === -1) keep = step! 18 | 19 | if (targetX !== null && targetY !== null) { 20 | const point = 21 | dyadicArray?.filter((item) => 22 | item instanceof Array 23 | ? item[0] <= targetX + keep && 24 | item[0] >= targetX - keep && 25 | item[1] <= targetY + keep && 26 | item[1] >= targetY - keep 27 | : item.x <= targetX + keep && 28 | item.x >= targetX - keep && 29 | item.y <= targetY + keep && 30 | item.y >= targetY - keep, 31 | ) ?? [] 32 | if (point && point.length !== 0) { 33 | // 收集距离 34 | const distances = 35 | point?.map((item: any) => ({ 36 | distance: Math.sqrt(Math.pow(targetX - item.x, 2) + Math.pow(targetY - item.y, 2)), 37 | })) ?? [] 38 | // 获取最小距离 39 | const minDistance = Math.min(...(distances?.map((item) => item.distance) ?? [])) 40 | // 获取最小索引 41 | const minIndex = distances?.findIndex((item) => item.distance === minDistance) 42 | // 根据最小距离索引有效最小点集的点 43 | return point[minIndex] 44 | } else { 45 | return minDistancePoint({ 46 | dyadicArray, 47 | targetPoint, 48 | step: step + 1000, 49 | keep, 50 | }) 51 | } 52 | } 53 | 54 | return null 55 | } 56 | 57 | 58 | Cartesian.register( 59 | 'minDistancePoint', 60 | (options: NearestPointType) => { 61 | return minDistancePoint(options) 62 | } 63 | ) 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /packages/data-design/dataDesign.ts: -------------------------------------------------------------------------------- 1 | import './register' 2 | import { Transforms } from './transforms' 3 | import { Geo } from './geo' 4 | import { Cartesian } from './cartesian' 5 | import { DataType as DataTypeIntance } from './dataType' 6 | import { AddonDataType, CartesianType, GeoType, TransformType } from './type' 7 | 8 | 9 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type 10 | export const dataType = ({ 11 | type, 12 | target, 13 | }: { 14 | type: AddonDataType 15 | target: any 16 | }) => { 17 | if (DataTypeIntance?.getDataType(type)) { 18 | return DataTypeIntance?.getDataType(type)(target) 19 | } else { 20 | console.error('Type does not exist') 21 | return 22 | } 23 | } 24 | 25 | export const dataTransform = ({ 26 | type, 27 | data, 28 | ...option 29 | }: { 30 | type: K 31 | data: T 32 | } & { 33 | [P in keyof TransformType[K]]: TransformType[K][P] 34 | }) => { 35 | const transform_ = Transforms.getTransform(type) 36 | return transform_(data as T, option) 37 | } 38 | 39 | export const dataCartesian = ({ 40 | type, 41 | ...option 42 | }: { 43 | type: K 44 | } & { 45 | [P in keyof CartesianType[K]]: CartesianType[K][P] 46 | }) => { 47 | const fn = Cartesian.get(type) 48 | return fn(option) 49 | } 50 | 51 | 52 | export const dataGeo = ({ 53 | type, 54 | ...option 55 | }: { 56 | type: K 57 | } & { 58 | [P in keyof GeoType[K]]: GeoType[K][P] 59 | }) => { 60 | const fn = Geo.get(type) 61 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 62 | // @ts-ignore 63 | return fn(option) 64 | } 65 | -------------------------------------------------------------------------------- /packages/data-design/dataType/builtIn.ts: -------------------------------------------------------------------------------- 1 | export const isArray = Array.isArray 2 | const objectToString = Object.prototype.toString 3 | export const toTypeString = (value: unknown): string => objectToString.call(value) 4 | export const isMap = (val: unknown): val is Map => toTypeString(val) === '[object Map]' 5 | export const isSet = (val: unknown): val is Set => toTypeString(val) === '[object Set]' 6 | export const isDate = (val: unknown): val is Date => val instanceof Date 7 | export const isFunction = (val: unknown): val is typeof Function => typeof val === 'function' 8 | export const isString = (val: unknown): val is string => typeof val === 'string' 9 | export const isSymbol = (val: unknown): val is symbol => typeof val === 'symbol' 10 | export const isObject = (val: unknown): val is Record => 11 | val !== null && typeof val === 'object' 12 | 13 | export const isPromise = (val: unknown): val is Promise => { 14 | return isObject(val) && isFunction(val.then) && isFunction(val.catch) 15 | } 16 | -------------------------------------------------------------------------------- /packages/data-design/dataType/index.ts: -------------------------------------------------------------------------------- 1 | export class DataType { 2 | /** 3 | * 已注册的 DataType-value 键值对) 4 | */ 5 | static dataTypes: Record = {} 6 | 7 | static registerDataType(name: string, typeFn: (target: any) => boolean): void { 8 | DataType.dataTypes[name] = typeFn 9 | } 10 | static getDataType(name: string): (target: any) => boolean { 11 | return DataType.dataTypes[name] 12 | } 13 | 14 | static DataType: typeof DataType = DataType 15 | } 16 | -------------------------------------------------------------------------------- /packages/data-design/geo/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Transform(key 注册中心-- 3 | * */ 4 | 5 | import { GeoType } from "../type"; 6 | 7 | type GeoFunction = (options: GeoType[K]) => void; 8 | 9 | export class Geo { 10 | /** 11 | * 已注册的 Transform(key-value 键值对) 12 | */ 13 | static geos: Record = {}; 14 | 15 | static register( 16 | name: K, 17 | fn: (options: GeoType[K]) => void 18 | ): void { 19 | Geo.geos[name] = fn; 20 | } 21 | 22 | static get(name: keyof GeoType): GeoFunction { 23 | return Geo.geos[name] || Geo.geos.default; 24 | } 25 | static Geo: typeof Geo = Geo; 26 | } 27 | -------------------------------------------------------------------------------- /packages/data-design/geo/isPointInCircle.ts: -------------------------------------------------------------------------------- 1 | import { Geo } from '.' 2 | 3 | const isPointInCircle = ( 4 | lnglat1: { 5 | lat: number, 6 | lng: number, 7 | }, 8 | lnglat2: { 9 | lat: number, 10 | lng: number, 11 | }, 12 | radius: number 13 | ) => { 14 | const lat1 = lnglat1.lat 15 | const lng1 = lnglat1.lng 16 | const lat2 = lnglat2.lat 17 | const lng2 = lnglat2.lng 18 | const radLat1 = (lat1 * Math.PI) / 180.0; 19 | const radLat2 = (lat2 * Math.PI) / 180.0; 20 | const a = radLat1 - radLat2; 21 | const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0; 22 | let s = 23 | 2 * 24 | Math.asin( 25 | Math.sqrt( 26 | Math.pow(Math.sin(a / 2), 2) + 27 | Math.cos(radLat1) * 28 | Math.cos(radLat2) * 29 | Math.pow(Math.sin(b / 2), 2), 30 | ), 31 | ); 32 | s = s * 6378.137; // 地球半径 33 | s = Math.round(s * 10000) / 10000; 34 | return s * 1000 <= radius; 35 | }; 36 | 37 | export interface isPointInCircleOptions { 38 | lnglat1: { 39 | lat: number, 40 | lng: number, 41 | }, 42 | lnglat2: { 43 | lat: number, 44 | lng: number, 45 | }, 46 | radius: number 47 | } 48 | 49 | Geo.register( 50 | 'isPointInCircle', 51 | (options: isPointInCircleOptions) => { 52 | return isPointInCircle(options.lnglat1, options.lnglat2, options.radius) 53 | } 54 | ) 55 | -------------------------------------------------------------------------------- /packages/data-design/geo/isPtInPoly.ts: -------------------------------------------------------------------------------- 1 | import { Geo } from '.' 2 | 3 | 4 | /* 5 | :param aLon: double 经度 6 | :param aLat: double 纬度 7 | :param pointList: list [{latitude: 22.22, longitude: 113.113}...] 多边形点的顺序需根据顺时针或逆时针 8 | */ 9 | const isPtInPoly = ( 10 | lnglat: { lng: number; lat: number }, 11 | pointList: { lng: number; lat: number }[], 12 | ) => { 13 | const aLat = lnglat.lat 14 | const aLon = lnglat.lng 15 | let iSum = 0; 16 | const iCount = pointList.length; 17 | if (iCount < 3) { 18 | return false; 19 | } 20 | // 待判断的点(x, y) 为已知值 21 | const y = aLat; 22 | const x = aLon; 23 | let y2; 24 | let x2; 25 | for (let i = 0; i < iCount; i++) { 26 | const y1 = pointList[i].lat; 27 | const x1 = pointList[i].lng; 28 | if (i == iCount - 1) { 29 | y2 = pointList[0].lat; 30 | x2 = pointList[0].lng; 31 | } else { 32 | y2 = pointList[i + 1].lat; 33 | x2 = pointList[i + 1].lng; 34 | } 35 | // 当前边的 2 个端点分别为 已知值(x1, y1), (x2, y2) 36 | if ((y >= y1 && y < y2) || (y >= y2 && y < y1)) { 37 | // y 界于 y1 和 y2 之间 38 | // 假设过待判断点(x, y)的水平直线和当前边的交点为(x_intersect, y_intersect),有y_intersect = y 39 | // 则有(2个相似三角形,公用顶角,宽/宽 = 高/高):|x1 - x2| / |x1 - x_intersect| = |y1 - y2| / |y1 - y| 40 | if (Math.abs(y1 - y2) > 0) { 41 | const x_intersect = x1 - ((x1 - x2) * (y1 - y)) / (y1 - y2); 42 | if (x_intersect < x) { 43 | iSum += 1; 44 | } 45 | } 46 | } 47 | } 48 | if (iSum % 2 != 0) { 49 | return true; 50 | } else { 51 | return false; 52 | } 53 | }; 54 | 55 | 56 | export interface isPtInPolyOptions { 57 | lnglat: { lng: number; lat: number }, 58 | pointList: { lng: number; lat: number }[] 59 | } 60 | 61 | Geo.register( 62 | 'isPtInPoly', 63 | (options: isPtInPolyOptions) => { 64 | return isPtInPoly(options.lnglat, options.pointList) 65 | } 66 | ) 67 | -------------------------------------------------------------------------------- /packages/data-design/index.ts: -------------------------------------------------------------------------------- 1 | import { dataTransform, dataType, dataGeo, dataCartesian } from './dataDesign' 2 | 3 | export { dataTransform, dataType, dataGeo, dataCartesian } 4 | -------------------------------------------------------------------------------- /packages/data-design/register.ts: -------------------------------------------------------------------------------- 1 | import { isFns } from 'js-utils-pro' 2 | import { DataType } from './dataType' 3 | import './transforms/array/sort' 4 | import './transforms/array/reverse' 5 | import './transforms/array/filter' 6 | import './transforms/array/map' 7 | import './transforms/array/rename' 8 | import './transforms/array/pick' 9 | import './transforms/array/sort-by' 10 | import './transforms/array/partition' 11 | import './transforms/tree/toTree' 12 | import './transforms/tree/flatTree' 13 | import './geo/isPtInPoly' 14 | import './cartesian/minDistancePoint' 15 | 16 | for (const key in isFns) { 17 | if (Object.prototype.hasOwnProperty.call(isFns, key)) { 18 | const dataTypeIteratorFn = isFns[key as keyof typeof isFns] 19 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 20 | // @ts-ignore 21 | if (key.includes('is')) DataType.registerDataType(key, dataTypeIteratorFn) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/filter.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | 3 | function defaultCallback(row: any): boolean { 4 | return !!row 5 | } 6 | 7 | export interface FilterOptions { 8 | callback?: (item: any) => boolean 9 | } 10 | 11 | Transforms.registerTransform( 12 | 'filter', 13 | (dataSource: any[], options: FilterOptions) => { 14 | return dataSource?.filter(options.callback || defaultCallback) ?? [] 15 | } 16 | ) 17 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/map.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | 3 | export interface MapOptions { 4 | callback?(item: any, index: number, arr: any[]): any 5 | } 6 | 7 | function defaultCallback(row: any): any { 8 | return row 9 | } 10 | 11 | Transforms.registerTransform( 12 | 'map', 13 | (dataSource: any[], options: MapOptions) => { 14 | return dataSource?.map(options.callback || defaultCallback) ?? [] 15 | } 16 | ) 17 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/partition.ts: -------------------------------------------------------------------------------- 1 | import { values, assign } from 'lodash' 2 | import { Transforms } from '..' 3 | import partition from '../utils/partition' 4 | 5 | export interface PartitionOptions { 6 | groupBy: string[] 7 | orderBy?: string[] 8 | } 9 | 10 | const DEFAULT_OPTIONS: PartitionOptions = { 11 | groupBy: [], // optional 12 | orderBy: [], 13 | } 14 | 15 | Transforms.registerTransform('partition', (dataSource: any[], options: PartitionOptions) => { 16 | options = assign({} as PartitionOptions, DEFAULT_OPTIONS, options) 17 | const rows = partition(dataSource, options.groupBy, options.orderBy) 18 | return rows 19 | }) 20 | 21 | function group(dataSource: any[], options: PartitionOptions): void { 22 | options = assign({} as PartitionOptions, DEFAULT_OPTIONS, options) 23 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 24 | // @ts-ignore 25 | return values(partition(dataSource, options.groupBy, options.orderBy)) 26 | } 27 | 28 | Transforms.registerTransform('group', group) 29 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/pick.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | import { pick } from 'lodash' 3 | export interface PickOptions { 4 | fields?: string[] 5 | } 6 | 7 | Transforms.registerTransform( 8 | 'pick', 9 | (dataSource: any[], options: PickOptions) => { 10 | if ( 11 | options && 12 | dataSource && 13 | options?.fields && 14 | options.fields instanceof Array 15 | ) { 16 | return dataSource?.map((row) => pick(row, options.fields!)) ?? [] 17 | } 18 | return dataSource 19 | } 20 | ) 21 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/rename.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | import { isPlainObject, forIn, isString } from 'lodash' 3 | 4 | export interface RenameOptions { 5 | map?: Record 6 | } 7 | 8 | Transforms.registerTransform( 9 | 'rename', 10 | (dataSource: any[], options: RenameOptions) => { 11 | const map = options.map || {} 12 | const cleanMap: Record = {} 13 | if (isPlainObject(map)) { 14 | forIn(map, (value, key) => { 15 | if (isString(value) && isString(key)) { 16 | cleanMap[key] = value 17 | } 18 | }) 19 | } 20 | 21 | dataSource?.forEach((row) => { 22 | forIn(cleanMap, (newKey, key) => { 23 | const temp = row[key] 24 | delete row[key] 25 | row[newKey] = temp 26 | }) 27 | }) 28 | return dataSource instanceof Array ? dataSource : [] 29 | } 30 | ) 31 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/reverse.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | 3 | Transforms.registerTransform('reverse', (dataSource: any[]) => { 4 | if (dataSource != undefined && dataSource !== null) { 5 | return dataSource.reverse() 6 | } 7 | return dataSource 8 | }) 9 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/sort-by.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | import { sortBy, isArray } from 'lodash' 3 | 4 | const VALID_ORDERS = ['ASC', 'DESC'] 5 | 6 | export interface SortByOptions { 7 | fields?: string[] 8 | order?: 'ASC' | 'DESC' 9 | } 10 | 11 | Transforms.registerTransform( 12 | 'sortBy', 13 | (dataSource: any[], options: SortByOptions) => { 14 | if (!isArray(options?.fields)) { 15 | throw new TypeError('Invalid fields: must be an array with strings!') 16 | } 17 | if ( 18 | options && 19 | dataSource && 20 | options?.fields && 21 | options.fields instanceof Array 22 | ) { 23 | const rows = sortBy(dataSource, options.fields) 24 | const order = options.order 25 | if (order && VALID_ORDERS.indexOf(order) === -1) { 26 | throw new TypeError( 27 | `Invalid order: ${order} must be one of ${VALID_ORDERS.join(', ')}` 28 | ) 29 | } else if (order === 'DESC') { 30 | rows.reverse() 31 | } 32 | return rows ?? [] 33 | } 34 | return dataSource 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /packages/data-design/transforms/array/sort.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | 3 | // sort array 4 | export interface SortOptions { 5 | columnName?: string 6 | callback?(a: any, b: any): number 7 | } 8 | Transforms.registerTransform( 9 | 'sort', 10 | (dataSource: any[], options: SortOptions) => { 11 | if (options?.callback && dataSource != undefined && dataSource !== null) { 12 | return dataSource.sort(options?.callback) 13 | } 14 | return dataSource.sort( 15 | options?.columnName 16 | ? (a, b) => a[options.columnName!] - b[options.columnName!] 17 | : (a, b) => a - b 18 | ) 19 | } 20 | ) 21 | -------------------------------------------------------------------------------- /packages/data-design/transforms/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Transform(key 注册中心-- 3 | * */ 4 | 5 | import { TransformType } from "../type"; 6 | 7 | type TransformFunction = (data: any, options: TransformType[K]) => void; 8 | export class Transforms { 9 | /** 10 | * 已注册的 Transform(key-value 键值对) 11 | */ 12 | static transforms: Record = {}; 13 | 14 | static registerTransform( 15 | name: K, 16 | transform: (data: any, options: TransformType[K]) => void 17 | ): void { 18 | Transforms.transforms[name] = transform; 19 | } 20 | 21 | static getTransform(name: keyof TransformType): TransformFunction { 22 | return Transforms.transforms[name] || Transforms.transforms.default; 23 | } 24 | static Transforms: typeof Transforms = Transforms; 25 | } 26 | -------------------------------------------------------------------------------- /packages/data-design/transforms/tree/flatTree.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | 3 | export interface FlatTreeOptions { 4 | flatKey: string 5 | } 6 | 7 | Transforms.registerTransform('flatTree', (dataSource: any[], options: FlatTreeOptions) => { 8 | const key = options.flatKey 9 | const treeNodes = dataSource ?? [] 10 | 11 | if (treeNodes.length === 0) return 12 | let stack: any[] = [] 13 | const result = [] 14 | for (let index = 0; index < treeNodes.length; index += 1) { 15 | stack.push(treeNodes[index]) 16 | } 17 | 18 | let item 19 | while (stack.length) { 20 | item = stack.shift() 21 | if (item[key] && item[key].length) { 22 | stack = (stack ?? []).concat(item[key]) 23 | } 24 | if (!item[key] && typeof item === 'object') { 25 | result.push(item) 26 | } 27 | } 28 | return result 29 | }) 30 | -------------------------------------------------------------------------------- /packages/data-design/transforms/tree/toTree.ts: -------------------------------------------------------------------------------- 1 | import { Transforms } from '..' 2 | 3 | export interface ToTreeOptions { 4 | parentIdName?: string 5 | idName?: string 6 | } 7 | 8 | Transforms.registerTransform( 9 | 'toTree', 10 | (dataSource: any[], options: ToTreeOptions) => { 11 | const id = options?.idName ?? 'id' 12 | const parentId = options?.parentIdName ?? 'parentId' 13 | // 删除 所有 children,以防止多次调用 14 | dataSource.forEach(function(item) { 15 | delete item.children 16 | }) 17 | // 将数据存储为 以 id 为 KEY 的 map 索引数据列 18 | const map: any = {} 19 | dataSource.forEach(function(item) { 20 | map[item[id]] = item 21 | }) 22 | const menu: any = [] 23 | dataSource.forEach(function(item) { 24 | // 在map中找到当前项的父级菜单 25 | const parent = map[item[parentId]] 26 | if (parent) { 27 | // 如果父级菜单存在,则将当前项存入父级的children 28 | // 如果父级的children不存在,初始化为空数组[]后再存入 29 | ;(parent.children || (parent.children = [])).push(item) 30 | } else { 31 | // 如果父级菜单不存在,则做为顶级菜单存入 32 | menu.push(item) 33 | } 34 | }) 35 | 36 | return menu 37 | } 38 | ) 39 | -------------------------------------------------------------------------------- /packages/data-design/transforms/utils/partition.ts: -------------------------------------------------------------------------------- 1 | import { isArray, isFunction, isString, groupBy } from 'lodash' 2 | import simpleSortBy from './simple-sort-by' 3 | 4 | export default ( 5 | rows: any[], 6 | group_by: string | string[] | ((item: any) => string), 7 | order_by: string | string[] | ((item: any) => number) = [] 8 | ): Record => { 9 | let newRows = rows 10 | if (order_by && order_by.length) { 11 | newRows = simpleSortBy(rows, order_by) 12 | } 13 | 14 | let groupingFn: (item: any) => string 15 | 16 | if (isFunction(group_by)) { 17 | groupingFn = group_by 18 | } else if (isArray(group_by)) { 19 | groupingFn = (row: any) => `_${group_by.map((col) => row[col]).join('-')}` 20 | // that is why we have to add a prefix 21 | } else if (isString(group_by)) { 22 | groupingFn = (row: any) => `_${row[group_by]}` 23 | } 24 | const groups = groupBy(newRows, groupingFn!) 25 | return groups 26 | } 27 | -------------------------------------------------------------------------------- /packages/data-design/transforms/utils/simple-sort-by.ts: -------------------------------------------------------------------------------- 1 | import { isArray, isFunction, isString } from 'lodash' 2 | 3 | export type SortTarget = string | string[] | ((a: any, b: any) => number) 4 | export default function sortBy(arr: any[], keys: SortTarget = []): any[] { 5 | let comparer: ((a: any, b: any) => number) | undefined = undefined 6 | if (isFunction(keys)) { 7 | comparer = keys 8 | } else if (isArray(keys)) { 9 | comparer = (a, b) => { 10 | for (let i = 0; i < keys.length; i++) { 11 | const key = keys[i] 12 | if (a[key] < b[key]) { 13 | return -1 14 | } 15 | if (a[key] > b[key]) { 16 | return 1 17 | } 18 | } 19 | return 0 20 | } 21 | } else if (isString(keys)) { 22 | comparer = (a, b) => { 23 | if (a[keys] < b[keys]) { 24 | return -1 25 | } 26 | if (a[keys] > b[keys]) { 27 | return 1 28 | } 29 | return 0 30 | } 31 | } 32 | return arr.sort(comparer) 33 | } 34 | -------------------------------------------------------------------------------- /packages/data-design/type.ts: -------------------------------------------------------------------------------- 1 | import { isFns } from 'js-utils-pro' 2 | import { SortOptions } from './transforms/array/sort' 3 | import { FilterOptions } from './transforms/array/filter' 4 | import { MapOptions } from './transforms/array/map' 5 | import { RenameOptions } from './transforms/array/rename' 6 | import { PickOptions } from './transforms/array/pick' 7 | import { SortByOptions } from './transforms/array/sort-by' 8 | import { PartitionOptions } from './transforms/array/partition' 9 | import { ToTreeOptions } from './transforms/tree/toTree' 10 | import { FlatTreeOptions } from './transforms/tree/flatTree' 11 | import { isPtInPolyOptions } from './geo/isPtInPoly' 12 | import './cartesian/minDistancePoint' 13 | import { NearestPointType } from './cartesian/minDistancePoint' 14 | import { isPointInCircleOptions } from './geo/isPointInCircle' 15 | 16 | export type MergeUnionType = T extends U ? U : T | U 17 | export type DataType = keyof Omit 18 | 19 | export interface TransformType { 20 | sort: SortOptions 21 | reverse: null 22 | filter: FilterOptions 23 | map: MapOptions 24 | rename: RenameOptions 25 | pick: PickOptions 26 | sortBy: SortByOptions 27 | group: PartitionOptions 28 | partition: PartitionOptions 29 | toTree: ToTreeOptions 30 | flatTree: FlatTreeOptions 31 | } 32 | 33 | export type CartesianType = { 34 | minDistancePoint: NearestPointType 35 | } 36 | 37 | export type GeoType = { 38 | isPtInPoly: isPtInPolyOptions 39 | isPointInCircle: isPointInCircleOptions 40 | } 41 | 42 | export type AddonDataType = MergeUnionType 43 | export type AddonTransformType = MergeUnionType 44 | export type AddonCartesianType = MergeUnionType 45 | export type AddonGeoType = MergeUnionType 46 | -------------------------------------------------------------------------------- /packages/share/index.ts: -------------------------------------------------------------------------------- 1 | export const share = "share"; 2 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | function App() { 4 | return
123
5 | } 6 | 7 | export default App 8 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | 9 | ) 10 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx", 18 | "baseUrl": ".", 19 | "rootDir": "./", 20 | "paths": { 21 | "@/src": ["src/*"], 22 | "data-design": ["./packages/data-design/index.ts"], 23 | "data-design/dataType": ["./packages/data-design/dataType/index.ts"], 24 | "data-design/transforms": ["./packages/data-design/transforms/index.ts"], 25 | "data-design/share": ["./packages/data-design/share/index.ts"] 26 | } 27 | }, 28 | "include": ["packages", "docs/**/*.tsx", "docs/hooks/*.ts"], 29 | "references": [{ "path": "./tsconfig.node.json" }] 30 | } 31 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import { resolve } from 'path' 4 | import dts from 'vite-plugin-dts' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [react(), dts()], 9 | resolve: { 10 | alias: [ 11 | { find: /^~/, replacement: '' }, 12 | { 13 | find: '@data-design', 14 | replacement: resolve(__dirname, 'packages/data-design'), 15 | }, 16 | { 17 | find: '@data-design/dataType', 18 | replacement: resolve(__dirname, 'packages/data-design/dataType'), 19 | }, 20 | { 21 | find: '@data-design/transforms', 22 | replacement: resolve(__dirname, 'packages/data-design/transforms'), 23 | }, 24 | { 25 | find: '@data-design/share', 26 | replacement: resolve(__dirname, 'packages/data-design/share'), 27 | }, 28 | ], 29 | }, 30 | build: { 31 | lib: { 32 | entry: resolve(__dirname, 'packages/data-design/index.ts'), 33 | name: 'data-design', 34 | formats: ['es', 'cjs'], 35 | fileName: (format) => `data-design.${format}.js`, 36 | }, 37 | rollupOptions: { 38 | // 确保外部化处理那些你不想打包进库的依赖 39 | external: ['react'], 40 | output: { 41 | // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 42 | globals: { 43 | react: 'React', 44 | }, 45 | }, 46 | }, 47 | outDir: 'dist', 48 | }, 49 | }) 50 | --------------------------------------------------------------------------------