Regression / regression (push) Canceled after 0s
## 品牌标识(本次会话) 起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」, 那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」, 移动端站已是「K」;移动端文档站则完全没有 favicon)。 - 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边; 描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」 - 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark); 顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28)) - 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg) - 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留) - 移动端 7 个模板补 favicon(此前计数 0) 验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/ theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致; 两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。 ## 并行会话成果(本次一并入库) - 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具 + IconPreview 预览页 + ICON-SPEC.md 冻结规格 - 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁 - PC 组件:103 个大后台组件 / 组件11 批次 - uni-app:PC 端试点 + 移动端端实现 + 真实编译验证 ## 工程 - .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库) - CHANGELOG 补品牌标识条目 - ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
224 lines
12 KiB
HTML
224 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||
<title>Kole UI Mobile · Message(H5)</title>
|
||
<link rel="stylesheet" href="../.design_library/kole-ui-mobile/colors_and_type.css">
|
||
<link rel="stylesheet" href="Message.css">
|
||
<style>
|
||
body { margin: 0; background: var(--kole-color-page-bg); font-family: var(--kole-font-family); color: var(--kole-color-text-body); }
|
||
.demo { max-width: 375px; margin: 0 auto; padding: var(--kole-m-gutter) 0; }
|
||
.demo-label { margin: 0; padding: var(--kole-space-12) var(--kole-m-gutter) var(--kole-space-8);
|
||
font-size: var(--kole-m-font-size-label); color: var(--kole-color-text-secondary); }
|
||
/* 展示框:transform 建立包含块,让 position: fixed 的消息层落在本框内(生产环境落在视口顶部)。
|
||
不做这一步,同页并列的多个消息层会全部叠在视口顶部,看起来「只渲染了一个」。 */
|
||
.demo-frame { position: relative; max-width: 375px; margin: 0 auto; height: 200px; overflow: hidden;
|
||
transform: translateZ(0); background: var(--kole-color-card-bg);
|
||
border-block: 1px solid var(--kole-color-border); }
|
||
.demo-frame__body { padding: var(--kole-space-12) var(--kole-m-gutter);
|
||
font-size: var(--kole-m-font-size-label); color: var(--kole-color-text-secondary); line-height: 1.7; }
|
||
.demo-actions { display: flex; flex-wrap: wrap; gap: var(--kole-space-8); }
|
||
.demo-trigger { min-height: var(--kole-m-touch-target); padding: 0 var(--kole-space-12);
|
||
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-base);
|
||
background: var(--kole-color-card-bg); color: var(--kole-color-text-body);
|
||
font-family: inherit; font-size: var(--kole-m-font-size-label); cursor: pointer; touch-action: manipulation; }
|
||
.demo-trigger:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 2px; }
|
||
.demo-hint { margin: 0; padding: var(--kole-space-8) var(--kole-m-gutter) 0;
|
||
font-size: var(--kole-m-font-size-caption); color: var(--kole-color-text-tertiary); }
|
||
.demo-block[hidden] { display: none; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="demo">
|
||
<section class="demo-block" data-demo="tones">
|
||
<p class="demo-label">四种语气(tone=info / success / warning / error:图标与侧边描边同族,文字保持正文色)</p>
|
||
<div class="demo-frame" data-assert="message-tones">
|
||
<div class="demo-frame__body">
|
||
<div class="demo-actions">
|
||
<button class="demo-trigger" type="button" id="msg-info-trigger"
|
||
data-behavior="click-toggles-class:#msg-info|is-open">信息</button>
|
||
<button class="demo-trigger" type="button" id="msg-success-trigger"
|
||
data-behavior="click-toggles-class:#msg-success|is-open">成功</button>
|
||
<button class="demo-trigger" type="button" id="msg-warning-trigger"
|
||
data-behavior="click-toggles-class:#msg-warning|is-open">警告</button>
|
||
<button class="demo-trigger" type="button" id="msg-error-trigger"
|
||
data-behavior="click-toggles-class:#msg-error|is-open">错误</button>
|
||
</div>
|
||
</div>
|
||
<div class="kole-m-message">
|
||
<div class="kole-m-message__item kole-m-message__item--info" id="msg-info"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">ℹ</span>
|
||
<span class="kole-m-message__text">已为你切换到最近使用的收货地址</span>
|
||
</div>
|
||
<div class="kole-m-message__item kole-m-message__item--success" id="msg-success"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">✓</span>
|
||
<span class="kole-m-message__text">提交成功,预计 2 小时内审核完成</span>
|
||
</div>
|
||
<div class="kole-m-message__item kole-m-message__item--warning" id="msg-warning"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">⚠</span>
|
||
<span class="kole-m-message__text">库存仅剩 2 件,下单后可能延迟发货</span>
|
||
</div>
|
||
<div class="kole-m-message__item kole-m-message__item--error" id="msg-error"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">✕</span>
|
||
<span class="kole-m-message__text">网络异常,请检查连接后重试</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p class="demo-hint">四条消息同一层并列,各自独立开关;点一次展开、再点一次收起。</p>
|
||
</section>
|
||
|
||
<section class="demo-block" data-demo="closable">
|
||
<p class="demo-label">可关闭(closable=true:右侧 × 是原生 button,热区 44px,点它立即收起)</p>
|
||
<div class="demo-frame" data-assert="message-closable">
|
||
<div class="demo-frame__body">
|
||
<button class="demo-trigger" type="button" id="msg-closable-trigger"
|
||
data-behavior="click-toggles-class:#msg-closable|is-open">显示可关闭消息</button>
|
||
</div>
|
||
<div class="kole-m-message">
|
||
<div class="kole-m-message__item kole-m-message__item--info" id="msg-closable"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">ℹ</span>
|
||
<span class="kole-m-message__text">本次更新包含 3 项改进,点右侧 ✕ 立即收起</span>
|
||
<button class="kole-m-message__close" type="button" aria-label="关闭消息">✕</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="demo-block" data-demo="duration">
|
||
<p class="demo-label">自动消失(duration=3000:到点回传 close 由宿主收起;duration=0 时不自动收)</p>
|
||
<div class="demo-frame" data-assert="message-duration">
|
||
<div class="demo-frame__body">
|
||
<button class="demo-trigger" type="button" id="msg-duration-trigger"
|
||
data-behavior="click-sets-attr:#msg-duration|data-open|true">显示并在 3 秒后自动收起</button>
|
||
<p class="demo-hint" id="msg-duration-tip">计时归宿主:组件只负责显示态,到点回传 close</p>
|
||
</div>
|
||
<div class="kole-m-message">
|
||
<div class="kole-m-message__item kole-m-message__item--success" id="msg-duration"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">✓</span>
|
||
<span class="kole-m-message__text">已保存,3 秒后这条消息自动收起</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="demo-block" data-demo="stack">
|
||
<p class="demo-label">多条并列(消息层纵向排列:新消息追加在下方,可同时在场)</p>
|
||
<div class="demo-frame" data-assert="message-stack">
|
||
<div class="demo-frame__body">两条消息同时在场,各自语气独立。</div>
|
||
<div class="kole-m-message">
|
||
<div class="kole-m-message__item kole-m-message__item--success is-open" data-open="true">
|
||
<span class="kole-m-message__icon" aria-hidden="true">✓</span>
|
||
<span class="kole-m-message__text">图片上传完成(1/2)</span>
|
||
</div>
|
||
<div class="kole-m-message__item kole-m-message__item--warning is-open" data-open="true">
|
||
<span class="kole-m-message__icon" aria-hidden="true">⚠</span>
|
||
<span class="kole-m-message__text">第 2 张超出 5MB,已跳过</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="demo-block" data-demo="plain">
|
||
<p class="demo-label">默认形态(不带关闭按钮、不阻断操作:消息层自身 pointer-events: none)</p>
|
||
<div class="demo-frame" data-assert="message-plain">
|
||
<div class="demo-frame__body">
|
||
<button class="demo-trigger" type="button" id="msg-plain-trigger"
|
||
data-behavior="click-sets-attr:#msg-plain|data-open|true">显示默认消息</button>
|
||
<p class="demo-hint">消息浮在顶部,下面这行文字仍然可以正常选中与点击。</p>
|
||
</div>
|
||
<div class="kole-m-message">
|
||
<div class="kole-m-message__item kole-m-message__item--info" id="msg-plain"
|
||
role="status" aria-live="polite" data-open="false">
|
||
<span class="kole-m-message__icon" aria-hidden="true">ℹ</span>
|
||
<span class="kole-m-message__text">已复制到剪贴板</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
<script>
|
||
/* 演示页交互:类名与 data-open 由**同一个函数**写入(避免视觉与状态分叉)。
|
||
每块自带开关,互不依赖:触发器 id 与消息 id 成对写在下方映射里,
|
||
因此任一 `?demo=<id>` 单块预览都能独立工作。 */
|
||
(function () {
|
||
function setOpen(el, open) {
|
||
el.classList.toggle('is-open', open);
|
||
el.setAttribute('data-open', open ? 'true' : 'false');
|
||
}
|
||
function bind(triggerId, itemId, mode) {
|
||
var trig = document.getElementById(triggerId);
|
||
var item = document.getElementById(itemId);
|
||
if (!trig || !item) return;
|
||
trig.addEventListener('click', function () {
|
||
if (mode === 'show') setOpen(item, true);
|
||
else setOpen(item, !item.classList.contains('is-open'));
|
||
});
|
||
}
|
||
/* 四种语气:点一次展开、再点一次收起 */
|
||
bind('msg-info-trigger', 'msg-info', 'toggle');
|
||
bind('msg-success-trigger', 'msg-success', 'toggle');
|
||
bind('msg-warning-trigger', 'msg-warning', 'toggle');
|
||
bind('msg-error-trigger', 'msg-error', 'toggle');
|
||
bind('msg-closable-trigger', 'msg-closable', 'toggle');
|
||
bind('msg-plain-trigger', 'msg-plain', 'show');
|
||
|
||
/* 可关闭:点 × 只关它自己那一条 */
|
||
document.querySelectorAll('.kole-m-message__close').forEach(function (btn) {
|
||
btn.addEventListener('click', function () {
|
||
var item = btn.closest('.kole-m-message__item');
|
||
if (item) setOpen(item, false);
|
||
});
|
||
});
|
||
|
||
/* 自动消失:时长由宿主决定(这里演示 3000ms),到点收起。
|
||
组件不持有默认时长 —— 规格 §42.7 明确把这条留给宿主。 */
|
||
var dur = document.getElementById('msg-duration');
|
||
var durTrig = document.getElementById('msg-duration-trigger');
|
||
var tip = document.getElementById('msg-duration-tip');
|
||
var timer = null;
|
||
if (dur && durTrig) {
|
||
durTrig.addEventListener('click', function () {
|
||
if (timer) clearTimeout(timer);
|
||
setOpen(dur, true);
|
||
if (tip) tip.textContent = '显示中…3 秒后自动收起';
|
||
timer = setTimeout(function () {
|
||
setOpen(dur, false);
|
||
timer = null;
|
||
if (tip) tip.textContent = '已自动收起(计时归宿主:组件只负责显示态)';
|
||
}, 3000);
|
||
});
|
||
}
|
||
})();
|
||
</script>
|
||
<script>
|
||
/* ?demo=<id> → 只显示该演示块(文档站按块预览用;无参数时全部显示,测试与回归走无参数路径) */
|
||
(function () {
|
||
var id = new URLSearchParams(location.search).get('demo');
|
||
if (!id) return;
|
||
var blocks = Array.prototype.slice.call(document.querySelectorAll('.demo-block'));
|
||
var hit = false;
|
||
blocks.forEach(function (b) {
|
||
var on = b.getAttribute('data-demo') === id;
|
||
if (on) hit = true;
|
||
b.hidden = !on;
|
||
});
|
||
if (!hit) { blocks.forEach(function (b) { b.hidden = false; }); return; }
|
||
document.body.classList.add('demo-single');
|
||
var demoBox = document.querySelector('.demo');
|
||
if (demoBox) demoBox.style.minHeight = 'auto';
|
||
blocks.forEach(function (b) {
|
||
var label = b.querySelector('.demo-label');
|
||
if (label && !b.hidden) label.hidden = true;
|
||
});
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|