clxx 2.1.7 → 3.0.0
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/AGENTS.md +2 -1
- package/README.md +147 -22
- package/build/Alert/Wrapper.js +12 -14
- package/build/Alert/style.js +44 -25
- package/build/AutoGrid/index.js +21 -15
- package/build/CarouselNotice/index.d.ts +19 -11
- package/build/CarouselNotice/index.js +80 -74
- package/build/CarouselNotice/style.js +14 -4
- package/build/CitySelect/index.js +81 -71
- package/build/CitySelect/style.js +22 -56
- package/build/Clickable/index.js +7 -0
- package/build/Container/index.d.ts +12 -4
- package/build/Container/index.js +94 -89
- package/build/Countdowner/index.js +4 -2
- package/build/DatePicker/Column.d.ts +9 -0
- package/build/DatePicker/Column.js +330 -0
- package/build/DatePicker/index.d.ts +32 -0
- package/build/DatePicker/index.js +230 -0
- package/build/DatePicker/style.d.ts +6 -0
- package/build/DatePicker/style.js +130 -0
- package/build/Dialog/Wrapper.d.ts +0 -1
- package/build/Dialog/Wrapper.js +22 -12
- package/build/Dialog/index.d.ts +7 -1
- package/build/Dialog/index.js +57 -32
- package/build/Dialog/style.js +6 -2
- package/build/Effect/useInterval.js +6 -3
- package/build/Fixed/index.js +13 -22
- package/build/Flex/FlexItem.d.ts +11 -0
- package/build/Flex/FlexItem.js +26 -0
- package/build/Flex/index.d.ts +2 -10
- package/build/Flex/index.js +12 -22
- package/build/Indicator/index.d.ts +9 -6
- package/build/Indicator/index.js +34 -37
- package/build/Indicator/style.d.ts +4 -3
- package/build/Indicator/style.js +8 -13
- package/build/Loading/Wrapper.js +2 -1
- package/build/Loading/style.js +9 -12
- package/build/Overlay/index.js +6 -1
- package/build/RegionPicker/data.d.ts +6 -0
- package/build/RegionPicker/data.js +14486 -0
- package/build/RegionPicker/index.d.ts +33 -0
- package/build/RegionPicker/index.js +205 -0
- package/build/RegionPicker/style.d.ts +4 -0
- package/build/RegionPicker/style.js +187 -0
- package/build/SafeArea/index.js +14 -17
- package/build/ScrollView/index.d.ts +23 -11
- package/build/ScrollView/index.js +132 -118
- package/build/ScrollView/style.d.ts +1 -1
- package/build/ScrollView/style.js +33 -22
- package/build/Toast/Toast.d.ts +0 -1
- package/build/Toast/Toast.js +6 -4
- package/build/Toast/style.d.ts +3 -10
- package/build/Toast/style.js +41 -45
- package/build/index.d.ts +3 -0
- package/build/index.js +7 -1
- package/build/utils/color.d.ts +5 -0
- package/build/utils/color.js +18 -0
- package/build/utils/dom.js +4 -3
- package/build/utils/theme.d.ts +2 -0
- package/build/utils/theme.js +7 -0
- package/package.json +1 -1
- package/test/src/date-picker/index.jsx +119 -0
- package/test/src/index/index.jsx +2 -0
- package/test/src/index.jsx +1 -0
- package/test/src/loading/index.jsx +2 -2
- package/test/src/region-picker/index.jsx +120 -0
- package/test/src/scrollview/BasicSection.jsx +56 -0
- package/test/src/scrollview/CustomLoadingSection.jsx +53 -0
- package/test/src/scrollview/HeightModeSection.jsx +42 -0
- package/test/src/scrollview/ImperativeSection.jsx +56 -0
- package/test/src/scrollview/NotScrollableSection.jsx +32 -0
- package/test/src/scrollview/PerfSection.jsx +34 -0
- package/test/src/scrollview/index.css +92 -8
- package/test/src/scrollview/index.jsx +13 -45
- package/test/src/toast/index.jsx +1 -0
|
@@ -11,30 +11,16 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.ScrollView =
|
|
14
|
+
exports.ScrollView = void 0;
|
|
15
15
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
16
16
|
const react_1 = require("react");
|
|
17
|
-
const Indicator_1 = require("../Indicator");
|
|
18
|
-
const Row_1 = require("../Flex/Row");
|
|
19
17
|
const style_1 = require("./style");
|
|
20
|
-
function ScrollView(props) {
|
|
21
|
-
const { children, height, reachTopThreshold = 50, onReachTop, reachBottomThreshold = 50, onReachBottom, showLoading = true, loadingContent, onScroll,
|
|
22
|
-
//
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
// 滚动容器
|
|
28
|
-
const container = (0, react_1.useRef)(null);
|
|
29
|
-
// 当前滚动到顶部的距离
|
|
30
|
-
const lastScrollTop = (0, react_1.useRef)(0);
|
|
31
|
-
// 防止重复触发的标记
|
|
32
|
-
const hasReachedTop = (0, react_1.useRef)(false);
|
|
33
|
-
const hasReachedBottom = (0, react_1.useRef)(false);
|
|
34
|
-
// 节流控制
|
|
35
|
-
const throttleTimer = (0, react_1.useRef)(undefined);
|
|
36
|
-
const lastCallTime = (0, react_1.useRef)(0);
|
|
37
|
-
// 使用 ref 保存所有滚动处理需要的 props,彻底消除陈旧闭包
|
|
18
|
+
exports.ScrollView = (0, react_1.forwardRef)(function ScrollView(props, ref) {
|
|
19
|
+
const { children, height, reachTopThreshold = 50, onReachTop, reachBottomThreshold = 50, onReachBottom, showLoading = true, loadingContent, onScroll, containerStyle, wrapperStyle, loadingStyle, style: userStyle } = props, attrs = __rest(props, ["children", "height", "reachTopThreshold", "onReachTop", "reachBottomThreshold", "onReachBottom", "showLoading", "loadingContent", "onScroll", "containerStyle", "wrapperStyle", "loadingStyle", "style"]);
|
|
20
|
+
// 滚动容器与内容包装层
|
|
21
|
+
const containerRef = (0, react_1.useRef)(null);
|
|
22
|
+
const wrapperRef = (0, react_1.useRef)(null);
|
|
23
|
+
// 用 ref 持有最新的回调与阈值,处理函数引用稳定,避免 listener 反复绑定 / 闭包过期
|
|
38
24
|
const propsRef = (0, react_1.useRef)({
|
|
39
25
|
onScroll,
|
|
40
26
|
onReachTop,
|
|
@@ -49,53 +35,37 @@ function ScrollView(props) {
|
|
|
49
35
|
reachTopThreshold,
|
|
50
36
|
reachBottomThreshold,
|
|
51
37
|
};
|
|
52
|
-
//
|
|
53
|
-
const
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return;
|
|
66
|
-
// 初始检查
|
|
67
|
-
checkScrollBar();
|
|
68
|
-
// 使用 ResizeObserver 监听尺寸变化
|
|
69
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
70
|
-
checkScrollBar();
|
|
71
|
-
});
|
|
72
|
-
// 观察容器和内容
|
|
73
|
-
resizeObserver.observe(containerEl);
|
|
74
|
-
if (containerEl.firstElementChild) {
|
|
75
|
-
resizeObserver.observe(containerEl.firstElementChild);
|
|
76
|
-
}
|
|
77
|
-
return () => {
|
|
78
|
-
resizeObserver.disconnect();
|
|
79
|
-
};
|
|
80
|
-
}, [checkScrollBar]);
|
|
81
|
-
// 核心滚动处理逻辑
|
|
82
|
-
// 所有外部值从 ref 读取,deps 为空,引用永远稳定,不存在闭包过期问题
|
|
38
|
+
// 上次 scrollTop(推断方向)
|
|
39
|
+
const lastScrollTopRef = (0, react_1.useRef)(0);
|
|
40
|
+
// 上次方向;delta==0 时沿用,避免水平滚动 / ResizeObserver / 浮点抖动误判
|
|
41
|
+
const lastDirectionRef = (0, react_1.useRef)("downward");
|
|
42
|
+
// 阈值边界防抖:避免在阈值带内反复触发
|
|
43
|
+
const reachedTopRef = (0, react_1.useRef)(false);
|
|
44
|
+
const reachedBottomRef = (0, react_1.useRef)(false);
|
|
45
|
+
// RAF 节流相关
|
|
46
|
+
const rafIdRef = (0, react_1.useRef)(null);
|
|
47
|
+
const pendingEventRef = (0, react_1.useRef)(null);
|
|
48
|
+
// 是否真的可滚动;用于决定是否显示底部 loading
|
|
49
|
+
const [scrollable, setScrollable] = (0, react_1.useState)(false);
|
|
50
|
+
// 真正处理一次滚动(始终从 DOM 读最新位置,避免依赖陈旧 event)
|
|
83
51
|
const processScroll = (0, react_1.useCallback)((rawEvent) => {
|
|
84
|
-
const box =
|
|
52
|
+
const box = containerRef.current;
|
|
85
53
|
if (!box)
|
|
86
54
|
return;
|
|
87
55
|
const { onScroll, onReachTop, onReachBottom, reachTopThreshold, reachBottomThreshold, } = propsRef.current;
|
|
88
56
|
const scrollTop = box.scrollTop;
|
|
89
57
|
const contentHeight = box.scrollHeight;
|
|
90
|
-
// clientHeight 即可视区域高度(不含 border),无需 Math.min(clientHeight, offsetHeight)
|
|
91
58
|
const containerHeight = box.clientHeight;
|
|
92
|
-
const maxScroll = contentHeight - containerHeight;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
59
|
+
const maxScroll = Math.max(0, contentHeight - containerHeight);
|
|
60
|
+
const last = lastScrollTopRef.current;
|
|
61
|
+
const delta = scrollTop - last;
|
|
62
|
+
// 0.5 容差屏蔽 hi-DPI 浮点抖动;|delta|<=0.5 视为无方向变化,沿用上次
|
|
63
|
+
let direction = lastDirectionRef.current;
|
|
64
|
+
if (delta < -0.5)
|
|
65
|
+
direction = "upward";
|
|
66
|
+
else if (delta > 0.5)
|
|
67
|
+
direction = "downward";
|
|
68
|
+
lastDirectionRef.current = direction;
|
|
99
69
|
const event = {
|
|
100
70
|
containerHeight,
|
|
101
71
|
contentHeight,
|
|
@@ -105,81 +75,125 @@ function ScrollView(props) {
|
|
|
105
75
|
rawEvent,
|
|
106
76
|
};
|
|
107
77
|
onScroll === null || onScroll === void 0 ? void 0 : onScroll(event);
|
|
108
|
-
//
|
|
78
|
+
// 触顶:仅在向上滚动且进入阈值带时触发一次
|
|
109
79
|
if (direction === "upward" && scrollTop <= reachTopThreshold) {
|
|
110
|
-
if (!
|
|
111
|
-
|
|
112
|
-
|
|
80
|
+
if (!reachedTopRef.current) {
|
|
81
|
+
reachedTopRef.current = true;
|
|
82
|
+
reachedBottomRef.current = false;
|
|
113
83
|
onReachTop === null || onReachTop === void 0 ? void 0 : onReachTop(event);
|
|
114
84
|
}
|
|
115
85
|
}
|
|
116
86
|
else if (scrollTop > reachTopThreshold) {
|
|
117
|
-
|
|
87
|
+
// 离开阈值带后允许下次再次触发
|
|
88
|
+
reachedTopRef.current = false;
|
|
118
89
|
}
|
|
119
|
-
//
|
|
90
|
+
// 触底:仅在确实可滚动且向下滚动进入阈值带时触发一次
|
|
120
91
|
if (direction === "downward" &&
|
|
121
92
|
maxScroll > 0 &&
|
|
122
93
|
scrollTop >= maxScroll - reachBottomThreshold) {
|
|
123
|
-
if (!
|
|
124
|
-
|
|
125
|
-
|
|
94
|
+
if (!reachedBottomRef.current) {
|
|
95
|
+
reachedBottomRef.current = true;
|
|
96
|
+
reachedTopRef.current = false;
|
|
126
97
|
onReachBottom === null || onReachBottom === void 0 ? void 0 : onReachBottom(event);
|
|
127
98
|
}
|
|
128
99
|
}
|
|
129
100
|
else if (scrollTop < maxScroll - reachBottomThreshold) {
|
|
130
|
-
|
|
101
|
+
reachedBottomRef.current = false;
|
|
131
102
|
}
|
|
132
|
-
|
|
103
|
+
lastScrollTopRef.current = scrollTop;
|
|
133
104
|
}, []);
|
|
134
|
-
//
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
processScroll(rawEvent);
|
|
105
|
+
// RAF 节流:连续滚动期间一帧只处理一次,最后一次 scroll 也会被处理(pending 会触发)
|
|
106
|
+
const scheduleProcess = (0, react_1.useCallback)((rawEvent) => {
|
|
107
|
+
pendingEventRef.current = rawEvent;
|
|
108
|
+
if (rafIdRef.current !== null)
|
|
139
109
|
return;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (throttleTimer.current !== undefined) {
|
|
149
|
-
clearTimeout(throttleTimer.current);
|
|
150
|
-
throttleTimer.current = undefined;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
// 尾部调用:按剩余时间调度,保证滚动停止后最终状态被处理
|
|
155
|
-
if (throttleTimer.current !== undefined) {
|
|
156
|
-
clearTimeout(throttleTimer.current);
|
|
157
|
-
}
|
|
158
|
-
throttleTimer.current = window.setTimeout(() => {
|
|
159
|
-
lastCallTime.current = Date.now();
|
|
160
|
-
throttleTimer.current = undefined;
|
|
161
|
-
// 尾部调用不传 rawEvent(已过期),processScroll 从 DOM 读取实时位置
|
|
162
|
-
processScroll();
|
|
163
|
-
}, scrollThrottle - elapsed);
|
|
164
|
-
}
|
|
165
|
-
}, [scrollThrottle, processScroll]);
|
|
166
|
-
// 清理节流定时器
|
|
110
|
+
rafIdRef.current = requestAnimationFrame(() => {
|
|
111
|
+
rafIdRef.current = null;
|
|
112
|
+
const ev = pendingEventRef.current;
|
|
113
|
+
pendingEventRef.current = null;
|
|
114
|
+
processScroll(ev !== null && ev !== void 0 ? ev : undefined);
|
|
115
|
+
});
|
|
116
|
+
}, [processScroll]);
|
|
117
|
+
// 直接绑定原生 scroll 事件(passive: true),避免 React 合成事件中介
|
|
167
118
|
(0, react_1.useEffect)(() => {
|
|
119
|
+
const box = containerRef.current;
|
|
120
|
+
if (!box)
|
|
121
|
+
return;
|
|
122
|
+
// 用 DOM 当前位置初始化 lastScrollTop,兼容路由切回 / SSR 恢复滚动位置
|
|
123
|
+
lastScrollTopRef.current = box.scrollTop;
|
|
124
|
+
const handler = (e) => scheduleProcess(e);
|
|
125
|
+
box.addEventListener("scroll", handler, { passive: true });
|
|
168
126
|
return () => {
|
|
169
|
-
|
|
170
|
-
|
|
127
|
+
box.removeEventListener("scroll", handler);
|
|
128
|
+
if (rafIdRef.current !== null) {
|
|
129
|
+
cancelAnimationFrame(rafIdRef.current);
|
|
130
|
+
rafIdRef.current = null;
|
|
171
131
|
}
|
|
132
|
+
pendingEventRef.current = null;
|
|
172
133
|
};
|
|
134
|
+
}, [scheduleProcess]);
|
|
135
|
+
// 监听容器与内容尺寸变化,自动维护 scrollable
|
|
136
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
137
|
+
const box = containerRef.current;
|
|
138
|
+
const wrap = wrapperRef.current;
|
|
139
|
+
if (!box || !wrap)
|
|
140
|
+
return;
|
|
141
|
+
const update = () => {
|
|
142
|
+
// +1 容差:屏蔽 hi-DPI 下 scrollHeight = clientHeight + 0.5 之类的误判
|
|
143
|
+
const next = box.scrollHeight - box.clientHeight > 1;
|
|
144
|
+
setScrollable((prev) => (prev === next ? prev : next));
|
|
145
|
+
};
|
|
146
|
+
update();
|
|
147
|
+
// 旧浏览器无 ResizeObserver 时降级:仅初始检测一次
|
|
148
|
+
if (typeof ResizeObserver === "undefined")
|
|
149
|
+
return;
|
|
150
|
+
const ro = new ResizeObserver(update);
|
|
151
|
+
ro.observe(box);
|
|
152
|
+
ro.observe(wrap);
|
|
153
|
+
return () => ro.disconnect();
|
|
173
154
|
}, []);
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
155
|
+
// 暴露命令式 API
|
|
156
|
+
(0, react_1.useImperativeHandle)(ref, () => ({
|
|
157
|
+
getElement: () => containerRef.current,
|
|
158
|
+
scrollTo: ({ top, behavior = "auto" }) => {
|
|
159
|
+
var _a;
|
|
160
|
+
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({ top, behavior });
|
|
161
|
+
},
|
|
162
|
+
scrollToTop: (behavior = "auto") => {
|
|
163
|
+
var _a;
|
|
164
|
+
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({ top: 0, behavior });
|
|
165
|
+
},
|
|
166
|
+
scrollToBottom: (behavior = "auto") => {
|
|
167
|
+
const box = containerRef.current;
|
|
168
|
+
if (!box)
|
|
169
|
+
return;
|
|
170
|
+
box.scrollTo({ top: box.scrollHeight, behavior });
|
|
171
|
+
},
|
|
172
|
+
scrollToElement: (target, options = {}) => {
|
|
173
|
+
var _a, _b;
|
|
174
|
+
const box = containerRef.current;
|
|
175
|
+
if (!box)
|
|
176
|
+
return;
|
|
177
|
+
const el = typeof target === "string"
|
|
178
|
+
? box.querySelector(target)
|
|
179
|
+
: target;
|
|
180
|
+
if (!el || !box.contains(el))
|
|
181
|
+
return;
|
|
182
|
+
// 用 getBoundingClientRect 计算偏移,兼容任意定位上下文
|
|
183
|
+
const top = el.getBoundingClientRect().top -
|
|
184
|
+
box.getBoundingClientRect().top +
|
|
185
|
+
box.scrollTop +
|
|
186
|
+
((_a = options.offset) !== null && _a !== void 0 ? _a : 0);
|
|
187
|
+
box.scrollTo({ top, behavior: (_b = options.behavior) !== null && _b !== void 0 ? _b : "auto" });
|
|
188
|
+
},
|
|
189
|
+
}), []);
|
|
190
|
+
// 合并 height 与外部传入 style;height 优先级高于 userStyle.height
|
|
191
|
+
const mergedStyle = (0, react_1.useMemo)(() => {
|
|
192
|
+
if (height === undefined)
|
|
193
|
+
return userStyle;
|
|
194
|
+
return Object.assign(Object.assign({}, userStyle), { height });
|
|
195
|
+
}, [height, userStyle]);
|
|
196
|
+
// 默认 loading:iOS 风三点跳动
|
|
197
|
+
const defaultLoading = ((0, jsx_runtime_1.jsxs)("div", { css: [style_1.style.loading, loadingStyle], children: [(0, jsx_runtime_1.jsx)("span", { css: style_1.style.loadingDot }), (0, jsx_runtime_1.jsx)("span", { css: style_1.style.loadingDot }), (0, jsx_runtime_1.jsx)("span", { css: style_1.style.loadingDot })] }));
|
|
198
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, attrs, { css: [style_1.style.container, containerStyle], style: mergedStyle, ref: containerRef, children: [(0, jsx_runtime_1.jsx)("div", { ref: wrapperRef, css: wrapperStyle, children: children }), showLoading && scrollable && (loadingContent !== null && loadingContent !== void 0 ? loadingContent : defaultLoading)] })));
|
|
199
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Interpolation, Theme } from "@emotion/react";
|
|
1
|
+
import type { Interpolation, Theme } from "@emotion/react";
|
|
2
2
|
export declare const style: Record<string, Interpolation<Theme>>;
|
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.style = void 0;
|
|
4
|
+
const react_1 = require("@emotion/react");
|
|
5
|
+
// 模仿 iOS「正在输入」气泡的三点呼吸节奏
|
|
6
|
+
const dotPulse = (0, react_1.keyframes) `
|
|
7
|
+
0%, 80%, 100% {
|
|
8
|
+
transform: scale(0.6);
|
|
9
|
+
opacity: 0.35;
|
|
10
|
+
}
|
|
11
|
+
40% {
|
|
12
|
+
transform: scale(1);
|
|
13
|
+
opacity: 1;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
4
16
|
exports.style = {
|
|
5
17
|
container: {
|
|
6
18
|
overflow: "auto",
|
|
7
19
|
height: "100%",
|
|
8
20
|
WebkitOverflowScrolling: "touch",
|
|
9
21
|
},
|
|
10
|
-
loading:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
],
|
|
22
|
+
loading: {
|
|
23
|
+
display: "flex",
|
|
24
|
+
alignItems: "center",
|
|
25
|
+
justifyContent: "center",
|
|
26
|
+
gap: ".12rem",
|
|
27
|
+
padding: ".24rem 0",
|
|
28
|
+
},
|
|
29
|
+
loadingDot: (0, react_1.css) `
|
|
30
|
+
width: 0.12rem;
|
|
31
|
+
height: 0.12rem;
|
|
32
|
+
border-radius: 50%;
|
|
33
|
+
background: #c7c7cc;
|
|
34
|
+
animation: ${dotPulse} 1.2s ease-in-out infinite both;
|
|
35
|
+
|
|
36
|
+
&:nth-of-type(1) {
|
|
37
|
+
animation-delay: -0.32s;
|
|
38
|
+
}
|
|
39
|
+
&:nth-of-type(2) {
|
|
40
|
+
animation-delay: -0.16s;
|
|
41
|
+
}
|
|
42
|
+
`,
|
|
32
43
|
};
|
package/build/Toast/Toast.d.ts
CHANGED
package/build/Toast/Toast.js
CHANGED
|
@@ -68,7 +68,7 @@ function Toast(props) {
|
|
|
68
68
|
showContent = (0, jsx_runtime_1.jsx)("div", { css: [middleStyle, contentStyle], children: content });
|
|
69
69
|
}
|
|
70
70
|
else {
|
|
71
|
-
showContent = ((0, jsx_runtime_1.jsx)("p", { css: [style_1.style.content
|
|
71
|
+
showContent = ((0, jsx_runtime_1.jsx)("p", { css: [style_1.style.content, middleStyle, contentStyle], style: { borderRadius: radius ? radius / 100 + "rem" : 0 }, children: content }));
|
|
72
72
|
}
|
|
73
73
|
// toast消失动画结束触发
|
|
74
74
|
const animationEnd = (event) => {
|
|
@@ -77,15 +77,17 @@ function Toast(props) {
|
|
|
77
77
|
onHide === null || onHide === void 0 ? void 0 : onHide();
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
+
// 位置偏移:所以 top/bottom 作为 inline style、middle 走常量 css
|
|
80
81
|
let positionStyle;
|
|
82
|
+
let positionInline;
|
|
81
83
|
if (position === "top") {
|
|
82
|
-
|
|
84
|
+
positionInline = { top: offsetTop / 100 + "rem" };
|
|
83
85
|
}
|
|
84
86
|
else if (position === "bottom") {
|
|
85
|
-
|
|
87
|
+
positionInline = { bottom: offsetBottom / 100 + "rem" };
|
|
86
88
|
}
|
|
87
89
|
else {
|
|
88
90
|
positionStyle = style_1.style.middle;
|
|
89
91
|
}
|
|
90
|
-
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: [style_1.style.container
|
|
92
|
+
return ((0, jsx_runtime_1.jsx)("div", Object.assign({}, attributes, { css: [style_1.style.container, positionStyle, animation, containerStyle], style: positionInline, onAnimationEnd: animationEnd, children: showContent })));
|
|
91
93
|
}
|
package/build/Toast/style.d.ts
CHANGED
|
@@ -37,21 +37,14 @@ export declare const bottomHideAnimation: {
|
|
|
37
37
|
} & string;
|
|
38
38
|
/**
|
|
39
39
|
* 根据位置和类型获取动画
|
|
40
|
-
* @param position
|
|
41
|
-
* @param type
|
|
42
|
-
* @returns
|
|
43
40
|
*/
|
|
44
41
|
export declare function getAnimation(position: "top" | "middle" | "bottom", type: "show" | "hide"): {
|
|
45
42
|
keyframes: Keyframes;
|
|
46
43
|
animation: import("@emotion/react").SerializedStyles;
|
|
47
44
|
};
|
|
48
45
|
export declare const style: {
|
|
49
|
-
container
|
|
50
|
-
top(offset: number): import("@emotion/react").SerializedStyles;
|
|
46
|
+
container: import("@emotion/react").SerializedStyles;
|
|
51
47
|
middle: import("@emotion/react").SerializedStyles;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
contentMiddle: {
|
|
55
|
-
transform: string;
|
|
56
|
-
};
|
|
48
|
+
content: import("@emotion/react").SerializedStyles;
|
|
49
|
+
contentMiddle: import("@emotion/react").SerializedStyles;
|
|
57
50
|
};
|
package/build/Toast/style.js
CHANGED
|
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.style = exports.bottomHideAnimation = exports.bottomShowAnimation = exports.topHideAnimation = exports.topShowAnimation = exports.middleHideAnimation = exports.middleShowAnimation = void 0;
|
|
4
4
|
exports.getAnimation = getAnimation;
|
|
5
5
|
const react_1 = require("@emotion/react");
|
|
6
|
+
const theme_1 = require("../utils/theme");
|
|
7
|
+
const easing = "cubic-bezier(.22,.61,.36,1)";
|
|
6
8
|
exports.middleShowAnimation = (0, react_1.keyframes) `
|
|
7
9
|
from {
|
|
8
10
|
opacity: 0;
|
|
9
|
-
transform: translateX(-50%) scale(0.
|
|
11
|
+
transform: translateX(-50%) scale(0.92);
|
|
10
12
|
}
|
|
11
13
|
to {
|
|
12
14
|
opacity: 1;
|
|
@@ -20,13 +22,13 @@ exports.middleHideAnimation = (0, react_1.keyframes) `
|
|
|
20
22
|
}
|
|
21
23
|
to {
|
|
22
24
|
opacity: 0;
|
|
23
|
-
transform: translateX(-50%) scale(0.
|
|
25
|
+
transform: translateX(-50%) scale(0.92);
|
|
24
26
|
}
|
|
25
27
|
`;
|
|
26
28
|
exports.topShowAnimation = (0, react_1.keyframes) `
|
|
27
29
|
from {
|
|
28
30
|
opacity: 0;
|
|
29
|
-
transform: translate(-50%, -
|
|
31
|
+
transform: translate(-50%, -120%);
|
|
30
32
|
}
|
|
31
33
|
to {
|
|
32
34
|
opacity: 1;
|
|
@@ -40,13 +42,13 @@ exports.topHideAnimation = (0, react_1.keyframes) `
|
|
|
40
42
|
}
|
|
41
43
|
to {
|
|
42
44
|
opacity: 0;
|
|
43
|
-
transform: translate(-50%, -
|
|
45
|
+
transform: translate(-50%, -120%);
|
|
44
46
|
}
|
|
45
47
|
`;
|
|
46
48
|
exports.bottomShowAnimation = (0, react_1.keyframes) `
|
|
47
49
|
from {
|
|
48
50
|
opacity: 0;
|
|
49
|
-
transform: translate(-50%,
|
|
51
|
+
transform: translate(-50%, 120%);
|
|
50
52
|
}
|
|
51
53
|
to {
|
|
52
54
|
opacity: 1;
|
|
@@ -60,14 +62,11 @@ exports.bottomHideAnimation = (0, react_1.keyframes) `
|
|
|
60
62
|
}
|
|
61
63
|
to {
|
|
62
64
|
opacity: 0;
|
|
63
|
-
transform: translate(-50%,
|
|
65
|
+
transform: translate(-50%, 120%);
|
|
64
66
|
}
|
|
65
67
|
`;
|
|
66
68
|
/**
|
|
67
69
|
* 根据位置和类型获取动画
|
|
68
|
-
* @param position
|
|
69
|
-
* @param type
|
|
70
|
-
* @returns
|
|
71
70
|
*/
|
|
72
71
|
function getAnimation(position, type) {
|
|
73
72
|
const animation = {
|
|
@@ -85,46 +84,43 @@ function getAnimation(position, type) {
|
|
|
85
84
|
return {
|
|
86
85
|
keyframes,
|
|
87
86
|
animation: (0, react_1.css)({
|
|
88
|
-
animation: `${keyframes}
|
|
87
|
+
animation: `${keyframes} 260ms ${easing}`,
|
|
89
88
|
}),
|
|
90
89
|
};
|
|
91
90
|
}
|
|
92
91
|
exports.style = {
|
|
93
|
-
container
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
92
|
+
// 容器静态样式:位置偏移由 container 提供,具体 top/bottom 偏移走 inline style。
|
|
93
|
+
container: (0, react_1.css)({
|
|
94
|
+
position: "fixed",
|
|
95
|
+
left: "50%",
|
|
96
|
+
transform: "translateX(-50%)",
|
|
97
|
+
zIndex: 9999,
|
|
98
|
+
maxWidth: "6rem",
|
|
99
|
+
pointerEvents: "none",
|
|
100
|
+
fontFamily: theme_1.fontStack,
|
|
101
|
+
WebkitFontSmoothing: "antialiased",
|
|
102
|
+
MozOsxFontSmoothing: "grayscale",
|
|
103
|
+
}),
|
|
105
104
|
middle: (0, react_1.css)({ top: "50%" }),
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
126
|
-
},
|
|
127
|
-
contentMiddle: {
|
|
105
|
+
// content 中与 radius 无关的部分作为常量,radius 走 inline style
|
|
106
|
+
content: (0, react_1.css)({
|
|
107
|
+
position: "relative",
|
|
108
|
+
backgroundColor: "rgba(0,0,0,.78)",
|
|
109
|
+
color: "#ffffff",
|
|
110
|
+
margin: 0,
|
|
111
|
+
whiteSpace: "pre-wrap",
|
|
112
|
+
wordBreak: "break-word",
|
|
113
|
+
lineHeight: 1.5,
|
|
114
|
+
fontSize: ".28rem",
|
|
115
|
+
fontWeight: 400,
|
|
116
|
+
letterSpacing: ".01rem",
|
|
117
|
+
textAlign: "center",
|
|
118
|
+
padding: ".2rem .32rem",
|
|
119
|
+
boxShadow: "0 .12rem .32rem rgba(0,0,0,.18)",
|
|
120
|
+
backdropFilter: "blur(20px) saturate(160%)",
|
|
121
|
+
WebkitBackdropFilter: "blur(20px) saturate(160%)",
|
|
122
|
+
}),
|
|
123
|
+
contentMiddle: (0, react_1.css)({
|
|
128
124
|
transform: `translateY(-50%)`,
|
|
129
|
-
},
|
|
125
|
+
}),
|
|
130
126
|
};
|
package/build/index.d.ts
CHANGED
|
@@ -32,5 +32,8 @@ export { SafeArea } from './SafeArea';
|
|
|
32
32
|
export { AutoGrid } from './AutoGrid';
|
|
33
33
|
export { showAlert } from './Alert';
|
|
34
34
|
export { ScrollView } from './ScrollView';
|
|
35
|
+
export type { ScrollViewHandle, ScrollViewProps, ScrollEvent } from './ScrollView';
|
|
35
36
|
export { CarouselNotice } from './CarouselNotice';
|
|
36
37
|
export { CitySelect, showCitySelect } from './CitySelect';
|
|
38
|
+
export { DatePicker, showDatePicker } from './DatePicker';
|
|
39
|
+
export { RegionPicker, showRegionPicker } from './RegionPicker';
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.showUniqToast = exports.showToast = exports.Overlay = exports.Countdowner = exports.ColStart = exports.ColEvenly = exports.ColEnd = exports.ColCenter = exports.ColBetween = exports.ColAround = exports.Col = exports.RowStart = exports.RowEvenly = exports.RowEnd = exports.RowCenter = exports.RowBetween = exports.RowAround = exports.Row = exports.FlexItem = exports.Flex = exports.Container = exports.Ago = exports.useViewport = exports.useWindowResize = exports.useUpdate = exports.useTick = exports.useInterval = exports.createPortalDOM = exports.getHistory = exports.history = exports.createApp = exports.splitValue = exports.normalizeUnit = exports.waitUntil = exports.waitFor = exports.is = exports.defaultScroll = exports.Countdown = exports.calendarTable = exports.registerHostAlias = exports.buildUrlByOption = exports.sendRequest = exports.sugarSend = exports.sendJSON = exports.POST = exports.GET = exports.ago = exports.uniqKey = exports.jsonp = exports.tick = void 0;
|
|
4
|
-
exports.showCitySelect = exports.CitySelect = exports.CarouselNotice = exports.ScrollView = exports.showAlert = exports.AutoGrid = exports.SafeArea = exports.showLoadingAtLeast = exports.showLoading = exports.Indicator = exports.Clickable = exports.showDialog = void 0;
|
|
4
|
+
exports.showRegionPicker = exports.RegionPicker = exports.showDatePicker = exports.DatePicker = exports.showCitySelect = exports.CitySelect = exports.CarouselNotice = exports.ScrollView = exports.showAlert = exports.AutoGrid = exports.SafeArea = exports.showLoadingAtLeast = exports.showLoading = exports.Indicator = exports.Clickable = exports.showDialog = void 0;
|
|
5
5
|
var tick_1 = require("./utils/tick");
|
|
6
6
|
Object.defineProperty(exports, "tick", { enumerable: true, get: function () { return tick_1.tick; } });
|
|
7
7
|
var jsonp_1 = require("./utils/jsonp");
|
|
@@ -100,3 +100,9 @@ Object.defineProperty(exports, "CarouselNotice", { enumerable: true, get: functi
|
|
|
100
100
|
var CitySelect_1 = require("./CitySelect");
|
|
101
101
|
Object.defineProperty(exports, "CitySelect", { enumerable: true, get: function () { return CitySelect_1.CitySelect; } });
|
|
102
102
|
Object.defineProperty(exports, "showCitySelect", { enumerable: true, get: function () { return CitySelect_1.showCitySelect; } });
|
|
103
|
+
var DatePicker_1 = require("./DatePicker");
|
|
104
|
+
Object.defineProperty(exports, "DatePicker", { enumerable: true, get: function () { return DatePicker_1.DatePicker; } });
|
|
105
|
+
Object.defineProperty(exports, "showDatePicker", { enumerable: true, get: function () { return DatePicker_1.showDatePicker; } });
|
|
106
|
+
var RegionPicker_1 = require("./RegionPicker");
|
|
107
|
+
Object.defineProperty(exports, "RegionPicker", { enumerable: true, get: function () { return RegionPicker_1.RegionPicker; } });
|
|
108
|
+
Object.defineProperty(exports, "showRegionPicker", { enumerable: true, get: function () { return RegionPicker_1.showRegionPicker; } });
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.darken = darken;
|
|
4
|
+
/**
|
|
5
|
+
* 将 #rrggbb 颜色按比例变暗;amount 取值 0~1
|
|
6
|
+
* 例:darken("#2f7dff", 0.15) → #2a6cd9(用于派生交互态色)
|
|
7
|
+
*/
|
|
8
|
+
function darken(hex, amount) {
|
|
9
|
+
const m = hex.replace("#", "");
|
|
10
|
+
if (m.length !== 6)
|
|
11
|
+
return hex;
|
|
12
|
+
const r = parseInt(m.slice(0, 2), 16);
|
|
13
|
+
const g = parseInt(m.slice(2, 4), 16);
|
|
14
|
+
const b = parseInt(m.slice(4, 6), 16);
|
|
15
|
+
const factor = (v) => Math.max(0, Math.min(255, Math.round(v * (1 - amount))));
|
|
16
|
+
const toHex = (v) => factor(v).toString(16).padStart(2, "0");
|
|
17
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
18
|
+
}
|