@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.d.mts +246 -0
- package/dist/index.d.ts +246 -0
- package/dist/index.js +253 -182
- package/dist/index.mjs +239 -169
- package/package.json +7 -8
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 =
|
|
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 ||
|
|
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
|
|
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__ */
|
|
81
|
-
import_components.View,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
123
|
+
onClick?.();
|
|
120
124
|
});
|
|
121
|
-
return /* @__PURE__ */
|
|
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
|
-
|
|
129
|
-
|
|
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
|
|
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
|
|
176
|
+
await onLoadMore?.();
|
|
171
177
|
});
|
|
172
178
|
const renderEmptyContent = () => {
|
|
173
179
|
if (renderEmpty) {
|
|
174
180
|
return renderEmpty();
|
|
175
181
|
}
|
|
176
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
281
|
-
return ((_a = this.info) == null ? void 0 : _a.statusBarHeight) || 44;
|
|
293
|
+
return this.info?.statusBarHeight || 44;
|
|
282
294
|
}
|
|
283
295
|
getNavBarHeight() {
|
|
284
|
-
|
|
285
|
-
return ((_a = this.info) == null ? void 0 : _a.navBarHeight) || 88;
|
|
296
|
+
return this.info?.navBarHeight || 88;
|
|
286
297
|
}
|
|
287
298
|
getSafeAreaInsets() {
|
|
288
|
-
|
|
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
|
|
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,
|
|
299
|
-
(0,
|
|
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__ */
|
|
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,
|
|
332
|
-
const [statusBarHeight, setStatusBarHeight] = (0,
|
|
333
|
-
const [menuButtonLeft, setMenuButtonLeft] = (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,
|
|
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__ */
|
|
405
|
-
|
|
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-
|
|
429
|
-
style: {
|
|
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
|
-
)
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
521
|
+
onChange?.(newImages);
|
|
498
522
|
}
|
|
499
523
|
}
|
|
500
524
|
});
|
|
501
525
|
};
|
|
502
|
-
return /* @__PURE__ */
|
|
503
|
-
import_components6.
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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__ */
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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__ */
|
|
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
|
-
|
|
571
|
-
|
|
572
|
-
)));
|
|
621
|
+
item.key
|
|
622
|
+
)) });
|
|
573
623
|
}
|
|
574
624
|
var Tabs_default = Tabs;
|
|
575
625
|
|
|
576
626
|
// src/components/ContentActionBar/index.tsx
|
|
577
|
-
var
|
|
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,
|
|
603
|
-
const [inputValue, setInputValue] = (0,
|
|
604
|
-
const [submitting, setSubmitting] = (0,
|
|
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
|
|
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
|
|
679
|
+
onLike?.();
|
|
629
680
|
};
|
|
630
681
|
const handleFavorite = (e) => {
|
|
631
682
|
e.stopPropagation();
|
|
632
683
|
if (disabled) return;
|
|
633
|
-
onFavorite
|
|
684
|
+
onFavorite?.();
|
|
634
685
|
};
|
|
635
686
|
const handleShare = (e) => {
|
|
636
687
|
e.stopPropagation();
|
|
637
688
|
if (disabled) return;
|
|
638
|
-
onShare
|
|
689
|
+
onShare?.();
|
|
639
690
|
};
|
|
640
|
-
return /* @__PURE__ */
|
|
691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components9.View, { className: "content-action-bar", children: !isExpanded ? (
|
|
641
692
|
// 收起状态:输入框占位 + 操作按钮
|
|
642
|
-
/* @__PURE__ */
|
|
643
|
-
import_components9.View,
|
|
644
|
-
{
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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__ */
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
{
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
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
|
|
775
|
+
var import_react6 = require("react");
|
|
705
776
|
function useScrollOpacity(threshold = 200) {
|
|
706
|
-
const [scrollOpacity, setScrollOpacity] = (0,
|
|
707
|
-
const handleScroll = (0,
|
|
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]);
|