@svton/taro-ui 1.0.0 → 1.0.1

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/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -45,11 +46,11 @@ __export(index_exports, {
45
46
  module.exports = __toCommonJS(index_exports);
46
47
 
47
48
  // src/components/TabBar/index.tsx
48
- var import_react = __toESM(require("react"));
49
+ var import_react = require("react");
49
50
  var import_components = require("@tarojs/components");
50
51
  var import_hooks = require("@svton/hooks");
52
+ var import_jsx_runtime = require("react/jsx-runtime");
51
53
  function TabBar(props) {
52
- var _a;
53
54
  const {
54
55
  items,
55
56
  activeKey: controlledActiveKey,
@@ -61,7 +62,7 @@ function TabBar(props) {
61
62
  showIndicator = true,
62
63
  sticky = true
63
64
  } = props;
64
- const [internalActiveKey, setInternalActiveKey] = (0, import_react.useState)(defaultActiveKey || ((_a = items[0]) == null ? void 0 : _a.key));
65
+ const [internalActiveKey, setInternalActiveKey] = (0, import_react.useState)(defaultActiveKey || items[0]?.key);
65
66
  const activeKey = controlledActiveKey !== void 0 ? controlledActiveKey : internalActiveKey;
66
67
  const activeIndex = items.findIndex((item) => item.key === activeKey);
67
68
  const indicatorLeft = items.length > 0 ? `${(activeIndex + 0.5) * (100 / items.length)}%` : "50%";
@@ -70,38 +71,41 @@ function TabBar(props) {
70
71
  if (controlledActiveKey === void 0) {
71
72
  setInternalActiveKey(key);
72
73
  }
73
- onChange == null ? void 0 : onChange(key);
74
+ onChange?.(key);
74
75
  });
75
76
  (0, import_react.useEffect)(() => {
76
77
  if (controlledActiveKey !== void 0) {
77
78
  setInternalActiveKey(controlledActiveKey);
78
79
  }
79
80
  }, [controlledActiveKey]);
80
- return /* @__PURE__ */ import_react.default.createElement(import_components.View, { className: `svton-tab-bar ${sticky ? "sticky" : ""} ${className}`, style }, /* @__PURE__ */ import_react.default.createElement(import_components.View, { className: "svton-tab-bar__list" }, items.map((item) => /* @__PURE__ */ import_react.default.createElement(
81
- import_components.View,
82
- {
83
- key: item.key,
84
- className: `svton-tab-bar__item ${activeKey === item.key ? "active" : ""} ${item.disabled ? "disabled" : ""}`,
85
- onClick: () => handleTabChange(item.key, item.disabled)
86
- },
87
- item.render ? item.render() : /* @__PURE__ */ import_react.default.createElement(import_components.Text, { className: "svton-tab-bar__text" }, item.label)
88
- ))), showIndicator && items.length > 0 && /* @__PURE__ */ import_react.default.createElement(import_components.View, { className: "svton-tab-bar__indicator-wrapper" }, /* @__PURE__ */ import_react.default.createElement(
89
- import_components.View,
90
- {
91
- className: "svton-tab-bar__indicator",
92
- style: {
93
- left: indicatorLeft,
94
- width: `${indicatorWidth}px`,
95
- marginLeft: `-${indicatorWidth / 2}px`
81
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.View, { className: `svton-tab-bar ${sticky ? "sticky" : ""} ${className}`, style, children: [
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.View, { className: "svton-tab-bar__list", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
83
+ import_components.View,
84
+ {
85
+ className: `svton-tab-bar__item ${activeKey === item.key ? "active" : ""} ${item.disabled ? "disabled" : ""}`,
86
+ onClick: () => handleTabChange(item.key, item.disabled),
87
+ children: item.render ? item.render() : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Text, { className: "svton-tab-bar__text", children: item.label })
88
+ },
89
+ item.key
90
+ )) }),
91
+ showIndicator && items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.View, { className: "svton-tab-bar__indicator-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
92
+ import_components.View,
93
+ {
94
+ className: "svton-tab-bar__indicator",
95
+ style: {
96
+ left: indicatorLeft,
97
+ width: `${indicatorWidth}px`,
98
+ marginLeft: `-${indicatorWidth / 2}px`
99
+ }
96
100
  }
97
- }
98
- )));
101
+ ) })
102
+ ] });
99
103
  }
100
104
 
101
105
  // src/components/Button/index.tsx
102
- var import_react2 = __toESM(require("react"));
103
106
  var import_components2 = require("@tarojs/components");
104
107
  var import_hooks2 = require("@svton/hooks");
108
+ var import_jsx_runtime2 = require("react/jsx-runtime");
105
109
  function Button(props) {
106
110
  const {
107
111
  type = "default",
@@ -116,24 +120,26 @@ function Button(props) {
116
120
  } = props;
117
121
  const handleClick = (0, import_hooks2.usePersistFn)(() => {
118
122
  if (disabled || loading) return;
119
- onClick == null ? void 0 : onClick();
123
+ onClick?.();
120
124
  });
121
- return /* @__PURE__ */ import_react2.default.createElement(
125
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
122
126
  import_components2.View,
123
127
  {
124
128
  className: `svton-button svton-button--${type} svton-button--${size} ${block ? "svton-button--block" : ""} ${disabled ? "svton-button--disabled" : ""} ${loading ? "svton-button--loading" : ""} ${className}`,
125
129
  style,
126
- onClick: handleClick
127
- },
128
- loading && /* @__PURE__ */ import_react2.default.createElement(import_components2.View, { className: "svton-button__loading" }, /* @__PURE__ */ import_react2.default.createElement(import_components2.Text, { className: "svton-button__loading-icon" }, "\u23F3")),
129
- /* @__PURE__ */ import_react2.default.createElement(import_components2.Text, { className: "svton-button__text" }, children)
130
+ onClick: handleClick,
131
+ children: [
132
+ loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components2.View, { className: "svton-button__loading", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components2.Text, { className: "svton-button__loading-icon", children: "\u23F3" }) }),
133
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_components2.Text, { className: "svton-button__text", children })
134
+ ]
135
+ }
130
136
  );
131
137
  }
132
138
 
133
139
  // src/components/List/index.tsx
134
- var import_react3 = __toESM(require("react"));
135
140
  var import_components3 = require("@tarojs/components");
136
141
  var import_taro = __toESM(require("@tarojs/taro"));
142
+ var import_jsx_runtime3 = require("react/jsx-runtime");
137
143
  function List(props) {
138
144
  const {
139
145
  data,
@@ -160,42 +166,49 @@ function List(props) {
160
166
  return;
161
167
  }
162
168
  try {
163
- await (onRefresh == null ? void 0 : onRefresh());
169
+ await onRefresh?.();
164
170
  } finally {
165
171
  import_taro.default.stopPullDownRefresh();
166
172
  }
167
173
  });
168
174
  (0, import_taro.useReachBottom)(async () => {
169
175
  if (!enableLoadMore || !hasMore || loading || !onLoadMore) return;
170
- await (onLoadMore == null ? void 0 : onLoadMore());
176
+ await onLoadMore?.();
171
177
  });
172
178
  const renderEmptyContent = () => {
173
179
  if (renderEmpty) {
174
180
  return renderEmpty();
175
181
  }
176
- return /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { className: "svton-list__empty" }, /* @__PURE__ */ import_react3.default.createElement(import_components3.Text, { className: "svton-list__empty-text" }, emptyText));
182
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__empty", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.Text, { className: "svton-list__empty-text", children: emptyText }) });
177
183
  };
178
184
  const renderLoadingTip = () => {
179
185
  if (!loading && !hasMore) {
180
- return /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { className: "svton-list__tip svton-list__tip--no-more" }, /* @__PURE__ */ import_react3.default.createElement(import_components3.Text, null, noMoreText));
186
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__tip svton-list__tip--no-more", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.Text, { children: noMoreText }) });
181
187
  }
182
188
  if (loading && data.length > 0) {
183
- return /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { className: "svton-list__tip svton-list__tip--loading" }, /* @__PURE__ */ import_react3.default.createElement(import_components3.Text, null, loadingText));
189
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__tip svton-list__tip--loading", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.Text, { children: loadingText }) });
184
190
  }
185
191
  return null;
186
192
  };
187
- return /* @__PURE__ */ import_react3.default.createElement(import_components3.ScrollView, { className: `svton-list ${className}`, style, scrollY: true, enableBackToTop: true }, header && /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { className: "svton-list__header" }, header), data.length === 0 && !loading ? renderEmptyContent() : /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { className: "svton-list__content" }, data.map((item, index) => /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { key: keyExtractor(item, index), className: "svton-list__item" }, renderItem(item, index)))), renderLoadingTip(), footer && /* @__PURE__ */ import_react3.default.createElement(import_components3.View, { className: "svton-list__footer" }, footer));
193
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_components3.ScrollView, { className: `svton-list ${className}`, style, scrollY: true, enableBackToTop: true, children: [
194
+ header && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__header", children: header }),
195
+ data.length === 0 && !loading ? renderEmptyContent() : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__content", children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__item", children: renderItem(item, index) }, keyExtractor(item, index))) }),
196
+ renderLoadingTip(),
197
+ footer && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components3.View, { className: "svton-list__footer", children: footer })
198
+ ] });
188
199
  }
189
200
 
190
201
  // src/components/NavBar/index.tsx
191
- var import_react5 = __toESM(require("react"));
202
+ var import_react3 = require("react");
192
203
  var import_components5 = require("@tarojs/components");
193
204
  var import_taro3 = __toESM(require("@tarojs/taro"));
194
205
 
195
206
  // src/utils/systemInfo.ts
196
207
  var import_taro2 = __toESM(require("@tarojs/taro"));
197
208
  var SystemInfoManager = class {
198
- info = null;
209
+ constructor() {
210
+ this.info = null;
211
+ }
199
212
  async init() {
200
213
  try {
201
214
  const systemInfo = await import_taro2.default.getSystemInfo();
@@ -277,32 +290,30 @@ var SystemInfoManager = class {
277
290
  return this.info;
278
291
  }
279
292
  getStatusBarHeight() {
280
- var _a;
281
- return ((_a = this.info) == null ? void 0 : _a.statusBarHeight) || 44;
293
+ return this.info?.statusBarHeight || 44;
282
294
  }
283
295
  getNavBarHeight() {
284
- var _a;
285
- return ((_a = this.info) == null ? void 0 : _a.navBarHeight) || 88;
296
+ return this.info?.navBarHeight || 88;
286
297
  }
287
298
  getSafeAreaInsets() {
288
- var _a;
289
- return ((_a = this.info) == null ? void 0 : _a.safeAreaInsets) || { top: 44, right: 0, bottom: 0, left: 0 };
299
+ return this.info?.safeAreaInsets || { top: 44, right: 0, bottom: 0, left: 0 };
290
300
  }
291
301
  };
292
302
  var systemInfoManager = new SystemInfoManager();
293
303
 
294
304
  // src/components/StatusBar/index.tsx
295
- var import_react4 = __toESM(require("react"));
305
+ var import_react2 = require("react");
296
306
  var import_components4 = require("@tarojs/components");
307
+ var import_jsx_runtime4 = require("react/jsx-runtime");
297
308
  function StatusBar({ backgroundColor, className = "" }) {
298
- const [height, setHeight] = (0, import_react4.useState)(44);
299
- (0, import_react4.useEffect)(() => {
309
+ const [height, setHeight] = (0, import_react2.useState)(44);
310
+ (0, import_react2.useEffect)(() => {
300
311
  const info = systemInfoManager.getInfo();
301
312
  if (info) {
302
313
  setHeight(info.statusBarHeight);
303
314
  }
304
315
  }, []);
305
- return /* @__PURE__ */ import_react4.default.createElement(
316
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
306
317
  import_components4.View,
307
318
  {
308
319
  className: `status-bar ${className}`,
@@ -315,6 +326,7 @@ function StatusBar({ backgroundColor, className = "" }) {
315
326
  }
316
327
 
317
328
  // src/components/NavBar/index.tsx
329
+ var import_jsx_runtime5 = require("react/jsx-runtime");
318
330
  var BACK_ICON_SVG = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBkPSJNMTUgMThMOSAxMkwxNSA2IiBzdHJva2U9IiMzMzMzMzMiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=";
319
331
  function CustomNavBar({
320
332
  title = "",
@@ -328,9 +340,9 @@ function CustomNavBar({
328
340
  fixed = false,
329
341
  scrollOpacity = 1
330
342
  }) {
331
- const [navBarContentHeight, setNavBarContentHeight] = (0, import_react5.useState)(44);
332
- const [statusBarHeight, setStatusBarHeight] = (0, import_react5.useState)(44);
333
- const [menuButtonLeft, setMenuButtonLeft] = (0, import_react5.useState)(0);
343
+ const [navBarContentHeight, setNavBarContentHeight] = (0, import_react3.useState)(44);
344
+ const [statusBarHeight, setStatusBarHeight] = (0, import_react3.useState)(44);
345
+ const [menuButtonLeft, setMenuButtonLeft] = (0, import_react3.useState)(0);
334
346
  const getBackgroundColor = () => {
335
347
  if (scrollOpacity >= 1) {
336
348
  return backgroundColor;
@@ -341,7 +353,7 @@ function CustomNavBar({
341
353
  const b = parseInt(hex.substring(4, 6), 16);
342
354
  return `rgba(${r}, ${g}, ${b}, ${scrollOpacity})`;
343
355
  };
344
- (0, import_react5.useEffect)(() => {
356
+ (0, import_react3.useEffect)(() => {
345
357
  const info = systemInfoManager.getInfo();
346
358
  if (info) {
347
359
  setNavBarContentHeight(info.navBarHeight - info.statusBarHeight);
@@ -401,49 +413,61 @@ function CustomNavBar({
401
413
  const navBarClass = `custom-nav-bar ${fixed ? "fixed" : ""}`;
402
414
  const actualBgColor = getBackgroundColor();
403
415
  const totalHeight = statusBarHeight + navBarContentHeight;
404
- const navBarContent = /* @__PURE__ */ import_react5.default.createElement(import_components5.View, { className: navBarClass, style: { backgroundColor: actualBgColor } }, /* @__PURE__ */ import_react5.default.createElement(StatusBar, { backgroundColor: actualBgColor }), /* @__PURE__ */ import_react5.default.createElement(
405
- import_components5.View,
406
- {
407
- className: "nav-bar-content",
408
- style: {
409
- height: `${navBarContentHeight}px`,
410
- backgroundColor: actualBgColor
411
- }
412
- },
413
- (showBack || showClose) && /* @__PURE__ */ import_react5.default.createElement(import_components5.View, { className: "nav-left" }, showBack && /* @__PURE__ */ import_react5.default.createElement(import_components5.View, { className: "nav-btn", onClick: handleBack }, /* @__PURE__ */ import_react5.default.createElement(
414
- import_components5.Image,
415
- {
416
- className: "nav-icon-img back-icon-img",
417
- src: BACK_ICON_SVG,
418
- mode: "aspectFit"
419
- }
420
- )), showClose && /* @__PURE__ */ import_react5.default.createElement(import_components5.View, { className: "nav-btn", onClick: handleClose }, /* @__PURE__ */ import_react5.default.createElement(import_components5.Text, { className: "nav-icon close-icon", style: { color: textColor } }, "\u2715"))),
421
- title && /* @__PURE__ */ import_react5.default.createElement(import_components5.View, { className: "nav-title" }, /* @__PURE__ */ import_react5.default.createElement(import_components5.Text, { className: "title-text", style: { color: textColor } }, title)),
422
- rightContent && /* @__PURE__ */ import_react5.default.createElement(import_components5.View, { className: "nav-right", style: { right: `${getRightSafeDistance()}px` } }, rightContent)
423
- ));
424
- if (fixed) {
425
- return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement(
416
+ const navBarContent = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_components5.View, { className: navBarClass, style: { backgroundColor: actualBgColor }, children: [
417
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusBar, { backgroundColor: actualBgColor }),
418
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
426
419
  import_components5.View,
427
420
  {
428
- className: "nav-bar-placeholder",
429
- style: { height: `${totalHeight}px` }
421
+ className: "nav-bar-content",
422
+ style: {
423
+ height: `${navBarContentHeight}px`,
424
+ backgroundColor: actualBgColor
425
+ },
426
+ children: [
427
+ (showBack || showClose) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_components5.View, { className: "nav-left", children: [
428
+ showBack && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components5.View, { className: "nav-btn", onClick: handleBack, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
429
+ import_components5.Image,
430
+ {
431
+ className: "nav-icon-img back-icon-img",
432
+ src: BACK_ICON_SVG,
433
+ mode: "aspectFit"
434
+ }
435
+ ) }),
436
+ showClose && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components5.View, { className: "nav-btn", onClick: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components5.Text, { className: "nav-icon close-icon", style: { color: textColor }, children: "\u2715" }) })
437
+ ] }),
438
+ title && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components5.View, { className: "nav-title", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components5.Text, { className: "title-text", style: { color: textColor }, children: title }) }),
439
+ rightContent && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components5.View, { className: "nav-right", style: { right: `${getRightSafeDistance()}px` }, children: rightContent })
440
+ ]
430
441
  }
431
- ), navBarContent);
442
+ )
443
+ ] });
444
+ if (fixed) {
445
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
446
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
447
+ import_components5.View,
448
+ {
449
+ className: "nav-bar-placeholder",
450
+ style: { height: `${totalHeight}px` }
451
+ }
452
+ ),
453
+ navBarContent
454
+ ] });
432
455
  }
433
456
  return navBarContent;
434
457
  }
435
458
 
436
459
  // src/components/ImageUploader/index.tsx
437
- var import_react6 = __toESM(require("react"));
460
+ var import_react4 = require("react");
438
461
  var import_components6 = require("@tarojs/components");
439
462
  var import_taro4 = __toESM(require("@tarojs/taro"));
463
+ var import_jsx_runtime6 = require("react/jsx-runtime");
440
464
  function ImageUploader({
441
465
  value = [],
442
466
  onChange,
443
467
  maxCount = 9,
444
468
  uploadUrl = process.env.TARO_APP_API + "/upload/image"
445
469
  }) {
446
- const [uploading, setUploading] = (0, import_react6.useState)(false);
470
+ const [uploading, setUploading] = (0, import_react4.useState)(false);
447
471
  const handleChooseImage = async () => {
448
472
  try {
449
473
  const res = await import_taro4.default.chooseImage({
@@ -467,7 +491,7 @@ function ImageUploader({
467
491
  });
468
492
  const urls = await Promise.all(uploadPromises);
469
493
  const newImages = [...value, ...urls];
470
- onChange == null ? void 0 : onChange(newImages);
494
+ onChange?.(newImages);
471
495
  import_taro4.default.showToast({
472
496
  title: "\u4E0A\u4F20\u6210\u529F",
473
497
  icon: "success"
@@ -494,33 +518,46 @@ function ImageUploader({
494
518
  success: (res) => {
495
519
  if (res.confirm) {
496
520
  const newImages = value.filter((_, i) => i !== index);
497
- onChange == null ? void 0 : onChange(newImages);
521
+ onChange?.(newImages);
498
522
  }
499
523
  }
500
524
  });
501
525
  };
502
- return /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { className: "image-uploader" }, /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { className: "image-list" }, value.map((url, index) => /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { key: index, className: "image-item" }, /* @__PURE__ */ import_react6.default.createElement(
503
- import_components6.Image,
504
- {
505
- src: url,
506
- mode: "aspectFill",
507
- className: "image",
508
- onClick: () => handlePreview(index)
509
- }
510
- ), /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { className: "delete-btn", onClick: () => handleDelete(index) }, "\xD7"))), value.length < maxCount && /* @__PURE__ */ import_react6.default.createElement(
511
- import_components6.View,
512
- {
513
- className: `add-btn ${uploading ? "disabled" : ""}`,
514
- onClick: uploading ? void 0 : handleChooseImage
515
- },
516
- uploading ? /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { className: "loading" }, "\u4E0A\u4F20\u4E2D...") : /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { className: "add-icon" }, "+")
517
- )), /* @__PURE__ */ import_react6.default.createElement(import_components6.View, { className: "tip" }, "\u6700\u591A\u4E0A\u4F20 ", maxCount, " \u5F20\u56FE\u7247"));
526
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_components6.View, { className: "image-uploader", children: [
527
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_components6.View, { className: "image-list", children: [
528
+ value.map((url, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_components6.View, { className: "image-item", children: [
529
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
530
+ import_components6.Image,
531
+ {
532
+ src: url,
533
+ mode: "aspectFill",
534
+ className: "image",
535
+ onClick: () => handlePreview(index)
536
+ }
537
+ ),
538
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components6.View, { className: "delete-btn", onClick: () => handleDelete(index), children: "\xD7" })
539
+ ] }, index)),
540
+ value.length < maxCount && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
541
+ import_components6.View,
542
+ {
543
+ className: `add-btn ${uploading ? "disabled" : ""}`,
544
+ onClick: uploading ? void 0 : handleChooseImage,
545
+ children: uploading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components6.View, { className: "loading", children: "\u4E0A\u4F20\u4E2D..." }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components6.View, { className: "add-icon", children: "+" })
546
+ }
547
+ )
548
+ ] }),
549
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_components6.View, { className: "tip", children: [
550
+ "\u6700\u591A\u4E0A\u4F20 ",
551
+ maxCount,
552
+ " \u5F20\u56FE\u7247"
553
+ ] })
554
+ ] });
518
555
  }
519
556
 
520
557
  // src/components/ImageGrid/index.tsx
521
- var import_react7 = __toESM(require("react"));
522
558
  var import_components7 = require("@tarojs/components");
523
559
  var import_taro5 = __toESM(require("@tarojs/taro"));
560
+ var import_jsx_runtime7 = require("react/jsx-runtime");
524
561
  function ImageGrid({ images, maxCount = 9, onImageClick }) {
525
562
  const displayImages = images.slice(0, maxCount);
526
563
  const count = displayImages.length;
@@ -539,19 +576,26 @@ function ImageGrid({ images, maxCount = 9, onImageClick }) {
539
576
  });
540
577
  }
541
578
  };
542
- return /* @__PURE__ */ import_react7.default.createElement(import_components7.View, { className: `image-grid ${getGridClass()}` }, displayImages.map((url, index) => /* @__PURE__ */ import_react7.default.createElement(import_components7.View, { key: index, className: "image-item", onClick: () => handleImageClick(index) }, /* @__PURE__ */ import_react7.default.createElement(
543
- import_components7.Image,
544
- {
545
- src: url,
546
- mode: count === 1 ? "widthFix" : "aspectFill",
547
- className: "image",
548
- lazyLoad: true
549
- }
550
- ), index === maxCount - 1 && images.length > maxCount && /* @__PURE__ */ import_react7.default.createElement(import_components7.View, { className: "image-overlay" }, /* @__PURE__ */ import_react7.default.createElement(import_components7.View, { className: "image-count" }, "+", images.length - maxCount + 1)))));
579
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_components7.View, { className: `image-grid ${getGridClass()}`, children: displayImages.map((url, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_components7.View, { className: "image-item", onClick: () => handleImageClick(index), children: [
580
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
581
+ import_components7.Image,
582
+ {
583
+ src: url,
584
+ mode: count === 1 ? "widthFix" : "aspectFill",
585
+ className: "image",
586
+ lazyLoad: true
587
+ }
588
+ ),
589
+ index === maxCount - 1 && images.length > maxCount && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_components7.View, { className: "image-overlay", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_components7.View, { className: "image-count", children: [
590
+ "+",
591
+ images.length - maxCount + 1
592
+ ] }) })
593
+ ] }, index)) });
551
594
  }
552
595
 
553
596
  // src/components/Tabs/index.tsx
554
597
  var import_components8 = require("@tarojs/components");
598
+ var import_jsx_runtime8 = require("react/jsx-runtime");
555
599
  function Tabs({ activeKey, items, onChange, className = "" }) {
556
600
  const handleItemClick = (e) => {
557
601
  const key = e.currentTarget.dataset.key;
@@ -559,23 +603,30 @@ function Tabs({ activeKey, items, onChange, className = "" }) {
559
603
  onChange(key);
560
604
  }
561
605
  };
562
- return /* @__PURE__ */ React.createElement(import_components8.View, { className: `svton-tabs ${className}` }, items.map((item) => /* @__PURE__ */ React.createElement(
606
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components8.View, { className: `svton-tabs ${className}`, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
563
607
  import_components8.View,
564
608
  {
565
- key: item.key,
566
609
  "data-key": item.key,
567
610
  className: `svton-tabs__item ${activeKey === item.key ? "svton-tabs__item--active" : ""}`,
568
- onClick: handleItemClick
611
+ onClick: handleItemClick,
612
+ children: [
613
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components8.Text, { className: "svton-tabs__label", children: item.label }),
614
+ item.count !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_components8.Text, { className: "svton-tabs__count", children: [
615
+ "(",
616
+ item.count,
617
+ ")"
618
+ ] })
619
+ ]
569
620
  },
570
- /* @__PURE__ */ React.createElement(import_components8.Text, { className: "svton-tabs__label" }, item.label),
571
- item.count !== void 0 && /* @__PURE__ */ React.createElement(import_components8.Text, { className: "svton-tabs__count" }, "(", item.count, ")")
572
- )));
621
+ item.key
622
+ )) });
573
623
  }
574
624
  var Tabs_default = Tabs;
575
625
 
576
626
  // src/components/ContentActionBar/index.tsx
577
- var import_react8 = __toESM(require("react"));
627
+ var import_react5 = require("react");
578
628
  var import_components9 = require("@tarojs/components");
629
+ var import_jsx_runtime9 = require("react/jsx-runtime");
579
630
  var ICONS = {
580
631
  // 点赞图标(未点赞) - 空心心形
581
632
  like: "https://miaoduo.fbcontent.cn/private/resource/image/19a9ba374ebbee0-0aa9c734-e868-4861-9bfd-37de7ed3a123.svg",
@@ -599,9 +650,9 @@ function ContentActionBar({
599
650
  maxLength = 500,
600
651
  disabled = false
601
652
  }) {
602
- const [isExpanded, setIsExpanded] = (0, import_react8.useState)(false);
603
- const [inputValue, setInputValue] = (0, import_react8.useState)("");
604
- const [submitting, setSubmitting] = (0, import_react8.useState)(false);
653
+ const [isExpanded, setIsExpanded] = (0, import_react5.useState)(false);
654
+ const [inputValue, setInputValue] = (0, import_react5.useState)("");
655
+ const [submitting, setSubmitting] = (0, import_react5.useState)(false);
605
656
  const handleExpand = () => {
606
657
  if (disabled) return;
607
658
  setIsExpanded(true);
@@ -614,7 +665,7 @@ function ContentActionBar({
614
665
  if (!inputValue.trim() || submitting || disabled) return;
615
666
  setSubmitting(true);
616
667
  try {
617
- await (onComment == null ? void 0 : onComment(inputValue.trim()));
668
+ await onComment?.(inputValue.trim());
618
669
  handleCollapse();
619
670
  } catch (error) {
620
671
  console.error("\u8BC4\u8BBA\u5931\u8D25:", error);
@@ -625,86 +676,106 @@ function ContentActionBar({
625
676
  const handleLike = (e) => {
626
677
  e.stopPropagation();
627
678
  if (disabled) return;
628
- onLike == null ? void 0 : onLike();
679
+ onLike?.();
629
680
  };
630
681
  const handleFavorite = (e) => {
631
682
  e.stopPropagation();
632
683
  if (disabled) return;
633
- onFavorite == null ? void 0 : onFavorite();
684
+ onFavorite?.();
634
685
  };
635
686
  const handleShare = (e) => {
636
687
  e.stopPropagation();
637
688
  if (disabled) return;
638
- onShare == null ? void 0 : onShare();
689
+ onShare?.();
639
690
  };
640
- return /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "content-action-bar" }, !isExpanded ? (
691
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.View, { className: "content-action-bar", children: !isExpanded ? (
641
692
  // 收起状态:输入框占位 + 操作按钮
642
- /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "action-bar-collapsed" }, /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "input-placeholder", onClick: handleExpand }, /* @__PURE__ */ import_react8.default.createElement(import_components9.Text, { className: "placeholder-text" }, placeholder)), /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "action-buttons" }, /* @__PURE__ */ import_react8.default.createElement(
643
- import_components9.View,
644
- {
645
- className: `action-btn ${liked ? "active" : ""}`,
646
- onClick: handleLike
647
- },
648
- /* @__PURE__ */ import_react8.default.createElement(
649
- import_components9.Image,
650
- {
651
- className: `action-icon-img ${liked ? "liked" : ""}`,
652
- src: liked ? ICONS.liked : ICONS.like,
653
- mode: "aspectFit"
654
- }
655
- )
656
- ), /* @__PURE__ */ import_react8.default.createElement(
657
- import_components9.View,
658
- {
659
- className: `action-btn ${favorited ? "active" : ""}`,
660
- onClick: handleFavorite
661
- },
662
- /* @__PURE__ */ import_react8.default.createElement(
663
- import_components9.Image,
664
- {
665
- className: `action-icon-img ${favorited ? "favorited" : ""}`,
666
- src: favorited ? ICONS.favorited : ICONS.favorite,
667
- mode: "aspectFit"
668
- }
669
- )
670
- ), /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "action-btn", onClick: handleShare }, /* @__PURE__ */ import_react8.default.createElement(
671
- import_components9.Image,
672
- {
673
- className: "action-icon-img",
674
- src: ICONS.share,
675
- mode: "aspectFit"
676
- }
677
- ))))
693
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_components9.View, { className: "action-bar-collapsed", children: [
694
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.View, { className: "input-placeholder", onClick: handleExpand, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.Text, { className: "placeholder-text", children: placeholder }) }),
695
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_components9.View, { className: "action-buttons", children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
697
+ import_components9.View,
698
+ {
699
+ className: `action-btn ${liked ? "active" : ""}`,
700
+ onClick: handleLike,
701
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
702
+ import_components9.Image,
703
+ {
704
+ className: `action-icon-img ${liked ? "liked" : ""}`,
705
+ src: liked ? ICONS.liked : ICONS.like,
706
+ mode: "aspectFit"
707
+ }
708
+ )
709
+ }
710
+ ),
711
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
712
+ import_components9.View,
713
+ {
714
+ className: `action-btn ${favorited ? "active" : ""}`,
715
+ onClick: handleFavorite,
716
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
717
+ import_components9.Image,
718
+ {
719
+ className: `action-icon-img ${favorited ? "favorited" : ""}`,
720
+ src: favorited ? ICONS.favorited : ICONS.favorite,
721
+ mode: "aspectFit"
722
+ }
723
+ )
724
+ }
725
+ ),
726
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.View, { className: "action-btn", onClick: handleShare, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
727
+ import_components9.Image,
728
+ {
729
+ className: "action-icon-img",
730
+ src: ICONS.share,
731
+ mode: "aspectFit"
732
+ }
733
+ ) })
734
+ ] })
735
+ ] })
678
736
  ) : (
679
737
  // 展开状态:多行输入框 + 发送按钮
680
- /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "action-bar-expanded" }, /* @__PURE__ */ import_react8.default.createElement(
681
- import_components9.Textarea,
682
- {
683
- className: "comment-textarea",
684
- value: inputValue,
685
- onInput: (e) => setInputValue(e.detail.value),
686
- placeholder,
687
- maxlength: maxLength,
688
- autoHeight: true,
689
- focus: true,
690
- disabled
691
- }
692
- ), /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "expanded-actions" }, /* @__PURE__ */ import_react8.default.createElement(import_components9.Text, { className: "char-count" }, inputValue.length, "/", maxLength), /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "action-btns" }, /* @__PURE__ */ import_react8.default.createElement(import_components9.View, { className: "cancel-btn", onClick: handleCollapse }, /* @__PURE__ */ import_react8.default.createElement(import_components9.Text, { className: "btn-text" }, "\u53D6\u6D88")), /* @__PURE__ */ import_react8.default.createElement(
693
- import_components9.View,
694
- {
695
- className: `send-btn ${inputValue.trim() && !submitting ? "active" : "disabled"}`,
696
- onClick: handleSubmit
697
- },
698
- /* @__PURE__ */ import_react8.default.createElement(import_components9.Text, { className: "btn-text" }, submitting ? "\u53D1\u9001\u4E2D..." : "\u53D1\u9001")
699
- ))))
700
- ));
738
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_components9.View, { className: "action-bar-expanded", children: [
739
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
740
+ import_components9.Textarea,
741
+ {
742
+ className: "comment-textarea",
743
+ value: inputValue,
744
+ onInput: (e) => setInputValue(e.detail.value),
745
+ placeholder,
746
+ maxlength: maxLength,
747
+ autoHeight: true,
748
+ focus: true,
749
+ disabled
750
+ }
751
+ ),
752
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_components9.View, { className: "expanded-actions", children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_components9.Text, { className: "char-count", children: [
754
+ inputValue.length,
755
+ "/",
756
+ maxLength
757
+ ] }),
758
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_components9.View, { className: "action-btns", children: [
759
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.View, { className: "cancel-btn", onClick: handleCollapse, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.Text, { className: "btn-text", children: "\u53D6\u6D88" }) }),
760
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
761
+ import_components9.View,
762
+ {
763
+ className: `send-btn ${inputValue.trim() && !submitting ? "active" : "disabled"}`,
764
+ onClick: handleSubmit,
765
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.Text, { className: "btn-text", children: submitting ? "\u53D1\u9001\u4E2D..." : "\u53D1\u9001" })
766
+ }
767
+ )
768
+ ] })
769
+ ] })
770
+ ] })
771
+ ) });
701
772
  }
702
773
 
703
774
  // src/hooks/useScrollOpacity.ts
704
- var import_react9 = require("react");
775
+ var import_react6 = require("react");
705
776
  function useScrollOpacity(threshold = 200) {
706
- const [scrollOpacity, setScrollOpacity] = (0, import_react9.useState)(1);
707
- const handleScroll = (0, import_react9.useCallback)((scrollTop) => {
777
+ const [scrollOpacity, setScrollOpacity] = (0, import_react6.useState)(1);
778
+ const handleScroll = (0, import_react6.useCallback)((scrollTop) => {
708
779
  const opacity = Math.max(1 - scrollTop / threshold, 0);
709
780
  setScrollOpacity(opacity);
710
781
  }, [threshold]);