@tarojs/components-react 4.1.12-beta.5 → 4.1.12-beta.51

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 (70) hide show
  1. package/dist/components/image/index.js +5 -3
  2. package/dist/components/image/index.js.map +1 -1
  3. package/dist/components/map/MapContext.js +628 -0
  4. package/dist/components/map/MapContext.js.map +1 -0
  5. package/dist/components/map/MapCustomCallout.js +91 -0
  6. package/dist/components/map/MapCustomCallout.js.map +1 -0
  7. package/dist/components/map/common.js +4 -0
  8. package/dist/components/map/common.js.map +1 -0
  9. package/dist/components/map/createMapContext.js +34 -0
  10. package/dist/components/map/createMapContext.js.map +1 -0
  11. package/dist/components/map/handler.js +50 -0
  12. package/dist/components/map/handler.js.map +1 -0
  13. package/dist/components/map/index.js +329 -0
  14. package/dist/components/map/index.js.map +1 -0
  15. package/dist/components/picker/index.js +110 -38
  16. package/dist/components/picker/index.js.map +1 -1
  17. package/dist/components/picker/picker-group.js +400 -111
  18. package/dist/components/picker/picker-group.js.map +1 -1
  19. package/dist/components/scroll-view/index.js +80 -36
  20. package/dist/components/scroll-view/index.js.map +1 -1
  21. package/dist/components/switch/index.js +125 -0
  22. package/dist/components/switch/index.js.map +1 -0
  23. package/dist/components/switch/style/index.scss.js +4 -0
  24. package/dist/components/switch/style/index.scss.js.map +1 -0
  25. package/dist/contexts/ScrollElementContext.js +6 -0
  26. package/dist/contexts/ScrollElementContext.js.map +1 -0
  27. package/dist/index.css +1 -1
  28. package/dist/index.js +5 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/original/components/image/index.js +5 -3
  31. package/dist/original/components/image/index.js.map +1 -1
  32. package/dist/original/components/image/style/index.scss +5 -1
  33. package/dist/original/components/map/MapContext.js +628 -0
  34. package/dist/original/components/map/MapContext.js.map +1 -0
  35. package/dist/original/components/map/MapCustomCallout.js +91 -0
  36. package/dist/original/components/map/MapCustomCallout.js.map +1 -0
  37. package/dist/original/components/map/common.js +4 -0
  38. package/dist/original/components/map/common.js.map +1 -0
  39. package/dist/original/components/map/createMapContext.js +34 -0
  40. package/dist/original/components/map/createMapContext.js.map +1 -0
  41. package/dist/original/components/map/handler.js +50 -0
  42. package/dist/original/components/map/handler.js.map +1 -0
  43. package/dist/original/components/map/index.js +329 -0
  44. package/dist/original/components/map/index.js.map +1 -0
  45. package/dist/original/components/picker/index.js +110 -38
  46. package/dist/original/components/picker/index.js.map +1 -1
  47. package/dist/original/components/picker/picker-group.js +400 -111
  48. package/dist/original/components/picker/picker-group.js.map +1 -1
  49. package/dist/original/components/picker/style/index.scss +9 -8
  50. package/dist/original/components/scroll-view/index.js +80 -36
  51. package/dist/original/components/scroll-view/index.js.map +1 -1
  52. package/dist/original/components/switch/index.js +125 -0
  53. package/dist/original/components/switch/index.js.map +1 -0
  54. package/dist/original/components/switch/style/index.scss +35 -0
  55. package/dist/original/contexts/ScrollElementContext.js +6 -0
  56. package/dist/original/contexts/ScrollElementContext.js.map +1 -0
  57. package/dist/original/index.js +5 -1
  58. package/dist/original/index.js.map +1 -1
  59. package/dist/solid/components/image/index.js +5 -3
  60. package/dist/solid/components/image/index.js.map +1 -1
  61. package/dist/solid/components/picker/index.js +121 -45
  62. package/dist/solid/components/picker/index.js.map +1 -1
  63. package/dist/solid/components/picker/picker-group.js +423 -135
  64. package/dist/solid/components/picker/picker-group.js.map +1 -1
  65. package/dist/solid/components/scroll-view/index.js +84 -40
  66. package/dist/solid/components/scroll-view/index.js.map +1 -1
  67. package/dist/solid/contexts/ScrollElementContext.js +6 -0
  68. package/dist/solid/contexts/ScrollElementContext.js.map +1 -0
  69. package/dist/solid/index.css +1 -1
  70. package/package.json +8 -6
@@ -2,6 +2,7 @@ import { createComponent, mergeProps, memo } from 'solid-js/web';
2
2
  import { __rest } from 'tslib';
3
3
  import './style/index.scss.js';
4
4
  import { View } from '@tarojs/components';
5
+ import Taro from '@tarojs/taro';
5
6
  import classNames from 'classnames';
6
7
  import React__default from 'react';
7
8
  import { verifyValue, verifyTime, hoursRange, minutesRange, verifyDate, getYearRange, getMonthRange, getDayRange, compareTime, omit } from '../../utils/index.js';
@@ -128,12 +129,13 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
128
129
  children,
129
130
  formType,
130
131
  lang,
131
- theme = 'light'
132
+ theme = 'light',
133
+ enableClickItemScroll = true
132
134
  } = props,
133
- restProps = __rest(props, ["mode", "disabled", "range", "rangeKey", "value", "start", "end", "fields", "headerText", "level", "regionData", "textProps", "colors", "onChange", "onColumnChange", "onCancel", "children", "formType", "lang", "theme"]);
135
+ restProps = __rest(props, ["mode", "disabled", "range", "rangeKey", "value", "start", "end", "fields", "headerText", "level", "regionData", "textProps", "colors", "onChange", "onColumnChange", "onCancel", "children", "formType", "lang", "theme", "enableClickItemScroll"]);
134
136
  const indexRef = React__default.useRef([]);
135
137
  const pickerDateRef = React__default.useRef();
136
- // 记录是否是用户滚动
138
+ // region:首次用户滚动初始化完成前不入库
137
139
  const isInitializationCompletedRef = React__default.useRef(false);
138
140
  const [state, setState] = React__default.useState({
139
141
  pickerValue: value || EMPTY_ARRAY,
@@ -142,14 +144,45 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
142
144
  hidden: true,
143
145
  fadeOut: false,
144
146
  isWillLoadCalled: false,
145
- timestamp: 0 // 用以部分模式下强制刷新组件的的时间戳,多用于反复限位
147
+ a11yTimeLimitColumnId: null,
148
+ a11yTimeLimitNonce: 0
146
149
  });
150
+ // 安全区域底部距离
151
+ const [safeAreaBottom, setSafeAreaBottom] = React__default.useState(0);
147
152
  // 在组件内部
148
153
  const [columnsCount, setColumnsCount] = React__default.useState(() => getRegionColumnsCount(level));
149
154
  // 只在level变化时更新列数
150
155
  React__default.useEffect(() => {
151
156
  setColumnsCount(getRegionColumnsCount(level));
152
157
  }, [level]);
158
+ // 更新安全区域
159
+ const updateSafeArea = React__default.useCallback(() => {
160
+ try {
161
+ const systemInfo = Taro.getSystemInfoSync();
162
+ const {
163
+ safeArea,
164
+ windowHeight
165
+ } = systemInfo;
166
+ if (safeArea && windowHeight) {
167
+ const lengthScaleRatio = systemInfo.lengthScaleRatio || 1;
168
+ const bottom = (windowHeight - safeArea.bottom) / lengthScaleRatio;
169
+ setSafeAreaBottom(Math.max(0, bottom));
170
+ }
171
+ } catch (e) {
172
+ // H5 环境或其他异常情况,不设置安全区域
173
+ setSafeAreaBottom(0);
174
+ }
175
+ }, []);
176
+ // 初始化安全区域
177
+ React__default.useEffect(() => {
178
+ updateSafeArea();
179
+ }, [updateSafeArea]);
180
+ // 监听窗口变化(导航方式切换等)
181
+ React__default.useEffect(() => {
182
+ const handleResize = () => updateSafeArea();
183
+ window.addEventListener('resize', handleResize);
184
+ return () => window.removeEventListener('resize', handleResize);
185
+ }, [updateSafeArea]);
153
186
  // 获取当前索引数组
154
187
  const getIndices = React__default.useCallback(() => {
155
188
  return indexRef.current;
@@ -200,25 +233,36 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
200
233
  const monthRange = getMonthRange(_start, _end, currentYear);
201
234
  const dayRange = getDayRange(_start, _end, currentYear, currentMonth);
202
235
  indexRef.current = [yearRange.indexOf(currentYear), monthRange.indexOf(currentMonth), dayRange.indexOf(currentDay)];
203
- if (!pickerDateRef.current || pickerDateRef.current._value.getTime() !== _value.getTime() || pickerDateRef.current._start.getTime() !== _start.getTime() || pickerDateRef.current._end.getTime() !== _end.getTime()) {
204
- pickerDateRef.current = {
205
- _value,
206
- _start,
207
- _end,
208
- _updateValue: [currentYear, currentMonth, currentDay]
209
- };
210
- }
236
+ // props 同步时始终刷新 _updateValue,避免取消后再开时日列草稿与索引不一致
237
+ pickerDateRef.current = {
238
+ _value,
239
+ _start,
240
+ _end,
241
+ _updateValue: [currentYear, currentMonth, currentDay]
242
+ };
211
243
  } else if (mode === 'region') {
212
244
  // region 模式处理 - 验证数据
213
245
  if (!regionData) {
214
246
  console.error('Picker: regionData is required for region mode');
215
- indexRef.current = [0];
247
+ indexRef.current = Array.from({
248
+ length: columnsCount
249
+ }, () => 0);
250
+ setState(prev => Object.assign(Object.assign({}, prev), {
251
+ selectedIndices: [...indexRef.current],
252
+ pickerValue: value || EMPTY_ARRAY
253
+ }));
216
254
  return;
217
255
  }
218
256
  const validation = validateRegionData(regionData, 'Picker');
219
257
  if (!validation.valid) {
220
258
  console.error(validation.error);
221
- indexRef.current = [0];
259
+ indexRef.current = Array.from({
260
+ length: columnsCount
261
+ }, () => 0);
262
+ setState(prev => Object.assign(Object.assign({}, prev), {
263
+ selectedIndices: [...indexRef.current],
264
+ pickerValue: value || EMPTY_ARRAY
265
+ }));
222
266
  return;
223
267
  }
224
268
  // 获取列数
@@ -265,16 +309,16 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
265
309
  handleProps();
266
310
  }
267
311
  }, [handleProps, state.isWillLoadCalled, JSON.stringify(value)]);
268
- // 显示 Picker
312
+ // 打开时按 props 重算索引,避免未确认的滑动与 indexRef 残留导致再开抖动
269
313
  const showPicker = React__default.useCallback(() => {
270
314
  if (disabled) return;
271
315
  isInitializationCompletedRef.current = false;
272
- const newIndices = getIndices();
316
+ handleProps();
273
317
  setState(prev => Object.assign(Object.assign({}, prev), {
274
- selectedIndices: newIndices,
275
- hidden: false
318
+ hidden: false,
319
+ a11yTimeLimitColumnId: null
276
320
  }));
277
- }, [disabled, getIndices]);
321
+ }, [disabled, handleProps]);
278
322
  // 隐藏 Picker
279
323
  const hidePicker = React__default.useCallback(() => {
280
324
  isInitializationCompletedRef.current = false;
@@ -349,11 +393,11 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
349
393
  finalIndices = [...newIndices];
350
394
  hasLimited = true;
351
395
  }
352
- // 触发限位,更新状态,其它状态不用主动触发滚动
353
396
  if (hasLimited) {
354
397
  setState(prev => Object.assign(Object.assign({}, prev), {
355
398
  selectedIndices: finalIndices,
356
- timestamp: Date.now()
399
+ a11yTimeLimitColumnId: columnId,
400
+ a11yTimeLimitNonce: prev.a11yTimeLimitNonce + 1
357
401
  }));
358
402
  } else {
359
403
  setState(prev => Object.assign(Object.assign({}, prev), {
@@ -586,11 +630,17 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
586
630
  }
587
631
  });
588
632
  }, [onColumnChange]);
589
- // 处理取消
633
+ const consumeTimeA11yLimitFocus = React__default.useCallback(() => {
634
+ setState(prev => Object.assign(Object.assign({}, prev), {
635
+ a11yTimeLimitColumnId: null
636
+ }));
637
+ }, []);
638
+ // 取消时按 props 回同步索引,避免与 value 脱节
590
639
  const handleCancel = React__default.useCallback(() => {
640
+ handleProps();
591
641
  hidePicker();
592
642
  onCancel === null || onCancel === void 0 ? void 0 : onCancel();
593
- }, [hidePicker, onCancel]);
643
+ }, [handleProps, hidePicker, onCancel]);
594
644
  // 渲染选择器组
595
645
  const renderPickerGroup = React__default.useMemo(() => {
596
646
  switch (mode) {
@@ -608,15 +658,18 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
608
658
  get selectedIndex() {
609
659
  return state.selectedIndices[index];
610
660
  },
611
- colors: colors
661
+ colors: colors,
662
+ enableClickItemScroll: enableClickItemScroll
612
663
  }));
613
664
  }
614
665
  case 'time':
615
666
  {
667
+ const timeA11yLimitFocus = state.a11yTimeLimitColumnId != null ? {
668
+ nonce: state.a11yTimeLimitNonce,
669
+ columnId: state.a11yTimeLimitColumnId
670
+ } : null;
616
671
  return [createComponent(PickerGroup, {
617
- get key() {
618
- return `hour-${state.timestamp}`;
619
- },
672
+ key: "hour",
620
673
  mode: "time",
621
674
  range: hoursRange,
622
675
  updateIndex: updateIndex,
@@ -624,11 +677,15 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
624
677
  get selectedIndex() {
625
678
  return state.selectedIndices[0];
626
679
  },
627
- colors: colors
628
- }), createComponent(PickerGroup, {
629
- get key() {
630
- return `minute-${state.timestamp}`;
680
+ colors: colors,
681
+ timeA11yLimitFocus: timeA11yLimitFocus,
682
+ onTimeA11yLimitFocusConsumed: consumeTimeA11yLimitFocus,
683
+ get timeA11yLimitEventNonce() {
684
+ return state.a11yTimeLimitNonce;
631
685
  },
686
+ enableClickItemScroll: enableClickItemScroll
687
+ }), createComponent(PickerGroup, {
688
+ key: "minute",
632
689
  mode: "time",
633
690
  range: minutesRange,
634
691
  updateIndex: updateIndex,
@@ -636,7 +693,13 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
636
693
  get selectedIndex() {
637
694
  return state.selectedIndices[1];
638
695
  },
639
- colors: colors
696
+ colors: colors,
697
+ timeA11yLimitFocus: timeA11yLimitFocus,
698
+ onTimeA11yLimitFocusConsumed: consumeTimeA11yLimitFocus,
699
+ get timeA11yLimitEventNonce() {
700
+ return state.a11yTimeLimitNonce;
701
+ },
702
+ enableClickItemScroll: enableClickItemScroll
640
703
  })];
641
704
  }
642
705
  case 'date':
@@ -664,7 +727,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
664
727
  get selectedIndex() {
665
728
  return state.selectedIndices[0];
666
729
  },
667
- colors: colors
730
+ colors: colors,
731
+ enableClickItemScroll: enableClickItemScroll
668
732
  })];
669
733
  if (fields === 'month' || fields === 'day') {
670
734
  renderView.push(createComponent(PickerGroup, {
@@ -677,7 +741,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
677
741
  get selectedIndex() {
678
742
  return state.selectedIndices[1];
679
743
  },
680
- colors: colors
744
+ colors: colors,
745
+ enableClickItemScroll: enableClickItemScroll
681
746
  }));
682
747
  }
683
748
  if (fields === 'day') {
@@ -691,7 +756,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
691
756
  get selectedIndex() {
692
757
  return state.selectedIndices[2];
693
758
  },
694
- colors: colors
759
+ colors: colors,
760
+ enableClickItemScroll: enableClickItemScroll
695
761
  }));
696
762
  }
697
763
  return renderView;
@@ -731,7 +797,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
731
797
  get selectedIndex() {
732
798
  return state.selectedIndices[i];
733
799
  },
734
- colors: colors
800
+ colors: colors,
801
+ enableClickItemScroll: enableClickItemScroll
735
802
  }));
736
803
  }
737
804
  return columns;
@@ -745,10 +812,11 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
745
812
  get selectedIndex() {
746
813
  return state.selectedIndices[0];
747
814
  },
748
- colors: colors
815
+ colors: colors,
816
+ enableClickItemScroll: enableClickItemScroll
749
817
  });
750
818
  }
751
- }, [mode, range, rangeKey, fields, updateIndex, updateDay, handleColumnChange, pickerDateRef.current, level, regionData, state.selectedIndices, columnsCount, lang, colors]);
819
+ }, [mode, range, rangeKey, fields, updateIndex, updateDay, handleColumnChange, pickerDateRef.current, level, regionData, state.selectedIndices, state.a11yTimeLimitColumnId, state.a11yTimeLimitNonce, consumeTimeA11yLimitFocus, columnsCount, lang, colors, enableClickItemScroll]);
752
820
  // 动画类名控制逻辑
753
821
  const clsMask = classNames('taro-picker__mask-overlay', 'taro-picker__animate-fade-in', {
754
822
  'taro-picker__animate-fade-out': state.fadeOut
@@ -762,6 +830,9 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
762
830
  const titleStyle = colors.titleColor ? {
763
831
  color: colors.titleColor
764
832
  } : null;
833
+ const maskOverlayStyle = colors.maskColor ? {
834
+ backgroundColor: colors.maskColor
835
+ } : undefined;
765
836
  // 暴露方法给外部
766
837
  React__default.useImperativeHandle(ref, () => ({
767
838
  showPicker,
@@ -782,16 +853,21 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
782
853
  onClick: showPicker,
783
854
  children: children
784
855
  }), memo(() => memo(() => !!!state.hidden)() && createComponent(View, {
785
- className: "taro-picker__overlay",
856
+ get className() {
857
+ return classNames('taro-picker__overlay', `taro-picker__overlay--theme-${theme}`);
858
+ },
786
859
  get children() {
787
860
  return [createComponent(View, {
788
861
  className: clsMask,
862
+ style: maskOverlayStyle,
789
863
  onClick: handleCancel
790
- }), createComponent(View, mergeProps({
791
- className: clsSlider
792
- }, backgroundStyle ? {
793
- style: backgroundStyle
794
- } : {}, {
864
+ }), createComponent(View, {
865
+ className: clsSlider,
866
+ get style() {
867
+ return Object.assign(Object.assign({}, backgroundStyle), {
868
+ paddingBottom: safeAreaBottom ? `${safeAreaBottom}px` : undefined
869
+ });
870
+ },
795
871
  get children() {
796
872
  return [createComponent(View, mergeProps({
797
873
  className: "taro-picker__hd"
@@ -837,7 +913,7 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
837
913
  children: renderPickerGroup
838
914
  }))];
839
915
  }
840
- }))];
916
+ })];
841
917
  }
842
918
  }))];
843
919
  }