@tarojs/components-react 4.1.7-beta.1 → 4.1.7-beta.3

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 (60) hide show
  1. package/dist/components/button/index.js +20 -7
  2. package/dist/components/button/index.js.map +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/original/components/button/index.js +100 -0
  5. package/dist/original/components/button/index.js.map +1 -0
  6. package/dist/original/components/button/style/index.css +3 -0
  7. package/dist/original/components/button/style/index.css.map +1 -0
  8. package/dist/original/components/icon/index.js +36 -0
  9. package/dist/original/components/icon/index.js.map +1 -0
  10. package/dist/original/components/icon/style/index.css +3 -0
  11. package/dist/original/components/icon/style/index.css.map +1 -0
  12. package/dist/original/components/image/index.js +146 -0
  13. package/dist/original/components/image/index.js.map +1 -0
  14. package/dist/original/components/image/style/index.css +3 -0
  15. package/dist/original/components/image/style/index.css.map +1 -0
  16. package/dist/original/components/input/index.js +233 -0
  17. package/dist/original/components/input/index.js.map +1 -0
  18. package/dist/original/components/input/style/index.css +3 -0
  19. package/dist/original/components/input/style/index.css.map +1 -0
  20. package/dist/original/components/picker/index.js +788 -0
  21. package/dist/original/components/picker/index.js.map +1 -0
  22. package/dist/original/components/picker/picker-group.js +491 -0
  23. package/dist/original/components/picker/picker-group.js.map +1 -0
  24. package/dist/{components/picker/react-style/style.css → original/components/picker/style/index.css} +2 -1
  25. package/dist/original/components/picker/style/index.css.map +1 -0
  26. package/dist/original/components/pull-down-refresh/index.js +320 -0
  27. package/dist/original/components/pull-down-refresh/index.js.map +1 -0
  28. package/dist/original/components/pull-down-refresh/style/index.css +3 -0
  29. package/dist/original/components/pull-down-refresh/style/index.css.map +1 -0
  30. package/dist/original/components/refresher/index.js +7 -0
  31. package/dist/original/components/refresher/index.js.map +1 -0
  32. package/dist/original/components/scroll-view/index.js +189 -0
  33. package/dist/original/components/scroll-view/index.js.map +1 -0
  34. package/dist/original/components/scroll-view/style/index.css +3 -0
  35. package/dist/original/components/scroll-view/style/index.css.map +1 -0
  36. package/dist/original/components/swiper/index.js +461 -0
  37. package/dist/original/components/swiper/index.js.map +1 -0
  38. package/dist/original/components/swiper/style/index.css +3 -0
  39. package/dist/original/components/swiper/style/index.css.map +1 -0
  40. package/dist/original/components/text/index.js +28 -0
  41. package/dist/original/components/text/index.js.map +1 -0
  42. package/dist/original/components/text/style/index.css +3 -0
  43. package/dist/original/components/text/style/index.css.map +1 -0
  44. package/dist/original/components/view/index.js +80 -0
  45. package/dist/original/components/view/index.js.map +1 -0
  46. package/dist/original/index.css +2 -0
  47. package/dist/original/index.css.map +1 -0
  48. package/dist/original/index.js +15 -0
  49. package/dist/original/index.js.map +1 -0
  50. package/dist/original/utils/hooks.react.js +15 -0
  51. package/dist/original/utils/hooks.react.js.map +1 -0
  52. package/dist/original/utils/index.js +162 -0
  53. package/dist/original/utils/index.js.map +1 -0
  54. package/dist/solid/components/button/index.js +20 -7
  55. package/dist/solid/components/button/index.js.map +1 -1
  56. package/dist/solid/index.css +1 -1
  57. package/package.json +8 -6
  58. package/dist/components/picker/react-style/style.css.map +0 -1
  59. package/dist/components/picker/react-style/style.js +0 -4
  60. package/dist/components/picker/react-style/style.js.map +0 -1
@@ -0,0 +1,788 @@
1
+ import { __rest } from 'tslib';
2
+ import './style/index.css';
3
+ import { View } from '@tarojs/components';
4
+ import classNames from 'classnames';
5
+ import React__default from 'react';
6
+ import { verifyValue, verifyTime, hoursRange, minutesRange, verifyDate, getYearRange, getMonthRange, getDayRange, compareTime, omit } from '../../utils/index.js';
7
+ import { PickerGroup } from './picker-group.js';
8
+ import { jsx, jsxs } from 'react/jsx-runtime';
9
+
10
+ const EMPTY_ARRAY = [];
11
+ const EMPTY_OBJECT = {};
12
+ // 语言映射函数
13
+ function getLanguageText(lang) {
14
+ const isEnglish = lang === 'en-US' || lang === 'en-GB';
15
+ return {
16
+ confirm: isEnglish ? 'Confirm' : '确定',
17
+ cancel: isEnglish ? 'Cancel' : '取消',
18
+ year: isEnglish ? 'Year ' : '年',
19
+ month: isEnglish ? 'Month ' : '月',
20
+ day: isEnglish ? 'Day ' : '日'
21
+ };
22
+ }
23
+ // 数据验证函数
24
+ function validateRegionData(data) {
25
+ let componentName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Picker';
26
+ if (!data) {
27
+ return {
28
+ valid: false,
29
+ error: `${componentName}: regionData is required for region mode`
30
+ };
31
+ }
32
+ if (!Array.isArray(data)) {
33
+ return {
34
+ valid: false,
35
+ error: `${componentName}: regionData must be an array`
36
+ };
37
+ }
38
+ if (data.length === 0) {
39
+ return {
40
+ valid: false,
41
+ error: `${componentName}: regionData cannot be empty`
42
+ };
43
+ }
44
+ // 检查数据结构
45
+ const validateItem = (item, path) => {
46
+ if (!item || typeof item !== 'object') {
47
+ return {
48
+ valid: false,
49
+ error: `${componentName}: Invalid item at ${path}`
50
+ };
51
+ }
52
+ if (!item.value || typeof item.value !== 'string') {
53
+ return {
54
+ valid: false,
55
+ error: `${componentName}: Missing or invalid 'value' field at ${path}`
56
+ };
57
+ }
58
+ if (!item.code || typeof item.code !== 'string') {
59
+ return {
60
+ valid: false,
61
+ error: `${componentName}: Missing or invalid 'code' field at ${path}`
62
+ };
63
+ }
64
+ if (item.postcode !== undefined && typeof item.postcode !== 'string') {
65
+ return {
66
+ valid: false,
67
+ error: `${componentName}: Invalid 'postcode' field at ${path}`
68
+ };
69
+ }
70
+ if (item.children && !Array.isArray(item.children)) {
71
+ return {
72
+ valid: false,
73
+ error: `${componentName}: 'children' must be an array at ${path}`
74
+ };
75
+ }
76
+ if (item.children) {
77
+ for (let i = 0; i < item.children.length; i++) {
78
+ const childResult = validateItem(item.children[i], `${path}.children[${i}]`);
79
+ if (!childResult.valid) return childResult;
80
+ }
81
+ }
82
+ return {
83
+ valid: true
84
+ };
85
+ };
86
+ for (let i = 0; i < data.length; i++) {
87
+ const result = validateItem(data[i], `regionData[${i}]`);
88
+ if (!result.valid) return result;
89
+ }
90
+ return {
91
+ valid: true
92
+ };
93
+ }
94
+ // 普通函数
95
+ function getRegionColumnsCount(level) {
96
+ switch (level) {
97
+ case 'province':
98
+ return 1;
99
+ case 'city':
100
+ return 2;
101
+ case 'region':
102
+ return 3;
103
+ default:
104
+ return 3;
105
+ // 默认显示省市区/县三列
106
+ }
107
+ }
108
+ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
109
+ var _a, _b;
110
+ const {
111
+ mode = 'selector',
112
+ disabled = false,
113
+ range = EMPTY_ARRAY,
114
+ rangeKey,
115
+ value,
116
+ start = '',
117
+ end = '',
118
+ fields = 'day',
119
+ headerText,
120
+ level = 'region',
121
+ regionData,
122
+ textProps = EMPTY_OBJECT,
123
+ colors = EMPTY_OBJECT,
124
+ onChange,
125
+ onColumnChange,
126
+ onCancel,
127
+ children,
128
+ formType,
129
+ lang
130
+ } = props,
131
+ restProps = __rest(props, ["mode", "disabled", "range", "rangeKey", "value", "start", "end", "fields", "headerText", "level", "regionData", "textProps", "colors", "onChange", "onColumnChange", "onCancel", "children", "formType", "lang"]);
132
+ const indexRef = React__default.useRef([]);
133
+ const pickerDateRef = React__default.useRef();
134
+ // 记录是否是用户滚动
135
+ const isInitializationCompletedRef = React__default.useRef(false);
136
+ const [state, setState] = React__default.useState({
137
+ pickerValue: value || EMPTY_ARRAY,
138
+ selectedIndices: EMPTY_ARRAY.slice(),
139
+ // 索引数组
140
+ hidden: true,
141
+ fadeOut: false,
142
+ isWillLoadCalled: false,
143
+ timestamp: 0 // 用以部分模式下强制刷新组件的的时间戳,多用于反复限位
144
+ });
145
+ // 在组件内部
146
+ const [columnsCount, setColumnsCount] = React__default.useState(() => getRegionColumnsCount(level));
147
+ // 只在level变化时更新列数
148
+ React__default.useEffect(() => {
149
+ setColumnsCount(getRegionColumnsCount(level));
150
+ }, [level]);
151
+ // 获取当前索引数组
152
+ const getIndices = React__default.useCallback(() => {
153
+ return indexRef.current;
154
+ }, []);
155
+ // 处理属性变化
156
+ const handleProps = React__default.useCallback(() => {
157
+ var _a;
158
+ if (mode === 'selector') {
159
+ const val = value;
160
+ indexRef.current = [verifyValue(val, range) ? Math.floor(val) : 0];
161
+ } else if (mode === 'multiSelector') {
162
+ const val = value;
163
+ indexRef.current = [];
164
+ range.forEach((rangeItem, index) => {
165
+ const valItem = val === null || val === void 0 ? void 0 : val[index];
166
+ const item = verifyValue(valItem, rangeItem) ? Math.floor(valItem) : 0;
167
+ indexRef.current.push(item);
168
+ });
169
+ } else if (mode === 'time') {
170
+ let val = value;
171
+ if (!verifyTime(val)) {
172
+ console.warn('time picker value illegal');
173
+ val = '0:0';
174
+ }
175
+ const time = val.split(':').map(n => +n);
176
+ // 在 hoursRange 和 minutesRange 中找到对应的索引
177
+ const hourIndex = hoursRange.findIndex(item => parseInt(item) === time[0]);
178
+ const minuteIndex = minutesRange.findIndex(item => parseInt(item) === time[1]);
179
+ // 确保索引在有效范围内
180
+ const safeHourIndex = hourIndex >= 0 ? hourIndex : 0; // 默认为第一项
181
+ const safeMinuteIndex = minuteIndex >= 0 ? minuteIndex : 0; // 默认为第一项
182
+ indexRef.current = [Math.max(0, Math.min(safeHourIndex, hoursRange.length - 1)), Math.max(0, Math.min(safeMinuteIndex, minutesRange.length - 1))];
183
+ } else if (mode === 'date') {
184
+ const val = value;
185
+ let _value = verifyDate(val) || new Date(new Date().setHours(0, 0, 0, 0));
186
+ const _start = verifyDate(start) || new Date('1875/01/01');
187
+ const _end = verifyDate(end) || new Date('2100/01/01');
188
+ if (!(_start <= _end)) {
189
+ throw new Error(`Picker start time must be less than end time.`);
190
+ }
191
+ if (!(_value >= _start && _value <= _end)) {
192
+ _value = _start;
193
+ }
194
+ const currentYear = _value.getFullYear();
195
+ const currentMonth = _value.getMonth() + 1;
196
+ const currentDay = _value.getDate();
197
+ const yearRange = getYearRange(_start.getFullYear(), _end.getFullYear());
198
+ const monthRange = getMonthRange(_start, _end, currentYear);
199
+ const dayRange = getDayRange(_start, _end, currentYear, currentMonth);
200
+ indexRef.current = [yearRange.indexOf(currentYear), monthRange.indexOf(currentMonth), dayRange.indexOf(currentDay)];
201
+ if (!pickerDateRef.current || pickerDateRef.current._value.getTime() !== _value.getTime() || pickerDateRef.current._start.getTime() !== _start.getTime() || pickerDateRef.current._end.getTime() !== _end.getTime()) {
202
+ pickerDateRef.current = {
203
+ _value,
204
+ _start,
205
+ _end,
206
+ _updateValue: [currentYear, currentMonth, currentDay]
207
+ };
208
+ }
209
+ } else if (mode === 'region') {
210
+ // region 模式处理 - 验证数据
211
+ if (!regionData) {
212
+ console.error('Picker: regionData is required for region mode');
213
+ indexRef.current = [0];
214
+ return;
215
+ }
216
+ const validation = validateRegionData(regionData, 'Picker');
217
+ if (!validation.valid) {
218
+ console.error(validation.error);
219
+ indexRef.current = [0];
220
+ return;
221
+ }
222
+ // 获取列数
223
+ const val = Array.isArray(value) ? value : [];
224
+ // 根据level和当前值确定索引
225
+ indexRef.current = [];
226
+ let currentData = regionData;
227
+ for (let i = 0; i < columnsCount; i++) {
228
+ if (!(currentData === null || currentData === void 0 ? void 0 : currentData.length)) {
229
+ indexRef.current.push(0);
230
+ continue;
231
+ }
232
+ let idx = 0;
233
+ if (typeof val[i] === 'number') {
234
+ const rawIdx = val[i];
235
+ idx = rawIdx >= 0 && rawIdx < currentData.length ? rawIdx : 0;
236
+ } else if (typeof val[i] === 'string') {
237
+ const parsed = parseInt(val[i], 10);
238
+ idx = parsed >= 0 && parsed < currentData.length ? parsed : 0;
239
+ }
240
+ indexRef.current.push(idx);
241
+ currentData = ((_a = currentData[idx]) === null || _a === void 0 ? void 0 : _a.children) || [];
242
+ }
243
+ } else {
244
+ throw new Error(`Picker not support "${mode}" mode.`);
245
+ }
246
+ // 更新索引值
247
+ const newIndices = getIndices();
248
+ setState(prev => Object.assign(Object.assign({}, prev), {
249
+ selectedIndices: newIndices,
250
+ pickerValue: value || EMPTY_ARRAY
251
+ }));
252
+ }, [mode, range, value, start, end, fields, regionData, level, columnsCount, getIndices]);
253
+ // 组件初始化
254
+ React__default.useEffect(() => {
255
+ setState(prev => Object.assign(Object.assign({}, prev), {
256
+ isWillLoadCalled: true
257
+ }));
258
+ handleProps();
259
+ }, []);
260
+ // 属性变化监听 - 添加 value 依赖以支持联动选择器
261
+ React__default.useEffect(() => {
262
+ if (state.isWillLoadCalled) {
263
+ handleProps();
264
+ }
265
+ }, [handleProps, state.isWillLoadCalled, JSON.stringify(value)]);
266
+ // 显示 Picker
267
+ const showPicker = React__default.useCallback(() => {
268
+ if (disabled) return;
269
+ isInitializationCompletedRef.current = false;
270
+ const newIndices = getIndices();
271
+ setState(prev => Object.assign(Object.assign({}, prev), {
272
+ selectedIndices: newIndices,
273
+ hidden: false
274
+ }));
275
+ }, [disabled, getIndices]);
276
+ // 隐藏 Picker
277
+ const hidePicker = React__default.useCallback(() => {
278
+ isInitializationCompletedRef.current = false;
279
+ // 动画暂时不支持,暂时屏蔽相关样式挂载逻辑
280
+ // setState(prev => ({ ...prev, fadeOut: true }))
281
+ // setTimeout(() => {
282
+ // setState(prev => ({
283
+ // ...prev,
284
+ // hidden: true,
285
+ // fadeOut: false
286
+ // }))
287
+ // }, 350)
288
+ setState(prev => Object.assign(Object.assign({}, prev), {
289
+ hidden: true
290
+ }));
291
+ }, []);
292
+ // 更新索引
293
+ const updateIndex = React__default.useCallback(function (index, columnId) {
294
+ let needRevise = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
295
+ let isUserScrollRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
296
+ const columnIndex = Number(columnId);
297
+ let finalIndices = [...state.selectedIndices];
298
+ finalIndices[columnIndex] = index;
299
+ let hasLimited = false;
300
+ // region 模式的级联更新逻辑
301
+ if (mode === 'region' && regionData) {
302
+ if (isUserScrollRef && !isInitializationCompletedRef.current) {
303
+ isInitializationCompletedRef.current = true;
304
+ }
305
+ if (!isInitializationCompletedRef.current) {
306
+ return;
307
+ }
308
+ // 重置后续列
309
+ for (let i = columnIndex + 1; i < columnsCount; i++) {
310
+ finalIndices[i] = 0;
311
+ }
312
+ setState(prev => Object.assign(Object.assign({}, prev), {
313
+ selectedIndices: finalIndices
314
+ }));
315
+ return; // 直接返回
316
+ }
317
+ // time picker
318
+ if (needRevise && mode === 'time') {
319
+ let startTime = start;
320
+ let endTime = end;
321
+ if (!verifyTime(startTime)) startTime = '00:00';
322
+ if (!verifyTime(endTime)) endTime = '23:59';
323
+ if (!compareTime(startTime, endTime)) return false;
324
+ const timeRanges = [hoursRange.slice(), minutesRange.slice()];
325
+ // 然后基于更新后的索引数组计算时间
326
+ const timeStr = finalIndices.map((idx, i) => {
327
+ const rangeIdx = Math.max(0, Math.min(idx, timeRanges[i].length - 1));
328
+ return timeRanges[i][rangeIdx] || '00';
329
+ }).join(':');
330
+ // 检查是否需要限位
331
+ if (!compareTime(startTime, timeStr)) {
332
+ // 修正到 start
333
+ const startParts = startTime.split(':').map(part => parseInt(part));
334
+ const newIndices = startParts.map((time, i) => {
335
+ const idx = timeRanges[i].findIndex(item => parseInt(item) === time);
336
+ return idx >= 0 ? idx : 0;
337
+ });
338
+ finalIndices = [...newIndices];
339
+ hasLimited = true;
340
+ } else if (!compareTime(timeStr, endTime)) {
341
+ // 修正到 end
342
+ const endParts = endTime.split(':').map(part => parseInt(part));
343
+ const newIndices = endParts.map((time, i) => {
344
+ const idx = timeRanges[i].findIndex(item => parseInt(item) === time);
345
+ return idx >= 0 ? idx : 0;
346
+ });
347
+ finalIndices = [...newIndices];
348
+ hasLimited = true;
349
+ }
350
+ // 触发限位,更新状态,其它状态不用主动触发滚动
351
+ if (hasLimited) {
352
+ setState(prev => Object.assign(Object.assign({}, prev), {
353
+ selectedIndices: finalIndices,
354
+ timestamp: Date.now()
355
+ }));
356
+ } else {
357
+ setState(prev => Object.assign(Object.assign({}, prev), {
358
+ selectedIndices: finalIndices
359
+ }));
360
+ }
361
+ return hasLimited;
362
+ }
363
+ // 常规更新
364
+ finalIndices[columnIndex] = index;
365
+ setState(prev => Object.assign(Object.assign({}, prev), {
366
+ selectedIndices: finalIndices
367
+ }));
368
+ return false; // 没有限位
369
+ }, [start, end, mode, regionData, state.selectedIndices, columnsCount]);
370
+ // 更新日期
371
+ const updateDay = React__default.useCallback((value, fields) => {
372
+ if (!pickerDateRef.current) return;
373
+ const {
374
+ _start,
375
+ _end,
376
+ _updateValue
377
+ } = pickerDateRef.current;
378
+ // 更新当前字段的值
379
+ _updateValue[fields] = value;
380
+ // 获取当前年月日
381
+ const currentYear = _updateValue[0];
382
+ const currentMonth = _updateValue[1];
383
+ const currentDay = _updateValue[2];
384
+ // 保存原始值用于后面比较
385
+ const originalValues = [..._updateValue];
386
+ // 准备最终的索引数组 - 复制当前索引状态作为起点
387
+ const finalIndices = [...state.selectedIndices];
388
+ // 获取基础范围数据
389
+ const yearRange = getYearRange(_start.getFullYear(), _end.getFullYear());
390
+ const monthRange = getMonthRange(_start, _end, currentYear);
391
+ let dayRange = getDayRange(_start, _end, currentYear, currentMonth);
392
+ // 根据修改的字段进行不同处理
393
+ if (fields === 0) {
394
+ // 年份索引直接更新
395
+ finalIndices[0] = yearRange.indexOf(currentYear);
396
+ // 月份限位处理
397
+ if (monthRange.length > 0) {
398
+ if (currentMonth > monthRange[monthRange.length - 1]) {
399
+ _updateValue[1] = monthRange[monthRange.length - 1];
400
+ }
401
+ if (currentMonth < monthRange[0]) {
402
+ _updateValue[1] = monthRange[0];
403
+ }
404
+ // 更新月份索引
405
+ finalIndices[1] = monthRange.indexOf(_updateValue[1]);
406
+ // 重新计算日期范围
407
+ dayRange = getDayRange(_start, _end, currentYear, _updateValue[1]);
408
+ // 日期限位处理
409
+ if (dayRange.length > 0) {
410
+ if (currentDay > dayRange[dayRange.length - 1]) {
411
+ _updateValue[2] = dayRange[dayRange.length - 1];
412
+ }
413
+ if (currentDay < dayRange[0]) {
414
+ _updateValue[2] = dayRange[0];
415
+ }
416
+ // 更新日期索引
417
+ finalIndices[2] = dayRange.indexOf(_updateValue[2]);
418
+ }
419
+ }
420
+ } else if (fields === 1) {
421
+ // 月份变化
422
+ // 月份索引直接更新
423
+ finalIndices[1] = monthRange.indexOf(currentMonth);
424
+ // 日期限位处理
425
+ if (dayRange.length > 0) {
426
+ if (currentDay > dayRange[dayRange.length - 1]) {
427
+ _updateValue[2] = dayRange[dayRange.length - 1];
428
+ }
429
+ if (currentDay < dayRange[0]) {
430
+ _updateValue[2] = dayRange[0];
431
+ }
432
+ // 更新日期索引
433
+ finalIndices[2] = dayRange.indexOf(_updateValue[2]);
434
+ }
435
+ } else if (fields === 2) {
436
+ // 日期变化
437
+ // 日期索引直接更新
438
+ finalIndices[2] = dayRange.indexOf(currentDay);
439
+ }
440
+ // 只在有实际变化时更新状态
441
+ if (JSON.stringify(originalValues) !== JSON.stringify(_updateValue) || JSON.stringify(finalIndices) !== JSON.stringify(state.selectedIndices)) {
442
+ // 一次性更新状态
443
+ setState(prev => Object.assign(Object.assign({}, prev), {
444
+ selectedIndices: finalIndices
445
+ }));
446
+ }
447
+ }, [state.selectedIndices]);
448
+ // 处理确认
449
+ const handleChange = React__default.useCallback(() => {
450
+ const newIndices = [...state.selectedIndices];
451
+ indexRef.current = newIndices;
452
+ let newValue = newIndices.length && mode !== 'selector' ? newIndices : newIndices[0];
453
+ if (mode === 'time') {
454
+ const range = [hoursRange.slice(), minutesRange.slice()];
455
+ // 安全的时间处理,添加边界检查
456
+ const timeArr = newIndices.map((idx, i) => {
457
+ const index = Math.max(0, Math.min(idx, range[i].length - 1));
458
+ return range[i][index] || (i === 0 ? '00' : '00');
459
+ });
460
+ // 确保时间值有效
461
+ const validTimeArr = timeArr.map(time => {
462
+ const num = parseInt(time);
463
+ return isNaN(num) ? '00' : time;
464
+ });
465
+ indexRef.current = validTimeArr.map(item => parseInt(item));
466
+ newValue = validTimeArr.join(':');
467
+ }
468
+ if (mode === 'date') {
469
+ if (!pickerDateRef.current) return;
470
+ const {
471
+ _start,
472
+ _end,
473
+ _updateValue
474
+ } = pickerDateRef.current;
475
+ const currentYear = _updateValue[0];
476
+ const currentMonth = _updateValue[1];
477
+ const yearRange = getYearRange(_start.getFullYear(), _end.getFullYear());
478
+ const monthRange = getMonthRange(_start, _end, currentYear);
479
+ const dayRange = getDayRange(_start, _end, currentYear, currentMonth);
480
+ // 添加边界检查,确保索引有效
481
+ const yearIndex = Math.min(Math.max(Math.floor(newIndices[0]), 0), yearRange.length - 1);
482
+ const monthIndex = Math.min(Math.max(Math.floor(newIndices[1]), 0), monthRange.length - 1);
483
+ const dayIndex = Math.min(Math.max(Math.floor(newIndices[2]), 0), dayRange.length - 1);
484
+ const year = yearRange[yearIndex];
485
+ const month = monthRange[monthIndex];
486
+ const day = dayRange[dayIndex];
487
+ // 确保所有值都存在
488
+ if (year === undefined || month === undefined || day === undefined) {
489
+ console.warn('Date picker: invalid date values', {
490
+ year,
491
+ month,
492
+ day
493
+ });
494
+ return;
495
+ }
496
+ if (fields === 'year') {
497
+ newValue = year.toString();
498
+ } else if (fields === 'month') {
499
+ // YYYY-MM 格式
500
+ newValue = `${year}-${month < 10 ? `0${month}` : month}`;
501
+ } else {
502
+ // YYYY-MM-DD 格式
503
+ newValue = `${year}-${month < 10 ? `0${month}` : month}-${day < 10 ? `0${day}` : day}`;
504
+ }
505
+ hidePicker();
506
+ setState(prev => Object.assign(Object.assign({}, prev), {
507
+ pickerValue: newValue
508
+ }));
509
+ onChange === null || onChange === void 0 ? void 0 : onChange({
510
+ detail: {
511
+ value: newValue
512
+ }
513
+ });
514
+ return;
515
+ }
516
+ if (mode === 'region') {
517
+ if (!regionData) {
518
+ console.error('Picker: regionData is required for region mode');
519
+ return;
520
+ }
521
+ const validation = validateRegionData(regionData, 'Picker');
522
+ if (!validation.valid) {
523
+ console.error(validation.error);
524
+ return;
525
+ }
526
+ // 直接使用索引数组
527
+ const selectedCodes = [];
528
+ let postcode = '';
529
+ // 安全获取选中值
530
+ let currentData = regionData;
531
+ for (let i = 0; i < columnsCount; i++) {
532
+ if (!currentData || currentData.length === 0) break;
533
+ const index = newIndices[i] || 0;
534
+ if (index < 0 || index >= currentData.length) break;
535
+ const item = currentData[index];
536
+ selectedCodes.push(item.code);
537
+ // 如果是最后一项,获取邮政编码
538
+ if (i === columnsCount - 1 && item.postcode) {
539
+ postcode = item.postcode;
540
+ }
541
+ // 准备下一级数据
542
+ currentData = item.children || [];
543
+ }
544
+ // 检查索引数组长度是否符合要求
545
+ if (newIndices.length < columnsCount) {
546
+ console.warn('Region picker: incomplete selection');
547
+ return;
548
+ }
549
+ // 触发 onChange 事件,包含 code 信息
550
+ hidePicker();
551
+ setState(prev => Object.assign(Object.assign({}, prev), {
552
+ pickerValue: newIndices
553
+ }));
554
+ onChange === null || onChange === void 0 ? void 0 : onChange({
555
+ detail: {
556
+ value: newIndices,
557
+ code: selectedCodes.join(','),
558
+ postcode
559
+ }
560
+ });
561
+ return;
562
+ }
563
+ hidePicker();
564
+ setState(prev => Object.assign(Object.assign({}, prev), {
565
+ pickerValue: newValue
566
+ }));
567
+ // 触发 onChange 事件,格式与原始组件一致
568
+ onChange === null || onChange === void 0 ? void 0 : onChange({
569
+ detail: {
570
+ value: newValue
571
+ }
572
+ });
573
+ }, [hidePicker, state.selectedIndices, mode, fields, onChange, regionData, columnsCount]);
574
+ // 处理列变化
575
+ const handleColumnChange = React__default.useCallback(e => {
576
+ const {
577
+ columnId,
578
+ index
579
+ } = e;
580
+ onColumnChange === null || onColumnChange === void 0 ? void 0 : onColumnChange({
581
+ detail: {
582
+ column: Number(columnId),
583
+ value: index
584
+ }
585
+ });
586
+ }, [onColumnChange]);
587
+ // 处理取消
588
+ const handleCancel = React__default.useCallback(() => {
589
+ hidePicker();
590
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
591
+ }, [hidePicker, onCancel]);
592
+ // 渲染选择器组
593
+ const renderPickerGroup = React__default.useMemo(() => {
594
+ switch (mode) {
595
+ case 'multiSelector':
596
+ {
597
+ return range.map((rangeItem, index) => /*#__PURE__*/jsx(PickerGroup, {
598
+ range: rangeItem,
599
+ rangeKey: rangeKey,
600
+ updateIndex: updateIndex,
601
+ onColumnChange: handleColumnChange,
602
+ columnId: String(index),
603
+ selectedIndex: state.selectedIndices[index] // 传递对应列的selectedIndex
604
+ ,
605
+ colors: colors
606
+ }, index));
607
+ }
608
+ case 'time':
609
+ {
610
+ return [/*#__PURE__*/jsx(PickerGroup, {
611
+ mode: "time",
612
+ range: hoursRange,
613
+ updateIndex: updateIndex,
614
+ columnId: "0",
615
+ selectedIndex: state.selectedIndices[0] // 传递小时列的selectedIndex
616
+ ,
617
+ colors: colors
618
+ }, `hour-${state.timestamp}`), /*#__PURE__*/jsx(PickerGroup, {
619
+ mode: "time",
620
+ range: minutesRange,
621
+ updateIndex: updateIndex,
622
+ columnId: "1",
623
+ selectedIndex: state.selectedIndices[1] // 传递分钟列的selectedIndex
624
+ ,
625
+ colors: colors
626
+ }, `minute-${state.timestamp}`)];
627
+ }
628
+ case 'date':
629
+ {
630
+ if (!pickerDateRef.current) return null;
631
+ const {
632
+ _start,
633
+ _end,
634
+ _updateValue
635
+ } = pickerDateRef.current;
636
+ const currentYear = _updateValue[0];
637
+ const currentMonth = _updateValue[1];
638
+ const langText = getLanguageText(lang);
639
+ const isEnglish = lang === 'en-US' || lang === 'en-GB';
640
+ const yearRange = getYearRange(_start.getFullYear(), _end.getFullYear()).map(item => isEnglish ? `${langText.year}${item}` : `${item}${langText.year}`);
641
+ const monthRange = getMonthRange(_start, _end, currentYear).map(item => isEnglish ? `${langText.month}${item < 10 ? `0${item}` : item}` : `${item < 10 ? `0${item}` : item}${langText.month}`);
642
+ const dayRange = getDayRange(_start, _end, currentYear, currentMonth).map(item => isEnglish ? `${langText.day}${item < 10 ? `0${item}` : item}` : `${item < 10 ? `0${item}` : item}${langText.day}`);
643
+ const renderView = [/*#__PURE__*/jsx(PickerGroup, {
644
+ mode: "date",
645
+ range: yearRange,
646
+ updateDay: updateDay,
647
+ updateIndex: updateIndex,
648
+ columnId: "0",
649
+ selectedIndex: state.selectedIndices[0] // 传递年份列的selectedIndex
650
+ ,
651
+ colors: colors
652
+ }, `year`)];
653
+ if (fields === 'month' || fields === 'day') {
654
+ renderView.push(/*#__PURE__*/jsx(PickerGroup, {
655
+ mode: "date",
656
+ range: monthRange,
657
+ updateDay: updateDay,
658
+ updateIndex: updateIndex,
659
+ columnId: "1",
660
+ selectedIndex: state.selectedIndices[1] // 传递月份列的selectedIndex
661
+ ,
662
+ colors: colors
663
+ }, `month`));
664
+ }
665
+ if (fields === 'day') {
666
+ renderView.push(/*#__PURE__*/jsx(PickerGroup, {
667
+ mode: "date",
668
+ range: dayRange,
669
+ updateDay: updateDay,
670
+ updateIndex: updateIndex,
671
+ columnId: "2",
672
+ selectedIndex: state.selectedIndices[2] // 传递日期列的selectedIndex
673
+ ,
674
+ colors: colors
675
+ }, `day`));
676
+ }
677
+ return renderView;
678
+ }
679
+ case 'region':
680
+ {
681
+ // region 模式处理 - 自动识别数据层级
682
+ if (!regionData) {
683
+ console.error('Picker: regionData is required for region mode');
684
+ return null;
685
+ }
686
+ // 简化验证逻辑
687
+ if (!validateRegionData(regionData, 'Picker').valid) {
688
+ return null;
689
+ }
690
+ const columns = [];
691
+ let currentData = regionData;
692
+ for (let i = 0; i < columnsCount; i++) {
693
+ if (i > 0 && (currentData === null || currentData === void 0 ? void 0 : currentData.length)) {
694
+ // 获取上一级选中项的children作为当前列数据
695
+ const prevIndex = state.selectedIndices[i - 1] || 0;
696
+ if (prevIndex >= 0 && prevIndex < currentData.length) {
697
+ currentData = currentData[prevIndex].children || [];
698
+ } else {
699
+ currentData = [];
700
+ }
701
+ }
702
+ columns.push(/*#__PURE__*/jsx(PickerGroup, {
703
+ mode: "region",
704
+ range: currentData,
705
+ rangeKey: "value",
706
+ updateIndex: updateIndex,
707
+ columnId: String(i),
708
+ selectedIndex: state.selectedIndices[i],
709
+ colors: colors
710
+ }, `region-${i}`));
711
+ }
712
+ return columns;
713
+ }
714
+ default:
715
+ return /*#__PURE__*/jsx(PickerGroup, {
716
+ range: range,
717
+ rangeKey: rangeKey,
718
+ updateIndex: updateIndex,
719
+ columnId: "0",
720
+ selectedIndex: state.selectedIndices[0] // 传递selector模式的selectedIndex
721
+ ,
722
+ colors: colors
723
+ });
724
+ }
725
+ }, [mode, range, rangeKey, fields, updateIndex, updateDay, handleColumnChange, pickerDateRef.current, level, regionData, state.selectedIndices, columnsCount, lang, colors]);
726
+ // 动画类名控制逻辑
727
+ const clsMask = classNames('taro-picker__mask-overlay', 'taro-picker__animate-fade-in', {
728
+ 'taro-picker__animate-fade-out': state.fadeOut
729
+ });
730
+ const clsSlider = classNames('taro-picker', 'taro-picker__animate-slide-up', {
731
+ 'taro-picker__animate-slide-down': state.fadeOut
732
+ });
733
+ // 暴露方法给外部
734
+ React__default.useImperativeHandle(ref, () => ({
735
+ showPicker,
736
+ hidePicker
737
+ }));
738
+ // 获取语言文本
739
+ const langText = getLanguageText(lang);
740
+ return /*#__PURE__*/jsxs(View, {
741
+ ref: ref // 直接绑定 ref
742
+ ,
743
+ ...(formType ? {
744
+ 'data-form-type': formType
745
+ } : {}),
746
+ ...omit(restProps, ['mode', 'disabled', 'range', 'rangeKey', 'value', 'start', 'end', 'fields', 'name', 'textProps', 'onChange', 'onColumnChange', 'onCancel', 'children', 'formType']),
747
+ children: [/*#__PURE__*/jsx(View, {
748
+ onClick: showPicker,
749
+ children: children
750
+ }), !state.hidden && /*#__PURE__*/jsxs(View, {
751
+ className: "taro-picker__overlay",
752
+ children: [/*#__PURE__*/jsx(View, {
753
+ className: clsMask,
754
+ onClick: handleCancel
755
+ }), /*#__PURE__*/jsxs(View, {
756
+ className: clsSlider,
757
+ children: [/*#__PURE__*/jsxs(View, {
758
+ className: "taro-picker__hd",
759
+ children: [/*#__PURE__*/jsx(View, {
760
+ className: "taro-picker__action",
761
+ onClick: handleCancel,
762
+ style: {
763
+ color: colors.cancelButtonColor
764
+ },
765
+ children: (_a = textProps.cancelText) !== null && _a !== void 0 ? _a : langText.cancel
766
+ }), headerText && /*#__PURE__*/jsx(View, {
767
+ className: "taro-picker__title",
768
+ children: headerText
769
+ }), /*#__PURE__*/jsx(View, {
770
+ className: "taro-picker__action",
771
+ onClick: handleChange,
772
+ style: {
773
+ color: colors.confirmButtonColor
774
+ },
775
+ children: (_b = textProps.okText) !== null && _b !== void 0 ? _b : langText.confirm
776
+ })]
777
+ }), /*#__PURE__*/jsx(View, {
778
+ className: "taro-picker__bd",
779
+ children: renderPickerGroup
780
+ })]
781
+ })]
782
+ })]
783
+ });
784
+ });
785
+ Picker.displayName = 'Picker';
786
+
787
+ export { Picker as default };
788
+ //# sourceMappingURL=index.js.map