iter(g129): 新增排版文本组件 typography
This commit is contained in:
@@ -1388,6 +1388,46 @@
|
|||||||
"acceptance": "npm run changelog 重新生成(329 提交),changelog:check 一致(提交本条后按约定再差一条,属正常);npm run check 全绿",
|
"acceptance": "npm run changelog 重新生成(329 提交),changelog:check 一致(提交本条后按约定再差一条,属正常);npm run check 全绿",
|
||||||
"notes": "自补:发版前刷新步骤;本次唤起收尾轮,顺带提交 g127 漏带的 llms-full.txt",
|
"notes": "自补:发版前刷新步骤;本次唤起收尾轮,顺带提交 g127 漏带的 llms-full.txt",
|
||||||
"status": "done"
|
"status": "done"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "g129",
|
||||||
|
"title": "新增排版文本组件 typography",
|
||||||
|
"motivation": "文档类页面(详情、说明、条款)目前只能手搓 h/p + 内联样式,标题层级、语义色、多行省略、复制都没有统一入口",
|
||||||
|
"acceptance": "typography 支持 variant(title/text/paragraph) + level + type + 装饰位(strong/underline/delete/mark/code) + align + ellipsis 多行截断 + copyable;标题出语义 h1-h5;样式只消费 --ua-*;manifest/docs/README/demo/llms-full 同步;npm run check 全绿",
|
||||||
|
"status": "open",
|
||||||
|
"notes": "自补:组件补充方向"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "g130",
|
||||||
|
"title": "新增栅格布局 row / col",
|
||||||
|
"motivation": "页面骨架只能靠 space 与手写 flex,24 栅格、列间距、响应式断点缺失,示例页布局各写一套",
|
||||||
|
"acceptance": "row 提供 gutter 列间距与 justify/align,col 提供 span/offset 与 sm/md 断点;窄屏自动堆叠;样式只消费 --ua-*;文档与演示同步;npm run check 全绿",
|
||||||
|
"status": "open",
|
||||||
|
"notes": "自补:组件补充方向"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "g131",
|
||||||
|
"title": "新增悬浮操作按钮 floatButton",
|
||||||
|
"motivation": "backTop 只能回顶,页面里「新建 / 帮助 / 客服」这类常驻悬浮入口没有统一件,各处自己 fixed 定位",
|
||||||
|
"acceptance": "floatButton 固定右下角,支持 icon/label/tooltip/badge/点击回调与 position 偏移,键盘可达;样式只消费 --ua-*;文档与演示同步;npm run check 全绿",
|
||||||
|
"status": "open",
|
||||||
|
"notes": "自补:组件补充方向"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "g132",
|
||||||
|
"title": "@提及输入补 mentions 组件",
|
||||||
|
"motivation": "评论 / 协作场景要 @ 选人,目前只能 textarea + 自己接 autoComplete,光标定位与插入逻辑重复实现",
|
||||||
|
"acceptance": "mentions 在 @ 触发后按光标位置弹候选,↑↓/Enter/Tab 选择、Esc 关闭,选中插入文本并回调 onSelect;受控 value 信号;样式只消费 --ua-*;文档与演示同步;npm run check 全绿",
|
||||||
|
"status": "open",
|
||||||
|
"notes": "自补:组件补充方向"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "g133",
|
||||||
|
"title": "树形选择补 treeSelect 组件",
|
||||||
|
"motivation": "tree 与 select 都在,但「可搜索的层级下拉选择」缺位,级联选择 cascader 不适配任意深度懒加载场景",
|
||||||
|
"acceptance": "treeSelect 点击开弹层、支持搜索过滤、单选/多选、父子联动、清空,弹层沿用 overlay 的 Esc 栈与外部点击收起;样式只消费 --ua-*;文档与演示同步;npm run check 全绿",
|
||||||
|
"status": "open",
|
||||||
|
"notes": "自补:组件补充方向"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+88
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "ui-arch-registry-index/0.1",
|
"$schema": "ui-arch-registry-index/0.1",
|
||||||
"generatedAt": "2026-10-26T06:49:03.720Z",
|
"generatedAt": "2026-10-26T07:17:51.824Z",
|
||||||
"repoRoot": ".",
|
"repoRoot": ".",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
@@ -203,7 +203,8 @@
|
|||||||
"multiSelect(props):多选下拉,标签式回显 + 可搜索弹层,点选不收起便于连续多选,max 到限后未选项禁用",
|
"multiSelect(props):多选下拉,标签式回显 + 可搜索弹层,点选不收起便于连续多选,max 到限后未选项禁用",
|
||||||
"anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器",
|
"anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器",
|
||||||
"popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」",
|
"popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」",
|
||||||
"calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange"
|
"calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange",
|
||||||
|
"typography(props):排版文本,variant 决定语义(标题出 h1-h5 / 段落出 p / 行内出 span),支持语义色、装饰位、对齐、多行截断与复制按钮"
|
||||||
],
|
],
|
||||||
"keyTypes": [
|
"keyTypes": [
|
||||||
"ButtonProps",
|
"ButtonProps",
|
||||||
@@ -3075,6 +3076,91 @@
|
|||||||
"需要显示每天有几件事就传 marker:返回非空文案即渲染小徽标,并拼进 aria-label 让读屏也听得到",
|
"需要显示每天有几件事就传 marker:返回非空文案即渲染小徽标,并拼进 aria-label 让读屏也听得到",
|
||||||
"键盘:Tab 进入网格一次,←→ 逐日、↑↓ 逐周、Enter / 空格 选中;跨月会自动翻页并交接焦点"
|
"键盘:Tab 进入网格一次,←→ 逐日、↑↓ 逐周、Enter / 空格 选中;跨月会自动翻页并交接焦点"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "typography",
|
||||||
|
"title": "排版文本 Typography",
|
||||||
|
"demo": "sec-typography",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"n": "content",
|
||||||
|
"t": "string | Node",
|
||||||
|
"r": 1,
|
||||||
|
"d": "文本内容:字符串按纯文本渲染;传 DOM 则原样插入(此时不参与截断与复制)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "variant",
|
||||||
|
"t": "'title' | 'text' | 'paragraph'",
|
||||||
|
"df": "text",
|
||||||
|
"d": "排版形态,决定语义标签与字号:title 出 h1-h5、paragraph 出 p、text 出 span"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "level",
|
||||||
|
"t": "1 | 2 | 3 | 4 | 5",
|
||||||
|
"df": "3",
|
||||||
|
"d": "标题层级,仅 variant=title 生效;越界值会被夹到 1-5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "type",
|
||||||
|
"t": "'secondary' | 'success' | 'warning' | 'danger'",
|
||||||
|
"d": "语义色调;缺省主文本色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "strong",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "加粗强调"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "underline",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "下划线(可为链接式文案保留指引视觉)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "delete",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "删除线,用于作废文案;会同时弱化文字颜色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "mark",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "高亮底纹(警示色 24% 混透明),用于搜索命中片段"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "code",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "等宽代码样式,用于行内字段名 / 命令"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "align",
|
||||||
|
"t": "'left' | 'center' | 'right'",
|
||||||
|
"d": "水平对齐;缺省左对齐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "ellipsis",
|
||||||
|
"t": "number",
|
||||||
|
"d": "截断行数(1 起):超出显示省略号,纯文本自动挂 title 供悬停看全文;缺省不截断"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "copyable",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "右侧附复制按钮:点击写剪贴板并回显「已复制 / 复制失败」,1.2 秒后复原"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": "typography({ variant: 'title', level: 2, content: '部署说明' }); typography({ content: 'RB-2048', code: true, copyable: true }); typography({ variant: 'paragraph', ellipsis: 2, content: '一段很长的说明……' })",
|
||||||
|
"steps": [
|
||||||
|
"正文一律用 variant='text' 或 'paragraph',标题用 variant='title' + level,标签自动出 h1-h5,别自己写 h 标签再叠样式",
|
||||||
|
"文内强调用装饰位组合:strong 加粗、mark 高亮、code 等宽、underline / delete 表示链接与作废,一个组件内可叠加",
|
||||||
|
"长描述(卡片摘要、表格说明)用 ellipsis 给行数:超出显示省略号并自动挂 title,悬停即看全文,不必额外做展开按钮",
|
||||||
|
"订单号 / 密钥 / 命令这类要复制的内容传 copyable:按钮独立于文本节点,复制失败会回显「复制失败」而不是静默",
|
||||||
|
"content 传 DOM 时组件只负责语义标签与类名:截断与复制对 DOM 内容不生效(取不到稳定文本)",
|
||||||
|
"段落连续排列时相邻 .ua-type-paragraph 自动留出间距,单个段落不额外撑高,嵌进卡片也不会有空隙"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
- `packages/core/table-core`(@ui-arch/table-core):Headless 表格逻辑内核
|
- `packages/core/table-core`(@ui-arch/table-core):Headless 表格逻辑内核
|
||||||
- `packages/core/frame`(@ui-arch/frame):signal + hyperscript 微框架
|
- `packages/core/frame`(@ui-arch/frame):signal + hyperscript 微框架
|
||||||
- `packages/skin/ui`(@ui-arch/ui):60 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
- `packages/skin/ui`(@ui-arch/ui):61 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
||||||
- `packages/design/tokens`(@ui-arch/tokens):设计令牌
|
- `packages/design/tokens`(@ui-arch/tokens):设计令牌
|
||||||
- `packages/tools/cli`(@ui-arch/cli):`ua` 命令行 + MCP 注册表服务(private)
|
- `packages/tools/cli`(@ui-arch/cli):`ua` 命令行 + MCP 注册表服务(private)
|
||||||
- `apps/demo`(@ui-arch/demo):交互演示,产物 apps/demo/dist/demo.html
|
- `apps/demo`(@ui-arch/demo):交互演示,产物 apps/demo/dist/demo.html
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ ui-arch-mvp/
|
|||||||
│ │ ├── table-core/ # 表格状态内核
|
│ │ ├── table-core/ # 表格状态内核
|
||||||
│ │ └── frame/ # 信号 + hyperscript 微框架
|
│ │ └── frame/ # 信号 + hyperscript 微框架
|
||||||
│ ├── skin/ # 皮肤层(DOM 组件,可发布)
|
│ ├── skin/ # 皮肤层(DOM 组件,可发布)
|
||||||
│ │ └── ui/ # 60 个组件 + ui.css
|
│ │ └── ui/ # 61 个组件 + ui.css
|
||||||
│ ├── design/ # 资产层(可发布)
|
│ ├── design/ # 资产层(可发布)
|
||||||
│ │ └── tokens/ # --ua-* 设计令牌
|
│ │ └── tokens/ # --ua-* 设计令牌
|
||||||
│ └── tools/ # 工程层(private,不发布)
|
│ └── tools/ # 工程层(private,不发布)
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ npm run docs # 生成人类文档站 apps/docs/index.html + Agent 全
|
|||||||
npm run changelog # 依据 git 提交史重写 CHANGELOG.md(发版前跑;changelog:check 可查漂移)
|
npm run changelog # 依据 git 提交史重写 CHANGELOG.md(发版前跑;changelog:check 可查漂移)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 组件(共 60 个)
|
## 组件(共 61 个)
|
||||||
|
|
||||||
<!-- ua:components -->
|
<!-- ua:components -->
|
||||||
accordion · affix · alert · anchor · autoComplete · avatar · backTop · badge · breadcrumb · button · calendar · carousel · card · cascader · checkbox · checkboxGroup · colorPicker · dataTable · datePicker · descriptions · divider · drawer · empty · form · image · inputNumber · list · menu · modal · multiSelect · notification · pagination · popover · popconfirm · progress · radioGroup · rate · result · segmented · select · skeleton · slider · space · spinner · splitter · statistic · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip · tour · transfer · tree · upload · watermark
|
accordion · affix · alert · anchor · autoComplete · avatar · backTop · badge · breadcrumb · button · calendar · carousel · card · cascader · checkbox · checkboxGroup · colorPicker · dataTable · datePicker · descriptions · divider · drawer · empty · form · image · inputNumber · list · menu · modal · multiSelect · notification · pagination · popover · popconfirm · progress · radioGroup · rate · result · segmented · select · skeleton · slider · space · spinner · splitter · statistic · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip · tour · transfer · tree · typography · upload · watermark
|
||||||
<!-- /ua:components -->
|
<!-- /ua:components -->
|
||||||
|
|
||||||
分组:表单(button / textField / inputNumber / textarea / checkbox / checkboxGroup / colorPicker / switchButton / select / multiSelect / radioGroup / slider / rate / autoComplete / datePicker / segmented / upload / form + formItem / transfer / cascader)、反馈(alert / toast / notification / result / spinner / progress / skeleton / badge / empty / statistic)、浮层(tooltip / popover / popconfirm / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper / tree / anchor)、数据展示(dataTable / descriptions / card / list / timeline / tag / avatar / image / carousel / calendar)、其他(space / divider / splitter / backTop / affix / tour / watermark)。
|
分组:表单(button / textField / inputNumber / textarea / checkbox / checkboxGroup / colorPicker / switchButton / select / multiSelect / radioGroup / slider / rate / autoComplete / datePicker / segmented / upload / form + formItem / transfer / cascader)、反馈(alert / toast / notification / result / spinner / progress / skeleton / badge / empty / statistic)、浮层(tooltip / popover / popconfirm / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper / tree / anchor)、数据展示(dataTable / descriptions / card / list / timeline / tag / avatar / image / carousel / calendar / typography)、其他(space / divider / splitter / backTop / affix / tour / watermark)。
|
||||||
|
|
||||||
## 可访问性约定
|
## 可访问性约定
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ accordion · affix · alert · anchor · autoComplete · avatar · backTop · ba
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `packages/core/frame` | @ui-arch/frame:signal / computed / effect + hyperscript(无虚拟 DOM) |
|
| `packages/core/frame` | @ui-arch/frame:signal / computed / effect + hyperscript(无虚拟 DOM) |
|
||||||
| `packages/core/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) |
|
| `packages/core/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) |
|
||||||
| `packages/skin/ui` | @ui-arch/ui:60 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
| `packages/skin/ui` | @ui-arch/ui:61 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
||||||
| `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) |
|
| `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) |
|
||||||
| `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server |
|
| `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server |
|
||||||
| `apps/demo` | 交互演示(esbuild 打包成单文件) |
|
| `apps/demo` | 交互演示(esbuild 打包成单文件) |
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import {
|
|||||||
toast,
|
toast,
|
||||||
tour,
|
tour,
|
||||||
tooltip,
|
tooltip,
|
||||||
|
typography,
|
||||||
} from '@ui-arch/ui';
|
} from '@ui-arch/ui';
|
||||||
import type { RowKey } from '@ui-arch/ui';
|
import type { RowKey } from '@ui-arch/ui';
|
||||||
|
|
||||||
@@ -1252,6 +1253,42 @@ const content = h(
|
|||||||
}),
|
}),
|
||||||
h('span', { class: 'out' }, () => `当前选中:${calDay() || '无'}`),
|
h('span', { class: 'out' }, () => `当前选中:${calDay() || '无'}`),
|
||||||
),
|
),
|
||||||
|
section(
|
||||||
|
'sec-typography',
|
||||||
|
'排版文本',
|
||||||
|
'typography 一个入口覆盖标题 / 正文 / 行内三种形态:variant 决定语义标签(标题出 h1-h5,读屏可按层级跳读),装饰位可叠加,长描述用 ellipsis 截断并自动挂 title 看全文,copyable 给订单号这类要复制的字段。',
|
||||||
|
card({ title: '标题层级' },
|
||||||
|
typography({ variant: 'title', level: 3, content: '订单详情' }),
|
||||||
|
typography({ variant: 'title', level: 5, content: '第三节:配送与售后' }),
|
||||||
|
typography({ variant: 'paragraph', type: 'secondary', content: '标题按 level 出 h1-h5,字号由样式表按标签给,这里没写任何内联字号。' }),
|
||||||
|
),
|
||||||
|
card({ title: '行内装饰' },
|
||||||
|
typography({
|
||||||
|
variant: 'paragraph',
|
||||||
|
content: h('span', null,
|
||||||
|
'本周新增 ',
|
||||||
|
typography({ content: '2', strong: true, type: 'success' }),
|
||||||
|
' 个组件,门禁命令 ',
|
||||||
|
typography({ content: 'npm run check', code: true }),
|
||||||
|
',搜索命中 ',
|
||||||
|
typography({ content: '排版', mark: true }),
|
||||||
|
',已作废 ',
|
||||||
|
typography({ content: '旧接口', delete: true }),
|
||||||
|
'。'),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
card({ title: '截断与复制' },
|
||||||
|
typography({
|
||||||
|
variant: 'paragraph',
|
||||||
|
ellipsis: 2,
|
||||||
|
content: '这一段故意写得很长用来演示多行截断:组件把行数写进 CSS 变量交给 -webkit-line-clamp,超出的部分显示省略号,同时把全文挂到 title 上,鼠标停留即可读完,调用方不需要自己算宽度或加「展开」按钮。',
|
||||||
|
}),
|
||||||
|
space({ size: 'sm' },
|
||||||
|
typography({ content: 'RB-2048-0917-3355', code: true, copyable: true }),
|
||||||
|
typography({ content: '点右侧复制可写进剪贴板', type: 'secondary' }),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 引导漫游实例:根节点需挂到 body(fixed 定位,不参与布局)
|
// 引导漫游实例:根节点需挂到 body(fixed 定位,不参与布局)
|
||||||
|
|||||||
+36
-1
@@ -1,6 +1,6 @@
|
|||||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||||
|
|
||||||
> 自动生成于 2026-10-26T06:49:03.720Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
> 自动生成于 2026-10-26T07:17:51.824Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
@@ -1668,6 +1668,40 @@ const day = signal(''); calendar({ value: day, marker: (d) => (d === '2026-10-26
|
|||||||
|
|
||||||
现场演示:apps/docs/demo.html#sec-calendar
|
现场演示:apps/docs/demo.html#sec-calendar
|
||||||
|
|
||||||
|
### typography — 排版文本 Typography
|
||||||
|
|
||||||
|
参数:
|
||||||
|
|
||||||
|
- content(必填):string | Node —— 文本内容:字符串按纯文本渲染;传 DOM 则原样插入(此时不参与截断与复制)
|
||||||
|
- variant(默认 text):'title' | 'text' | 'paragraph' —— 排版形态,决定语义标签与字号:title 出 h1-h5、paragraph 出 p、text 出 span
|
||||||
|
- level(默认 3):1 | 2 | 3 | 4 | 5 —— 标题层级,仅 variant=title 生效;越界值会被夹到 1-5
|
||||||
|
- type:'secondary' | 'success' | 'warning' | 'danger' —— 语义色调;缺省主文本色
|
||||||
|
- strong(默认 false):boolean —— 加粗强调
|
||||||
|
- underline(默认 false):boolean —— 下划线(可为链接式文案保留指引视觉)
|
||||||
|
- delete(默认 false):boolean —— 删除线,用于作废文案;会同时弱化文字颜色
|
||||||
|
- mark(默认 false):boolean —— 高亮底纹(警示色 24% 混透明),用于搜索命中片段
|
||||||
|
- code(默认 false):boolean —— 等宽代码样式,用于行内字段名 / 命令
|
||||||
|
- align:'left' | 'center' | 'right' —— 水平对齐;缺省左对齐
|
||||||
|
- ellipsis:number —— 截断行数(1 起):超出显示省略号,纯文本自动挂 title 供悬停看全文;缺省不截断
|
||||||
|
- copyable(默认 false):boolean —— 右侧附复制按钮:点击写剪贴板并回显「已复制 / 复制失败」,1.2 秒后复原
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
typography({ variant: 'title', level: 2, content: '部署说明' }); typography({ content: 'RB-2048', code: true, copyable: true }); typography({ variant: 'paragraph', ellipsis: 2, content: '一段很长的说明……' })
|
||||||
|
```
|
||||||
|
|
||||||
|
手把手:
|
||||||
|
|
||||||
|
1. 正文一律用 variant='text' 或 'paragraph',标题用 variant='title' + level,标签自动出 h1-h5,别自己写 h 标签再叠样式
|
||||||
|
2. 文内强调用装饰位组合:strong 加粗、mark 高亮、code 等宽、underline / delete 表示链接与作废,一个组件内可叠加
|
||||||
|
3. 长描述(卡片摘要、表格说明)用 ellipsis 给行数:超出显示省略号并自动挂 title,悬停即看全文,不必额外做展开按钮
|
||||||
|
4. 订单号 / 密钥 / 命令这类要复制的内容传 copyable:按钮独立于文本节点,复制失败会回显「复制失败」而不是静默
|
||||||
|
5. content 传 DOM 时组件只负责语义标签与类名:截断与复制对 DOM 内容不生效(取不到稳定文本)
|
||||||
|
6. 段落连续排列时相邻 .ua-type-paragraph 自动留出间距,单个段落不额外撑高,嵌进卡片也不会有空隙
|
||||||
|
|
||||||
|
现场演示:apps/docs/demo.html#sec-typography
|
||||||
|
|
||||||
API 速览:
|
API 速览:
|
||||||
|
|
||||||
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用;type 缺省 button(表单内不隐式提交)
|
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用;type 缺省 button(表单内不隐式提交)
|
||||||
@@ -1732,6 +1766,7 @@ API 速览:
|
|||||||
- anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器
|
- anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器
|
||||||
- popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」
|
- popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」
|
||||||
- calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange
|
- calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange
|
||||||
|
- typography(props):排版文本,variant 决定语义(标题出 h1-h5 / 段落出 p / 行内出 span),支持语义色、装饰位、对齐、多行截断与复制按钮
|
||||||
|
|
||||||
一行用法:
|
一行用法:
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@
|
|||||||
- anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器
|
- anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器
|
||||||
- popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」
|
- popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」
|
||||||
- calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange
|
- calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange
|
||||||
|
- typography(props):排版文本,variant 决定语义(标题出 h1-h5 / 段落出 p / 行内出 span),支持语义色、装饰位、对齐、多行截断与复制按钮
|
||||||
- 用法: `const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')`
|
- 用法: `const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')`
|
||||||
- 约定: 皮肤不持有业务状态,一律委托 headless 内核或调用方信号
|
- 约定: 皮肤不持有业务状态,一律委托 headless 内核或调用方信号
|
||||||
- 约定: 表单类组件统一约定:*Props.value/checked/active 为 Signal 双向绑定,onChange/onInput 为回调
|
- 约定: 表单类组件统一约定:*Props.value/checked/active 为 Signal 双向绑定,onChange/onInput 为回调
|
||||||
|
|||||||
@@ -60,3 +60,4 @@ export { affix } from './affix.js';
|
|||||||
export { anchor } from './anchor.js';
|
export { anchor } from './anchor.js';
|
||||||
export { popconfirm } from './popconfirm.js';
|
export { popconfirm } from './popconfirm.js';
|
||||||
export { calendar } from './calendar.js';
|
export { calendar } from './calendar.js';
|
||||||
|
export { typography } from './typography.js';
|
||||||
|
|||||||
@@ -741,4 +741,20 @@ export interface CalendarProps {
|
|||||||
onMonthChange?: (month: string) => void; // 翻月回调,参数为 YYYY-MM
|
onMonthChange?: (month: string) => void; // 翻月回调,参数为 YYYY-MM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** 排版文本入参(variant 决定语义标签:title 出 h1-h5、paragraph 出 p、text 出 span) ***/
|
||||||
|
export interface TypographyProps {
|
||||||
|
content: string | Node; // 文本内容:字符串按纯文本渲染,传 DOM 则原样插入
|
||||||
|
variant?: 'title' | 'text' | 'paragraph'; // 排版形态;缺省 text
|
||||||
|
level?: 1 | 2 | 3 | 4 | 5; // 标题层级,仅 variant=title 生效;缺省 3
|
||||||
|
type?: 'secondary' | 'success' | 'warning' | 'danger'; // 语义色调;缺省主文本色
|
||||||
|
strong?: boolean; // 加粗强调;缺省 false
|
||||||
|
underline?: boolean; // 下划线;缺省 false
|
||||||
|
delete?: boolean; // 删除线(作废文案);缺省 false
|
||||||
|
mark?: boolean; // 高亮底纹;缺省 false
|
||||||
|
code?: boolean; // 等宽代码样式;缺省 false
|
||||||
|
align?: 'left' | 'center' | 'right'; // 水平对齐;缺省左对齐
|
||||||
|
ellipsis?: number; // 截断行数(1 起),超出显示省略号且悬停给全文;缺省不截断
|
||||||
|
copyable?: boolean; // 附复制按钮:点后写剪贴板并短暂回显结果;缺省 false
|
||||||
|
}
|
||||||
|
|
||||||
export type { ColumnDef, RowKey }; // 再导出常用内核类型,方便调用方
|
export type { ColumnDef, RowKey }; // 再导出常用内核类型,方便调用方
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { h } from '@ui-arch/frame';
|
||||||
|
import type { TypographyProps } from './types.js';
|
||||||
|
|
||||||
|
// 标题层级 → 语义标签(level 已在入口夹到 1-5)
|
||||||
|
const HEADING = ['h1', 'h2', 'h3', 'h4', 'h5'] as const;
|
||||||
|
// 形态 → 缺省标签
|
||||||
|
const TAG: Record<string, string> = { title: 'h3', text: 'span', paragraph: 'p' };
|
||||||
|
|
||||||
|
/*** 复制到剪贴板:优先异步 API,非安全上下文退回复选式复制,两者都失败返回 false ***/
|
||||||
|
function copyText(text: string): Promise<boolean> {
|
||||||
|
if (navigator.clipboard?.writeText) return navigator.clipboard.writeText(text).then(() => true, () => false);
|
||||||
|
const box = h('textarea', { class: 'ua-type-copybox', readonly: true }, text) as HTMLTextAreaElement;
|
||||||
|
document.body.append(box);
|
||||||
|
box.select(); // 不可见文本框选中后再走兼容接口
|
||||||
|
const ok = document.execCommand('copy');
|
||||||
|
box.remove();
|
||||||
|
return Promise.resolve(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** 类名拼装:形态 + 语义色 + 装饰位,均为纯类名,颜色留给样式表与令牌 ***/
|
||||||
|
function classOf(props: TypographyProps): string {
|
||||||
|
const variant = props.variant ?? 'text';
|
||||||
|
return ['ua-type', `ua-type-${variant}`, props.type ? `is-${props.type}` : '', props.strong ? 'is-strong' : '',
|
||||||
|
props.underline ? 'is-underline' : '', props.delete ? 'is-delete' : '', props.mark ? 'is-mark' : '',
|
||||||
|
props.code ? 'is-code' : '', props.align ? `is-${props.align}` : '', props.ellipsis ? 'is-clamped' : '']
|
||||||
|
.filter(Boolean).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** 复制按钮:点击后短暂回显结果,1.2 秒复原;按钮自身不参与文本截断 ***/
|
||||||
|
function copyButton(el: HTMLElement): HTMLElement {
|
||||||
|
const btn = h('button', { class: 'ua-type-copy', type: 'button', 'aria-label': '复制文本' }, '复制');
|
||||||
|
btn.addEventListener('click', async () => {
|
||||||
|
const ok = await copyText(el.textContent ?? '');
|
||||||
|
btn.textContent = ok ? '已复制' : '复制失败';
|
||||||
|
btn.classList.toggle('is-ok', ok); // 成功态换色,失败保持中性
|
||||||
|
setTimeout(() => {
|
||||||
|
btn.textContent = '复制';
|
||||||
|
btn.classList.remove('is-ok');
|
||||||
|
}, 1200); // 回显窗口
|
||||||
|
});
|
||||||
|
return btn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** 排版文本:variant 决定语义标签(title 出 h1-h5、paragraph 出 p、text 出 span),ellipsis 走多行截断,copyable 附复制按钮 ***/
|
||||||
|
export function typography(props: TypographyProps): HTMLElement {
|
||||||
|
const variant = props.variant ?? 'text';
|
||||||
|
const level = Math.min(Math.max(props.level ?? 3, 1), 5); // 层级夹取,避免越界索引
|
||||||
|
const tag = variant === 'title' ? HEADING[level - 1] : TAG[variant];
|
||||||
|
const plain = typeof props.content === 'string' ? props.content : null; // 只有字符串可安全截断
|
||||||
|
const el = h(tag, { class: classOf(props) }, props.content);
|
||||||
|
el.style.setProperty('--ua-type-clamp', String(props.ellipsis ?? 0)); // 行数交给 CSS 变量,样式表统一 clamp
|
||||||
|
if (plain && props.ellipsis) el.title = plain; // 截断后悬停可读全文
|
||||||
|
if (!props.copyable) return el;
|
||||||
|
return h('span', { class: 'ua-type-wrap' }, el, copyButton(el));
|
||||||
|
}
|
||||||
@@ -74,7 +74,8 @@
|
|||||||
"multiSelect(props):多选下拉,标签式回显 + 可搜索弹层,点选不收起便于连续多选,max 到限后未选项禁用",
|
"multiSelect(props):多选下拉,标签式回显 + 可搜索弹层,点选不收起便于连续多选,max 到限后未选项禁用",
|
||||||
"anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器",
|
"anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器",
|
||||||
"popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」",
|
"popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」",
|
||||||
"calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange"
|
"calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange",
|
||||||
|
"typography(props):排版文本,variant 决定语义(标题出 h1-h5 / 段落出 p / 行内出 span),支持语义色、装饰位、对齐、多行截断与复制按钮"
|
||||||
],
|
],
|
||||||
"keyTypes": [
|
"keyTypes": [
|
||||||
"ButtonProps",
|
"ButtonProps",
|
||||||
@@ -2946,6 +2947,91 @@
|
|||||||
"需要显示每天有几件事就传 marker:返回非空文案即渲染小徽标,并拼进 aria-label 让读屏也听得到",
|
"需要显示每天有几件事就传 marker:返回非空文案即渲染小徽标,并拼进 aria-label 让读屏也听得到",
|
||||||
"键盘:Tab 进入网格一次,←→ 逐日、↑↓ 逐周、Enter / 空格 选中;跨月会自动翻页并交接焦点"
|
"键盘:Tab 进入网格一次,←→ 逐日、↑↓ 逐周、Enter / 空格 选中;跨月会自动翻页并交接焦点"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "typography",
|
||||||
|
"title": "排版文本 Typography",
|
||||||
|
"demo": "sec-typography",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"n": "content",
|
||||||
|
"t": "string | Node",
|
||||||
|
"r": 1,
|
||||||
|
"d": "文本内容:字符串按纯文本渲染;传 DOM 则原样插入(此时不参与截断与复制)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "variant",
|
||||||
|
"t": "'title' | 'text' | 'paragraph'",
|
||||||
|
"df": "text",
|
||||||
|
"d": "排版形态,决定语义标签与字号:title 出 h1-h5、paragraph 出 p、text 出 span"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "level",
|
||||||
|
"t": "1 | 2 | 3 | 4 | 5",
|
||||||
|
"df": "3",
|
||||||
|
"d": "标题层级,仅 variant=title 生效;越界值会被夹到 1-5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "type",
|
||||||
|
"t": "'secondary' | 'success' | 'warning' | 'danger'",
|
||||||
|
"d": "语义色调;缺省主文本色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "strong",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "加粗强调"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "underline",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "下划线(可为链接式文案保留指引视觉)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "delete",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "删除线,用于作废文案;会同时弱化文字颜色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "mark",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "高亮底纹(警示色 24% 混透明),用于搜索命中片段"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "code",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "等宽代码样式,用于行内字段名 / 命令"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "align",
|
||||||
|
"t": "'left' | 'center' | 'right'",
|
||||||
|
"d": "水平对齐;缺省左对齐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "ellipsis",
|
||||||
|
"t": "number",
|
||||||
|
"d": "截断行数(1 起):超出显示省略号,纯文本自动挂 title 供悬停看全文;缺省不截断"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "copyable",
|
||||||
|
"t": "boolean",
|
||||||
|
"df": "false",
|
||||||
|
"d": "右侧附复制按钮:点击写剪贴板并回显「已复制 / 复制失败」,1.2 秒后复原"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": "typography({ variant: 'title', level: 2, content: '部署说明' }); typography({ content: 'RB-2048', code: true, copyable: true }); typography({ variant: 'paragraph', ellipsis: 2, content: '一段很长的说明……' })",
|
||||||
|
"steps": [
|
||||||
|
"正文一律用 variant='text' 或 'paragraph',标题用 variant='title' + level,标签自动出 h1-h5,别自己写 h 标签再叠样式",
|
||||||
|
"文内强调用装饰位组合:strong 加粗、mark 高亮、code 等宽、underline / delete 表示链接与作废,一个组件内可叠加",
|
||||||
|
"长描述(卡片摘要、表格说明)用 ellipsis 给行数:超出显示省略号并自动挂 title,悬停即看全文,不必额外做展开按钮",
|
||||||
|
"订单号 / 密钥 / 命令这类要复制的内容传 copyable:按钮独立于文本节点,复制失败会回显「复制失败」而不是静默",
|
||||||
|
"content 传 DOM 时组件只负责语义标签与类名:截断与复制对 DOM 内容不生效(取不到稳定文本)",
|
||||||
|
"段落连续排列时相邻 .ua-type-paragraph 自动留出间距,单个段落不额外撑高,嵌进卡片也不会有空隙"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3961,3 +3961,87 @@ button.ua-step-dot:hover {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
box-shadow: 0 0 24px rgba(0, 0, 0, 0.18);
|
box-shadow: 0 0 24px rgba(0, 0, 0, 0.18);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* —— 排版文本:层级靠字号与字重区分,语义色与装饰位只换颜色,不引布局 —— */
|
||||||
|
.ua-type {
|
||||||
|
color: var(--ua-color-text);
|
||||||
|
font-size: var(--ua-font-size-md);
|
||||||
|
line-height: 1.65;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.ua-type-paragraph + .ua-type-paragraph {
|
||||||
|
margin-top: var(--ua-space-2); /* 段落之间留呼吸,单段不额外撑高 */
|
||||||
|
}
|
||||||
|
.ua-type-title {
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.35;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
h1.ua-type-title { font-size: calc(var(--ua-font-size-lg) * 1.6); }
|
||||||
|
h2.ua-type-title { font-size: calc(var(--ua-font-size-lg) * 1.32); }
|
||||||
|
h3.ua-type-title { font-size: calc(var(--ua-font-size-lg) * 1.12); }
|
||||||
|
h4.ua-type-title { font-size: var(--ua-font-size-lg); }
|
||||||
|
h5.ua-type-title { font-size: var(--ua-font-size-md); }
|
||||||
|
.ua-type.is-secondary { color: var(--ua-color-text-muted); }
|
||||||
|
.ua-type.is-success { color: var(--ua-color-success); }
|
||||||
|
.ua-type.is-warning { color: var(--ua-color-warning); }
|
||||||
|
.ua-type.is-danger { color: var(--ua-color-danger); }
|
||||||
|
.ua-type.is-strong { font-weight: 600; }
|
||||||
|
.ua-type.is-underline { text-decoration: underline; text-underline-offset: 2px; }
|
||||||
|
.ua-type.is-delete { text-decoration: line-through; color: var(--ua-color-text-muted); }
|
||||||
|
.ua-type.is-underline.is-delete { text-decoration: underline line-through; }
|
||||||
|
.ua-type.is-mark {
|
||||||
|
background: color-mix(in srgb, var(--ua-color-warning) 24%, transparent);
|
||||||
|
border-radius: var(--ua-radius-sm);
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
.ua-type.is-code {
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||||
|
font-size: 0.92em;
|
||||||
|
background: color-mix(in srgb, var(--ua-color-border) 45%, transparent);
|
||||||
|
border-radius: var(--ua-radius-sm);
|
||||||
|
padding: 1px var(--ua-space-1);
|
||||||
|
}
|
||||||
|
.ua-type.is-center { text-align: center; }
|
||||||
|
.ua-type.is-right { text-align: right; }
|
||||||
|
.ua-type.is-clamped {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: var(--ua-type-clamp, 1);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.ua-type-wrap {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: var(--ua-space-1);
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.ua-type-copy {
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--ua-color-text-muted);
|
||||||
|
font: inherit;
|
||||||
|
font-size: var(--ua-font-size-sm);
|
||||||
|
padding: 0 2px;
|
||||||
|
border-radius: var(--ua-radius-sm);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.15s ease, background 0.15s ease;
|
||||||
|
}
|
||||||
|
.ua-type-copy:hover {
|
||||||
|
color: var(--ua-color-accent);
|
||||||
|
background: color-mix(in srgb, var(--ua-color-accent) 10%, transparent);
|
||||||
|
}
|
||||||
|
.ua-type-copy.is-ok { color: var(--ua-color-success); }
|
||||||
|
.ua-type-copybox {
|
||||||
|
position: fixed;
|
||||||
|
left: -9999px;
|
||||||
|
top: 0;
|
||||||
|
opacity: 0; /* 兼容复制用的离屏文本框,不参与视觉布局 */
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.ua-type-copy {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user