@tarojs/components-react 4.1.12-beta.6 → 4.1.12-beta.60

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 +119 -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 +119 -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 +132 -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,47 @@ 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
+ // safeArea.bottom 为安全区底边的 Y 坐标,有效值应接近 windowHeight;
167
+ // 全 0 表示安全区信息尚不可用,此时不能用 windowHeight-0 算出整屏高度作为底部间距
168
+ if (safeArea && windowHeight && safeArea.bottom > 0) {
169
+ const lengthScaleRatio = systemInfo.lengthScaleRatio || 1;
170
+ const bottom = (windowHeight - safeArea.bottom) / lengthScaleRatio;
171
+ setSafeAreaBottom(Math.max(0, bottom));
172
+ } else {
173
+ setSafeAreaBottom(0);
174
+ }
175
+ } catch (e) {
176
+ // H5 环境或其他异常情况,不设置安全区域
177
+ setSafeAreaBottom(0);
178
+ }
179
+ }, []);
180
+ // 初始化安全区域
181
+ React__default.useEffect(() => {
182
+ updateSafeArea();
183
+ }, [updateSafeArea]);
184
+ // 监听窗口变化(导航方式切换等)
185
+ Taro.useResize(() => {
186
+ updateSafeArea();
187
+ });
153
188
  // 获取当前索引数组
154
189
  const getIndices = React__default.useCallback(() => {
155
190
  return indexRef.current;
@@ -200,25 +235,36 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
200
235
  const monthRange = getMonthRange(_start, _end, currentYear);
201
236
  const dayRange = getDayRange(_start, _end, currentYear, currentMonth);
202
237
  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
- }
238
+ // props 同步时始终刷新 _updateValue,避免取消后再开时日列草稿与索引不一致
239
+ pickerDateRef.current = {
240
+ _value,
241
+ _start,
242
+ _end,
243
+ _updateValue: [currentYear, currentMonth, currentDay]
244
+ };
211
245
  } else if (mode === 'region') {
212
246
  // region 模式处理 - 验证数据
213
247
  if (!regionData) {
214
248
  console.error('Picker: regionData is required for region mode');
215
- indexRef.current = [0];
249
+ indexRef.current = Array.from({
250
+ length: columnsCount
251
+ }, () => 0);
252
+ setState(prev => Object.assign(Object.assign({}, prev), {
253
+ selectedIndices: [...indexRef.current],
254
+ pickerValue: value || EMPTY_ARRAY
255
+ }));
216
256
  return;
217
257
  }
218
258
  const validation = validateRegionData(regionData, 'Picker');
219
259
  if (!validation.valid) {
220
260
  console.error(validation.error);
221
- indexRef.current = [0];
261
+ indexRef.current = Array.from({
262
+ length: columnsCount
263
+ }, () => 0);
264
+ setState(prev => Object.assign(Object.assign({}, prev), {
265
+ selectedIndices: [...indexRef.current],
266
+ pickerValue: value || EMPTY_ARRAY
267
+ }));
222
268
  return;
223
269
  }
224
270
  // 获取列数
@@ -265,16 +311,18 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
265
311
  handleProps();
266
312
  }
267
313
  }, [handleProps, state.isWillLoadCalled, JSON.stringify(value)]);
268
- // 显示 Picker
314
+ // 打开时按 props 重算索引,避免未确认的滑动与 indexRef 残留导致再开抖动
269
315
  const showPicker = React__default.useCallback(() => {
270
316
  if (disabled) return;
317
+ // 打开弹层时再读一次:此时安全区必然已稳定,避免 mount 首帧拿到全 0 的无效值
318
+ updateSafeArea();
271
319
  isInitializationCompletedRef.current = false;
272
- const newIndices = getIndices();
320
+ handleProps();
273
321
  setState(prev => Object.assign(Object.assign({}, prev), {
274
- selectedIndices: newIndices,
275
- hidden: false
322
+ hidden: false,
323
+ a11yTimeLimitColumnId: null
276
324
  }));
277
- }, [disabled, getIndices]);
325
+ }, [disabled, handleProps, updateSafeArea]);
278
326
  // 隐藏 Picker
279
327
  const hidePicker = React__default.useCallback(() => {
280
328
  isInitializationCompletedRef.current = false;
@@ -349,11 +397,11 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
349
397
  finalIndices = [...newIndices];
350
398
  hasLimited = true;
351
399
  }
352
- // 触发限位,更新状态,其它状态不用主动触发滚动
353
400
  if (hasLimited) {
354
401
  setState(prev => Object.assign(Object.assign({}, prev), {
355
402
  selectedIndices: finalIndices,
356
- timestamp: Date.now()
403
+ a11yTimeLimitColumnId: columnId,
404
+ a11yTimeLimitNonce: prev.a11yTimeLimitNonce + 1
357
405
  }));
358
406
  } else {
359
407
  setState(prev => Object.assign(Object.assign({}, prev), {
@@ -586,11 +634,17 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
586
634
  }
587
635
  });
588
636
  }, [onColumnChange]);
589
- // 处理取消
637
+ const consumeTimeA11yLimitFocus = React__default.useCallback(() => {
638
+ setState(prev => Object.assign(Object.assign({}, prev), {
639
+ a11yTimeLimitColumnId: null
640
+ }));
641
+ }, []);
642
+ // 取消时按 props 回同步索引,避免与 value 脱节
590
643
  const handleCancel = React__default.useCallback(() => {
644
+ handleProps();
591
645
  hidePicker();
592
646
  onCancel === null || onCancel === void 0 ? void 0 : onCancel();
593
- }, [hidePicker, onCancel]);
647
+ }, [handleProps, hidePicker, onCancel]);
594
648
  // 渲染选择器组
595
649
  const renderPickerGroup = React__default.useMemo(() => {
596
650
  switch (mode) {
@@ -608,15 +662,18 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
608
662
  get selectedIndex() {
609
663
  return state.selectedIndices[index];
610
664
  },
611
- colors: colors
665
+ colors: colors,
666
+ enableClickItemScroll: enableClickItemScroll
612
667
  }));
613
668
  }
614
669
  case 'time':
615
670
  {
671
+ const timeA11yLimitFocus = state.a11yTimeLimitColumnId != null ? {
672
+ nonce: state.a11yTimeLimitNonce,
673
+ columnId: state.a11yTimeLimitColumnId
674
+ } : null;
616
675
  return [createComponent(PickerGroup, {
617
- get key() {
618
- return `hour-${state.timestamp}`;
619
- },
676
+ key: "hour",
620
677
  mode: "time",
621
678
  range: hoursRange,
622
679
  updateIndex: updateIndex,
@@ -624,11 +681,15 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
624
681
  get selectedIndex() {
625
682
  return state.selectedIndices[0];
626
683
  },
627
- colors: colors
628
- }), createComponent(PickerGroup, {
629
- get key() {
630
- return `minute-${state.timestamp}`;
684
+ colors: colors,
685
+ timeA11yLimitFocus: timeA11yLimitFocus,
686
+ onTimeA11yLimitFocusConsumed: consumeTimeA11yLimitFocus,
687
+ get timeA11yLimitEventNonce() {
688
+ return state.a11yTimeLimitNonce;
631
689
  },
690
+ enableClickItemScroll: enableClickItemScroll
691
+ }), createComponent(PickerGroup, {
692
+ key: "minute",
632
693
  mode: "time",
633
694
  range: minutesRange,
634
695
  updateIndex: updateIndex,
@@ -636,7 +697,13 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
636
697
  get selectedIndex() {
637
698
  return state.selectedIndices[1];
638
699
  },
639
- colors: colors
700
+ colors: colors,
701
+ timeA11yLimitFocus: timeA11yLimitFocus,
702
+ onTimeA11yLimitFocusConsumed: consumeTimeA11yLimitFocus,
703
+ get timeA11yLimitEventNonce() {
704
+ return state.a11yTimeLimitNonce;
705
+ },
706
+ enableClickItemScroll: enableClickItemScroll
640
707
  })];
641
708
  }
642
709
  case 'date':
@@ -664,7 +731,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
664
731
  get selectedIndex() {
665
732
  return state.selectedIndices[0];
666
733
  },
667
- colors: colors
734
+ colors: colors,
735
+ enableClickItemScroll: enableClickItemScroll
668
736
  })];
669
737
  if (fields === 'month' || fields === 'day') {
670
738
  renderView.push(createComponent(PickerGroup, {
@@ -677,7 +745,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
677
745
  get selectedIndex() {
678
746
  return state.selectedIndices[1];
679
747
  },
680
- colors: colors
748
+ colors: colors,
749
+ enableClickItemScroll: enableClickItemScroll
681
750
  }));
682
751
  }
683
752
  if (fields === 'day') {
@@ -691,7 +760,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
691
760
  get selectedIndex() {
692
761
  return state.selectedIndices[2];
693
762
  },
694
- colors: colors
763
+ colors: colors,
764
+ enableClickItemScroll: enableClickItemScroll
695
765
  }));
696
766
  }
697
767
  return renderView;
@@ -731,7 +801,8 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
731
801
  get selectedIndex() {
732
802
  return state.selectedIndices[i];
733
803
  },
734
- colors: colors
804
+ colors: colors,
805
+ enableClickItemScroll: enableClickItemScroll
735
806
  }));
736
807
  }
737
808
  return columns;
@@ -745,10 +816,11 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
745
816
  get selectedIndex() {
746
817
  return state.selectedIndices[0];
747
818
  },
748
- colors: colors
819
+ colors: colors,
820
+ enableClickItemScroll: enableClickItemScroll
749
821
  });
750
822
  }
751
- }, [mode, range, rangeKey, fields, updateIndex, updateDay, handleColumnChange, pickerDateRef.current, level, regionData, state.selectedIndices, columnsCount, lang, colors]);
823
+ }, [mode, range, rangeKey, fields, updateIndex, updateDay, handleColumnChange, pickerDateRef.current, level, regionData, state.selectedIndices, state.a11yTimeLimitColumnId, state.a11yTimeLimitNonce, consumeTimeA11yLimitFocus, columnsCount, lang, colors, enableClickItemScroll]);
752
824
  // 动画类名控制逻辑
753
825
  const clsMask = classNames('taro-picker__mask-overlay', 'taro-picker__animate-fade-in', {
754
826
  'taro-picker__animate-fade-out': state.fadeOut
@@ -762,6 +834,9 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
762
834
  const titleStyle = colors.titleColor ? {
763
835
  color: colors.titleColor
764
836
  } : null;
837
+ const maskOverlayStyle = colors.maskColor ? {
838
+ backgroundColor: colors.maskColor
839
+ } : undefined;
765
840
  // 暴露方法给外部
766
841
  React__default.useImperativeHandle(ref, () => ({
767
842
  showPicker,
@@ -782,16 +857,19 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
782
857
  onClick: showPicker,
783
858
  children: children
784
859
  }), memo(() => memo(() => !!!state.hidden)() && createComponent(View, {
785
- className: "taro-picker__overlay",
860
+ get className() {
861
+ return classNames('taro-picker__overlay', `taro-picker__overlay--theme-${theme}`);
862
+ },
786
863
  get children() {
787
864
  return [createComponent(View, {
788
865
  className: clsMask,
866
+ style: maskOverlayStyle,
789
867
  onClick: handleCancel
790
- }), createComponent(View, mergeProps({
791
- className: clsSlider
792
- }, backgroundStyle ? {
793
- style: backgroundStyle
794
- } : {}, {
868
+ }), createComponent(View, {
869
+ className: clsSlider,
870
+ get style() {
871
+ return Object.assign({}, backgroundStyle);
872
+ },
795
873
  get children() {
796
874
  return [createComponent(View, mergeProps({
797
875
  className: "taro-picker__hd"
@@ -835,9 +913,18 @@ const Picker = /*#__PURE__*/React__default.forwardRef((props, ref) => {
835
913
  style: backgroundStyle
836
914
  } : {}, {
837
915
  children: renderPickerGroup
916
+ })), memo(() => safeAreaBottom > 0 && createComponent(View, {
917
+ className: "taro-picker__bd",
918
+ get style() {
919
+ return Object.assign(Object.assign({}, backgroundStyle), {
920
+ height: `${safeAreaBottom}px`,
921
+ flex: 'none',
922
+ overflow: 'visible'
923
+ });
924
+ }
838
925
  }))];
839
926
  }
840
- }))];
927
+ })];
841
928
  }
842
929
  }))];
843
930
  }