@saco/ui

Saco UI component library
368
Install
npm install @saco/ui
Latest Version:2.0.1
Vue:3
License:MIT
Last Updated:Oct 15, 2026
Links: npm
Maintainer: seawavew

@saco/ui

Vue 3、Capacitor 的组件库。模板标签例如 <saco-button type="primary">保存</saco-button>。

uni-app x 的接入、主题,以及和 Web 不一致的地方,写在 UNI-APP.md。

组件名是 Saco*,样式类是 saco-*。每个组件的 Props / Events / Slots 见文末组件文档。

主题(SCSS !default)

覆盖种子、黑、白、文字时传 Sass 色值,亮色、暗色各传一档。light-3/5/7/8/9、dark-2 在编译期用 Sass color.mix 写成 rgba。不要传 var(--primary-color) 这类 CSS 变量,库里混不了。不要写 CSS color-mix(),套壳 WebView 会把整段声明丢掉。不要再往色板里塞第二颗浅色 hex。

// src/styles/saco/index.scss
@forward '@saco/ui/theme-chalk/src/common/var.scss' with (
  $color-palette: (
    primary-color: (
      light: #266fff,
      dark: #3b82f6,
    ),
    white-color: (
      light: #fff,
      dark: #eaf2ff,
    ),
    black-color: (
      light: #000,
      dark: #070b14,
    ),
    text-color: (
      light: #515151,
      dark: #cbd5e1,
    ),
  ),
  $font-size: 14px,
  // 默认是 data-theme-type。不用这套属性时改成自己的选择器
  // $theme-light-selector: ':root, [data-theme-type="light"]',
  // $theme-dark-selector: '[data-theme-type="dark"]'
);

键跟种子同名:primary-color、success-color、warning-color、danger-color、info-color、white-color、black-color、text-color。每键有 light 和 dark。没写的键用默认种子,暗色跟亮色相同。

color-tokens 按两个选择器各写一套:

  • $theme-light-selector(默认 :root, [data-theme-type="light"]):亮色种子和档位,边框、阴影也挂在这里
  • $theme-dark-selector(默认 [data-theme-type="dark"]):暗色种子和档位

对应变量:--saco-color-primary、--saco-color-primary-light-3、--saco-color-primary-dark-2、--saco-color-text、--saco-color-white、--saco-color-black。

选择器由业务传入,库不假定一定用 @saco/theme。用了 @saco/theme 就保持默认,根节点写 data-theme-type="dark"。别的主题体系把命中暗色的选择器传进来,例如 [data-theme="dark"] 或 .dark。跟系统切换时,把暗色选择器放进 $theme-dark-media,例如 '(prefers-color-scheme: dark)'。uni-app x 的写法见 UNI-APP.md。

档位在样式编译时就算好了。运行时改 --saco-color-primary 不会连带改档位,要换档位就改 Sass 种子。装好的 CSS 用的是默认选择器;要换成自己的选择器,按需样式传 importStyle: 'sass'。

Button 的内置 type(primary / success / warning / danger / info)读 --saco-color-{type}-light-* 和 dark-2,所以悬停会跟着主题换。自定义 type 没有这些档位时,悬停回落到 --button-color 本身。

种子怎么注入、会生成哪些变量,写在文末 种子注入。

Vite 里把种子文件挂到 additionalData(用 SCSS 或 Less 其中一套):

css: {
  preprocessorOptions: {
    scss: {
      additionalData: `@use "@/styles/saco/index.scss" as *;`
    },
    less: {
      additionalData: `@import "@/styles/saco/index.less";`
    }
  }
}

Vue 3 按需(推荐)

import Components from 'unplugin-vue-components/vite'
import { SacoUiResolver, SacoUiPlugin } from '@saco/ui/resolver'

plugins: [
  SacoUiPlugin({
    svgDirs: ['src/assets/icons'],
    // pnpm store 只读时:svgDtsDir: '.types'
    // styleLayer: 'saco-ui', // 需要 CSS @layer 时再开
  }),
  Components({
    resolvers: [SacoUiResolver({ importStyle: 'sass' })]
  })
]

SacoUiResolver 按 package.json 的 name 解析,当前是 @saco/ui,组件路径是 @saco/ui/es/components/button。不要再传 packageName: 'saco-ui'。

模板 v-loading / v-power 也走这条 resolver。SacoUiPlugin 把图标 Extra 和这两条指令写进同一份声明:不传 dts 时是 Vite 项目根的 saco-ui.d.ts。业务不要再写 saco-ui-directives.d.ts,也不要在 env.d.ts 手抄 GlobalDirectives。脚本里的 SacoMessage / SacoMessageBox 用 sacoUiAutoImports(),按需路径是 @saco/ui/es/components/message,不要 from '@saco/ui' 主包把全部组件打进来。

按需 theme-chalk 默认不分 @layer(传 styleLayer: 'saco-ui' 可开启)。全量 index.scss 不进 layer。

模板里的 Saco* 已经带类型。不要在 env.d.ts / tsconfig.types 里再写 @saco/ui/global,也不要自己写 declare module '@saco/ui/resolver'。

@click.stop、@mousedown.prevent 这类修饰符照常生效。Button 的 click 是组件自己的事件。

unplugin-vue-components 的 dts 只记录用过的组件。还没写进那份 dts 的 Saco* 用本包自带的声明。

业务图标 svgDirs

不必再包一层自己的 Svg。把 .svg 放到业务或公共库目录,经 svgDirs 注册进 SacoSvg,<saco-svg name="logo" /> 和 Button icon 都能用:

SacoUiPlugin({
  svgDirs: ['src/assets/icons'], // 可多个;后者覆盖前者;同名覆盖库内图标
  // icons: ['dynamic-name'], // 动态 :name 静态分析扫不到时强制打进包
  // dts: '.types/saco-ui.d.ts', // 不传则写 Vite 项目根的 saco-ui.d.ts
})
项 说明
svgDirs 业务 / 公共库图标目录(相对项目根或绝对路径)。不传默认 src/assets/svg
同名 业务覆盖库内;多个目录时数组靠后的赢
dts 可选。图标 Extra 和 v-loading / v-power 写在同一份。不传则是项目根 saco-ui.d.ts;false 不生成
icons 可选。动态名补全,不是指定目录
styleLayer 按需 theme-chalk 的 CSS @layer 名。默认不分层;传 saco-ui 等 slug 开启

Vue 3 全量

import SacoUI from '@saco/ui'
import '@saco/ui/theme-chalk/src/index.scss'
app.use(SacoUI)

全量会带上全部组件和样式。命令式 API 在 app.use 之后可用:SacoMessage、SacoMessageBox、SacoLoading.service、v-loading、v-power。

使用时注意

事项 说明
带行数据的组件 SacoTable / SacoSelect / SacoTree 用 InstanceType<typeof SacoTable<Row>> 取实例,方法返回值跟着行类型走
dayjs Vite 里把 dayjs 的 alias 和 dedupe 指到应用自己的 node_modules/dayjs

组件文档

用法、Props、Events、Slots、Expose 在各组件文档里。

组件 文档
Button / Group button · group
Checkbox / Group / Button checkbox · group · button
Radio / Group / Button radio · group · button
Input / Textarea / Number input · textarea · number
Text text
Card card
Progress progress
Select select
DatePicker / DateTimer date-picker · date-timer
Form / FormItem form · form-item
Table / TableColumn table · table-column
Tree tree
Dialog / Drawer / Overlay dialog · drawer · overlay
Message / MessageBox / Loading message · message-box · loading
Menu menu · sub-menu · menu-item · group
Dropdown dropdown · menu · item
Tabs tabs · tab-pane
Pagination pagination
Tooltip tooltip
Popper popper
Roll roll · item
Power power
Upload / Signature upload · signature
Svg / Render / ConfigProvide svg · render · config-provide

种子注入

只改种子。light-3 / light-5 / light-7 / light-8 / light-9、dark-2,以及边框、阴影、字号、控件高度,都由种子生成。不要手写整份 :root。

变量前缀是 saco。生成名例如 --saco-color-primary、--saco-color-white、--saco-color-black、--saco-font-size、--saco-button-height。组件只读这些变量,不要写在 .saco-button 上。

size="large" / small 不改高度和字号。要放大缩小,改 $control-height / $font-size(Less 里是 @control-height / @font-size)。

下面列出的就是当前默认。只改你要动的那几项。

SCSS

@forward … with 在编译组件样式时换种子,边框、阴影会按新的黑白重新算。

// src/styles/saco/index.scss
@forward '@saco/ui/theme-chalk/src/common/var.scss' with (
  $color-palette: (
    primary-color: (light: #409eff, dark: #3b82f6),
    success-color: (light: #67c23a, dark: #67c23a),
    warning-color: (light: #e6a23c, dark: #e6a23c),
    danger-color: (light: #f56c6c, dark: #f56c6c),
    info-color: (light: #909399, dark: #909399),
    white-color: (light: #fff, dark: #eaf2ff),
    black-color: (light: #000, dark: #070b14),
    text-color: (light: #515151, dark: #cbd5e1),
  ),
  $font-size: 14px,
  $control-height: 32px
);

Vite 挂到 additionalData 的写法见上文 主题。

Less

业务文件只写要改的种子。Less 转写只认 @primary-color: #409eff 这种字面量,亮色写进去后暗色种子跟着这颗走。要亮暗分开,用上面的 SCSS $color-palette。不要 @import seed.less:那份会直接输出整段 :root,挂进 additionalData 后每个 less 文件都会再打一份。

SacoUiPlugin 读 less.additionalData,转成跟 SCSS 一样的 @use … with,在编译组件样式时换种子。

// src/styles/saco/index.less
@primary-color: #409eff;
@success-color: #67c23a;
@warning-color: #e6a23c;
@danger-color: #f56c6c;
@info-color: #909399;
@white-color: #fff;
@black-color: #000;
@font-size: 14px;
@control-height: 32px;
css: {
  preprocessorOptions: {
    less: {
      additionalData: `@import "@/styles/saco/index.less";`
    }
  }
}

只影响某一块页面时,在祖先上改已经生成出来的变量:

.theme-compact {
  --saco-border-radius: 2px;
  --saco-input-height: 28px;
  --saco-button-height: 28px;
}

Button 的 type / plain / hover 仍从 --saco-color-{type} 推。--saco-button-text-color、--saco-button-bg-color、--saco-button-border-color 默认不生成。写上之后会盖过 type 色。

Related Packages

seeroad-ui

seeroad project ui library

3,733
ui
smart-ui

High Quality Mobile UI Componets by Vue.js 2.

1,883 11
ui
hea-ui

hea-ui is a h5 ui component for vue

1,520 14
ui
canna-ui-vue

shims-vue.d.ts declare module 'canna-ui-vue'

674
ui

Version History

Version Released Vue License
2.0.1 ^3.5.0 MIT
2.0.0 ^3.5.0 MIT
1.0.2 ^3.5.0 MIT
1.0.1 ^3.5.0 MIT
1.0.0 ^3.5.0 MIT