ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

一份行为,三种宿主:聊聊 XiHan.UI 这个框架无关的 Headless 组件库

一份行为,三种宿主:聊聊 XiHan.UI 这个框架无关的 Headless 组件库 一份行为三种宿主聊聊 XiHan.UI 这个框架无关的 Headless 组件库做前端久了多半碰到过这种局面后台用 Vue官网用 React角落里还剩几个没有框架的老页面。三边各有一个弹窗按 Esc 有的关有的不关关掉以后焦点有的回到按钮上有的掉回页面顶部。用鼠标的人察觉不到用键盘和读屏的人每天都被绊一下。再往后换框架组件库整套重写最先丢的正是这些看不见的东西方向键往哪走读屏念什么焦点落在哪。XiHan.UI 就是冲着这件事做的快速、轻量、高效、用心的框架无关 Headless UI 组件库。是面向企业级前端的设计系统运行时无头内核多框架适配器。提供基础组件与 AI 组件覆盖从中后台到 AI 对话的界面构建场景。曦寒懿XiHanFun开源生态的前端基座。下面把它的设计、细节和取舍摊开讲也包括它现在做不到的地方。文档站每个组件都有能点、能切换框架的真实示例文档站https://ui.docs.xihanfun.comGitHubhttps://github.com/XiHanFun/XiHan.UIGiteehttps://gitee.com/XiHanFun/XiHan.UIGitCodehttps://gitcode.com/XiHanFun/XiHan.UI一、先看用起来是什么样pnpmaddxihan-ui/vue xihan-ui/tokens xihan-ui/styles入口引一次皮肤组件按名字 import不用app.use()。所有包都声明了sideEffects: false没用到的组件会被摇掉XhDialogRoot v-slot{ setOpen } XhDialogTrigger打开对话框/XhDialogTrigger XhDialogContent XhDialogTitle确认操作/XhDialogTitle XhButton clicksetOpen(false)确定/XhButton /XhDialogContent /XhDialogRoot打开以后焦点圈在内容区、Esc 或点遮罩关闭、关闭后焦点回到触发按钮、背后锁住滚动、其余部分对读屏隐藏这些一行都不用写。React 19 的组件名和写法完全一样。没有框架的页面用自定义元素结构自己写用data-xh-part标出每个节点的角色xh-dialogbuttondata-xh-parttrigger打开/buttondivdata-xh-partpositionerdivdata-xh-partcontent…/div/div/xh-dialog三种写法跑的是同一台状态机、同一份connect差别只在于谁把属性写到 DOM 上。二、一个组件五份产物以对话框为例它在仓库里落成五处无头内核解剖、状态机、键盘规格表、connect、Vue 组件、React 组件、自定义元素xh-dialog、纯 CSS 皮肤。行为只在内核里定义一次适配器只做三件事把状态机接进各自的响应式把部件包成组件把属性铺到节点上。全库的地基是解剖每个部件在 DOM 上由data-scope加data-part唯一标识皮肤、测试、诊断都建在这对属性上。皮肤只认属性不认类名所以同一份 CSS 同时作用于三端[data-scopebutton][data-partroot][data-variantsolid]{…}connect是内核的出口一个纯函数输入状态机服务输出一组getXxxProps()。每个 getter 产出结构标识、ARIA 语义、状态钩子、id 关联和事件处理器五类东西里面没有一行 DOM 操作getTriggerProps:itemnormalize.button({...parts.trigger.attrs,//>id:triggerId(item.value),// 由 scope 派生同页多实例不冲突aria-controls:contentId(item.value),aria-expanded:isOpen(item.value)?true:false,data-state:stateAttr(item),// 皮肤钩子onClick:(){/* send({ type: ITEM.TOGGLE, … }) */},});不想要现成结构时直接拿api用v-bind铺到自己的标签上。一次点击经过的路径是这样的用户点击 → 适配器把 DOM 事件交给 connect 产出的 onClick → service.send({ type: TRIGGER.CLICK }) → 状态机 closed → open行为原语锁滚动、建焦点域、压入层栈浮层再请定位引擎算坐标 → 适配器重读 connect把新的 aria-* />三、状态机很薄规矩不少状态机运行时自研、零依赖。states里只能用字符串引用具名的动作、守卫和副作用写内联函数或引用不存在的名字createMachine当场抛错开发和生产一致。这样状态图本身是可静态分析的数据测试能直接算转移覆盖率。受控与非受控收在cell一处value:cellstring[](()({value:prop(value),// 传了就是受控组件只调 onChange 通知你defaultValue:prop(defaultValue)??[],// 只传它就是非受控组件自己持有onChange:valueprop(onValueChange)?.({value}),})),浮层开关走“意图加回写”受控时点触发器只发open-change你写回open状态机才转移。服务没有直接改状态的入口状态只能由事件驱动所以永远能用一串事件复现跨端一致性测试靠的就是这一点。副作用装配是事务化的一批 effect 中后一项初始化失败前面拿到的资源按逆序全部释放回滚异常和原始异常一起放进AggregateError。浮层打开时“登记层、消隐层、焦点域、滚动锁、背景失活”就在同一个事务里失败不会留下一个永远占着栈顶的半成品。四、三端一致是测出来的框架无关的组件库最常见的病是各适配器慢慢走样。这里每个组件有一份零框架的一致性规格三个适配器各实现一个 harness运行器逐帧采集归一化后的 DOM 快照比对id 的具体值和data-v-*被抹掉aria-controls这类引用翻译成part(...)抹完必须逐字相同。还有抹不掉的差异说明抽象漏了要改的是库不是测试。每个适配器也有自己的坑。React 的 props 变化不经过可订阅的源推式依赖追踪会让所有track静默失效所以 React 运行时改成每次提交后逐项比对flush用flushSyncpointerenter不冒泡、合成事件上没有stopImmediatePropagation()这类处理器改挂原生监听有门禁逐组件核对全局配置的代理实现了ownKeys否则{ ...props }一展开默认值就没了。Web Components 选的是 Light DOM 行为宿主元素不渲染结构只找到作者写的角色节点写入属性和事件。不用 Shadow DOM是因为它会封住结构、挡住外部 CSS表单关联和跨边界的aria-*引用都要额外机制。代价是结构得自己写所以有校验作者写data-xh-part声明接线后写data-part事实分得清“写了但没接上”。缺必备部件报wc.missing-part标签用错报wc.wrong-part-tag比如表单的label写成divfor关联会静默失效。布尔属性是三态的缺席、false、其余各不相同角色节点真的进出才重新接线脚本到达前用:not(:defined)先收起浮层子树免得裸文本被搜索引擎当正文包里还附带custom-elements.json给编辑器补全。五、无障碍每个组件一张键盘规格表每个组件有一份机读的键盘规格表exportconstaccordionKeyboard:KeyboardTable{component:accordion,source:https://www.w3.org/WAI/ARIA/apg/patterns/accordion/#keyboardinteraction,rows:[{id:accordion.kbd.toggle,keys:[Space,Enter],when:focus in trigger, not disabled,does:展开/收起该条目的 content},// …],};测试用例通过covers反查行 id少覆盖一行套件就失败文档站的键盘表也由它渲染。想让测试通过只能补用例不能改分母。几处 ARIA 处理禁用项仍需可聚焦时用aria-disabled不用会让元素失焦的原生disabled手风琴按 APG 规定不做 roving tabindex方向键的轴向和 RTL 换向收在一处不属于导航的按键一律不preventDefault。输入法组合期的按键单独识别这条对中文用户格外重要拼音输入时的回车是在确认候选词所以提示输入框里组合中的 Enter 一律放行。焦点环向内收一个环宽聚焦前后占位不变。环内收以后紧挨着它的是元素自己的面WCAG 2.2 要求 3:1而实心面上品牌色的环能低到 1:1这些档位的环改取该面配对的前景色。环也不随语气变色warning 色对白底只有 2.70:1。这条由静态计算和真实 Chromium 逐档实测两道门禁一起守两边的分母还要互相对账。axe 扫描同样跑在真实 Chromium 里明暗各一遍存量违规登记成表某条不再命中就判定登记过期必须删掉。同一份皮肤还要在紧凑密度、RTL、粗指针命中区至少 44×44px、减弱动效、减少透明度、强制色和打印下都成立。六、浮层最容易出 bug拆得最细点外面关闭、焦点陷入、背景禁止滚动这些在 core 里实现一次所有浮层调用。浮层叠成一个栈。每层要登记branches逻辑属于本层、DOM 在别处的节点比如 portal 出去的子菜单漏了的话点子菜单会关掉父层和surfaces遮罩这类点了要关本层的面。层级由逻辑栈派生不靠各组件拿静态z-index去猜。只有栈顶响应 Esc。Esc、点外部、焦点移出都会派发一张可取消的表决票preventDefault()即否决表单没填完先弹个确认不用绕开组件实现。触屏上 pointerdown 只建立候选同一目标上的 click 到来才提交中途一滚动就作废在手机上划页面不会误关浮层。滚动锁是引用计数的让出来的滚动条宽度写在--xh-scroll-lock-gutter上fixed顶栏读它就不会在弹窗打开时跳一下。背景失活给其余子树加inert。退场动画用租约等浏览器真正创建的动画对象播完再卸载不写死超时焦点则在逻辑关闭那一刻就交回触发器。定位引擎也是自研的十二种方位、主轴放不下自动翻面、交叉轴沿边推回并留 4px 余量支持虚拟锚点。状态机传给引擎的strategy、内联position、皮肤里的position三处必须一致否则整族浮层偏移一个滚动距离还不报错有门禁专门核对。首帧坐标未定时浮层默认visibility: hidden引擎回报坐标后才显示不会在左上角闪一下用 visibility 不用 display是因为后者会让元素退出排版量不到尺寸。浮层 portal 到 body 后会把来源处的主题、品牌、密度、动效、书写方向连同祖先上声明的 CSS 变量一起投到实例壳上局部深色区里弹出的菜单还是深色。组件私有槽不跨 Portal表格斑马行改写的底色不会漏进行里的下拉菜单。子菜单用安全三角指针斜着移过去途中扫过别的条目子菜单不会被切走。七、指针与手势跟手交互要同时做对四件事监听挂在 document 上处理pointercancel第二根手指不能劫持会话卸载时清干净监听。漏一条就是只在真机上偶发的 bug。xihan-ui/pointer把这四条一次做对压缩后 2.04 kB滑块、分栏、取色器、签名板、轮播、排序、表格、树都走它。双指缩放相对起始那一刻计算避免逐帧累乘积累浮点误差拖放落点按中心是否越过判定不按矩形相交项高不一时后者会来回跳几何一律取按下时的快照避免让位之后自激振荡激活阈值用直线距离斜着拖 4px 4px 实际是 5.7px分轴比较会误判成没动。八、主题一个控制器八条轴令牌源是 DTCG 格式的 JSON产物提交进仓库CI 重新生成后比对。颜色一律写成oklch同明度不同色相看起来一样亮所以整套色板只定一条明度曲线任何色相的 700 档铺白字都过 4.5:1深色主题沿同一条曲线反向取档。令牌分原语、语义、组件覆盖槽三层皮肤只能消费语义层。createVisualEnvironmentController统一管理明暗、品牌、密度、书写方向、对比度、动效、透明度、材质八条轴constvisualcreateVisualEnvironmentController({root:document.documentElement,storageKey:app-visual-environment,onStorageError:detailconsole.error(视觉偏好持久化失败,detail),initial:{mode:system,motion:system,transparency:system},});visual.setPreference({mode:dark,density:compact});它最终投影成html>九、皮肤纯 CSS可以整套扔掉xihan-ui/styles不依赖任何 JS。层序是xihan.reset, xihan.tokens, xihan.motion, xihan.components, xihan.overridesreset 只作用于带data-scope的库节点、特指度为 0和现有页面共存不用隔离。改样式有三种粒度优先用前两种直接写死的规则会绕开令牌深色和密度切换随之失效:root{--xh-shape-control:var(--xh-radius-md);}/* 改语义令牌影响全库 */:root{--xh-button-h:40px;}/* 改组件覆盖槽只影响一类组件 */layerxihan.overrides{/* 直接写规则 */[data-scopebutton][data-partroot]{text-transform:uppercase;}}CSS 级联有条容易忽略的规则无层声明胜过任何有层声明与特指度无关。宿主一条无层的button { padding: 0 }就能把皮肤压成裸元素Tailwind v3 的 preflight、normalize.css、VitePress 都是这种无层重置。XiHan.UI 自己的文档站就撞上过所以包里另提供一份同源生成的index.unlayered.css规则改按特指度竞争。全量皮肤压缩后约 130 kB按需引入时漏引一份是静默的开发期可以开startSkinCheck()它会报出缺哪份、该怎么 import。每个部件归入六个家族之一Action Control、Field Chrome、Collection Item、Surface、Overlay、Feedback。Select 的 trigger、option、content 分属三个家族同族成员的同类部件由门禁逐条比对必须同值。几条全库规则圆角只有 4 / 8 / 12px 三档外加 pill 和 circle只有 Button 默认品牌实心离散控件按下 120ms 缩到 0.97、释放 200ms 回来整行条目只换底色但不允许零反馈边界只由描边承担字段默认 16rem 宽、压缩底线 12rem禁用不能只降 opacity。皮肤最怕写错不报错引用一个不存在的令牌名整条声明会在计算值阶段静默失效。对应的门禁有查孤儿令牌、查未命名的共享字面量、查声明了却没接线的部件、查永远选不中节点的遗留规则。data-tone也能用在自己的节点上取到整族--xh-tone-*语气色随明暗和品牌一起切。完全不要默认皮肤也行组件只往 DOM 写属性开合一律是data-stateopen | closed布尔状态为真时属性存在。十、动效、声音和背景xihan-ui/motion的缓动和时长与令牌同源有门禁双向比对。JS 动画用readMotion(el)从元素上读实际生效的令牌不写死毫秒resolveEasing认不出的写法直接抛错不悄悄按匀速播放。弹簧用解析解任意时刻 O(1) 可算能烘焙成 CSS 的linear()交给浏览器沉降时长与 0.1ms 步长的龙格-库塔积分逐点比对过核心组件只用超调不超过 3% 的预设。减弱动效只有一条通道最近祖先的data-motion其次是应用级 override最后是系统设置。降级是去掉位移、保留 120ms 淡变有进场就有退场初始内容不播进场。xihan-ui/animations里的动画是一份可以 JSON 序列化的配方播放前校验不合法直接拒播。其中一条来自 WCAG 2.3.1任意一秒内闪烁不超过三次。splitText按码点拆字原文写进aria-label免得读屏逐字念。xihan-ui/sound没有任何音频文件提示音在播放的那一瞬间用振荡器和噪声合成整包不到 5 kB内置清亮、极简、柔和三套主题。withNotificationSound(toast)包一层就能给通知配声调用点不用改浏览器自动播放策略挂起时只保留最近一声单个元素配声挂在click上键盘激活也会发声按下后拖开取消的不发声。xihan-ui/backgrounds是 WebGL2 背景效果极光、星云、流体、星空等WebGL2 不可用时降级成 CSS 背景。滚出视口自动暂停、减弱动效下冻结页面开十个效果也只有一条共享的 rAF 循环。文字、图片、SVG 都能采样成点云让粒子排成“曦寒”两个字再形变到别的形状。十一、组件挑些细节说组件按通用、布局、导航、数据录入、数据展示、图表、反馈、浮层、AI 对话分类每个都有内核、三端组件和皮肤。挑几处Select 只负责从固定选项里选要边输入边筛选用 Combobox筛选结果由调用方掌管多选显示为标签行最多 3 枚其余折成N。日期分两条路已知日期用可键入的分段日期框需要浏览用日历选择器min/max可以精确到时刻。TextField 的字数按字素算组合 emoji、国旗都算一个字NumberField 长按会加速FileUpload 支持粘贴上传和并发排队Mention 插入的引用按整体删除SignaturePad 输出 SVG可撤销重做ColorPicker 支持oklch、屏幕取色和最近使用色。Table 支持排序、选择、展开、吸顶、冻结列、合并单元格、表头分组、树形级联勾选和拖动列宽。Virtualizer 已接进树、列表、下拉、表格和日志只渲染可见行但键盘、检索、选择和读屏念的“第几项共几项”都按完整集合计算。Tabs、Toolbar 放不下时自动出现“更多”下拉面包屑的折叠位可用键盘就地展开Anchor 平滑滚动途中高亮锁定直到滚动停稳Tour 的目标还没挂载时会先等它出现。Carousel 悬停、聚焦、滚出视口或页面转入后台都会暂停拖拽松手按速度判定翻页并由弹簧落位ImageViewer 拖出图片范围有阻尼、快甩有惯性Progress 加上分段色带、目标刻度和指针就是仪表盘与子弹图。Dialog 可以拖标题栏Drawer 可以拖动或用方向键调厚度按钮在途时加载环压在按钮上、宽度不变短请求不会闪Watermark 节点被删掉会原位放回二维码中心的 logo 挖掉的码字超过纠错能力时会报诊断。提示延迟、轮播间隔、轻提示停留这类“等待”不归动效管由组件属性给缺省值Tooltip 700 / 300ms子菜单 100 / 300ms卡片通知 5000ms轻提示 4000ms。减弱动效不会让提示更早消失唯一的例外是自动播放减弱动效下轮播不自己起播。十二、AI 对话读流、收敛状态、增量渲染拆成三个不碰 DOM 的包。xihan-ui/chat-stream的链路是 SSE 读取 → 协议归一 → parts 归约 → 会话 store。传输层是一个接口stream()不抛异常错误在流的边界转成事件。一条消息由正文、思维链、工具调用、文件、引用来源等 part 组成增量按块键回到原位工具调用先到参数后到结果也不会错位。会话按树来存每条消息记着自己的父消息conststorecreateThreadStore({transport:createHttpSseTransport({url:/api/chat})});store.submit(你好);store.regenerate(messageId);// 同一提问再要一条回复原回复留作分支store.edit(messageId,改过的问题);store.retry();// 撤掉失败的回复重新发起不产生分支store.stop();// 保留已产出的内容这条记为 abortedstore.continue();// 在截断处接着写selectBranch用来做“‹ 2 / 3 ›”切换getTree()导出整棵树可恢复会话非法操作立即报错。帧批处理把一帧内的增量合并成一次通知打字机把网络抖动摊平成匀速输出。xihan-ui/markdown每次接收截至当前的全文已定型的前缀块冻结只解析尾巴生长中的块 key 恒为live框架复用同一份 DOM用户的选区和滚动位置不会丢。消毒在解析器内部完成不透传原生 HTML所以直接v-html是安全的。没写完的**粗先按闭合显示半截链接只显示文字流结束后再严格解析。它是 CommonMark 的子集官方用例通过 489/65275.0%刨掉按设计不支持的两节原生 HTML 是 82.0%仓库里有棘轮盯着只许升不许降。xihan-ui/code-highlight只区分注释、字符串、数字、关键字、标点五类。不内置 Shiki是因为几百 kB 的语法数据对偶尔出现一段代码的场景不成比例着色器是端口需要更高精度时把 Shiki 接进来组件一行不用改。对话组件按职责拆开PromptInput处理输入法发送与停止共用一颗按钮、MessageFeed粘底跟随、播报区、未读数、ToolCall运行时展开、结束收起手动开合过一次就不再自动等待批准的闸门常驻不会被折叠藏起来、Reasoning显示已经想了几秒、Approval超时按拒绝授权范围与判定原子提交、QuestionFlow一次一题末题不替用户提交、Citation、CodeView、DiffView支持行评论和 Log支持 ANSI 着色。十三、图表零依赖的引擎最近一个大版本带来了xihan-ui/viz比例尺、刻度、布局、拾取、降采样全是纯函数。CartesianChart 一个组件覆盖柱、条、堆叠、瀑布、折线、面积、散点、K 线、箱线和小提琴支持参考线、趋势线、Ctrl / ⌘ 滚轮与双指缩放、刷选和多图联动另有饼图、漏斗、雷达、桑基、关系图五种布局、层级图矩形树图、旭日图等可逐层下钻、迷你图和热力图。标记超过 3000 个时数据层自动切到画布键盘、读屏、主题和打印不受影响列式数据仓配合降采样百万点仍然流畅实时追加会合并到同一帧刷新。无障碍没有省绘图区只占一个 Tab 位方向键在数据点之间移动还会自动生成视觉隐藏的摘要和数据表。分类色亮暗各八支过了对比度和色弱区分校验超过八个系列会报诊断强制色和打印下改用纹理区分系列双 y 轴是刻意不提供的。十四、表单、日期与国际化复合控件给了name就会生成表单影子随form一起提交没勾选的 checkbox 不进FormData与原生一致。form.reset()时组件按当下的 props 回到默认值受控组件要响应重置必须传defaultValue否则组件的空值会被当默认值发出去“重置”就成了“清空数据”。参与表单的组件名单由门禁从源码里扫新组件没接重置会被拦下来。日期运算是自研的xihan-ui/core/date命名沿用 Temporal。之所以自己写是因为日期的边界情况错一处就会有某一天错位1 月 31 日加一个月是 2 月 28 日Date表示时刻不是日期跨夏令时会差一小时周首日按地区不同美国周日、中国周一、埃及周六2027-01-01 属于 2026 年的第 53 周。周规则按 CLDR 查表不问各浏览器实现不一的Intl.Locale#getWeekInfo值对象写a b会直接抛错。PlainDate.from(2026-01-31).add({months:1}).toString();// 2026-02-28today(Asia/Shanghai).toString();// 上海此刻的日期内建文案默认英文日期组件跟随locale解析顺序是实例 props → 全局配置 → 浏览器语言 →en-US。中文项目在根组件调用一次provideXhConfig({ locale: zh-CN, translations })即可按键合并传 ref 还能运行时切换。服务端渲染要在两端注入同一个locale否则月历会水合不一致。十五、命令式服务删除前确认、保存后提示这类反馈一次调用弹出最省事。库里有对话框、通知、顶部进度条三个服务工厂constokawaitdialog.confirm({title:删除这条记录,tone:danger,okText:删除,onOk:()api.remove(id),// 返回 Promise 时按钮自动加载失败不关闭});constidtoast.loading(正在上传…);awaitupload(file);toast.update(id,{loading:false,tone:success,title:上传完成});toast.info(已删除 3 条记录,{actionLabel:撤销,onAction:()restore()});对话框多次调用会排队前一个退场完才弹下一个。通知分轻提示和卡片两种预设从加载中到完成是同一条通知就地改写dedupe: content让连发的报错显示成「同步失败 ×2」超出上限时先挤掉低优先级的。进度条用在途计数写成布尔开关的话三个并发请求里第一个返回它就收起了。文档里还有一条建议可撤销的操作别弹确认框直接执行再给一条带“撤销”按钮的轻提示。十六、零第三方运行时依赖除宿主框架本身所有库包的运行时都不引入第三方依赖。日期、浮层定位、代码着色、Web Components 响应式基类、Markdown、状态机和图表引擎全是自研常见的同类选择分别是 date-fns、Floating UI、Shiki、Lit、markdown-it、XState 和各类图表库。代价是每一块都要自己证明是对的所以测试里拿成熟的响应式基类对拍自研版、用 CommonMark 官方用例集测渲染器这些依赖只在测试里出现。新增运行时依赖要登记白名单写明理由和移除条件分层依赖由 dependency-cruiser 强制全部 ESM体积有棘轮把关。图标是结构化记录渲染时逐节点创建元素运行期不解析 SVG 字符串也就不存在写innerHTML的路径。npx xihan-icons svg目录能把任意图标集转成同样的模块转换时丢掉class和onclick碰到script、use直接报错跳过。十七、工程上的几道门pnpm gate按包与依赖、令牌、皮肤、视觉、浮层、动效、无障碍、适配器、文档、仓库十个模块执行前面提到的检查基本都在里面。除此之外还有几道像素基线在固定的 Playwright Linux 容器里生成字体钉死为 DejaVu SansWindows 上用 Docker 跑出来的结果和 CI 逐像素一致PR 里改了基线图片要逐张说明、逐张审。视觉性能预算磨砂对话框在 4 倍 CPU 降速下逐帧跑统计帧间隔、长任务和 DOM 留存报告不编造内存数字。公开面基线覆盖 JS 导出、解剖属性、状态属性、CSS 变量、自定义元素标签五种介质删名或改名都判失败。所有包始终同号发布破坏性变更直接升主版本不留别名也不留兼容层。组件契约问题投递到诊断通道带稳定的code、组件、部件和节点开发期打印生产环境静默零开销。文档站会生成llms.txt等给 AI 读的纯文本每页地址后缀改成.md就能拿到 Markdown仓库根有设计、开发、三端适配三份 Agent Skills。还有个小彩蛋在vite.config.ts里挂上xihanUiBanner()开发服务器启动时终端会打出彩虹色的 Logo 和两句诗碧落降恩承淑颜共挚崎缘挽曦寒。 迁般故事终成忆谨此葳蕤换思短。十八、它在哪儿被用着XiHan.BasicApp 的前端整体用 XiHan.UI 重建这是它在真实业务里的第一个大体量消费方。文档站另有一册“场景示例”把后台壳、表单页、数据页、对话页整屏摆出来都是真组件没有一处裸色值也没有一个写死的毫秒数。十九、最后XiHan.UI 是曦寒懿XiHanFun开源生态的前端基座同一生态里还有XiHan.Framework快速、轻量、高效、用心的 .NET 现代模块化开发框架。是面向企业级应用的模块化后端框架框架优先使用 .NET 原生功能减少第三方依赖理念现代、开箱即用、模块清晰、依赖可控、扩展可维护。曦寒懿XiHanFun开源生态的后端基座。XiHan.BasicApp基于 XiHan.Framework 和 XiHan.UI 的超高颜值通用中后台内核。开箱即用提供 RBAC ABAC 混合权限管理、多租户隔离、代码生成、实时通信、灰度发布、AI等核心能力满足新型企业级中后台管理场景。属于曦寒懿XiHanFun开源生态的基础应用。本地跑起来看看需要 Node.js 24、pnpm 11gitclone https://github.com/XiHanFun/XiHan.UI.gitcdXiHan.UI/uipnpminstall--frozen-lockfilepnpmbuildcd../docspnpminstallpnpmdev项目采用 MIT 授权。组件状态图与 ARIA 接线参考了 Zag.js 的规格无障碍交互依据 W3C APGMarkdown 以 CommonMark 规范为判据无障碍扫描用的是 axe-core在此一并致谢。欢迎提 Issue 和 PR觉得有用的话点个 Star 就是很大的鼓励。文档站https://ui.docs.xihanfun.com生态门户https://docs.xihanfun.com
返回列表