@unif/react-native-design 0.18.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.
Files changed (28) hide show
  1. package/lib/module/components/ui/Carousel/Carousel.js +29 -33
  2. package/lib/module/components/ui/Carousel/Carousel.js.map +1 -1
  3. package/lib/module/components/ui/Carousel/styles.js +4 -7
  4. package/lib/module/components/ui/Carousel/styles.js.map +1 -1
  5. package/lib/module/components/ui/Chip/Chip.js +26 -6
  6. package/lib/module/components/ui/Chip/Chip.js.map +1 -1
  7. package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts +3 -3
  8. package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts.map +1 -1
  9. package/lib/typescript/src/components/ui/Carousel/index.d.ts +1 -1
  10. package/lib/typescript/src/components/ui/Carousel/index.d.ts.map +1 -1
  11. package/lib/typescript/src/components/ui/Carousel/styles.d.ts +3 -6
  12. package/lib/typescript/src/components/ui/Carousel/styles.d.ts.map +1 -1
  13. package/lib/typescript/src/components/ui/Carousel/types.d.ts +14 -11
  14. package/lib/typescript/src/components/ui/Carousel/types.d.ts.map +1 -1
  15. package/lib/typescript/src/components/ui/Chip/Chip.d.ts +2 -1
  16. package/lib/typescript/src/components/ui/Chip/Chip.d.ts.map +1 -1
  17. package/lib/typescript/src/components/ui/Chip/types.d.ts +4 -0
  18. package/lib/typescript/src/components/ui/Chip/types.d.ts.map +1 -1
  19. package/lib/typescript/src/components/ui/index.d.ts +1 -1
  20. package/lib/typescript/src/components/ui/index.d.ts.map +1 -1
  21. package/package.json +6 -6
  22. package/src/components/ui/Carousel/Carousel.tsx +30 -38
  23. package/src/components/ui/Carousel/index.ts +1 -1
  24. package/src/components/ui/Carousel/styles.ts +4 -7
  25. package/src/components/ui/Carousel/types.ts +17 -11
  26. package/src/components/ui/Chip/Chip.tsx +45 -5
  27. package/src/components/ui/Chip/types.ts +4 -0
  28. 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, { Pagination } from 'react-native-reanimated-carousel';
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-beta.5`。
10
+ /** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0`。
11
11
  *
12
- * dot indicator 走 `c.primary` token,使用库内置 `Pagination.Custom`
13
- * (`useSharedValue` + `onProgressChange` 驱动,re-render 全在 worklet 里)。
12
+ * dot indicator 走 `c.primary` token,使用库内置 `Pagination`
13
+ * (`useSharedValue` + `progress` 驱动,视觉插值留在 UI 线程)。
14
14
  *
15
- * Pagination.Custom 而非 Basic:Basic activeDot translateX 推进
16
- * 内层 fill,外壳宽度等于 dotStyle.width,activeDotStyle.width 只影响内层,
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
- items,
19
+ data,
25
20
  renderItem,
21
+ keyExtractor,
26
22
  height,
27
- itemWidth,
28
- autoPlay,
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 = itemWidth ?? screenWidth;
37
+ const width = itemSize ?? screenWidth;
41
38
  const styles = useThemedStyles(makeCarouselStyles);
42
- // Carousel `onProgressChange` 把 absoluteProgress 写进 shared value,Pagination 自动跟。
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
- autoPlay: !!autoPlay,
65
- autoPlayInterval: autoPlay,
66
- onProgressChange: progress,
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(item, index)
95
+ children: renderItem({
96
+ item,
97
+ index,
98
+ relativeProgress
99
+ })
97
100
  })
98
- }), showIndicator && items.length > 1 ?
101
+ }), showIndicator && data.length > 1 ?
99
102
  /*#__PURE__*/
100
- // importantForAccessibility="no" —— dots 仅视觉辅助,SR 不需要读出
101
- // 每个 dot 的状态(已由 accessibilityRole=tab / accessibilityState.selected 表达
102
- // 的场景另论,这里 Pagination.Custom 无内置 a11y 语义,对 SR 隐藏比误读更优)。
103
- _jsx(Pagination.Custom, {
103
+ // 未传 onPress 时,正式版 Pagination 会把 dots 作为纯视觉辅助从 a11y 树隐藏。
104
+ _jsx(Pagination, {
104
105
  progress: progress,
105
- data: data,
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","items","renderItem","height","itemWidth","autoPlay","loop","showIndicator","indicatorPosition","onPressItem","getAccessibilityLabel","style","testID","ref","width","screenWidth","styles","progress","indicatorReservedHeight","data","children","autoPlayInterval","onProgressChange","item","index","onPress","accessibilityRole","accessibilityLabel","length","Custom","dotStyle","dot","activeDotStyle","dotActive","containerStyle","dotsWrapOverlay","dotsWrapBottom","importantForAccessibility","accessibilityElementsHidden","Carousel","forwardRef"],"sourceRoot":"../../../../../src","sources":["components/ui/Carousel/Carousel.tsx"],"mappings":"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","ignoreList":[]}
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' 模式:独立行容器,覆盖 Pagination.Custom 默认的 `justifyContent: 'space-between'`
7
- * (否则 dot 横向撑开),让 dot 居中紧贴。 */
6
+ /** 'bottom' 模式:独立行容器,让 dot 居中紧贴。 */
8
7
  dotsWrapBottom: {
9
- flexDirection: 'row',
10
8
  justifyContent: 'center',
11
9
  alignItems: 'center',
12
- // 3pt 横间距:dot 单元 4pt + space[1]=r(4) 偏大,保留 r(3) 作为局部 dot 间隙
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 长条,Pagination.Custom 会把 dotStyle height /
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","flexDirection","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;AACJ;EACIC,cAAc,EAAE;IACdC,aAAa,EAAE,KAAK;IACpBC,cAAc,EAAE,QAAQ;IACxBC,UAAU,EAAE,QAAQ;IACpB;IACAC,GAAG,EAAEV,CAAC,CAAC,CAAC,CAAC;IACTW,UAAU,EAAET,KAAK,CAAC,GAAG;EACvB,CAAC;EACD;AACJ;EACIU,eAAe,EAAE;IACfC,QAAQ,EAAE,UAAU;IACpBC,MAAM,EAAEZ,KAAK,CAAC,GAAG,CAAC;IAClBa,KAAK,EAAEb,KAAK,CAAC,GAAG,CAAC;IACjBK,aAAa,EAAE,KAAK;IACpBC,cAAc,EAAE,UAAU;IAC1BC,UAAU,EAAE,QAAQ;IACpBC,GAAG,EAAEV,CAAC,CAAC,CAAC;EACV,CAAC;EACDgB,GAAG,EAAE;IACHC,KAAK,EAAEf,KAAK,CAAC,GAAG,CAAC;IACjBgB,MAAM,EAAEhB,KAAK,CAAC,GAAG,CAAC;IAClB;IACAiB,YAAY,EAAElB,MAAM,CAACmB,IAAI;IACzBC,eAAe,EAAEjB,CAAC,CAACkB,OAAO;IAC1BC,OAAO,EAAE;EACX,CAAC;EACD;AACJ;EACIC,SAAS,EAAE;IACTP,KAAK,EAAEf,KAAK,CAAC,GAAG,CAAC;IACjBqB,OAAO,EAAE;EACX;AACF,CAAC,CAAC","ignoreList":[]}
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":[]}
@@ -3,15 +3,23 @@
3
3
  import React from 'react';
4
4
  import { Text, View } from 'react-native';
5
5
  import { Pressable } from 'react-native-gesture-handler';
6
- import { fixed, pressedOpacity, r, rf, useThemedStyles } from "../../../theme/index.js";
6
+ import { fixed, pressedOpacity, r, rf, useColors, useThemedStyles } from "../../../theme/index.js";
7
+ import { Spinner } from "../Spinner/index.js";
7
8
  import { makeStyles } from "./styles.js";
8
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ /** 处理中 chip 的透明度 —— 比 disabled(0.5)亮、比按下(pressedOpacity)暗:
11
+ * 「正在办」既要压下去,又不能和「不能点」长一样(那两者只靠 spinner 区分就太弱了)。 */
12
+ const busyOpacity = 0.6;
13
+ /** busy spinner 直径 —— 与调用方常用的 leading icon(12)等大,顶替时不改 chip 宽度。 */
14
+ const busySpinner = r(12);
15
+
9
16
  /**
10
17
  * 胶囊形可点击 chip。
11
18
  * - 默认:surface 底 + outline 细线边框,foreground 文本
12
19
  * - 选中:主色边框 + 主色文本
13
20
  * - 按下:透明度 pressedOpacity(与 ButtonBase 同源)
14
21
  * - 禁用:透明度 0.5 + 不响应 onPress
22
+ * - 处理中(`busy`):leading 换 spinner + 透明度 0.6 + 不响应二次点击
15
23
  *
16
24
  * 常用于建议 chip、筛选 pill、多选标签等。
17
25
  */
@@ -20,17 +28,26 @@ export function Chip({
20
28
  selected,
21
29
  onPress,
22
30
  disabled,
31
+ busy,
23
32
  leading,
24
33
  trailing,
25
34
  style,
26
35
  testID
27
36
  }) {
37
+ const c = useColors();
28
38
  const styles = useThemedStyles(makeStyles);
39
+ // 处理中把 spinner 放进 leading 位(有 leading 就顶掉它):label 必须留着 —— 换掉它 chip
40
+ // 会塌成一个圆点,同排 chip 集体重排。spinner 跟随文本色,不在未选中的 chip 上凭空冒主色。
41
+ const lead = busy ? /*#__PURE__*/_jsx(Spinner, {
42
+ size: busySpinner,
43
+ thickness: r(1.5),
44
+ color: selected ? c.primary : c.foreground
45
+ }) : leading;
29
46
  const inner = /*#__PURE__*/_jsxs(View, {
30
47
  style: [styles.chip, selected && styles.chipOn, style],
31
48
  testID: onPress ? undefined : testID,
32
- children: [leading != null ? /*#__PURE__*/_jsx(View, {
33
- children: leading
49
+ children: [lead != null ? /*#__PURE__*/_jsx(View, {
50
+ children: lead
34
51
  }) : null, /*#__PURE__*/_jsx(Text, {
35
52
  style: [styles.text, selected && styles.textOn],
36
53
  numberOfLines: 1,
@@ -43,13 +60,16 @@ export function Chip({
43
60
  // [M-7] chip 内容高 ≈ 2×space[3] + xs 行高 ≈ 34pt < 44pt
44
61
  // Pressable 是外壳,hitSlop 向外补足到 fixed.hitTarget
45
62
  const chipHitSlopV = Math.max(0, Math.round((fixed.hitTarget - (2 * r(8) + rf(13) * 1.4)) / 2));
63
+ // 处理中同样不响应:chip 的高频用法是「点一下发起一次请求」,放行二次点击就是重复提交。
64
+ const inactive = !!disabled || !!busy;
46
65
  return /*#__PURE__*/_jsx(Pressable, {
47
66
  onPress: onPress,
48
- disabled: disabled,
67
+ disabled: inactive,
49
68
  accessibilityRole: "button",
50
69
  accessibilityState: {
51
70
  selected: !!selected,
52
- disabled: !!disabled
71
+ disabled: inactive,
72
+ busy: !!busy
53
73
  },
54
74
  accessibilityLabel: label,
55
75
  testID: testID,
@@ -63,7 +83,7 @@ export function Chip({
63
83
  pressed
64
84
  }) => [{
65
85
  alignSelf: 'flex-start',
66
- opacity: disabled ? 0.5 : pressed ? pressedOpacity : 1
86
+ opacity: disabled ? 0.5 : busy ? busyOpacity : pressed ? pressedOpacity : 1
67
87
  }],
68
88
  children: inner
69
89
  });
@@ -1 +1 @@
1
- {"version":3,"names":["React","Text","View","Pressable","fixed","pressedOpacity","r","rf","useThemedStyles","makeStyles","jsx","_jsx","jsxs","_jsxs","Chip","label","selected","onPress","disabled","leading","trailing","style","testID","styles","inner","chip","chipOn","undefined","children","text","textOn","numberOfLines","chipHitSlopV","Math","max","round","hitTarget","accessibilityRole","accessibilityState","accessibilityLabel","hitSlop","top","bottom","left","right","pressed","alignSelf","opacity"],"sourceRoot":"../../../../../src","sources":["components/ui/Chip/Chip.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,EAAEC,IAAI,QAAQ,cAAc;AACzC,SAASC,SAAS,QAAQ,8BAA8B;AACxD,SAASC,KAAK,EAAEC,cAAc,EAAEC,CAAC,EAAEC,EAAE,EAAEC,eAAe,QAAQ,yBAAgB;AAC9E,SAASC,UAAU,QAAQ,aAAU;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAGtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,IAAIA,CAAC;EACnBC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,KAAK;EACLC;AACS,CAAC,EAAqB;EAC/B,MAAMC,MAAM,GAAGf,eAAe,CAACC,UAAU,CAAC;EAC1C,MAAMe,KAAK,gBACTX,KAAA,CAACX,IAAI;IACHmB,KAAK,EAAE,CAACE,MAAM,CAACE,IAAI,EAAET,QAAQ,IAAIO,MAAM,CAACG,MAAM,EAAEL,KAAK,CAAE;IACvDC,MAAM,EAAEL,OAAO,GAAGU,SAAS,GAAGL,MAAO;IAAAM,QAAA,GAEpCT,OAAO,IAAI,IAAI,gBAAGR,IAAA,CAACT,IAAI;MAAA0B,QAAA,EAAET;IAAO,CAAO,CAAC,GAAG,IAAI,eAChDR,IAAA,CAACV,IAAI;MAACoB,KAAK,EAAE,CAACE,MAAM,CAACM,IAAI,EAAEb,QAAQ,IAAIO,MAAM,CAACO,MAAM,CAAE;MAACC,aAAa,EAAE,CAAE;MAAAH,QAAA,EACrEb;IAAK,CACF,CAAC,EACNK,QAAQ,IAAI,IAAI,gBAAGT,IAAA,CAACT,IAAI;MAAA0B,QAAA,EAAER;IAAQ,CAAO,CAAC,GAAG,IAAI;EAAA,CAC9C,CACP;EAED,IAAIH,OAAO,EAAE;IACX;IACA;IACA,MAAMe,YAAY,GAAGC,IAAI,CAACC,GAAG,CAC3B,CAAC,EACDD,IAAI,CAACE,KAAK,CAAC,CAAC/B,KAAK,CAACgC,SAAS,IAAI,CAAC,GAAG9B,CAAC,CAAC,CAAC,CAAC,GAAGC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAC9D,CAAC;IACD,oBACEI,IAAA,CAACR,SAAS;MACRc,OAAO,EAAEA,OAAQ;MACjBC,QAAQ,EAAEA,QAAS;MACnBmB,iBAAiB,EAAC,QAAQ;MAC1BC,kBAAkB,EAAE;QAAEtB,QAAQ,EAAE,CAAC,CAACA,QAAQ;QAAEE,QAAQ,EAAE,CAAC,CAACA;MAAS,CAAE;MACnEqB,kBAAkB,EAAExB,KAAM;MAC1BO,MAAM,EAAEA,MAAO;MACfkB,OAAO,EAAE;QAAEC,GAAG,EAAET,YAAY;QAAEU,MAAM,EAAEV,YAAY;QAAEW,IAAI,EAAE,CAAC;QAAEC,KAAK,EAAE;MAAE,CAAE;MACxEvB,KAAK,EAAEA,CAAC;QAAEwB;MAAQ,CAAC,KAAK,CACtB;QACEC,SAAS,EAAE,YAAY;QACvBC,OAAO,EAAE7B,QAAQ,GAAG,GAAG,GAAG2B,OAAO,GAAGxC,cAAc,GAAG;MACvD,CAAC,CACD;MAAAuB,QAAA,EAEDJ;IAAK,CACG,CAAC;EAEhB;EACA,OAAOA,KAAK;AACd","ignoreList":[]}
1
+ {"version":3,"names":["React","Text","View","Pressable","fixed","pressedOpacity","r","rf","useColors","useThemedStyles","Spinner","makeStyles","jsx","_jsx","jsxs","_jsxs","busyOpacity","busySpinner","Chip","label","selected","onPress","disabled","busy","leading","trailing","style","testID","c","styles","lead","size","thickness","color","primary","foreground","inner","chip","chipOn","undefined","children","text","textOn","numberOfLines","chipHitSlopV","Math","max","round","hitTarget","inactive","accessibilityRole","accessibilityState","accessibilityLabel","hitSlop","top","bottom","left","right","pressed","alignSelf","opacity"],"sourceRoot":"../../../../../src","sources":["components/ui/Chip/Chip.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import type { CarouselProps, ICarouselInstance } from './types';
3
- export declare const Carousel: <T extends object>(props: CarouselProps<T> & {
4
- ref?: React.Ref<ICarouselInstance>;
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;AAQ1B,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAiHhE,eAAO,MAAM,QAAQ,EAAsC,CAAC,CAAC,SAAS,MAAM,EAC1E,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;CAAE,KAC7D,KAAK,CAAC,GAAG,CAAC,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,3 +1,3 @@
1
1
  export { Carousel } from './Carousel';
2
- export type { CarouselProps, ICarouselInstance } from './types';
2
+ export type { CarouselProps, CarouselRef } from './types';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -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,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
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' 模式:独立行容器,覆盖 Pagination.Custom 默认的 `justifyContent: 'space-between'`
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 长条,Pagination.Custom 会把 dotStyle height /
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;oCACgC;;;;;;;;IAShC;4DACwD;;;;;;;;;;;;;;;;;IAkBxD;iFAC6E;;;;;EAK7E,CAAC"}
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 { ICarouselInstance } from 'react-native-reanimated-carousel';
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 { ICarouselInstance };
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
- items: ReadonlyArray<T>;
10
+ data: T[];
12
11
  /** 单项渲染 */
13
- renderItem: (item: T, index: number) => ReactNode;
14
- /** 每张高度(宽度默认 = 屏宽,被 itemWidth 覆盖) */
12
+ renderItem: CarouselRenderItem<T>;
13
+ /** 稳定 key 解析器,数据更新时用于保持 item 身份。 */
14
+ keyExtractor?: (item: T, index: number) => string;
15
+ /** 每张高度(宽度默认 = 屏宽,被 itemSize 覆盖) */
15
16
  height: number;
16
- /** 每张宽度,默认 useWindowDimensions().width。
17
+ /** 每张宽度与水平翻页步长,默认 useWindowDimensions().width。
17
18
  * 若 caller 外层有 marginHorizontal(如 Dashboard banner inset 16),需要传
18
19
  * `屏宽 - 左右 margin*2`,否则 slide 宽度超过可视区,右侧内容被裁切。 */
19
- itemWidth?: number;
20
- /** autoPlay 间隔 ms,undefined / 0 不自动 */
21
- autoPlay?: number;
22
- /** 是否循环播放,默认 true。传 false 时首尾不循环,可配合 a11y 暂停控制。 */
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,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC;;mEAEmE;AACnE,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,sBAAsB,CAAC;AAE1E,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,WAAW;IACX,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACxB,WAAW;IACX,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;uDAEmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,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"}
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"}
@@ -6,8 +6,9 @@ import type { ChipProps } from './types';
6
6
  * - 选中:主色边框 + 主色文本
7
7
  * - 按下:透明度 pressedOpacity(与 ButtonBase 同源)
8
8
  * - 禁用:透明度 0.5 + 不响应 onPress
9
+ * - 处理中(`busy`):leading 换 spinner + 透明度 0.6 + 不响应二次点击
9
10
  *
10
11
  * 常用于建议 chip、筛选 pill、多选标签等。
11
12
  */
12
- export declare function Chip({ label, selected, onPress, disabled, leading, trailing, style, testID, }: ChipProps): React.JSX.Element;
13
+ export declare function Chip({ label, selected, onPress, disabled, busy, leading, trailing, style, testID, }: ChipProps): React.JSX.Element;
13
14
  //# sourceMappingURL=Chip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,GACP,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2C/B"}
1
+ {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAQzC;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,GACP,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAmE/B"}
@@ -6,6 +6,10 @@ export type ChipProps = {
6
6
  onPress?: () => void;
7
7
  /** 整体禁用:opacity 0.5 + 不响应 onPress + accessibilityState.disabled */
8
8
  disabled?: boolean;
9
+ /** 处理中(点了、请求在飞):leading 位换 spinner + opacity 0.6 + 不响应二次点击 +
10
+ * accessibilityState.busy。label 保留 —— 换掉它 chip 会塌成一个圆点、整行跟着重排。
11
+ * 与 `disabled` 的分工:disabled = 现在不能点(更暗、无 spinner),busy = 正在办。 */
12
+ busy?: boolean;
9
13
  /** 可选的前置插槽 —— 如 <Icon name="spark" /> */
10
14
  leading?: ReactNode;
11
15
  /** 可选的后置插槽 —— 如一个小的 × 关闭按钮 */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;sEAEkE;IAClE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,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":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unif/react-native-design",
3
- "version": "0.18.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.0.0",
91
+ "react-native-gesture-handler": "^3.1.0",
92
92
  "react-native-reanimated": "^4.4.0",
93
- "react-native-reanimated-carousel": "^5.0.0-beta.5",
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": ">=2",
106
- "react-native-reanimated": ">=4",
107
- "react-native-reanimated-carousel": ">=5.0.0-beta.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 ReanimatedCarousel, {
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, ICarouselInstance } from './types';
10
+ import type { CarouselProps, CarouselRef } from './types';
10
11
 
11
- /** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0-beta.5`。
12
+ /** Carousel —— 包装 `react-native-reanimated-carousel@5.0.0`。
12
13
  *
13
- * dot indicator 走 `c.primary` token,使用库内置 `Pagination.Custom`
14
- * (`useSharedValue` + `onProgressChange` 驱动,re-render 全在 worklet 里)。
14
+ * dot indicator 走 `c.primary` token,使用库内置 `Pagination`
15
+ * (`useSharedValue` + `progress` 驱动,视觉插值留在 UI 线程)。
15
16
  *
16
- * Pagination.Custom 而非 Basic:Basic activeDot translateX 推进
17
- * 内层 fill,外壳宽度等于 dotStyle.width,activeDotStyle.width 只影响内层,
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
- // T 约束 object —— `Pagination.Basic<T extends {}>` 需要 object
24
- function CarouselInner<T extends object>(
20
+ function CarouselInner<T>(
25
21
  {
26
- items,
22
+ data,
27
23
  renderItem,
24
+ keyExtractor,
28
25
  height,
29
- itemWidth,
30
- autoPlay,
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<ICarouselInstance>
37
+ ref: React.Ref<CarouselRef>
40
38
  ): React.JSX.Element {
41
39
  const { width: screenWidth } = useWindowDimensions();
42
- const width = itemWidth ?? screenWidth;
40
+ const width = itemSize ?? screenWidth;
43
41
  const styles = useThemedStyles(makeCarouselStyles);
44
- // Carousel `onProgressChange` 把 absoluteProgress 写进 shared value,Pagination 自动跟。
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
- autoPlay={!!autoPlay}
66
- autoPlayInterval={autoPlay}
67
- onProgressChange={progress}
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 && items.length > 1 ? (
98
- // importantForAccessibility="no" —— dots 仅视觉辅助,SR 不需要读出
99
- // 每个 dot 的状态(已由 accessibilityRole=tab / accessibilityState.selected 表达
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
- data={data}
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 extends object>(
123
- props: CarouselProps<T> & { ref?: React.Ref<ICarouselInstance> }
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, ICarouselInstance } from './types';
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' 模式:独立行容器,覆盖 Pagination.Custom 默认的 `justifyContent: 'space-between'`
7
- * (否则 dot 横向撑开),让 dot 居中紧贴。 */
6
+ /** 'bottom' 模式:独立行容器,让 dot 居中紧贴。 */
8
7
  dotsWrapBottom: {
9
- flexDirection: 'row',
10
8
  justifyContent: 'center',
11
9
  alignItems: 'center',
12
- // 3pt 横间距:dot 单元 4pt + space[1]=r(4) 偏大,保留 r(3) 作为局部 dot 间隙
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 长条,Pagination.Custom 会把 dotStyle height /
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 { ICarouselInstance } from 'react-native-reanimated-carousel';
2
- import type { ReactNode } from 'react';
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 { ICarouselInstance };
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
- items: ReadonlyArray<T>;
16
+ data: T[];
15
17
  /** 单项渲染 */
16
- renderItem: (item: T, index: number) => ReactNode;
17
- /** 每张高度(宽度默认 = 屏宽,被 itemWidth 覆盖) */
18
+ renderItem: CarouselRenderItem<T>;
19
+ /** 稳定 key 解析器,数据更新时用于保持 item 身份。 */
20
+ keyExtractor?: (item: T, index: number) => string;
21
+ /** 每张高度(宽度默认 = 屏宽,被 itemSize 覆盖) */
18
22
  height: number;
19
- /** 每张宽度,默认 useWindowDimensions().width。
23
+ /** 每张宽度与水平翻页步长,默认 useWindowDimensions().width。
20
24
  * 若 caller 外层有 marginHorizontal(如 Dashboard banner inset 16),需要传
21
25
  * `屏宽 - 左右 margin*2`,否则 slide 宽度超过可视区,右侧内容被裁切。 */
22
- itemWidth?: number;
23
- /** autoPlay 间隔 ms,undefined / 0 不自动 */
24
- autoPlay?: number;
25
- /** 是否循环播放,默认 true。传 false 时首尾不循环,可配合 a11y 暂停控制。 */
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;
@@ -1,16 +1,31 @@
1
1
  import React from 'react';
2
2
  import { Text, View } from 'react-native';
3
3
  import { Pressable } from 'react-native-gesture-handler';
4
- import { fixed, pressedOpacity, r, rf, useThemedStyles } from '../../../theme';
4
+ import {
5
+ fixed,
6
+ pressedOpacity,
7
+ r,
8
+ rf,
9
+ useColors,
10
+ useThemedStyles,
11
+ } from '../../../theme';
12
+ import { Spinner } from '../Spinner';
5
13
  import { makeStyles } from './styles';
6
14
  import type { ChipProps } from './types';
7
15
 
16
+ /** 处理中 chip 的透明度 —— 比 disabled(0.5)亮、比按下(pressedOpacity)暗:
17
+ * 「正在办」既要压下去,又不能和「不能点」长一样(那两者只靠 spinner 区分就太弱了)。 */
18
+ const busyOpacity = 0.6;
19
+ /** busy spinner 直径 —— 与调用方常用的 leading icon(12)等大,顶替时不改 chip 宽度。 */
20
+ const busySpinner = r(12);
21
+
8
22
  /**
9
23
  * 胶囊形可点击 chip。
10
24
  * - 默认:surface 底 + outline 细线边框,foreground 文本
11
25
  * - 选中:主色边框 + 主色文本
12
26
  * - 按下:透明度 pressedOpacity(与 ButtonBase 同源)
13
27
  * - 禁用:透明度 0.5 + 不响应 onPress
28
+ * - 处理中(`busy`):leading 换 spinner + 透明度 0.6 + 不响应二次点击
14
29
  *
15
30
  * 常用于建议 chip、筛选 pill、多选标签等。
16
31
  */
@@ -19,18 +34,31 @@ export function Chip({
19
34
  selected,
20
35
  onPress,
21
36
  disabled,
37
+ busy,
22
38
  leading,
23
39
  trailing,
24
40
  style,
25
41
  testID,
26
42
  }: ChipProps): React.JSX.Element {
43
+ const c = useColors();
27
44
  const styles = useThemedStyles(makeStyles);
45
+ // 处理中把 spinner 放进 leading 位(有 leading 就顶掉它):label 必须留着 —— 换掉它 chip
46
+ // 会塌成一个圆点,同排 chip 集体重排。spinner 跟随文本色,不在未选中的 chip 上凭空冒主色。
47
+ const lead = busy ? (
48
+ <Spinner
49
+ size={busySpinner}
50
+ thickness={r(1.5)}
51
+ color={selected ? c.primary : c.foreground}
52
+ />
53
+ ) : (
54
+ leading
55
+ );
28
56
  const inner = (
29
57
  <View
30
58
  style={[styles.chip, selected && styles.chipOn, style]}
31
59
  testID={onPress ? undefined : testID}
32
60
  >
33
- {leading != null ? <View>{leading}</View> : null}
61
+ {lead != null ? <View>{lead}</View> : null}
34
62
  <Text style={[styles.text, selected && styles.textOn]} numberOfLines={1}>
35
63
  {label}
36
64
  </Text>
@@ -45,19 +73,31 @@ export function Chip({
45
73
  0,
46
74
  Math.round((fixed.hitTarget - (2 * r(8) + rf(13) * 1.4)) / 2)
47
75
  );
76
+ // 处理中同样不响应:chip 的高频用法是「点一下发起一次请求」,放行二次点击就是重复提交。
77
+ const inactive = !!disabled || !!busy;
48
78
  return (
49
79
  <Pressable
50
80
  onPress={onPress}
51
- disabled={disabled}
81
+ disabled={inactive}
52
82
  accessibilityRole="button"
53
- accessibilityState={{ selected: !!selected, disabled: !!disabled }}
83
+ accessibilityState={{
84
+ selected: !!selected,
85
+ disabled: inactive,
86
+ busy: !!busy,
87
+ }}
54
88
  accessibilityLabel={label}
55
89
  testID={testID}
56
90
  hitSlop={{ top: chipHitSlopV, bottom: chipHitSlopV, left: 0, right: 0 }}
57
91
  style={({ pressed }) => [
58
92
  {
59
93
  alignSelf: 'flex-start',
60
- opacity: disabled ? 0.5 : pressed ? pressedOpacity : 1,
94
+ opacity: disabled
95
+ ? 0.5
96
+ : busy
97
+ ? busyOpacity
98
+ : pressed
99
+ ? pressedOpacity
100
+ : 1,
61
101
  },
62
102
  ]}
63
103
  >
@@ -7,6 +7,10 @@ export type ChipProps = {
7
7
  onPress?: () => void;
8
8
  /** 整体禁用:opacity 0.5 + 不响应 onPress + accessibilityState.disabled */
9
9
  disabled?: boolean;
10
+ /** 处理中(点了、请求在飞):leading 位换 spinner + opacity 0.6 + 不响应二次点击 +
11
+ * accessibilityState.busy。label 保留 —— 换掉它 chip 会塌成一个圆点、整行跟着重排。
12
+ * 与 `disabled` 的分工:disabled = 现在不能点(更暗、无 spinner),busy = 正在办。 */
13
+ busy?: boolean;
10
14
  /** 可选的前置插槽 —— 如 <Icon name="spark" /> */
11
15
  leading?: ReactNode;
12
16
  /** 可选的后置插槽 —— 如一个小的 × 关闭按钮 */
@@ -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';