@unif/react-native-design 0.19.0 → 0.20.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/lib/module/components/ui/Carousel/Carousel.js +29 -33
- package/lib/module/components/ui/Carousel/Carousel.js.map +1 -1
- package/lib/module/components/ui/Carousel/styles.js +4 -7
- package/lib/module/components/ui/Carousel/styles.js.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts +3 -3
- package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/index.d.ts +1 -1
- package/lib/typescript/src/components/ui/Carousel/index.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/styles.d.ts +3 -6
- package/lib/typescript/src/components/ui/Carousel/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/types.d.ts +14 -11
- package/lib/typescript/src/components/ui/Carousel/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/index.d.ts +1 -1
- package/lib/typescript/src/components/ui/index.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/components/ui/Carousel/Carousel.tsx +30 -38
- package/src/components/ui/Carousel/index.ts +1 -1
- package/src/components/ui/Carousel/styles.ts +4 -7
- package/src/components/ui/Carousel/types.ts +17 -11
- package/src/components/ui/index.ts +1 -1
|
@@ -2,30 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Pressable, useWindowDimensions, View } from 'react-native';
|
|
5
|
-
import ReanimatedCarousel,
|
|
5
|
+
import { Carousel as ReanimatedCarousel, Pagination } from 'react-native-reanimated-carousel';
|
|
6
6
|
import { useSharedValue } from 'react-native-reanimated';
|
|
7
7
|
import { space, useThemedStyles } from "../../../theme/index.js";
|
|
8
8
|
import { makeCarouselStyles } from "./styles.js";
|
|
9
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
-
/** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0
|
|
10
|
+
/** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0`。
|
|
11
11
|
*
|
|
12
|
-
* dot indicator 走 `c.primary` token,使用库内置 `Pagination
|
|
13
|
-
* (`useSharedValue` + `
|
|
12
|
+
* dot indicator 走 `c.primary` token,使用库内置 `Pagination`
|
|
13
|
+
* (`useSharedValue` + `progress` 驱动,视觉插值留在 UI 线程)。
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* 做不出"active 4 → 12 长条"。Custom 自己 interpolate width/height/bg。
|
|
18
|
-
*
|
|
19
|
-
* forwardRef 透传 ICarouselInstance —— 解锁 a11y 暂停(ref.current.scrollTo)
|
|
20
|
-
* 以及宿主页面的命令式 scrollTo / prev / next。
|
|
15
|
+
* forwardRef 透传 CarouselRef,供宿主命令式 scrollTo / prev / next
|
|
16
|
+
* 并读取最后一次完成落位的 index。
|
|
21
17
|
*/
|
|
22
|
-
// T 约束 object —— `Pagination.Basic<T extends {}>` 需要 object
|
|
23
18
|
function CarouselInner({
|
|
24
|
-
|
|
19
|
+
data,
|
|
25
20
|
renderItem,
|
|
21
|
+
keyExtractor,
|
|
26
22
|
height,
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
itemSize,
|
|
24
|
+
autoplay,
|
|
25
|
+
autoplayInterval,
|
|
29
26
|
loop = true,
|
|
30
27
|
showIndicator = true,
|
|
31
28
|
indicatorPosition = 'bottom',
|
|
@@ -37,16 +34,15 @@ function CarouselInner({
|
|
|
37
34
|
const {
|
|
38
35
|
width: screenWidth
|
|
39
36
|
} = useWindowDimensions();
|
|
40
|
-
const width =
|
|
37
|
+
const width = itemSize ?? screenWidth;
|
|
41
38
|
const styles = useThemedStyles(makeCarouselStyles);
|
|
42
|
-
// Carousel
|
|
39
|
+
// Carousel 把逻辑页进度写进 shared value,Pagination 自动跟随。
|
|
43
40
|
const progress = useSharedValue(0);
|
|
44
41
|
|
|
45
42
|
// 'bottom' 模式给容器额外 +space[7] (=r(16)) 高度容纳独立行指示器;
|
|
46
43
|
// 与 dotsWrapBottom 的 paddingTop=space[3]+dot height space[1] 一起跟 r() 同步缩放。
|
|
47
44
|
// 'overlay-bottom-right' 不占额外高度。
|
|
48
45
|
const indicatorReservedHeight = showIndicator && indicatorPosition === 'bottom' ? space['7'] : 0;
|
|
49
|
-
const data = items;
|
|
50
46
|
return /*#__PURE__*/_jsxs(View, {
|
|
51
47
|
style: [{
|
|
52
48
|
height: height + indicatorReservedHeight
|
|
@@ -59,15 +55,18 @@ function CarouselInner({
|
|
|
59
55
|
width,
|
|
60
56
|
height
|
|
61
57
|
},
|
|
58
|
+
itemSize: width,
|
|
62
59
|
data: data,
|
|
60
|
+
keyExtractor: keyExtractor,
|
|
63
61
|
loop: loop,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
autoplay: autoplay,
|
|
63
|
+
autoplayInterval: autoplayInterval,
|
|
64
|
+
progress: progress,
|
|
67
65
|
ref: ref,
|
|
68
66
|
renderItem: ({
|
|
69
67
|
item,
|
|
70
|
-
index
|
|
68
|
+
index,
|
|
69
|
+
relativeProgress
|
|
71
70
|
}) =>
|
|
72
71
|
/*#__PURE__*/
|
|
73
72
|
// RN Pressable 而非 RNGH Pressable:Carousel 的 GestureDetector 已挂在
|
|
@@ -93,24 +92,21 @@ function CarouselInner({
|
|
|
93
92
|
accessibilityRole: 'button',
|
|
94
93
|
accessibilityLabel: getAccessibilityLabel?.(item, index) ?? `第 ${index + 1} 项`
|
|
95
94
|
} : null),
|
|
96
|
-
children: renderItem(
|
|
95
|
+
children: renderItem({
|
|
96
|
+
item,
|
|
97
|
+
index,
|
|
98
|
+
relativeProgress
|
|
99
|
+
})
|
|
97
100
|
})
|
|
98
|
-
}), showIndicator &&
|
|
101
|
+
}), showIndicator && data.length > 1 ?
|
|
99
102
|
/*#__PURE__*/
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
// 的场景另论,这里 Pagination.Custom 无内置 a11y 语义,对 SR 隐藏比误读更优)。
|
|
103
|
-
_jsx(Pagination.Custom, {
|
|
103
|
+
// 未传 onPress 时,正式版 Pagination 会把 dots 作为纯视觉辅助从 a11y 树隐藏。
|
|
104
|
+
_jsx(Pagination, {
|
|
104
105
|
progress: progress,
|
|
105
|
-
|
|
106
|
+
count: data.length,
|
|
106
107
|
dotStyle: styles.dot,
|
|
107
108
|
activeDotStyle: styles.dotActive,
|
|
108
109
|
containerStyle: indicatorPosition === 'overlay-bottom-right' ? styles.dotsWrapOverlay : styles.dotsWrapBottom
|
|
109
|
-
// @ts-expect-error — importantForAccessibility 是 RN View prop,
|
|
110
|
-
// Pagination.Custom containerStyle 走 ViewStyle 但 TS 类型未收录该 prop
|
|
111
|
-
,
|
|
112
|
-
importantForAccessibility: "no-hide-descendants",
|
|
113
|
-
accessibilityElementsHidden: true
|
|
114
110
|
}) : null]
|
|
115
111
|
});
|
|
116
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Pressable","useWindowDimensions","View","ReanimatedCarousel","Pagination","useSharedValue","space","useThemedStyles","makeCarouselStyles","jsx","_jsx","jsxs","_jsxs","CarouselInner","
|
|
1
|
+
{"version":3,"names":["React","Pressable","useWindowDimensions","View","Carousel","ReanimatedCarousel","Pagination","useSharedValue","space","useThemedStyles","makeCarouselStyles","jsx","_jsx","jsxs","_jsxs","CarouselInner","data","renderItem","keyExtractor","height","itemSize","autoplay","autoplayInterval","loop","showIndicator","indicatorPosition","onPressItem","getAccessibilityLabel","style","testID","ref","width","screenWidth","styles","progress","indicatorReservedHeight","children","item","index","relativeProgress","onPress","accessibilityRole","accessibilityLabel","length","count","dotStyle","dot","activeDotStyle","dotActive","containerStyle","dotsWrapOverlay","dotsWrapBottom","forwardRef"],"sourceRoot":"../../../../../src","sources":["components/ui/Carousel/Carousel.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
import { StyleSheet } from 'react-native';
|
|
4
4
|
import { r, radius, space } from "../../../theme/index.js";
|
|
5
5
|
export const makeCarouselStyles = c => StyleSheet.create({
|
|
6
|
-
/** 'bottom'
|
|
7
|
-
* (否则 dot 横向撑开),让 dot 居中紧贴。 */
|
|
6
|
+
/** 'bottom' 模式:独立行容器,让 dot 居中紧贴。 */
|
|
8
7
|
dotsWrapBottom: {
|
|
9
|
-
flexDirection: 'row',
|
|
10
8
|
justifyContent: 'center',
|
|
11
9
|
alignItems: 'center',
|
|
12
|
-
//
|
|
10
|
+
// 正式版按 active 最大宽度为每个 dot 预留 12pt,额外保留 3pt 间距。
|
|
13
11
|
gap: r(3),
|
|
14
12
|
paddingTop: space['3']
|
|
15
13
|
},
|
|
@@ -19,7 +17,6 @@ export const makeCarouselStyles = c => StyleSheet.create({
|
|
|
19
17
|
position: 'absolute',
|
|
20
18
|
bottom: space['3'],
|
|
21
19
|
right: space['5'],
|
|
22
|
-
flexDirection: 'row',
|
|
23
20
|
justifyContent: 'flex-end',
|
|
24
21
|
alignItems: 'center',
|
|
25
22
|
gap: r(3)
|
|
@@ -32,10 +29,10 @@ export const makeCarouselStyles = c => StyleSheet.create({
|
|
|
32
29
|
backgroundColor: c.primary,
|
|
33
30
|
opacity: 0.32
|
|
34
31
|
},
|
|
35
|
-
/** activeDot —— 12×4
|
|
36
|
-
* borderRadius 与 activeDotStyle 的 width 一起 interpolate,这里只 override 变化值。 */
|
|
32
|
+
/** activeDot —— 12×4 长条,正式版 Pagination 为每项预留 12pt 宽避免布局跳动。 */
|
|
37
33
|
dotActive: {
|
|
38
34
|
width: space['5'],
|
|
35
|
+
backgroundColor: c.primary,
|
|
39
36
|
opacity: 1
|
|
40
37
|
}
|
|
41
38
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["StyleSheet","r","radius","space","makeCarouselStyles","c","create","dotsWrapBottom","
|
|
1
|
+
{"version":3,"names":["StyleSheet","r","radius","space","makeCarouselStyles","c","create","dotsWrapBottom","justifyContent","alignItems","gap","paddingTop","dotsWrapOverlay","position","bottom","right","dot","width","height","borderRadius","pill","backgroundColor","primary","opacity","dotActive"],"sourceRoot":"../../../../../src","sources":["components/ui/Carousel/styles.ts"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,CAAC,EAAEC,MAAM,EAAEC,KAAK,QAA0B,yBAAgB;AAEnE,OAAO,MAAMC,kBAAkB,GAAIC,CAAc,IAC/CL,UAAU,CAACM,MAAM,CAAC;EAChB;EACAC,cAAc,EAAE;IACdC,cAAc,EAAE,QAAQ;IACxBC,UAAU,EAAE,QAAQ;IACpB;IACAC,GAAG,EAAET,CAAC,CAAC,CAAC,CAAC;IACTU,UAAU,EAAER,KAAK,CAAC,GAAG;EACvB,CAAC;EACD;AACJ;EACIS,eAAe,EAAE;IACfC,QAAQ,EAAE,UAAU;IACpBC,MAAM,EAAEX,KAAK,CAAC,GAAG,CAAC;IAClBY,KAAK,EAAEZ,KAAK,CAAC,GAAG,CAAC;IACjBK,cAAc,EAAE,UAAU;IAC1BC,UAAU,EAAE,QAAQ;IACpBC,GAAG,EAAET,CAAC,CAAC,CAAC;EACV,CAAC;EACDe,GAAG,EAAE;IACHC,KAAK,EAAEd,KAAK,CAAC,GAAG,CAAC;IACjBe,MAAM,EAAEf,KAAK,CAAC,GAAG,CAAC;IAClB;IACAgB,YAAY,EAAEjB,MAAM,CAACkB,IAAI;IACzBC,eAAe,EAAEhB,CAAC,CAACiB,OAAO;IAC1BC,OAAO,EAAE;EACX,CAAC;EACD;EACAC,SAAS,EAAE;IACTP,KAAK,EAAEd,KAAK,CAAC,GAAG,CAAC;IACjBkB,eAAe,EAAEhB,CAAC,CAACiB,OAAO;IAC1BC,OAAO,EAAE;EACX;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { CarouselProps,
|
|
3
|
-
export declare const Carousel: <T
|
|
4
|
-
ref?: React.Ref<
|
|
2
|
+
import type { CarouselProps, CarouselRef } from './types';
|
|
3
|
+
export declare const Carousel: <T>(props: CarouselProps<T> & {
|
|
4
|
+
ref?: React.Ref<CarouselRef>;
|
|
5
5
|
}) => React.JSX.Element;
|
|
6
6
|
//# sourceMappingURL=Carousel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/Carousel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/Carousel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAwG1D,eAAO,MAAM,QAAQ,EAAsC,CAAC,CAAC,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;CAAE,KACvD,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { type ColorTokens } from '../../../theme';
|
|
2
2
|
export declare const makeCarouselStyles: (c: ColorTokens) => Readonly<{
|
|
3
|
-
/** 'bottom'
|
|
4
|
-
* (否则 dot 横向撑开),让 dot 居中紧贴。 */
|
|
3
|
+
/** 'bottom' 模式:独立行容器,让 dot 居中紧贴。 */
|
|
5
4
|
dotsWrapBottom: {
|
|
6
|
-
flexDirection: "row";
|
|
7
5
|
justifyContent: "center";
|
|
8
6
|
alignItems: "center";
|
|
9
7
|
gap: number;
|
|
@@ -15,7 +13,6 @@ export declare const makeCarouselStyles: (c: ColorTokens) => Readonly<{
|
|
|
15
13
|
position: "absolute";
|
|
16
14
|
bottom: number;
|
|
17
15
|
right: number;
|
|
18
|
-
flexDirection: "row";
|
|
19
16
|
justifyContent: "flex-end";
|
|
20
17
|
alignItems: "center";
|
|
21
18
|
gap: number;
|
|
@@ -27,10 +24,10 @@ export declare const makeCarouselStyles: (c: ColorTokens) => Readonly<{
|
|
|
27
24
|
backgroundColor: string;
|
|
28
25
|
opacity: number;
|
|
29
26
|
};
|
|
30
|
-
/** activeDot —— 12×4
|
|
31
|
-
* borderRadius 与 activeDotStyle 的 width 一起 interpolate,这里只 override 变化值。 */
|
|
27
|
+
/** activeDot —— 12×4 长条,正式版 Pagination 为每项预留 12pt 宽避免布局跳动。 */
|
|
32
28
|
dotActive: {
|
|
33
29
|
width: number;
|
|
30
|
+
backgroundColor: string;
|
|
34
31
|
opacity: number;
|
|
35
32
|
};
|
|
36
33
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,kBAAkB,GAAI,GAAG,WAAW;IAE7C;
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,kBAAkB,GAAI,GAAG,WAAW;IAE7C,oCAAoC;;;;;;;IAQpC;4DACwD;;;;;;;;;;;;;;;;IAiBxD,8DAA8D;;;;;;EAM9D,CAAC"}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
1
|
+
import type { CarouselRef, CarouselRenderItem } from 'react-native-reanimated-carousel';
|
|
3
2
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
4
|
-
export type {
|
|
3
|
+
export type { CarouselRef };
|
|
5
4
|
/** Indicator 位置策略:
|
|
6
5
|
* - 'bottom'(默认):指示器独立行,跟 Carousel 下方;容器高度 = height + 16
|
|
7
6
|
* - 'overlay-bottom-right':指示器 absolute 浮在 Carousel 右下角,不占额外高度 */
|
|
8
7
|
export type CarouselIndicatorPosition = 'bottom' | 'overlay-bottom-right';
|
|
9
8
|
export type CarouselProps<T> = {
|
|
10
9
|
/** 数组数据 */
|
|
11
|
-
|
|
10
|
+
data: T[];
|
|
12
11
|
/** 单项渲染 */
|
|
13
|
-
renderItem:
|
|
14
|
-
/**
|
|
12
|
+
renderItem: CarouselRenderItem<T>;
|
|
13
|
+
/** 稳定 key 解析器,数据更新时用于保持 item 身份。 */
|
|
14
|
+
keyExtractor?: (item: T, index: number) => string;
|
|
15
|
+
/** 每张高度(宽度默认 = 屏宽,被 itemSize 覆盖) */
|
|
15
16
|
height: number;
|
|
16
|
-
/**
|
|
17
|
+
/** 每张宽度与水平翻页步长,默认 useWindowDimensions().width。
|
|
17
18
|
* 若 caller 外层有 marginHorizontal(如 Dashboard banner inset 16),需要传
|
|
18
19
|
* `屏宽 - 左右 margin*2`,否则 slide 宽度超过可视区,右侧内容被裁切。 */
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
/**
|
|
20
|
+
itemSize?: number;
|
|
21
|
+
/** 是否自动播放,默认 false。 */
|
|
22
|
+
autoplay?: boolean;
|
|
23
|
+
/** 自动播放间隔 ms,默认 3000。 */
|
|
24
|
+
autoplayInterval?: number;
|
|
25
|
+
/** 是否循环播放,默认 true。传 false 时到首尾停止。 */
|
|
23
26
|
loop?: boolean;
|
|
24
27
|
/** 是否显示底部 dot indicator,默认 true */
|
|
25
28
|
showIndicator?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Carousel/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EACnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B;;mEAEmE;AACnE,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,sBAAsB,CAAC;AAE1E,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,WAAW;IACX,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,WAAW;IACX,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAClC,oCAAoC;IACpC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf;;uDAEmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mCAAmC;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,yBAAyB,CAAC;IAC9C,WAAW;IACX,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C;sEACkE;IAClE,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,mBAAmB;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
|
|
@@ -7,7 +7,7 @@ export type { ButtonProps, ButtonSize, ButtonVariant } from './Button';
|
|
|
7
7
|
export { Card } from './Card';
|
|
8
8
|
export type { CardProps, CardVariant } from './Card';
|
|
9
9
|
export { Carousel } from './Carousel';
|
|
10
|
-
export type { CarouselProps } from './Carousel';
|
|
10
|
+
export type { CarouselProps, CarouselRef } from './Carousel';
|
|
11
11
|
export { Cell, List } from './Cell';
|
|
12
12
|
export type { CellProps, ListProps } from './Cell';
|
|
13
13
|
export { Checkbox } from './Checkbox';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,IAAI,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EACV,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unif/react-native-design",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Unif 设计系统:theme + icons + utils + components",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -88,9 +88,9 @@
|
|
|
88
88
|
"react": "19.2.3",
|
|
89
89
|
"react-native": "0.85.3",
|
|
90
90
|
"react-native-builder-bob": "^0.41.0",
|
|
91
|
-
"react-native-gesture-handler": "^3.
|
|
91
|
+
"react-native-gesture-handler": "^3.1.0",
|
|
92
92
|
"react-native-reanimated": "^4.4.0",
|
|
93
|
-
"react-native-reanimated-carousel": "^5.0.0
|
|
93
|
+
"react-native-reanimated-carousel": "^5.0.0",
|
|
94
94
|
"react-native-safe-area-context": "^5.7.0",
|
|
95
95
|
"react-native-svg": "^15.15.5",
|
|
96
96
|
"react-native-worklets": "0.9.1",
|
|
@@ -102,9 +102,9 @@
|
|
|
102
102
|
"@sbaiahmed1/react-native-blur": ">=4",
|
|
103
103
|
"react": "*",
|
|
104
104
|
"react-native": "*",
|
|
105
|
-
"react-native-gesture-handler": ">=
|
|
106
|
-
"react-native-reanimated": ">=4",
|
|
107
|
-
"react-native-reanimated-carousel": ">=5.0.0
|
|
105
|
+
"react-native-gesture-handler": ">=3.0.0 <4.0.0",
|
|
106
|
+
"react-native-reanimated": ">=4.1.0",
|
|
107
|
+
"react-native-reanimated-carousel": ">=5.0.0 <6.0.0",
|
|
108
108
|
"react-native-safe-area-context": ">=5",
|
|
109
109
|
"react-native-svg": ">=15",
|
|
110
110
|
"react-native-worklets": ">=0.9"
|
|
@@ -1,33 +1,31 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Pressable, useWindowDimensions, View } from 'react-native';
|
|
3
|
-
import
|
|
3
|
+
import {
|
|
4
|
+
Carousel as ReanimatedCarousel,
|
|
4
5
|
Pagination,
|
|
5
6
|
} from 'react-native-reanimated-carousel';
|
|
6
7
|
import { useSharedValue } from 'react-native-reanimated';
|
|
7
8
|
import { space, useThemedStyles } from '../../../theme';
|
|
8
9
|
import { makeCarouselStyles } from './styles';
|
|
9
|
-
import type { CarouselProps,
|
|
10
|
+
import type { CarouselProps, CarouselRef } from './types';
|
|
10
11
|
|
|
11
|
-
/** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0
|
|
12
|
+
/** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0`。
|
|
12
13
|
*
|
|
13
|
-
* dot indicator 走 `c.primary` token,使用库内置 `Pagination
|
|
14
|
-
* (`useSharedValue` + `
|
|
14
|
+
* dot indicator 走 `c.primary` token,使用库内置 `Pagination`
|
|
15
|
+
* (`useSharedValue` + `progress` 驱动,视觉插值留在 UI 线程)。
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* 做不出"active 4 → 12 长条"。Custom 自己 interpolate width/height/bg。
|
|
19
|
-
*
|
|
20
|
-
* forwardRef 透传 ICarouselInstance —— 解锁 a11y 暂停(ref.current.scrollTo)
|
|
21
|
-
* 以及宿主页面的命令式 scrollTo / prev / next。
|
|
17
|
+
* forwardRef 透传 CarouselRef,供宿主命令式 scrollTo / prev / next
|
|
18
|
+
* 并读取最后一次完成落位的 index。
|
|
22
19
|
*/
|
|
23
|
-
|
|
24
|
-
function CarouselInner<T extends object>(
|
|
20
|
+
function CarouselInner<T>(
|
|
25
21
|
{
|
|
26
|
-
|
|
22
|
+
data,
|
|
27
23
|
renderItem,
|
|
24
|
+
keyExtractor,
|
|
28
25
|
height,
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
itemSize,
|
|
27
|
+
autoplay,
|
|
28
|
+
autoplayInterval,
|
|
31
29
|
loop = true,
|
|
32
30
|
showIndicator = true,
|
|
33
31
|
indicatorPosition = 'bottom',
|
|
@@ -36,12 +34,12 @@ function CarouselInner<T extends object>(
|
|
|
36
34
|
style,
|
|
37
35
|
testID,
|
|
38
36
|
}: CarouselProps<T>,
|
|
39
|
-
ref: React.Ref<
|
|
37
|
+
ref: React.Ref<CarouselRef>
|
|
40
38
|
): React.JSX.Element {
|
|
41
39
|
const { width: screenWidth } = useWindowDimensions();
|
|
42
|
-
const width =
|
|
40
|
+
const width = itemSize ?? screenWidth;
|
|
43
41
|
const styles = useThemedStyles(makeCarouselStyles);
|
|
44
|
-
// Carousel
|
|
42
|
+
// Carousel 把逻辑页进度写进 shared value,Pagination 自动跟随。
|
|
45
43
|
const progress = useSharedValue<number>(0);
|
|
46
44
|
|
|
47
45
|
// 'bottom' 模式给容器额外 +space[7] (=r(16)) 高度容纳独立行指示器;
|
|
@@ -50,8 +48,6 @@ function CarouselInner<T extends object>(
|
|
|
50
48
|
const indicatorReservedHeight =
|
|
51
49
|
showIndicator && indicatorPosition === 'bottom' ? space['7'] : 0;
|
|
52
50
|
|
|
53
|
-
const data = items as T[];
|
|
54
|
-
|
|
55
51
|
return (
|
|
56
52
|
<View
|
|
57
53
|
style={[{ height: height + indicatorReservedHeight }, style]}
|
|
@@ -60,13 +56,15 @@ function CarouselInner<T extends object>(
|
|
|
60
56
|
<ReanimatedCarousel
|
|
61
57
|
// v5 把 width / height prop deprecate,迁到 style
|
|
62
58
|
style={{ width, height }}
|
|
59
|
+
itemSize={width}
|
|
63
60
|
data={data}
|
|
61
|
+
keyExtractor={keyExtractor}
|
|
64
62
|
loop={loop}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
autoplay={autoplay}
|
|
64
|
+
autoplayInterval={autoplayInterval}
|
|
65
|
+
progress={progress}
|
|
68
66
|
ref={ref}
|
|
69
|
-
renderItem={({ item, index }) => (
|
|
67
|
+
renderItem={({ item, index, relativeProgress }) => (
|
|
70
68
|
// RN Pressable 而非 RNGH Pressable:Carousel 的 GestureDetector 已挂在
|
|
71
69
|
// ReanimatedCarousel 内部,外层再套 RNGH Pressable 会产生手势冲突;
|
|
72
70
|
// 用 RN 原生 Pressable 让库自己的拖拽手势优先,tap 仍正常触发。
|
|
@@ -90,17 +88,15 @@ function CarouselInner<T extends object>(
|
|
|
90
88
|
}
|
|
91
89
|
: null)}
|
|
92
90
|
>
|
|
93
|
-
{renderItem(item, index)}
|
|
91
|
+
{renderItem({ item, index, relativeProgress })}
|
|
94
92
|
</Pressable>
|
|
95
93
|
)}
|
|
96
94
|
/>
|
|
97
|
-
{showIndicator &&
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
// 的场景另论,这里 Pagination.Custom 无内置 a11y 语义,对 SR 隐藏比误读更优)。
|
|
101
|
-
<Pagination.Custom<T>
|
|
95
|
+
{showIndicator && data.length > 1 ? (
|
|
96
|
+
// 未传 onPress 时,正式版 Pagination 会把 dots 作为纯视觉辅助从 a11y 树隐藏。
|
|
97
|
+
<Pagination
|
|
102
98
|
progress={progress}
|
|
103
|
-
|
|
99
|
+
count={data.length}
|
|
104
100
|
dotStyle={styles.dot}
|
|
105
101
|
activeDotStyle={styles.dotActive}
|
|
106
102
|
containerStyle={
|
|
@@ -108,10 +104,6 @@ function CarouselInner<T extends object>(
|
|
|
108
104
|
? styles.dotsWrapOverlay
|
|
109
105
|
: styles.dotsWrapBottom
|
|
110
106
|
}
|
|
111
|
-
// @ts-expect-error — importantForAccessibility 是 RN View prop,
|
|
112
|
-
// Pagination.Custom containerStyle 走 ViewStyle 但 TS 类型未收录该 prop
|
|
113
|
-
importantForAccessibility="no-hide-descendants"
|
|
114
|
-
accessibilityElementsHidden={true}
|
|
115
107
|
/>
|
|
116
108
|
) : null}
|
|
117
109
|
</View>
|
|
@@ -119,6 +111,6 @@ function CarouselInner<T extends object>(
|
|
|
119
111
|
}
|
|
120
112
|
|
|
121
113
|
// forwardRef 不支持泛型函数组件直接推断 T,需要手动标注 + 类型断言
|
|
122
|
-
export const Carousel = React.forwardRef(CarouselInner) as <T
|
|
123
|
-
props: CarouselProps<T> & { ref?: React.Ref<
|
|
114
|
+
export const Carousel = React.forwardRef(CarouselInner) as <T>(
|
|
115
|
+
props: CarouselProps<T> & { ref?: React.Ref<CarouselRef> }
|
|
124
116
|
) => React.JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Carousel } from './Carousel';
|
|
2
|
-
export type { CarouselProps,
|
|
2
|
+
export type { CarouselProps, CarouselRef } from './types';
|
|
@@ -3,13 +3,11 @@ import { r, radius, space, type ColorTokens } from '../../../theme';
|
|
|
3
3
|
|
|
4
4
|
export const makeCarouselStyles = (c: ColorTokens) =>
|
|
5
5
|
StyleSheet.create({
|
|
6
|
-
/** 'bottom'
|
|
7
|
-
* (否则 dot 横向撑开),让 dot 居中紧贴。 */
|
|
6
|
+
/** 'bottom' 模式:独立行容器,让 dot 居中紧贴。 */
|
|
8
7
|
dotsWrapBottom: {
|
|
9
|
-
flexDirection: 'row',
|
|
10
8
|
justifyContent: 'center',
|
|
11
9
|
alignItems: 'center',
|
|
12
|
-
//
|
|
10
|
+
// 正式版按 active 最大宽度为每个 dot 预留 12pt,额外保留 3pt 间距。
|
|
13
11
|
gap: r(3),
|
|
14
12
|
paddingTop: space['3'],
|
|
15
13
|
},
|
|
@@ -19,7 +17,6 @@ export const makeCarouselStyles = (c: ColorTokens) =>
|
|
|
19
17
|
position: 'absolute',
|
|
20
18
|
bottom: space['3'],
|
|
21
19
|
right: space['5'],
|
|
22
|
-
flexDirection: 'row',
|
|
23
20
|
justifyContent: 'flex-end',
|
|
24
21
|
alignItems: 'center',
|
|
25
22
|
gap: r(3),
|
|
@@ -32,10 +29,10 @@ export const makeCarouselStyles = (c: ColorTokens) =>
|
|
|
32
29
|
backgroundColor: c.primary,
|
|
33
30
|
opacity: 0.32,
|
|
34
31
|
},
|
|
35
|
-
/** activeDot —— 12×4
|
|
36
|
-
* borderRadius 与 activeDotStyle 的 width 一起 interpolate,这里只 override 变化值。 */
|
|
32
|
+
/** activeDot —— 12×4 长条,正式版 Pagination 为每项预留 12pt 宽避免布局跳动。 */
|
|
37
33
|
dotActive: {
|
|
38
34
|
width: space['5'],
|
|
35
|
+
backgroundColor: c.primary,
|
|
39
36
|
opacity: 1,
|
|
40
37
|
},
|
|
41
38
|
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
CarouselRef,
|
|
3
|
+
CarouselRenderItem,
|
|
4
|
+
} from 'react-native-reanimated-carousel';
|
|
3
5
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
4
6
|
|
|
5
|
-
export type {
|
|
7
|
+
export type { CarouselRef };
|
|
6
8
|
|
|
7
9
|
/** Indicator 位置策略:
|
|
8
10
|
* - 'bottom'(默认):指示器独立行,跟 Carousel 下方;容器高度 = height + 16
|
|
@@ -11,18 +13,22 @@ export type CarouselIndicatorPosition = 'bottom' | 'overlay-bottom-right';
|
|
|
11
13
|
|
|
12
14
|
export type CarouselProps<T> = {
|
|
13
15
|
/** 数组数据 */
|
|
14
|
-
|
|
16
|
+
data: T[];
|
|
15
17
|
/** 单项渲染 */
|
|
16
|
-
renderItem:
|
|
17
|
-
/**
|
|
18
|
+
renderItem: CarouselRenderItem<T>;
|
|
19
|
+
/** 稳定 key 解析器,数据更新时用于保持 item 身份。 */
|
|
20
|
+
keyExtractor?: (item: T, index: number) => string;
|
|
21
|
+
/** 每张高度(宽度默认 = 屏宽,被 itemSize 覆盖) */
|
|
18
22
|
height: number;
|
|
19
|
-
/**
|
|
23
|
+
/** 每张宽度与水平翻页步长,默认 useWindowDimensions().width。
|
|
20
24
|
* 若 caller 外层有 marginHorizontal(如 Dashboard banner inset 16),需要传
|
|
21
25
|
* `屏宽 - 左右 margin*2`,否则 slide 宽度超过可视区,右侧内容被裁切。 */
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
+
itemSize?: number;
|
|
27
|
+
/** 是否自动播放,默认 false。 */
|
|
28
|
+
autoplay?: boolean;
|
|
29
|
+
/** 自动播放间隔 ms,默认 3000。 */
|
|
30
|
+
autoplayInterval?: number;
|
|
31
|
+
/** 是否循环播放,默认 true。传 false 时到首尾停止。 */
|
|
26
32
|
loop?: boolean;
|
|
27
33
|
/** 是否显示底部 dot indicator,默认 true */
|
|
28
34
|
showIndicator?: boolean;
|
|
@@ -7,7 +7,7 @@ export type { ButtonProps, ButtonSize, ButtonVariant } from './Button';
|
|
|
7
7
|
export { Card } from './Card';
|
|
8
8
|
export type { CardProps, CardVariant } from './Card';
|
|
9
9
|
export { Carousel } from './Carousel';
|
|
10
|
-
export type { CarouselProps } from './Carousel';
|
|
10
|
+
export type { CarouselProps, CarouselRef } from './Carousel';
|
|
11
11
|
export { Cell, List } from './Cell';
|
|
12
12
|
export type { CellProps, ListProps } from './Cell';
|
|
13
13
|
export { Checkbox } from './Checkbox';
|