# UI框架 **Repository Path**: bingbingyihao/ui-framework ## Basic Information - **Project Name**: UI框架 - **Description**: No description available - **Primary Language**: JavaScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-23 - **Last Updated**: 2026-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Focus UI **聚焦 5 个高频交互组件的 Vue 3 组件库**,内置 **黑白灰极简 / 暖色系 / 冷色系** 三套主题。 不做大而全的组件库。绝大多数业务页面反复用到的其实只有这几个: **Dialog(对话框)、Confirm(确认框)、Message(消息提示)、Select(下拉)、DatePicker(日期选择)** —— 而它们恰恰是原生控件最不好用、各平台差异最大、最影响"整体质感"的五个。 所以这里只把它们做透:每个都能独立拿走用,且共享同一套设计令牌。 ``` ┌─ 组件 ────────────────────────────────────────────────────────────┐ │ FxSelect 单选 / 多选 / 搜索 / 分组 / 色点 / 清除 / 键盘 │ │ FxDatePicker 单选 / 区间 / 日-月-年三级视图 / 快捷预设 / 格式化 │ │ FxDialog 遮罩 / Esc / 焦点陷阱 / 锁滚动 / 命令式 openDialog │ │ FxConfirm 命令式 confirm() → Promise,支持异步校验 │ │ message 命令式 message.success / error / warning / loading │ │ FxButton 统一按钮(弹窗 / 提示内部与业务页共用) │ └─ 主题 ────────────────────────────────────────────────────────────┘ data-theme="mono" | "warm" | "cool" → 只换令牌,组件代码零改动 ``` ## 快速开始 ```bash npm install npm run dev # http://127.0.0.1:5175/ 演示页(顶栏可切三套主题) ``` ### 在别的工程里使用 本仓库是「组件源码 + 演示页」,没有发布到 npm。要复用的东西只有两处: ``` src/ui/ 组件本体(不含任何 demo 代码) src/styles/ tokens.css / themes.css / base.css ``` 把它们拷进你的工程,或作为本地依赖(`"focus-ui": "file:../ui-framework"`)后: ```js // main.js —— 样式顺序不能反:基线里会用主题令牌,必须在其之后解析 import 'focus-ui/styles/tokens.css' // 结构令牌:字体 / 间距 / 动效 / 层级 import 'focus-ui/styles/themes.css' // 三套主题令牌 import 'focus-ui/styles/base.css' // reset + 原生控件归一化 import FocusUI from 'focus-ui' createApp(App).use(FocusUI) // 方式一:全量注册(FxSelect / FxDialog ...) // 方式二:按需引入(推荐) import { FxSelect, confirm, message, setTheme } from 'focus-ui' ``` > 主题令牌挂在 `:root` 上,所以**必须**引入 `themes.css` 才能拿到颜色; > 不想全量引 `base.css` 也行,但它负责把原生 `select / input / textarea` 归一化, > 少了它页面里会出现"自绘组件很精致、旁边原生控件很土"的割裂感。 ## 三套主题 ```js import { setTheme } from 'focus-ui' setTheme('warm') // mono | warm | cool // 等价于: document.documentElement.dataset.theme = 'warm' ``` **三套主题的差异不只是色相** —— 圆角、阴影、边框强度、字重都在变。 只换颜色的话,三套主题看起来会像同一个东西换了皮: | | 黑白灰极简 `mono` | 暖色系 `warm` | 冷色系 `cool`(默认) | | -------- | ---------------------- | -------------- | --------------------- | | 主色 | `#18181b` 近黑 | `#c2410c` 橙 | `#2563eb` 蓝 | | 页面底色 | `#f5f5f6` | `#fdf8f2` 暖白 | `#f4f7fc` 冷白 | | 圆角 md | `6px` 小硬 | `12px` 大柔 | `10px` 中 | | 阴影 | 几乎不投影,靠"线"分层 | 柔和暖阴影 | 清晰冷阴影 | | 边框 | 对比更强(`#b9b9c0`) | 压得很淡 | 中性 | | 强调字重 | `700` | `600` | `600` | | 危险色 | 仍保留红(语义不能丢) | 砖红 | 正红 | 两个配套能力: - **可以局部生效**。令牌挂在 `[data-theme]` 选择器上,所以任意元素都能套一套风格 —— 演示页的「主题与令牌」区块就是并排渲染了三套风格,不用来回切换。 ⚠️ 唯一的例外是 Teleport 到 `body` 的浮层(下拉面板 / 日历 / 弹窗),它们只跟随 `html` 上的主题。 - **令牌表读的是真实值**。演示页的令牌对照表是用游离探针元素 `getComputedStyle` 读出来的, 改了 `themes.css` 表格会跟着变,不存在"文档写了但代码没改"的偏差。 ### 令牌清单 组件样式只引用 `--fx-*`,因此换主题不需要动任何组件代码。 | 分类 | 令牌 | | -------- | -------------------------------------------------------------------------------------------- | | 表面层级 | `--fx-color-bg` → `--fx-color-surface` → `-2` → `-3` | | 描边 | `--fx-color-border`、`--fx-color-border-strong` | | 文本 | `--fx-color-text`、`-2`、`-3` | | 强调色 | `--fx-color-primary(-hover/-active/-weak/-contrast)`、`danger`、`success`、`warning`、`info` | | 遮罩 | `--fx-color-mask` | | 形状 | `--fx-radius-xs/sm/md/lg/full`、`--fx-shadow-1/2/3`、`--fx-ring` | | 质感 | `--fx-border-width`、`--fx-font-weight-strong` | | 结构 | `--fx-font-*`、`--fx-space-*`、`--fx-control-*`、`--fx-dur-*`、`--fx-ease`、`--fx-z-*` | 三套主题的令牌集合由 `npm run test:theme` 强制保持一致:**少写一个令牌就会回退到上一套主题的值**, 表现为"切了主题但某个角落没变",这类问题在页面上极难靠肉眼发现。 ## 组件 ### FxSelect 下拉选择 替代原生 `