iter(g192): 动效时长字面值归零补循环档
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"$schema": "视觉漂移基线:各类硬编码视觉字面量的允许上限,任一类超出即 ua audit:visual 退出码 1;迁移后用 --baseline 重写",
|
"$schema": "视觉漂移基线:各类硬编码视觉字面量的允许上限,任一类超出即 ua audit:visual 退出码 1;迁移后用 --baseline 重写",
|
||||||
"file": "packages/skin/ui/ui.css",
|
"file": "packages/skin/ui/ui.css",
|
||||||
"commit": "654a9dd",
|
"commit": "0e996e4",
|
||||||
"generatedAt": "2026-10-26T09:53:34.712Z",
|
"generatedAt": "2026-10-26T09:54:55.315Z",
|
||||||
"lines": 4874,
|
"lines": 4874,
|
||||||
"total": 27,
|
"total": 18,
|
||||||
"counts": {
|
"counts": {
|
||||||
"font-size-literal": 0,
|
"font-size-literal": 0,
|
||||||
"duration-literal": 9,
|
"duration-literal": 0,
|
||||||
"shadow-literal": 5,
|
"shadow-literal": 5,
|
||||||
"radius-literal": 0,
|
"radius-literal": 0,
|
||||||
"focus-ring-variant": 0,
|
"focus-ring-variant": 0,
|
||||||
|
|||||||
@@ -2220,6 +2220,11 @@ node packages/tools/cli/bin/ua.js <index|list|info <包名|组件id>|docs|tokens
|
|||||||
- --ua-duration-fast: 0.15s
|
- --ua-duration-fast: 0.15s
|
||||||
- --ua-duration-base: 0.2s
|
- --ua-duration-base: 0.2s
|
||||||
- --ua-duration-slow: 0.25s
|
- --ua-duration-slow: 0.25s
|
||||||
|
- --ua-duration-slower: 0.35s
|
||||||
|
- --ua-duration-loop-fast: 0.6s
|
||||||
|
- --ua-duration-loop-mid: 0.8s
|
||||||
|
- --ua-duration-loop-slow: 1.2s
|
||||||
|
- --ua-duration-loop-long: 1.6s
|
||||||
- --ua-ease: cubic-bezier(0.2, 0.8, 0.2, 1)
|
- --ua-ease: cubic-bezier(0.2, 0.8, 0.2, 1)
|
||||||
- --ua-ease-out: cubic-bezier(0.16, 1, 0.3, 1)
|
- --ua-ease-out: cubic-bezier(0.16, 1, 0.3, 1)
|
||||||
- --ua-focus-ring: 0 0 0 3px color-mix(in srgb, var(--ua-color-accent) 22%, transparent)(暗色 0 0 0 3px color-mix(in srgb, var(--ua-color-accent) 34%, transparent))
|
- --ua-focus-ring: 0 0 0 3px color-mix(in srgb, var(--ua-color-accent) 22%, transparent)(暗色 0 0 0 3px color-mix(in srgb, var(--ua-color-accent) 34%, transparent))
|
||||||
|
|||||||
@@ -64,10 +64,15 @@
|
|||||||
--ua-shadow-accent: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent); /* 主题色投影:主按钮 / 强调控件悬停浮起 */
|
--ua-shadow-accent: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent); /* 主题色投影:主按钮 / 强调控件悬停浮起 */
|
||||||
--ua-shadow-accent-strong: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent); /* 主题色强投影:返回顶部等悬浮强调件 */
|
--ua-shadow-accent-strong: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent); /* 主题色强投影:返回顶部等悬浮强调件 */
|
||||||
|
|
||||||
/* ---- 动效:三档时长 + 两条主缓动曲线 ---- */
|
/* ---- 动效:四档交互时长 + 四档循环时长 + 两条主缓动曲线 ---- */
|
||||||
--ua-duration-fast: 0.15s; /* 快:hover / 聚焦 / 颜色与边框变化(既有样式的主流时长) */
|
--ua-duration-fast: 0.15s; /* 快:hover / 聚焦 / 颜色与边框变化(既有样式的主流时长) */
|
||||||
--ua-duration-base: 0.2s; /* 中:展开收起 / 位移 / 透明度过渡 */
|
--ua-duration-base: 0.2s; /* 中:展开收起 / 位移 / 透明度过渡 */
|
||||||
--ua-duration-slow: 0.25s; /* 慢:浮层出入场 / 较大面积变化 */
|
--ua-duration-slow: 0.25s; /* 慢:浮层出入场 / 较大面积变化 */
|
||||||
|
--ua-duration-slower: 0.35s; /* 更慢:进度条宽度推进 / 描边长度等大跨度形变(比浮层出场再长一档) */
|
||||||
|
--ua-duration-loop-fast: 0.6s; /* 循环快档:条纹滚动等细微循环 */
|
||||||
|
--ua-duration-loop-mid: 0.8s; /* 循环中档:加载转圈 / 开关内转圈(0.7 与 0.8 收敛到此档) */
|
||||||
|
--ua-duration-loop-slow: 1.2s; /* 循环慢档:骨架扫光 / 不确定进度条(1.4 收敛到此档) */
|
||||||
|
--ua-duration-loop-long: 1.6s; /* 循环长档:时间线呼吸等低频脉冲,别再用在加载态上 */
|
||||||
--ua-ease: cubic-bezier(0.2, 0.8, 0.2, 1); /* 标准缓动:先快后缓,控件交互默认用这条 */
|
--ua-ease: cubic-bezier(0.2, 0.8, 0.2, 1); /* 标准缓动:先快后缓,控件交互默认用这条 */
|
||||||
--ua-ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* 出场缓动:元素进入视口 / 弹层出现时使用 */
|
--ua-ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* 出场缓动:元素进入视口 / 弹层出现时使用 */
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,12 @@
|
|||||||
"duration": {
|
"duration": {
|
||||||
"fast": "0.15s",
|
"fast": "0.15s",
|
||||||
"base": "0.2s",
|
"base": "0.2s",
|
||||||
"slow": "0.25s"
|
"slow": "0.25s",
|
||||||
|
"slower": "0.35s",
|
||||||
|
"loopFast": "0.6s",
|
||||||
|
"loopMid": "0.8s",
|
||||||
|
"loopSlow": "1.2s",
|
||||||
|
"loopLong": "1.6s"
|
||||||
},
|
},
|
||||||
"ease": "cubic-bezier(0.2, 0.8, 0.2, 1)",
|
"ease": "cubic-bezier(0.2, 0.8, 0.2, 1)",
|
||||||
"easeOut": "cubic-bezier(0.16, 1, 0.3, 1)"
|
"easeOut": "cubic-bezier(0.16, 1, 0.3, 1)"
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ body.ua-col-resizing {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border: 2px solid color-mix(in srgb, var(--ua-color-bg) 40%, transparent);
|
border: 2px solid color-mix(in srgb, var(--ua-color-bg) 40%, transparent);
|
||||||
border-top-color: var(--ua-color-bg);
|
border-top-color: var(--ua-color-bg);
|
||||||
animation: ua-switch-spin 0.7s linear infinite;
|
animation: ua-switch-spin var(--ua-duration-loop-mid) linear infinite;
|
||||||
}
|
}
|
||||||
@keyframes ua-switch-spin {
|
@keyframes ua-switch-spin {
|
||||||
to { transform: rotate(360deg); }
|
to { transform: rotate(360deg); }
|
||||||
@@ -1380,7 +1380,7 @@ button.ua-step-dot:hover {
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--ua-color-bg) 65%, transparent), transparent);
|
background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--ua-color-bg) 65%, transparent), transparent);
|
||||||
animation: ua-shimmer 1.4s ease-in-out infinite;
|
animation: ua-shimmer var(--ua-duration-loop-slow) ease-in-out infinite;
|
||||||
}
|
}
|
||||||
@keyframes ua-shimmer {
|
@keyframes ua-shimmer {
|
||||||
to {
|
to {
|
||||||
@@ -1478,7 +1478,7 @@ button.ua-step-dot:hover {
|
|||||||
border: 2px solid var(--ua-color-border);
|
border: 2px solid var(--ua-color-border);
|
||||||
border-top-color: var(--ua-color-accent);
|
border-top-color: var(--ua-color-accent);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
animation: ua-spin 0.8s linear infinite;
|
animation: ua-spin var(--ua-duration-loop-mid) linear infinite;
|
||||||
}
|
}
|
||||||
@keyframes ua-spin {
|
@keyframes ua-spin {
|
||||||
to {
|
to {
|
||||||
@@ -1506,7 +1506,7 @@ button.ua-step-dot:hover {
|
|||||||
width: 0;
|
width: 0;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
background: linear-gradient(90deg, color-mix(in srgb, var(--ua-color-accent) 65%, transparent), var(--ua-color-accent));
|
background: linear-gradient(90deg, color-mix(in srgb, var(--ua-color-accent) 65%, transparent), var(--ua-color-accent));
|
||||||
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: width var(--ua-duration-slower) cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
.ua-progress-fill::after {
|
.ua-progress-fill::after {
|
||||||
content: '';
|
content: '';
|
||||||
@@ -1514,7 +1514,7 @@ button.ua-step-dot:hover {
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.18) 0 6px, transparent 6px 12px);
|
background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.18) 0 6px, transparent 6px 12px);
|
||||||
background-size: 17px 100%;
|
background-size: 17px 100%;
|
||||||
animation: ua-stripe 0.6s linear infinite;
|
animation: ua-stripe var(--ua-duration-loop-fast) linear infinite;
|
||||||
}
|
}
|
||||||
.ua-progress-fill.ua-done {
|
.ua-progress-fill.ua-done {
|
||||||
background: var(--ua-color-success);
|
background: var(--ua-color-success);
|
||||||
@@ -1537,7 +1537,7 @@ button.ua-step-dot:hover {
|
|||||||
.ua-progress-fill.ua-indeterminate {
|
.ua-progress-fill.ua-indeterminate {
|
||||||
width: 35%;
|
width: 35%;
|
||||||
transition: none;
|
transition: none;
|
||||||
animation: ua-indeterminate 1.2s ease-in-out infinite;
|
animation: ua-indeterminate var(--ua-duration-loop-slow) ease-in-out infinite;
|
||||||
}
|
}
|
||||||
.ua-progress-fill.ua-indeterminate::after {
|
.ua-progress-fill.ua-indeterminate::after {
|
||||||
animation: none;
|
animation: none;
|
||||||
@@ -2238,7 +2238,7 @@ button.ua-step-dot:hover {
|
|||||||
.ua-tl-dot-pending {
|
.ua-tl-dot-pending {
|
||||||
background: var(--ua-color-bg);
|
background: var(--ua-color-bg);
|
||||||
border: 1px dashed var(--ua-color-accent);
|
border: 1px dashed var(--ua-color-accent);
|
||||||
animation: ua-tl-pulse 1.6s ease-in-out infinite;
|
animation: ua-tl-pulse var(--ua-duration-loop-long) ease-in-out infinite;
|
||||||
}
|
}
|
||||||
.ua-tl-head {
|
.ua-tl-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -2565,7 +2565,7 @@ button.ua-step-dot:hover {
|
|||||||
.ua-carousel-track {
|
.ua-carousel-track {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: transform 0.32s ease;
|
transition: transform var(--ua-duration-slower) ease;
|
||||||
}
|
}
|
||||||
.ua-carousel-slide {
|
.ua-carousel-slide {
|
||||||
flex: 0 0 100%;
|
flex: 0 0 100%;
|
||||||
@@ -4730,7 +4730,7 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); }
|
|||||||
.ua-progress-ring-arc {
|
.ua-progress-ring-arc {
|
||||||
stroke: var(--ua-color-accent);
|
stroke: var(--ua-color-accent);
|
||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
transition: stroke-dashoffset 0.3s ease;
|
transition: stroke-dashoffset var(--ua-duration-slower) ease;
|
||||||
}
|
}
|
||||||
.ua-progress-ring.is-success .ua-progress-ring-arc { stroke: var(--ua-color-success); }
|
.ua-progress-ring.is-success .ua-progress-ring-arc { stroke: var(--ua-color-success); }
|
||||||
.ua-progress-ring.is-warning .ua-progress-ring-arc { stroke: var(--ua-color-warning); }
|
.ua-progress-ring.is-warning .ua-progress-ring-arc { stroke: var(--ua-color-warning); }
|
||||||
|
|||||||
@@ -194,8 +194,19 @@ const DURATION_STEPS = [
|
|||||||
{ max: 0.17, token: 'var(--ua-duration-fast)' },
|
{ max: 0.17, token: 'var(--ua-duration-fast)' },
|
||||||
{ max: 0.23, token: 'var(--ua-duration-base)' },
|
{ max: 0.23, token: 'var(--ua-duration-base)' },
|
||||||
{ max: 0.2501, token: 'var(--ua-duration-slow)' },
|
{ max: 0.2501, token: 'var(--ua-duration-slow)' },
|
||||||
|
{ max: 0.36, token: 'var(--ua-duration-slower)' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/*** 作用:循环动效(infinite)的时长 → 循环四档;0.7/0.8 收敛到中档、1.2/1.4 收敛到慢档,表外保留 ***/
|
||||||
|
const LOOP_DURATIONS = new Map([
|
||||||
|
['0.6s', 'var(--ua-duration-loop-fast)'],
|
||||||
|
['0.7s', 'var(--ua-duration-loop-mid)'],
|
||||||
|
['0.8s', 'var(--ua-duration-loop-mid)'],
|
||||||
|
['1.2s', 'var(--ua-duration-loop-slow)'],
|
||||||
|
['1.4s', 'var(--ua-duration-loop-slow)'],
|
||||||
|
['1.6s', 'var(--ua-duration-loop-long)'],
|
||||||
|
]);
|
||||||
|
|
||||||
/*** 作用:控件高度三档的字面值 → 令牌(28/34/40px 三个值保留给控件高度档位,其余尺寸不入此口径) ***/
|
/*** 作用:控件高度三档的字面值 → 令牌(28/34/40px 三个值保留给控件高度档位,其余尺寸不入此口径) ***/
|
||||||
const CONTROL_H_TOKENS = new Map([
|
const CONTROL_H_TOKENS = new Map([
|
||||||
['28px', 'var(--ua-control-h-sm)'],
|
['28px', 'var(--ua-control-h-sm)'],
|
||||||
@@ -305,12 +316,13 @@ function hasTiming(value) {
|
|||||||
/*** 作用:迁移单个动效声明值(逐段替换时长,缺缓动时补 --ua-ease);返回 null 表示无需改动 ***/
|
/*** 作用:迁移单个动效声明值(逐段替换时长,缺缓动时补 --ua-ease);返回 null 表示无需改动 ***/
|
||||||
function migrateMotion(prop, core) {
|
function migrateMotion(prop, core) {
|
||||||
const shorthand = prop === 'transition' || prop === 'animation'; // 只有简写能补缓动,-duration 属性补了是非法的
|
const shorthand = prop === 'transition' || prop === 'animation'; // 只有简写能补缓动,-duration 属性补了是非法的
|
||||||
|
const loop = /infinite/.test(core) && (prop === 'animation' || prop === 'animation-duration'); // 无限循环走循环四档
|
||||||
const parts = splitTopLevel(core);
|
const parts = splitTopLevel(core);
|
||||||
let hits = 0;
|
let hits = 0;
|
||||||
const next = parts.map((segment) => {
|
const next = parts.map((segment) => {
|
||||||
let replaced = 0;
|
let replaced = 0;
|
||||||
let out = segment.replace(/(\d*\.?\d+)(ms|s)\b/gi, (token) => {
|
let out = segment.replace(/(\d*\.?\d+)(ms|s)\b/gi, (token) => {
|
||||||
const mapped = durationToken(token);
|
const mapped = loop ? LOOP_DURATIONS.get(token.toLowerCase()) ?? null : durationToken(token);
|
||||||
if (!mapped) return token; // 表外时长保留,交给后续视觉条目单独评估
|
if (!mapped) return token; // 表外时长保留,交给后续视觉条目单独评估
|
||||||
replaced++;
|
replaced++;
|
||||||
hits++;
|
hits++;
|
||||||
|
|||||||
Reference in New Issue
Block a user