@coinbase/cds-mobile 8.42.0 → 8.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dts/carousel/Carousel.d.ts +88 -14
- package/dts/carousel/Carousel.d.ts.map +1 -1
- package/dts/carousel/CarouselContext.d.ts +18 -0
- package/dts/carousel/CarouselContext.d.ts.map +1 -1
- package/dts/carousel/DefaultCarouselNavigation.d.ts +16 -0
- package/dts/carousel/DefaultCarouselNavigation.d.ts.map +1 -1
- package/dts/carousel/DefaultCarouselPagination.d.ts.map +1 -1
- package/dts/carousel/__figma__/Carousel.figma.d.ts +2 -0
- package/dts/carousel/__figma__/Carousel.figma.d.ts.map +1 -0
- package/esm/buttons/__figma__/SlideButton.figma.js +1 -1
- package/esm/cards/MediaCard/__figma__/MediaCard.figma.js +20 -15
- package/esm/cards/MessagingCard/__figma__/MessagingCard.figma.js +3 -9
- package/esm/carousel/Carousel.js +114 -57
- package/esm/carousel/CarouselContext.js +8 -0
- package/esm/carousel/DefaultCarouselNavigation.js +17 -2
- package/esm/carousel/DefaultCarouselPagination.js +150 -15
- package/esm/carousel/__figma__/Carousel.figma.js +15 -0
- package/esm/carousel/__stories__/Carousel.stories.js +60 -11
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file.
|
|
|
8
8
|
|
|
9
9
|
<!-- template-start -->
|
|
10
10
|
|
|
11
|
+
## 8.43.0 (2/6/2026 PST)
|
|
12
|
+
|
|
13
|
+
#### 🚀 Updates
|
|
14
|
+
|
|
15
|
+
- Carousel autoplay. [[#361](https://github.com/coinbase/cds/pull/361)]
|
|
16
|
+
|
|
11
17
|
## 8.42.0 (2/4/2026 PST)
|
|
12
18
|
|
|
13
19
|
#### 🚀 Updates
|
|
@@ -2,7 +2,14 @@ import React from 'react';
|
|
|
2
2
|
import { type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
|
|
3
3
|
import type { SharedAccessibilityProps, SharedProps } from '@coinbase/cds-common/types';
|
|
4
4
|
import { type BoxBaseProps, type BoxProps } from '../layout/Box';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
CarouselAutoplayContext,
|
|
7
|
+
type CarouselAutoplayContextValue,
|
|
8
|
+
CarouselContext,
|
|
9
|
+
type CarouselContextValue,
|
|
10
|
+
useCarouselAutoplayContext,
|
|
11
|
+
useCarouselContext,
|
|
12
|
+
} from './CarouselContext';
|
|
6
13
|
export type CarouselItemRenderChildren = React.FC<{
|
|
7
14
|
isVisible: boolean;
|
|
8
15
|
}>;
|
|
@@ -21,9 +28,16 @@ export type CarouselItemBaseProps = Omit<BoxBaseProps, 'children'> &
|
|
|
21
28
|
export type CarouselItemProps = Omit<BoxProps, 'children'> & CarouselItemBaseProps;
|
|
22
29
|
export type CarouselItemComponent = React.FC<CarouselItemProps>;
|
|
23
30
|
export type CarouselItemElement = React.ReactElement<CarouselItemProps, CarouselItemComponent>;
|
|
24
|
-
export { CarouselContext, useCarouselContext };
|
|
25
|
-
export type { CarouselContextValue };
|
|
26
|
-
export type CarouselNavigationComponentBaseProps =
|
|
31
|
+
export { CarouselAutoplayContext, CarouselContext, useCarouselAutoplayContext, useCarouselContext };
|
|
32
|
+
export type { CarouselAutoplayContextValue, CarouselContextValue };
|
|
33
|
+
export type CarouselNavigationComponentBaseProps = Pick<
|
|
34
|
+
CarouselBaseProps,
|
|
35
|
+
| 'autoplay'
|
|
36
|
+
| 'nextPageAccessibilityLabel'
|
|
37
|
+
| 'previousPageAccessibilityLabel'
|
|
38
|
+
| 'startAutoplayAccessibilityLabel'
|
|
39
|
+
| 'stopAutoplayAccessibilityLabel'
|
|
40
|
+
> & {
|
|
27
41
|
/**
|
|
28
42
|
* Callback for when the previous button is pressed.
|
|
29
43
|
*/
|
|
@@ -41,13 +55,13 @@ export type CarouselNavigationComponentBaseProps = {
|
|
|
41
55
|
*/
|
|
42
56
|
disableGoNext: boolean;
|
|
43
57
|
/**
|
|
44
|
-
*
|
|
58
|
+
* Whether autoplay is currently stopped.
|
|
45
59
|
*/
|
|
46
|
-
|
|
60
|
+
isAutoplayStopped?: boolean;
|
|
47
61
|
/**
|
|
48
|
-
*
|
|
62
|
+
* Callback fired when the autoplay button is pressed.
|
|
49
63
|
*/
|
|
50
|
-
|
|
64
|
+
onToggleAutoplay?: () => void;
|
|
51
65
|
};
|
|
52
66
|
export type CarouselNavigationComponentProps = CarouselNavigationComponentBaseProps & {
|
|
53
67
|
/**
|
|
@@ -73,6 +87,14 @@ export type CarouselPaginationComponentBaseProps = {
|
|
|
73
87
|
* Accessibility label for the go to page button. You can optionally pass a function that will receive the pageIndex as an argument, and return an accessibility label string.
|
|
74
88
|
*/
|
|
75
89
|
paginationAccessibilityLabel?: string | ((pageIndex: number) => string);
|
|
90
|
+
/**
|
|
91
|
+
* Visual variant for the pagination indicators.
|
|
92
|
+
* - 'pill': All indicators are pill-shaped (default)
|
|
93
|
+
* - 'dot': Inactive indicators are small dots, active indicator expands to a pill
|
|
94
|
+
* @default 'pill'
|
|
95
|
+
* @note 'pill' variant is deprecated, use 'dot' instead
|
|
96
|
+
*/
|
|
97
|
+
variant?: 'pill' | 'dot';
|
|
76
98
|
};
|
|
77
99
|
export type CarouselPaginationComponentProps = CarouselPaginationComponentBaseProps & {
|
|
78
100
|
/**
|
|
@@ -155,12 +177,21 @@ export type CarouselBaseProps = SharedProps &
|
|
|
155
177
|
previousPageAccessibilityLabel?: string;
|
|
156
178
|
/**
|
|
157
179
|
* Accessibility label for the go to page button.
|
|
180
|
+
* When a string is provided, it is used as-is for all indicators.
|
|
181
|
+
* When a function is provided, it receives the page index and returns a label.
|
|
182
|
+
* @default (pageIndex) => `Go to page ${pageIndex + 1}`
|
|
158
183
|
*/
|
|
159
|
-
|
|
184
|
+
paginationAccessibilityLabel?: string | ((pageIndex: number) => string);
|
|
160
185
|
/**
|
|
161
|
-
* Accessibility label for
|
|
186
|
+
* Accessibility label for starting autoplay.
|
|
187
|
+
* @default 'Play Carousel'
|
|
162
188
|
*/
|
|
163
|
-
|
|
189
|
+
startAutoplayAccessibilityLabel?: string;
|
|
190
|
+
/**
|
|
191
|
+
* Accessibility label for stopping autoplay.
|
|
192
|
+
* @default 'Pause Carousel'
|
|
193
|
+
*/
|
|
194
|
+
stopAutoplayAccessibilityLabel?: string;
|
|
164
195
|
/**
|
|
165
196
|
* Callback fired when the page changes.
|
|
166
197
|
*/
|
|
@@ -179,6 +210,23 @@ export type CarouselBaseProps = SharedProps &
|
|
|
179
210
|
* @note Requires at least 2 pages worth of content to function.
|
|
180
211
|
*/
|
|
181
212
|
loop?: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Whether autoplay is enabled for the carousel.
|
|
215
|
+
*/
|
|
216
|
+
autoplay?: boolean;
|
|
217
|
+
/**
|
|
218
|
+
* The interval in milliseconds for autoplay.
|
|
219
|
+
* @default 3000 (3 seconds)
|
|
220
|
+
*/
|
|
221
|
+
autoplayInterval?: number;
|
|
222
|
+
/**
|
|
223
|
+
* Visual variant for the pagination indicators.
|
|
224
|
+
* - 'pill': All indicators are pill-shaped (default)
|
|
225
|
+
* - 'dot': Inactive indicators are small dots, active indicator expands to a pill
|
|
226
|
+
* @default 'pill'
|
|
227
|
+
* @note 'pill' variant is deprecated, use 'dot' instead
|
|
228
|
+
*/
|
|
229
|
+
paginationVariant?: CarouselPaginationComponentBaseProps['variant'];
|
|
182
230
|
};
|
|
183
231
|
export type CarouselProps = CarouselBaseProps & {
|
|
184
232
|
/**
|
|
@@ -293,12 +341,21 @@ export declare const Carousel: React.MemoExoticComponent<
|
|
|
293
341
|
previousPageAccessibilityLabel?: string;
|
|
294
342
|
/**
|
|
295
343
|
* Accessibility label for the go to page button.
|
|
344
|
+
* When a string is provided, it is used as-is for all indicators.
|
|
345
|
+
* When a function is provided, it receives the page index and returns a label.
|
|
346
|
+
* @default (pageIndex) => `Go to page ${pageIndex + 1}`
|
|
296
347
|
*/
|
|
297
|
-
|
|
348
|
+
paginationAccessibilityLabel?: string | ((pageIndex: number) => string);
|
|
298
349
|
/**
|
|
299
|
-
* Accessibility label for
|
|
350
|
+
* Accessibility label for starting autoplay.
|
|
351
|
+
* @default 'Play Carousel'
|
|
300
352
|
*/
|
|
301
|
-
|
|
353
|
+
startAutoplayAccessibilityLabel?: string;
|
|
354
|
+
/**
|
|
355
|
+
* Accessibility label for stopping autoplay.
|
|
356
|
+
* @default 'Pause Carousel'
|
|
357
|
+
*/
|
|
358
|
+
stopAutoplayAccessibilityLabel?: string;
|
|
302
359
|
/**
|
|
303
360
|
* Callback fired when the page changes.
|
|
304
361
|
*/
|
|
@@ -317,6 +374,23 @@ export declare const Carousel: React.MemoExoticComponent<
|
|
|
317
374
|
* @note Requires at least 2 pages worth of content to function.
|
|
318
375
|
*/
|
|
319
376
|
loop?: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Whether autoplay is enabled for the carousel.
|
|
379
|
+
*/
|
|
380
|
+
autoplay?: boolean;
|
|
381
|
+
/**
|
|
382
|
+
* The interval in milliseconds for autoplay.
|
|
383
|
+
* @default 3000 (3 seconds)
|
|
384
|
+
*/
|
|
385
|
+
autoplayInterval?: number;
|
|
386
|
+
/**
|
|
387
|
+
* Visual variant for the pagination indicators.
|
|
388
|
+
* - 'pill': All indicators are pill-shaped (default)
|
|
389
|
+
* - 'dot': Inactive indicators are small dots, active indicator expands to a pill
|
|
390
|
+
* @default 'pill'
|
|
391
|
+
* @note 'pill' variant is deprecated, use 'dot' instead
|
|
392
|
+
*/
|
|
393
|
+
paginationVariant?: CarouselPaginationComponentBaseProps['variant'];
|
|
320
394
|
} & {
|
|
321
395
|
/**
|
|
322
396
|
* Custom styles for the root element.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../src/carousel/Carousel.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../../src/carousel/Carousel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { CarouselAutoplay } from '@coinbase/cds-common';
|
|
2
3
|
import type { Rect } from '@coinbase/cds-common/types';
|
|
3
4
|
export type CarouselContextValue = {
|
|
4
5
|
registerItem: (id: string, state: Rect) => void;
|
|
@@ -10,4 +11,21 @@ export type CarouselContextValue = {
|
|
|
10
11
|
};
|
|
11
12
|
export declare const CarouselContext: React.Context<CarouselContextValue | undefined>;
|
|
12
13
|
export declare const useCarouselContext: () => CarouselContextValue;
|
|
14
|
+
export type CarouselAutoplayContextValue = Omit<
|
|
15
|
+
CarouselAutoplay,
|
|
16
|
+
'remainingTime' | 'addCompletionListener'
|
|
17
|
+
> & {
|
|
18
|
+
/**
|
|
19
|
+
* Whether autoplay is enabled via props.
|
|
20
|
+
*/
|
|
21
|
+
isEnabled: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The autoplay interval duration in milliseconds.
|
|
24
|
+
*/
|
|
25
|
+
interval: number;
|
|
26
|
+
};
|
|
27
|
+
export declare const CarouselAutoplayContext: React.Context<
|
|
28
|
+
CarouselAutoplayContextValue | undefined
|
|
29
|
+
>;
|
|
30
|
+
export declare const useCarouselAutoplayContext: () => CarouselAutoplayContextValue;
|
|
13
31
|
//# sourceMappingURL=CarouselContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CarouselContext.d.ts","sourceRoot":"","sources":["../../src/carousel/CarouselContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,eAAe,iDAAmE,CAAC;AAEhG,eAAO,MAAM,kBAAkB,QAAO,oBAMrC,CAAC"}
|
|
1
|
+
{"version":3,"file":"CarouselContext.d.ts","sourceRoot":"","sources":["../../src/carousel/CarouselContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,eAAe,iDAAmE,CAAC;AAEhG,eAAO,MAAM,kBAAkB,QAAO,oBAMrC,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG,IAAI,CAC7C,gBAAgB,EAChB,eAAe,GAAG,uBAAuB,CAC1C,GAAG;IACF;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,uBAAuB,yDAExB,CAAC;AAEb,eAAO,MAAM,0BAA0B,QAAO,4BAM7C,CAAC"}
|
|
@@ -15,6 +15,10 @@ export type DefaultCarouselNavigationProps = CarouselNavigationComponentProps &
|
|
|
15
15
|
* Test ID for the next button.
|
|
16
16
|
*/
|
|
17
17
|
nextButton?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Test ID for the autoplay button.
|
|
20
|
+
*/
|
|
21
|
+
autoplayButton?: string;
|
|
18
22
|
};
|
|
19
23
|
/**
|
|
20
24
|
* Icon to use for the previous button.
|
|
@@ -24,6 +28,14 @@ export type DefaultCarouselNavigationProps = CarouselNavigationComponentProps &
|
|
|
24
28
|
* Icon to use for the next button.
|
|
25
29
|
*/
|
|
26
30
|
nextIcon?: IconName;
|
|
31
|
+
/**
|
|
32
|
+
* Icon to use for the start autoplay button.
|
|
33
|
+
*/
|
|
34
|
+
startIcon?: IconName;
|
|
35
|
+
/**
|
|
36
|
+
* Icon to use for the stop autoplay button.
|
|
37
|
+
*/
|
|
38
|
+
stopIcon?: IconName;
|
|
27
39
|
/**
|
|
28
40
|
* Variant of the icon button.
|
|
29
41
|
*/
|
|
@@ -48,6 +60,10 @@ export type DefaultCarouselNavigationProps = CarouselNavigationComponentProps &
|
|
|
48
60
|
* Custom styles for the next button.
|
|
49
61
|
*/
|
|
50
62
|
nextButton?: StyleProp<ViewStyle>;
|
|
63
|
+
/**
|
|
64
|
+
* Custom styles for the autoplay button.
|
|
65
|
+
*/
|
|
66
|
+
autoplayButton?: StyleProp<ViewStyle>;
|
|
51
67
|
};
|
|
52
68
|
};
|
|
53
69
|
export declare const DefaultCarouselNavigation: React.NamedExoticComponent<DefaultCarouselNavigationProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultCarouselNavigation.d.ts","sourceRoot":"","sources":["../../src/carousel/DefaultCarouselNavigation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMxE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,MAAM,8BAA8B,GAAG,gCAAgC,GAAG;IAC9E;;OAEG;IACH,SAAS,CAAC,EAAE;QACV;;WAEG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"DefaultCarouselNavigation.d.ts","sourceRoot":"","sources":["../../src/carousel/DefaultCarouselNavigation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMxE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,MAAM,8BAA8B,GAAG,gCAAgC,GAAG;IAC9E;;OAEG;IACH,SAAS,CAAC,EAAE;QACV;;WAEG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;WAEG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;OAEG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5B;;WAEG;QACH,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC;;WAEG;QACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAClC;;WAEG;QACH,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KACvC,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,4DAmEpC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultCarouselPagination.d.ts","sourceRoot":"","sources":["../../src/carousel/DefaultCarouselPagination.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"DefaultCarouselPagination.d.ts","sourceRoot":"","sources":["../../src/carousel/DefaultCarouselPagination.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzD,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,MAAM,8BAA8B,GAAG,gCAAgC,GAAG;IAC9E;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5B;;WAEG;QACH,GAAG,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC5B,CAAC;CACH,CAAC;AA+IF,eAAO,MAAM,yBAAyB,4DA4DpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.figma.d.ts","sourceRoot":"","sources":["../../../src/carousel/__figma__/Carousel.figma.tsx"],"names":[],"mappings":""}
|
|
@@ -5,7 +5,7 @@ import { figma } from '@figma/code-connect';
|
|
|
5
5
|
import { SlideButton } from '../SlideButton';
|
|
6
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
7
|
figma.connect(SlideButton, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E2%9C%A8-CDS-Components?node-id=49598-10283&m=dev', {
|
|
8
|
-
imports: ["import { SlideButton } from '@coinbase/cds-mobile/buttons/SlideButton'"],
|
|
8
|
+
imports: ["import { SlideButton } from '@coinbase/cds-mobile/buttons/SlideButton';"],
|
|
9
9
|
props: {
|
|
10
10
|
checked: figma.enum('Position', {
|
|
11
11
|
// TODO: fix falsy values returning undefined. This is an existing issue in code connect https://github.com/figma/code-connect/issues/193
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
function _objectDestructuringEmpty(t) { if (null == t) throw new TypeError("Cannot destructure " + t); }
|
|
2
1
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
3
2
|
import React from 'react';
|
|
3
|
+
import { ethBackground } from '@coinbase/cds-common/internal/data/assets';
|
|
4
4
|
import { figma } from '@figma/code-connect';
|
|
5
|
-
import {
|
|
5
|
+
import { RemoteImage } from '../../../media';
|
|
6
6
|
import { MediaCard } from '../';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
figma.connect(MediaCard, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E2%9C%A8-CDS-Components?node-id=72941-18302&m=dev', {
|
|
@@ -17,25 +17,30 @@ figma.connect(MediaCard, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E
|
|
|
17
17
|
true: figma.instance('↳ subdetail'),
|
|
18
18
|
false: undefined
|
|
19
19
|
}),
|
|
20
|
-
|
|
20
|
+
thumbnail: figma.boolean('show media', {
|
|
21
21
|
true: figma.instance('↳ media'),
|
|
22
22
|
false: undefined
|
|
23
23
|
}),
|
|
24
|
-
mediaPlacement: figma.enum('
|
|
24
|
+
mediaPlacement: figma.enum('image placement', {
|
|
25
25
|
left: 'start',
|
|
26
26
|
right: 'end',
|
|
27
27
|
none: undefined
|
|
28
|
+
}),
|
|
29
|
+
media: figma.enum('image placement', {
|
|
30
|
+
left: /*#__PURE__*/_jsx(RemoteImage, {
|
|
31
|
+
alt: "Media",
|
|
32
|
+
shape: "rectangle",
|
|
33
|
+
source: ethBackground,
|
|
34
|
+
width: "100%"
|
|
35
|
+
}),
|
|
36
|
+
right: /*#__PURE__*/_jsx(RemoteImage, {
|
|
37
|
+
alt: "Media",
|
|
38
|
+
shape: "rectangle",
|
|
39
|
+
source: ethBackground,
|
|
40
|
+
width: "100%"
|
|
41
|
+
}),
|
|
42
|
+
none: undefined
|
|
28
43
|
})
|
|
29
44
|
},
|
|
30
|
-
example:
|
|
31
|
-
let props = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
|
|
32
|
-
return /*#__PURE__*/_jsx(MediaCard, _extends({
|
|
33
|
-
thumbnail: /*#__PURE__*/_jsx(Avatar, {
|
|
34
|
-
accessibilityLabel: "",
|
|
35
|
-
shape: "circle",
|
|
36
|
-
size: "l",
|
|
37
|
-
src: ""
|
|
38
|
-
})
|
|
39
|
-
}, props));
|
|
40
|
-
}
|
|
45
|
+
example: props => /*#__PURE__*/_jsx(MediaCard, _extends({}, props))
|
|
41
46
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
function _objectDestructuringEmpty(t) { if (null == t) throw new TypeError("Cannot destructure " + t); }
|
|
2
1
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import { figma } from '@figma/code-connect';
|
|
@@ -23,10 +22,6 @@ figma.connect(MessagingCard, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2
|
|
|
23
22
|
true: figma.instance('↳ tag'),
|
|
24
23
|
false: undefined
|
|
25
24
|
}),
|
|
26
|
-
action: figma.boolean('show cta', {
|
|
27
|
-
true: figma.instance('↳ cta'),
|
|
28
|
-
false: undefined
|
|
29
|
-
}),
|
|
30
25
|
media: figma.instance('media'),
|
|
31
26
|
mediaPlacement: figma.enum('media placement', {
|
|
32
27
|
left: 'start',
|
|
@@ -37,8 +32,7 @@ figma.connect(MessagingCard, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2
|
|
|
37
32
|
false: undefined
|
|
38
33
|
})
|
|
39
34
|
},
|
|
40
|
-
example:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
35
|
+
example: props => /*#__PURE__*/_jsx(MessagingCard, _extends({
|
|
36
|
+
action: "Button"
|
|
37
|
+
}, props))
|
|
44
38
|
});
|
package/esm/carousel/Carousel.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
const _excluded = ["children", "title", "hideNavigation", "hidePagination", "drag", "snapMode", "NavigationComponent", "PaginationComponent", "style", "styles", "nextPageAccessibilityLabel", "previousPageAccessibilityLabel", "
|
|
1
|
+
const _excluded = ["children", "title", "hideNavigation", "hidePagination", "drag", "snapMode", "NavigationComponent", "PaginationComponent", "style", "styles", "nextPageAccessibilityLabel", "previousPageAccessibilityLabel", "startAutoplayAccessibilityLabel", "stopAutoplayAccessibilityLabel", "paginationAccessibilityLabel", "onChangePage", "onDragStart", "onDragEnd", "loop", "autoplay", "autoplayInterval", "paginationVariant"];
|
|
2
2
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
3
3
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
4
|
-
import React, { forwardRef, memo, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import { View } from 'react-native';
|
|
6
6
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
7
|
+
import { useCarouselAutoplay } from '@coinbase/cds-common/carousel/useCarouselAutoplay';
|
|
7
8
|
import { animated, useSpring } from '@react-spring/native';
|
|
8
9
|
import { useLayout } from '../hooks/useLayout';
|
|
9
10
|
import { HStack } from '../layout/HStack';
|
|
10
11
|
import { VStack } from '../layout/VStack';
|
|
11
12
|
import { Text } from '../typography/Text';
|
|
12
|
-
import { CarouselContext, useCarouselContext } from './CarouselContext';
|
|
13
|
+
import { CarouselAutoplayContext, CarouselContext, useCarouselAutoplayContext, useCarouselContext } from './CarouselContext';
|
|
13
14
|
import { CarouselItem } from './CarouselItem';
|
|
14
15
|
import { DefaultCarouselNavigation } from './DefaultCarouselNavigation';
|
|
15
16
|
import { DefaultCarouselPagination } from './DefaultCarouselPagination';
|
|
@@ -26,7 +27,7 @@ const wrap = (min, max, value) => {
|
|
|
26
27
|
const range = max - min;
|
|
27
28
|
return min + ((value - min) % range + range) % range;
|
|
28
29
|
};
|
|
29
|
-
export { CarouselContext, useCarouselContext };
|
|
30
|
+
export { CarouselAutoplayContext, CarouselContext, useCarouselAutoplayContext, useCarouselContext };
|
|
30
31
|
/**
|
|
31
32
|
* Calculates the locations of each item in the carousel, offset from the first item.
|
|
32
33
|
* @param itemRects - The items to get the offsets for.
|
|
@@ -250,8 +251,8 @@ const getVisibleItems = (itemRects, containerWidth, scrollOffset) => {
|
|
|
250
251
|
return visibleItems;
|
|
251
252
|
};
|
|
252
253
|
const animationConfig = {
|
|
253
|
-
|
|
254
|
-
|
|
254
|
+
stiffness: 900,
|
|
255
|
+
damping: 120
|
|
255
256
|
};
|
|
256
257
|
export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) => {
|
|
257
258
|
let {
|
|
@@ -267,11 +268,16 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
267
268
|
styles,
|
|
268
269
|
nextPageAccessibilityLabel,
|
|
269
270
|
previousPageAccessibilityLabel,
|
|
270
|
-
|
|
271
|
+
startAutoplayAccessibilityLabel,
|
|
272
|
+
stopAutoplayAccessibilityLabel,
|
|
273
|
+
paginationAccessibilityLabel,
|
|
271
274
|
onChangePage,
|
|
272
275
|
onDragStart,
|
|
273
276
|
onDragEnd,
|
|
274
|
-
loop
|
|
277
|
+
loop,
|
|
278
|
+
autoplay,
|
|
279
|
+
autoplayInterval = 3000,
|
|
280
|
+
paginationVariant
|
|
275
281
|
} = _ref4,
|
|
276
282
|
props = _objectWithoutPropertiesLoose(_ref4, _excluded);
|
|
277
283
|
const carouselScrollX = useRef(0);
|
|
@@ -283,14 +289,11 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
283
289
|
const [containerSize, onLayout] = useLayout();
|
|
284
290
|
const [carouselItemRects, setCarouselItemRects] = useState({});
|
|
285
291
|
const [visibleCarouselItems, setVisibleCarouselItems] = useState(new Set());
|
|
286
|
-
const rootRef = useRef(null);
|
|
287
292
|
const isDragEnabled = drag !== 'none';
|
|
288
293
|
const updateActivePageIndex = useCallback(newPageIndexOrUpdater => {
|
|
289
294
|
setActivePageIndex(prevIndex => {
|
|
290
295
|
const newPageIndex = typeof newPageIndexOrUpdater === 'function' ? newPageIndexOrUpdater(prevIndex) : newPageIndexOrUpdater;
|
|
291
|
-
if (prevIndex !== newPageIndex
|
|
292
|
-
onChangePage(newPageIndex);
|
|
293
|
-
}
|
|
296
|
+
if (prevIndex !== newPageIndex) onChangePage == null || onChangePage(newPageIndex);
|
|
294
297
|
return newPageIndex;
|
|
295
298
|
});
|
|
296
299
|
}, [onChangePage]);
|
|
@@ -398,6 +401,22 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
398
401
|
updateActivePageIndex(pageIndex => Math.min(pageIndex, pageOffsets.totalPages - 1));
|
|
399
402
|
return pageOffsets;
|
|
400
403
|
}, [hasCalculatedDimensions, carouselItemRects, snapMode, containerSize.width, maxScrollOffset, shouldLoop, updateActivePageIndex]);
|
|
404
|
+
const {
|
|
405
|
+
isPlaying,
|
|
406
|
+
isStopped,
|
|
407
|
+
isPaused,
|
|
408
|
+
start,
|
|
409
|
+
stop,
|
|
410
|
+
toggle,
|
|
411
|
+
reset,
|
|
412
|
+
pause,
|
|
413
|
+
resume,
|
|
414
|
+
getRemainingTime,
|
|
415
|
+
addCompletionListener
|
|
416
|
+
} = useCarouselAutoplay({
|
|
417
|
+
enabled: autoplay != null ? autoplay : false,
|
|
418
|
+
interval: autoplayInterval
|
|
419
|
+
});
|
|
401
420
|
const goToPage = useCallback(page => {
|
|
402
421
|
const newPage = Math.max(0, Math.min(totalPages - 1, page));
|
|
403
422
|
updateActivePageIndex(newPage);
|
|
@@ -408,12 +427,22 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
408
427
|
to: targetOffset,
|
|
409
428
|
config: animationConfig
|
|
410
429
|
});
|
|
411
|
-
|
|
430
|
+
reset();
|
|
431
|
+
}, [totalPages, updateActivePageIndex, updateVisibleCarouselItems, pageOffsets, isLoopingActive, loopLength, animationApi.x, reset]);
|
|
412
432
|
useImperativeHandle(ref, () => ({
|
|
413
433
|
activePageIndex,
|
|
414
434
|
totalPages,
|
|
415
435
|
goToPage
|
|
416
436
|
}), [activePageIndex, totalPages, goToPage]);
|
|
437
|
+
useEffect(() => {
|
|
438
|
+
if (!autoplay || totalPages === 0) return;
|
|
439
|
+
const unsubscribe = addCompletionListener(() => {
|
|
440
|
+
const nextPage = wrap(0, totalPages, activePageIndex + 1);
|
|
441
|
+
reset();
|
|
442
|
+
goToPage(nextPage);
|
|
443
|
+
});
|
|
444
|
+
return unsubscribe;
|
|
445
|
+
}, [autoplay, addCompletionListener, activePageIndex, totalPages, goToPage, reset]);
|
|
417
446
|
const handleGoNext = useCallback(() => {
|
|
418
447
|
const nextPage = shouldLoop ? wrap(0, totalPages, activePageIndex + 1) : activePageIndex + 1;
|
|
419
448
|
goToPage(nextPage);
|
|
@@ -424,10 +453,12 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
424
453
|
}, [shouldLoop, totalPages, activePageIndex, goToPage]);
|
|
425
454
|
const handleDragStart = useCallback(() => {
|
|
426
455
|
onDragStart == null || onDragStart();
|
|
427
|
-
|
|
456
|
+
pause();
|
|
457
|
+
}, [onDragStart, pause]);
|
|
428
458
|
const handleDragEnd = useCallback(() => {
|
|
429
459
|
onDragEnd == null || onDragEnd();
|
|
430
|
-
|
|
460
|
+
resume();
|
|
461
|
+
}, [onDragEnd, resume]);
|
|
431
462
|
const handleDragTransition = useCallback(targetOffsetScroll => {
|
|
432
463
|
if (drag === 'none') return targetOffsetScroll;
|
|
433
464
|
if (isLoopingActive) {
|
|
@@ -435,6 +466,7 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
435
466
|
offset: nearestOffset,
|
|
436
467
|
index: pageIndex
|
|
437
468
|
} = findNearestLoopOffset(targetOffsetScroll, pageOffsets, loopLength);
|
|
469
|
+
if (pageIndex !== activePageIndex) reset();
|
|
438
470
|
updateActivePageIndex(pageIndex);
|
|
439
471
|
if (drag === 'snap') {
|
|
440
472
|
updateVisibleCarouselItems(pageOffsets[pageIndex]);
|
|
@@ -448,6 +480,7 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
448
480
|
// Non-looping logic with clamping
|
|
449
481
|
const clampedScrollOffset = clampWithElasticResistance(targetOffsetScroll, maxScrollOffset, 0);
|
|
450
482
|
const closestPageIndex = getNearestPageIndexFromOffset(clampedScrollOffset, pageOffsets);
|
|
483
|
+
if (closestPageIndex !== activePageIndex) reset();
|
|
451
484
|
updateActivePageIndex(closestPageIndex);
|
|
452
485
|
if (drag === 'snap') {
|
|
453
486
|
const snapOffset = pageOffsets[closestPageIndex];
|
|
@@ -457,7 +490,7 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
457
490
|
updateVisibleCarouselItems(clampedScrollOffset);
|
|
458
491
|
return targetOffsetScroll;
|
|
459
492
|
}
|
|
460
|
-
}, [drag, isLoopingActive, loopLength, maxScrollOffset, pageOffsets, updateVisibleCarouselItems, updateActivePageIndex]);
|
|
493
|
+
}, [drag, isLoopingActive, loopLength, maxScrollOffset, pageOffsets, activePageIndex, updateVisibleCarouselItems, updateActivePageIndex, reset]);
|
|
461
494
|
const panGesture = useMemo(() => Gesture.Pan()
|
|
462
495
|
// Only activate when horizontal movement exceeds threshold
|
|
463
496
|
.activeOffsetX([-10, 10])
|
|
@@ -595,49 +628,73 @@ export const Carousel = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref4, ref) =
|
|
|
595
628
|
unregisterItem,
|
|
596
629
|
visibleCarouselItems
|
|
597
630
|
}), [registerItem, unregisterItem, visibleCarouselItems]);
|
|
631
|
+
const autoplayContextValue = useMemo(() => {
|
|
632
|
+
return {
|
|
633
|
+
isEnabled: !!autoplay,
|
|
634
|
+
isStopped,
|
|
635
|
+
isPaused,
|
|
636
|
+
isPlaying,
|
|
637
|
+
interval: autoplayInterval,
|
|
638
|
+
getRemainingTime,
|
|
639
|
+
start,
|
|
640
|
+
stop,
|
|
641
|
+
toggle,
|
|
642
|
+
reset,
|
|
643
|
+
pause,
|
|
644
|
+
resume
|
|
645
|
+
};
|
|
646
|
+
}, [autoplay, isStopped, isPaused, isPlaying, autoplayInterval, getRemainingTime, start, stop, toggle, reset, pause, resume]);
|
|
598
647
|
return /*#__PURE__*/_jsx(CarouselContext.Provider, {
|
|
599
648
|
value: carouselContextValue,
|
|
600
|
-
children: /*#__PURE__*/
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
649
|
+
children: /*#__PURE__*/_jsx(CarouselAutoplayContext.Provider, {
|
|
650
|
+
value: autoplayContextValue,
|
|
651
|
+
children: /*#__PURE__*/_jsxs(VStack, _extends({
|
|
652
|
+
"aria-live": "polite",
|
|
653
|
+
"aria-roledescription": "carousel",
|
|
654
|
+
gap: 2,
|
|
655
|
+
role: "group",
|
|
656
|
+
style: containerStyle
|
|
657
|
+
}, props, {
|
|
658
|
+
children: [(title || !hideNavigation) && /*#__PURE__*/_jsxs(HStack, {
|
|
659
|
+
alignItems: "center",
|
|
660
|
+
justifyContent: title ? 'space-between' : 'flex-end',
|
|
661
|
+
children: [typeof title === 'string' ? /*#__PURE__*/_jsx(Text, {
|
|
662
|
+
font: "title3",
|
|
663
|
+
style: styles == null ? void 0 : styles.title,
|
|
664
|
+
children: title
|
|
665
|
+
}) : title, !hideNavigation && /*#__PURE__*/_jsx(NavigationComponent, {
|
|
666
|
+
autoplay: autoplay,
|
|
667
|
+
disableGoNext: totalPages <= 1 || !shouldLoop && activePageIndex >= totalPages - 1,
|
|
668
|
+
disableGoPrevious: totalPages <= 1 || !shouldLoop && activePageIndex <= 0,
|
|
669
|
+
isAutoplayStopped: isStopped,
|
|
670
|
+
nextPageAccessibilityLabel: nextPageAccessibilityLabel,
|
|
671
|
+
onGoNext: handleGoNext,
|
|
672
|
+
onGoPrevious: handleGoPrevious,
|
|
673
|
+
onToggleAutoplay: toggle,
|
|
674
|
+
previousPageAccessibilityLabel: previousPageAccessibilityLabel,
|
|
675
|
+
startAutoplayAccessibilityLabel: startAutoplayAccessibilityLabel,
|
|
676
|
+
stopAutoplayAccessibilityLabel: stopAutoplayAccessibilityLabel,
|
|
677
|
+
style: styles == null ? void 0 : styles.navigation
|
|
678
|
+
})]
|
|
679
|
+
}), /*#__PURE__*/_jsx(GestureDetector, {
|
|
680
|
+
gesture: panGesture,
|
|
681
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
682
|
+
onLayout: onLayout,
|
|
683
|
+
style: scrollViewStyle,
|
|
684
|
+
children: /*#__PURE__*/_jsx(animated.View, {
|
|
685
|
+
style: [animatedStyle, animatedTransform],
|
|
686
|
+
children: childrenWithClones
|
|
687
|
+
})
|
|
632
688
|
})
|
|
633
|
-
})
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
689
|
+
}), !hidePagination && /*#__PURE__*/_jsx(PaginationComponent, {
|
|
690
|
+
activePageIndex: activePageIndex,
|
|
691
|
+
onPressPage: goToPage,
|
|
692
|
+
paginationAccessibilityLabel: paginationAccessibilityLabel,
|
|
693
|
+
style: styles == null ? void 0 : styles.pagination,
|
|
694
|
+
totalPages: totalPages,
|
|
695
|
+
variant: paginationVariant
|
|
696
|
+
})]
|
|
697
|
+
}))
|
|
698
|
+
})
|
|
642
699
|
});
|
|
643
700
|
}));
|
|
@@ -6,4 +6,12 @@ export const useCarouselContext = () => {
|
|
|
6
6
|
throw new Error('useCarouselContext must be used within a Carousel component');
|
|
7
7
|
}
|
|
8
8
|
return context;
|
|
9
|
+
};
|
|
10
|
+
export const CarouselAutoplayContext = /*#__PURE__*/React.createContext(undefined);
|
|
11
|
+
export const useCarouselAutoplayContext = () => {
|
|
12
|
+
const context = useContext(CarouselAutoplayContext);
|
|
13
|
+
if (!context) {
|
|
14
|
+
throw new Error('useCarouselAutoplayContext must be used within a Carousel component');
|
|
15
|
+
}
|
|
16
|
+
return context;
|
|
9
17
|
};
|
|
@@ -4,7 +4,7 @@ import { useTheme } from '../hooks/useTheme';
|
|
|
4
4
|
import { HStack } from '../layout/HStack';
|
|
5
5
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
6
|
export const DefaultCarouselNavigation = /*#__PURE__*/memo(function DefaultCarouselNavigation(_ref) {
|
|
7
|
-
var _testIDMap$previousBu, _testIDMap$nextButton;
|
|
7
|
+
var _testIDMap$autoplayBu, _testIDMap$previousBu, _testIDMap$nextButton;
|
|
8
8
|
let {
|
|
9
9
|
onGoPrevious,
|
|
10
10
|
onGoNext,
|
|
@@ -12,10 +12,17 @@ export const DefaultCarouselNavigation = /*#__PURE__*/memo(function DefaultCarou
|
|
|
12
12
|
disableGoNext,
|
|
13
13
|
previousPageAccessibilityLabel = 'Previous page',
|
|
14
14
|
nextPageAccessibilityLabel = 'Next page',
|
|
15
|
+
autoplay,
|
|
16
|
+
isAutoplayStopped,
|
|
17
|
+
onToggleAutoplay,
|
|
18
|
+
startAutoplayAccessibilityLabel = 'Play Carousel',
|
|
19
|
+
stopAutoplayAccessibilityLabel = 'Pause Carousel',
|
|
15
20
|
variant = 'secondary',
|
|
16
21
|
compact,
|
|
17
22
|
previousIcon = 'caretLeft',
|
|
18
23
|
nextIcon = 'caretRight',
|
|
24
|
+
startIcon = 'play',
|
|
25
|
+
stopIcon = 'pause',
|
|
19
26
|
style,
|
|
20
27
|
styles,
|
|
21
28
|
testIDMap
|
|
@@ -29,7 +36,15 @@ export const DefaultCarouselNavigation = /*#__PURE__*/memo(function DefaultCarou
|
|
|
29
36
|
return /*#__PURE__*/_jsxs(HStack, {
|
|
30
37
|
gap: 1,
|
|
31
38
|
style: rootStyles,
|
|
32
|
-
children: [/*#__PURE__*/_jsx(IconButton, {
|
|
39
|
+
children: [autoplay && /*#__PURE__*/_jsx(IconButton, {
|
|
40
|
+
accessibilityLabel: isAutoplayStopped ? startAutoplayAccessibilityLabel : stopAutoplayAccessibilityLabel,
|
|
41
|
+
compact: compact,
|
|
42
|
+
name: isAutoplayStopped ? startIcon : stopIcon,
|
|
43
|
+
onPress: onToggleAutoplay,
|
|
44
|
+
style: styles == null ? void 0 : styles.autoplayButton,
|
|
45
|
+
testID: (_testIDMap$autoplayBu = testIDMap == null ? void 0 : testIDMap.autoplayButton) != null ? _testIDMap$autoplayBu : 'carousel-autoplay-button',
|
|
46
|
+
variant: variant
|
|
47
|
+
}), /*#__PURE__*/_jsx(IconButton, {
|
|
33
48
|
accessibilityLabel: previousPageAccessibilityLabel,
|
|
34
49
|
compact: compact,
|
|
35
50
|
disabled: disableGoPrevious,
|
|
@@ -1,49 +1,184 @@
|
|
|
1
|
-
import React, { memo, useMemo } from 'react';
|
|
1
|
+
import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { animated, useSpring } from '@react-spring/native';
|
|
2
3
|
import { useTheme } from '../hooks/useTheme';
|
|
3
4
|
import { HStack } from '../layout/HStack';
|
|
4
5
|
import { Pressable } from '../system/Pressable';
|
|
6
|
+
import { useCarouselAutoplayContext } from './CarouselContext';
|
|
5
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
-
|
|
8
|
+
const INDICATOR_ACTIVE_WIDTH = 24;
|
|
9
|
+
const INDICATOR_INACTIVE_WIDTH = 4;
|
|
10
|
+
const INDICATOR_HEIGHT = 4;
|
|
11
|
+
const PaginationPill = /*#__PURE__*/memo(function PaginationPill(_ref) {
|
|
12
|
+
let {
|
|
13
|
+
index,
|
|
14
|
+
isActive,
|
|
15
|
+
onPress,
|
|
16
|
+
accessibilityLabel,
|
|
17
|
+
style
|
|
18
|
+
} = _ref;
|
|
19
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
20
|
+
accessibilityLabel: accessibilityLabel,
|
|
21
|
+
background: isActive ? 'bgPrimary' : 'bgLine',
|
|
22
|
+
borderColor: "transparent",
|
|
23
|
+
borderRadius: 100,
|
|
24
|
+
height: INDICATOR_HEIGHT,
|
|
25
|
+
onPress: onPress,
|
|
26
|
+
style: style,
|
|
27
|
+
testID: "carousel-page-" + index,
|
|
28
|
+
width: INDICATOR_ACTIVE_WIDTH
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
const animationConfig = {
|
|
32
|
+
stiffness: 900,
|
|
33
|
+
damping: 120,
|
|
34
|
+
clamp: true
|
|
35
|
+
};
|
|
36
|
+
const PaginationDot = /*#__PURE__*/memo(function PaginationDot(_ref2) {
|
|
37
|
+
let {
|
|
38
|
+
index,
|
|
39
|
+
isActive,
|
|
40
|
+
onPress,
|
|
41
|
+
accessibilityLabel,
|
|
42
|
+
style
|
|
43
|
+
} = _ref2;
|
|
44
|
+
const theme = useTheme();
|
|
45
|
+
const autoplayContext = useCarouselAutoplayContext();
|
|
46
|
+
const {
|
|
47
|
+
isPlaying,
|
|
48
|
+
isEnabled,
|
|
49
|
+
interval,
|
|
50
|
+
getRemainingTime
|
|
51
|
+
} = autoplayContext;
|
|
52
|
+
const showProgress = isActive && isEnabled;
|
|
53
|
+
const springProps = useSpring({
|
|
54
|
+
width: isActive ? INDICATOR_ACTIVE_WIDTH : INDICATOR_INACTIVE_WIDTH,
|
|
55
|
+
backgroundColor: isActive && !showProgress ? theme.color.bgPrimary : theme.color.bgLine,
|
|
56
|
+
config: animationConfig
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Track progress animation state
|
|
60
|
+
const [progressState, setProgressState] = useState({
|
|
61
|
+
width: 0,
|
|
62
|
+
duration: 0
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Use a ref to track the last paused progress so we can resume from it
|
|
66
|
+
const lastProgressRef = useRef(0);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!showProgress) {
|
|
69
|
+
setProgressState({
|
|
70
|
+
width: 0,
|
|
71
|
+
duration: 0
|
|
72
|
+
});
|
|
73
|
+
lastProgressRef.current = 0;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const remainingTime = getRemainingTime();
|
|
77
|
+
if (!interval || interval <= 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const currentProgress = 1 - remainingTime / interval;
|
|
81
|
+
if (isPlaying) {
|
|
82
|
+
lastProgressRef.current = currentProgress;
|
|
83
|
+
setProgressState({
|
|
84
|
+
width: INDICATOR_ACTIVE_WIDTH,
|
|
85
|
+
duration: remainingTime
|
|
86
|
+
});
|
|
87
|
+
} else {
|
|
88
|
+
setProgressState({
|
|
89
|
+
width: currentProgress * INDICATOR_ACTIVE_WIDTH,
|
|
90
|
+
duration: 0
|
|
91
|
+
});
|
|
92
|
+
lastProgressRef.current = currentProgress;
|
|
93
|
+
}
|
|
94
|
+
}, [isPlaying, showProgress, interval, getRemainingTime]);
|
|
95
|
+
|
|
96
|
+
// Use spring with duration config for linear timed animation
|
|
97
|
+
// immediate: true when duration is 0 to force instant snap (not animated)
|
|
98
|
+
const progressSpring = useSpring({
|
|
99
|
+
width: progressState.width,
|
|
100
|
+
config: progressState.duration > 0 ? {
|
|
101
|
+
duration: progressState.duration
|
|
102
|
+
} : {
|
|
103
|
+
duration: 0
|
|
104
|
+
},
|
|
105
|
+
immediate: progressState.duration === 0
|
|
106
|
+
});
|
|
107
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
108
|
+
accessibilityLabel: accessibilityLabel,
|
|
109
|
+
borderColor: "transparent",
|
|
110
|
+
borderRadius: 100,
|
|
111
|
+
borderWidth: 0,
|
|
112
|
+
onPress: onPress,
|
|
113
|
+
overflow: "hidden",
|
|
114
|
+
style: style,
|
|
115
|
+
testID: "carousel-page-" + index,
|
|
116
|
+
children: /*#__PURE__*/_jsx(animated.View, {
|
|
117
|
+
style: {
|
|
118
|
+
width: springProps.width,
|
|
119
|
+
height: INDICATOR_HEIGHT,
|
|
120
|
+
backgroundColor: springProps.backgroundColor,
|
|
121
|
+
borderRadius: theme.borderRadius[100],
|
|
122
|
+
overflow: 'hidden'
|
|
123
|
+
},
|
|
124
|
+
children: showProgress && /*#__PURE__*/_jsx(animated.View, {
|
|
125
|
+
style: {
|
|
126
|
+
width: progressSpring.width,
|
|
127
|
+
height: '100%',
|
|
128
|
+
backgroundColor: theme.color.bgPrimary,
|
|
129
|
+
borderRadius: theme.borderRadius[100]
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
const defaultPaginationAccessibilityLabel = pageIndex => "Go to page " + (pageIndex + 1);
|
|
136
|
+
export const DefaultCarouselPagination = /*#__PURE__*/memo(function DefaultCarouselPagination(_ref3) {
|
|
7
137
|
let {
|
|
8
138
|
totalPages,
|
|
9
139
|
activePageIndex,
|
|
10
140
|
onPressPage,
|
|
11
141
|
style,
|
|
12
142
|
styles,
|
|
13
|
-
paginationAccessibilityLabel =
|
|
14
|
-
|
|
143
|
+
paginationAccessibilityLabel = defaultPaginationAccessibilityLabel,
|
|
144
|
+
variant = 'pill'
|
|
145
|
+
} = _ref3;
|
|
15
146
|
const theme = useTheme();
|
|
147
|
+
const isDot = variant === 'dot';
|
|
16
148
|
|
|
17
149
|
// Using paddingVertical here instead of HStack prop so it can be overridden by custom styles
|
|
18
150
|
const rootStyles = useMemo(() => [{
|
|
19
151
|
paddingVertical: theme.space[0.5]
|
|
20
152
|
}, style, styles == null ? void 0 : styles.root], [style, styles == null ? void 0 : styles.root, theme.space]);
|
|
153
|
+
const getAccessibilityLabel = index => typeof paginationAccessibilityLabel === 'function' ? paginationAccessibilityLabel(index) : paginationAccessibilityLabel;
|
|
21
154
|
return /*#__PURE__*/_jsx(HStack, {
|
|
22
155
|
gap: 0.5,
|
|
23
156
|
justifyContent: "center",
|
|
24
157
|
style: rootStyles,
|
|
25
158
|
children: totalPages > 0 ? Array.from({
|
|
26
159
|
length: totalPages
|
|
27
|
-
}, (_, index) => /*#__PURE__*/_jsx(
|
|
28
|
-
accessibilityLabel:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
160
|
+
}, (_, index) => isDot ? /*#__PURE__*/_jsx(PaginationDot, {
|
|
161
|
+
accessibilityLabel: getAccessibilityLabel(index),
|
|
162
|
+
index: index,
|
|
163
|
+
isActive: index === activePageIndex,
|
|
164
|
+
onPress: () => onPressPage(index),
|
|
165
|
+
style: styles == null ? void 0 : styles.dot
|
|
166
|
+
}, index) : /*#__PURE__*/_jsx(PaginationPill, {
|
|
167
|
+
accessibilityLabel: getAccessibilityLabel(index),
|
|
168
|
+
index: index,
|
|
169
|
+
isActive: index === activePageIndex,
|
|
33
170
|
onPress: () => onPressPage(index),
|
|
34
|
-
style: styles == null ? void 0 : styles.dot
|
|
35
|
-
testID: "carousel-page-" + index,
|
|
36
|
-
width: 24
|
|
171
|
+
style: styles == null ? void 0 : styles.dot
|
|
37
172
|
}, index)) : /*#__PURE__*/_jsx(Pressable, {
|
|
38
173
|
disabled: true,
|
|
39
174
|
background: "bgLine",
|
|
40
175
|
borderColor: "transparent",
|
|
41
176
|
borderRadius: 100,
|
|
42
|
-
height:
|
|
177
|
+
height: INDICATOR_HEIGHT,
|
|
43
178
|
style: [{
|
|
44
179
|
opacity: 0
|
|
45
180
|
}, styles == null ? void 0 : styles.dot],
|
|
46
|
-
width:
|
|
181
|
+
width: isDot ? INDICATOR_INACTIVE_WIDTH : INDICATOR_ACTIVE_WIDTH
|
|
47
182
|
})
|
|
48
183
|
});
|
|
49
184
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Carousel, CarouselItem } from '@coinbase/cds-mobile/carousel';
|
|
2
|
+
import figma from '@figma/code-connect/react';
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
+
figma.connect(Carousel, 'https://www.figma.com/design/k5CtyJccNQUGMI5bI4lJ2g/%E2%9C%A8-CDS-Components?node-id=48671-10433', {
|
|
5
|
+
imports: ["import { Carousel, CarouselItem } from '@coinbase/cds-mobile/carousel'"],
|
|
6
|
+
example: () => /*#__PURE__*/_jsxs(Carousel, {
|
|
7
|
+
children: [/*#__PURE__*/_jsx(CarouselItem, {
|
|
8
|
+
id: "1"
|
|
9
|
+
}), /*#__PURE__*/_jsx(CarouselItem, {
|
|
10
|
+
id: "2"
|
|
11
|
+
}), /*#__PURE__*/_jsx(CarouselItem, {
|
|
12
|
+
id: "3"
|
|
13
|
+
})]
|
|
14
|
+
})
|
|
15
|
+
});
|
|
@@ -101,7 +101,8 @@ const SeeAllComponent = () => /*#__PURE__*/_jsx(Text, {
|
|
|
101
101
|
const SquareAssetCard = _ref2 => {
|
|
102
102
|
let {
|
|
103
103
|
imageUrl,
|
|
104
|
-
name
|
|
104
|
+
name,
|
|
105
|
+
onPress
|
|
105
106
|
} = _ref2;
|
|
106
107
|
return /*#__PURE__*/_jsx(ContainedAssetCard, {
|
|
107
108
|
description: /*#__PURE__*/_jsx(Text, {
|
|
@@ -116,6 +117,7 @@ const SquareAssetCard = _ref2 => {
|
|
|
116
117
|
style: styles.assetImage,
|
|
117
118
|
width: 32
|
|
118
119
|
}),
|
|
120
|
+
onPress: onPress,
|
|
119
121
|
subtitle: name,
|
|
120
122
|
title: "$0.87"
|
|
121
123
|
});
|
|
@@ -132,6 +134,8 @@ const BasicExamples = () => {
|
|
|
132
134
|
children: [/*#__PURE__*/_jsx(Example, {
|
|
133
135
|
paddingX: 0,
|
|
134
136
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
137
|
+
autoplay: true,
|
|
138
|
+
paginationVariant: "dot",
|
|
135
139
|
styles: {
|
|
136
140
|
root: {
|
|
137
141
|
paddingHorizontal: horizontalPadding
|
|
@@ -151,6 +155,7 @@ const BasicExamples = () => {
|
|
|
151
155
|
paddingX: 0,
|
|
152
156
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
153
157
|
drag: "snap",
|
|
158
|
+
paginationVariant: "dot",
|
|
154
159
|
snapMode: "item",
|
|
155
160
|
styles: {
|
|
156
161
|
root: {
|
|
@@ -173,8 +178,10 @@ const BasicExamples = () => {
|
|
|
173
178
|
}), /*#__PURE__*/_jsx(Example, {
|
|
174
179
|
paddingX: 0,
|
|
175
180
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
181
|
+
loop: true,
|
|
176
182
|
NavigationComponent: SeeAllComponent,
|
|
177
183
|
drag: "free",
|
|
184
|
+
paginationVariant: "dot",
|
|
178
185
|
snapMode: "item",
|
|
179
186
|
styles: {
|
|
180
187
|
root: {
|
|
@@ -186,10 +193,12 @@ const BasicExamples = () => {
|
|
|
186
193
|
},
|
|
187
194
|
title: "Square Items Carousel",
|
|
188
195
|
children: Object.values(assets).map(asset => /*#__PURE__*/_jsx(CarouselItem, {
|
|
196
|
+
accessibilityLabel: asset.name,
|
|
189
197
|
id: asset.symbol,
|
|
190
198
|
children: /*#__PURE__*/_jsx(SquareAssetCard, {
|
|
191
199
|
imageUrl: asset.imageUrl,
|
|
192
|
-
name: asset.symbol
|
|
200
|
+
name: asset.symbol,
|
|
201
|
+
onPress: () => console.log(asset.symbol + " clicked")
|
|
193
202
|
})
|
|
194
203
|
}, asset.symbol))
|
|
195
204
|
})
|
|
@@ -197,6 +206,7 @@ const BasicExamples = () => {
|
|
|
197
206
|
paddingX: 0,
|
|
198
207
|
children: /*#__PURE__*/_jsxs(Carousel, {
|
|
199
208
|
drag: "snap",
|
|
209
|
+
paginationVariant: "dot",
|
|
200
210
|
snapMode: "page",
|
|
201
211
|
styles: {
|
|
202
212
|
root: {
|
|
@@ -233,6 +243,7 @@ const BasicExamples = () => {
|
|
|
233
243
|
paddingX: 0,
|
|
234
244
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
235
245
|
drag: "none",
|
|
246
|
+
paginationVariant: "dot",
|
|
236
247
|
styles: {
|
|
237
248
|
root: {
|
|
238
249
|
paddingHorizontal: horizontalPadding
|
|
@@ -378,6 +389,35 @@ const CustomComponentsExample = () => {
|
|
|
378
389
|
})
|
|
379
390
|
});
|
|
380
391
|
};
|
|
392
|
+
const AutoplayExample = () => {
|
|
393
|
+
const theme = useTheme();
|
|
394
|
+
return /*#__PURE__*/_jsx(Example, {
|
|
395
|
+
paddingX: 0,
|
|
396
|
+
children: /*#__PURE__*/_jsx(Carousel, {
|
|
397
|
+
autoplay: true,
|
|
398
|
+
loop: true,
|
|
399
|
+
paginationVariant: "dot",
|
|
400
|
+
styles: {
|
|
401
|
+
root: {
|
|
402
|
+
paddingHorizontal: theme.space[2]
|
|
403
|
+
},
|
|
404
|
+
carousel: {
|
|
405
|
+
gap: theme.space[1]
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
title: "Autoplay Carousel",
|
|
409
|
+
children: Object.values(assets).map(asset => /*#__PURE__*/_jsx(CarouselItem, {
|
|
410
|
+
accessibilityLabel: asset.name,
|
|
411
|
+
id: asset.symbol,
|
|
412
|
+
children: /*#__PURE__*/_jsx(SquareAssetCard, {
|
|
413
|
+
imageUrl: asset.imageUrl,
|
|
414
|
+
name: asset.symbol,
|
|
415
|
+
onPress: () => console.log(asset.symbol + " clicked")
|
|
416
|
+
})
|
|
417
|
+
}, asset.symbol))
|
|
418
|
+
})
|
|
419
|
+
});
|
|
420
|
+
};
|
|
381
421
|
const DynamicContentExample = () => {
|
|
382
422
|
const theme = useTheme();
|
|
383
423
|
const [items, setItems] = useState(Object.values(assets).slice(0, 3));
|
|
@@ -405,6 +445,7 @@ const DynamicContentExample = () => {
|
|
|
405
445
|
children: "Remove Last"
|
|
406
446
|
})]
|
|
407
447
|
}), /*#__PURE__*/_jsx(Carousel, {
|
|
448
|
+
paginationVariant: "dot",
|
|
408
449
|
styles: {
|
|
409
450
|
root: {
|
|
410
451
|
paddingHorizontal: theme.space[3]
|
|
@@ -416,10 +457,12 @@ const DynamicContentExample = () => {
|
|
|
416
457
|
},
|
|
417
458
|
title: "Explore Assets",
|
|
418
459
|
children: items.map(asset => /*#__PURE__*/_jsx(CarouselItem, {
|
|
460
|
+
accessibilityLabel: asset.name,
|
|
419
461
|
id: asset.symbol,
|
|
420
462
|
children: /*#__PURE__*/_jsx(SquareAssetCard, {
|
|
421
463
|
imageUrl: asset.imageUrl,
|
|
422
|
-
name: asset.symbol
|
|
464
|
+
name: asset.symbol,
|
|
465
|
+
onPress: () => console.log(asset.symbol + " clicked")
|
|
423
466
|
})
|
|
424
467
|
}, asset.symbol))
|
|
425
468
|
})]
|
|
@@ -427,7 +470,7 @@ const DynamicContentExample = () => {
|
|
|
427
470
|
};
|
|
428
471
|
const AnimatedExample = () => {
|
|
429
472
|
const theme = useTheme();
|
|
430
|
-
const
|
|
473
|
+
const AnimatedSquareAssetCard = /*#__PURE__*/memo(_ref4 => {
|
|
431
474
|
let {
|
|
432
475
|
imageUrl,
|
|
433
476
|
name
|
|
@@ -485,6 +528,7 @@ const AnimatedExample = () => {
|
|
|
485
528
|
return /*#__PURE__*/_jsx(Example, {
|
|
486
529
|
paddingX: 0,
|
|
487
530
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
531
|
+
paginationVariant: "dot",
|
|
488
532
|
styles: {
|
|
489
533
|
root: {
|
|
490
534
|
paddingHorizontal: theme.space[3]
|
|
@@ -493,10 +537,11 @@ const AnimatedExample = () => {
|
|
|
493
537
|
gap: theme.space[1]
|
|
494
538
|
}
|
|
495
539
|
},
|
|
496
|
-
title: "
|
|
540
|
+
title: "Animated Selection",
|
|
497
541
|
children: Object.values(assets).map(asset => /*#__PURE__*/_jsx(CarouselItem, {
|
|
542
|
+
accessibilityLabel: asset.name,
|
|
498
543
|
id: asset.symbol,
|
|
499
|
-
children: /*#__PURE__*/_jsx(
|
|
544
|
+
children: /*#__PURE__*/_jsx(AnimatedSquareAssetCard, {
|
|
500
545
|
imageUrl: asset.imageUrl,
|
|
501
546
|
name: asset.symbol
|
|
502
547
|
})
|
|
@@ -603,13 +648,14 @@ const ImperativeApiExample = () => {
|
|
|
603
648
|
gap: theme.space[1]
|
|
604
649
|
}
|
|
605
650
|
},
|
|
606
|
-
title: "
|
|
651
|
+
title: "Imperative API",
|
|
607
652
|
children: Object.values(assets).map(asset => /*#__PURE__*/_jsx(CarouselItem, {
|
|
608
653
|
accessibilityLabel: asset.name,
|
|
609
654
|
id: asset.symbol,
|
|
610
655
|
children: /*#__PURE__*/_jsx(SquareAssetCard, {
|
|
611
656
|
imageUrl: asset.imageUrl,
|
|
612
|
-
name: asset.symbol
|
|
657
|
+
name: asset.symbol,
|
|
658
|
+
onPress: () => console.log(asset.symbol + " clicked")
|
|
613
659
|
})
|
|
614
660
|
}, asset.symbol))
|
|
615
661
|
})]
|
|
@@ -629,6 +675,7 @@ const LoopingExamples = () => {
|
|
|
629
675
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
630
676
|
loop: true,
|
|
631
677
|
drag: "snap",
|
|
678
|
+
paginationVariant: "dot",
|
|
632
679
|
snapMode: "page",
|
|
633
680
|
styles: {
|
|
634
681
|
root: {
|
|
@@ -648,8 +695,10 @@ const LoopingExamples = () => {
|
|
|
648
695
|
}), /*#__PURE__*/_jsx(Example, {
|
|
649
696
|
paddingX: 0,
|
|
650
697
|
children: /*#__PURE__*/_jsx(Carousel, {
|
|
698
|
+
autoplay: true,
|
|
651
699
|
loop: true,
|
|
652
700
|
drag: "snap",
|
|
701
|
+
paginationVariant: "dot",
|
|
653
702
|
snapMode: "item",
|
|
654
703
|
styles: {
|
|
655
704
|
root: {
|
|
@@ -659,7 +708,7 @@ const LoopingExamples = () => {
|
|
|
659
708
|
gap: horizontalGap
|
|
660
709
|
}
|
|
661
710
|
},
|
|
662
|
-
title: "Looping - Snap Item",
|
|
711
|
+
title: "Looping with Autoplay - Snap Item",
|
|
663
712
|
children: sampleItems.map((item, index) => /*#__PURE__*/_jsx(CarouselItem, {
|
|
664
713
|
id: "loop-item-" + index,
|
|
665
714
|
width: threeItemsWidth,
|
|
@@ -680,7 +729,7 @@ const LoopingExamples = () => {
|
|
|
680
729
|
gap: horizontalGap
|
|
681
730
|
}
|
|
682
731
|
},
|
|
683
|
-
title: "Looping - Free Drag",
|
|
732
|
+
title: "Looping - Free Drag (visreg)",
|
|
684
733
|
children: sampleItems.map((item, index) => /*#__PURE__*/_jsx(CarouselItem, {
|
|
685
734
|
id: "loop-free-" + index,
|
|
686
735
|
width: threeItemsWidth,
|
|
@@ -811,6 +860,6 @@ const AnimatedPaginationExample = () => {
|
|
|
811
860
|
export default function CarouselScreen() {
|
|
812
861
|
return /*#__PURE__*/_jsxs(ExampleScreen, {
|
|
813
862
|
paddingX: 0,
|
|
814
|
-
children: [/*#__PURE__*/_jsx(BasicExamples, {}), /*#__PURE__*/_jsx(CustomComponentsExample, {}), /*#__PURE__*/_jsx(DynamicContentExample, {}), /*#__PURE__*/_jsx(AnimatedExample, {}), /*#__PURE__*/_jsx(ImperativeApiExample, {}), /*#__PURE__*/_jsx(AnimatedPaginationExample, {}), /*#__PURE__*/_jsx(LoopingExamples, {})]
|
|
863
|
+
children: [/*#__PURE__*/_jsx(BasicExamples, {}), /*#__PURE__*/_jsx(CustomComponentsExample, {}), /*#__PURE__*/_jsx(DynamicContentExample, {}), /*#__PURE__*/_jsx(AnimatedExample, {}), /*#__PURE__*/_jsx(ImperativeApiExample, {}), /*#__PURE__*/_jsx(AnimatedPaginationExample, {}), /*#__PURE__*/_jsx(LoopingExamples, {}), /*#__PURE__*/_jsx(AutoplayExample, {})]
|
|
815
864
|
});
|
|
816
865
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coinbase/cds-mobile",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.43.0",
|
|
4
4
|
"description": "Coinbase Design System - Mobile",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -198,8 +198,8 @@
|
|
|
198
198
|
"react-native-svg": "^14.1.0"
|
|
199
199
|
},
|
|
200
200
|
"dependencies": {
|
|
201
|
-
"@coinbase/cds-common": "^8.
|
|
202
|
-
"@coinbase/cds-icons": "^5.
|
|
201
|
+
"@coinbase/cds-common": "^8.43.0",
|
|
202
|
+
"@coinbase/cds-icons": "^5.11.0",
|
|
203
203
|
"@coinbase/cds-illustrations": "^4.31.0",
|
|
204
204
|
"@coinbase/cds-lottie-files": "^3.3.4",
|
|
205
205
|
"@coinbase/cds-utils": "^2.3.5",
|