shadcn-vue-cdn
v0.0.4
Published
shadcn-vue 组件库 — 全局注册、运行时主题、UMD/ES 双格式,可直接通过第三方 CDN 引入
Maintainers
Readme
shadcn-vue 组件库
把 shadcn-vue 的 components/ui 组件导出为可打包的组件库,支持 element-ui 式全局注册、运行时主题切换与 CDN 引入。
特性
- 全局注册:
app.use(ShadcnVue, options),模板直接<Button /> - 按需导入:
import { Button } from 'shadcn-vue' - 运行时主题:
css:直接传 CSS 字符串(同步注入,优先级最高)preset:传 shadcn-vue preset 短码,纯本地查表生成主题 CSS,零网络请求
- usePreset hooks:容器作用域主题切换——接受 preset code 或 JSON 配置,主题只作用于指定容器内
- 图标导出:
export * from '@remixicon/vue',命名导出RiXxx系列约 3000 个图标 - CDN 可用:UMD + ES 双格式打包,基础样式独立 CSS,reka-ui 内置(仅外部依赖 Vue + VueDemi)
组件
51 个组件目录,覆盖:基础原语(Button / Input / Select / Switch / Checkbox / Slider / Toggle …)、反馈(Alert / Badge / Skeleton / Spinner / Progress / Sonner)、覆盖层(Dialog / AlertDialog / Sheet / Drawer / Popover / Tooltip / DropdownMenu / ContextMenu / Command …)、数据展示与布局(Card / Table / Avatar / Tabs / Accordion / Breadcrumb / ScrollArea / Resizable / Carousel / Stepper / Sidebar / NavigationMenu / Menubar / Pagination / Calendar / Form …)等。
完整清单见 src/components/ui/。
构建
包管理器:bun(依赖安装与构建脚本)+ pnpm(scripts 入口,两者等价可用)。
pnpm build # 应用构建(vue-tsc -b + vite)→ dist/
pnpm build:lib # 库打包(一条命令):JS(ES + UMD)+ CSS + d.ts → dist-lib/
pnpm build:css # 仅重编基础样式 → dist-lib/shadcn-vue.css
pnpm build:cdn # 等效于 build:lib + build:css(bun 串联)
pnpm test # vitest 单元测试(jsdom)库产物输出到独立的
dist-lib/,与应用构建的dist/互不干扰。build:lib与build:css脚本内部使用bunx --bun调用 vite 与 Tailwind CLI。
产物
dist-lib/ 包含:
shadcn-vue.es.js/shadcn-vue.umd.js— 双格式库 JS(已内置 reka-ui 等依赖,仅外部依赖vue+vue-demi)shadcn-vue.css— Tailwind 编译的基础样式(独立文件,不嵌套进 JS)index.d.ts+components/、lib/— 类型声明
用法
全局注册(推荐)
import { createApp } from 'vue'
import App from './App.vue'
import 'shadcn-vue/style.css' // 基础样式(必须)
import ShadcnVue from 'shadcn-vue'
const app = createApp(App)
// 方式 A:直接传 CSS(同步,优先级最高)
app.use(ShadcnVue, {
css: `:root { --primary: oklch(0.6 0.2 250); }`,
})
// 方式 B:preset 短码(纯本地同步生成,零网络请求)
// preset 短码可在 shadcn-vue.com 自定义主题后获取,或由 presetConfigToCode(JSON) 生成
app.use(ShadcnVue, { preset: 'a5UoQS7t' })
app.mount('#app')按需导入
import { Button } from 'shadcn-vue'工具函数
import { presetToCss, presetConfigToCode, resolveConfig } from 'shadcn-vue'
// preset 短码 → 完整主题 CSS(纯本地查表,同步返回)
const css = presetToCss('a5UoQS7t')
// JSON 配置 → preset 短码(支持部分字段,其余取默认值)
const code = presetConfigToCode({ theme: 'blue', radius: 'large', font: 'inter' })
// preset 短码或 JSON 配置 → 完整配置对象
const config = resolveConfig({ theme: 'blue' }) // { base: 'reka', theme: 'blue', ... }CDN 引入
包已发布到 npm:shadcn-vue-cdn,可通过任何 npm CDN 引入(unpkg / jsDelivr)。
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist-lib/shadcn-vue.css" />
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/index.iife.js"></script>
<script src="https://unpkg.com/[email protected]/dist-lib/shadcn-vue.umd.js"></script>
<script>
const app = Vue.createApp({ template: '<Button>Click</Button>' })
// preset 主题:纯本地生成,无需网络请求
app.use(ShadcnVue.ShadcnVue, { preset: 'a326wSQq' })
app.mount('#app')
</script>- 省略版本号可始终用最新版:
https://unpkg.com/shadcn-vue-cdn/dist-lib/shadcn-vue.umd.js(不推荐生产使用,建议锁定版本) - 等效 jsDelivr 地址:
https://cdn.jsdelivr.net/npm/[email protected]/dist-lib/shadcn-vue.umd.js - 本地完整示例见
examples/cdn/index.html(51 个组件的 props 可视化调节 + 交互测试 + 图标浏览器)
注:UMD 构建已内置 reka-ui,仅外部依赖 Vue + VueDemi(因此需先加载两者);Tailwind 样式独立在
shadcn-vue.css,不嵌套进 JS。
preset 主题机制
主题数据内嵌在库中(src/lib/preset-data.ts,提取自 shadcn-vue 官方源码的 registry/themes.ts 与 registry/fonts.ts),纯本地生成 CSS,零网络请求。不需要访问 shadcn-vue 官网 API,也不存在跨域/CORS 问题。
支持的全部字段与取值
| 字段 | 可选值 | 说明 |
|---|---|---|
| base | reka | 组件基底 |
| style | vega / nova / maia / lyra / mira / luma / sera / rhea | 视觉风格 |
| baseColor | neutral / stone / zinc / mauve / olive / mist / taupe | 基础色(背景/前景/边框) |
| theme | 24 种:neutral / stone / zinc / mauve / olive / mist / taupe + amber / blue / cyan / emerald / fuchsia / green / indigo / lime / orange / pink / purple / red / rose / sky / teal / violet / yellow | 强调色(primary/ring 等) |
| chartColor | 同 theme 的 24 种 | 图表色(chart-1~5) |
| font | 24 种字体 | 正文字体,如 inter / jetbrains-mono / geist-sans |
| fontHeading | inherit + 24 种字体 | 标题字体,inherit 表示跟随正文 |
| radius | default / none / small / medium / large | 圆角档位 |
| menuAccent | subtle / bold | 菜单强调 |
| menuColor | default / inverted / default-translucent / inverted-translucent | 菜单配色 |
完整枚举见
PRESET常量(由库导出),或直接看src/lib/preset-theme.ts。
三种使用方式
1. 插件全局注入(preset 短码)
app.use(ShadcnVue, { preset: 'a5UoQS7t' })2. JSON 配置 → preset 短码
import { presetConfigToCode } from 'shadcn-vue'
const code = presetConfigToCode({ theme: 'blue', baseColor: 'neutral', font: 'inter' })
app.use(ShadcnVue, { preset: code })3. 直接拿 CSS(自行注入)
import { presetToCss } from 'shadcn-vue'
const css = presetToCss('a5UoQS7t') // 同步返回 ':root { ... } .dark { ... }'
document.head.insertAdjacentHTML('beforeend', `<style>${css}</style>`)容器作用域主题(usePreset)
usePreset 把主题 CSS 限定在指定容器内生效,适合"局部换肤 / 多主题并存"场景。接受 preset code 或 JSON 配置,第二参数传容器选择器与深色模式 ref。
import { ref } from 'vue'
import { usePreset } from 'shadcn-vue'
// 深色模式状态(可绑定 Switch)
const dark = ref(false)
// 初始化:JSON 配置 + 容器作用域
const preset = usePreset(
{ theme: 'blue', baseColor: 'neutral' },
{ selector: '.theme-container', dark },
)
// 切换主题:preset code 或 JSON 配置(基于当前配置合并,只覆盖传入字段)
preset.switchTo({ theme: 'green' })
preset.switchTo('abT3Ca')
// 其他方法
preset.config.value // 当前完整配置
preset.applyCss(css) // 手动注入 CSS
preset.clear() // 移除主题样式容器内深色模式:将 .dark 类同时挂到容器自身即可命中 .theme-container.dark 规则:
<div class="theme-container" :class="{ dark }">
<!-- 容器内组件使用 var(--primary) 等变量,主题只影响这里 -->
</div>生成的选择器:
.theme-container { --background: ...; --primary: ... }与.theme-container.dark, .theme-container .dark { ...深色变量... }。组件样式(如bg-primary)解析为var(--primary),在容器内就近取值,因此主题只作用于容器内部。
CDN 场景实现主题
CDN 引入时,UMD 全局对象 ShadcnVue 已包含完整的主题数据与工具函数,无需任何网络请求:
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/index.iife.js"></script>
<script src="https://unpkg.com/[email protected]/dist-lib/shadcn-vue.umd.js"></script>
<script>
// 1) 插件方式:preset 短码或 JSON 配置(全局生效)
const app = Vue.createApp({ template: '<Button>主题按钮</Button>' })
app.use(ShadcnVue.ShadcnVue, { preset: 'a326wSQq' })
app.mount('#app')
// 2) 工具函数:JSON → code、code → CSS
const code = ShadcnVue.presetConfigToCode({ theme: 'blue' })
const css = ShadcnVue.presetToCss('a326wSQq')
// 3) 容器作用域:局部换肤(只影响 .my-panel 内部)
const dark = Vue.ref(false)
const preset = ShadcnVue.usePreset(
{ theme: 'purple' },
{ selector: '.my-panel', dark },
)
preset.switchTo({ theme: 'emerald' })
</script>preset 短码从哪来
- 在 shadcn-vue.com/create 自定义主题后复制短码;
- 或本地用
presetConfigToCode(JSON)生成(见上),生成的短码与官网格式完全兼容(同一套 base62 编码)。
命令行工具 scripts/presets-to-css.js:
node scripts/presets-to-css.js a5UoQS7t # 打印 CSS 到 stdout
node scripts/presets-to-css.js a5UoQS7t -o luma.css # 写入文件脚本默认 preset 为
a2LP1P8;CDN 示例默认用a326wSQq。
相关文档
docs/superpowers/specs/— 组件库设计文档docs/superpowers/plans/— 实现计划
