@xnary/pastry-ui
Pastry UI
基于 Vue 3 的企业级组件库,从内部项目抽离并发布到公网 npm。
- 包名:
@xnary/pastry-ui - 依赖:
vue@^3.3(peer) - 组件:53 个(表单、表格、弹窗、菜单、日期时间、上传、树形/级联、DAG 画布等)
- 设计特点:核心包零业务依赖——不引用任何宿主代码、不内置图标库、不内置请求实现,全部通过注册/注入接入。
安装
npm install @xnary/pastry-ui
快速开始
// main.js
import { createApp } from 'vue'
import PastryUI from '@xnary/pastry-ui'
import '@xnary/pastry-ui/style.css' // 组件样式(必须)
import '@xnary/pastry-ui/global.css' // 全局滚动条等(可选,会作用于整个页面)
import { useIconParkIcons } from '@xnary/pastry-ui/adapters/iconpark'
const app = createApp(App)
app.use(PastryUI, {
// 可选:注入默认上传实现,PtUpload 不传 action/httpRequest 时用它
upload: {
request: ({ file, onSuccess, onError }) => { /* ... */ }
}
})
// 图标:注册适配器后 <PtIcon name="search" /> 才会渲染
useIconParkIcons()
按需引入(不注册全局组件):
import { PtButton, PtTable, PtTableColumn } from '@xnary/pastry-ui'
import '@xnary/pastry-ui/style.css'
图标(PtIcon)
PtIcon 是纯包装组件:自身不含任何图标库代码,图标一律通过适配器注册提供。
<PtIcon name="search" /> <!-- 走默认适配器 -->
<PtIcon name="tdesign:home" /> <!-- 冒号前缀显式指定适配器(多个图标库可共存) -->
<PtIcon name="search"><svg/></PtIcon> <!-- 有插槽时插槽优先 -->
适配器契约:
import { registerIconAdapter } from '@xnary/pastry-ui'
registerIconAdapter({
name: 'my-icons', // 适配器名,用于 name="my-icons:home"
resolve: (iconName) => icons[iconName], // 返回组件对象或已全局注册的组件名字符串;拿不到返回 null
props: ({ size, color, strokeWidth }) => ({ // 可选:抹平图标库传参差异
size, fill: color
}),
aliases: { 'arrow-left': 'Left' } // 可选:本图标库专有的名称别名表
}, { asDefault: true })
用 IconPark
npm install @icon-park/vue-next
import { useIconParkIcons } from '@xnary/pastry-ui/adapters/iconpark'
useIconParkIcons() // 注册为默认适配器
useIconParkIcons({ asDefault: false }) // 或只注册,之后写 name="iconpark:home"
该适配器保留了历史别名表(arrow-left、warning、success-filled、document-add、setting、people 等),老项目的 name 写法可直接沿用。
用 TDesign 图标
import { registerIconAdapter } from '@xnary/pastry-ui'
import * as TDesign from 'tdesign-icons-vue-next'
const pascal = (name) => String(name).replace(/(^[a-zA-Z])|(-[a-zA-Z])/g, (c) => c.slice(-1).toUpperCase())
registerIconAdapter({
name: 'tdesign',
// TDesign 的组件名带 Icon 后缀:home → HomeIcon
resolve: (name) => TDesign[`${pascal(name)}Icon`] ?? TDesign[pascal(name)] ?? null,
props: ({ size, color }) => ({ size, fill: color })
}, { asDefault: true })
图标找不到时不会抛错:优先渲染插槽,无插槽则渲染空占位,并在控制台按图标名提示一次。
上传(PtUpload)
包内不含任何请求实现,上传通过以下三种方式之一提供(优先级从高到低):
- 组件 prop:
:http-request="fn"
const uploader = ({ file, onSuccess, onError }) => {
const fd = new FormData()
fd.append('file', file)
myApi.post('file/upload', fd, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(onSuccess)
.catch(onError)
}
-
组件 prop:
action="/api/file/upload"(配:headers,内部用 fetch) -
安装时注入默认上传器(适合大量存量调用点):
app.use(PastryUI, {
upload: {
request: ({ file, onSuccess, onError }) => { /* 同上 */ }
}
})
也可以在运行时配置:
import { setPastryUIConfig } from '@xnary/pastry-ui'
setPastryUIConfig({ upload: { request: uploader } })
三者都没有时会给出明确报错提示,不会静默失败。
组件清单
- 基础:
PtButtonPtButtonGroupPtIconPtDividerPtTagPtAlertPtProgressPtEmpty - 表单:
PtInputPtInputNumberPtSelectPtOptionPtOptionGroupPtCheckboxPtCheckboxGroupPtRadioPtRadioGroupPtRadioButtonPtSwitchPtSliderPtColorPickerPtCascaderPtCitySelectPtUploadPtFormPtFormItem - 日期时间:
PtDatePickerPtDateTimePickerPtTimePicker - 数据:
PtTablePtTableColumnPtPaginationPtTransferPtDagCanvas - 反馈/浮层:
PtDialogPtDrawerPtTooltipPtPopoverPtPopupPtDropdownPtDropdownMenuPtDropdownItemPtImagePreviewPtCascadingMenu - 导航/布局:
PtMenuPtMenuItemPtSubMenuPtSidebarPtTabsPtTabPanePtRowPtCol - 命令式 API:
PtMessagePtMessageBoxPtLoading、指令v-pt-loading
组件文档(Storybook)
组件文档是本仓库里的一个独立子项目 storybook/(自带 package.json、依赖与脚本,不参与组件库构建与发布;根包 files 白名单不含它)。
文档直接引用 src/ 源码,改组件即时生效;覆盖全部 52 个组件 + 命令式 API + 设计令牌。
cd storybook
npm install # 只装文档工程依赖
npm run storybook # http://localhost:6006
新增组件后请补 storybook/stories/<分类>/<组件名>.stories.js:npm run build-storybook 与 npm run storybook 都会先跑
npm run check,漏写文档会直接失败并列出缺哪个组件。写故事的约定见 storybook/README.md。
样式与主题
@xnary/pastry-ui/style.css:组件样式 + CSS 变量(--pt-*),必须引入。@xnary/pastry-ui/global.css:全局滚动条等会外溢的规则,可选。- 主题:覆盖
:root上的--pt-accent、--pt-surface、--pt-border-radius-*等变量即可。 - 移动端适配断点约定为
768px。
发布
npm run release -- patch # 递增版本 → 构建 → 校验产物 → npm publish --access public
npm run release -- 0.2.0 # 指定版本
npm run release -- patch --dry-run # 只构建与校验,不发布
发布前需要拥有 @xnary scope 的公网 npm 权限(npm login,或 CI 中配置 Automation token)。脚本会自动校验产物里没有内网地址、内部接口路径等痕迹。
完整发版与升级流程
-
改代码:在
E:/workspaces/pastry-ui修改组件,本地npm run dev起 demo 页面自测。 -
构建与校验:
npm run build,确认dist/下有pastry-ui.es.js、pastry-ui.umd.cjs、pastry-ui.css、global.css、cityData.json、adapters/iconpark.js。 -
本地验证:
npm pack出 tgz,在任一业务项目里npm install <tgz 路径>跑通页面(图标、上传、表格、弹窗)后再发布。 -
发布:
npm run release -- patch(版本号递增 + 构建 + 校验 +npm publish --access public),随后git commit、git tag v<版本>、git push --follow-tags。 -
各项目升级(6 个项目:
basic-framework、ajitai-lesson、stardust-new、falco-shop、shimmer/server、pastrybi):# npm 项目 npm install @xnary/pastry-ui@<版本> && npm run build # shimmer/server 用 pnpm pnpm add @xnary/pastry-ui@<版本> && npm run build升级后回归:图标显示、上传、表格(排序/列宽/固定列/分页)、弹窗与提示、日期时间选择器、页面整体样式(滚动条)。
-
archetype 模板同步(仅
basic-framework):在basic-framework/archetype下跑python3 sync-to-archetype.py,把最新的frontend/(含新版本依赖与main.js接入代码)同步进模板,再mvn install更新本地 archetype。
破坏性变更(组件 API、样式引入方式、图标注册方式等)必须同步更新
MIGRATION.md,并在CHANGELOG.md里单独标出。
License
MIT
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.1.0 | ^3.3.0 | MIT |