@chenzy-design/core 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-chat-dialogue.d.ts +300 -0
- package/dist/ai-chat-dialogue.d.ts.map +1 -0
- package/dist/ai-chat-dialogue.js +699 -0
- package/dist/ai-chat-dialogue.js.map +1 -0
- package/dist/ai-chat-dialogue.test.d.ts +2 -0
- package/dist/ai-chat-dialogue.test.d.ts.map +1 -0
- package/dist/ai-chat-dialogue.test.js +338 -0
- package/dist/ai-chat-dialogue.test.js.map +1 -0
- package/dist/ai-chat-input.d.ts +191 -0
- package/dist/ai-chat-input.d.ts.map +1 -0
- package/dist/ai-chat-input.js +274 -0
- package/dist/ai-chat-input.js.map +1 -0
- package/dist/ai-chat-input.test.d.ts +2 -0
- package/dist/ai-chat-input.test.d.ts.map +1 -0
- package/dist/ai-chat-input.test.js +339 -0
- package/dist/ai-chat-input.test.js.map +1 -0
- package/dist/audio-player.d.ts +154 -0
- package/dist/audio-player.d.ts.map +1 -0
- package/dist/audio-player.js +254 -0
- package/dist/audio-player.js.map +1 -0
- package/dist/audio-player.test.d.ts +2 -0
- package/dist/audio-player.test.d.ts.map +1 -0
- package/dist/audio-player.test.js +275 -0
- package/dist/audio-player.test.js.map +1 -0
- package/dist/back-top.d.ts +4 -1
- package/dist/back-top.d.ts.map +1 -1
- package/dist/back-top.js +5 -2
- package/dist/back-top.js.map +1 -1
- package/dist/back-top.test.js +3 -2
- package/dist/back-top.test.js.map +1 -1
- package/dist/calendar.d.ts +132 -44
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +413 -70
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.test.js +160 -76
- package/dist/calendar.test.js.map +1 -1
- package/dist/chat.d.ts +172 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +210 -0
- package/dist/chat.js.map +1 -0
- package/dist/chat.test.d.ts +2 -0
- package/dist/chat.test.d.ts.map +1 -0
- package/dist/chat.test.js +181 -0
- package/dist/chat.test.js.map +1 -0
- package/dist/code-highlight.d.ts +30 -0
- package/dist/code-highlight.d.ts.map +1 -0
- package/dist/code-highlight.js +37 -0
- package/dist/code-highlight.js.map +1 -0
- package/dist/code-highlight.test.d.ts +2 -0
- package/dist/code-highlight.test.d.ts.map +1 -0
- package/dist/code-highlight.test.js +36 -0
- package/dist/code-highlight.test.js.map +1 -0
- package/dist/collapsible.d.ts +41 -0
- package/dist/collapsible.d.ts.map +1 -0
- package/dist/collapsible.js +33 -0
- package/dist/collapsible.js.map +1 -0
- package/dist/collapsible.test.d.ts +2 -0
- package/dist/collapsible.test.d.ts.map +1 -0
- package/dist/collapsible.test.js +57 -0
- package/dist/collapsible.test.js.map +1 -0
- package/dist/color-value.d.ts +60 -0
- package/dist/color-value.d.ts.map +1 -0
- package/dist/color-value.js +165 -0
- package/dist/color-value.js.map +1 -0
- package/dist/color-value.test.d.ts +2 -0
- package/dist/color-value.test.d.ts.map +1 -0
- package/dist/color-value.test.js +104 -0
- package/dist/color-value.test.js.map +1 -0
- package/dist/config-provider.d.ts +76 -37
- package/dist/config-provider.d.ts.map +1 -1
- package/dist/config-provider.js +107 -32
- package/dist/config-provider.js.map +1 -1
- package/dist/config-provider.test.js +123 -60
- package/dist/config-provider.test.js.map +1 -1
- package/dist/cropper.d.ts +164 -0
- package/dist/cropper.d.ts.map +1 -0
- package/dist/cropper.js +841 -0
- package/dist/cropper.js.map +1 -0
- package/dist/cropper.test.d.ts +2 -0
- package/dist/cropper.test.d.ts.map +1 -0
- package/dist/cropper.test.js +259 -0
- package/dist/cropper.test.js.map +1 -0
- package/dist/drag-move.d.ts +119 -0
- package/dist/drag-move.d.ts.map +1 -0
- package/dist/drag-move.js +237 -0
- package/dist/drag-move.js.map +1 -0
- package/dist/drag-move.test.d.ts +2 -0
- package/dist/drag-move.test.d.ts.map +1 -0
- package/dist/drag-move.test.js +304 -0
- package/dist/drag-move.test.js.map +1 -0
- package/dist/editable.d.ts +24 -4
- package/dist/editable.d.ts.map +1 -1
- package/dist/editable.js +18 -0
- package/dist/editable.js.map +1 -1
- package/dist/editable.test.js +55 -2
- package/dist/editable.test.js.map +1 -1
- package/dist/ellipsis.d.ts +13 -0
- package/dist/ellipsis.d.ts.map +1 -1
- package/dist/ellipsis.js +36 -0
- package/dist/ellipsis.js.map +1 -1
- package/dist/ellipsis.test.js +37 -1
- package/dist/ellipsis.test.js.map +1 -1
- package/dist/form-path.d.ts +19 -0
- package/dist/form-path.d.ts.map +1 -0
- package/dist/form-path.js +97 -0
- package/dist/form-path.js.map +1 -0
- package/dist/form-path.test.d.ts +2 -0
- package/dist/form-path.test.d.ts.map +1 -0
- package/dist/form-path.test.js +57 -0
- package/dist/form-path.test.js.map +1 -0
- package/dist/form-validate.d.ts +13 -0
- package/dist/form-validate.d.ts.map +1 -0
- package/dist/form-validate.js +204 -0
- package/dist/form-validate.js.map +1 -0
- package/dist/form.d.ts +91 -18
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +170 -115
- package/dist/form.js.map +1 -1
- package/dist/form.test.js +349 -76
- package/dist/form.test.js.map +1 -1
- package/dist/highlight.d.ts +42 -32
- package/dist/highlight.d.ts.map +1 -1
- package/dist/highlight.js +67 -41
- package/dist/highlight.js.map +1 -1
- package/dist/highlight.test.js +73 -32
- package/dist/highlight.test.js.map +1 -1
- package/dist/hotkeys.d.ts +151 -0
- package/dist/hotkeys.d.ts.map +1 -0
- package/dist/hotkeys.js +188 -0
- package/dist/hotkeys.js.map +1 -0
- package/dist/hotkeys.test.d.ts +2 -0
- package/dist/hotkeys.test.d.ts.map +1 -0
- package/dist/hotkeys.test.js +170 -0
- package/dist/hotkeys.test.js.map +1 -0
- package/dist/index.d.ts +33 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -13
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +34 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +54 -0
- package/dist/input.js.map +1 -0
- package/dist/input.test.d.ts +2 -0
- package/dist/input.test.d.ts.map +1 -0
- package/dist/input.test.js +56 -0
- package/dist/input.test.js.map +1 -0
- package/dist/markdown-render.d.ts +49 -0
- package/dist/markdown-render.d.ts.map +1 -0
- package/dist/markdown-render.js +61 -0
- package/dist/markdown-render.js.map +1 -0
- package/dist/markdown-render.test.d.ts +2 -0
- package/dist/markdown-render.test.d.ts.map +1 -0
- package/dist/markdown-render.test.js +106 -0
- package/dist/markdown-render.test.js.map +1 -0
- package/dist/notification.d.ts +40 -31
- package/dist/notification.d.ts.map +1 -1
- package/dist/notification.js +86 -70
- package/dist/notification.js.map +1 -1
- package/dist/notification.test.js +62 -39
- package/dist/notification.test.js.map +1 -1
- package/dist/numeral.d.ts +32 -0
- package/dist/numeral.d.ts.map +1 -0
- package/dist/numeral.js +67 -0
- package/dist/numeral.js.map +1 -0
- package/dist/numeral.test.d.ts +2 -0
- package/dist/numeral.test.d.ts.map +1 -0
- package/dist/numeral.test.js +59 -0
- package/dist/numeral.test.js.map +1 -0
- package/dist/overflow-list.d.ts +9 -40
- package/dist/overflow-list.d.ts.map +1 -1
- package/dist/overflow-list.js +9 -70
- package/dist/overflow-list.js.map +1 -1
- package/dist/overflow-list.test.js +1 -122
- package/dist/overflow-list.test.js.map +1 -1
- package/dist/pagination.d.ts +17 -0
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +48 -0
- package/dist/pagination.js.map +1 -1
- package/dist/pagination.test.js +40 -1
- package/dist/pagination.test.js.map +1 -1
- package/dist/pincode.d.ts +79 -0
- package/dist/pincode.d.ts.map +1 -0
- package/dist/pincode.js +119 -0
- package/dist/pincode.js.map +1 -0
- package/dist/pincode.test.d.ts +2 -0
- package/dist/pincode.test.d.ts.map +1 -0
- package/dist/pincode.test.js +151 -0
- package/dist/pincode.test.js.map +1 -0
- package/dist/progress.d.ts +32 -30
- package/dist/progress.d.ts.map +1 -1
- package/dist/progress.js +257 -64
- package/dist/progress.js.map +1 -1
- package/dist/progress.test.js +50 -47
- package/dist/progress.test.js.map +1 -1
- package/dist/resizable.d.ts +200 -0
- package/dist/resizable.d.ts.map +1 -0
- package/dist/resizable.js +329 -0
- package/dist/resizable.js.map +1 -0
- package/dist/resizable.test.d.ts +2 -0
- package/dist/resizable.test.d.ts.map +1 -0
- package/dist/resizable.test.js +302 -0
- package/dist/resizable.test.js.map +1 -0
- package/dist/scroll-list.d.ts +69 -62
- package/dist/scroll-list.d.ts.map +1 -1
- package/dist/scroll-list.js +103 -144
- package/dist/scroll-list.js.map +1 -1
- package/dist/scroll-list.test.js +100 -110
- package/dist/scroll-list.test.js.map +1 -1
- package/dist/sidebar.d.ts +46 -0
- package/dist/sidebar.d.ts.map +1 -0
- package/dist/sidebar.js +65 -0
- package/dist/sidebar.js.map +1 -0
- package/dist/sidebar.test.d.ts +2 -0
- package/dist/sidebar.test.d.ts.map +1 -0
- package/dist/sidebar.test.js +88 -0
- package/dist/sidebar.test.js.map +1 -0
- package/dist/spin.d.ts +5 -5
- package/dist/spin.d.ts.map +1 -1
- package/dist/spin.js +13 -39
- package/dist/spin.js.map +1 -1
- package/dist/spin.test.js +2 -26
- package/dist/spin.test.js.map +1 -1
- package/dist/toast.d.ts +33 -30
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +77 -72
- package/dist/toast.js.map +1 -1
- package/dist/toast.test.js +63 -37
- package/dist/toast.test.js.map +1 -1
- package/dist/tree.d.ts +22 -5
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +61 -9
- package/dist/tree.js.map +1 -1
- package/dist/tree.test.js +72 -1
- package/dist/tree.test.js.map +1 -1
- package/dist/user-guide.d.ts +73 -0
- package/dist/user-guide.d.ts.map +1 -0
- package/dist/user-guide.js +95 -0
- package/dist/user-guide.js.map +1 -0
- package/dist/user-guide.test.d.ts +2 -0
- package/dist/user-guide.test.d.ts.map +1 -0
- package/dist/user-guide.test.js +109 -0
- package/dist/user-guide.test.js.map +1 -0
- package/dist/video-player.d.ts +196 -0
- package/dist/video-player.d.ts.map +1 -0
- package/dist/video-player.js +461 -0
- package/dist/video-player.js.map +1 -0
- package/dist/video-player.test.d.ts +2 -0
- package/dist/video-player.test.d.ts.map +1 -0
- package/dist/video-player.test.js +435 -0
- package/dist/video-player.test.js.map +1 -0
- package/package.json +17 -1
- package/dist/banner.d.ts +0 -19
- package/dist/banner.d.ts.map +0 -1
- package/dist/banner.js +0 -20
- package/dist/banner.js.map +0 -1
- package/dist/banner.test.d.ts +0 -2
- package/dist/banner.test.d.ts.map +0 -1
- package/dist/banner.test.js +0 -29
- package/dist/banner.test.js.map +0 -1
- package/dist/breakpoints.d.ts +0 -30
- package/dist/breakpoints.d.ts.map +0 -1
- package/dist/breakpoints.js +0 -45
- package/dist/breakpoints.js.map +0 -1
- package/dist/breakpoints.test.d.ts +0 -2
- package/dist/breakpoints.test.d.ts.map +0 -1
- package/dist/breakpoints.test.js +0 -46
- package/dist/breakpoints.test.js.map +0 -1
- package/dist/lottie-icon.d.ts +0 -88
- package/dist/lottie-icon.d.ts.map +0 -1
- package/dist/lottie-icon.js +0 -84
- package/dist/lottie-icon.js.map +0 -1
- package/dist/lottie-icon.test.d.ts +0 -2
- package/dist/lottie-icon.test.d.ts.map +0 -1
- package/dist/lottie-icon.test.js +0 -88
- package/dist/lottie-icon.test.js.map +0 -1
- package/dist/sider.d.ts +0 -26
- package/dist/sider.d.ts.map +0 -1
- package/dist/sider.js +0 -55
- package/dist/sider.js.map +0 -1
- package/dist/sider.test.d.ts +0 -2
- package/dist/sider.test.d.ts.map +0 -1
- package/dist/sider.test.js +0 -29
- package/dist/sider.test.js.map +0 -1
package/dist/scroll-list.js
CHANGED
|
@@ -1,175 +1,134 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* ScrollList / ScrollItem helpers — framework-agnostic picker math.
|
|
3
|
+
*
|
|
4
|
+
* 严格对齐 Semi Design(semi-foundation/scrollList)。Semi 的 itemFoundation 是有
|
|
5
|
+
* 状态、直接操作真实 DOM 的类;本层遵循 chenzy-design headless 哲学,只抽出**纯函数**
|
|
6
|
+
* 几何 / 文案 / 缓动数学,DOM 读写(节点搬移、getBoundingClientRect)由 svelte 渲染层
|
|
7
|
+
* 用这些函数实现,无 DOM、无框架依赖、无内部可变状态。
|
|
8
|
+
*
|
|
9
|
+
* 对齐来源:
|
|
10
|
+
* - scrollItem.tsx `scrollToNode` / `scrollToCenter` → {@link centerOffset}
|
|
11
|
+
* - itemFoundation `getNearestNodeInfo`(选区中线找最近非禁用节点) → {@link nearestIndex}
|
|
12
|
+
* - scrollTo.ts(semi-animation 驱动 scrollTop) → {@link scrollFrame}
|
|
13
|
+
* (已核 semi-animation 源码:scrollTo 传 `{duration}` 不传 easing → wrapValue 走 bezier 分支 →
|
|
14
|
+
* getEasing(undefined)='linear'=cubic-bezier(.25,.25,.75,.75),数学上即线性。故本层用**线性**缓动,
|
|
15
|
+
* 非弹簧、非 ease-out。)
|
|
16
|
+
* - renderItemList `transform`(选中项文案变换) → {@link resolveItemText}
|
|
17
|
+
* - constants.ts `DEFAULT_ITEM_HEIGHT=36` / `DEFAULT_SCROLL_DURATION=120`
|
|
8
18
|
*/
|
|
9
|
-
/**
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
return 0;
|
|
13
|
-
const raw = Math.round(scrollTop / itemHeight);
|
|
14
|
-
return Math.max(0, Math.min(count - 1, raw));
|
|
15
|
-
}
|
|
16
|
-
/** The scrollTop that centers a given index. */
|
|
17
|
-
export function indexToOffset(index, itemHeight) {
|
|
18
|
-
return index * itemHeight;
|
|
19
|
-
}
|
|
20
|
-
/** Index of an item by value, or -1. */
|
|
21
|
-
export function indexOfValue(items, value) {
|
|
22
|
-
if (value === undefined)
|
|
23
|
-
return -1;
|
|
24
|
-
return items.findIndex((it) => it.value === value);
|
|
25
|
-
}
|
|
19
|
+
/** Semi scrollList numbers 常量。 */
|
|
20
|
+
export const SCROLL_LIST_DEFAULT_ITEM_HEIGHT = 36;
|
|
21
|
+
export const SCROLL_LIST_DEFAULT_SCROLL_DURATION = 120;
|
|
26
22
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
23
|
+
* 解析一项应展示的文案(对齐 Semi renderItemList)。
|
|
24
|
+
* selected 时优先用 transform(item.transform > 公共 transform)变换,否则 text ?? String(value)。
|
|
29
25
|
*/
|
|
30
|
-
export function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
26
|
+
export function resolveItemText(item, selected, commonTransform) {
|
|
27
|
+
const base = item.text == null ? String(item.value) : item.text;
|
|
28
|
+
if (!selected)
|
|
29
|
+
return base;
|
|
30
|
+
const transform = typeof item.transform === 'function' ? item.transform : commonTransform;
|
|
31
|
+
if (typeof transform === 'function')
|
|
32
|
+
return transform(item.value, base);
|
|
33
|
+
return base;
|
|
38
34
|
}
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/** Last enabled index (for End), or -1 if all disabled. */
|
|
48
|
-
export function lastEnabledIndex(items) {
|
|
49
|
-
for (let i = items.length - 1; i >= 0; i -= 1) {
|
|
50
|
-
if (!items[i]?.disabled)
|
|
51
|
-
return i;
|
|
52
|
-
}
|
|
53
|
-
return -1;
|
|
35
|
+
/**
|
|
36
|
+
* 把某 index 的项**居中**到视窗中线所需的 scrollTop(对齐 Semi scrollToNode):
|
|
37
|
+
* targetTop = node.offsetTop - (wrapperHeight - itemHeight) / 2。
|
|
38
|
+
* offsetTop = index * itemHeight(含 ul 顶部 `:before` 空白,见样式)。
|
|
39
|
+
*/
|
|
40
|
+
export function centerOffset(index, itemHeight, wrapperHeight, topPadding = 0) {
|
|
41
|
+
const nodeTop = topPadding + index * itemHeight;
|
|
42
|
+
return nodeTop - (wrapperHeight - itemHeight) / 2;
|
|
54
43
|
}
|
|
55
44
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
45
|
+
* 给定当前 scrollTop 与视窗高度,求中线最近的**非禁用**项索引(对齐 getNearestNodeInfo)。
|
|
46
|
+
* 中线在视窗几何正中;每项中心 = topPadding + (i + 0.5) * itemHeight - scrollTop。
|
|
47
|
+
* 返回 -1 表示无可选项(全禁用 / 空)。
|
|
59
48
|
*/
|
|
60
|
-
export function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
case 'PageUp': {
|
|
75
|
-
let target = current;
|
|
76
|
-
for (let n = 0; n < page; n += 1) {
|
|
77
|
-
const nxt = nextEnabledIndex(items, target, -1);
|
|
78
|
-
if (nxt === target)
|
|
79
|
-
break;
|
|
80
|
-
target = nxt;
|
|
81
|
-
}
|
|
82
|
-
return target;
|
|
83
|
-
}
|
|
84
|
-
case 'PageDown': {
|
|
85
|
-
let target = current;
|
|
86
|
-
for (let n = 0; n < page; n += 1) {
|
|
87
|
-
const nxt = nextEnabledIndex(items, target, 1);
|
|
88
|
-
if (nxt === target)
|
|
89
|
-
break;
|
|
90
|
-
target = nxt;
|
|
91
|
-
}
|
|
92
|
-
return target;
|
|
49
|
+
export function nearestIndex(scrollTop, itemHeight, wrapperHeight, count, isDisabled, topPadding = 0) {
|
|
50
|
+
if (itemHeight <= 0 || count <= 0)
|
|
51
|
+
return -1;
|
|
52
|
+
const selectorCenter = wrapperHeight / 2;
|
|
53
|
+
let best = -1;
|
|
54
|
+
let bestDist = Infinity;
|
|
55
|
+
for (let i = 0; i < count; i += 1) {
|
|
56
|
+
if (isDisabled(i))
|
|
57
|
+
continue;
|
|
58
|
+
const itemCenter = topPadding + (i + 0.5) * itemHeight - scrollTop;
|
|
59
|
+
const dist = Math.abs(itemCenter - selectorCenter);
|
|
60
|
+
if (dist < bestDist) {
|
|
61
|
+
bestDist = dist;
|
|
62
|
+
best = i;
|
|
93
63
|
}
|
|
94
|
-
default:
|
|
95
|
-
return current;
|
|
96
64
|
}
|
|
65
|
+
return best;
|
|
97
66
|
}
|
|
98
|
-
|
|
99
|
-
// cyclic(循环列)—— 无限轮:用「重复 N 份」+ 中段定位实现。
|
|
100
|
-
// 渲染层把 data 重复 `repeat` 份铺成一个长列表(virtual count = count*repeat),
|
|
101
|
-
// 滚到靠近首/尾时命令式跳回中段(无动画),视觉无缝。下面是纯索引数学。
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
/** 正取模(结果恒非负),把任意整数索引折回 [0, count)。 */
|
|
67
|
+
/** 正取模:把任意整数索引折回 [0, count)(cycled 用)。对齐 Semi `index % list.length` 语义(负值也回正)。 */
|
|
104
68
|
export function wrapIndex(index, count) {
|
|
105
69
|
if (count <= 0)
|
|
106
70
|
return 0;
|
|
107
71
|
return ((index % count) + count) % count;
|
|
108
72
|
}
|
|
109
73
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
74
|
+
* cubic ease-out(先快后缓)。t ∈ [0,1]。通用缓动工具。
|
|
75
|
+
* 注意:ScrollList 落定**不**用它——Semi scrollTo 用的是线性(见 {@link scrollFrame})。
|
|
112
76
|
*/
|
|
113
|
-
export function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return count * Math.max(3, repeat | 1);
|
|
77
|
+
export function easeOut(t) {
|
|
78
|
+
const clamped = t < 0 ? 0 : t > 1 ? 1 : t;
|
|
79
|
+
return 1 - Math.pow(1 - clamped, 3);
|
|
117
80
|
}
|
|
118
81
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
82
|
+
* 缓动滚动的单帧 scrollTop(照搬 Semi scrollTo.ts:from→to over duration,**线性**)。
|
|
83
|
+
* Semi 的 scrollTo 只传 duration 不传 easing → semi-animation 落到 'linear' bezier
|
|
84
|
+
* (cubic-bezier(.25,.25,.75,.75),即匀速 y=x)。故此处用线性插值 `elapsed/duration`。
|
|
85
|
+
* elapsed>=duration 或 duration<=0 时返回 to(落定)。渲染层用 rAF 逐帧调用并写 el.scrollTop。
|
|
121
86
|
*/
|
|
122
|
-
export function
|
|
123
|
-
if (
|
|
124
|
-
return
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
return mid * count + wrapIndex(logical, count);
|
|
87
|
+
export function scrollFrame(from, to, elapsed, duration) {
|
|
88
|
+
if (duration <= 0 || elapsed >= duration)
|
|
89
|
+
return to;
|
|
90
|
+
const p = elapsed / duration; // 线性,对齐 Semi
|
|
91
|
+
return from + (to - from) * p;
|
|
128
92
|
}
|
|
129
93
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
94
|
+
* cycled 头部要补多少「份」完整数据,才能让首节点越过上缓冲区顶(对齐 Semi shouldPrepend)。
|
|
95
|
+
* 照搬 Semi while 循环:`while (baseTop + itemHeight >= wrapperTop - wrapperHeight*ratio) { count++; baseTop -= listHeight }`,
|
|
96
|
+
* 参数化为相对坐标 `firstTop = firstNodeTop - wrapperTop`(首 li 顶相对视窗顶的偏移,可负),不读 DOM。
|
|
97
|
+
* ratio=缓冲区为视窗高度的倍数(init 时 2,滚动调整时 1,对齐 Semi)。
|
|
133
98
|
*/
|
|
134
|
-
export function
|
|
135
|
-
if (count <= 0)
|
|
99
|
+
export function shouldPrepend(firstTop, count, itemHeight, wrapperHeight, ratio = 2) {
|
|
100
|
+
if (count <= 0 || itemHeight <= 0)
|
|
136
101
|
return 0;
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
* @param dt 帧间隔(ms)
|
|
149
|
-
* @param decay 每 ~16.67ms(60fps 一帧)的衰减系数,默认 0.95
|
|
150
|
-
* @param minV 停止阈值(px/ms),默认 0.02
|
|
151
|
-
*/
|
|
152
|
-
export function momentumStep(velocity, dt, decay = 0.95, minV = 0.02) {
|
|
153
|
-
const frames = dt / (1000 / 60);
|
|
154
|
-
const next = velocity * Math.pow(decay, frames);
|
|
155
|
-
// 平均速度积分(梯形)得位移,避免高速时单帧跨度过大。
|
|
156
|
-
const delta = ((velocity + next) / 2) * dt;
|
|
157
|
-
return { velocity: next, delta, done: Math.abs(next) < minV };
|
|
102
|
+
const listHeight = count * itemHeight;
|
|
103
|
+
if (listHeight <= 0)
|
|
104
|
+
return 0;
|
|
105
|
+
const threshold = -wrapperHeight * ratio; // wrapperTop - wrapperHeight*ratio,相对坐标下 wrapperTop=0
|
|
106
|
+
let baseTop = firstTop;
|
|
107
|
+
let n = 0;
|
|
108
|
+
while (baseTop + itemHeight >= threshold) {
|
|
109
|
+
n += 1;
|
|
110
|
+
baseTop -= listHeight;
|
|
111
|
+
}
|
|
112
|
+
return n;
|
|
158
113
|
}
|
|
159
114
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* @param velocity 当前速度(px/ms)
|
|
164
|
-
* @param itemHeight 行高
|
|
165
|
-
* @param count 行数
|
|
166
|
-
* @param projection 速度前瞻系数(默认 80:v*80 px 的滑行预估)
|
|
115
|
+
* cycled 尾部要补多少「份」完整数据,才能让尾节点越过下缓冲区底(对齐 Semi shouldAppend)。
|
|
116
|
+
* 照搬 Semi while 循环:`while (baseTop <= wrapperTop + wrapperHeight*ratio) { count++; baseTop += listHeight }`,
|
|
117
|
+
* 参数化为相对坐标 `lastTop = lastNodeTop - wrapperTop`(尾 li 顶相对视窗顶的偏移),不读 DOM。
|
|
167
118
|
*/
|
|
168
|
-
export function
|
|
169
|
-
if (
|
|
119
|
+
export function shouldAppend(lastTop, count, itemHeight, wrapperHeight, ratio = 2) {
|
|
120
|
+
if (count <= 0 || itemHeight <= 0)
|
|
121
|
+
return 0;
|
|
122
|
+
const listHeight = count * itemHeight;
|
|
123
|
+
if (listHeight <= 0)
|
|
170
124
|
return 0;
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
125
|
+
const threshold = wrapperHeight * ratio; // wrapperTop + wrapperHeight*ratio,相对坐标下 wrapperTop=0
|
|
126
|
+
let baseTop = lastTop;
|
|
127
|
+
let n = 0;
|
|
128
|
+
while (baseTop <= threshold) {
|
|
129
|
+
n += 1;
|
|
130
|
+
baseTop += listHeight;
|
|
131
|
+
}
|
|
132
|
+
return n;
|
|
174
133
|
}
|
|
175
134
|
//# sourceMappingURL=scroll-list.js.map
|
package/dist/scroll-list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-list.js","sourceRoot":"","sources":["../src/scroll-list.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"scroll-list.js","sourceRoot":"","sources":["../src/scroll-list.ts"],"names":[],"mappings":"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"}
|
package/dist/scroll-list.test.js
CHANGED
|
@@ -1,135 +1,125 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveItemText, centerOffset, nearestIndex, wrapIndex, easeOut, scrollFrame, shouldPrepend, shouldAppend, SCROLL_LIST_DEFAULT_ITEM_HEIGHT, SCROLL_LIST_DEFAULT_SCROLL_DURATION, } from './scroll-list.js';
|
|
3
3
|
const items = [
|
|
4
|
-
{ value: 0
|
|
5
|
-
{ value: 1,
|
|
6
|
-
{ value: 2,
|
|
7
|
-
{ value: 3
|
|
8
|
-
{ value: 4,
|
|
9
|
-
{ value: 5
|
|
4
|
+
{ value: 0 },
|
|
5
|
+
{ value: 1, disabled: true },
|
|
6
|
+
{ value: 2, text: '两' },
|
|
7
|
+
{ value: 3 },
|
|
8
|
+
{ value: 4, disabled: true },
|
|
9
|
+
{ value: 5 },
|
|
10
10
|
];
|
|
11
|
-
describe('
|
|
12
|
-
it('
|
|
13
|
-
expect(
|
|
14
|
-
expect(
|
|
15
|
-
expect(offsetToIndex(90, 36, 6)).toBe(3); // 90/36 = 2.5 → 3 (round half up)
|
|
16
|
-
expect(offsetToIndex(9999, 36, 6)).toBe(5); // clamp to last
|
|
17
|
-
expect(offsetToIndex(-50, 36, 6)).toBe(0); // clamp to first
|
|
18
|
-
});
|
|
19
|
-
it('indexToOffset centers an index', () => {
|
|
20
|
-
expect(indexToOffset(0, 36)).toBe(0);
|
|
21
|
-
expect(indexToOffset(3, 36)).toBe(108);
|
|
22
|
-
});
|
|
23
|
-
it('handles degenerate inputs', () => {
|
|
24
|
-
expect(offsetToIndex(10, 0, 6)).toBe(0);
|
|
25
|
-
expect(offsetToIndex(10, 36, 0)).toBe(0);
|
|
11
|
+
describe('constants 对齐 Semi', () => {
|
|
12
|
+
it('DEFAULT_ITEM_HEIGHT=36, DEFAULT_SCROLL_DURATION=120', () => {
|
|
13
|
+
expect(SCROLL_LIST_DEFAULT_ITEM_HEIGHT).toBe(36);
|
|
14
|
+
expect(SCROLL_LIST_DEFAULT_SCROLL_DURATION).toBe(120);
|
|
26
15
|
});
|
|
27
16
|
});
|
|
28
|
-
describe('
|
|
29
|
-
it('
|
|
30
|
-
expect(
|
|
31
|
-
expect(
|
|
32
|
-
expect(indexOfValue(items, undefined)).toBe(-1);
|
|
17
|
+
describe('resolveItemText(对齐 Semi renderItemList transform)', () => {
|
|
18
|
+
it('未选中用 text ?? value', () => {
|
|
19
|
+
expect(resolveItemText({ value: 3 }, false)).toBe('3');
|
|
20
|
+
expect(resolveItemText({ value: 2, text: '两' }, false)).toBe('两');
|
|
33
21
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
expect(
|
|
39
|
-
expect(nextEnabledIndex(items, 2, -1)).toBe(0); // skip disabled 1
|
|
22
|
+
it('选中且有 item.transform 优先用之', () => {
|
|
23
|
+
const item = { value: 8, transform: (v) => `${v}时` };
|
|
24
|
+
expect(resolveItemText(item, true)).toBe('8时');
|
|
25
|
+
// 未选中不变换
|
|
26
|
+
expect(resolveItemText(item, false)).toBe('8');
|
|
40
27
|
});
|
|
41
|
-
it('
|
|
42
|
-
expect(
|
|
43
|
-
expect(nextEnabledIndex(items, 0, -1)).toBe(0); // no enabled before
|
|
28
|
+
it('选中用公共 transform(无 item.transform 时)', () => {
|
|
29
|
+
expect(resolveItemText({ value: 8 }, true, (v) => `第${v}`)).toBe('第8');
|
|
44
30
|
});
|
|
45
|
-
it('
|
|
46
|
-
|
|
47
|
-
expect(
|
|
48
|
-
expect(firstEnabledIndex([{ value: 'x', label: 'x', disabled: true }])).toBe(-1);
|
|
31
|
+
it('item.transform 优先于公共 transform', () => {
|
|
32
|
+
const item = { value: 8, transform: (v) => `A${v}` };
|
|
33
|
+
expect(resolveItemText(item, true, (v) => `B${v}`)).toBe('A8');
|
|
49
34
|
});
|
|
50
35
|
});
|
|
51
|
-
describe('
|
|
52
|
-
it('
|
|
53
|
-
|
|
54
|
-
expect(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
expect(keyboardTarget(items, 3, 'Home')).toBe(0);
|
|
58
|
-
expect(keyboardTarget(items, 0, 'End')).toBe(5);
|
|
36
|
+
describe('centerOffset(对齐 Semi scrollToNode)', () => {
|
|
37
|
+
it('把 index 居中所需 scrollTop = index*ih - (wrapperH - ih)/2', () => {
|
|
38
|
+
// ih=36, wrapperH=300, index=0 → 0 - (300-36)/2 = -132
|
|
39
|
+
expect(centerOffset(0, 36, 300)).toBe(-132);
|
|
40
|
+
// index=5 → 180 - 132 = 48
|
|
41
|
+
expect(centerOffset(5, 36, 300)).toBe(48);
|
|
59
42
|
});
|
|
60
|
-
it('
|
|
61
|
-
|
|
62
|
-
expect(keyboardTarget(items, 0, 'PageDown', 3)).toBe(5);
|
|
63
|
-
// from 0, page 2 → 0→2→3 → index 3
|
|
64
|
-
expect(keyboardTarget(items, 0, 'PageDown', 2)).toBe(3);
|
|
43
|
+
it('含 topPadding 偏移', () => {
|
|
44
|
+
expect(centerOffset(0, 36, 300, 132)).toBe(0); // padding 抵消
|
|
65
45
|
});
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
});
|
|
47
|
+
describe('nearestIndex(对齐 getNearestNodeInfo,跳过禁用)', () => {
|
|
48
|
+
it('中线对准第 i 项时返回 i(非禁用)', () => {
|
|
49
|
+
const ih = 36;
|
|
50
|
+
const wrapperH = 300;
|
|
51
|
+
const isDisabled = (i) => Boolean(items[i]?.disabled);
|
|
52
|
+
// scrollTop 使 index 3 居中:centerOffset(3) = 108 - 132 = -24
|
|
53
|
+
const st = centerOffset(3, ih, wrapperH);
|
|
54
|
+
expect(nearestIndex(st, ih, wrapperH, items.length, isDisabled)).toBe(3);
|
|
55
|
+
});
|
|
56
|
+
it('中线落在禁用项时选最近的非禁用', () => {
|
|
57
|
+
const ih = 36;
|
|
58
|
+
const wrapperH = 300;
|
|
59
|
+
const isDisabled = (i) => Boolean(items[i]?.disabled);
|
|
60
|
+
// 对准 index 1(禁用)→ 应回退到相邻非禁用(0 或 2,距离相等取先命中的 0)
|
|
61
|
+
const st = centerOffset(1, ih, wrapperH);
|
|
62
|
+
const idx = nearestIndex(st, ih, wrapperH, items.length, isDisabled);
|
|
63
|
+
expect(idx === 0 || idx === 2).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it('全禁用或空返回 -1', () => {
|
|
66
|
+
expect(nearestIndex(0, 36, 300, 0, () => false)).toBe(-1);
|
|
67
|
+
expect(nearestIndex(0, 36, 300, 3, () => true)).toBe(-1);
|
|
68
|
+
expect(nearestIndex(0, 0, 300, 3, () => false)).toBe(-1);
|
|
68
69
|
});
|
|
69
70
|
});
|
|
70
|
-
describe('
|
|
71
|
-
it('
|
|
71
|
+
describe('wrapIndex(cycled 取模,对齐 index % list.length)', () => {
|
|
72
|
+
it('折回 [0,count)(含负值回正)', () => {
|
|
72
73
|
expect(wrapIndex(0, 24)).toBe(0);
|
|
73
74
|
expect(wrapIndex(24, 24)).toBe(0);
|
|
74
75
|
expect(wrapIndex(25, 24)).toBe(1);
|
|
75
76
|
expect(wrapIndex(-1, 24)).toBe(23);
|
|
76
|
-
expect(wrapIndex(-25, 24)).toBe(23);
|
|
77
77
|
expect(wrapIndex(5, 0)).toBe(0);
|
|
78
78
|
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
expect(
|
|
83
|
-
expect(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
expect(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
expect(
|
|
95
|
-
expect(
|
|
96
|
-
// 重定位后必同余
|
|
97
|
-
expect(wrapIndex(cyclicRecenter(5, 24, 5), 24)).toBe(5);
|
|
79
|
+
});
|
|
80
|
+
describe('缓动 easeOut / scrollFrame(对齐 Semi scrollTo.ts)', () => {
|
|
81
|
+
it('easeOut 单调、端点 0/1、越界 clamp', () => {
|
|
82
|
+
expect(easeOut(0)).toBe(0);
|
|
83
|
+
expect(easeOut(1)).toBe(1);
|
|
84
|
+
expect(easeOut(-1)).toBe(0);
|
|
85
|
+
expect(easeOut(2)).toBe(1);
|
|
86
|
+
expect(easeOut(0.5)).toBeGreaterThan(0.5); // ease-out 前段更快
|
|
87
|
+
});
|
|
88
|
+
it('scrollFrame 起点=from、终点=to、duration<=0 直接落定', () => {
|
|
89
|
+
expect(scrollFrame(0, 100, 0, 120)).toBe(0);
|
|
90
|
+
expect(scrollFrame(0, 100, 120, 120)).toBe(100);
|
|
91
|
+
expect(scrollFrame(0, 100, 200, 120)).toBe(100); // 超时 clamp
|
|
92
|
+
expect(scrollFrame(0, 100, 50, 0)).toBe(100); // 无动画直接落定
|
|
93
|
+
const mid = scrollFrame(0, 100, 60, 120);
|
|
94
|
+
expect(mid).toBeGreaterThan(0);
|
|
95
|
+
expect(mid).toBeLessThan(100);
|
|
98
96
|
});
|
|
99
97
|
});
|
|
100
|
-
describe('
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
expect(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
expect(
|
|
115
|
-
expect(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
expect(projectSettleIndex(0, 0, 36, 24)).toBe(0);
|
|
126
|
-
// scrollTop=360(行10),向下速度前瞻 80px:(360+80)/36≈12.2 → round 12
|
|
127
|
-
expect(projectSettleIndex(360, 1, 36, 24, 80)).toBe(12);
|
|
128
|
-
// clamp 到末行
|
|
129
|
-
expect(projectSettleIndex(99999, 5, 36, 24)).toBe(23);
|
|
130
|
-
// clamp 到首行
|
|
131
|
-
expect(projectSettleIndex(0, -5, 36, 24)).toBe(0);
|
|
132
|
-
expect(projectSettleIndex(0, 0, 0, 24)).toBe(0);
|
|
98
|
+
describe('shouldPrepend / shouldAppend(cycled 补份数,逐份 while 循环对齐 Semi)', () => {
|
|
99
|
+
// 校准自 Semi 官方 demo 实测:hours(12项)→4 份(48 li)、minutes(60项)→2 份(120 li)。
|
|
100
|
+
// init 基准份 selected(idx=1) 居中 → baseFirstTop=(300-36)/2 - 1*36=96。
|
|
101
|
+
it('hours(count=12)init(ratio=2) 头 2 份 + 尾 1 份,合基准共 4 份(对齐 Semi 48 li)', () => {
|
|
102
|
+
const firstTop = (300 - 36) / 2 - 1 * 36; // 96
|
|
103
|
+
const lastTop = firstTop + (12 - 1) * 36; // 492
|
|
104
|
+
expect(shouldPrepend(firstTop, 12, 36, 300, 2)).toBe(2);
|
|
105
|
+
expect(shouldAppend(lastTop, 12, 36, 300, 2)).toBe(1);
|
|
106
|
+
// 总份 = prepend + 1 基准 + append
|
|
107
|
+
expect(2 + 1 + 1).toBe(4);
|
|
108
|
+
});
|
|
109
|
+
it('minutes(count=60)init(ratio=2) 头 1 份 + 尾 0 份,合基准共 2 份(对齐 Semi 120 li)', () => {
|
|
110
|
+
const firstTop = (300 - 36) / 2 - 1 * 36; // 96
|
|
111
|
+
const lastTop = firstTop + (60 - 1) * 36; // 2220
|
|
112
|
+
expect(shouldPrepend(firstTop, 60, 36, 300, 2)).toBe(1);
|
|
113
|
+
expect(shouldAppend(lastTop, 60, 36, 300, 2)).toBe(0);
|
|
114
|
+
expect(1 + 1 + 0).toBe(2);
|
|
115
|
+
});
|
|
116
|
+
it('滚动调整用 ratio=1(缓冲收窄为 1× 视窗)', () => {
|
|
117
|
+
// 首项恰在视窗顶(firstTop=0):ratio=1 时上方需 1 份缓冲
|
|
118
|
+
expect(shouldPrepend(0, 12, 36, 300, 1)).toBe(1);
|
|
119
|
+
});
|
|
120
|
+
it('退化输入返回 0', () => {
|
|
121
|
+
expect(shouldPrepend(0, 0, 36, 300)).toBe(0);
|
|
122
|
+
expect(shouldAppend(0, 12, 0, 300)).toBe(0);
|
|
133
123
|
});
|
|
134
124
|
});
|
|
135
125
|
//# sourceMappingURL=scroll-list.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-list.test.js","sourceRoot":"","sources":["../src/scroll-list.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"scroll-list.test.js","sourceRoot":"","sources":["../src/scroll-list.test.ts"],"names":[],"mappings":"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"}
|