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.
Files changed (55) hide show
  1. package/AGENTS.md +49 -3
  2. package/README.md +6 -3
  3. package/build/Alert/style.js +15 -14
  4. package/build/CarouselNotice/style.js +2 -1
  5. package/build/CitySelect/data.d.ts +1 -1
  6. package/build/CitySelect/data.js +2277 -1674
  7. package/build/CitySelect/index.d.ts +2 -1
  8. package/build/CitySelect/index.js +35 -9
  9. package/build/CitySelect/style.js +52 -48
  10. package/build/Container/index.js +21 -1
  11. package/build/DatePicker/style.d.ts +1 -1
  12. package/build/DatePicker/style.js +39 -35
  13. package/build/Indicator/index.js +2 -1
  14. package/build/Loading/Wrapper.js +3 -2
  15. package/build/Loading/style.js +7 -6
  16. package/build/MapLocationSelection/buildSelectedLocation.d.ts +16 -0
  17. package/build/MapLocationSelection/buildSelectedLocation.js +123 -0
  18. package/build/MapLocationSelection/createProvider.d.ts +8 -0
  19. package/build/MapLocationSelection/createProvider.js +33 -0
  20. package/build/MapLocationSelection/getLocation.d.ts +8 -0
  21. package/build/MapLocationSelection/getLocation.js +112 -0
  22. package/build/MapLocationSelection/index.d.ts +16 -0
  23. package/build/MapLocationSelection/index.js +985 -0
  24. package/build/MapLocationSelection/loader.amap.d.ts +48 -0
  25. package/build/MapLocationSelection/loader.amap.js +125 -0
  26. package/build/MapLocationSelection/loader.bmap.d.ts +8 -0
  27. package/build/MapLocationSelection/loader.bmap.js +60 -0
  28. package/build/MapLocationSelection/provider.amap.d.ts +38 -0
  29. package/build/MapLocationSelection/provider.amap.js +659 -0
  30. package/build/MapLocationSelection/provider.bmap.d.ts +36 -0
  31. package/build/MapLocationSelection/provider.bmap.js +837 -0
  32. package/build/MapLocationSelection/provider.d.ts +45 -0
  33. package/build/MapLocationSelection/provider.js +10 -0
  34. package/build/MapLocationSelection/style.d.ts +4 -0
  35. package/build/MapLocationSelection/style.js +442 -0
  36. package/build/MapLocationSelection/types.d.ts +29 -0
  37. package/build/MapLocationSelection/types.js +22 -0
  38. package/build/MapLocationSelection/userMarker.d.ts +2 -0
  39. package/build/MapLocationSelection/userMarker.js +95 -0
  40. package/build/RegionPicker/data.js +974 -992
  41. package/build/RegionPicker/index.d.ts +3 -2
  42. package/build/RegionPicker/index.js +29 -10
  43. package/build/RegionPicker/style.js +54 -49
  44. package/build/ScrollView/style.js +5 -4
  45. package/build/Toast/style.js +6 -5
  46. package/build/index.d.ts +3 -0
  47. package/build/index.js +8 -2
  48. package/build/utils/rem.d.ts +1 -0
  49. package/build/utils/rem.js +48 -0
  50. package/package.json +2 -2
  51. package/test/src/city-select/index.jsx +28 -15
  52. package/test/src/index/index.jsx +5 -0
  53. package/test/src/index.jsx +1 -0
  54. package/test/src/map-location-selection/index.jsx +192 -0
  55. 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
- // 根据 value 初始化(只在首次 & data 变化时)
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 = data.find((x) => x.value === pv)) !== null && _a !== void 0 ? _a : null;
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 到「最深的未选层」,全部选好时停在 district
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 data;
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, data, provinceNode, cityNode]);
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 && cityNode && districtNode);
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: { value: districtNode.value, label: districtNode.label },
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
- // iOS 风格设计变量
9
- const textPrimary = "#000000";
10
- const textSecondary = "#3c3c43"; // iOS secondaryLabel
11
- const textTertiary = "#8e8e93"; // iOS tertiaryLabel / placeholder
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 = "rgba(0,0,0,.04)"; // 按下态浅灰
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 ? ".28rem" : "0";
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
- // iOS 风标题栏:无底边框,标题加粗居中,左右按钮都用主色
37
+ // 标题栏:底部 hairline 与列表区分;按钮中等字重
36
38
  header: (0, react_1.css)({
37
39
  flexShrink: 0,
38
- height: ".92rem",
40
+ height: (0, rem_1.r)(92),
39
41
  display: "flex",
40
42
  alignItems: "center",
41
43
  justifyContent: "space-between",
42
- padding: "0 .16rem",
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: ".32rem",
50
+ fontSize: (0, rem_1.r)(30),
48
51
  fontWeight: 600,
49
52
  color: textPrimary,
50
- letterSpacing: ".01rem",
53
+ letterSpacing: (0, rem_1.r)(1),
51
54
  }),
52
55
  btn: (0, react_1.css)({
53
- minWidth: "1.1rem",
54
- padding: "0 .08rem",
55
- fontSize: ".3rem",
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: ".92rem",
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: 600,
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: 600,
79
+ fontWeight: 500,
77
80
  "&:active": { opacity: 1, color: textTertiary },
78
81
  }),
79
- // tabs 行:轻量化,激活态用细下划线提示;底部加 hairline 分隔下方列表
82
+ // tabs 行:浅灰底色(与 CitySelect 字母分组标题色一致),激活态细下划线
80
83
  tabs: (0, react_1.css)({
81
84
  flexShrink: 0,
82
85
  display: "flex",
83
86
  alignItems: "stretch",
84
- height: ".8rem",
85
- padding: "0 .16rem",
86
- borderBottom: "1px solid rgba(60,60,67,.18)",
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: "0 .08rem",
95
- fontSize: ".28rem",
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: ".01rem",
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: 500,
114
+ fontWeight: 600,
111
115
  "&::after": {
112
116
  content: '""',
113
117
  position: "absolute",
114
118
  left: "50%",
115
- bottom: ".06rem",
119
+ bottom: (0, rem_1.r)(6),
116
120
  transform: "translateX(-50%)",
117
- width: ".32rem",
118
- height: ".04rem",
121
+ width: (0, rem_1.r)(32),
122
+ height: (0, rem_1.r)(4),
119
123
  backgroundColor: primary,
120
- borderRadius: ".02rem",
124
+ borderRadius: (0, rem_1.r)(2),
121
125
  },
122
126
  }),
123
- // 选项列表(固定高度,避免跳变;6 行 × .88rem = 5.28rem,整体更紧凑)
127
+ // 选项列表:固定高度避免跳变
124
128
  list: (0, react_1.css)({
125
129
  flexShrink: 0,
126
- height: "5.28rem",
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
- // iOS 风列表项:无分隔线,仅按下态浅灰底
137
+ // 列表项:底部 hairline 分隔(CitySelect 风),按下浅灰底
135
138
  listItem: (0, react_1.css)({
136
139
  position: "relative",
137
- height: ".88rem",
140
+ height: (0, rem_1.r)(88),
138
141
  display: "flex",
139
142
  alignItems: "center",
140
- padding: "0 .32rem",
141
- fontSize: ".3rem",
143
+ padding: `0 ${(0, rem_1.r)(30)}`,
144
+ fontSize: (0, rem_1.r)(30),
142
145
  color: textPrimary,
143
- transition: "background-color .15s",
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: ".01rem",
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
- // iOS 风对勾(SF Symbol checkmark 风格)
165
+ // 对勾
161
166
  checkIcon: (0, react_1.css)({
162
- width: ".32rem",
163
- height: ".32rem",
167
+ width: (0, rem_1.r)(32),
168
+ height: (0, rem_1.r)(32),
164
169
  flexShrink: 0,
165
- marginLeft: ".16rem",
170
+ marginLeft: (0, rem_1.r)(16),
166
171
  position: "relative",
167
172
  "&::after": {
168
173
  content: '""',
169
174
  position: "absolute",
170
- left: ".06rem",
171
- top: ".04rem",
172
- width: ".1rem",
173
- height: ".2rem",
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: "0 .03rem .03rem 0",
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: ".6rem 0",
186
+ padding: `${(0, rem_1.r)(60)} 0`,
182
187
  textAlign: "center",
183
- fontSize: ".26rem",
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: ".12rem",
27
- padding: ".24rem 0",
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.12rem;
31
- height: 0.12rem;
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;
@@ -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: "6rem",
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: ".28rem",
115
+ fontSize: (0, rem_1.r)(28),
115
116
  fontWeight: 400,
116
- letterSpacing: ".01rem",
117
+ letterSpacing: (0, rem_1.r)(1),
117
118
  textAlign: "center",
118
- padding: ".2rem .32rem",
119
- boxShadow: "0 .12rem .32rem rgba(0,0,0,.18)",
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.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.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.1",
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
- "start": "tsc -w --pretty",
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
- <button
7
- onClick={() => {
8
- showCitySelect({
9
- onSelect: (city) => {
10
- console.log("选择了城市:", city);
11
- },
12
- getLocation() {
13
- return "北京";
14
- },
15
- });
16
- }}
17
- >
18
- 选择城市
19
- </button>
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
  }
@@ -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() {
@@ -7,6 +7,7 @@ createApp({
7
7
  target: "#root",
8
8
  // maxDocWidth: 10000,
9
9
  maxWidth: 750,
10
+ // designWidth: 375,
10
11
  async render(pathname) {
11
12
  const module = await import(`./${pathname}/index.jsx`);
12
13
  const Page = module.default;