clxx 3.0.1 → 3.0.4
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 +49 -3
- package/README.md +6 -3
- package/build/Alert/style.js +15 -14
- package/build/CarouselNotice/style.js +2 -1
- package/build/CitySelect/data.d.ts +1 -1
- package/build/CitySelect/data.js +2277 -1674
- package/build/CitySelect/index.d.ts +2 -1
- package/build/CitySelect/index.js +35 -9
- package/build/CitySelect/style.js +52 -48
- package/build/Container/index.js +21 -1
- package/build/DatePicker/style.d.ts +1 -1
- package/build/DatePicker/style.js +39 -35
- package/build/Indicator/index.js +2 -1
- package/build/Loading/Wrapper.js +3 -2
- package/build/Loading/style.js +7 -6
- package/build/MapLocationSelection/buildSelectedLocation.d.ts +16 -0
- package/build/MapLocationSelection/buildSelectedLocation.js +123 -0
- package/build/MapLocationSelection/createProvider.d.ts +8 -0
- package/build/MapLocationSelection/createProvider.js +33 -0
- package/build/MapLocationSelection/getLocation.d.ts +8 -0
- package/build/MapLocationSelection/getLocation.js +112 -0
- package/build/MapLocationSelection/index.d.ts +16 -0
- package/build/MapLocationSelection/index.js +985 -0
- package/build/MapLocationSelection/loader.amap.d.ts +48 -0
- package/build/MapLocationSelection/loader.amap.js +125 -0
- package/build/MapLocationSelection/loader.bmap.d.ts +8 -0
- package/build/MapLocationSelection/loader.bmap.js +60 -0
- package/build/MapLocationSelection/provider.amap.d.ts +38 -0
- package/build/MapLocationSelection/provider.amap.js +659 -0
- package/build/MapLocationSelection/provider.bmap.d.ts +36 -0
- package/build/MapLocationSelection/provider.bmap.js +837 -0
- package/build/MapLocationSelection/provider.d.ts +45 -0
- package/build/MapLocationSelection/provider.js +10 -0
- package/build/MapLocationSelection/style.d.ts +4 -0
- package/build/MapLocationSelection/style.js +442 -0
- package/build/MapLocationSelection/types.d.ts +29 -0
- package/build/MapLocationSelection/types.js +22 -0
- package/build/MapLocationSelection/userMarker.d.ts +2 -0
- package/build/MapLocationSelection/userMarker.js +95 -0
- package/build/RegionPicker/data.js +974 -992
- package/build/RegionPicker/index.d.ts +3 -2
- package/build/RegionPicker/index.js +29 -10
- package/build/RegionPicker/style.js +54 -49
- package/build/ScrollView/style.js +5 -4
- package/build/Toast/style.js +6 -5
- package/build/index.d.ts +3 -0
- package/build/index.js +8 -2
- package/build/utils/rem.d.ts +1 -0
- package/build/utils/rem.js +48 -0
- package/package.json +2 -2
- package/test/src/city-select/index.jsx +28 -15
- package/test/src/index/index.jsx +5 -0
- package/test/src/index.jsx +1 -0
- package/test/src/map-location-selection/index.jsx +192 -0
- package/test/src/region-picker/index.jsx +29 -21
|
@@ -8,7 +8,7 @@ export interface RegionNode {
|
|
|
8
8
|
export interface RegionSelection {
|
|
9
9
|
province: RegionNode;
|
|
10
10
|
city: RegionNode;
|
|
11
|
-
district: RegionNode;
|
|
11
|
+
district: RegionNode | null;
|
|
12
12
|
}
|
|
13
13
|
export interface RegionLabels {
|
|
14
14
|
province?: string;
|
|
@@ -25,9 +25,10 @@ export interface RegionPickerProps {
|
|
|
25
25
|
maskClosable?: boolean;
|
|
26
26
|
primary?: string;
|
|
27
27
|
rounded?: boolean;
|
|
28
|
+
taiwanHKMacau?: boolean;
|
|
28
29
|
onClose?: () => void;
|
|
29
30
|
onCancel?: () => void;
|
|
30
31
|
onConfirm?: (selection: RegionSelection) => void;
|
|
31
32
|
}
|
|
32
33
|
export declare function RegionPicker(props: RegionPickerProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
33
|
-
export declare function showRegionPicker(options?: Pick<RegionPickerProps, "value" | "data" | "title" | "cancelText" | "confirmText" | "labels" | "maskClosable" | "primary" | "rounded" | "onCancel" | "onConfirm">): void;
|
|
34
|
+
export declare function showRegionPicker(options?: Pick<RegionPickerProps, "value" | "data" | "title" | "cancelText" | "confirmText" | "labels" | "maskClosable" | "primary" | "rounded" | "taiwanHKMacau" | "onCancel" | "onConfirm">): void;
|
|
@@ -19,6 +19,12 @@ const Dialog_1 = require("../Dialog");
|
|
|
19
19
|
const Clickable_1 = require("../Clickable");
|
|
20
20
|
const style_1 = require("./style");
|
|
21
21
|
const data_1 = require("./data");
|
|
22
|
+
// 港澳台对应的顶层省级 value(台湾、香港、澳门)
|
|
23
|
+
const HK_MO_TW_VALUES = new Set([
|
|
24
|
+
"710000",
|
|
25
|
+
"810000",
|
|
26
|
+
"820000",
|
|
27
|
+
]);
|
|
22
28
|
const DEFAULT_LABELS = {
|
|
23
29
|
province: "省",
|
|
24
30
|
city: "市",
|
|
@@ -26,8 +32,12 @@ const DEFAULT_LABELS = {
|
|
|
26
32
|
};
|
|
27
33
|
const TAB_ORDER = ["province", "city", "district"];
|
|
28
34
|
function RegionPicker(props) {
|
|
29
|
-
const { value, data = data_1.treeRegionData, title = "请选择地区", cancelText = "取消", confirmText = "确定", labels, primary = style_1.DEFAULT_PRIMARY, rounded = true, onClose, onCancel, onConfirm, } = props;
|
|
35
|
+
const { value, data = data_1.treeRegionData, title = "请选择地区", cancelText = "取消", confirmText = "确定", labels, primary = style_1.DEFAULT_PRIMARY, rounded = true, taiwanHKMacau = false, onClose, onCancel, onConfirm, } = props;
|
|
30
36
|
const style = (0, react_1.useMemo)(() => (0, style_1.createStyle)(primary, rounded), [primary, rounded]);
|
|
37
|
+
// 过滤后的顶层数据:仅在 data / taiwanHKMacau 变化时重建
|
|
38
|
+
const effectiveData = (0, react_1.useMemo)(() => taiwanHKMacau
|
|
39
|
+
? data
|
|
40
|
+
: data.filter((x) => !HK_MO_TW_VALUES.has(x.value)), [data, taiwanHKMacau]);
|
|
31
41
|
const lab = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, DEFAULT_LABELS), labels)), [labels]);
|
|
32
42
|
// === 选中状态 ===
|
|
33
43
|
// 当前每级选中节点;未选为 null
|
|
@@ -36,23 +46,26 @@ function RegionPicker(props) {
|
|
|
36
46
|
const [districtNode, setDistrictNode] = (0, react_1.useState)(null);
|
|
37
47
|
// 当前激活 tab
|
|
38
48
|
const [activeTab, setActiveTab] = (0, react_1.useState)("province");
|
|
39
|
-
//
|
|
49
|
+
// 初始化 / data 恢复选中里允许 city 无 children(部分地区没有区级)
|
|
40
50
|
(0, react_1.useEffect)(() => {
|
|
41
51
|
var _a, _b, _c, _d, _e;
|
|
42
52
|
if (!value)
|
|
43
53
|
return;
|
|
44
54
|
const [pv, cv, dv] = value;
|
|
45
|
-
const p = (_a =
|
|
55
|
+
const p = (_a = effectiveData.find((x) => x.value === pv)) !== null && _a !== void 0 ? _a : null;
|
|
46
56
|
const c = (_c = (_b = p === null || p === void 0 ? void 0 : p.children) === null || _b === void 0 ? void 0 : _b.find((x) => x.value === cv)) !== null && _c !== void 0 ? _c : null;
|
|
47
57
|
const d = (_e = (_d = c === null || c === void 0 ? void 0 : c.children) === null || _d === void 0 ? void 0 : _d.find((x) => x.value === dv)) !== null && _e !== void 0 ? _e : null;
|
|
48
58
|
setProvinceNode(p);
|
|
49
59
|
setCityNode(c);
|
|
50
60
|
setDistrictNode(d);
|
|
51
|
-
// 定位 activeTab
|
|
61
|
+
// 定位 activeTab 到「最深的未选层」;
|
|
62
|
+
// 如果选中的市无 children,则停在 city
|
|
52
63
|
if (!p)
|
|
53
64
|
setActiveTab("province");
|
|
54
65
|
else if (!c)
|
|
55
66
|
setActiveTab("city");
|
|
67
|
+
else if (!c.children || c.children.length === 0)
|
|
68
|
+
setActiveTab("city");
|
|
56
69
|
else
|
|
57
70
|
setActiveTab("district");
|
|
58
71
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -61,11 +74,11 @@ function RegionPicker(props) {
|
|
|
61
74
|
const currentList = (0, react_1.useMemo)(() => {
|
|
62
75
|
var _a, _b;
|
|
63
76
|
if (activeTab === "province")
|
|
64
|
-
return
|
|
77
|
+
return effectiveData;
|
|
65
78
|
if (activeTab === "city")
|
|
66
79
|
return (_a = provinceNode === null || provinceNode === void 0 ? void 0 : provinceNode.children) !== null && _a !== void 0 ? _a : [];
|
|
67
80
|
return (_b = cityNode === null || cityNode === void 0 ? void 0 : cityNode.children) !== null && _b !== void 0 ? _b : [];
|
|
68
|
-
}, [activeTab,
|
|
81
|
+
}, [activeTab, effectiveData, provinceNode, cityNode]);
|
|
69
82
|
const selectedValueOfTab = (tab) => {
|
|
70
83
|
var _a, _b, _c;
|
|
71
84
|
if (tab === "province")
|
|
@@ -74,13 +87,13 @@ function RegionPicker(props) {
|
|
|
74
87
|
return (_b = cityNode === null || cityNode === void 0 ? void 0 : cityNode.value) !== null && _b !== void 0 ? _b : null;
|
|
75
88
|
return (_c = districtNode === null || districtNode === void 0 ? void 0 : districtNode.value) !== null && _c !== void 0 ? _c : null;
|
|
76
89
|
};
|
|
77
|
-
// tab
|
|
90
|
+
// tab 是否可点击:上级已选;district 额外要求 city 有子级
|
|
78
91
|
const tabEnabled = (tab) => {
|
|
79
92
|
if (tab === "province")
|
|
80
93
|
return true;
|
|
81
94
|
if (tab === "city")
|
|
82
95
|
return !!provinceNode;
|
|
83
|
-
return !!cityNode;
|
|
96
|
+
return !!(cityNode && cityNode.children && cityNode.children.length > 0);
|
|
84
97
|
};
|
|
85
98
|
// 点击列表项
|
|
86
99
|
const handlePick = (item) => {
|
|
@@ -146,14 +159,20 @@ function RegionPicker(props) {
|
|
|
146
159
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
147
160
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
148
161
|
};
|
|
149
|
-
const canConfirm = !!(provinceNode &&
|
|
162
|
+
const canConfirm = !!(provinceNode &&
|
|
163
|
+
cityNode &&
|
|
164
|
+
(!cityNode.children || cityNode.children.length === 0 || districtNode));
|
|
150
165
|
const handleConfirm = () => {
|
|
151
166
|
if (!canConfirm)
|
|
152
167
|
return;
|
|
168
|
+
if (!provinceNode || !cityNode)
|
|
169
|
+
return;
|
|
153
170
|
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm({
|
|
154
171
|
province: { value: provinceNode.value, label: provinceNode.label },
|
|
155
172
|
city: { value: cityNode.value, label: cityNode.label },
|
|
156
|
-
district:
|
|
173
|
+
district: districtNode
|
|
174
|
+
? { value: districtNode.value, label: districtNode.label }
|
|
175
|
+
: null,
|
|
157
176
|
});
|
|
158
177
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
159
178
|
};
|
|
@@ -5,16 +5,18 @@ exports.createStyle = createStyle;
|
|
|
5
5
|
const react_1 = require("@emotion/react");
|
|
6
6
|
const color_1 = require("../utils/color");
|
|
7
7
|
const theme_1 = require("../utils/theme");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
8
|
+
const rem_1 = require("../utils/rem");
|
|
9
|
+
// 与 CitySelect 一致的设计变量(带线条风格)
|
|
10
|
+
const textPrimary = "#1f2328";
|
|
11
|
+
const textSecondary = "#6b7280";
|
|
12
|
+
const textTertiary = "#9ca3af";
|
|
12
13
|
const bgPage = "#ffffff";
|
|
13
|
-
const bgSubtle = "
|
|
14
|
+
const bgSubtle = "#f5f6f8";
|
|
15
|
+
const border = "#e5e7eb";
|
|
14
16
|
exports.DEFAULT_PRIMARY = "#2f7dff";
|
|
15
17
|
function createStyle(primary, rounded = true) {
|
|
16
18
|
const primaryActive = (0, color_1.darken)(primary, 0.15);
|
|
17
|
-
const sheetRadius = rounded ?
|
|
19
|
+
const sheetRadius = rounded ? (0, rem_1.r)(24) : "0";
|
|
18
20
|
return {
|
|
19
21
|
// 内容容器:动画/遮罩/全屏由 Dialog 提供,这里只保留视觉与排版
|
|
20
22
|
sheet: (0, react_1.css)({
|
|
@@ -32,29 +34,30 @@ function createStyle(primary, rounded = true) {
|
|
|
32
34
|
WebkitFontSmoothing: "antialiased",
|
|
33
35
|
MozOsxFontSmoothing: "grayscale",
|
|
34
36
|
}),
|
|
35
|
-
//
|
|
37
|
+
// 标题栏:底部 hairline 与列表区分;按钮中等字重
|
|
36
38
|
header: (0, react_1.css)({
|
|
37
39
|
flexShrink: 0,
|
|
38
|
-
height:
|
|
40
|
+
height: (0, rem_1.r)(92),
|
|
39
41
|
display: "flex",
|
|
40
42
|
alignItems: "center",
|
|
41
43
|
justifyContent: "space-between",
|
|
42
|
-
padding:
|
|
44
|
+
padding: `0 ${(0, rem_1.r)(16)}`,
|
|
45
|
+
borderBottom: `1px solid ${border}`,
|
|
43
46
|
}),
|
|
44
47
|
title: (0, react_1.css)({
|
|
45
48
|
flex: 1,
|
|
46
49
|
textAlign: "center",
|
|
47
|
-
fontSize:
|
|
50
|
+
fontSize: (0, rem_1.r)(30),
|
|
48
51
|
fontWeight: 600,
|
|
49
52
|
color: textPrimary,
|
|
50
|
-
letterSpacing:
|
|
53
|
+
letterSpacing: (0, rem_1.r)(1),
|
|
51
54
|
}),
|
|
52
55
|
btn: (0, react_1.css)({
|
|
53
|
-
minWidth:
|
|
54
|
-
padding:
|
|
55
|
-
fontSize:
|
|
56
|
+
minWidth: (0, rem_1.r)(110),
|
|
57
|
+
padding: `0 ${(0, rem_1.r)(8)}`,
|
|
58
|
+
fontSize: (0, rem_1.r)(28),
|
|
56
59
|
fontWeight: 400,
|
|
57
|
-
lineHeight:
|
|
60
|
+
lineHeight: (0, rem_1.r)(92),
|
|
58
61
|
cursor: "pointer",
|
|
59
62
|
transition: "opacity .15s, color .15s",
|
|
60
63
|
}),
|
|
@@ -65,7 +68,7 @@ function createStyle(primary, rounded = true) {
|
|
|
65
68
|
}),
|
|
66
69
|
btnConfirm: (0, react_1.css)({
|
|
67
70
|
textAlign: "right",
|
|
68
|
-
fontWeight:
|
|
71
|
+
fontWeight: 500,
|
|
69
72
|
color: primary,
|
|
70
73
|
"&:active": { color: primaryActive, opacity: 0.65 },
|
|
71
74
|
}),
|
|
@@ -73,17 +76,18 @@ function createStyle(primary, rounded = true) {
|
|
|
73
76
|
color: textTertiary,
|
|
74
77
|
cursor: "not-allowed",
|
|
75
78
|
pointerEvents: "none",
|
|
76
|
-
fontWeight:
|
|
79
|
+
fontWeight: 500,
|
|
77
80
|
"&:active": { opacity: 1, color: textTertiary },
|
|
78
81
|
}),
|
|
79
|
-
// tabs
|
|
82
|
+
// tabs 行:浅灰底色(与 CitySelect 字母分组标题色一致),激活态细下划线
|
|
80
83
|
tabs: (0, react_1.css)({
|
|
81
84
|
flexShrink: 0,
|
|
82
85
|
display: "flex",
|
|
83
86
|
alignItems: "stretch",
|
|
84
|
-
height:
|
|
85
|
-
padding:
|
|
86
|
-
|
|
87
|
+
height: (0, rem_1.r)(80),
|
|
88
|
+
padding: `0 ${(0, rem_1.r)(16)}`,
|
|
89
|
+
backgroundColor: bgSubtle,
|
|
90
|
+
borderBottom: `1px solid ${border}`,
|
|
87
91
|
}),
|
|
88
92
|
tab: (0, react_1.css)({
|
|
89
93
|
flex: 1,
|
|
@@ -91,8 +95,8 @@ function createStyle(primary, rounded = true) {
|
|
|
91
95
|
display: "flex",
|
|
92
96
|
alignItems: "center",
|
|
93
97
|
justifyContent: "center",
|
|
94
|
-
padding:
|
|
95
|
-
fontSize:
|
|
98
|
+
padding: `0 ${(0, rem_1.r)(8)}`,
|
|
99
|
+
fontSize: (0, rem_1.r)(26),
|
|
96
100
|
color: textSecondary,
|
|
97
101
|
position: "relative",
|
|
98
102
|
cursor: "pointer",
|
|
@@ -100,47 +104,48 @@ function createStyle(primary, rounded = true) {
|
|
|
100
104
|
whiteSpace: "nowrap",
|
|
101
105
|
overflow: "hidden",
|
|
102
106
|
textOverflow: "ellipsis",
|
|
103
|
-
letterSpacing:
|
|
107
|
+
letterSpacing: (0, rem_1.r)(1),
|
|
104
108
|
}),
|
|
105
109
|
tabPlaceholder: (0, react_1.css)({
|
|
106
110
|
color: textTertiary,
|
|
107
111
|
}),
|
|
108
112
|
tabActive: (0, react_1.css)({
|
|
109
113
|
color: primary,
|
|
110
|
-
fontWeight:
|
|
114
|
+
fontWeight: 600,
|
|
111
115
|
"&::after": {
|
|
112
116
|
content: '""',
|
|
113
117
|
position: "absolute",
|
|
114
118
|
left: "50%",
|
|
115
|
-
bottom:
|
|
119
|
+
bottom: (0, rem_1.r)(6),
|
|
116
120
|
transform: "translateX(-50%)",
|
|
117
|
-
width:
|
|
118
|
-
height:
|
|
121
|
+
width: (0, rem_1.r)(32),
|
|
122
|
+
height: (0, rem_1.r)(4),
|
|
119
123
|
backgroundColor: primary,
|
|
120
|
-
borderRadius:
|
|
124
|
+
borderRadius: (0, rem_1.r)(2),
|
|
121
125
|
},
|
|
122
126
|
}),
|
|
123
|
-
//
|
|
127
|
+
// 选项列表:固定高度避免跳变
|
|
124
128
|
list: (0, react_1.css)({
|
|
125
129
|
flexShrink: 0,
|
|
126
|
-
height:
|
|
130
|
+
height: (0, rem_1.r)(528),
|
|
127
131
|
overflowY: "auto",
|
|
128
132
|
overflowX: "hidden",
|
|
129
133
|
WebkitOverflowScrolling: "touch",
|
|
130
134
|
overscrollBehavior: "contain",
|
|
131
135
|
backgroundColor: bgPage,
|
|
132
|
-
paddingBottom: ".12rem",
|
|
133
136
|
}),
|
|
134
|
-
//
|
|
137
|
+
// 列表项:底部 hairline 分隔(CitySelect 风),按下浅灰底
|
|
135
138
|
listItem: (0, react_1.css)({
|
|
136
139
|
position: "relative",
|
|
137
|
-
height:
|
|
140
|
+
height: (0, rem_1.r)(88),
|
|
138
141
|
display: "flex",
|
|
139
142
|
alignItems: "center",
|
|
140
|
-
padding:
|
|
141
|
-
fontSize:
|
|
143
|
+
padding: `0 ${(0, rem_1.r)(30)}`,
|
|
144
|
+
fontSize: (0, rem_1.r)(30),
|
|
142
145
|
color: textPrimary,
|
|
143
|
-
|
|
146
|
+
backgroundColor: bgPage,
|
|
147
|
+
borderBottom: `1px solid ${border}`,
|
|
148
|
+
transition: "background-color .12s",
|
|
144
149
|
"&:active": {
|
|
145
150
|
backgroundColor: bgSubtle,
|
|
146
151
|
},
|
|
@@ -151,36 +156,36 @@ function createStyle(primary, rounded = true) {
|
|
|
151
156
|
whiteSpace: "nowrap",
|
|
152
157
|
overflow: "hidden",
|
|
153
158
|
textOverflow: "ellipsis",
|
|
154
|
-
letterSpacing:
|
|
159
|
+
letterSpacing: (0, rem_1.r)(1),
|
|
155
160
|
}),
|
|
156
161
|
listItemSelected: (0, react_1.css)({
|
|
157
162
|
color: primary,
|
|
158
163
|
fontWeight: 500,
|
|
159
164
|
}),
|
|
160
|
-
//
|
|
165
|
+
// 对勾
|
|
161
166
|
checkIcon: (0, react_1.css)({
|
|
162
|
-
width:
|
|
163
|
-
height:
|
|
167
|
+
width: (0, rem_1.r)(32),
|
|
168
|
+
height: (0, rem_1.r)(32),
|
|
164
169
|
flexShrink: 0,
|
|
165
|
-
marginLeft:
|
|
170
|
+
marginLeft: (0, rem_1.r)(16),
|
|
166
171
|
position: "relative",
|
|
167
172
|
"&::after": {
|
|
168
173
|
content: '""',
|
|
169
174
|
position: "absolute",
|
|
170
|
-
left:
|
|
171
|
-
top:
|
|
172
|
-
width:
|
|
173
|
-
height:
|
|
175
|
+
left: (0, rem_1.r)(6),
|
|
176
|
+
top: (0, rem_1.r)(4),
|
|
177
|
+
width: (0, rem_1.r)(10),
|
|
178
|
+
height: (0, rem_1.r)(20),
|
|
174
179
|
border: `solid ${primary}`,
|
|
175
|
-
borderWidth:
|
|
180
|
+
borderWidth: `0 ${(0, rem_1.r)(3)} ${(0, rem_1.r)(3)} 0`,
|
|
176
181
|
transform: "rotate(45deg)",
|
|
177
182
|
},
|
|
178
183
|
}),
|
|
179
184
|
// 空数据占位
|
|
180
185
|
empty: (0, react_1.css)({
|
|
181
|
-
padding:
|
|
186
|
+
padding: `${(0, rem_1.r)(60)} 0`,
|
|
182
187
|
textAlign: "center",
|
|
183
|
-
fontSize:
|
|
188
|
+
fontSize: (0, rem_1.r)(26),
|
|
184
189
|
color: textTertiary,
|
|
185
190
|
}),
|
|
186
191
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.style = void 0;
|
|
4
4
|
const react_1 = require("@emotion/react");
|
|
5
|
+
const rem_1 = require("../utils/rem");
|
|
5
6
|
// 模仿 iOS「正在输入」气泡的三点呼吸节奏
|
|
6
7
|
const dotPulse = (0, react_1.keyframes) `
|
|
7
8
|
0%, 80%, 100% {
|
|
@@ -23,12 +24,12 @@ exports.style = {
|
|
|
23
24
|
display: "flex",
|
|
24
25
|
alignItems: "center",
|
|
25
26
|
justifyContent: "center",
|
|
26
|
-
gap:
|
|
27
|
-
padding:
|
|
27
|
+
gap: (0, rem_1.r)(12),
|
|
28
|
+
padding: `${(0, rem_1.r)(24)} 0`,
|
|
28
29
|
},
|
|
29
30
|
loadingDot: (0, react_1.css) `
|
|
30
|
-
width: 0.
|
|
31
|
-
height: 0.
|
|
31
|
+
width: ${(0, rem_1.r)(12)};
|
|
32
|
+
height: ${(0, rem_1.r)(12)};
|
|
32
33
|
border-radius: 50%;
|
|
33
34
|
background: #c7c7cc;
|
|
34
35
|
animation: ${dotPulse} 1.2s ease-in-out infinite both;
|
package/build/Toast/style.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.style = exports.bottomHideAnimation = exports.bottomShowAnimation = expo
|
|
|
4
4
|
exports.getAnimation = getAnimation;
|
|
5
5
|
const react_1 = require("@emotion/react");
|
|
6
6
|
const theme_1 = require("../utils/theme");
|
|
7
|
+
const rem_1 = require("../utils/rem");
|
|
7
8
|
const easing = "cubic-bezier(.22,.61,.36,1)";
|
|
8
9
|
exports.middleShowAnimation = (0, react_1.keyframes) `
|
|
9
10
|
from {
|
|
@@ -95,7 +96,7 @@ exports.style = {
|
|
|
95
96
|
left: "50%",
|
|
96
97
|
transform: "translateX(-50%)",
|
|
97
98
|
zIndex: 9999,
|
|
98
|
-
maxWidth:
|
|
99
|
+
maxWidth: (0, rem_1.r)(600),
|
|
99
100
|
pointerEvents: "none",
|
|
100
101
|
fontFamily: theme_1.fontStack,
|
|
101
102
|
WebkitFontSmoothing: "antialiased",
|
|
@@ -111,12 +112,12 @@ exports.style = {
|
|
|
111
112
|
whiteSpace: "pre-wrap",
|
|
112
113
|
wordBreak: "break-word",
|
|
113
114
|
lineHeight: 1.5,
|
|
114
|
-
fontSize:
|
|
115
|
+
fontSize: (0, rem_1.r)(28),
|
|
115
116
|
fontWeight: 400,
|
|
116
|
-
letterSpacing:
|
|
117
|
+
letterSpacing: (0, rem_1.r)(1),
|
|
117
118
|
textAlign: "center",
|
|
118
|
-
padding:
|
|
119
|
-
boxShadow:
|
|
119
|
+
padding: `${(0, rem_1.r)(20)} ${(0, rem_1.r)(32)}`,
|
|
120
|
+
boxShadow: `0 ${(0, rem_1.r)(12)} ${(0, rem_1.r)(32)} rgba(0,0,0,.18)`,
|
|
120
121
|
backdropFilter: "blur(20px) saturate(160%)",
|
|
121
122
|
WebkitBackdropFilter: "blur(20px) saturate(160%)",
|
|
122
123
|
}),
|
package/build/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { defaultScroll } from './utils/defaultScroll';
|
|
|
9
9
|
export { is } from './utils/is';
|
|
10
10
|
export { waitFor, waitUntil } from './utils/wait';
|
|
11
11
|
export { normalizeUnit, splitValue } from './utils/cssUtil';
|
|
12
|
+
export { r } from './utils/rem';
|
|
12
13
|
export { createApp, history, getHistory } from './utils/createApp';
|
|
13
14
|
export { createPortalDOM } from './utils/dom';
|
|
14
15
|
export { useInterval } from './Effect/useInterval';
|
|
@@ -37,3 +38,5 @@ export { CarouselNotice } from './CarouselNotice';
|
|
|
37
38
|
export { CitySelect, showCitySelect } from './CitySelect';
|
|
38
39
|
export { DatePicker, showDatePicker } from './DatePicker';
|
|
39
40
|
export { RegionPicker, showRegionPicker } from './RegionPicker';
|
|
41
|
+
export { MapLocationSelection, showMapLocationSelection, getLocation, } from './MapLocationSelection';
|
|
42
|
+
export type { MapLocationSelectionProps, SelectedLocation, GetLocationOptions, } from './MapLocationSelection';
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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;
|
|
3
|
+
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.r = 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.getLocation = exports.showMapLocationSelection = exports.MapLocationSelection = 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 = exports.showUniqToast = 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");
|
|
@@ -32,6 +32,8 @@ Object.defineProperty(exports, "waitUntil", { enumerable: true, get: function ()
|
|
|
32
32
|
var cssUtil_1 = require("./utils/cssUtil");
|
|
33
33
|
Object.defineProperty(exports, "normalizeUnit", { enumerable: true, get: function () { return cssUtil_1.normalizeUnit; } });
|
|
34
34
|
Object.defineProperty(exports, "splitValue", { enumerable: true, get: function () { return cssUtil_1.splitValue; } });
|
|
35
|
+
var rem_1 = require("./utils/rem");
|
|
36
|
+
Object.defineProperty(exports, "r", { enumerable: true, get: function () { return rem_1.r; } });
|
|
35
37
|
var createApp_1 = require("./utils/createApp");
|
|
36
38
|
Object.defineProperty(exports, "createApp", { enumerable: true, get: function () { return createApp_1.createApp; } });
|
|
37
39
|
Object.defineProperty(exports, "history", { enumerable: true, get: function () { return createApp_1.history; } });
|
|
@@ -106,3 +108,7 @@ Object.defineProperty(exports, "showDatePicker", { enumerable: true, get: functi
|
|
|
106
108
|
var RegionPicker_1 = require("./RegionPicker");
|
|
107
109
|
Object.defineProperty(exports, "RegionPicker", { enumerable: true, get: function () { return RegionPicker_1.RegionPicker; } });
|
|
108
110
|
Object.defineProperty(exports, "showRegionPicker", { enumerable: true, get: function () { return RegionPicker_1.showRegionPicker; } });
|
|
111
|
+
var MapLocationSelection_1 = require("./MapLocationSelection");
|
|
112
|
+
Object.defineProperty(exports, "MapLocationSelection", { enumerable: true, get: function () { return MapLocationSelection_1.MapLocationSelection; } });
|
|
113
|
+
Object.defineProperty(exports, "showMapLocationSelection", { enumerable: true, get: function () { return MapLocationSelection_1.showMapLocationSelection; } });
|
|
114
|
+
Object.defineProperty(exports, "getLocation", { enumerable: true, get: function () { return MapLocationSelection_1.getLocation; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function r(px750: number): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.r = r;
|
|
4
|
+
// 把 750 设计稿下的像素值转成响应式 css 长度。
|
|
5
|
+
//
|
|
6
|
+
// 库内组件统一使用 r() 表达尺寸,不再写 ".28rem" 字面量——这样即便用户在
|
|
7
|
+
// Container 上传入非 750 的 designWidth(如 375 / 1080),库内组件的视觉比例
|
|
8
|
+
// 仍然按 750 设计稿计算,不会被放大或缩小。
|
|
9
|
+
//
|
|
10
|
+
// 实现原理:依赖 Container 注入的 --clxx-px 变量。
|
|
11
|
+
// - --clxx-px 的语义是「750 设计稿下的 1px 在当前视口下渲染成多少 css px」
|
|
12
|
+
// 即 --clxx-px = clamp(viewport, maxWidth) / 750(单位 px)
|
|
13
|
+
// - r(28) → calc(28 * var(--clxx-px, 1px))
|
|
14
|
+
// 视口 750 时 = 28px
|
|
15
|
+
// 视口 375 时 = 14px
|
|
16
|
+
// 视口 1080(无 maxWidth)时 = 40.32px
|
|
17
|
+
// —— 与原 ".28rem" 在默认 designWidth=750 + 同视口下完全一致
|
|
18
|
+
//
|
|
19
|
+
// fallback 1px:用户未挂 Container 时(或 SSR 首屏未注入 :root 变量),
|
|
20
|
+
// calc 不会因 var() 解析失败而整体 invalid,组件至少能以 750 设计稿原像素显示,
|
|
21
|
+
// 不会坍缩成 width:auto / padding:0。
|
|
22
|
+
//
|
|
23
|
+
// 与「写字面 rem」相比的关键差异:
|
|
24
|
+
// - rem 字面量受 html font-size 影响,html font-size 由 Container 按
|
|
25
|
+
// **用户的** designWidth 计算 —— 用户改 designWidth=375 时库内 rem 视觉翻倍;
|
|
26
|
+
// - r() 走独立 CSS 变量 --clxx-px,与用户 designWidth 完全解耦,永远稳。
|
|
27
|
+
//
|
|
28
|
+
// 性能:calc/var 是 specified→computed 一次求值,结果进 computed style 缓存,
|
|
29
|
+
// 不会每帧重算。同 px 值复用同一字符串实例(cache),减少 GC 压力,emotion
|
|
30
|
+
// className hash 命中率也更高。
|
|
31
|
+
//
|
|
32
|
+
// @param px750 在 750 设计稿下的像素值
|
|
33
|
+
// @returns css 长度字符串,可直接喂给 emotion css 对象 / 模板字符串 / 内联 style
|
|
34
|
+
//
|
|
35
|
+
// @example
|
|
36
|
+
// // before
|
|
37
|
+
// const style = css({ padding: ".2rem .32rem" });
|
|
38
|
+
// // after
|
|
39
|
+
// const style = css({ padding: `${r(20)} ${r(32)}` });
|
|
40
|
+
const cache = new Map();
|
|
41
|
+
function r(px750) {
|
|
42
|
+
const cached = cache.get(px750);
|
|
43
|
+
if (cached !== undefined)
|
|
44
|
+
return cached;
|
|
45
|
+
const value = `calc(${px750} * var(--clxx-px, 1px))`;
|
|
46
|
+
cache.set(px750, value);
|
|
47
|
+
return value;
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clxx",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.4",
|
|
4
4
|
"description": "Basic JS library for mobile devices",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"example": "example"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"
|
|
11
|
+
"dev": "tsc -w --pretty",
|
|
12
12
|
"build": "rimraf ./build && tsc",
|
|
13
13
|
"pub": "npm run build && npm publish"
|
|
14
14
|
},
|
|
@@ -1,21 +1,34 @@
|
|
|
1
1
|
import { showCitySelect } from "@";
|
|
2
|
-
import { useEffect } from "react";
|
|
3
2
|
|
|
4
3
|
export default function Index() {
|
|
5
4
|
return (
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "0.2rem", padding: "0.3rem" }}>
|
|
6
|
+
<button
|
|
7
|
+
onClick={() => {
|
|
8
|
+
showCitySelect({
|
|
9
|
+
onSelect: (city) => {
|
|
10
|
+
console.log("选择了城市:", city);
|
|
11
|
+
},
|
|
12
|
+
getLocation() {
|
|
13
|
+
return "北京";
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}}
|
|
17
|
+
>
|
|
18
|
+
选择城市(默认:不含港澳台)
|
|
19
|
+
</button>
|
|
20
|
+
<button
|
|
21
|
+
onClick={() => {
|
|
22
|
+
showCitySelect({
|
|
23
|
+
taiwanHKMacau: true,
|
|
24
|
+
onSelect: (city) => {
|
|
25
|
+
console.log("选择了城市:", city);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
选择城市(含港澳台)
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
20
33
|
);
|
|
21
34
|
}
|
package/test/src/index/index.jsx
CHANGED
|
@@ -19,6 +19,11 @@ const pageConfig = [
|
|
|
19
19
|
{ path: "city-select", title: "CitySelect城市选择器", enable: true },
|
|
20
20
|
{ path: "date-picker", title: "DatePicker日期时间选择器", enable: true },
|
|
21
21
|
{ path: "region-picker", title: "RegionPicker省市区选择器", enable: true },
|
|
22
|
+
{
|
|
23
|
+
path: "map-location-selection",
|
|
24
|
+
title: "MapLocationSelection地图选址",
|
|
25
|
+
enable: true,
|
|
26
|
+
},
|
|
22
27
|
];
|
|
23
28
|
|
|
24
29
|
export default function Index() {
|