Преглед на файлове

refactor(架构调整): eslint配置从ts-workplace到基于element配置

gemercheung преди 2 години
родител
ревизия
aa36c8b70b
променени са 84 файла, в които са добавени 837 реда и са изтрити 1012 реда
  1. 2 4
      .eslintignore
  2. 0 75
      .eslintrc.js
  3. 4 0
      .eslintrc.json
  4. 6 0
      .gitattributes
  5. 1 1
      commitlint.config.js
  6. 1 1
      docs/.vitepress/vitepress/components/common/vp-link.vue
  7. 1 1
      docs/.vitepress/vitepress/components/common/vp-markdown.vue
  8. 1 1
      docs/.vitepress/vitepress/components/common/vp-switch.vue
  9. 1 1
      docs/.vitepress/vitepress/components/demo/vp-source-code.vue
  10. 1 1
      docs/.vitepress/vitepress/components/doc-content/vp-table-of-content.vue
  11. 1 1
      docs/.vitepress/vitepress/components/globals/main-color.vue
  12. 1 1
      docs/.vitepress/vitepress/components/globals/resource.vue
  13. 1 1
      docs/.vitepress/vitepress/components/globals/secondary-colors.vue
  14. 3 3
      docs/.vitepress/vitepress/components/navbar/vp-hamburger.vue
  15. 1 1
      docs/.vitepress/vitepress/components/navbar/vp-search.vue
  16. 6 6
      docs/.vitepress/vitepress/components/vp-app.vue
  17. 2 2
      docs/.vitepress/vitepress/components/vp-content.vue
  18. 1 1
      docs/.vitepress/vitepress/components/vp-demo.vue
  19. 1 1
      docs/.vitepress/vitepress/components/vp-overlay.vue
  20. 2 2
      docs/.vitepress/vitepress/components/vp-sidebar.vue
  21. 6 6
      internal/build/build.config.ts
  22. 26 45
      internal/build/gulpfile.ts
  23. 36 38
      internal/build/src/build-info.ts
  24. 13 13
      internal/build/src/plugins/element-plus-alias.ts
  25. 100 129
      internal/build/src/tasks/full-bundle.ts
  26. 95 128
      internal/build/src/tasks/helper.ts
  27. 49 49
      internal/build/src/tasks/modules.ts
  28. 104 128
      internal/build/src/tasks/types-definitions.ts
  29. 2 6
      internal/build/src/utils/gulp.ts
  30. 6 6
      internal/build/src/utils/pkg.ts
  31. 15 18
      internal/build/src/utils/process.ts
  32. 11 17
      internal/build/src/utils/rollup.ts
  33. 12 9
      package.json
  34. 2 2
      packages/components/basic/audio/__tests__/audio.test.tsx
  35. 2 2
      packages/components/basic/audio/src/audio.vue
  36. 3 3
      packages/components/basic/bubble/src/bubble.vue
  37. 1 1
      packages/components/basic/button/src/button.ts
  38. 3 3
      packages/components/basic/button/src/button.vue
  39. 8 8
      packages/components/basic/cropper/cropper.vue
  40. 1 1
      packages/components/basic/cropper/index.js
  41. 4 4
      packages/components/basic/dialog/src/alert.vue
  42. 5 5
      packages/components/basic/dialog/src/confirm.vue
  43. 3 3
      packages/components/basic/dialog/src/dialog-content.vue
  44. 1 1
      packages/components/basic/dialog/src/dialog.ts
  45. 4 4
      packages/components/basic/dialog/src/dialog.vue
  46. 5 5
      packages/components/basic/dialog/src/toast.vue
  47. 5 5
      packages/components/basic/dialog/src/window.vue
  48. 14 13
      packages/components/basic/floating/src/floating.vue
  49. 3 3
      packages/components/basic/gate/content.vue
  50. 3 3
      packages/components/basic/gate/layer.vue
  51. 3 3
      packages/components/basic/group/ui-group-option.vue
  52. 12 12
      packages/components/basic/group/ui-group.vue
  53. 7 7
      packages/components/basic/guide/index.vue
  54. 1 1
      packages/components/basic/icon/src/icon.ts
  55. 5 5
      packages/components/basic/icon/src/icon.vue
  56. 4 4
      packages/components/basic/input/src/checkRadio/checkRadio.vue
  57. 4 4
      packages/components/basic/input/src/checkbox/checkbox.vue
  58. 17 17
      packages/components/basic/input/src/file/file.vue
  59. 13 13
      packages/components/basic/input/src/index copy.vue
  60. 3 3
      packages/components/basic/input/src/input.ts
  61. 4 4
      packages/components/basic/input/src/input.vue
  62. 13 13
      packages/components/basic/input/src/number/number.vue
  63. 1 1
      packages/components/basic/input/src/password.vue
  64. 6 6
      packages/components/basic/input/src/radio/radio.vue
  65. 7 7
      packages/components/basic/input/src/range/range.vue
  66. 21 21
      packages/components/basic/input/src/richtext/richtext.vue
  67. 5 5
      packages/components/basic/input/src/search/search.vue
  68. 11 11
      packages/components/basic/input/src/select/select.vue
  69. 4 4
      packages/components/basic/input/src/switch/switch.vue
  70. 8 8
      packages/components/basic/input/src/text/text.vue
  71. 8 8
      packages/components/basic/input/src/textarea/textarea.vue
  72. 1 1
      packages/components/basic/menu-item/src/menu-item.ts
  73. 3 3
      packages/components/basic/menu-item/src/menu-item.vue
  74. 2 2
      packages/components/basic/message/index.ts
  75. 3 3
      packages/components/basic/message/message.vue
  76. 40 42
      packages/components/basic/scrollbar/index.js
  77. 3 3
      packages/components/basic/size-animation/index.vue
  78. 5 5
      packages/components/basic/slide/index.vue
  79. 9 7
      packages/components/basic/tree/TreeItem.vue
  80. 17 15
      packages/components/basic/tree/index.vue
  81. 10 10
      packages/utils/dom/others.ts
  82. 1 1
      packages/utils/dom/parent.ts
  83. 1 1
      packages/utils/normal.ts
  84. 6 0
      pnpm-lock.yaml

+ 2 - 4
.eslintignore

@@ -1,7 +1,5 @@
 node_modules
 !.*
 dist
-build
-
-
-examples/cra-ejected-babel
+playground
+iconfont

+ 0 - 75
.eslintrc.js

@@ -1,75 +0,0 @@
-// @ts-check
-const { defineConfig } = require('eslint-define-config')
-module.exports = defineConfig({
-    root: true,
-    env: {
-        browser: true,
-        node: true,
-        es6: true,
-    },
-    parser: 'vue-eslint-parser',
-    parserOptions: {
-        parser: '@typescript-eslint/parser',
-        ecmaVersion: 2020,
-        sourceType: 'module',
-        jsxPragma: 'React',
-        ecmaFeatures: {
-            jsx: true,
-        },
-    },
-    extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended', 'plugin:jest/recommended'],
-    rules: {
-        'vue/script-setup-uses-vars': 'error',
-        '@typescript-eslint/ban-ts-ignore': 'off',
-        '@typescript-eslint/explicit-function-return-type': 'off',
-        '@typescript-eslint/no-explicit-any': 'off',
-        '@typescript-eslint/no-var-requires': 'off',
-        '@typescript-eslint/no-empty-function': 'off',
-        'vue/custom-event-name-casing': 'off',
-        'no-use-before-define': 'off',
-        '@typescript-eslint/no-use-before-define': 'off',
-        '@typescript-eslint/ban-ts-comment': 'off',
-        '@typescript-eslint/ban-types': 'off',
-        '@typescript-eslint/no-non-null-assertion': 'off',
-        '@typescript-eslint/explicit-module-boundary-types': 'off',
-        '@typescript-eslint/no-unused-vars': [
-            'error',
-            {
-                argsIgnorePattern: '^_',
-                varsIgnorePattern: '^_',
-            },
-        ],
-        'no-unused-vars': [
-            'error',
-            {
-                argsIgnorePattern: '^_',
-                varsIgnorePattern: '^_',
-            },
-        ],
-        'space-before-function-paren': 'off',
-
-        'vue/attributes-order': 'off',
-        'vue/one-component-per-file': 'off',
-        'vue/html-closing-bracket-newline': 'off',
-        'vue/max-attributes-per-line': 'off',
-        'vue/multiline-html-element-content-newline': 'off',
-        'vue/singleline-html-element-content-newline': 'off',
-        'vue/attribute-hyphenation': 'off',
-        'vue/require-default-prop': 'off',
-        'vue/require-explicit-emits': 'off',
-        'vue/no-useless-template-attributes': 'off',
-        'vue/html-self-closing': [
-            'error',
-            {
-                html: {
-                    void: 'always',
-                    normal: 'never',
-                    component: 'always',
-                },
-                svg: 'always',
-                math: 'always',
-            },
-        ],
-        'vue/multi-word-component-names': 'off',
-    },
-})

+ 4 - 0
.eslintrc.json

@@ -0,0 +1,4 @@
+{
+    "root": true,
+    "extends": ["@kankan/eslint-config"]
+}

+ 6 - 0
.gitattributes

@@ -0,0 +1,6 @@
+* text=auto eol=lf
+*.ts linguist-detectable=false
+*.css linguist-detectable=false
+*.scss linguist-detectable=false
+*.js linguist-detectable=true
+*.vue linguist-detectable=true

+ 1 - 1
commitlint.config.js

@@ -2,7 +2,7 @@ module.exports = {
     extends: ['cz'],
     parserPreset: {
         parserOpts: {
-            headerPattern: /^(\w*)\(([\u4e00-\u9fa5]*)\)/,
+            headerPattern: /^(\w*)\(([\u4E00-\u9FA5]*)\)/,
             headerCorrespondence: ['type', 'scope'],
         },
     },

+ 1 - 1
docs/.vitepress/vitepress/components/common/vp-link.vue

@@ -11,7 +11,7 @@ const isExternal = computed(() => props.href && /^[a-z]+:/i.test(props.href))
 
 <template>
     <component :is="href ? 'a' : 'span'" class="link-item" :class="{ link: href }" :href="href" :target="isExternal ? '_blank' : undefined" :rel="isExternal ? 'noopener noreferrer' : undefined">
-        <slot></slot>
+        <slot />
         <ElIcon v-if="isExternal && !noIcon">
             <i-ri-external-link-line class="link-icon" />
         </ElIcon>

+ 1 - 1
docs/.vitepress/vitepress/components/common/vp-markdown.vue

@@ -20,7 +20,7 @@ const parsed = computed(() => {
 </script>
 
 <template>
-    <div class="markdown-wrapper" v-html="parsed"></div>
+    <div class="markdown-wrapper" v-html="parsed" />
 </template>
 
 <style>

+ 1 - 1
docs/.vitepress/vitepress/components/common/vp-switch.vue

@@ -8,7 +8,7 @@
     <div class="switch" role="switch">
         <div class="switch__action">
             <div class="switch__icon">
-                <slot></slot>
+                <slot />
             </div>
         </div>
     </div>

+ 1 - 1
docs/.vitepress/vitepress/components/demo/vp-source-code.vue

@@ -15,7 +15,7 @@ const decoded = computed(() => {
 
 <template>
     <div class="example-source-wrapper">
-        <div class="example-source language-vue" v-html="decoded"></div>
+        <div class="example-source language-vue" v-html="decoded" />
     </div>
 </template>
 

+ 1 - 1
docs/.vitepress/vitepress/components/doc-content/vp-table-of-content.vue

@@ -32,7 +32,7 @@ const sponsor = computed(() => sponsorLocale[lang.value])
                     </ul>
                 </li>
             </ul>
-            <div ref="marker" class="toc-marker"></div>
+            <div ref="marker" class="toc-marker" />
             <!-- <SponsorLarge
         class="mt-8 toc-ads flex flex-col"
         item-style="width: 180px; height: 55px;"

+ 1 - 1
docs/.vitepress/vitepress/components/globals/main-color.vue

@@ -25,7 +25,7 @@ const { copyColor } = useCopyColor()
                             background: 'var(--el-color-primary-' + level + ')',
                         }"
                         @click="copyColor('primary-' + level)"
-                    ></div>
+                    />
                 </div>
             </div>
         </el-col>

+ 1 - 1
docs/.vitepress/vitepress/components/globals/resource.vue

@@ -31,7 +31,7 @@ const onClick = (item: string) => {
     <div class="page-resource">
         <h1>{{ resourceLang.title }}</h1>
         <p>{{ resourceLang.lineOne }}</p>
-        <p v-html="resourceLang.lineTwo"></p>
+        <p v-html="resourceLang.lineTwo" />
         <div class="flex flex-wrap justify-center mt-32px">
             <div class="inline-flex w-full md:w-1/3" p="2" pl-0>
                 <el-card class="card" shadow="hover">

+ 1 - 1
docs/.vitepress/vitepress/components/globals/secondary-colors.vue

@@ -27,7 +27,7 @@ const { copyColor } = useCopyColor()
                             background: `var(--el-color-${type}-` + level + ')',
                         }"
                         @click="copyColor(type + '-' + level)"
-                    ></div>
+                    />
                 </div>
             </div>
         </el-col>

+ 3 - 3
docs/.vitepress/vitepress/components/navbar/vp-hamburger.vue

@@ -6,8 +6,8 @@ defineProps<{
 
 <template>
     <div :class="{ 'menu-hamburger': true, active }" role="button">
-        <span class="hamburger-1"></span>
-        <span class="hamburger-2"></span>
-        <span class="hamburger-3"></span>
+        <span class="hamburger-1" />
+        <span class="hamburger-2" />
+        <span class="hamburger-3" />
     </div>
 </template>

+ 1 - 1
docs/.vitepress/vitepress/components/navbar/vp-search.vue

@@ -129,7 +129,7 @@ function initialize(userOptions: any) {
 </script>
 
 <template>
-    <div id="docsearch" class="algolia-search-box"></div>
+    <div id="docsearch" class="algolia-search-box" />
 </template>
 
 <style lang="scss">

+ 6 - 6
docs/.vitepress/vitepress/components/vp-app.vue

@@ -103,24 +103,24 @@ onMounted(async () => {
                 <VPSponsors />
             </template>
             <template #bottom>
-                <slot name="sidebar-bottom"></slot>
+                <slot name="sidebar-bottom" />
             </template>
         </VPSidebar>
         <VPContent :is-sidebar-open="isSidebarOpen">
             <template #content-top>
-                <slot name="content-top"></slot>
+                <slot name="content-top" />
             </template>
             <template #content-bottom>
-                <slot name="content-bottom"></slot>
+                <slot name="content-bottom" />
             </template>
             <template #aside-top>
-                <slot name="aside-top"></slot>
+                <slot name="aside-top" />
             </template>
             <template #aside-mid>
-                <slot name="aside-mid"></slot>
+                <slot name="aside-mid" />
             </template>
             <template #aside-bottom>
-                <slot name="aside-bottom"></slot>
+                <slot name="aside-bottom" />
             </template>
         </VPContent>
         <Debug />

+ 2 - 2
docs/.vitepress/vitepress/components/vp-content.vue

@@ -40,8 +40,8 @@ onUpdated(() => {
         <VPNotFound v-if="isNotFound" />
         <VPHeroContent v-else-if="isHeroPost" />
         <VPDocContent v-else>
-            <template #content-top><slot name="content-top"></slot></template>
-            <template #content-bottom><slot name="content-bottom"></slot></template>
+            <template #content-top><slot name="content-top" /></template>
+            <template #content-bottom><slot name="content-bottom" /></template>
         </VPDocContent>
         <VPFooter v-if="!isHeroPost" />
     </main>

+ 1 - 1
docs/.vitepress/vitepress/components/vp-demo.vue

@@ -66,7 +66,7 @@ const copyCode = async () => {
 <template>
     <ClientOnly>
         <!-- danger here DO NOT USE INLINE SCRIPT TAG -->
-        <p text="sm" v-html="decodedDescription"></p>
+        <p text="sm" v-html="decodedDescription" />
 
         <div class="example">
             <Example :file="path" :demo="formatPathDemos[path]" />

+ 1 - 1
docs/.vitepress/vitepress/components/vp-overlay.vue

@@ -6,6 +6,6 @@ defineProps<{
 
 <template>
     <Transition name="el-fade-in">
-        <div v-if="show"></div>
+        <div v-if="show" />
     </Transition>
 </template>

+ 2 - 2
docs/.vitepress/vitepress/components/vp-sidebar.vue

@@ -13,7 +13,7 @@ const { sidebars, hasSidebar } = useSidebar()
 <template>
     <el-scrollbar v-if="hasSidebar" :class="{ sidebar: true, open }">
         <aside>
-            <slot name="top"></slot>
+            <slot name="top" />
             <div class="sidebar-groups">
                 <section v-for="(item, key) of sidebars" :key="key" class="sidebar-group">
                     <p class="sidebar-group__title">
@@ -22,7 +22,7 @@ const { sidebars, hasSidebar } = useSidebar()
                     <VPSidebarLink v-for="(child, childKey) in item.children" :key="childKey" :item="child" @close="$emit('close')" />
                 </section>
             </div>
-            <slot name="bottom"></slot>
+            <slot name="bottom" />
         </aside>
     </el-scrollbar>
 </template>

+ 6 - 6
internal/build/build.config.ts

@@ -1,10 +1,10 @@
 import { defineBuildConfig } from 'unbuild'
 
 export default defineBuildConfig({
-  entries: ['src/index'],
-  clean: true,
-  declaration: true,
-  rollup: {
-    emitCJS: true,
-  },
+    entries: ['src/index'],
+    clean: true,
+    declaration: true,
+    rollup: {
+        emitCJS: true,
+    },
 })

+ 26 - 45
internal/build/gulpfile.ts

@@ -2,65 +2,46 @@ import path from 'path'
 import { copyFile, mkdir } from 'fs/promises'
 import { copy } from 'fs-extra'
 import { parallel, series } from 'gulp'
-import {
-  buildOutput,
-  epOutput,
-  epPackage,
-  projRoot,
-} from '@kankan/build-utils'
+import { buildOutput, epOutput, epPackage, projRoot } from '@kankan/build-utils'
 import { buildConfig, run, runTask, withTaskName } from './src'
 import type { TaskFunction } from 'gulp'
 import type { Module } from './src'
 
 export const copyFiles = () =>
-  Promise.all([
-    copyFile(epPackage, path.join(epOutput, 'package.json')),
-    copyFile(
-      path.resolve(projRoot, 'README.md'),
-      path.resolve(epOutput, 'README.md')
-    ),
-    copyFile(
-      path.resolve(projRoot, 'global.d.ts'),
-      path.resolve(epOutput, 'global.d.ts')
-    ),
-  ])
+    Promise.all([
+        copyFile(epPackage, path.join(epOutput, 'package.json')),
+        copyFile(path.resolve(projRoot, 'README.md'), path.resolve(epOutput, 'README.md')),
+        copyFile(path.resolve(projRoot, 'global.d.ts'), path.resolve(epOutput, 'global.d.ts')),
+    ])
 
-export const copyTypesDefinitions: TaskFunction = (done) => {
-  const src = path.resolve(buildOutput, 'types', 'packages')
-  const copyTypes = (module: Module) =>
-    withTaskName(`copyTypes:${module}`, () =>
-      copy(src, buildConfig[module].output.path, { recursive: true })
-    )
+export const copyTypesDefinitions: TaskFunction = done => {
+    const src = path.resolve(buildOutput, 'types', 'packages')
+    const copyTypes = (module: Module) => withTaskName(`copyTypes:${module}`, () => copy(src, buildConfig[module].output.path, { recursive: true }))
 
-  return parallel(copyTypes('esm'), copyTypes('cjs'))(done)
+    return parallel(copyTypes('esm'), copyTypes('cjs'))(done)
 }
 
 export const copyFullStyle = async () => {
-  await mkdir(path.resolve(epOutput, 'dist'), { recursive: true })
-  await copyFile(
-    path.resolve(epOutput, 'theme-chalk/index.css'),
-    path.resolve(epOutput, 'dist/index.css')
-  )
+    await mkdir(path.resolve(epOutput, 'dist'), { recursive: true })
+    await copyFile(path.resolve(epOutput, 'theme-chalk/index.css'), path.resolve(epOutput, 'dist/index.css'))
 }
 
 export default series(
-  withTaskName('clean', () => run('pnpm run clean')),
-  withTaskName('createOutput', () => mkdir(epOutput, { recursive: true })),
-
-  parallel(
-    runTask('buildModules'),
-    runTask('buildFullBundle'),
-    runTask('generateTypesDefinitions'),
-    runTask('buildHelper'),
-    series(
-      withTaskName('buildThemeChalk', () =>
-        run('pnpm run -C packages/theme-chalk build')
-      ),
-      copyFullStyle
-    )
-  ),
+    withTaskName('clean', () => run('pnpm run clean')),
+    withTaskName('createOutput', () => mkdir(epOutput, { recursive: true })),
+
+    parallel(
+        runTask('buildModules'),
+        runTask('buildFullBundle'),
+        runTask('generateTypesDefinitions'),
+        runTask('buildHelper'),
+        series(
+            withTaskName('buildThemeChalk', () => run('pnpm run -C packages/theme-chalk build')),
+            copyFullStyle
+        )
+    ),
 
-  parallel(copyTypesDefinitions, copyFiles)
+    parallel(copyTypesDefinitions, copyFiles)
 )
 
 export * from './src'

+ 36 - 38
internal/build/src/build-info.ts

@@ -7,51 +7,49 @@ import type { ModuleFormat } from 'rollup'
 export const modules = ['esm', 'cjs'] as const
 export type Module = typeof modules[number]
 export interface BuildInfo {
-  module: 'ESNext' | 'CommonJS'
-  format: ModuleFormat
-  ext: 'mjs' | 'cjs' | 'js'
-  output: {
-    /** e.g: `es` */
-    name: string
-    /** e.g: `dist/element-plus/es` */
-    path: string
-  }
+    module: 'ESNext' | 'CommonJS'
+    format: ModuleFormat
+    ext: 'mjs' | 'cjs' | 'js'
+    output: {
+        /** e.g: `es` */
+        name: string
+        /** e.g: `dist/element-plus/es` */
+        path: string
+    }
 
-  bundle: {
-    /** e.g: `element-plus/es` */
-    path: string
-  }
+    bundle: {
+        /** e.g: `element-plus/es` */
+        path: string
+    }
 }
 
 export const buildConfig: Record<Module, BuildInfo> = {
-  esm: {
-    module: 'ESNext',
-    format: 'esm',
-    ext: 'mjs',
-    output: {
-      name: 'es',
-      path: path.resolve(epOutput, 'es'),
-    },
-    bundle: {
-      path: `${PKG_NAME}/es`,
-    },
-  },
-  cjs: {
-    module: 'CommonJS',
-    format: 'cjs',
-    ext: 'js',
-    output: {
-      name: 'lib',
-      path: path.resolve(epOutput, 'lib'),
+    esm: {
+        module: 'ESNext',
+        format: 'esm',
+        ext: 'mjs',
+        output: {
+            name: 'es',
+            path: path.resolve(epOutput, 'es'),
+        },
+        bundle: {
+            path: `${PKG_NAME}/es`,
+        },
     },
-    bundle: {
-      path: `${PKG_NAME}/lib`,
+    cjs: {
+        module: 'CommonJS',
+        format: 'cjs',
+        ext: 'js',
+        output: {
+            name: 'lib',
+            path: path.resolve(epOutput, 'lib'),
+        },
+        bundle: {
+            path: `${PKG_NAME}/lib`,
+        },
     },
-  },
 }
-export const buildConfigEntries = Object.entries(
-  buildConfig
-) as BuildConfigEntries
+export const buildConfigEntries = Object.entries(buildConfig) as BuildConfigEntries
 
 export type BuildConfig = typeof buildConfig
 export type BuildConfigEntries = [Module, BuildInfo][]

+ 13 - 13
internal/build/src/plugins/element-plus-alias.ts

@@ -3,18 +3,18 @@ import { PKG_NAME, PKG_PREFIX } from '@kankan/build-constants'
 import type { Plugin } from 'rollup'
 
 export function ElementPlusAlias(): Plugin {
-  const themeChalk = 'theme-chalk'
-  const sourceThemeChalk = `${PKG_PREFIX}/${themeChalk}` as const
-  const bundleThemeChalk = `${PKG_NAME}/${themeChalk}` as const
+    const themeChalk = 'theme-chalk'
+    const sourceThemeChalk = `${PKG_PREFIX}/${themeChalk}` as const
+    const bundleThemeChalk = `${PKG_NAME}/${themeChalk}` as const
 
-  return {
-    name: 'element-plus-alias-plugin',
-    resolveId(id) {
-      if (!id.startsWith(sourceThemeChalk)) return
-      return {
-        id: id.replaceAll(sourceThemeChalk, bundleThemeChalk),
-        external: 'absolute',
-      }
-    },
-  }
+    return {
+        name: 'element-plus-alias-plugin',
+        resolveId(id) {
+            if (!id.startsWith(sourceThemeChalk)) return
+            return {
+                id: id.replaceAll(sourceThemeChalk, bundleThemeChalk),
+                external: 'absolute',
+            }
+        },
+    }
 }

+ 100 - 129
internal/build/src/tasks/full-bundle.ts

@@ -9,152 +9,123 @@ import esbuild, { minify as minifyPlugin } from 'rollup-plugin-esbuild'
 import { parallel } from 'gulp'
 import glob from 'fast-glob'
 import { camelCase, upperFirst } from 'lodash'
-import {
-  PKG_BRAND_NAME,
-  PKG_CAMELCASE_LOCAL_NAME,
-  PKG_CAMELCASE_NAME,
-} from '@kankan/build-constants'
+import { PKG_BRAND_NAME, PKG_CAMELCASE_LOCAL_NAME, PKG_CAMELCASE_NAME } from '@kankan/build-constants'
 import { epOutput, epRoot, localeRoot } from '@kankan/build-utils'
 import { version } from '../../../../packages/kankan/version'
 import { ElementPlusAlias } from '../plugins/kankan-alias'
-import {
-  formatBundleFilename,
-  generateExternal,
-  withTaskName,
-  writeBundles,
-} from '../utils'
+import { formatBundleFilename, generateExternal, withTaskName, writeBundles } from '../utils'
 import { target } from '../build-info'
 import type { Plugin } from 'rollup'
 
 const banner = `/*! ${PKG_BRAND_NAME} v${version} */\n`
 
 async function buildFullEntry(minify: boolean) {
-  const plugins: Plugin[] = [
-    ElementPlusAlias(),
-    VueMacros({
-      setupComponent: false,
-      setupSFC: false,
-      plugins: {
-        vue: vue({
-          isProduction: true,
+    const plugins: Plugin[] = [
+        ElementPlusAlias(),
+        VueMacros({
+            setupComponent: false,
+            setupSFC: false,
+            plugins: {
+                vue: vue({
+                    isProduction: true,
+                }),
+                vueJsx: vueJsx(),
+            },
         }),
-        vueJsx: vueJsx(),
-      },
-    }),
-    nodeResolve({
-      extensions: ['.mjs', '.js', '.json', '.ts'],
-    }),
-    commonjs(),
-    esbuild({
-      exclude: [],
-      sourceMap: minify,
-      target,
-      loaders: {
-        '.vue': 'ts',
-      },
-      define: {
-        'process.env.NODE_ENV': JSON.stringify('production'),
-      },
-      treeShaking: true,
-      legalComments: 'eof',
-    }),
-  ]
-  if (minify) {
-    plugins.push(
-      minifyPlugin({
-        target,
-        sourceMap: true,
-      })
-    )
-  }
-
-  const bundle = await rollup({
-    input: path.resolve(epRoot, 'index.ts'),
-    plugins,
-    external: await generateExternal({ full: true }),
-    treeshake: true,
-  })
-  await writeBundles(bundle, [
-    {
-      format: 'umd',
-      file: path.resolve(
-        epOutput,
-        'dist',
-        formatBundleFilename('index.full', minify, 'js')
-      ),
-      exports: 'named',
-      name: PKG_CAMELCASE_NAME,
-      globals: {
-        vue: 'Vue',
-      },
-      sourcemap: minify,
-      banner,
-    },
-    {
-      format: 'esm',
-      file: path.resolve(
-        epOutput,
-        'dist',
-        formatBundleFilename('index.full', minify, 'mjs')
-      ),
-      sourcemap: minify,
-      banner,
-    },
-  ])
-}
-
-async function buildFullLocale(minify: boolean) {
-  const files = await glob(`**/*.ts`, {
-    cwd: path.resolve(localeRoot, 'lang'),
-    absolute: true,
-  })
-  return Promise.all(
-    files.map(async (file) => {
-      const filename = path.basename(file, '.ts')
-      const name = upperFirst(camelCase(filename))
-
-      const bundle = await rollup({
-        input: file,
-        plugins: [
-          esbuild({
-            minify,
+        nodeResolve({
+            extensions: ['.mjs', '.js', '.json', '.ts'],
+        }),
+        commonjs(),
+        esbuild({
+            exclude: [],
             sourceMap: minify,
             target,
-          }),
-        ],
-      })
-      await writeBundles(bundle, [
+            loaders: {
+                '.vue': 'ts',
+            },
+            define: {
+                'process.env.NODE_ENV': JSON.stringify('production'),
+            },
+            treeShaking: true,
+            legalComments: 'eof',
+        }),
+    ]
+    if (minify) {
+        plugins.push(
+            minifyPlugin({
+                target,
+                sourceMap: true,
+            })
+        )
+    }
+
+    const bundle = await rollup({
+        input: path.resolve(epRoot, 'index.ts'),
+        plugins,
+        external: await generateExternal({ full: true }),
+        treeshake: true,
+    })
+    await writeBundles(bundle, [
         {
-          format: 'umd',
-          file: path.resolve(
-            epOutput,
-            'dist/locale',
-            formatBundleFilename(filename, minify, 'js')
-          ),
-          exports: 'default',
-          name: `${PKG_CAMELCASE_LOCAL_NAME}${name}`,
-          sourcemap: minify,
-          banner,
+            format: 'umd',
+            file: path.resolve(epOutput, 'dist', formatBundleFilename('index.full', minify, 'js')),
+            exports: 'named',
+            name: PKG_CAMELCASE_NAME,
+            globals: {
+                vue: 'Vue',
+            },
+            sourcemap: minify,
+            banner,
         },
         {
-          format: 'esm',
-          file: path.resolve(
-            epOutput,
-            'dist/locale',
-            formatBundleFilename(filename, minify, 'mjs')
-          ),
-          sourcemap: minify,
-          banner,
+            format: 'esm',
+            file: path.resolve(epOutput, 'dist', formatBundleFilename('index.full', minify, 'mjs')),
+            sourcemap: minify,
+            banner,
         },
-      ])
+    ])
+}
+
+async function buildFullLocale(minify: boolean) {
+    const files = await glob(`**/*.ts`, {
+        cwd: path.resolve(localeRoot, 'lang'),
+        absolute: true,
     })
-  )
+    return Promise.all(
+        files.map(async file => {
+            const filename = path.basename(file, '.ts')
+            const name = upperFirst(camelCase(filename))
+
+            const bundle = await rollup({
+                input: file,
+                plugins: [
+                    esbuild({
+                        minify,
+                        sourceMap: minify,
+                        target,
+                    }),
+                ],
+            })
+            await writeBundles(bundle, [
+                {
+                    format: 'umd',
+                    file: path.resolve(epOutput, 'dist/locale', formatBundleFilename(filename, minify, 'js')),
+                    exports: 'default',
+                    name: `${PKG_CAMELCASE_LOCAL_NAME}${name}`,
+                    sourcemap: minify,
+                    banner,
+                },
+                {
+                    format: 'esm',
+                    file: path.resolve(epOutput, 'dist/locale', formatBundleFilename(filename, minify, 'mjs')),
+                    sourcemap: minify,
+                    banner,
+                },
+            ])
+        })
+    )
 }
 
-export const buildFull = (minify: boolean) => async () =>
-  Promise.all([buildFullEntry(minify), buildFullLocale(minify)])
+export const buildFull = (minify: boolean) => async () => Promise.all([buildFullEntry(minify), buildFullLocale(minify)])
 
-export const buildFullBundle = parallel(
-  withTaskName('buildFullMinified', buildFull(true)),
-  withTaskName('buildFull', buildFull(false))
-)
+export const buildFullBundle = parallel(withTaskName('buildFullMinified', buildFull(true)), withTaskName('buildFull', buildFull(false)))

+ 95 - 128
internal/build/src/tasks/helper.ts

@@ -1,158 +1,125 @@
 import path from 'path'
-import {
-  arrayToRegExp,
-  getTypeSymbol,
-  hyphenate,
-  isCommonType,
-  isUnionType,
-  main,
-} from 'components-helper'
-import {
-  epOutput,
-  epPackage,
-  getPackageManifest,
-  projRoot,
-} from '@kankan/build-utils'
+import { arrayToRegExp, getTypeSymbol, hyphenate, isCommonType, isUnionType, main } from 'components-helper'
+import { epOutput, epPackage, getPackageManifest, projRoot } from '@kankan/build-utils'
 
 import type { TaskFunction } from 'gulp'
-import type {
-  ReAttribute,
-  ReComponentName,
-  ReDocUrl,
-  ReWebTypesSource,
-  ReWebTypesType,
-} from 'components-helper'
+import type { ReAttribute, ReComponentName, ReDocUrl, ReWebTypesSource, ReWebTypesType } from 'components-helper'
 
 const typeMap = {
-  vue: ['Component', 'VNode', 'CSSProperties', 'StyleValue'],
+    vue: ['Component', 'VNode', 'CSSProperties', 'StyleValue'],
 }
 
-const reComponentName: ReComponentName = (title) =>
-  `el-${hyphenate(title).replace(/[ ]+/g, '-')}`
+const reComponentName: ReComponentName = title => `el-${hyphenate(title).replace(/[ ]+/g, '-')}`
 
 const reDocUrl: ReDocUrl = (fileName, header) => {
-  const docs = 'https://element-plus.org/en-US/component/'
-  const _header = header ? header.replaceAll(/\s+/g, '-').toLowerCase() : ''
+    const docs = 'https://element-plus.org/en-US/component/'
+    const _header = header ? header.replaceAll(/\s+/g, '-').toLowerCase() : ''
 
-  return `${docs}${fileName}.html${_header ? '#' : ''}${_header}`
+    return `${docs}${fileName}.html${_header ? '#' : ''}${_header}`
 }
 
-const reWebTypesSource: ReWebTypesSource = (title) => {
-  const symbol = `El${title
-    .replaceAll(/-/g, ' ')
-    .replaceAll(/^\w|\s+\w/g, (item) => {
-      return item.trim().toUpperCase()
+const reWebTypesSource: ReWebTypesSource = title => {
+    const symbol = `El${title.replaceAll(/-/g, ' ').replaceAll(/^\w|\s+\w/g, item => {
+        return item.trim().toUpperCase()
     })}`
 
-  return { symbol }
+    return { symbol }
 }
 
 const reAttribute: ReAttribute = (value, key) => {
-  const str = value
-    .replace(/^\*\*(.*)\*\*$/, '$1')
-    .replace(/^`(.*)`$/, '$1')
-    .replace(/^~~(.*)~~$/, '')
-    .replaceAll(/<del>.*<\/del>/g, '')
-
-  if (key === 'Name' && /^(-|—)$/.test(str)) {
-    return 'default'
-  } else if (str === '' || /^(-|—)$/.test(str)) {
-    return undefined
-  } else if (key === 'Name' && /v-model:(.+)/.test(str)) {
-    const _str = str.match(/v-model:(.+)/)
-    return _str ? _str[1] : undefined
-  } else if (key === 'Name' && /v-model/.test(str)) {
-    return 'model-value'
-  } else if (key === 'Name') {
-    return str
-      .replaceAll(/\s*[\\*]\s*/g, '')
-      .replaceAll(/\s*<.*>\s*/g, '')
-      .replaceAll(/\s*\(.*\)\s*/g, '')
-      .replaceAll(/\B([A-Z])/g, '-$1')
-      .toLowerCase()
-  } else if (key === 'Type') {
-    return str
-      .replaceAll(/\bfunction(\(.*\))?(:\s*\w+)?\b/gi, 'Function')
-      .replaceAll(/\bdate\b/g, 'Date')
-      .replaceAll(/\([^)]*\)(?!\s*=>)/g, '')
-      .replaceAll(/(<[^>]*>|\{[^}]*}|\([^)]*\))/g, (item) => {
-        return item.replaceAll(/(\/|\|)/g, '=_0!')
-      })
-      .replaceAll(/(\b\w+)\s*\|/g, '$1 /')
-      .replaceAll(/\|\s*(\b\w+)/g, '/ $1')
-      .replaceAll(/=_0!/g, '|')
-  } else if (key === 'Accepted Values') {
-    return /\[.+\]\(.+\)/.test(str) || /^\*$/.test(str)
-      ? undefined
-      : str.replaceAll(/`/g, '').replaceAll(/\([^)]*\)(?!\s*=>)/g, '')
-  } else if (key === 'Subtags') {
-    return str
-      ? `el-${str
-        .replaceAll(/\s*\/\s*/g, '/el-')
-        .replaceAll(/\B([A-Z])/g, '-$1')
-        .replaceAll(/\s+/g, '-')
-        .toLowerCase()}`
-      : undefined
-  } else {
-    return str
-  }
+    const str = value
+        .replace(/^\*\*(.*)\*\*$/, '$1')
+        .replace(/^`(.*)`$/, '$1')
+        .replace(/^~~(.*)~~$/, '')
+        .replaceAll(/<del>.*<\/del>/g, '')
+
+    if (key === 'Name' && /^(-|—)$/.test(str)) {
+        return 'default'
+    } else if (str === '' || /^(-|—)$/.test(str)) {
+        return undefined
+    } else if (key === 'Name' && /v-model:(.+)/.test(str)) {
+        const _str = str.match(/v-model:(.+)/)
+        return _str ? _str[1] : undefined
+    } else if (key === 'Name' && /v-model/.test(str)) {
+        return 'model-value'
+    } else if (key === 'Name') {
+        return str
+            .replaceAll(/\s*[\\*]\s*/g, '')
+            .replaceAll(/\s*<.*>\s*/g, '')
+            .replaceAll(/\s*\(.*\)\s*/g, '')
+            .replaceAll(/\B([A-Z])/g, '-$1')
+            .toLowerCase()
+    } else if (key === 'Type') {
+        return str
+            .replaceAll(/\bfunction(\(.*\))?(:\s*\w+)?\b/gi, 'Function')
+            .replaceAll(/\bdate\b/g, 'Date')
+            .replaceAll(/\([^)]*\)(?!\s*=>)/g, '')
+            .replaceAll(/(<[^>]*>|\{[^}]*}|\([^)]*\))/g, item => {
+                return item.replaceAll(/(\/|\|)/g, '=_0!')
+            })
+            .replaceAll(/(\b\w+)\s*\|/g, '$1 /')
+            .replaceAll(/\|\s*(\b\w+)/g, '/ $1')
+            .replaceAll(/=_0!/g, '|')
+    } else if (key === 'Accepted Values') {
+        return /\[.+\]\(.+\)/.test(str) || /^\*$/.test(str) ? undefined : str.replaceAll(/`/g, '').replaceAll(/\([^)]*\)(?!\s*=>)/g, '')
+    } else if (key === 'Subtags') {
+        return str
+            ? `el-${str
+                  .replaceAll(/\s*\/\s*/g, '/el-')
+                  .replaceAll(/\B([A-Z])/g, '-$1')
+                  .replaceAll(/\s+/g, '-')
+                  .toLowerCase()}`
+            : undefined
+    } else {
+        return str
+    }
 }
 
-const reWebTypesType: ReWebTypesType = (type) => {
-  const isPublicType = isCommonType(type)
-  const symbol = getTypeSymbol(type)
-  const isUnion = isUnionType(symbol)
-  const module = findModule(symbol)
+const reWebTypesType: ReWebTypesType = type => {
+    const isPublicType = isCommonType(type)
+    const symbol = getTypeSymbol(type)
+    const isUnion = isUnionType(symbol)
+    const module = findModule(symbol)
 
-  return isPublicType || !symbol || isUnion
-    ? type
-    : { name: type, source: { symbol, module } }
+    return isPublicType || !symbol || isUnion ? type : { name: type, source: { symbol, module } }
 }
 
 const findModule = (type: string): string | undefined => {
-  let result: string | undefined = undefined
+    let result: string | undefined = undefined
 
-  for (const key in typeMap) {
-    const regExp = arrayToRegExp(typeMap[key as keyof typeof typeMap])
-    const inModule = regExp.test(getTypeSymbol(type))
+    for (const key in typeMap) {
+        const regExp = arrayToRegExp(typeMap[key as keyof typeof typeMap])
+        const inModule = regExp.test(getTypeSymbol(type))
 
-    if (inModule) {
-      result = key
-      break
+        if (inModule) {
+            result = key
+            break
+        }
     }
-  }
 
-  return result
+    return result
 }
 
-export const buildHelper: TaskFunction = (done) => {
-  const { name, version } = getPackageManifest(epPackage)
-
-  const tagVer = process.env.TAG_VERSION
-  const _version = tagVer
-    ? tagVer.startsWith('v')
-      ? tagVer.slice(1)
-      : tagVer
-    : version!
-
-  main({
-    name: name!,
-    version: _version,
-    entry: `${path.resolve(
-      projRoot,
-      'docs/en-US/component'
-    )}/!(datetime-picker|message-box|message).md`,
-    outDir: epOutput,
-    reComponentName,
-    reDocUrl,
-    reWebTypesSource,
-    reAttribute,
-    reWebTypesType,
-    props: 'Attributes',
-    propsOptions: 'Accepted Values',
-    tableRegExp:
-      /#+\s+(.*\s*Attributes|.*\s*Events|.*\s*Slots|.*\s*Directives)\s*\n+(\|?.+\|.+)\n\|?\s*:?-+:?\s*\|.+((\n\|?.+\|.+)+)/g,
-  })
-
-  done()
+export const buildHelper: TaskFunction = done => {
+    const { name, version } = getPackageManifest(epPackage)
+
+    const tagVer = process.env.TAG_VERSION
+    const _version = tagVer ? (tagVer.startsWith('v') ? tagVer.slice(1) : tagVer) : version!
+
+    main({
+        name: name!,
+        version: _version,
+        entry: `${path.resolve(projRoot, 'docs/en-US/component')}/!(datetime-picker|message-box|message).md`,
+        outDir: epOutput,
+        reComponentName,
+        reDocUrl,
+        reWebTypesSource,
+        reAttribute,
+        reWebTypesType,
+        props: 'Attributes',
+        propsOptions: 'Accepted Values',
+        tableRegExp: /#+\s+(.*\s*Attributes|.*\s*Events|.*\s*Slots|.*\s*Directives)\s*\n+(\|?.+\|.+)\n\|?\s*:?-+:?\s*\|.+((\n\|?.+\|.+)+)/g,
+    })
+
+    done()
 }

+ 49 - 49
internal/build/src/tasks/modules.ts

@@ -14,54 +14,54 @@ import { buildConfigEntries, target } from '../build-info'
 import type { OutputOptions } from 'rollup'
 
 export const buildModules = async () => {
-  const input = excludeFiles(
-    await glob('**/*.{js,ts,vue}', {
-      cwd: pkgRoot,
-      absolute: true,
-      onlyFiles: true,
+    const input = excludeFiles(
+        await glob('**/*.{js,ts,vue}', {
+            cwd: pkgRoot,
+            absolute: true,
+            onlyFiles: true,
+        })
+    )
+    const bundle = await rollup({
+        input,
+        plugins: [
+            ElementPlusAlias(),
+            VueMacros({
+                setupComponent: false,
+                setupSFC: false,
+                plugins: {
+                    vue: vue({
+                        isProduction: false,
+                    }),
+                    vueJsx: vueJsx(),
+                },
+            }),
+            nodeResolve({
+                extensions: ['.mjs', '.js', '.json', '.ts'],
+            }),
+            commonjs(),
+            esbuild({
+                sourceMap: true,
+                target,
+                loaders: {
+                    '.vue': 'ts',
+                },
+            }),
+        ],
+        external: await generateExternal({ full: false }),
+        treeshake: false,
     })
-  )
-  const bundle = await rollup({
-    input,
-    plugins: [
-      ElementPlusAlias(),
-      VueMacros({
-        setupComponent: false,
-        setupSFC: false,
-        plugins: {
-          vue: vue({
-            isProduction: false,
-          }),
-          vueJsx: vueJsx(),
-        },
-      }),
-      nodeResolve({
-        extensions: ['.mjs', '.js', '.json', '.ts'],
-      }),
-      commonjs(),
-      esbuild({
-        sourceMap: true,
-        target,
-        loaders: {
-          '.vue': 'ts',
-        },
-      }),
-    ],
-    external: await generateExternal({ full: false }),
-    treeshake: false,
-  })
-  await writeBundles(
-    bundle,
-    buildConfigEntries.map(([module, config]): OutputOptions => {
-      return {
-        format: config.format,
-        dir: config.output.path,
-        exports: module === 'cjs' ? 'named' : undefined,
-        preserveModules: true,
-        preserveModulesRoot: epRoot,
-        sourcemap: true,
-        entryFileNames: `[name].${config.ext}`,
-      }
-    })
-  )
+    await writeBundles(
+        bundle,
+        buildConfigEntries.map(([module, config]): OutputOptions => {
+            return {
+                format: config.format,
+                dir: config.output.path,
+                exports: module === 'cjs' ? 'named' : undefined,
+                preserveModules: true,
+                preserveModulesRoot: epRoot,
+                sourcemap: true,
+                entryFileNames: `[name].${config.ext}`,
+            }
+        })
+    )
 }

+ 104 - 128
internal/build/src/tasks/types-definitions.ts

@@ -6,13 +6,7 @@ import * as vueCompiler from 'vue/compiler-sfc'
 import glob from 'fast-glob'
 import chalk from 'chalk'
 import { Project } from 'ts-morph'
-import {
-  buildOutput,
-  epRoot,
-  excludeFiles,
-  pkgRoot,
-  projRoot,
-} from '@kankan/build-utils'
+import { buildOutput, epRoot, excludeFiles, pkgRoot, projRoot } from '@kankan/build-utils'
 import { pathRewriter } from '../utils'
 import type { CompilerOptions, SourceFile } from 'ts-morph'
 
@@ -23,136 +17,118 @@ const outDir = path.resolve(buildOutput, 'types')
  * fork = require( https://github.com/egoist/vue-dts-gen/blob/main/src/index.ts
  */
 export const generateTypesDefinitions = async () => {
-  const compilerOptions: CompilerOptions = {
-    emitDeclarationOnly: true,
-    outDir,
-    baseUrl: projRoot,
-    preserveSymlinks: true,
-    skipLibCheck: true,
-    noImplicitAny: false,
-  }
-  const project = new Project({
-    compilerOptions,
-    tsConfigFilePath: TSCONFIG_PATH,
-    skipAddingFilesFromTsConfig: true,
-  })
-
-  const sourceFiles = await addSourceFiles(project)
-  consola.success('Added source files')
-
-  typeCheck(project)
-  consola.success('Type check passed!')
-
-  await project.emit({
-    emitOnlyDtsFiles: true,
-  })
-
-  const tasks = sourceFiles.map(async (sourceFile) => {
-    const relativePath = path.relative(pkgRoot, sourceFile.getFilePath())
-    consola.trace(
-      chalk.yellow(
-        `Generating definition for file: ${chalk.bold(relativePath)}`
-      )
-    )
-
-    const emitOutput = sourceFile.getEmitOutput()
-    const emitFiles = emitOutput.getOutputFiles()
-    if (emitFiles.length === 0) {
-      throw new Error(`Emit no file: ${chalk.bold(relativePath)}`)
+    const compilerOptions: CompilerOptions = {
+        emitDeclarationOnly: true,
+        outDir,
+        baseUrl: projRoot,
+        preserveSymlinks: true,
+        skipLibCheck: true,
+        noImplicitAny: false,
     }
+    const project = new Project({
+        compilerOptions,
+        tsConfigFilePath: TSCONFIG_PATH,
+        skipAddingFilesFromTsConfig: true,
+    })
 
-    const subTasks = emitFiles.map(async (outputFile) => {
-      const filepath = outputFile.getFilePath()
-      await mkdir(path.dirname(filepath), {
-        recursive: true,
-      })
-
-      await writeFile(
-        filepath,
-        pathRewriter('esm')(outputFile.getText()),
-        'utf8'
-      )
-
-      consola.success(
-        chalk.green(
-          `Definition for file: ${chalk.bold(relativePath)} generated`
-        )
-      )
+    const sourceFiles = await addSourceFiles(project)
+    consola.success('Added source files')
+
+    typeCheck(project)
+    consola.success('Type check passed!')
+
+    await project.emit({
+        emitOnlyDtsFiles: true,
     })
 
-    await Promise.all(subTasks)
-  })
+    const tasks = sourceFiles.map(async sourceFile => {
+        const relativePath = path.relative(pkgRoot, sourceFile.getFilePath())
+        consola.trace(chalk.yellow(`Generating definition for file: ${chalk.bold(relativePath)}`))
+
+        const emitOutput = sourceFile.getEmitOutput()
+        const emitFiles = emitOutput.getOutputFiles()
+        if (emitFiles.length === 0) {
+            throw new Error(`Emit no file: ${chalk.bold(relativePath)}`)
+        }
+
+        const subTasks = emitFiles.map(async outputFile => {
+            const filepath = outputFile.getFilePath()
+            await mkdir(path.dirname(filepath), {
+                recursive: true,
+            })
+
+            await writeFile(filepath, pathRewriter('esm')(outputFile.getText()), 'utf8')
+
+            consola.success(chalk.green(`Definition for file: ${chalk.bold(relativePath)} generated`))
+        })
 
-  await Promise.all(tasks)
+        await Promise.all(subTasks)
+    })
+
+    await Promise.all(tasks)
 }
 
 async function addSourceFiles(project: Project) {
-  project.addSourceFileAtPath(path.resolve(projRoot, 'typings/env.d.ts'))
-
-  const globSourceFile = '**/*.{js?(x),ts?(x),vue}'
-  const filePaths = excludeFiles(
-    await glob([globSourceFile, '!element-plus/**/*'], {
-      cwd: pkgRoot,
-      absolute: true,
-      onlyFiles: true,
-    })
-  )
-  const epPaths = excludeFiles(
-    await glob(globSourceFile, {
-      cwd: epRoot,
-      onlyFiles: true,
-    })
-  )
-
-  const sourceFiles: SourceFile[] = []
-  await Promise.all([
-    ...filePaths.map(async (file) => {
-      if (file.endsWith('.vue')) {
-        const content = await readFile(file, 'utf-8')
-        const hasTsNoCheck = content.includes('@ts-nocheck')
-
-        const sfc = vueCompiler.parse(content)
-        const { script, scriptSetup } = sfc.descriptor
-        if (script || scriptSetup) {
-          let content =
-            (hasTsNoCheck ? '// @ts-nocheck\n' : '') + (script?.content ?? '')
-
-          if (scriptSetup) {
-            const compiled = vueCompiler.compileScript(sfc.descriptor, {
-              id: 'xxx',
-            })
-            content += compiled.content
-          }
-
-          const lang = scriptSetup?.lang || script?.lang || 'js'
-          const sourceFile = project.createSourceFile(
-            `${path.relative(process.cwd(), file)}.${lang}`,
-            content
-          )
-          sourceFiles.push(sourceFile)
-        }
-      } else {
-        const sourceFile = project.addSourceFileAtPath(file)
-        sourceFiles.push(sourceFile)
-      }
-    }),
-    ...epPaths.map(async (file) => {
-      const content = await readFile(path.resolve(epRoot, file), 'utf-8')
-      sourceFiles.push(
-        project.createSourceFile(path.resolve(pkgRoot, file), content)
-      )
-    }),
-  ])
-
-  return sourceFiles
+    project.addSourceFileAtPath(path.resolve(projRoot, 'typings/env.d.ts'))
+
+    const globSourceFile = '**/*.{js?(x),ts?(x),vue}'
+    const filePaths = excludeFiles(
+        await glob([globSourceFile, '!element-plus/**/*'], {
+            cwd: pkgRoot,
+            absolute: true,
+            onlyFiles: true,
+        })
+    )
+    const epPaths = excludeFiles(
+        await glob(globSourceFile, {
+            cwd: epRoot,
+            onlyFiles: true,
+        })
+    )
+
+    const sourceFiles: SourceFile[] = []
+    await Promise.all([
+        ...filePaths.map(async file => {
+            if (file.endsWith('.vue')) {
+                const content = await readFile(file, 'utf-8')
+                const hasTsNoCheck = content.includes('@ts-nocheck')
+
+                const sfc = vueCompiler.parse(content)
+                const { script, scriptSetup } = sfc.descriptor
+                if (script || scriptSetup) {
+                    let content = (hasTsNoCheck ? '// @ts-nocheck\n' : '') + (script?.content ?? '')
+
+                    if (scriptSetup) {
+                        const compiled = vueCompiler.compileScript(sfc.descriptor, {
+                            id: 'xxx',
+                        })
+                        content += compiled.content
+                    }
+
+                    const lang = scriptSetup?.lang || script?.lang || 'js'
+                    const sourceFile = project.createSourceFile(`${path.relative(process.cwd(), file)}.${lang}`, content)
+                    sourceFiles.push(sourceFile)
+                }
+            } else {
+                const sourceFile = project.addSourceFileAtPath(file)
+                sourceFiles.push(sourceFile)
+            }
+        }),
+        ...epPaths.map(async file => {
+            const content = await readFile(path.resolve(epRoot, file), 'utf-8')
+            sourceFiles.push(project.createSourceFile(path.resolve(pkgRoot, file), content))
+        }),
+    ])
+
+    return sourceFiles
 }
 
 function typeCheck(project: Project) {
-  const diagnostics = project.getPreEmitDiagnostics()
-  if (diagnostics.length > 0) {
-    consola.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
-    const err = new Error('Failed to generate dts.')
-    consola.error(err)
-    throw err
-  }
+    const diagnostics = project.getPreEmitDiagnostics()
+    if (diagnostics.length > 0) {
+        consola.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
+        const err = new Error('Failed to generate dts.')
+        consola.error(err)
+        throw err
+    }
 }

+ 2 - 6
internal/build/src/utils/gulp.ts

@@ -3,10 +3,6 @@ import { run } from './process'
 
 import type { TaskFunction } from 'gulp'
 
-export const withTaskName = <T extends TaskFunction>(name: string, fn: T) =>
-  Object.assign(fn, { displayName: name })
+export const withTaskName = <T extends TaskFunction>(name: string, fn: T) => Object.assign(fn, { displayName: name })
 
-export const runTask = (name: string) =>
-  withTaskName(`shellTask:${name}`, () =>
-    run(`pnpm run start ${name}`, buildRoot)
-  )
+export const runTask = (name: string) => withTaskName(`shellTask:${name}`, () => run(`pnpm run start ${name}`, buildRoot))

+ 6 - 6
internal/build/src/utils/pkg.ts

@@ -5,11 +5,11 @@ import type { Module } from '../build-info'
 
 /** used for type generator */
 export const pathRewriter = (module: Module) => {
-  const config = buildConfig[module]
+    const config = buildConfig[module]
 
-  return (id: string) => {
-    id = id.replaceAll(`${PKG_PREFIX}/theme-chalk`, `${PKG_NAME}/theme-chalk`)
-    id = id.replaceAll(`${PKG_PREFIX}/`, `${config.bundle.path}/`)
-    return id
-  }
+    return (id: string) => {
+        id = id.replaceAll(`${PKG_PREFIX}/theme-chalk`, `${PKG_NAME}/theme-chalk`)
+        id = id.replaceAll(`${PKG_PREFIX}/`, `${config.bundle.path}/`)
+        return id
+    }
 }

+ 15 - 18
internal/build/src/utils/process.ts

@@ -4,25 +4,22 @@ import consola from 'consola'
 import { projRoot } from '@kankan/build-utils'
 
 export const run = async (command: string, cwd: string = projRoot) =>
-  new Promise<void>((resolve, reject) => {
-    const [cmd, ...args] = command.split(' ')
-    consola.info(`run: ${chalk.green(`${cmd} ${args.join(' ')}`)}`)
-    const app = spawn(cmd, args, {
-      cwd,
-      stdio: 'inherit',
-      shell: process.platform === 'win32',
-    })
+    new Promise<void>((resolve, reject) => {
+        const [cmd, ...args] = command.split(' ')
+        consola.info(`run: ${chalk.green(`${cmd} ${args.join(' ')}`)}`)
+        const app = spawn(cmd, args, {
+            cwd,
+            stdio: 'inherit',
+            shell: process.platform === 'win32',
+        })
 
-    const onProcessExit = () => app.kill('SIGHUP')
+        const onProcessExit = () => app.kill('SIGHUP')
 
-    app.on('close', (code) => {
-      process.removeListener('exit', onProcessExit)
+        app.on('close', code => {
+            process.removeListener('exit', onProcessExit)
 
-      if (code === 0) resolve()
-      else
-        reject(
-          new Error(`Command failed. \n Command: ${command} \n Code: ${code}`)
-        )
+            if (code === 0) resolve()
+            else reject(new Error(`Command failed. \n Command: ${command} \n Code: ${code}`))
+        })
+        process.on('exit', onProcessExit)
     })
-    process.on('exit', onProcessExit)
-  })

+ 11 - 17
internal/build/src/utils/rollup.ts

@@ -3,28 +3,22 @@ import { epPackage, getPackageDependencies } from '@kankan/build-utils'
 import type { OutputOptions, RollupBuild } from 'rollup'
 
 export const generateExternal = async (options: { full: boolean }) => {
-  const { dependencies, peerDependencies } = getPackageDependencies(epPackage)
+    const { dependencies, peerDependencies } = getPackageDependencies(epPackage)
 
-  return (id: string) => {
-    const packages: string[] = peerDependencies
-    if (!options.full) {
-      packages.push('@vue', ...dependencies)
-    }
+    return (id: string) => {
+        const packages: string[] = peerDependencies
+        if (!options.full) {
+            packages.push('@vue', ...dependencies)
+        }
 
-    return [...new Set(packages)].some(
-      (pkg) => id === pkg || id.startsWith(`${pkg}/`)
-    )
-  }
+        return [...new Set(packages)].some(pkg => id === pkg || id.startsWith(`${pkg}/`))
+    }
 }
 
 export function writeBundles(bundle: RollupBuild, options: OutputOptions[]) {
-  return Promise.all(options.map((option) => bundle.write(option)))
+    return Promise.all(options.map(option => bundle.write(option)))
 }
 
-export function formatBundleFilename(
-  name: string,
-  minify: boolean,
-  ext: string
-) {
-  return `${name}${minify ? '.min' : ''}.${ext}`
+export function formatBundleFilename(name: string, minify: boolean, ext: string) {
+    return `${name}${minify ? '.min' : ''}.${ext}`
 }

+ 12 - 9
package.json

@@ -1,7 +1,7 @@
 {
     "name": "kankan-components",
-    "description": "a collection of 4dkankan components",
     "private": true,
+    "description": "a collection of 4dkankan components",
     "workspaces": [
         "packages/*",
         "apps/*"
@@ -36,18 +36,21 @@
     "devDependencies": {
         "@changesets/cli": "^2.24.4",
         "@commitlint/cli": "^17.1.2",
-        "@types/jsdom": "^16.2.14",
-        "@types/node": "*",
+        "@kankan/build": "workspace:*",
+        "@kankan/build-utils": "workspace:*",
+        "@kankan/eslint-config": "workspace:*",
         "@pnpm/find-workspace-packages": "^4.0.16",
         "@pnpm/logger": "^4.0.0",
         "@pnpm/types": "^8.4.0",
+        "@types/jsdom": "^16.2.14",
+        "@types/node": "*",
         "@typescript-eslint/eslint-plugin": "^5.38.1",
         "@vitejs/plugin-vue": "^3.1.0",
         "@vitejs/plugin-vue-jsx": "^2.0.1",
         "@vue/test-utils": "^2.0.2",
         "commitizen": "^4.2.5",
-        "concurrently": "^7.2.2",
         "commitlint-config-cz": "^0.13.3",
+        "concurrently": "^7.2.2",
         "cz-customizable": "^7.0.0",
         "eslint": "~8.23.1",
         "eslint-config-prettier": "^8.5.0",
@@ -67,14 +70,14 @@
         "unplugin-vue-macros": "^0.11.2",
         "vitest": "^0.23.4"
     },
-    "lint-staged": {
-        "*.{vue,js,ts,jsx,tsx,mts,json}": [
-            "eslint --fix"
-        ]
-    },
     "config": {
         "commitizen": {
             "path": "cz-customizable"
         }
+    },
+    "lint-staged": {
+        "*.{vue,js,ts,jsx,tsx,mts,json}": [
+            "eslint --fix"
+        ]
     }
 }

+ 2 - 2
packages/components/basic/audio/__tests__/audio.test.tsx

@@ -1,6 +1,6 @@
-import { describe, expect, test } from 'vitest'
-import { mount } from '@vue/test-utils'
 import { ref } from 'vue'
+import { mount } from '@vue/test-utils'
+import { describe, expect, test } from 'vitest'
 import Audio from '../src/audio.vue'
 // import type { VNode } from 'vue';
 

+ 2 - 2
packages/components/basic/audio/src/audio.vue

@@ -1,9 +1,9 @@
 <template>
     <div class="ui-audio" @click="clickHandler">
-        <audio @play="rotation" ref="audio" autoplay loop>
+        <audio ref="audio" autoplay loop @play="rotation">
             <source :src="src" />
         </audio>
-        <span v-for="random in randoms" :style="{ '--percent': random }" :key="random"></span>
+        <span v-for="random in randoms" :key="random" :style="{ '--percent': random }" />
     </div>
 </template>
 

+ 3 - 3
packages/components/basic/bubble/src/bubble.vue

@@ -1,9 +1,9 @@
 <template>
     <transition name="fade">
-        <div class="bubble" :class="{ [type]: true, [level]: true }" v-if="show" @click.stop>
+        <div v-if="show" class="bubble" :class="{ [type]: true, [level]: true }" @click.stop>
             <div class="bubble-layer">
-                <div class="bubble-arr"></div>
-                <slot></slot>
+                <div class="bubble-arr" />
+                <slot />
             </div>
         </div>
     </transition>

+ 1 - 1
packages/components/basic/button/src/button.ts

@@ -1,5 +1,5 @@
-import type { ExtractPropTypes } from 'vue'
 import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
 import type button from './button.vue'
 
 export const buttonProps = buildProps({

+ 3 - 3
packages/components/basic/button/src/button.vue

@@ -1,12 +1,12 @@
 <template>
     <button class="ui-button" :class="className" :style="style">
-        <UIIcon :type="icon" v-if="icon" class="ui-button-icon" />
-        <slot></slot>
+        <UIIcon v-if="icon" :type="icon" class="ui-button-icon" />
+        <slot />
     </button>
 </template>
 
 <script lang="ts" setup>
-import { defineProps, computed } from 'vue'
+import { computed, defineProps } from 'vue'
 import { normalizeUnitToStyle } from '@kankan/utils'
 // import UIIcon from '../../icon/src/icon.vue'
 import UIIcon from '@kankan/components/basic/icon'

+ 8 - 8
packages/components/basic/cropper/cropper.vue

@@ -1,14 +1,14 @@
 <template>
     <div>
-        <Confirm :title="title" :func="clickHandler" :noText="noText" :okText="okText">
+        <Confirm :title="title" :func="clickHandler" :no-text="noText" :ok-text="okText">
             <template #content>
                 <div>
                     <div class="cropper-layer" :style="style">
                         <VueCropper v-if="show" ref="vmRef" v-bind="option" v-on="on" />
                     </div>
-                    <div class="size" v-if="showSize">
-                        <ui-input :label="`Logo-${longSize}`" type="radio" name="size" :modelValue="sizeType == 1" @update:modelValue="changSize(1)" />
-                        <ui-input :label="`Logo-${squareSize}`" type="radio" name="size" :modelValue="sizeType == 2" @update:modelValue="changSize(2)" />
+                    <div v-if="showSize" class="size">
+                        <ui-input :label="`Logo-${longSize}`" type="radio" name="size" :model-value="sizeType == 1" @update:modelValue="changSize(1)" />
+                        <ui-input :label="`Logo-${squareSize}`" type="radio" name="size" :model-value="sizeType == 2" @update:modelValue="changSize(2)" />
                     </div>
                 </div>
             </template>
@@ -17,9 +17,9 @@
 </template>
 
 <script setup lang="ts">
+import { computed, defineProps, nextTick, ref } from 'vue'
 import { VueCropper } from 'vue-cropper'
 import Confirm from '../dialog/confirm.vue'
-import { computed, defineProps, ref, nextTick } from 'vue'
 import 'vue-cropper/dist/index.css'
 // import { useI18n } from '@/i18n'
 // const { t } = useI18n({ useScope: 'global' })
@@ -104,8 +104,8 @@ const changSize = type => {
     }
 }
 const style = computed(() => ({
-    width: layerWidth + 'px',
-    height: getHeight(layerWidth) + 'px',
+    width: `${layerWidth}px`,
+    height: `${getHeight(layerWidth)}px`,
 }))
 
 const vmRef = ref()
@@ -119,7 +119,7 @@ const on = {
 
 const clickHandler = async status => {
     if (status === 'ok') {
-        let data = await Promise.all([new Promise(resolve => vmRef.value.getCropBlob(resolve)), new Promise(resolve => vmRef.value.getCropData(resolve))])
+        const data = await Promise.all([new Promise(resolve => vmRef.value.getCropBlob(resolve)), new Promise(resolve => vmRef.value.getCropData(resolve))])
         if (props.showSize) {
             data.push(sizeType.value)
         }

+ 1 - 1
packages/components/basic/cropper/index.js

@@ -1,6 +1,6 @@
-import Cropper from './cropper.vue'
 import { mount } from '../../utils/componentHelper'
 import { toRawType } from '../../utils/index'
+import Cropper from './cropper.vue'
 
 Cropper.use = function use(app) {
     const isCropper = false

+ 4 - 4
packages/components/basic/dialog/src/alert.vue

@@ -2,10 +2,10 @@
     <ui-dialog>
         <template #header>
             <span>{{ title }}</span>
-            <i v-if="showCloseIcon" class="iconfont icon-close" @click="close"></i>
+            <i v-if="showCloseIcon" class="iconfont icon-close" @click="close" />
         </template>
-        <div v-html="content"></div>
-        <template #footer v-if="showFooter">
+        <div v-html="content" />
+        <template v-if="showFooter" #footer>
             <ui-button type="submit" @click="close">{{ okText }}</ui-button>
         </template>
     </ui-dialog>
@@ -37,7 +37,7 @@ export default defineComponent({
         content: String,
         destroy: Function,
     },
-    setup: function (props) {
+    setup(props) {
         const close = () => {
             if (isFunction(props.func) && props.func() === false) {
                 return

+ 5 - 5
packages/components/basic/dialog/src/confirm.vue

@@ -2,15 +2,15 @@
     <ui-dialog>
         <template #header>
             <span>{{ title }}</span>
-            <i class="iconfont icon-close" @click="close('no')"></i>
+            <i class="iconfont icon-close" @click="close('no')" />
         </template>
         <template v-if="$slots.content">
-            <slot name="content"></slot>
+            <slot name="content" />
         </template>
         <template v-else>
-            <div class="message" v-html="content"></div>
+            <div class="message" v-html="content" />
         </template>
-        <template #footer v-if="!hideFoot">
+        <template v-if="!hideFoot" #footer>
             <ui-button v-if="!single" type="cancel" @click="close('no')">{{ noText }}</ui-button>
             <ui-button type="primary" @click="close('ok')">{{ okText }}</ui-button>
         </template>
@@ -47,7 +47,7 @@ export default defineComponent({
         content: String,
         destroy: Function,
     },
-    setup: function (props, _) {
+    setup(props, _) {
         const close = result => {
             if (isFunction(props.func) && props.func(result) === false) {
                 return

+ 3 - 3
packages/components/basic/dialog/src/dialog-content.vue

@@ -1,13 +1,13 @@
 <template>
     <div class="ui-dialog__box">
         <header v-if="$slots.header">
-            <slot name="header"></slot>
+            <slot name="header" />
         </header>
         <section>
-            <slot></slot>
+            <slot />
         </section>
         <footer v-if="$slots.footer">
-            <slot name="footer"></slot>
+            <slot name="footer" />
         </footer>
     </div>
 </template>

+ 1 - 1
packages/components/basic/dialog/src/dialog.ts

@@ -1,10 +1,10 @@
+import { mount } from '@vue/test-utils'
 import Dialog from './dialog.vue'
 import Window from './window.vue'
 import Toast from './toast.vue'
 import Alert from './alert.vue'
 import Confirm from './confirm.vue'
 import DialogContent from './dialog-content.vue'
-import { mount } from '@vue/test-utils'
 
 Dialog.use = function use(app) {
     Dialog.toast = function (options) {

+ 4 - 4
packages/components/basic/dialog/src/dialog.vue

@@ -1,9 +1,9 @@
 <template>
     <teleport to="body">
-        <div class="ui-dialog" :style="{ zIndex: zIndex }" v-if="show">
+        <div v-if="show" class="ui-dialog" :style="{ zIndex: zIndex }">
             <dialog-content>
                 <template v-for="(slot, name) in $slots" #[name]="raw">
-                    <slot :name="name" v-bind="raw"></slot>
+                    <slot :name="name" v-bind="raw" />
                 </template>
             </dialog-content>
         </div>
@@ -12,13 +12,13 @@
 <script lang="ts">
 import { defineComponent, ref } from 'vue'
 import { useZIndex } from '@kankan/hooks'
-const { currentZIndex } = useZIndex()
 
 import DialogContent from './dialog-content.vue'
+const { currentZIndex } = useZIndex()
 export default defineComponent({
     name: 'UIDialog',
     components: { DialogContent },
-    setup: function () {
+    setup() {
         const show = ref(true)
         return {
             show,

+ 5 - 5
packages/components/basic/dialog/src/toast.vue

@@ -1,11 +1,11 @@
 <template>
     <teleport to="body">
         <transition name="slide-down" mode="out-in" appear>
-            <div class="ui-toast" :style="{ zIndex: zIndex }" v-if="show">
+            <div v-if="show" class="ui-toast" :style="{ zIndex: zIndex }">
                 <div class="ui-toast__box" :class="[type]">
-                    <i v-if="type !== 'fixed' && type" class="icon"></i>
-                    <div class="ui-toast__msg" v-html="content"></div>
-                    <i class="iconfont icon-close close" @click="close" v-if="showClose"></i>
+                    <i v-if="type !== 'fixed' && type" class="icon" />
+                    <div class="ui-toast__msg" v-html="content" />
+                    <i v-if="showClose" class="iconfont icon-close close" @click="close" />
                 </div>
             </div>
         </transition>
@@ -26,7 +26,7 @@ export default defineComponent({
         close: Function,
         showClose: Boolean,
     },
-    setup: function (props, _) {
+    setup(props, _) {
         const show = ref(true)
         const close = () => {
             show.value = false

+ 5 - 5
packages/components/basic/dialog/src/window.vue

@@ -2,16 +2,16 @@
     <ui-dialog>
         <template #header>
             <span style="font-size: 16px">{{ title }}</span>
-            <i class="iconfont icon-close" @click="onNo('close')" v-if="showCloseIcon"></i>
+            <i v-if="showCloseIcon" class="iconfont icon-close" @click="onNo('close')" />
         </template>
         <template v-if="$slots.content">
-            <slot name="content"></slot>
+            <slot name="content" />
         </template>
         <template v-else>
-            <div class="message" v-html="content"></div>
+            <div class="message" v-html="content" />
         </template>
         <template #footer>
-            <ui-button type="cancel" @click="onNo" v-if="showCancelButton">{{ noText }}</ui-button>
+            <ui-button v-if="showCancelButton" type="cancel" @click="onNo">{{ noText }}</ui-button>
             <ui-button :class="{ disabled: !canSubmit }" type="submit primary" @click="onOk">{{ okText }}</ui-button>
         </template>
     </ui-dialog>
@@ -51,7 +51,7 @@ export default defineComponent({
         },
     },
     emits: ['ok', 'no'],
-    setup: function (props, ctx) {
+    setup(props, ctx) {
         const onNo = name => {
             ctx.emit('no', name)
         }

+ 14 - 13
packages/components/basic/floating/src/floating.vue

@@ -1,14 +1,14 @@
 <template>
     <teleport :to="mount">
         <div class="ui-floating" :style="style" :class="props.class" @mouseenter="emit('enter')" @mouseleave="emit('leave')">
-            <slot></slot>
+            <slot />
         </div>
     </teleport>
 </template>
 
 <script setup lang="ts">
 // onUpdated
-import { defineProps, defineExpose, onUnmounted, reactive, watch, computed, onActivated } from 'vue'
+import { computed, defineExpose, defineProps, onActivated, onUnmounted, reactive, watch } from 'vue'
 import { getPostionByTarget, getScrollParents } from '@kankan/utils'
 import { useZIndex } from '@kankan/hooks'
 const { currentZIndex } = useZIndex()
@@ -58,16 +58,17 @@ const dires = computed(() => {
     return [horizontal, vertical]
 })
 
-const normalizeUnit = (unit, total) => {
-    if (unit === void 0) {
-        return void 0
+const normalizeUnit = (unit: number | string, total: number): number => {
+    if (unit === 0) {
+        return 0
     } else if (typeof unit === 'number') {
-        return unit ? ((unit <= 1) & (unit >= 0) ? total * unit : unit) : void 0
+        return unit ? (unit <= 1 && unit >= 0 ? total * unit : unit) : 0
     } else if (unit.includes('px')) {
-        return normalizeUnit(parseFloat(unit), total)
+        return normalizeUnit(Number.parseFloat(unit), total)
     } else if (unit.includes('%')) {
-        return normalizeUnit(parseFloat(unit) / 100, total)
+        return normalizeUnit(Number.parseFloat(unit) / 100, total)
     }
+    return 0
 }
 
 const width = computed(() => props.refer && normalizeUnit(props.width, props.refer.offsetWidth))
@@ -91,11 +92,11 @@ watch(
 // const zIndex = currentZIndex
 
 const style = computed(() => {
-    let style = {
-        width: width.value && width.value + 'px',
-        height: height.value && height.value + 'px',
-        left: location.x + 'px',
-        top: location.y + 'px',
+    const style = {
+        width: width.value && `${width.value}px`,
+        height: height.value && `${height.value}px`,
+        left: `${location.x}px`,
+        top: `${location.y}px`,
         zIndex: currentZIndex,
     }
     if (location.x > 0 && location.y > 0) {

+ 3 - 3
packages/components/basic/gate/content.vue

@@ -1,12 +1,12 @@
 <template>
-    <div class="ui-gate-content" :class="{ active }" v-if="brotherInstances">
-        <slot :active="active"></slot>
+    <div v-if="brotherInstances" class="ui-gate-content" :class="{ active }">
+        <slot :active="active" />
     </div>
 </template>
 
 <script setup>
 // getCurrentInstance
-import { onBeforeMount, ref, inject, onUnmounted } from 'vue'
+import { inject, onBeforeMount, onUnmounted, ref } from 'vue'
 import { Relation } from './constant'
 
 const active = ref(false)

+ 3 - 3
packages/components/basic/gate/layer.vue

@@ -8,15 +8,15 @@
         }"
     >
         <div class="ui-gate-slides">
-            <slot></slot>
+            <slot />
         </div>
     </div>
 </template>
 
 <script setup>
 // watchEffect
-import { ref, defineProps, computed, provide, watch } from 'vue'
-import { normalizeUnitToStyle } from '../../utils'
+import { computed, defineProps, provide, ref, watch } from 'vue'
+import { normalizeUnitToStyle } from '@kankan/utils'
 import { Relation } from './constant'
 
 const contentInstances = ref([])

+ 3 - 3
packages/components/basic/group/ui-group-option.vue

@@ -1,15 +1,15 @@
 <template>
     <div class="group-option">
-        <span class="group-option-label" v-if="props.label">
+        <span v-if="props.label" class="group-option-label">
             {{ props.label }}
         </span>
-        <slot></slot>
+        <slot />
     </div>
 </template>
 
 <script setup>
+import { getCurrentInstance, inject, onBeforeMount, onUnmounted } from 'vue'
 import { Relation } from './constant'
-import { inject, onBeforeMount, onUnmounted, getCurrentInstance } from 'vue'
 const props = defineProps({
     label: String,
 })

+ 12 - 12
packages/components/basic/group/ui-group.vue

@@ -3,36 +3,36 @@
         <template v-if="!$slots.header">
             <h3 v-if="props.title" class="group-title" :class="!$slots.default && contentStyle">
                 {{ props.title }}
-                <span class="group-icon" :class="animationRef && { show: animationRef.show }" @click="control && animationRef.changeShow()" v-if="$slots.icon || control">
-                    <slot name="icon" v-if="$slots.icon"></slot>
-                    <icon type="pull-down" size="12px" v-else />
+                <span v-if="$slots.icon || control" class="group-icon" :class="animationRef && { show: animationRef.show }" @click="control && animationRef.changeShow()">
+                    <slot v-if="$slots.icon" name="icon" />
+                    <icon v-else type="pull-down" size="12px" />
                 </span>
             </h3>
         </template>
         <div v-else class="group-title" :class="!$slots.default && contentStyle">
-            <slot name="header"></slot>
+            <slot name="header" />
 
-            <span class="group-icon" :class="animationRef && { show: animationRef.show }" @click="control && animationRef.changeShow()" v-if="$slots.icon || control">
-                <slot name="icon" v-if="$slots.icon"></slot>
-                <icon type="pull-down" size="12px" v-else />
+            <span v-if="$slots.icon || control" class="group-icon" :class="animationRef && { show: animationRef.show }" @click="control && animationRef.changeShow()">
+                <slot v-if="$slots.icon" name="icon" />
+                <icon v-else type="pull-down" size="12px" />
             </span>
         </div>
 
         <template v-if="$slots.default">
-            <UISizeAnimation ref="animationRef" class="group-content" :class="contentStyle" v-if="control">
-                <slot></slot>
+            <UISizeAnimation v-if="control" ref="animationRef" class="group-content" :class="contentStyle">
+                <slot />
             </UISizeAnimation>
-            <div class="group-content" :class="contentStyle" v-else>
-                <slot></slot>
+            <div v-else class="group-content" :class="contentStyle">
+                <slot />
             </div>
         </template>
     </div>
 </template>
 
 <script setup>
+import { computed, provide, ref, watch, watchEffect } from 'vue'
 import icon from '../icon'
 import UISizeAnimation from '../size-animation'
-import { watchEffect, watch, ref, computed, provide } from 'vue'
 import { Relation } from './constant'
 
 const animationRef = ref(null)

+ 7 - 7
packages/components/basic/guide/index.vue

@@ -1,12 +1,12 @@
 <template>
-    <div class="guide" v-if="mount && (msg || $slots.default)" ref="guideRef" :class="{ 'floating-mode': floatClass }">
-        <slot name="content" :show="shouldShow"></slot>
+    <div v-if="mount && (msg || $slots.default)" ref="guideRef" class="guide" :class="{ 'floating-mode': floatClass }">
+        <slot name="content" :show="shouldShow" />
         <UIFloating v-if="floatClass" :mount="mountEl" :refer="guideRef" dire="bottom" :class="`guide-floating ${props.floatClass}  ${type}`">
             <Bubble :show="shouldShow" class="guide-bubble" :type="type">
                 <template v-if="msg">
                     <p class="default-msg">{{ msg }}</p>
                 </template>
-                <slot v-else></slot>
+                <slot v-else />
 
                 <span class="guide-close" @click="shouldShow = false">
                     <ui-icon type="close" ctrl />
@@ -14,24 +14,24 @@
             </Bubble>
         </UIFloating>
 
-        <Bubble :show="shouldShow" class="guide-bubble" :type="type" v-else>
+        <Bubble v-else :show="shouldShow" class="guide-bubble" :type="type">
             <template v-if="msg">
                 <p class="default-msg">{{ msg }}</p>
             </template>
-            <slot v-else></slot>
+            <slot v-else />
 
             <span class="guide-close" @click="shouldShow = false">
                 <ui-icon type="close" ctrl />
             </span>
         </Bubble>
     </div>
-    <slot name="content" v-else :show="false"></slot>
+    <slot v-else name="content" :show="false" />
 </template>
 
 <script setup>
+import { ref, watch } from 'vue'
 import Bubble from '../bubble'
 import UIFloating from '../floating/index.vue'
-import { ref, watch } from 'vue'
 
 const props = defineProps({
     mark: {

+ 1 - 1
packages/components/basic/icon/src/icon.ts

@@ -1,5 +1,5 @@
-import type { ExtractPropTypes } from 'vue'
 import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
 import type Icon from './icon.vue'
 
 export const iconProps = buildProps({

+ 5 - 5
packages/components/basic/icon/src/icon.vue

@@ -1,13 +1,13 @@
 <template>
     <i class="iconfont ui-kankan-icon icon" :class="className" :style="style" @click="ev => emit('click', ev)">
-        <slot></slot>
+        <slot />
 
-        <p class="tip" v-if="tip && os.isPc && !os.isTablet">{{ tip }}</p>
+        <p v-if="tip && os.isPc && !os.isTablet" class="tip">{{ tip }}</p>
     </i>
 </template>
 
 <script lang="ts" setup>
-import { defineProps, computed, defineEmits } from 'vue'
+import { computed, defineEmits, defineProps } from 'vue'
 import { normalizeUnitToStyle, os } from '@kankan/utils'
 import { iconProps } from './icon'
 
@@ -27,8 +27,8 @@ const className = computed(() => {
         medium: props.medium,
         big: props.big,
         disabled: props.disabled,
-        [`tip-h-` + props.tipH]: true,
-        [`tip-v-` + props.tipV]: true,
+        [`tip-h-${props.tipH}`]: true,
+        [`tip-v-${props.tipV}`]: true,
         ['fun-ctrl']: props.ctrl,
     }
     if (props.type) {

+ 4 - 4
packages/components/basic/input/src/checkRadio/checkRadio.vue

@@ -1,20 +1,20 @@
 <template>
     <div class="input radio" :style="{ width, height }">
-        <input :disabled="disabled" :id="id" type="checkbox" :checked="props.modelValue" @input="ev => emit('update:modelValue', (ev.target as HTMLInputElement).checked)" />
+        <input :id="id" :disabled="disabled" type="checkbox" :checked="props.modelValue" @input="ev => emit('update:modelValue', (ev.target as HTMLInputElement).checked)" />
         <span class="replace">
             <icon type="checkbox" :size="width > height ? height : width" />
         </span>
     </div>
-    <label class="label" v-if="props.label" :for="id">
+    <label v-if="props.label" class="label" :for="id">
         {{ props.label }}
     </label>
 </template>
 
 <script setup lang="ts">
+import { defineEmits, defineProps } from 'vue'
 import icon from '@kankan/components/basic/icon'
-import { checkRadioProps } from './checkRadio'
 import { randomId } from '@kankan/utils'
-import { defineProps, defineEmits } from 'vue'
+import { checkRadioProps } from './checkRadio'
 const props = defineProps(checkRadioProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)

+ 4 - 4
packages/components/basic/input/src/checkbox/checkbox.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="input checkbox" :style="{ width, height }" :class="{ disabled }">
         <input
-            :disabled="disabled"
             :id="id"
+            :disabled="disabled"
             type="checkbox"
             class="replace-input"
             :checked="props.modelValue"
@@ -12,16 +12,16 @@
             <UIIcon :type="props.modelValue ? 'checkbox' : 'nor'" :size="props.width > props.height ? props.height : props.width" />
         </span>
     </div>
-    <label class="label" v-if="props.label" :for="id">
+    <label v-if="props.label" class="label" :for="id">
         {{ props.label }}
     </label>
 </template>
 
 <script lang="ts" setup>
+import { defineEmits, defineProps } from 'vue'
+import { randomId } from '@kankan/utils'
 import UIIcon from '../../../icon/src/icon.vue'
 import { checkboxInputProps } from './checkbox'
-import { randomId } from '@kankan/utils'
-import { defineProps, defineEmits } from 'vue'
 const props = defineProps(checkboxInputProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)

+ 17 - 17
packages/components/basic/input/src/file/file.vue

@@ -1,12 +1,12 @@
 <template>
     <div class="input file" :class="{ suffix: $slots.icon, disabled: disabled, valuable }">
         <template v-if="valuable">
-            <slot name="valuable" :key="modelValue"></slot>
+            <slot :key="modelValue" name="valuable" />
         </template>
-        <input title="" class="ui-text" type="file" ref="inputRef" :accept="accept" :multiple="multiple" @change="selectFileHandler" v-if="!maxLen || maxLen > modelValue.length" />
+        <input v-if="!maxLen || maxLen > modelValue.length" ref="inputRef" title="" class="ui-text" type="file" :accept="accept" :multiple="multiple" @change="selectFileHandler" />
         <template v-if="!$slots.replace">
             <span class="replace">
-                <div class="placeholder" v-if="!valuable">
+                <div v-if="!valuable" class="placeholder">
                     <p><ui-icon type="add" /></p>
                     <p>{{ placeholder }}</p>
                     <p class="bottom">
@@ -25,23 +25,23 @@
                 <span v-else-if="!maxLen || maxLen > modelValue.length">
                     {{ multiple ? '继续添加' : '替换' }}
                 </span>
-                <span class="tj" v-if="maxLen && modelValue.length">
+                <span v-if="maxLen && modelValue.length" class="tj">
                     <span>{{ modelValue.length || 0 }}</span> / {{ maxLen }}
                 </span>
             </span>
         </template>
-        <div class="use-replace" v-else>
-            <slot name="replace"></slot>
+        <div v-else class="use-replace">
+            <slot name="replace" />
         </div>
     </div>
 </template>
 
 <script setup lang="ts">
-import { fileProps } from './file'
+import { computed, defineEmits, defineExpose, defineProps, ref } from 'vue'
 import { toRawType } from '@kankan/utils'
-// import Message from '../message';
 import Dialog from '@kankan/components/basic/dialog'
-import { defineProps, defineEmits, defineExpose, ref, computed } from 'vue'
+import { fileProps } from './file'
+// import Message from '../message';
 // import { useI18n } from '@/i18n'
 // const { t } = useI18n({ useScope: 'global' })
 const props = defineProps(fileProps)
@@ -58,7 +58,7 @@ const normalizeScale = computed(() => {
 })
 
 const valuable = computed(() => (Array.isArray(props.modelValue) ? props.modelValue.length : !!props.modelValue))
-const sizeStr = computed(() => props.maxSize && props.maxSize / 1024 / 1024 + 'MB')
+const sizeStr = computed(() => props.maxSize && `${props.maxSize / 1024 / 1024}MB`)
 
 const supports = {
     image: {
@@ -99,7 +99,7 @@ const producePreviews = files =>
         )
     )
 
-const calcScale = (w, h) => parseInt((w / h) * 1000)
+const calcScale = (w, h) => Number.parseInt((w / h) * 1000)
 
 const selectFileHandler = async ev => {
     const fileEl = ev.target
@@ -119,10 +119,10 @@ const selectFileHandler = async ev => {
             const accepts = props.accept.split(',').map(atom => {
                 return atom.trim()
             })
-            const hname = file.name.substr(file.name.lastIndexOf('.')).toLowerCase()
+            const hname = file.name.slice(file.name.lastIndexOf('.')).toLowerCase()
             if (!accepts.includes(hname)) {
                 // return previewError('格式错误', `仅支持${props.accept}格式文件`)
-                let accept = props.accept.split('.').join('').replace(',', '/').toLowerCase()
+                const accept = props.accept.split('.').join('').replace(',', '/').toLowerCase()
                 return previewError('格式错误', `${t('limit.formFile', { form: accept })}`)
             }
         }
@@ -139,10 +139,10 @@ const selectFileHandler = async ev => {
 
     if (normalizeScale.value) {
         const sizesConfirm = []
-        for (let i = 0; i < files.length; i++) {
-            const support = Object.values(supports).find(support => support.types.includes(files[i].type))
+        for (const [i, file] of files.entries()) {
+            const support = Object.values(supports).find(support => support.types.includes(file.type))
             if (support) {
-                sizesConfirm.push(support.preview(files[i], previews[i]))
+                sizesConfirm.push(support.preview(file, previews[i]))
             }
         }
 
@@ -169,7 +169,7 @@ const selectFileHandler = async ev => {
                 // return previewError('error size', `${file.name}的大小超过${sizeStr.value}`)
                 // return previewError('error size', `${file.name}的大小超过${sizeStr.value}`)
 
-                let accept = props.accept.split('.').join('').replace(',', '/').toLowerCase()
+                const accept = props.accept.split('.').join('').replace(',', '/').toLowerCase()
                 return previewError('格式错误', `${t('limit.formSize', { size: sizeStr.value, form: accept })}`)
             }
         }

+ 13 - 13
packages/components/basic/input/src/index copy.vue

@@ -1,13 +1,13 @@
 <template>
-    <div class="ui-input" v-if="types[type]" :style="style" :class="{ require: props.require, error: props.error }">
-        <component :is="types[type].component" v-bind="childProps" :modelValue="props.modelValue" @update:model-value="newValue => emit('update:modelValue', newValue)">
+    <div v-if="types[type]" class="ui-input" :style="style" :class="{ require: props.require, error: props.error }">
+        <component :is="types[type].component" v-bind="childProps" :model-value="props.modelValue" @update:model-value="newValue => emit('update:modelValue', newValue)">
             <template v-for="(slot, name) in $slots" #[name]="raw">
-                <slot :name="name" v-bind="raw"></slot>
+                <slot :name="name" v-bind="raw" />
             </template>
         </component>
-        <slot></slot>
+        <slot />
 
-        <p class="error-msg" v-if="error">{{ error }}</p>
+        <p v-if="error" class="error-msg">{{ error }}</p>
     </div>
 </template>
 
@@ -25,18 +25,18 @@ import file from './file.vue'
 import search from './search.vue'
 import richtext from './richtext.vue'
 import {
-    inputPropsDesc,
-    textPropsDesc,
-    selectPropsDesc,
     checkboxPropsDesc,
+    filePropsDesc,
+    inputPropsDesc,
+    numberPropsDesc,
     radioPropsDesc,
     rangePropsDesc,
-    numberPropsDesc,
+    richtextPropsDesc,
+    searchPropsDesc,
+    selectPropsDesc,
     switchPropsDesc,
+    textPropsDesc,
     textareaPropsDesc,
-    filePropsDesc,
-    searchPropsDesc,
-    richtextPropsDesc,
 } from './state.js.bk'
 
 const types = {
@@ -93,7 +93,7 @@ const type = computed(() => (types[props.type] ? props.type : 'text'))
 const childProps = computed(() => {
     const retain = Object.keys(types[type.value].propsDesc)
     const childProps = {}
-    for (let key in props) {
+    for (const key in props) {
         if (retain.includes(key)) {
             childProps[key] = props[key]
         }

+ 3 - 3
packages/components/basic/input/src/input.ts

@@ -1,7 +1,4 @@
 import { buildProps, definePropType } from '@kankan/utils'
-import type { ExtractPropTypes, VNode } from 'vue'
-
-export type InputType = 'checkbox' | 'text' | 'select' | 'radio' | 'range' | 'number' | 'switch' | 'textarea' | 'search' | 'richtext' | 'file'
 
 import { checkboxInputProps } from './checkbox/checkbox'
 import { checkRadioProps } from './checkRadio/checkRadio'
@@ -27,6 +24,9 @@ import number from './number/number.vue'
 import file from './file/file.vue'
 import search from './search/search.vue'
 import richtext from './richtext/richtext.vue'
+import type { ExtractPropTypes, VNode } from 'vue'
+
+export type InputType = 'checkbox' | 'text' | 'select' | 'radio' | 'range' | 'number' | 'switch' | 'textarea' | 'search' | 'richtext' | 'file'
 // import type { PropType } from 'vue'
 
 export const inputProps = buildProps({

+ 4 - 4
packages/components/basic/input/src/input.vue

@@ -1,12 +1,12 @@
 <template>
     <div class="ui-input">
         <template v-if="type">
-            <component :is="InputComponents[type].component" v-bind="$attrs" :modelValue="props.modelValue" @update:model-value="handleUpdate">
+            <component :is="InputComponents[type].component" v-bind="$attrs" :model-value="props.modelValue" @update:model-value="handleUpdate">
                 <template v-for="(slot, name) in $slots" #[name]="raw">
-                    <slot :name="name" v-bind="raw"></slot>
+                    <slot :name="name" v-bind="raw" />
                 </template>
             </component>
-            <slot></slot>
+            <slot />
 
             <!-- <p class="error-msg" v-if="error">{{ error }}</p> -->
         </template>
@@ -14,7 +14,7 @@
 </template>
 
 <script setup lang="ts">
-import { inputProps, InputComponents } from './input'
+import { InputComponents, inputProps } from './input'
 const props = defineProps(inputProps)
 
 const emit = defineEmits(['update:modelValue'])

+ 13 - 13
packages/components/basic/input/src/number/number.vue

@@ -4,17 +4,17 @@
         :class="{ ctrl }"
         type="number"
         :right="right"
-        :modelValue="tempValue"
+        :model-value="tempValue"
         :placeholder="placeholder"
-        @update:model-value="updateTempValue"
         :other="{ min, max, step }"
-        @blur="blurHandler"
         :readonly="!inInput"
+        @update:model-value="updateTempValue"
+        @blur="blurHandler"
     >
         <template v-for="(slot, name) in $slots" #[name]="raw">
-            <slot :name="name" v-bind="raw"></slot>
+            <slot :name="name" v-bind="raw" />
         </template>
-        <template #icon v-if="ctrl">
+        <template v-if="ctrl" #icon>
             <div class="ctrls">
                 <UIIcon type="up-a" ctrl class="up" @click="updateModelValue(normValue(modelValue) + step)" />
                 <UIIcon type="d-r" ctrl class="down" @click="updateModelValue(normValue(modelValue) - step)" />
@@ -24,16 +24,16 @@
 </template>
 
 <script setup lang="ts">
-import UIText from '../text/text.vue'
-import { numberProps } from './number'
-import { defineProps, defineEmits, watchEffect, ref } from 'vue'
+import { defineEmits, defineProps, ref, watchEffect } from 'vue'
 import { toRawType } from '@kankan/utils'
 import UIIcon from '@kankan/components/basic/icon'
+import UIText from '../text/text.vue'
+import { numberProps } from './number'
 
 const emit = defineEmits(['update:modelValue'])
 const props = defineProps(numberProps)
 
-const isNumber = raw => !(toRawType(raw) === 'Number' ? isNaN(raw) : isNaN(Number(raw)))
+const isNumber = raw => !(toRawType(raw) === 'Number' ? Number.isNaN(raw) : Number.isNaN(Number(raw)))
 const tempValue = ref(props.modelValue)
 
 watchEffect(() => {
@@ -42,7 +42,7 @@ watchEffect(() => {
 const updateTempValue = val => {
     tempValue.value = val
     const tval = Number(val)
-    if (!isNaN(tval) && tval !== props.modelValue) {
+    if (!Number.isNaN(tval) && tval !== props.modelValue) {
         updateModelValue(tval)
     }
 }
@@ -54,7 +54,7 @@ const blurHandler = () => {
 
 const normValue = val => {
     val = Number(val)
-    if (isNaN(val)) {
+    if (Number.isNaN(val)) {
         return props.min || 0
     } else {
         return val
@@ -64,11 +64,11 @@ const normValue = val => {
 const updateModelValue = val => {
     val = normValue(val)
     if (isNumber(props.min)) {
-        let min = Number(props.min)
+        const min = Number(props.min)
         val = val < min ? min : val
     }
     if (isNumber(props.max)) {
-        let max = Number(props.max)
+        const max = Number(props.max)
         val = val > max ? max : val
     }
     emit('update:modelValue', val)

+ 1 - 1
packages/components/basic/input/src/password.vue

@@ -1,3 +1,3 @@
 <template>
-    <div></div>
+    <div />
 </template>

+ 6 - 6
packages/components/basic/input/src/radio/radio.vue

@@ -1,19 +1,19 @@
 <template>
     <div class="input radio" :style="{ width, height }">
-        <input :name="name" :disabled="disabled" :id="id" type="radio" class="replace-input" :checked="props.modelValue" @change="ev => emit('update:modelValue', ev.target.checked)" />
-        <span class="replace"></span>
+        <input :id="id" :name="name" :disabled="disabled" type="radio" class="replace-input" :checked="props.modelValue" @change="ev => emit('update:modelValue', ev.target.checked)" />
+        <span class="replace" />
     </div>
-    <label class="label" v-if="props.label || props.icon" :for="id">
-        <UIIcon :type="props.icon" :tip="props.tip" v-if="props.icon" />
+    <label v-if="props.label || props.icon" class="label" :for="id">
+        <UIIcon v-if="props.icon" :type="props.icon" :tip="props.tip" />
         {{ props.label }}
     </label>
 </template>
 
 <script setup lang="ts">
+import { defineEmits, defineProps } from 'vue'
 import UIIcon from '@kankan/components/basic/icon'
-import { radioProps } from './radio'
 import { randomId } from '@kankan/utils'
-import { defineProps, defineEmits } from 'vue'
+import { radioProps } from './radio'
 const props = defineProps(radioProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)

+ 7 - 7
packages/components/basic/input/src/range/range.vue

@@ -1,24 +1,24 @@
 <template>
     <div class="input range">
-        <div class="range-content" :class="{ animation: mode === modeEmun.default }" :style="{ '--percentage': percenStyle }" @click="rangeClickHandler" ref="rangeRef">
-            <div class="range-locus" ref="locusRef">
+        <div ref="rangeRef" class="range-content" :class="{ animation: mode === modeEmun.default }" :style="{ '--percentage': percenStyle }" @click="rangeClickHandler">
+            <div ref="locusRef" class="range-locus">
                 <span class="range-slide" @click.stop @mousedown="slideDownHandler">
                     <span v-if="rangeTips" class="tips">{{ modelValue }}%</span>
                 </span>
             </div>
         </div>
         <div v-if="rangeInput">
-            <UItext v-if="inch" :modelValue="inch" class="range-text" style="pointer-events: none" />
-            <UInumber v-else :modelValue="modelValue" @update:model-value="inputUpdateHandler" :min="min" :max="max" :step="step" :ctrl="false" right class="range-text" />
+            <UItext v-if="inch" :model-value="inch" class="range-text" style="pointer-events: none" />
+            <UInumber v-else :model-value="modelValue" :min="min" :max="max" :step="step" :ctrl="false" right class="range-text" @update:model-value="inputUpdateHandler" />
         </div>
     </div>
 </template>
 
 <script setup lang="ts">
-import { ref, computed, onMounted, defineProps, nextTick } from 'vue'
-import { rangProps } from './range'
+import { computed, defineProps, nextTick, onMounted, ref } from 'vue'
 import UInumber from '../number/number.vue'
 import UItext from '../text/text.vue'
+import { rangProps } from './range'
 
 const props = defineProps(rangProps)
 const emit = defineEmits(['update:modelValue'])
@@ -82,7 +82,7 @@ const rangeClickHandler = ev => {
     percen.value = ev.offsetX / rangeWidth.value
     console.log(ev.offsetX, rangeWidth.value)
     //首次点击,获取limit的值
-    let t = setTimeout(() => {
+    const t = setTimeout(() => {
         const len = Number(props.max) - Number(props.min)
         if (props.limit > 0 && Number(props.min) + len * percen.value > props.limit) {
             percen.value = (props.limit - Number(props.min)) / len

+ 21 - 21
packages/components/basic/input/src/richtext/richtext.vue

@@ -1,23 +1,23 @@
 <template>
-    <div class="input textarea" :class="{ suffix: $slots.icon || maxlength, disabled, right }" ref="textRef">
+    <div ref="textRef" class="input textarea" :class="{ suffix: $slots.icon || maxlength, disabled, right }">
         <div
+            ref="inputRef"
             contenteditable="true"
             class="ui-text input-div"
-            @input="inputHandler"
             :placeholder="props.placeholder"
             :readonly="readonly"
+            v-bind="other"
+            @input="inputHandler"
             @click="emit('click')"
             @focus="focusHandler"
             @blur="blurHandler"
             @paste="pasteHandler"
             @compositionstart="compositionstartHandler"
             @compositionend="compositionendHandler"
-            ref="inputRef"
-            v-bind="other"
-        ></div>
-        <span class="replace"></span>
+        />
+        <span class="replace" />
         <span v-if="$slots.icon || props.maxlength" class="retouch">
-            <slot name="icon"></slot>
+            <slot name="icon" />
             <span v-if="props.maxlength" class="len">
                 <span>{{ length }}</span> / {{ maxlength }}
             </span>
@@ -26,8 +26,8 @@
 </template>
 
 <script setup lang="ts">
+import { defineEmits, defineExpose, defineProps, nextTick, ref, watchEffect } from 'vue'
 import { richTextProps } from './richtext'
-import { defineProps, defineEmits, defineExpose, nextTick, ref, watchEffect } from 'vue'
 const props = defineProps(richTextProps)
 
 const emit = defineEmits(['update:modelValue', 'focus', 'blur', 'click', ''])
@@ -71,25 +71,25 @@ const inputHandler = (ev: any) => {
 }
 //获取当前光标位置
 const getCursortPosition = function (element = inputRef.value) {
-    var caretOffset = 0
-    var doc = element.ownerDocument || element.document
-    var win = doc.defaultView || doc.parentWindow
-    var sel
+    let caretOffset = 0
+    const doc = element.ownerDocument || element.document
+    const win = doc.defaultView || doc.parentWindow
+    let sel
     if (typeof win.getSelection != 'undefined') {
         //谷歌、火狐
         sel = win.getSelection()
         if (sel.rangeCount > 0) {
             //选中的区域
-            var range = win.getSelection().getRangeAt(0)
-            var preCaretRange = range.cloneRange() //克隆一个选中区域
+            const range = win.getSelection().getRangeAt(0)
+            const preCaretRange = range.cloneRange() //克隆一个选中区域
             preCaretRange.selectNodeContents(element) //设置选中区域的节点内容为当前节点
             preCaretRange.setEnd(range.endContainer, range.endOffset) //重置选中区域的结束位置
             caretOffset = preCaretRange.toString().length
         }
     } else if ((sel = doc.selection) && sel.type != 'Control') {
         //IE
-        var textRange = sel.createRange()
-        var preCaretTextRange = doc.body.createTextRange()
+        const textRange = sel.createRange()
+        const preCaretTextRange = doc.body.createTextRange()
         preCaretTextRange.moveToElementText(element)
         preCaretTextRange.setEndPoint('EndToEnd', textRange)
         caretOffset = preCaretTextRange.text.length
@@ -126,7 +126,7 @@ const getPasteText = text => {
     const $el = document.createElement('div')
     $el.innerHTML = text
     if ($el.textContent.length > props.maxlength - length.value) {
-        return $el.textContent.substring(0, props.maxlength - length.value)
+        return $el.textContent.slice(0, Math.max(0, props.maxlength - length.value))
     } else {
         return text
     }
@@ -134,15 +134,15 @@ const getPasteText = text => {
 
 const pasteHandler = event => {
     event.preventDefault()
-    var text
-    var clp = (event.originalEvent || event).clipboardData
+    let text
+    const clp = (event.originalEvent || event).clipboardData
     // 兼容针对于opera ie等浏览器
     if (clp === undefined || clp === null) {
         text = window.clipboardData.getData('text') || ''
         if (text !== '') {
             if (window.getSelection) {
                 // 针对于ie11 10 9 safari
-                var newNode = document.createElement('span')
+                const newNode = document.createElement('span')
                 newNode.innerHTML = getPasteText(text)
                 window.getSelection().getRangeAt(0).insertNode(newNode)
             } else {
@@ -161,6 +161,6 @@ const pasteHandler = event => {
 defineExpose({
     root: textRef,
     input: inputRef,
-    getCursortPosition: getCursortPosition,
+    getCursortPosition,
 })
 </script>

+ 5 - 5
packages/components/basic/input/src/search/search.vue

@@ -1,10 +1,10 @@
 <template>
-    <UISelect ref="selectVM" className="search" v-bind="props" :readonly="false" @update:model-value="update" :labelValue="labelValue" :options="options">
+    <UISelect ref="selectVM" class-name="search" v-bind="props" :readonly="false" :label-value="labelValue" :options="options" @update:model-value="update">
         <template v-for="(slot, name) in $slots" #[name]="raw">
-            <slot :name="name" v-bind="raw"></slot>
+            <slot :name="name" v-bind="raw" />
         </template>
         <template #icon>
-            <ui-icon type="close" class="clear" small @click="clearHandler" v-if="labelValue" />
+            <ui-icon v-if="labelValue" type="close" class="clear" small @click="clearHandler" />
         </template>
         <template #preIcon>
             <ui-icon type="search" color="rgba(255,255,255,.3)" small />
@@ -13,9 +13,9 @@
 </template>
 
 <script setup lang="ts">
-import { ref, watchEffect, defineEmits, onUnmounted } from 'vue'
-import { searchProps } from './search'
+import { defineEmits, onUnmounted, ref, watchEffect } from 'vue'
 import UISelect from '../select/select.vue'
+import { searchProps } from './search'
 
 const props = defineProps(searchProps)
 const labelValue = ref('')

+ 11 - 11
packages/components/basic/input/src/select/select.vue

@@ -1,28 +1,28 @@
 <template>
     <UItext
+        ref="vmRef"
         :disabled="props.disabled"
         class="select ready"
         :class="{
             focus: showOption,
             [className]: className,
         }"
-        ref="vmRef"
-        :modelValue="typeof labelValue === 'string' ? labelValue : inputValue"
-        @update:model-value="val => emit('update:modelValue', val)"
+        :model-value="typeof labelValue === 'string' ? labelValue : inputValue"
         :width="props.width"
         :height="props.height"
         :readonly="readonly"
         :placeholder="props.placeholder"
+        @update:model-value="val => emit('update:modelValue', val)"
         @blur="blurHandler"
         @focus="showHandler"
         @click="clickShowHandler"
     >
         <template #icon>
-            <icon type="pull-down" small v-if="!$slots.icon" />
-            <slot name="icon" v-else></slot>
+            <icon v-if="!$slots.icon" type="pull-down" small />
+            <slot v-else name="icon" />
         </template>
-        <template #preIcon v-if="$slots.preIcon">
-            <slot name="preIcon"></slot>
+        <template v-if="$slots.preIcon" #preIcon>
+            <slot name="preIcon" />
         </template>
     </UItext>
 
@@ -38,13 +38,13 @@
         class="select-float"
         :dire="dire === 'top' ? 'left-top' : 'left-bottom'"
     >
-        <slot name="floating-pre"></slot>
+        <slot name="floating-pre" />
         <div class="select-replace" :class="{ 'hide-scroll': props.hideScroll }">
             <ul>
                 <template v-for="option in props.options" :key="option.value">
                     <li v-if="props.options?.length" :key="option.value" :class="{ active: props.modelValue === option.value }" @mousedown="ev => optionClickHandler(ev, option)">
                         <template v-if="$slots.option">
-                            <slot name="option" :raw="option" :active="props.modelValue === option.value"></slot>
+                            <slot name="option" :raw="option" :active="props.modelValue === option.value" />
                         </template>
                         <template v-else>{{ option.label }}</template>
                     </li>
@@ -56,10 +56,10 @@
 </template>
 
 <script setup lang="ts">
+import { computed, defineExpose, ref } from 'vue'
 import icon from '@kankan/components/basic/icon'
-import UItext from '../text/text.vue'
 import UIFloating from '@kankan/components/basic/floating'
-import { ref, computed, defineExpose } from 'vue'
+import UItext from '../text/text.vue'
 import { selectProps } from './select'
 
 const props = defineProps(selectProps)

+ 4 - 4
packages/components/basic/input/src/switch/switch.vue

@@ -1,14 +1,14 @@
 <template>
     <div class="input switch" :style="{ width, height }" :class="{ disabled }">
-        <input class="replace-input" :disabled="disabled" :id="id" type="checkbox" :checked="props.modelValue" @input="handleInput" />
-        <span class="replace"></span>
+        <input :id="id" class="replace-input" :disabled="disabled" type="checkbox" :checked="props.modelValue" @input="handleInput" />
+        <span class="replace" />
     </div>
 </template>
 
 <script setup lang="ts">
-import { switchProps } from './switch'
+import { defineEmits, defineProps } from 'vue'
 import { randomId } from '@kankan/utils'
-import { defineProps, defineEmits } from 'vue'
+import { switchProps } from './switch'
 const props = defineProps(switchProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)

+ 8 - 8
packages/components/basic/input/src/text/text.vue

@@ -1,5 +1,5 @@
 <template>
-    <div @click="emit('click')" class="input text" :class="{ suffix: $slots.icon || maxlength, disabled, right, 'pre-suffix': $slots.preIcon }" ref="textRef">
+    <div ref="textRef" class="input text" :class="{ suffix: $slots.icon || maxlength, disabled, right, 'pre-suffix': $slots.preIcon }" @click="emit('click')">
         <template v-if="type === 'password'">
             <div class="is-hidden">
                 <input type="text" class="is-hidden" />
@@ -8,36 +8,36 @@
         </template>
 
         <span v-if="$slots.preIcon" class="pre-icon">
-            <slot name="preIcon"></slot>
+            <slot name="preIcon" />
         </span>
         <input
+            ref="inputRef"
             class="ui-text"
             :class="{ icon: $slots.icon }"
             :type="type"
             :value="modelValue"
             autocomplete="off"
-            @input="inputHandler"
             :placeholder="placeholder"
             :readonly="readonly"
             :maxlength="maxlength"
+            v-bind="other"
+            @input="inputHandler"
             @focus="emit('focus')"
             @blur="emit('blur')"
-            ref="inputRef"
-            v-bind="other"
         />
         <span v-if="$slots.icon || props.maxlength" class="retouch">
-            <slot name="icon"></slot>
+            <slot name="icon" />
             <span v-if="props.maxlength" class="len">
                 <span>{{ modelValue?.length }}</span> / {{ maxlength }}
             </span>
         </span>
-        <slot></slot>
+        <slot />
     </div>
 </template>
 
 <script setup lang="ts">
+import { defineEmits, defineExpose, defineProps, ref } from 'vue'
 import { textInputProps } from './text'
-import { defineProps, defineEmits, defineExpose, ref } from 'vue'
 const props = defineProps(textInputProps)
 const emit = defineEmits(['update:modelValue', 'focus', 'blur', 'click'])
 // const test = () => {

+ 8 - 8
packages/components/basic/input/src/textarea/textarea.vue

@@ -1,22 +1,22 @@
 <template>
-    <div class="input textarea" :class="{ suffix: $slots.icon || maxlength, disabled, right }" ref="textRef">
+    <div ref="textRef" class="input textarea" :class="{ suffix: $slots.icon || maxlength, disabled, right }">
         {{ modelValue }}
         <textarea
+            ref="inputRef"
             class="ui-text"
             :value="modelValue"
-            @input="inputHandler"
             :placeholder="props.placeholder"
             :readonly="readonly"
             :maxlength="props.maxlength"
+            v-bind="other"
+            @input="inputHandler"
             @click="emit('click')"
             @focus="emit('focus')"
             @blur="emit('blur')"
-            ref="inputRef"
-            v-bind="other"
-        ></textarea>
-        <span class="replace"></span>
+        />
+        <span class="replace" />
         <span v-if="$slots.icon || props.maxlength" class="retouch">
-            <slot name="icon"></slot>
+            <slot name="icon" />
             <span v-if="props.maxlength" class="len">
                 <span>{{ modelValue.length }}</span> / {{ maxlength }}
             </span>
@@ -25,8 +25,8 @@
 </template>
 
 <script setup lang="ts">
+import { defineEmits, defineExpose, defineProps, nextTick, ref } from 'vue'
 import { textareaProps } from './textarea'
-import { defineProps, defineEmits, defineExpose, nextTick, ref } from 'vue'
 const props = defineProps(textareaProps)
 
 console.log(props)

+ 1 - 1
packages/components/basic/menu-item/src/menu-item.ts

@@ -1,5 +1,5 @@
-import type { ExtractPropTypes } from 'vue'
 import { buildProps } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
 import type MenuItem from './menu-item.vue'
 
 export const menuItemProps = buildProps({

+ 3 - 3
packages/components/basic/menu-item/src/menu-item.vue

@@ -1,14 +1,14 @@
 <template>
-    <div class="ui-menu-item" :class="{ active }" ref="self" @mouseenter="emit('enter')" @mouseleave="emit('leave')" @click="emit('click')">
+    <div ref="self" class="ui-menu-item" :class="{ active }" @mouseenter="emit('enter')" @mouseleave="emit('leave')" @click="emit('click')">
         <UIIcon :type="icon" size="18px" />
         <span>{{ text }}</span>
-        <slot></slot>
+        <slot />
     </div>
 </template>
 
 <script lang="ts" setup>
+import { defineEmits, defineExpose, defineProps, ref } from 'vue'
 import UIIcon from '@kankan/components/basic/icon'
-import { defineProps, defineExpose, defineEmits, ref } from 'vue'
 import { menuItemProps } from './menu-item'
 
 defineOptions({

+ 2 - 2
packages/components/basic/message/index.ts

@@ -1,7 +1,7 @@
-import Message from './message.vue'
+import { computed, ref } from 'vue'
 import { mount } from '../../utils/componentHelper'
 import { toRawType } from '../../utils/index'
-import { computed, ref } from 'vue'
+import Message from './message.vue'
 
 const types = ['success', 'warning', 'error']
 

+ 3 - 3
packages/components/basic/message/message.vue

@@ -1,7 +1,7 @@
 <template>
     <teleport to="body">
         <transition name="fade">
-            <div class="ui-message" :style="{ zIndex: zIndex, marginTop: `${index.value * 60}px` }" :class="type" v-if="show">
+            <div v-if="show" class="ui-message" :style="{ zIndex: zIndex, marginTop: `${index.value * 60}px` }" :class="type">
                 <ui-icon :type="icons[type]" class="icon" />
                 <p>{{ msg }}</p>
             </div>
@@ -10,10 +10,10 @@
 </template>
 
 <script setup lang="ts">
-import uiIcon from '../icon'
 // import getZindex from '../../utils/zindex'
-import { defineProps, onMounted, ref, nextTick } from 'vue'
+import { defineProps, nextTick, onMounted, ref } from 'vue'
 import { useZIndex } from '@kankan/hooks'
+import uiIcon from '../icon'
 const { currentZIndex } = useZIndex()
 
 const props = defineProps({

+ 40 - 42
packages/components/basic/scrollbar/index.js

@@ -15,10 +15,10 @@ class XScrollbar {
         this.$dom.classList.add('x-scrollbar')
 
         // 移动端检测
-        this.isMobile = window.navigator.userAgent.toLowerCase().indexOf('mobile') != -1
+        this.isMobile = window.navigator.userAgent.toLowerCase().includes('mobile')
 
         // 合并配置
-        let defaultOptions = {
+        const defaultOptions = {
             // 响应容器和内容大小改变(自动更新滚动条)
             autoUpdate: true,
             // 阻止向上传递滚动事件
@@ -28,7 +28,7 @@ class XScrollbar {
             // 自动隐藏
             autoHide: true,
         }
-        let defaultStyle = {
+        const defaultStyle = {
             // 滑块大小
             thumbSize: '5px',
             // 轨道颜色
@@ -41,8 +41,8 @@ class XScrollbar {
         Object.assign(this, defaultOptions, defaultStyle, options)
 
         // 构造dom
-        let scrollLeft = this.$dom.scrollLeft
-        let scrollTop = this.$dom.scrollTop
+        const scrollLeft = this.$dom.scrollLeft
+        const scrollTop = this.$dom.scrollTop
         this.$container = this.html2dom('<div class="x-scrollbar__container"></div>')
         this.$content = this.html2dom('<div class="x-scrollbar__content"></div>')
         this.$trackX = this.html2dom('<div class="x-scrollbar__track-x"></div>')
@@ -51,21 +51,19 @@ class XScrollbar {
         this.$thumbY = this.html2dom('<div class="x-scrollbar__thumb-y"></div>')
         this.$trackX.appendChild(this.$thumbX)
         this.$trackY.appendChild(this.$thumbY)
-        let childNodes = []
-        Array.prototype.forEach.call(this.$dom.childNodes, function (node) {
+        const childNodes = []
+        Array.prototype.forEach.call(this.$dom.childNodes, node => {
             childNodes.push(node)
         })
-        childNodes.forEach(
-            function (node) {
-                this.$content.appendChild(node)
-            }.bind(this)
-        )
+        childNodes.forEach(node => {
+            this.$content.appendChild(node)
+        })
         this.$container.appendChild(this.$content)
         this.$dom.appendChild(this.$container)
 
         // 处理内边距
-        let styleObj = getComputedStyle(this.$dom)
-        let padding = `${styleObj.paddingTop} ${styleObj.paddingRight} ${styleObj.paddingBottom} ${styleObj.paddingLeft}`
+        const styleObj = getComputedStyle(this.$dom)
+        const padding = `${styleObj.paddingTop} ${styleObj.paddingRight} ${styleObj.paddingBottom} ${styleObj.paddingLeft}`
         if (padding != '0px 0px 0px 0px') {
             this.$dom.style.padding = '0px 0px 0px 0px'
             this.$container.style.padding = padding
@@ -137,8 +135,8 @@ class XScrollbar {
 
         this.$trackX.style.display = this.hasXScrollbar ? 'block' : 'none'
         this.$trackY.style.display = this.hasYScrollbar ? 'block' : 'none'
-        this.$thumbX.style.width = this.thumbXWidth + 'px'
-        this.$thumbY.style.height = this.thumbYHeight + 'px'
+        this.$thumbX.style.width = `${this.thumbXWidth}px`
+        this.$thumbY.style.height = `${this.thumbYHeight}px`
     }
 
     /**
@@ -174,16 +172,16 @@ class XScrollbar {
 
             requestAnimationFrame(() => {
                 if (this.thumbXActive) {
-                    let offset = e.screenX - screenX
+                    const offset = e.screenX - screenX
                     screenX = e.screenX
-                    let left = Math.max(Math.min(parseFloat(this.$thumbX.style.left || 0) + offset, this.thumbXMaxLeft), 0)
-                    this.$thumbX.style.left = left + 'px'
+                    const left = Math.max(Math.min(Number.parseFloat(this.$thumbX.style.left || 0) + offset, this.thumbXMaxLeft), 0)
+                    this.$thumbX.style.left = `${left}px`
                     this.$container.scrollLeft = (left / this.thumbXMaxLeft) * this.maxScrollLeft
                 } else {
-                    let offset = e.screenY - screenY
+                    const offset = e.screenY - screenY
                     screenY = e.screenY
-                    let top = Math.max(Math.min(parseFloat(this.$thumbY.style.top || 0) + offset, this.thumbYMaxTop), 0)
-                    this.$thumbY.style.top = top + 'px'
+                    const top = Math.max(Math.min(Number.parseFloat(this.$thumbY.style.top || 0) + offset, this.thumbYMaxTop), 0)
+                    this.$thumbY.style.top = `${top}px`
                     this.$container.scrollTop = (top / this.thumbYMaxTop) * this.maxScrollTop
                 }
             })
@@ -194,7 +192,7 @@ class XScrollbar {
      * 仅水平滚动(拨动鼠标滚轮时将作用于X轴)
      */
     bindWheel() {
-        let easeout = (start, end) => {
+        const easeout = (start, end) => {
             if (Math.abs(end - start) <= 1) return end
             return start + (end - start) / 4
         }
@@ -217,13 +215,13 @@ class XScrollbar {
 
                 // 起始值
                 let scrollLeft = this.$container.scrollLeft
-                let left = parseFloat(this.$thumbX.style.left || 0)
+                let left = Number.parseFloat(this.$thumbX.style.left || 0)
 
-                let animate = () => {
+                const animate = () => {
                     scrollLeft = easeout(scrollLeft, this.scrollLeft)
                     left = easeout(left, this.left)
                     this.$container.scrollLeft = scrollLeft
-                    this.$thumbX.style.left = left + 'px'
+                    this.$thumbX.style.left = `${left}px`
                     this.innerScroll = true
                     if (scrollLeft != this.scrollLeft) {
                         this.reqId = requestAnimationFrame(animate)
@@ -245,10 +243,10 @@ class XScrollbar {
         this.$container.addEventListener('scroll', () => {
             if (this.thumbXActive || this.thumbYActive || this.innerScroll) return
             if (this.hasXScrollbar) {
-                this.$thumbX.style.left = (this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft + 'px'
+                this.$thumbX.style.left = `${(this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft}px`
             }
             if (this.hasYScrollbar) {
-                this.$thumbY.style.top = (this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop + 'px'
+                this.$thumbY.style.top = `${(this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop}px`
             }
         })
     }
@@ -258,7 +256,7 @@ class XScrollbar {
      */
     resizeObserver() {
         this.$resizeObserver = new ResizeObserver(entries => {
-            let contentRect = entries[0].contentRect
+            const contentRect = entries[0].contentRect
             if (!(contentRect.width || contentRect.height)) return
             this.update()
         })
@@ -273,10 +271,10 @@ class XScrollbar {
     update() {
         this.setThumbSize()
         if (this.hasXScrollbar) {
-            this.$thumbX.style.left = (this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft + 'px'
+            this.$thumbX.style.left = `${(this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft}px`
         }
         if (this.hasYScrollbar) {
-            this.$thumbY.style.top = (this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop + 'px'
+            this.$thumbY.style.top = `${(this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop}px`
         }
     }
 
@@ -286,9 +284,9 @@ class XScrollbar {
      * @returns
      */
     html2dom(html) {
-        let element = document.createElement('div')
+        const element = document.createElement('div')
         element.innerHTML = html
-        let children = element.children
+        const children = element.children
         if (children.length <= 1) {
             return children[0]
         } else {
@@ -303,37 +301,37 @@ class XScrollbar {
         let content = `
   /* 轨道 */
   .x-scrollbar__track-x {
-    height: ${parseInt(this.thumbSize) * 2 + 4}px;
+    height: ${Number.parseInt(this.thumbSize) * 2 + 4}px;
   }
   
   .x-scrollbar__track-y {
-    width: ${parseInt(this.thumbSize) * 2 + 4}px;
+    width: ${Number.parseInt(this.thumbSize) * 2 + 4}px;
   }
   
   /* 滑块 */
   .x-scrollbar__track-x > .x-scrollbar__thumb-x,
   .x-scrollbar__track-y > .x-scrollbar__thumb-y {
     background: ${this.thumbBackground};
-    border-radius: ${parseInt(this.thumbRadius || 0) != 5 ? parseInt(this.thumbRadius || 0) : parseInt(this.thumbSize)}px;
+    border-radius: ${Number.parseInt(this.thumbRadius || 0) != 5 ? Number.parseInt(this.thumbRadius || 0) : Number.parseInt(this.thumbSize)}px;
   }
   
   .x-scrollbar__track-x > .x-scrollbar__thumb-x {
-    height: ${parseInt(this.thumbSize)}px;
+    height: ${Number.parseInt(this.thumbSize)}px;
   }
   
   .x-scrollbar__track-y > .x-scrollbar__thumb-y {
-    width: ${parseInt(this.thumbSize)}px;
+    width: ${Number.parseInt(this.thumbSize)}px;
   }
   
   /* 激活后大小 */
   .x-scrollbar__track-x:hover > .x-scrollbar__thumb-x,
   .x-scrollbar__track--draging > .x-scrollbar__thumb-x {
-    height: ${parseInt(this.thumbSize) * 2}px;
+    height: ${Number.parseInt(this.thumbSize) * 2}px;
   }
   
   .x-scrollbar__track-y:hover > .x-scrollbar__thumb-y,
   .x-scrollbar__track--draging > .x-scrollbar__thumb-y {
-    width: ${parseInt(this.thumbSize) * 2}px;
+    width: ${Number.parseInt(this.thumbSize) * 2}px;
   }
   
   /* 鼠标移入轨道 || 拖动过程中 => 显示轨道 & 高亮滑块 */
@@ -344,9 +342,9 @@ class XScrollbar {
     background: ${this.trackBackground || 'transparent'};
   }`
 
-        this.key = 'x-scrollbar-' + Math.abs(((1 + Math.random()) * Date.now()) | 0).toString(16)
+        this.key = `x-scrollbar-${Math.abs(Math.trunc((1 + Math.random()) * Date.now())).toString(16)}`
         this.$dom.setAttribute(this.key, '')
-        let style = this.html2dom(`<style ${this.key}></style>`)
+        const style = this.html2dom(`<style ${this.key}></style>`)
         content = content.replaceAll('\n.x-scrollbar', `\n[${this.key}] > .x-scrollbar`)
         content = content.replaceAll(';', ' !important;')
         style.innerHTML = content

+ 3 - 3
packages/components/basic/size-animation/index.vue

@@ -1,12 +1,12 @@
 <template>
-    <div class="ui-size-animation" :class="{ ready, show: max !== 0, [animationStyle]: animationStyle }" :style="origin && { 'max-height': max + 'px' }" ref="contentRef">
-        <slot></slot>
+    <div ref="contentRef" class="ui-size-animation" :class="{ ready, show: max !== 0, [animationStyle]: animationStyle }" :style="origin && { 'max-height': max + 'px' }">
+        <slot />
     </div>
 </template>
 
 <script lang="ts" setup>
+import { defineExpose, defineProps, ref, watchEffect } from 'vue'
 import { changeWHFactory } from '@kankan/utils'
-import { defineExpose, ref, watchEffect, defineProps } from 'vue'
 
 defineOptions({
     name: 'UISizeAnimation',

+ 5 - 5
packages/components/basic/slide/index.vue

@@ -2,21 +2,21 @@
     <div class="ui-slide">
         <Gate :index="index">
             <GateContent v-for="(item, i) in items" :key="i">
-                <slot :raw="item" :active="items[index]"></slot>
+                <slot :raw="item" :active="items[index]" />
             </GateContent>
         </Gate>
         <template v-if="showCtrl">
-            <span class="left" @click="prevHandler" v-if="index !== 0"><UIIcon type="left" /></span>
-            <span class="right" @click="nextHandler" v-if="index !== items.length - 1"><UIIcon type="pull-more" /></span>
+            <span v-if="index !== 0" class="left" @click="prevHandler"><UIIcon type="left" /></span>
+            <span v-if="index !== items.length - 1" class="right" @click="nextHandler"><UIIcon type="pull-more" /></span>
         </template>
-        <slot name="attach" :active="items[index]"></slot>
+        <slot name="attach" :active="items[index]" />
     </div>
 </template>
 
 <script lang="ts" setup>
-import { Gate, GateContent } from '../gate'
 import { defineProps, ref, watchEffect } from 'vue'
 import UIIcon from '@kankan/components/basic/icon'
+import { Gate, GateContent } from '../gate'
 
 defineOptions({
     name: 'UISlide',

+ 9 - 7
packages/components/basic/tree/TreeItem.vue

@@ -1,31 +1,33 @@
 <template>
     <li class="ui-tree-item">
         <div :class="{}" @click="toggle" @dblclick="makeFolder">
-            <i class="arrow iconfont icon-pull-down" :class="{ open: isOpen, visibility: isFolder }"></i>{{ item.name }}
+            <i class="arrow iconfont icon-pull-down" :class="{ open: isOpen, visibility: isFolder }" />{{ item.name }}
             <span v-if="isFolder">[{{ isOpen ? '-' : '+' }}]</span>
         </div>
         <ul v-show="isOpen" v-if="isFolder">
-            <ui-tree-item class="item" v-for="(child, index) in item.children" :key="index" :item="child" @make-folder="$emit('make-folder', $event)" @add-item="$emit('add-item', $event)" />
+            <ui-tree-item v-for="(child, index) in item.children" :key="index" class="item" :item="child" @make-folder="$emit('make-folder', $event)" @add-item="$emit('add-item', $event)" />
             <li class="add" @click="$emit('add-item', item)">+</li>
         </ul>
     </li>
 </template>
-<script>
-import { defineComponent, ref, computed } from 'vue'
+<script lang="ts">
+import { computed, defineComponent, ref } from 'vue'
 export default defineComponent({
-    name: 'UiTreeItem',
+    name: 'UITreeItem',
     components: {},
     props: {
         item: Object,
     },
     setup(props, _) {
-        const item = props.item.getValue()
+        const item = props.item?.getValue()
         const toggle = () => {
             if (isFolder.value) {
                 isOpen.value = !isOpen.value
             }
         }
-        const makeFolder = () => {}
+        const makeFolder = () => {
+            // console.log()
+        }
         const isOpen = ref(false)
         const isFolder = computed(() => item.children && item.children.length)
 

+ 17 - 15
packages/components/basic/tree/index.vue

@@ -2,43 +2,45 @@
     <ul class="ui-tree" :style="style" :class="{ children: level > 1, stroke, flat: level > maxTab }">
         <template v-for="(item, index) in data" :key="item.id || index">
             <li
+                v-if="item.children && item.children.length"
                 class="ui-tree-item"
                 :class="{
                     alone: data.length === 1,
                     put: animationsRef[index].value && !animationsRef[index].value.show,
                 }"
-                v-if="item.children && item.children.length"
             >
                 <div class="ui-tree-content">
-                    <span :class="{ first: !index }" class="ui-tree-auxiliary" v-if="stroke && index !== item.children.lengt - 1"> </span>
-                    <span class="ui-tree-ctrl" :class="{ open: animationsRef[index]?.value?.show }" @click="animationsRef[index].value.changeShow()"> </span>
-                    <slot :row="item" :locals="[...locals, index]"></slot>
+                    <span v-if="stroke && index !== item.children.lengt - 1" :class="{ first: !index }" class="ui-tree-auxiliary" />
+                    <span class="ui-tree-ctrl" :class="{ open: animationsRef[index]?.value?.show }" @click="animationsRef[index].value.changeShow()" />
+                    <slot :row="item" :locals="[...locals, index]" />
                 </div>
-                <UISizeAnimation animationStyle="scale" :ref="animationsRef[index]" class="ui-tree-item-child">
+                <UISizeAnimation :ref="animationsRef[index]" animation-style="scale" class="ui-tree-item-child">
                     <ui-tree :style="style" :stroke="stroke" :data="item.children" :max-tab="maxTab" :level="level + 1" :open="open" :locals="[...locals, index]">
                         <template #default="slotData">
-                            <slot v-bind="slotData"></slot>
+                            <slot v-bind="slotData" />
                         </template>
                     </ui-tree>
                 </UISizeAnimation>
             </li>
-            <li class="ui-tree-item un-children" v-else>
+            <li v-else class="ui-tree-item un-children">
                 <div class="ui-tree-content">
-                    <slot :row="item" :locals="[...locals, index]"></slot>
+                    <slot :row="item" :locals="[...locals, index]" />
                 </div>
-                <div class="ui-tree-item-child" v-if="stroke"></div>
+                <div v-if="stroke" class="ui-tree-item-child" />
             </li>
         </template>
     </ul>
 </template>
 
-<script>
-export default { name: 'UiTree' }
-</script>
-<script setup>
+<script lang="ts" setup>
 // computed
-import { defineProps, ref, watchEffect, defineExpose } from 'vue'
+import { defineExpose, defineProps, ref, watchEffect } from 'vue'
 import UISizeAnimation from '../size-animation'
+// export default { name: 'UiTree' }
+
+defineOptions({
+    name: 'UITree',
+})
 
 const props = defineProps({
     data: {
@@ -61,7 +63,7 @@ const props = defineProps({
 
 const animationsRef = ref(props.data.map(item => ref(null)))
 const changeShowAll = isOpen => {
-    for (let ranimationRef of animationsRef.value) {
+    for (const ranimationRef of animationsRef.value) {
         ranimationRef && ranimationRef.value?.changeShow(isOpen)
     }
 }

+ 10 - 10
packages/utils/dom/others.ts

@@ -2,15 +2,15 @@ import { toTypeString } from '@vue/shared'
 
 export const toRawType = (value: any) => toTypeString(value).slice(8, -1)
 
-export const normalizeUnitToStyle = unit => {
-    if (unit === void 0) {
+export const normalizeUnitToStyle: number = (unit: number | string) => {
+    if (unit === 0) {
         return unit
-    } else if (toRawType(unit) === 'Number') {
-        return unit ? ((unit <= 1) & (unit >= 0) ? 100 * unit + '%' : unit + 'px') : void 0
+    } else if (typeof unit === 'number') {
+        return unit ? (unit <= 1 && unit >= 0 ? `${100 * unit}%` : `${unit}px`) : 0
     } else if (unit.includes('px')) {
-        return normalizeUnitToStyle(parseFloat(unit))
+        return normalizeUnitToStyle(Number.parseFloat(unit))
     } else if (unit.includes('%')) {
-        return normalizeUnitToStyle(parseFloat(unit) / 100)
+        return normalizeUnitToStyle(Number.parseFloat(unit) / 100)
     } else {
         return unit
     }
@@ -31,9 +31,9 @@ export const os = (function () {
         isTablet = true
     }
     return {
-        isTablet: isTablet,
-        isPhone: isPhone,
-        isAndroid: isAndroid,
-        isPc: isPc,
+        isTablet,
+        isPhone,
+        isAndroid,
+        isPc,
     }
 })()

+ 1 - 1
packages/utils/dom/parent.ts

@@ -1,4 +1,4 @@
-import { ref, onMounted, computed } from 'vue'
+import { computed, onMounted, ref } from 'vue'
 
 /**
  * 获取真实DOM的高度

+ 1 - 1
packages/utils/normal.ts

@@ -10,7 +10,7 @@ export const randomId = (e = 6): string => {
 
 export function omit(obj, ...props) {
     const result = { ...obj }
-    props.forEach(function (prop) {
+    props.forEach(prop => {
         delete result[prop]
     })
     return result

+ 6 - 0
pnpm-lock.yaml

@@ -6,7 +6,10 @@ importers:
     specifiers:
       '@changesets/cli': ^2.24.4
       '@commitlint/cli': ^17.1.2
+      '@kankan/build': workspace:*
+      '@kankan/build-utils': workspace:*
       '@kankan/components': workspace:*
+      '@kankan/eslint-config': workspace:*
       '@kankan/hooks': workspace:*
       '@pnpm/find-workspace-packages': ^4.0.16
       '@pnpm/logger': ^4.0.0
@@ -54,6 +57,9 @@ importers:
     devDependencies:
       '@changesets/cli': 2.24.4
       '@commitlint/cli': 17.1.2
+      '@kankan/build': link:internal/build
+      '@kankan/build-utils': link:internal/build-utils
+      '@kankan/eslint-config': link:internal/eslint-config
       '@pnpm/find-workspace-packages': 4.0.43_vp7a5l77f5ejdshrmfsgf4kfnm
       '@pnpm/logger': 4.0.0
       '@pnpm/types': 8.7.0