clxx 2.1.8 → 3.0.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/AGENTS.md +2 -1
- package/README.md +147 -22
- package/build/Alert/Wrapper.js +4 -3
- package/build/Alert/style.js +11 -7
- 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 +30 -55
- 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 -7
- package/build/Toast/style.js +33 -41
- 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/createApp.d.ts +16 -2
- package/build/utils/createApp.js +142 -109
- 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
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { ScrollView } from "@";
|
|
3
|
+
|
|
4
|
+
export default function CustomLoadingSection() {
|
|
5
|
+
const [list, setList] = useState(() =>
|
|
6
|
+
Array.from({ length: 5 }, (_, i) => i + 1),
|
|
7
|
+
);
|
|
8
|
+
const [loading, setLoading] = useState(false);
|
|
9
|
+
|
|
10
|
+
const onReachBottom = () => {
|
|
11
|
+
if (loading) return;
|
|
12
|
+
setLoading(true);
|
|
13
|
+
window.setTimeout(() => {
|
|
14
|
+
setList((prev) => [
|
|
15
|
+
...prev,
|
|
16
|
+
...Array.from({ length: 5 }, (_, i) => prev.length + i + 1),
|
|
17
|
+
]);
|
|
18
|
+
setLoading(false);
|
|
19
|
+
}, 600);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div className="section">
|
|
24
|
+
<div className="section-title">
|
|
25
|
+
自定义 loading 内容 + 触底阈值 100px
|
|
26
|
+
</div>
|
|
27
|
+
<div className="section-body" style={{ height: "4rem" }}>
|
|
28
|
+
<ScrollView
|
|
29
|
+
reachBottomThreshold={100}
|
|
30
|
+
onReachBottom={onReachBottom}
|
|
31
|
+
loadingContent={
|
|
32
|
+
<div
|
|
33
|
+
style={{
|
|
34
|
+
padding: "0.2rem",
|
|
35
|
+
textAlign: "center",
|
|
36
|
+
fontSize: "0.24rem",
|
|
37
|
+
color: loading ? "#2f7dff" : "#8e8e93",
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{loading ? "正在加载…" : "上拉加载更多"}
|
|
41
|
+
</div>
|
|
42
|
+
}
|
|
43
|
+
>
|
|
44
|
+
{list.map((n) => (
|
|
45
|
+
<div className="item" key={n}>
|
|
46
|
+
卡片 {n}
|
|
47
|
+
</div>
|
|
48
|
+
))}
|
|
49
|
+
</ScrollView>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ScrollView } from "@";
|
|
2
|
+
|
|
3
|
+
export default function HeightModeSection() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="section">
|
|
6
|
+
<div className="section-title">两种高度方式:prop height vs CSS</div>
|
|
7
|
+
<div className="section-body">
|
|
8
|
+
<div style={{ display: "flex", gap: "0.16rem", padding: "0.16rem" }}>
|
|
9
|
+
<div style={{ flex: 1, border: "1px solid #eee" }}>
|
|
10
|
+
<div className="stat">prop height="2.4rem"</div>
|
|
11
|
+
<ScrollView height="2.4rem">
|
|
12
|
+
{Array.from({ length: 12 }, (_, i) => (
|
|
13
|
+
<div className="item" key={i}>
|
|
14
|
+
A{i + 1}
|
|
15
|
+
</div>
|
|
16
|
+
))}
|
|
17
|
+
</ScrollView>
|
|
18
|
+
</div>
|
|
19
|
+
<div
|
|
20
|
+
style={{
|
|
21
|
+
flex: 1,
|
|
22
|
+
border: "1px solid #eee",
|
|
23
|
+
display: "flex",
|
|
24
|
+
flexDirection: "column",
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
<div className="stat">外层 flex 高 2.4rem</div>
|
|
28
|
+
<div style={{ height: "2.4rem" }}>
|
|
29
|
+
<ScrollView>
|
|
30
|
+
{Array.from({ length: 12 }, (_, i) => (
|
|
31
|
+
<div className="item" key={i}>
|
|
32
|
+
B{i + 1}
|
|
33
|
+
</div>
|
|
34
|
+
))}
|
|
35
|
+
</ScrollView>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { ScrollView } from "@";
|
|
3
|
+
|
|
4
|
+
export default function ImperativeSection() {
|
|
5
|
+
const ref = useRef(null);
|
|
6
|
+
const list = Array.from({ length: 30 }, (_, i) => i + 1);
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div className="section">
|
|
10
|
+
<div className="section-title">命令式 API(forwardRef + handle)</div>
|
|
11
|
+
<div className="section-body" style={{ height: "4rem" }}>
|
|
12
|
+
<ScrollView ref={ref}>
|
|
13
|
+
{list.map((n) => (
|
|
14
|
+
<div
|
|
15
|
+
className={"item" + (n === 18 ? " target" : "")}
|
|
16
|
+
key={n}
|
|
17
|
+
data-index={n}
|
|
18
|
+
>
|
|
19
|
+
Item #{n}
|
|
20
|
+
{n === 18 && " ← 目标项"}
|
|
21
|
+
</div>
|
|
22
|
+
))}
|
|
23
|
+
</ScrollView>
|
|
24
|
+
</div>
|
|
25
|
+
<div className="toolbar">
|
|
26
|
+
<button onClick={() => ref.current?.scrollToTop("smooth")}>
|
|
27
|
+
↑ 顶部
|
|
28
|
+
</button>
|
|
29
|
+
<button onClick={() => ref.current?.scrollToBottom("smooth")}>
|
|
30
|
+
↓ 底部
|
|
31
|
+
</button>
|
|
32
|
+
<button onClick={() => ref.current?.scrollTo({ top: 200 })}>
|
|
33
|
+
跳到 200px
|
|
34
|
+
</button>
|
|
35
|
+
<button
|
|
36
|
+
onClick={() =>
|
|
37
|
+
ref.current?.scrollToElement('[data-index="18"]', {
|
|
38
|
+
behavior: "smooth",
|
|
39
|
+
offset: -20,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
>
|
|
43
|
+
滚到目标项
|
|
44
|
+
</button>
|
|
45
|
+
<button
|
|
46
|
+
onClick={() => {
|
|
47
|
+
const el = ref.current?.getElement();
|
|
48
|
+
console.log("getElement →", el);
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
打印 DOM
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { ScrollView } from "@";
|
|
3
|
+
|
|
4
|
+
export default function NotScrollableSection() {
|
|
5
|
+
const [items, setItems] = useState([1, 2]);
|
|
6
|
+
return (
|
|
7
|
+
<div className="section">
|
|
8
|
+
<div className="section-title">
|
|
9
|
+
内容不足时自动隐藏 loading(点击按钮加内容观察 loading 出现)
|
|
10
|
+
</div>
|
|
11
|
+
<div className="section-body" style={{ height: "3rem" }}>
|
|
12
|
+
<ScrollView showLoading>
|
|
13
|
+
{items.map((n) => (
|
|
14
|
+
<div className="item" key={n}>
|
|
15
|
+
Row {n}
|
|
16
|
+
</div>
|
|
17
|
+
))}
|
|
18
|
+
</ScrollView>
|
|
19
|
+
</div>
|
|
20
|
+
<div className="toolbar">
|
|
21
|
+
<button
|
|
22
|
+
onClick={() =>
|
|
23
|
+
setItems((prev) => [...prev, prev.length + 1, prev.length + 2])
|
|
24
|
+
}
|
|
25
|
+
>
|
|
26
|
+
+ 加 2 行
|
|
27
|
+
</button>
|
|
28
|
+
<button onClick={() => setItems([1, 2])}>重置</button>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { ScrollView } from "@";
|
|
3
|
+
|
|
4
|
+
export default function PerfSection() {
|
|
5
|
+
const ref = useRef(null);
|
|
6
|
+
const [count, setCount] = useState(0);
|
|
7
|
+
const list = Array.from({ length: 1000 }, (_, i) => i + 1);
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
console.log("PerfSection mounted, 1000 items");
|
|
11
|
+
}, []);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className="section">
|
|
15
|
+
<div className="section-title">大列表性能(1000 项 + RAF 节流)</div>
|
|
16
|
+
<div className="stat">onScroll 触发次数: {count}</div>
|
|
17
|
+
<div className="section-body" style={{ height: "4rem" }}>
|
|
18
|
+
<ScrollView ref={ref} onScroll={() => setCount((c) => c + 1)}>
|
|
19
|
+
{list.map((n) => (
|
|
20
|
+
<div className="item" key={n}>
|
|
21
|
+
性能行 {n}
|
|
22
|
+
</div>
|
|
23
|
+
))}
|
|
24
|
+
</ScrollView>
|
|
25
|
+
</div>
|
|
26
|
+
<div className="toolbar">
|
|
27
|
+
<button onClick={() => ref.current?.scrollToTop("smooth")}>
|
|
28
|
+
回顶部
|
|
29
|
+
</button>
|
|
30
|
+
<button onClick={() => setCount(0)}>重置计数</button>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -1,10 +1,94 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
.scrollview-demo {
|
|
2
|
+
padding: 0.2rem;
|
|
3
|
+
font-size: 0.28rem;
|
|
4
|
+
color: #1d1d1f;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.scrollview-demo .section {
|
|
8
|
+
margin-bottom: 0.32rem;
|
|
9
|
+
border-radius: 0.16rem;
|
|
10
|
+
background: #fff;
|
|
11
|
+
box-shadow: 0 0.04rem 0.16rem rgba(0, 0, 0, 0.06);
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.scrollview-demo .section-title {
|
|
16
|
+
padding: 0.18rem 0.24rem;
|
|
17
|
+
font-size: 0.26rem;
|
|
18
|
+
font-weight: 600;
|
|
19
|
+
color: #3c3c43;
|
|
20
|
+
background: #f2f2f7;
|
|
21
|
+
border-bottom: 1px solid rgba(60, 60, 67, 0.18);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.scrollview-demo .section-body {
|
|
25
|
+
position: relative;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.scrollview-demo .section-body .ScrollView {
|
|
29
|
+
background: #f9f9fb;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.scrollview-demo .item {
|
|
33
|
+
padding: 0.24rem 0.3rem;
|
|
34
|
+
font-size: 0.28rem;
|
|
35
|
+
color: #1d1d1f;
|
|
36
|
+
border-bottom: 1px solid rgba(60, 60, 67, 0.12);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.scrollview-demo .item.target {
|
|
40
|
+
background: rgba(47, 125, 255, 0.12);
|
|
41
|
+
color: #2f7dff;
|
|
42
|
+
font-weight: 600;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.scrollview-demo .toolbar {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-wrap: wrap;
|
|
48
|
+
gap: 0.12rem;
|
|
49
|
+
padding: 0.16rem 0.24rem;
|
|
50
|
+
background: #fff;
|
|
51
|
+
border-top: 1px solid rgba(60, 60, 67, 0.12);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.scrollview-demo .toolbar button {
|
|
55
|
+
flex: 1 1 auto;
|
|
56
|
+
min-width: 1.4rem;
|
|
57
|
+
height: 0.64rem;
|
|
58
|
+
font-size: 0.24rem;
|
|
59
|
+
border: 1px solid rgba(60, 60, 67, 0.18);
|
|
60
|
+
border-radius: 0.32rem;
|
|
61
|
+
background: #fff;
|
|
62
|
+
color: #2f7dff;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.scrollview-demo .toolbar button:active {
|
|
67
|
+
opacity: 0.6;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.scrollview-demo .stat {
|
|
71
|
+
padding: 0.12rem 0.24rem;
|
|
72
|
+
font-size: 0.22rem;
|
|
73
|
+
font-family: "SF Mono", "Menlo", monospace;
|
|
74
|
+
color: #6b7280;
|
|
75
|
+
background: #f2f2f7;
|
|
76
|
+
border-bottom: 1px solid rgba(60, 60, 67, 0.12);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.scrollview-demo .badge {
|
|
80
|
+
display: inline-block;
|
|
4
81
|
padding: 0 0.1rem;
|
|
5
|
-
|
|
6
|
-
.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
82
|
+
margin-left: 0.08rem;
|
|
83
|
+
font-size: 0.22rem;
|
|
84
|
+
border-radius: 0.08rem;
|
|
85
|
+
background: rgba(47, 125, 255, 0.12);
|
|
86
|
+
color: #2f7dff;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.scrollview-demo .empty {
|
|
90
|
+
padding: 0.6rem;
|
|
91
|
+
text-align: center;
|
|
92
|
+
color: #8e8e93;
|
|
93
|
+
font-size: 0.26rem;
|
|
10
94
|
}
|
|
@@ -1,52 +1,20 @@
|
|
|
1
1
|
import "./index.css";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import BasicSection from "./BasicSection";
|
|
3
|
+
import ImperativeSection from "./ImperativeSection";
|
|
4
|
+
import CustomLoadingSection from "./CustomLoadingSection";
|
|
5
|
+
import NotScrollableSection from "./NotScrollableSection";
|
|
6
|
+
import PerfSection from "./PerfSection";
|
|
7
|
+
import HeightModeSection from "./HeightModeSection";
|
|
4
8
|
|
|
5
9
|
export default function Index() {
|
|
6
|
-
const [list, setList] = useState([1]);
|
|
7
|
-
const isLoading = useRef(false);
|
|
8
|
-
const [showLoading, setShowLoading] = useState(true);
|
|
9
|
-
|
|
10
|
-
const loadMore = async () => {
|
|
11
|
-
if (!showLoading) return;
|
|
12
|
-
|
|
13
|
-
isLoading.current = true;
|
|
14
|
-
return new Promise((resolve) => {
|
|
15
|
-
window.setTimeout(() => {
|
|
16
|
-
const num = list.length + 1;
|
|
17
|
-
list.push(num);
|
|
18
|
-
setList([...list]);
|
|
19
|
-
resolve();
|
|
20
|
-
isLoading.current = false;
|
|
21
|
-
if (num > 5) {
|
|
22
|
-
setShowLoading(false);
|
|
23
|
-
}
|
|
24
|
-
}, 800);
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
|
|
28
10
|
return (
|
|
29
|
-
<div className="
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (!isLoading.current) {
|
|
37
|
-
loadMore();
|
|
38
|
-
}
|
|
39
|
-
}}
|
|
40
|
-
showLoading={showLoading}
|
|
41
|
-
>
|
|
42
|
-
{list.map((item, index) => {
|
|
43
|
-
return (
|
|
44
|
-
<div className="content" key={index}>
|
|
45
|
-
{item}
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
})}
|
|
49
|
-
</ScrollView>
|
|
11
|
+
<div className="scrollview-demo">
|
|
12
|
+
<BasicSection />
|
|
13
|
+
<ImperativeSection />
|
|
14
|
+
<CustomLoadingSection />
|
|
15
|
+
<NotScrollableSection />
|
|
16
|
+
<PerfSection />
|
|
17
|
+
<HeightModeSection />
|
|
50
18
|
</div>
|
|
51
19
|
);
|
|
52
20
|
}
|