@nutui/nutui-react-taro 2.7.15-beta.1 → 2.7.16-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # v2.7.15
2
+
3
+ `2026-03-09`
4
+
5
+ - 🏡 chore: 升级版本
6
+ - :sparkles: feat: 调整button圆角、dialog内边间距 (#3321)
7
+ - :bug: fix: uploader上传组件taro版本h5端支持文件选择 (#3424)
8
+ - :bug: fix(uploader): 修复H5上传 (#3421)
9
+ - :bug: fix(form): setFieldValue与setFieldsValue 重复触发notifyWatch (#3228)
10
+
1
11
  # v2.7.14
2
12
 
3
13
  `2025-04-30`
@@ -1,4 +1,4 @@
1
- import { C as Calendar } from "./calendar.taro-C-5Lmq9i.js";
1
+ import { C as Calendar } from "./calendar.taro-DzEStrql.js";
2
2
  export {
3
3
  Calendar as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { C as CalendarItem } from "./calendaritem.taro-B0QA0q4N.js";
1
+ import { C as CalendarItem } from "./calendaritem.taro-DT5xXwyk.js";
2
2
  export {
3
3
  CalendarItem as default
4
4
  };
package/dist/esm/Radio.js CHANGED
@@ -1,4 +1,4 @@
1
- import { R as Radio } from "./radio.taro-M2in687s.js";
1
+ import { R as Radio } from "./radio.taro-BCsQcVdu.js";
2
2
  export {
3
3
  Radio as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { a as RadioGroup } from "./radio.taro-M2in687s.js";
1
+ import { a as RadioGroup } from "./radio.taro-BCsQcVdu.js";
2
2
  export {
3
3
  RadioGroup as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { U as Uploader } from "./uploader.taro-S9pOua4j.js";
1
+ import { U as Uploader } from "./uploader.taro-D3zeUFqf.js";
2
2
  export {
3
3
  Uploader as default
4
4
  };
@@ -1,6 +1,6 @@
1
1
  import React__default, { useState, useRef, useEffect } from "react";
2
2
  import { P as Popup } from "./popup.taro-JynjcLCn.js";
3
- import { s as splitDate, g as getPreMonths, a as getMonths, b as getPreQuarters, c as getQuarters, d as getNextQuarters, C as CalendarItem } from "./calendaritem.taro-B0QA0q4N.js";
3
+ import { s as splitDate, g as getPreMonths, a as getMonths, b as getPreQuarters, c as getQuarters, d as getNextQuarters, C as CalendarItem } from "./calendaritem.taro-DT5xXwyk.js";
4
4
  import classNames from "classnames";
5
5
  import Taro from "@tarojs/taro";
6
6
  import { View, ScrollView } from "@tarojs/components";
@@ -246,6 +246,9 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
246
246
  const [state] = useState({
247
247
  currDateArray: []
248
248
  });
249
+ const isSameRange = (range, start, end) => {
250
+ return range[0] === start && range[1] === end;
251
+ };
249
252
  const resetDefaultValue = () => {
250
253
  if (defaultValue || Array.isArray(defaultValue) && defaultValue.length > 0) {
251
254
  return type !== "single" ? [...defaultValue] : defaultValue;
@@ -323,7 +326,9 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
323
326
  start = 0;
324
327
  end = monthNum + 2;
325
328
  }
326
- setMonthDefaultRange([start, end]);
329
+ setMonthDefaultRange((range) => {
330
+ return isSameRange(range, start, end) ? range : [start, end];
331
+ });
327
332
  setTranslateY(monthsData[start].scrollTop);
328
333
  setReachedYearMonthInfo(current);
329
334
  };
@@ -462,8 +467,10 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
462
467
  viewHeight = getMonthsRef().clientHeight;
463
468
  getMonthsPanel().style.height = `${containerHeight}px`;
464
469
  const currTop = monthsData[current].scrollTop;
465
- getMonthsRef().scrollTop = currTop;
466
- setScrollTop(currTop);
470
+ const maxScrollTop = getMonthsRef().scrollHeight - getMonthsRef().clientHeight;
471
+ const targetScrollTop = Math.min(currTop, maxScrollTop);
472
+ getMonthsRef().scrollTop = targetScrollTop;
473
+ setScrollTop(targetScrollTop);
467
474
  nextTick(() => setScrollWithAnimation(true));
468
475
  }
469
476
  });
@@ -543,6 +550,7 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
543
550
  if (monthsData.length <= 1)
544
551
  return;
545
552
  const scrollTop2 = e.target.scrollTop;
553
+ console.log("🚀 ~ monthsViewScroll ~ scrollTop:", scrollTop2);
546
554
  Taro.getEnv() === "WEB" && setScrollTop(scrollTop2);
547
555
  let current = Math.floor(scrollTop2 / avgHeight);
548
556
  if (current < 0)
@@ -25,8 +25,8 @@ import { T as T2 } from "./tabbaritem.taro-BPe2bsMQ.js";
25
25
  import { T as T3 } from "./tabpane.taro-B8CBhFle.js";
26
26
  import { T as T4 } from "./tabs.taro-xLGG_Fux.js";
27
27
  import { A } from "./address.taro-C1ibsNFa.js";
28
- import { C as C5 } from "./calendar.taro-C-5Lmq9i.js";
29
- import { C as C6 } from "./calendaritem.taro-B0QA0q4N.js";
28
+ import { C as C5 } from "./calendar.taro-DzEStrql.js";
29
+ import { C as C6 } from "./calendaritem.taro-DT5xXwyk.js";
30
30
  import { C as C7 } from "./calendarcard.taro-Cp3yzc6h.js";
31
31
  import { C as C8 } from "./cascader.taro-D8z5VSBF.js";
32
32
  import { C as C9, a as a2 } from "./checkbox.taro-CgqJyhrh.js";
@@ -39,7 +39,7 @@ import { M } from "./menu.taro-9N8A5UoN.js";
39
39
  import { M as M2 } from "./menuitem.taro-CnsORm5-.js";
40
40
  import { N as N2 } from "./numberkeyboard.taro-blGUntGo.js";
41
41
  import { P } from "./picker.taro-Ctc0Wt4S.js";
42
- import { R as R2, a as a3 } from "./radio.taro-M2in687s.js";
42
+ import { R as R2, a as a3 } from "./radio.taro-BCsQcVdu.js";
43
43
  import { R as R3 } from "./range.taro-C5SuX_2b.js";
44
44
  import { R as R4 } from "./rate.taro-DsDMiRHd.js";
45
45
  import { S as S7 } from "./searchbar.taro-B7UhNlBh.js";
@@ -47,7 +47,7 @@ import { S as S8 } from "./shortpassword.taro--atvsdZp.js";
47
47
  import { S as S9 } from "./signature.taro-BW4eiGIR.js";
48
48
  import { S as S10 } from "./switch.taro-CdBmDo18.js";
49
49
  import { T as T5 } from "./textarea.taro-CGMI5QNw.js";
50
- import { U } from "./uploader.taro-S9pOua4j.js";
50
+ import { U } from "./uploader.taro-D3zeUFqf.js";
51
51
  import { A as A2 } from "./actionsheet.taro-kMhbV73n.js";
52
52
  import { B as B3 } from "./badge.taro-W8s89KAj.js";
53
53
  import { B as B4 } from "./dialog.taro-1Vukbvap.js";
@@ -16,7 +16,7 @@ const classPrefix = "nut-radiogroup";
16
16
  const RadioGroup = React__default.forwardRef((props, ref) => {
17
17
  const _a = Object.assign(Object.assign({}, defaultProps$1), props), { children, className, value, defaultValue, onChange, shape, labelPosition, direction, options, disabled } = _a, rest = __rest(_a, ["children", "className", "value", "defaultValue", "onChange", "shape", "labelPosition", "direction", "options", "disabled"]);
18
18
  const cls = classNames(classPrefix, {
19
- [`${classPrefix}-${props.direction}`]: props.direction
19
+ [`${classPrefix}-${direction}`]: direction
20
20
  }, className);
21
21
  const [val2State, setVal2State] = usePropsValue({
22
22
  defaultValue: props.defaultValue,
@@ -138,6 +138,105 @@ class FileItem {
138
138
  this.formData = {};
139
139
  }
140
140
  }
141
+ const chooseFile = (options) => {
142
+ const shouldBeObjectNative = (options2) => {
143
+ const isObject2 = options2 !== null && typeof options2 === "object" && !Array.isArray(options2);
144
+ if (!isObject2) {
145
+ return {
146
+ flag: false,
147
+ msg: "parameter should be Object"
148
+ };
149
+ }
150
+ return {
151
+ flag: true,
152
+ msg: ""
153
+ };
154
+ };
155
+ const isObject = shouldBeObjectNative(options);
156
+ if (!isObject.flag) {
157
+ const res2 = { errMsg: `taroChooseFile:fail ${isObject.msg}` };
158
+ console.error(res2.errMsg);
159
+ return Promise.reject(res2);
160
+ }
161
+ const { count = 1, success, fail, complete, imageId = "taroChooseFile", sourceType = ["album", "camera"] } = options;
162
+ const res = {
163
+ tempFilePaths: [],
164
+ tempFiles: [],
165
+ errMsg: ""
166
+ };
167
+ const handleSuccess = (data = {}, resolve = Promise.resolve.bind(Promise)) => {
168
+ if (!data.errMsg) {
169
+ data.errMsg = "taroChooseFile:ok";
170
+ }
171
+ typeof success === "function" && success(data);
172
+ typeof complete === "function" && complete(data);
173
+ return resolve(data);
174
+ };
175
+ const handleFail = (data = {}, reject = Promise.reject.bind(Promise)) => {
176
+ if (!data.errMsg) {
177
+ data.errMsg = "taroChooseFile:fail";
178
+ } else {
179
+ data.errMsg = `taroChooseFile:fail ${data.errMsg}`;
180
+ }
181
+ console.error(data.errMsg);
182
+ typeof fail === "function" && fail(data);
183
+ typeof complete === "function" && complete(data);
184
+ return reject(data);
185
+ };
186
+ const sourceTypeString = sourceType && sourceType.toString();
187
+ const acceptableSourceType = ["user", "environment", "camera"];
188
+ if (count && typeof count !== "number") {
189
+ res.errMsg = `parameter error: count should be number, but got ${typeof count}`;
190
+ return handleFail(res);
191
+ }
192
+ const el = document.getElementById(imageId);
193
+ if (!el) {
194
+ res.errMsg = "taroChooseFile:fail element not found";
195
+ return handleFail(res);
196
+ }
197
+ if (count > 1) {
198
+ el.setAttribute("multiple", "multiple");
199
+ } else {
200
+ el.removeAttribute("multiple");
201
+ }
202
+ if (acceptableSourceType.indexOf(sourceTypeString) > -1) {
203
+ el.setAttribute("capture", sourceTypeString);
204
+ } else {
205
+ el.removeAttribute("capture");
206
+ }
207
+ return new Promise((resolve) => {
208
+ if (el) {
209
+ const evt = new MouseEvent("click", {
210
+ bubbles: true,
211
+ cancelable: true,
212
+ view: window
213
+ });
214
+ el.dispatchEvent(evt);
215
+ el.onchange = (e) => {
216
+ const target = e.target;
217
+ if (target) {
218
+ const files = target.files || [];
219
+ const arr = Array.from(files);
220
+ arr.forEach((item) => {
221
+ const blob = new Blob([item], {
222
+ type: item.type
223
+ });
224
+ const url = URL.createObjectURL(blob);
225
+ res.tempFilePaths.push(url);
226
+ res.tempFiles.push({
227
+ path: url,
228
+ size: item.size,
229
+ type: item.type,
230
+ originalFileObj: item
231
+ });
232
+ });
233
+ handleSuccess(res, resolve);
234
+ target.value = "";
235
+ }
236
+ };
237
+ }
238
+ });
239
+ };
141
240
  const Preview = ({ fileList, previewType, deletable, onDeleteItem, handleItemClick, previewUrl, deleteIcon, children }) => {
142
241
  const renderIcon = (item) => {
143
242
  if (item.status === ERROR) {
@@ -206,7 +305,7 @@ const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { url:
206
305
  } });
207
306
  const InternalUploader = (props, ref) => {
208
307
  const { locale } = useConfig();
209
- const _a = Object.assign(Object.assign({}, defaultProps), props), { children, uploadIcon, deleteIcon, uploadLabel, accept, name, camera, defaultValue, value, previewType, fit, disabled, multiple, url, previewUrl, headers, timeout, method, xhrState, data, preview, deletable, maxCount, maxFileSize, mediaType, className, autoUpload, sizeType, sourceType, maxDuration, onStart, onDelete, onChange, onFileItemClick, onProgress, onSuccess, onUpdate, onFailure, onOversize, beforeUpload, beforeXhrUpload, beforeDelete } = _a, restProps = __rest(_a, ["children", "uploadIcon", "deleteIcon", "uploadLabel", "accept", "name", "camera", "defaultValue", "value", "previewType", "fit", "disabled", "multiple", "url", "previewUrl", "headers", "timeout", "method", "xhrState", "data", "preview", "deletable", "maxCount", "maxFileSize", "mediaType", "className", "autoUpload", "sizeType", "sourceType", "maxDuration", "onStart", "onDelete", "onChange", "onFileItemClick", "onProgress", "onSuccess", "onUpdate", "onFailure", "onOversize", "beforeUpload", "beforeXhrUpload", "beforeDelete"]);
308
+ const _a = Object.assign(Object.assign({}, defaultProps), props), { children, uploadIcon, deleteIcon, uploadLabel, accept, name, camera, defaultValue, value, previewType, fit, disabled, multiple, url, previewUrl, headers, timeout, method, xhrState, data, preview, deletable, maxCount, maxFileSize, mediaType, className, autoUpload, sizeType, sourceType, maxDuration, onStart, onDelete, onChange, onFileItemClick, onProgress, onSuccess, onUpdate, onFailure, onOversize, beforeUpload, beforeXhrUpload, beforeDelete, needChooseFile } = _a, restProps = __rest(_a, ["children", "uploadIcon", "deleteIcon", "uploadLabel", "accept", "name", "camera", "defaultValue", "value", "previewType", "fit", "disabled", "multiple", "url", "previewUrl", "headers", "timeout", "method", "xhrState", "data", "preview", "deletable", "maxCount", "maxFileSize", "mediaType", "className", "autoUpload", "sizeType", "sourceType", "maxDuration", "onStart", "onDelete", "onChange", "onFileItemClick", "onProgress", "onSuccess", "onUpdate", "onFailure", "onOversize", "beforeUpload", "beforeXhrUpload", "beforeDelete", "needChooseFile"]);
210
309
  const [fileList, setFileList] = usePropsValue({
211
310
  value,
212
311
  defaultValue,
@@ -244,20 +343,29 @@ const InternalUploader = (props, ref) => {
244
343
  if (disabled) {
245
344
  return;
246
345
  }
247
- if (Taro.getEnv() === "WEB") {
248
- const el = document.getElementById("taroChooseImage");
346
+ if (Taro.getEnv() === "WEB" && needChooseFile) {
347
+ const el = document.getElementById("taroChooseFile");
249
348
  if (el) {
250
349
  el === null || el === void 0 ? void 0 : el.setAttribute("accept", accept);
251
350
  } else {
252
351
  const obj = document.createElement("input");
253
352
  obj.setAttribute("type", "file");
254
- obj.setAttribute("id", "taroChooseImage");
353
+ obj.setAttribute("id", "taroChooseFile");
255
354
  obj.setAttribute("accept", accept);
256
355
  obj.setAttribute("style", "position: fixed; top: -4000px; left: -3000px; z-index: -300;");
257
356
  document.body.appendChild(obj);
258
357
  }
259
- }
260
- if (["WEAPP", "JD"].includes(getEnv()) && chooseMedia) {
358
+ chooseFile({
359
+ count: multiple ? maxCount * 1 - fileList.length : 1,
360
+ // 可以指定是原图还是压缩图,默认二者都有
361
+ sizeType,
362
+ sourceType,
363
+ success: onChangeImage,
364
+ fail: (res) => {
365
+ onFailure && onFailure(res);
366
+ }
367
+ });
368
+ } else if (["WEAPP", "JD", "WEB"].includes(getEnv()) && chooseMedia) {
261
369
  chooseMedia({
262
370
  count: multiple ? maxCount * 1 - fileList.length : 1,
263
371
  /** 文件类型 */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:25:15 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:55 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:24:45 GMT+0800 (China Standard Time)
2
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:20 GMT+0800 (China Standard Time)
3
3
  * (c) 2023 @jdf2e.
4
4
  * Released under the MIT License.
5
5
  */
@@ -6584,6 +6584,9 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
6584
6584
  const [state] = useState({
6585
6585
  currDateArray: []
6586
6586
  });
6587
+ const isSameRange = (range3, start, end) => {
6588
+ return range3[0] === start && range3[1] === end;
6589
+ };
6587
6590
  const resetDefaultValue = () => {
6588
6591
  if (defaultValue || Array.isArray(defaultValue) && defaultValue.length > 0) {
6589
6592
  return type4 !== "single" ? [...defaultValue] : defaultValue;
@@ -6666,7 +6669,9 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
6666
6669
  start = 0;
6667
6670
  end = monthNum + 2;
6668
6671
  }
6669
- setMonthDefaultRange([start, end]);
6672
+ setMonthDefaultRange((range3) => {
6673
+ return isSameRange(range3, start, end) ? range3 : [start, end];
6674
+ });
6670
6675
  setTranslateY(monthsData[start].scrollTop);
6671
6676
  setReachedYearMonthInfo(current);
6672
6677
  };
@@ -6813,8 +6818,10 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
6813
6818
  viewHeight = getMonthsRef().clientHeight;
6814
6819
  getMonthsPanel().style.height = `${containerHeight}px`;
6815
6820
  const currTop = monthsData[current].scrollTop;
6816
- getMonthsRef().scrollTop = currTop;
6817
- setScrollTop(currTop);
6821
+ const maxScrollTop = getMonthsRef().scrollHeight - getMonthsRef().clientHeight;
6822
+ const targetScrollTop = Math.min(currTop, maxScrollTop);
6823
+ getMonthsRef().scrollTop = targetScrollTop;
6824
+ setScrollTop(targetScrollTop);
6818
6825
  nextTick(() => setScrollWithAnimation(true));
6819
6826
  }
6820
6827
  });
@@ -6891,6 +6898,7 @@ const CalendarItem = React__default.forwardRef((props, ref) => {
6891
6898
  const monthsViewScroll = (e2) => {
6892
6899
  if (monthsData.length <= 1) return;
6893
6900
  const scrollTop2 = e2.target.scrollTop;
6901
+ console.log("🚀 ~ monthsViewScroll ~ scrollTop:", scrollTop2);
6894
6902
  Taro.getEnv() === "WEB" && setScrollTop(scrollTop2);
6895
6903
  let current = Math.floor(scrollTop2 / avgHeight);
6896
6904
  if (current < 0) return;
@@ -11849,7 +11857,7 @@ const RadioGroup = React__default.forwardRef(
11849
11857
  const cls = classNames(
11850
11858
  classPrefix$g,
11851
11859
  {
11852
- [`${classPrefix$g}-${props.direction}`]: props.direction
11860
+ [`${classPrefix$g}-${direction}`]: direction
11853
11861
  },
11854
11862
  className
11855
11863
  );
@@ -13246,6 +13254,112 @@ class FileItem {
13246
13254
  this.formData = {};
13247
13255
  }
13248
13256
  }
13257
+ const chooseFile = (options) => {
13258
+ const shouldBeObjectNative = (options2) => {
13259
+ const isObject22 = options2 !== null && typeof options2 === "object" && !Array.isArray(options2);
13260
+ if (!isObject22) {
13261
+ return {
13262
+ flag: false,
13263
+ msg: "parameter should be Object"
13264
+ };
13265
+ }
13266
+ return {
13267
+ flag: true,
13268
+ msg: ""
13269
+ };
13270
+ };
13271
+ const isObject2 = shouldBeObjectNative(options);
13272
+ if (!isObject2.flag) {
13273
+ const res2 = { errMsg: `taroChooseFile:fail ${isObject2.msg}` };
13274
+ console.error(res2.errMsg);
13275
+ return Promise.reject(res2);
13276
+ }
13277
+ const {
13278
+ count = 1,
13279
+ success,
13280
+ fail,
13281
+ complete,
13282
+ imageId = "taroChooseFile",
13283
+ sourceType = ["album", "camera"]
13284
+ } = options;
13285
+ const res = {
13286
+ tempFilePaths: [],
13287
+ tempFiles: [],
13288
+ errMsg: ""
13289
+ };
13290
+ const handleSuccess = (data = {}, resolve = Promise.resolve.bind(Promise)) => {
13291
+ if (!data.errMsg) {
13292
+ data.errMsg = "taroChooseFile:ok";
13293
+ }
13294
+ typeof success === "function" && success(data);
13295
+ typeof complete === "function" && complete(data);
13296
+ return resolve(data);
13297
+ };
13298
+ const handleFail = (data = {}, reject = Promise.reject.bind(Promise)) => {
13299
+ if (!data.errMsg) {
13300
+ data.errMsg = "taroChooseFile:fail";
13301
+ } else {
13302
+ data.errMsg = `taroChooseFile:fail ${data.errMsg}`;
13303
+ }
13304
+ console.error(data.errMsg);
13305
+ typeof fail === "function" && fail(data);
13306
+ typeof complete === "function" && complete(data);
13307
+ return reject(data);
13308
+ };
13309
+ const sourceTypeString = sourceType && sourceType.toString();
13310
+ const acceptableSourceType = ["user", "environment", "camera"];
13311
+ if (count && typeof count !== "number") {
13312
+ res.errMsg = `parameter error: count should be number, but got ${typeof count}`;
13313
+ return handleFail(res);
13314
+ }
13315
+ const el = document.getElementById(imageId);
13316
+ if (!el) {
13317
+ res.errMsg = "taroChooseFile:fail element not found";
13318
+ return handleFail(res);
13319
+ }
13320
+ if (count > 1) {
13321
+ el.setAttribute("multiple", "multiple");
13322
+ } else {
13323
+ el.removeAttribute("multiple");
13324
+ }
13325
+ if (acceptableSourceType.indexOf(sourceTypeString) > -1) {
13326
+ el.setAttribute("capture", sourceTypeString);
13327
+ } else {
13328
+ el.removeAttribute("capture");
13329
+ }
13330
+ return new Promise((resolve) => {
13331
+ if (el) {
13332
+ const evt = new MouseEvent("click", {
13333
+ bubbles: true,
13334
+ cancelable: true,
13335
+ view: window
13336
+ });
13337
+ el.dispatchEvent(evt);
13338
+ el.onchange = (e2) => {
13339
+ const target = e2.target;
13340
+ if (target) {
13341
+ const files = target.files || [];
13342
+ const arr = Array.from(files);
13343
+ arr.forEach((item) => {
13344
+ const blob = new Blob([item], {
13345
+ type: item.type
13346
+ });
13347
+ const url2 = URL.createObjectURL(blob);
13348
+ res.tempFilePaths.push(url2);
13349
+ res.tempFiles.push({
13350
+ path: url2,
13351
+ size: item.size,
13352
+ type: item.type,
13353
+ originalFileObj: item
13354
+ });
13355
+ });
13356
+ handleSuccess(res, resolve);
13357
+ target.value = "";
13358
+ }
13359
+ };
13360
+ }
13361
+ });
13362
+ };
13249
13363
  const defaultProps$I = {
13250
13364
  ...ComponentDefaults,
13251
13365
  percent: 0,
@@ -13557,6 +13671,7 @@ const InternalUploader = (props, ref) => {
13557
13671
  beforeUpload,
13558
13672
  beforeXhrUpload,
13559
13673
  beforeDelete,
13674
+ needChooseFile,
13560
13675
  ...restProps
13561
13676
  } = { ...defaultProps$H, ...props };
13562
13677
  const [fileList, setFileList] = usePropsValue({
@@ -13596,14 +13711,14 @@ const InternalUploader = (props, ref) => {
13596
13711
  if (disabled) {
13597
13712
  return;
13598
13713
  }
13599
- if (Taro.getEnv() === "WEB") {
13600
- const el = document.getElementById("taroChooseImage");
13714
+ if (Taro.getEnv() === "WEB" && needChooseFile) {
13715
+ const el = document.getElementById("taroChooseFile");
13601
13716
  if (el) {
13602
13717
  el == null ? void 0 : el.setAttribute("accept", accept);
13603
13718
  } else {
13604
13719
  const obj = document.createElement("input");
13605
13720
  obj.setAttribute("type", "file");
13606
- obj.setAttribute("id", "taroChooseImage");
13721
+ obj.setAttribute("id", "taroChooseFile");
13607
13722
  obj.setAttribute("accept", accept);
13608
13723
  obj.setAttribute(
13609
13724
  "style",
@@ -13611,8 +13726,17 @@ const InternalUploader = (props, ref) => {
13611
13726
  );
13612
13727
  document.body.appendChild(obj);
13613
13728
  }
13614
- }
13615
- if (["WEAPP", "JD"].includes(getEnv()) && chooseMedia) {
13729
+ chooseFile({
13730
+ count: multiple ? maxCount * 1 - fileList.length : 1,
13731
+ // 可以指定是原图还是压缩图,默认二者都有
13732
+ sizeType,
13733
+ sourceType,
13734
+ success: onChangeImage,
13735
+ fail: (res) => {
13736
+ onFailure && onFailure(res);
13737
+ }
13738
+ });
13739
+ } else if (["WEAPP", "JD", "WEB"].includes(getEnv()) && chooseMedia) {
13616
13740
  chooseMedia({
13617
13741
  count: multiple ? maxCount * 1 - fileList.length : 1,
13618
13742
  /** 文件类型 */
@@ -2,7 +2,7 @@
2
2
  typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("@tarojs/taro"), require("@tarojs/components"), require("react-dom")) : typeof define === "function" && define.amd ? define(["exports", "react", "@tarojs/taro", "@tarojs/components", "react-dom"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory((global2.nutui = global2.nutui || {}, global2.nutui.react = {}), global2.React, global2.Taro, global2.components, global2.ReactDOM));
3
3
  })(this, function(exports2, React, Taro, components, ReactDOM) {
4
4
  "use strict";/*!
5
- * @nutui/nutui-react-taro v2.7.15-beta.1 Tue Feb 10 2026 22:24:45 GMT+0800 (China Standard Time)
5
+ * @nutui/nutui-react-taro v2.7.16-beta.0 Fri May 22 2026 21:54:20 GMT+0800 (China Standard Time)
6
6
  * (c) 2023 @jdf2e.
7
7
  * Released under the MIT License.
8
8
  */
@@ -6600,6 +6600,9 @@
6600
6600
  const [state] = React.useState({
6601
6601
  currDateArray: []
6602
6602
  });
6603
+ const isSameRange = (range2, start, end) => {
6604
+ return range2[0] === start && range2[1] === end;
6605
+ };
6603
6606
  const resetDefaultValue = () => {
6604
6607
  if (defaultValue || Array.isArray(defaultValue) && defaultValue.length > 0) {
6605
6608
  return type2 !== "single" ? [...defaultValue] : defaultValue;
@@ -6682,7 +6685,9 @@
6682
6685
  start = 0;
6683
6686
  end = monthNum + 2;
6684
6687
  }
6685
- setMonthDefaultRange([start, end]);
6688
+ setMonthDefaultRange((range2) => {
6689
+ return isSameRange(range2, start, end) ? range2 : [start, end];
6690
+ });
6686
6691
  setTranslateY(monthsData[start].scrollTop);
6687
6692
  setReachedYearMonthInfo(current);
6688
6693
  };
@@ -6829,8 +6834,10 @@
6829
6834
  viewHeight = getMonthsRef().clientHeight;
6830
6835
  getMonthsPanel().style.height = `${containerHeight}px`;
6831
6836
  const currTop = monthsData[current].scrollTop;
6832
- getMonthsRef().scrollTop = currTop;
6833
- setScrollTop(currTop);
6837
+ const maxScrollTop = getMonthsRef().scrollHeight - getMonthsRef().clientHeight;
6838
+ const targetScrollTop = Math.min(currTop, maxScrollTop);
6839
+ getMonthsRef().scrollTop = targetScrollTop;
6840
+ setScrollTop(targetScrollTop);
6834
6841
  Taro.nextTick(() => setScrollWithAnimation(true));
6835
6842
  }
6836
6843
  });
@@ -6907,6 +6914,7 @@
6907
6914
  const monthsViewScroll = (e2) => {
6908
6915
  if (monthsData.length <= 1) return;
6909
6916
  const scrollTop2 = e2.target.scrollTop;
6917
+ console.log("🚀 ~ monthsViewScroll ~ scrollTop:", scrollTop2);
6910
6918
  Taro.getEnv() === "WEB" && setScrollTop(scrollTop2);
6911
6919
  let current = Math.floor(scrollTop2 / avgHeight);
6912
6920
  if (current < 0) return;
@@ -11865,7 +11873,7 @@
11865
11873
  const cls = classNames(
11866
11874
  classPrefix$g,
11867
11875
  {
11868
- [`${classPrefix$g}-${props.direction}`]: props.direction
11876
+ [`${classPrefix$g}-${direction}`]: direction
11869
11877
  },
11870
11878
  className
11871
11879
  );
@@ -13262,6 +13270,112 @@
13262
13270
  this.formData = {};
13263
13271
  }
13264
13272
  }
13273
+ const chooseFile = (options) => {
13274
+ const shouldBeObjectNative = (options2) => {
13275
+ const isObject22 = options2 !== null && typeof options2 === "object" && !Array.isArray(options2);
13276
+ if (!isObject22) {
13277
+ return {
13278
+ flag: false,
13279
+ msg: "parameter should be Object"
13280
+ };
13281
+ }
13282
+ return {
13283
+ flag: true,
13284
+ msg: ""
13285
+ };
13286
+ };
13287
+ const isObject2 = shouldBeObjectNative(options);
13288
+ if (!isObject2.flag) {
13289
+ const res2 = { errMsg: `taroChooseFile:fail ${isObject2.msg}` };
13290
+ console.error(res2.errMsg);
13291
+ return Promise.reject(res2);
13292
+ }
13293
+ const {
13294
+ count = 1,
13295
+ success,
13296
+ fail,
13297
+ complete,
13298
+ imageId = "taroChooseFile",
13299
+ sourceType = ["album", "camera"]
13300
+ } = options;
13301
+ const res = {
13302
+ tempFilePaths: [],
13303
+ tempFiles: [],
13304
+ errMsg: ""
13305
+ };
13306
+ const handleSuccess = (data = {}, resolve = Promise.resolve.bind(Promise)) => {
13307
+ if (!data.errMsg) {
13308
+ data.errMsg = "taroChooseFile:ok";
13309
+ }
13310
+ typeof success === "function" && success(data);
13311
+ typeof complete === "function" && complete(data);
13312
+ return resolve(data);
13313
+ };
13314
+ const handleFail = (data = {}, reject = Promise.reject.bind(Promise)) => {
13315
+ if (!data.errMsg) {
13316
+ data.errMsg = "taroChooseFile:fail";
13317
+ } else {
13318
+ data.errMsg = `taroChooseFile:fail ${data.errMsg}`;
13319
+ }
13320
+ console.error(data.errMsg);
13321
+ typeof fail === "function" && fail(data);
13322
+ typeof complete === "function" && complete(data);
13323
+ return reject(data);
13324
+ };
13325
+ const sourceTypeString = sourceType && sourceType.toString();
13326
+ const acceptableSourceType = ["user", "environment", "camera"];
13327
+ if (count && typeof count !== "number") {
13328
+ res.errMsg = `parameter error: count should be number, but got ${typeof count}`;
13329
+ return handleFail(res);
13330
+ }
13331
+ const el = document.getElementById(imageId);
13332
+ if (!el) {
13333
+ res.errMsg = "taroChooseFile:fail element not found";
13334
+ return handleFail(res);
13335
+ }
13336
+ if (count > 1) {
13337
+ el.setAttribute("multiple", "multiple");
13338
+ } else {
13339
+ el.removeAttribute("multiple");
13340
+ }
13341
+ if (acceptableSourceType.indexOf(sourceTypeString) > -1) {
13342
+ el.setAttribute("capture", sourceTypeString);
13343
+ } else {
13344
+ el.removeAttribute("capture");
13345
+ }
13346
+ return new Promise((resolve) => {
13347
+ if (el) {
13348
+ const evt = new MouseEvent("click", {
13349
+ bubbles: true,
13350
+ cancelable: true,
13351
+ view: window
13352
+ });
13353
+ el.dispatchEvent(evt);
13354
+ el.onchange = (e2) => {
13355
+ const target = e2.target;
13356
+ if (target) {
13357
+ const files = target.files || [];
13358
+ const arr = Array.from(files);
13359
+ arr.forEach((item) => {
13360
+ const blob = new Blob([item], {
13361
+ type: item.type
13362
+ });
13363
+ const url = URL.createObjectURL(blob);
13364
+ res.tempFilePaths.push(url);
13365
+ res.tempFiles.push({
13366
+ path: url,
13367
+ size: item.size,
13368
+ type: item.type,
13369
+ originalFileObj: item
13370
+ });
13371
+ });
13372
+ handleSuccess(res, resolve);
13373
+ target.value = "";
13374
+ }
13375
+ };
13376
+ }
13377
+ });
13378
+ };
13265
13379
  const defaultProps$I = {
13266
13380
  ...ComponentDefaults,
13267
13381
  percent: 0,
@@ -13573,6 +13687,7 @@
13573
13687
  beforeUpload,
13574
13688
  beforeXhrUpload,
13575
13689
  beforeDelete,
13690
+ needChooseFile,
13576
13691
  ...restProps
13577
13692
  } = { ...defaultProps$H, ...props };
13578
13693
  const [fileList, setFileList] = usePropsValue({
@@ -13612,14 +13727,14 @@
13612
13727
  if (disabled) {
13613
13728
  return;
13614
13729
  }
13615
- if (Taro.getEnv() === "WEB") {
13616
- const el = document.getElementById("taroChooseImage");
13730
+ if (Taro.getEnv() === "WEB" && needChooseFile) {
13731
+ const el = document.getElementById("taroChooseFile");
13617
13732
  if (el) {
13618
13733
  el == null ? void 0 : el.setAttribute("accept", accept);
13619
13734
  } else {
13620
13735
  const obj = document.createElement("input");
13621
13736
  obj.setAttribute("type", "file");
13622
- obj.setAttribute("id", "taroChooseImage");
13737
+ obj.setAttribute("id", "taroChooseFile");
13623
13738
  obj.setAttribute("accept", accept);
13624
13739
  obj.setAttribute(
13625
13740
  "style",
@@ -13627,8 +13742,17 @@
13627
13742
  );
13628
13743
  document.body.appendChild(obj);
13629
13744
  }
13630
- }
13631
- if (["WEAPP", "JD"].includes(Taro.getEnv()) && Taro.chooseMedia) {
13745
+ chooseFile({
13746
+ count: multiple ? maxCount * 1 - fileList.length : 1,
13747
+ // 可以指定是原图还是压缩图,默认二者都有
13748
+ sizeType,
13749
+ sourceType,
13750
+ success: onChangeImage,
13751
+ fail: (res) => {
13752
+ onFailure && onFailure(res);
13753
+ }
13754
+ });
13755
+ } else if (["WEAPP", "JD", "WEB"].includes(Taro.getEnv()) && Taro.chooseMedia) {
13632
13756
  Taro.chooseMedia({
13633
13757
  count: multiple ? maxCount * 1 - fileList.length : 1,
13634
13758
  /** 文件类型 */
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 从本地选择文件。
3
+ */
4
+ export declare const chooseFile: (options: any) => any;
@@ -97,7 +97,11 @@ export interface UploaderProps extends BasicComponent {
97
97
  * @default file
98
98
  */
99
99
  name: string
100
- accept: string;
100
+ /**
101
+ * H5 端 input 的 accept 属性,用于限制选择的文件类型(仅 H5 端生效)
102
+ * @default *
103
+ */
104
+ accept: string
101
105
  /**
102
106
  * 是否禁用文件上传
103
107
  * @default false
@@ -228,6 +232,11 @@ export interface UploaderProps extends BasicComponent {
228
232
  * @default -
229
233
  */
230
234
  onFileItemClick?: (file: FileItem, index: number) => void
235
+ /**
236
+ * 是否在 H5 端使用原生 input 选择文件(配合 accept 自定义文件类型,仅 H5 端生效)
237
+ * @default false
238
+ */
239
+ needChooseFile?: boolean
231
240
  }
232
241
  export declare const Uploader: React.ForwardRefExoticComponent<Partial<UploaderProps> & {
233
242
  children?: React.ReactNode | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nutui/nutui-react-taro",
3
- "version": "2.7.15-beta.1",
3
+ "version": "2.7.16-beta.0",
4
4
  "style": "dist/style.css",
5
5
  "main": "dist/nutui.react.umd.js",
6
6
  "module": "dist/esm/nutui-react.es.js",