@lookiero/checkout 3.9.0 → 3.10.0-beta.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/dist/infrastructure/ui/components/layouts/layout/dummyLayout/DummyLayout.js +7 -5
- package/dist/infrastructure/ui/components/layouts/layout/dummyLayout/useScrollViewRef.d.ts +15 -0
- package/dist/infrastructure/ui/components/layouts/layout/dummyLayout/useScrollViewRef.js +14 -0
- package/dist/infrastructure/ui/components/layouts/tabs/Tabs.d.ts +6 -4
- package/dist/infrastructure/ui/components/layouts/tabs/Tabs.js +9 -11
- package/dist/infrastructure/ui/components/layouts/tabs/Tabs.style.d.ts +1 -0
- package/dist/infrastructure/ui/components/layouts/tabs/Tabs.style.js +1 -0
- package/dist/infrastructure/ui/hooks/useSubmitCheckout.d.ts +1 -1
- package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.style.js +3 -3
- package/dist/infrastructure/ui/views/item/components/productVariantDescription/ProductVariantDescription.style.d.ts +2 -1
- package/dist/infrastructure/ui/views/item/components/productVariantDescription/ProductVariantDescription.style.js +4 -3
- package/dist/infrastructure/ui/views/item/components/productVariantSlider/ProductVariantSlider.js +16 -15
- package/dist/infrastructure/ui/views/item/components/productVariantSlider/ProductVariantSlider.style.d.ts +3 -0
- package/dist/infrastructure/ui/views/item/components/productVariantSlider/ProductVariantSlider.style.js +4 -1
- package/dist/infrastructure/ui/views/item/views/productVariant/ProductVariant.js +5 -5
- package/dist/infrastructure/ui/views/item/views/productVariant/ProductVariant.style.d.ts +0 -4
- package/dist/infrastructure/ui/views/item/views/productVariant/ProductVariant.style.js +0 -4
- package/dist/infrastructure/ui/views/summaryTabs/components/checkoutItemsTabs/CheckoutItemsTabs.js +6 -6
- package/dist/shared/ui/components/layouts/carousel/Bullets.d.ts +10 -0
- package/dist/shared/ui/components/layouts/carousel/Bullets.js +28 -0
- package/dist/shared/ui/components/layouts/carousel/Bullets.style.d.ts +12 -0
- package/dist/shared/ui/components/layouts/carousel/Bullets.style.js +15 -0
- package/dist/shared/ui/components/layouts/carousel/Carousel.d.ts +32 -0
- package/dist/shared/ui/components/layouts/carousel/Carousel.js +87 -0
- package/dist/shared/ui/components/layouts/carousel/Carousel.style.d.ts +24 -0
- package/dist/shared/ui/components/layouts/carousel/Carousel.style.js +25 -0
- package/dist/shared/ui/components/layouts/carousel/Carousel2.d.ts +30 -0
- package/dist/shared/ui/components/layouts/carousel/Carousel2.js +79 -0
- package/dist/shared/ui/components/layouts/carousel/DragComponent.d.ts +3 -0
- package/dist/shared/ui/components/layouts/carousel/DragComponent.js +48 -0
- package/dist/shared/ui/components/layouts/slider/Bullets.d.ts +10 -0
- package/dist/shared/ui/components/layouts/slider/Bullets.js +28 -0
- package/dist/shared/ui/components/layouts/slider/Bullets.style.d.ts +12 -0
- package/dist/shared/ui/components/layouts/slider/Bullets.style.js +15 -0
- package/dist/shared/ui/components/layouts/slider/Bullets2.d.ts +10 -0
- package/dist/shared/ui/components/layouts/slider/Bullets2.js +30 -0
- package/dist/shared/ui/components/layouts/slider/Slider.d.ts +0 -5
- package/dist/shared/ui/components/layouts/slider/Slider.js +4 -4
- package/dist/shared/ui/components/layouts/slider/SliderDots.d.ts +8 -0
- package/dist/shared/ui/components/layouts/slider/SliderDots.js +16 -0
- package/dist/shared/ui/components/layouts/slider/SliderDots.style.d.ts +12 -0
- package/dist/shared/ui/components/layouts/slider/SliderDots.style.js +15 -0
- package/dist/shared/ui/components/layouts/sticky/Sticky.js +1 -3
- package/dist/shared/ui/components/layouts/sticky/Sticky.style.d.ts +3 -0
- package/dist/shared/ui/components/layouts/sticky/Sticky.style.js +3 -2
- package/package.json +6 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable react/prop-types */
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { View } from "react-native";
|
|
4
|
+
import { GestureHandlerRootView, ScrollView as RNGHScrollView } from "react-native-gesture-handler";
|
|
4
5
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
5
6
|
import { Footer as DefaultFooter } from "../../../templates/footer/Footer";
|
|
6
7
|
import { DefaultHeader } from "../../../templates/header/defaultHeader/DefaultHeader";
|
|
@@ -8,9 +9,10 @@ import { Footer } from "../components/footer/Footer";
|
|
|
8
9
|
import { Header } from "../components/header/Header";
|
|
9
10
|
import { style } from "./DummyLayout.style";
|
|
10
11
|
const DummyLayout = ({ children, header = React.createElement(DefaultHeader, null), footer = React.createElement(DefaultFooter, null), panel, style: customStyle, scrollEnabled, onLayout, }) => (React.createElement(SafeAreaView, { style: [style.safeAreaView, customStyle?.safeAreaView] },
|
|
11
|
-
React.createElement(
|
|
12
|
-
React.createElement(
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
React.createElement(GestureHandlerRootView, { style: { flex: 1 } },
|
|
13
|
+
React.createElement(RNGHScrollView, { contentContainerStyle: [style.scrollView, customStyle?.scrollView], scrollEnabled: scrollEnabled, scrollEventThrottle: 16, showsVerticalScrollIndicator: false, stickyHeaderIndices: [0] },
|
|
14
|
+
React.createElement(Header, null, header),
|
|
15
|
+
panel,
|
|
16
|
+
React.createElement(View, { style: style.children, onLayout: onLayout }, children))),
|
|
15
17
|
React.createElement(Footer, null, footer)));
|
|
16
18
|
export { DummyLayout };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FC, ReactNode, Ref } from "react";
|
|
2
|
+
import { GestureType, ScrollView } from "react-native-gesture-handler";
|
|
3
|
+
interface ContextShape {
|
|
4
|
+
readonly scrollViewRef: Ref<ScrollView>;
|
|
5
|
+
readonly panGestureRef: Ref<GestureType>;
|
|
6
|
+
}
|
|
7
|
+
interface ScrollViewRefContextProviderProps {
|
|
8
|
+
readonly children: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
declare const ScrollViewRefContextProvider: FC<ScrollViewRefContextProviderProps>;
|
|
11
|
+
interface UseScrollViewRefFunction {
|
|
12
|
+
(): ContextShape;
|
|
13
|
+
}
|
|
14
|
+
declare const useScrollViewRef: UseScrollViewRefFunction;
|
|
15
|
+
export { useScrollViewRef, ScrollViewRefContextProvider };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { createContext, useContext, useRef } from "react";
|
|
2
|
+
import invariant from "tiny-invariant";
|
|
3
|
+
const ScrollViewRefContext = createContext(null);
|
|
4
|
+
const ScrollViewRefContextProvider = ({ children }) => {
|
|
5
|
+
const scrollViewRef = useRef(null);
|
|
6
|
+
const panGestureRef = useRef(null);
|
|
7
|
+
return (React.createElement(ScrollViewRefContext.Provider, { value: { scrollViewRef, panGestureRef } }, children));
|
|
8
|
+
};
|
|
9
|
+
const useScrollViewRef = () => {
|
|
10
|
+
const ref = useContext(ScrollViewRefContext);
|
|
11
|
+
invariant(ref, "Your are trying to use the useScrollViewRef hook without wrapping your app with the <ScrollViewRefContextProvider>.");
|
|
12
|
+
return ref;
|
|
13
|
+
};
|
|
14
|
+
export { useScrollViewRef, ScrollViewRefContextProvider };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
2
|
import { StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
3
|
+
import { RenderItemFunction } from "../../../../../shared/ui/components/layouts/carousel/Carousel";
|
|
3
4
|
interface TabStyle {
|
|
4
5
|
readonly tab: StyleProp<ViewStyle>;
|
|
5
6
|
readonly tabText: StyleProp<TextStyle>;
|
|
@@ -14,13 +15,14 @@ interface TabsStyle {
|
|
|
14
15
|
readonly sliderContainer: StyleProp<ViewStyle>;
|
|
15
16
|
readonly tabList: Partial<TabListStyle>;
|
|
16
17
|
}
|
|
17
|
-
interface TabsProps {
|
|
18
|
-
readonly
|
|
18
|
+
interface TabsProps<T> {
|
|
19
|
+
readonly data: T[];
|
|
20
|
+
readonly children: RenderItemFunction<T>;
|
|
19
21
|
readonly defaultIndex?: number;
|
|
20
22
|
readonly tabLabels: string[];
|
|
21
23
|
readonly style?: Partial<TabsStyle>;
|
|
22
24
|
readonly onChanged?: (index: number) => void;
|
|
23
25
|
readonly tabLabelsWrapper?: (children: ReactNode) => ReactNode;
|
|
24
26
|
}
|
|
25
|
-
declare const Tabs:
|
|
27
|
+
declare const Tabs: <T>({ data, children, defaultIndex, tabLabels, style: customStyle, onChanged, tabLabelsWrapper, }: TabsProps<T>) => JSX.Element;
|
|
26
28
|
export { Tabs };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { COLOR, Text } from "@lookiero/aurora";
|
|
2
2
|
import { animated, useSpring } from "@react-spring/native";
|
|
3
|
-
import React, {
|
|
3
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
4
4
|
import { Pressable, View } from "react-native";
|
|
5
5
|
import invariant from "tiny-invariant";
|
|
6
|
-
import {
|
|
6
|
+
import { Carousel } from "../../../../../shared/ui/components/layouts/carousel/Carousel";
|
|
7
7
|
import { style } from "./Tabs.style";
|
|
8
8
|
const Tab = ({ children, active, disabled = false, style: customStyle, onPress, onLayout }) => (React.createElement(Pressable, { disabled: disabled, style: [style.tab, customStyle?.tab], testID: "tab", onLayout: onLayout, onPress: onPress },
|
|
9
9
|
React.createElement(Text, { color: active ? COLOR.CONTENT : COLOR.GRAYSCALE_L, level: 2, style: customStyle?.tabText, detail: true }, children)));
|
|
@@ -18,8 +18,8 @@ const TabList = ({ labels = [], tabIndex = 0, style: customStyle, onSelect }) =>
|
|
|
18
18
|
...prevState.slice(index),
|
|
19
19
|
]), []);
|
|
20
20
|
const springs = useSpring({
|
|
21
|
-
width: tabItemPositions[tabIndex]?.width,
|
|
22
|
-
left: tabItemPositions[tabIndex]?.position,
|
|
21
|
+
width: tabItemPositions[tabIndex]?.width || 0,
|
|
22
|
+
left: tabItemPositions[tabIndex]?.position || 0,
|
|
23
23
|
});
|
|
24
24
|
return (React.createElement(View, { style: [style.tabs, customStyle?.tabList], testID: "tab-list" },
|
|
25
25
|
labels.map((item, index) => (React.createElement(Tab, { key: index, active: tabIndex === index, style: customStyle?.tab, onLayout: (event) => handleOnLayout(event, index), onPress: () => onSelect?.(index) }, item))),
|
|
@@ -27,21 +27,19 @@ const TabList = ({ labels = [], tabIndex = 0, style: customStyle, onSelect }) =>
|
|
|
27
27
|
style.indicator,
|
|
28
28
|
{
|
|
29
29
|
width: springs.width,
|
|
30
|
-
|
|
30
|
+
transform: [{ translateX: springs.left }],
|
|
31
31
|
},
|
|
32
32
|
customStyle?.indicator,
|
|
33
33
|
] })));
|
|
34
34
|
};
|
|
35
|
-
const Tabs = ({ children, defaultIndex = 0, tabLabels, style: customStyle, onChanged, tabLabelsWrapper = (children) => children, }) => {
|
|
36
|
-
invariant(
|
|
35
|
+
const Tabs = ({ data, children, defaultIndex = 0, tabLabels, style: customStyle, onChanged, tabLabelsWrapper = (children) => children, }) => {
|
|
36
|
+
invariant(data.length === tabLabels.length, "data and tab labels must be the same length");
|
|
37
37
|
const [active, setActive] = useState(defaultIndex);
|
|
38
38
|
const handleOnActiveChanged = useCallback((activeIndex) => setActive(activeIndex), []);
|
|
39
|
-
useEffect(() =>
|
|
40
|
-
onChanged?.(active);
|
|
41
|
-
}, [active, onChanged]);
|
|
39
|
+
useEffect(() => onChanged?.(active), [active, onChanged]);
|
|
42
40
|
return (React.createElement(View, { style: [style.container, customStyle?.tabContainer], testID: "tabs" },
|
|
43
41
|
tabLabelsWrapper(React.createElement(TabList, { labels: tabLabels, style: customStyle?.tabList, tabIndex: active, onSelect: handleOnActiveChanged })),
|
|
44
42
|
React.createElement(View, { style: customStyle?.sliderContainer },
|
|
45
|
-
React.createElement(
|
|
43
|
+
React.createElement(Carousel, { activeIndex: active, data: data, enabled: false, onActiveIndexChanged: handleOnActiveChanged }, children))));
|
|
46
44
|
};
|
|
47
45
|
export { Tabs };
|
|
@@ -23,5 +23,5 @@ interface UseSubmitCheckoutFunction {
|
|
|
23
23
|
(args: UseSubmitCheckoutFunctionArgs): UseSubmitCheckoutResult;
|
|
24
24
|
}
|
|
25
25
|
declare const useSubmitCheckout: UseSubmitCheckoutFunction;
|
|
26
|
-
export type { Status };
|
|
26
|
+
export type { Status, SubmitCheckoutFunction };
|
|
27
27
|
export { useSubmitCheckout };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
2
|
import { theme } from "../../../../theme/theme";
|
|
3
|
-
const { colorGrayscaleL,
|
|
3
|
+
const { colorGrayscaleL, spaceM, spaceXL } = theme();
|
|
4
4
|
const style = StyleSheet.create({
|
|
5
5
|
buttonText: {
|
|
6
6
|
width: "100%",
|
|
@@ -17,11 +17,11 @@ const style = StyleSheet.create({
|
|
|
17
17
|
row: {
|
|
18
18
|
alignItems: "center",
|
|
19
19
|
flexDirection: "row",
|
|
20
|
-
marginTop:
|
|
20
|
+
marginTop: spaceM,
|
|
21
21
|
},
|
|
22
22
|
sizeSelector: {
|
|
23
23
|
flex: 1,
|
|
24
|
-
marginRight:
|
|
24
|
+
marginRight: spaceM,
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
27
|
export { style };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
2
|
import { theme } from "../../../../theme/theme";
|
|
3
|
-
const {
|
|
3
|
+
const { spaceXS, spaceL } = theme();
|
|
4
4
|
const style = StyleSheet.create({
|
|
5
5
|
container: {
|
|
6
6
|
width: "100%",
|
|
7
7
|
},
|
|
8
8
|
name: {
|
|
9
|
-
marginVertical:
|
|
9
|
+
marginVertical: spaceXS,
|
|
10
10
|
},
|
|
11
11
|
size: {
|
|
12
|
-
|
|
12
|
+
marginBottom: spaceXS,
|
|
13
|
+
marginTop: spaceL,
|
|
13
14
|
},
|
|
14
15
|
});
|
|
15
16
|
export { style };
|
package/dist/infrastructure/ui/views/item/components/productVariantSlider/ProductVariantSlider.js
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import React, { useCallback, useState } from "react";
|
|
2
|
-
import { Image } from "react-native";
|
|
3
|
-
import {
|
|
2
|
+
import { Image, View } from "react-native";
|
|
3
|
+
import { AspectRatioView } from "../../../../../../shared/ui/components/atoms/aspectRatioView/AspectRatioView";
|
|
4
|
+
import { Bullets } from "../../../../../../shared/ui/components/layouts/carousel/Bullets";
|
|
5
|
+
import { Carousel, } from "../../../../../../shared/ui/components/layouts/carousel/Carousel";
|
|
4
6
|
import { useMediaImage } from "../../../../hooks/useMediaImage";
|
|
5
7
|
import { style } from "./ProductVariantSlider.style";
|
|
6
8
|
const ProductVariantSlider = ({ producVariantMedia, onChanged }) => {
|
|
7
9
|
const cdnImageUrl = useMediaImage();
|
|
8
|
-
const [
|
|
10
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
9
11
|
const handleOnActiveChanged = useCallback((activeIndex) => {
|
|
10
|
-
|
|
12
|
+
setActiveIndex(activeIndex);
|
|
11
13
|
onChanged?.(activeIndex);
|
|
12
14
|
}, [onChanged]);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
} })))));
|
|
15
|
+
const renderItem = useCallback(({ item }) => (React.createElement(View, { style: style.slide },
|
|
16
|
+
React.createElement(AspectRatioView, { aspectRatio: 4 / 3 },
|
|
17
|
+
React.createElement(Image, { resizeMode: "contain", style: style.image, testID: "product-variant-image", source: {
|
|
18
|
+
uri: cdnImageUrl({
|
|
19
|
+
url: item.url,
|
|
20
|
+
width: 600,
|
|
21
|
+
}),
|
|
22
|
+
} })))), [cdnImageUrl]);
|
|
23
|
+
const renderBullets = useCallback(({ activeIndex, count, onChange }) => React.createElement(Bullets, { activeIndex: activeIndex, count: count, onChange: onChange }), []);
|
|
24
|
+
return (React.createElement(Carousel, { activeIndex: activeIndex, bullets: renderBullets, data: producVariantMedia, onActiveIndexChanged: handleOnActiveChanged }, renderItem));
|
|
24
25
|
};
|
|
25
26
|
export { ProductVariantSlider };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
2
|
import { theme } from "../../../../theme/theme";
|
|
3
|
-
const { colorBase, colorGrayscaleL, colorContent, spaceM } = theme();
|
|
3
|
+
const { colorBase, colorGrayscaleL, colorContent, spaceM, spaceXL } = theme();
|
|
4
4
|
const PAGINATION_SIZE = 37;
|
|
5
5
|
const style = StyleSheet.create({
|
|
6
6
|
image: {
|
|
@@ -25,5 +25,8 @@ const style = StyleSheet.create({
|
|
|
25
25
|
marginTop: spaceM,
|
|
26
26
|
position: "relative",
|
|
27
27
|
},
|
|
28
|
+
slide: {
|
|
29
|
+
paddingHorizontal: spaceXL,
|
|
30
|
+
},
|
|
28
31
|
});
|
|
29
32
|
export { style };
|
|
@@ -19,10 +19,10 @@ const ProductVariant = ({ country, checkoutId, checkoutItem, currentProductVaria
|
|
|
19
19
|
const handleOnChangedProductVariantSlider = useCallback((active) => trackImageView({ perspective: checkoutItem.productVariant.media[active]?.perspective }), [checkoutItem.productVariant.media, trackImageView]);
|
|
20
20
|
const { price } = checkoutItem;
|
|
21
21
|
const { media, brand, name, color } = checkoutItem.productVariant;
|
|
22
|
-
return (React.createElement(View, {
|
|
23
|
-
React.createElement(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
return (React.createElement(View, { testID: "product-variant" },
|
|
23
|
+
React.createElement(ProductVariantSlider, { producVariantMedia: media, onChanged: handleOnChangedProductVariantSlider }),
|
|
24
|
+
React.createElement(View, { style: [style.content, customStyle?.content] },
|
|
25
|
+
React.createElement(ProductVariantDescription, { brand: brand, color: color, country: country, name: name, price: price, size: currentProductVariant.size }),
|
|
26
|
+
children)));
|
|
27
27
|
};
|
|
28
28
|
export { ProductVariant };
|
package/dist/infrastructure/ui/views/summaryTabs/components/checkoutItemsTabs/CheckoutItemsTabs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Text } from "@lookiero/aurora";
|
|
2
2
|
import { useI18nMessage } from "@lookiero/i18n-react";
|
|
3
|
-
import React, { useCallback } from "react";
|
|
3
|
+
import React, { useCallback, useMemo } from "react";
|
|
4
4
|
import { View } from "react-native";
|
|
5
5
|
import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
|
|
6
6
|
import { Tabs } from "../../../../components/layouts/tabs/Tabs";
|
|
@@ -15,10 +15,10 @@ const CheckoutItemsTabs = ({ tabIndex, checkoutItemsKept, checkoutItemsReturned,
|
|
|
15
15
|
const keepEmptyText = useI18nMessage({ id: I18nMessages.SUMMARY_KEEP_EMPTY });
|
|
16
16
|
const returnEmptyText = useI18nMessage({ id: I18nMessages.SUMMARY_RETURN_EMPTY });
|
|
17
17
|
const handleOnPressItem = useCallback((checkoutItemId) => onPressItem(checkoutItemId), [onPressItem]);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
const data = useMemo(() => [0, 0], []);
|
|
19
|
+
const renderItem = useCallback(({ index }) => index === 0 ? (checkoutItemsKept.length === 0 ? (React.createElement(Text, { style: style.emptyText }, keepEmptyText)) : (React.createElement(React.Fragment, null, checkoutItemsKept.map((checkoutItem) => (React.createElement(CheckoutItem, { key: checkoutItem.id, checkoutItemPrice: checkoutItem.price, checkoutItemStatus: checkoutItem.status, country: country, testID: "keep-checkout-item", checkoutItemProductVariant: checkoutItem.status === CheckoutItemStatus.REPLACED && checkoutItem.replacedFor
|
|
20
|
+
? checkoutItem.replacedFor
|
|
21
|
+
: checkoutItem.productVariant, onPress: () => handleOnPressItem(checkoutItem.id) })))))) : checkoutItemsReturned.length === 0 ? (React.createElement(Text, { style: style.emptyText }, returnEmptyText)) : (React.createElement(React.Fragment, null, checkoutItemsReturned.map((checkoutItem) => (React.createElement(CheckoutItem, { key: checkoutItem.id, checkoutItemPrice: checkoutItem.price, checkoutItemProductVariant: checkoutItem.productVariant, checkoutItemStatus: checkoutItem.status, country: country, style: { image: style.returnCheckoutItem }, testID: "return-checkout-item", discarded: true, onPress: () => handleOnPressItem(checkoutItem.id) }))))), [checkoutItemsKept, checkoutItemsReturned, country, handleOnPressItem, keepEmptyText, returnEmptyText]);
|
|
22
|
+
return (React.createElement(Tabs, { data: data, defaultIndex: tabIndex, style: { sliderContainer: style.sliderContainer }, tabLabels: [`${keepTabText} (${checkoutItemsKept.length})`, `${returnTabText} (${checkoutItemsReturned.length})`], onChanged: onChanged }, renderItem));
|
|
23
23
|
};
|
|
24
24
|
export { CheckoutItemsTabs };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
interface BulletsProps {
|
|
3
|
+
readonly activeIndex: number;
|
|
4
|
+
readonly onChange: (index: number) => void;
|
|
5
|
+
readonly count: number;
|
|
6
|
+
readonly maxBullets?: number;
|
|
7
|
+
readonly testID?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Bullets: FC<BulletsProps>;
|
|
10
|
+
export { Bullets };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { animated, useSpring } from "@react-spring/native";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { View, Pressable } from "react-native";
|
|
4
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
5
|
+
import { style } from "./Bullets.style";
|
|
6
|
+
const { colorContent, colorGrayscaleM } = theme();
|
|
7
|
+
const MAX = 5;
|
|
8
|
+
const DIAMETER_MAX = 8;
|
|
9
|
+
const DIAMETER_MIN = 2;
|
|
10
|
+
const Bullet = ({ index, activeIndex, maxBullets, onChange }) => {
|
|
11
|
+
const pivot = Math.floor(maxBullets / 2) + 1;
|
|
12
|
+
const delta = Math.abs(index - activeIndex);
|
|
13
|
+
const diameter = delta > 1 ? DIAMETER_MAX - delta * DIAMETER_MIN : DIAMETER_MAX;
|
|
14
|
+
const color = delta === 0 ? colorContent : colorGrayscaleM;
|
|
15
|
+
const springs = useSpring({ diameter, color });
|
|
16
|
+
return delta >= pivot ? null : (React.createElement(Pressable, { onPress: () => onChange(index) },
|
|
17
|
+
React.createElement(animated.View, { accessibilityState: { selected: delta === 0 }, testID: "bullet", style: [
|
|
18
|
+
style.bullet,
|
|
19
|
+
{
|
|
20
|
+
width: springs.diameter,
|
|
21
|
+
height: springs.diameter,
|
|
22
|
+
backgroundColor: springs.color,
|
|
23
|
+
borderRadius: springs.diameter,
|
|
24
|
+
},
|
|
25
|
+
] })));
|
|
26
|
+
};
|
|
27
|
+
const Bullets = ({ activeIndex, count, maxBullets = MAX, onChange, testID = "bullets" }) => (React.createElement(View, { style: style.bullets, testID: testID }, [...Array(count).keys()].map((index) => (React.createElement(Bullet, { key: index, activeIndex: activeIndex, index: index, maxBullets: maxBullets, onChange: onChange })))));
|
|
28
|
+
export { Bullets };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
3
|
+
const { spaceM } = theme();
|
|
4
|
+
const style = StyleSheet.create({
|
|
5
|
+
bullet: {
|
|
6
|
+
marginHorizontal: 3,
|
|
7
|
+
},
|
|
8
|
+
bullets: {
|
|
9
|
+
alignItems: "center",
|
|
10
|
+
flexDirection: "row",
|
|
11
|
+
justifyContent: "center",
|
|
12
|
+
paddingVertical: spaceM,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
export { style };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
interface RenderItemFunctionArgs<T> {
|
|
4
|
+
readonly item: T;
|
|
5
|
+
readonly index: number;
|
|
6
|
+
}
|
|
7
|
+
interface RenderItemFunction<T> {
|
|
8
|
+
(args: RenderItemFunctionArgs<T>): JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
interface RenderBulletsFunctionArgs {
|
|
11
|
+
readonly activeIndex: number;
|
|
12
|
+
readonly count: number;
|
|
13
|
+
readonly onChange: (index: number) => void;
|
|
14
|
+
}
|
|
15
|
+
interface RenderBulletsFunction {
|
|
16
|
+
(args: RenderBulletsFunctionArgs): JSX.Element;
|
|
17
|
+
}
|
|
18
|
+
interface CarouselStyle {
|
|
19
|
+
readonly container?: StyleProp<ViewStyle>;
|
|
20
|
+
}
|
|
21
|
+
interface CarouselProps<T> {
|
|
22
|
+
readonly activeIndex?: number;
|
|
23
|
+
readonly data: T[];
|
|
24
|
+
readonly enabled?: boolean;
|
|
25
|
+
readonly children: RenderItemFunction<T>;
|
|
26
|
+
readonly bullets?: RenderBulletsFunction;
|
|
27
|
+
readonly onActiveIndexChanged?: (index: number) => void;
|
|
28
|
+
readonly style?: CarouselStyle;
|
|
29
|
+
}
|
|
30
|
+
declare const Carousel: <T>({ activeIndex, data, enabled, children, bullets, onActiveIndexChanged, style: customStyle, }: CarouselProps<T>) => JSX.Element;
|
|
31
|
+
export type { RenderItemFunction, RenderBulletsFunction };
|
|
32
|
+
export { Carousel };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { Gesture, GestureDetector, GestureHandlerRootView } from "react-native-gesture-handler";
|
|
4
|
+
import Animated, { useSharedValue, withSpring, useAnimatedStyle, runOnJS } from "react-native-reanimated";
|
|
5
|
+
import { style } from "./Carousel.style";
|
|
6
|
+
const SPRING_CONFIG = {
|
|
7
|
+
damping: 25,
|
|
8
|
+
mass: 1,
|
|
9
|
+
stiffness: 300,
|
|
10
|
+
};
|
|
11
|
+
const clamp = (min, max, value) => {
|
|
12
|
+
"worklet";
|
|
13
|
+
return Math.min(max, Math.max(min, value));
|
|
14
|
+
};
|
|
15
|
+
const Carousel = ({ activeIndex = 0, data, enabled = true, children, bullets, onActiveIndexChanged, style: customStyle, }) => {
|
|
16
|
+
const [carouselDimensions, setCarouselDimensions] = useState();
|
|
17
|
+
const handleOnLayout = useCallback(({ nativeEvent: { layout } }) => setCarouselDimensions({ width: layout.width, height: layout.height }), []);
|
|
18
|
+
const carouselWidth = carouselDimensions?.width;
|
|
19
|
+
const panTranslationX = useSharedValue(0);
|
|
20
|
+
const panInitialTranslationX = useSharedValue(undefined);
|
|
21
|
+
const [panActive, setPanActive] = useState(false);
|
|
22
|
+
const activeIndexRef = useRef(activeIndex);
|
|
23
|
+
activeIndexRef.current = activeIndex;
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (panActive || !carouselWidth) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
panTranslationX.value = -activeIndex * carouselWidth;
|
|
29
|
+
}, [activeIndex, carouselWidth, panActive, panTranslationX]);
|
|
30
|
+
const updateActiveIndex = useCallback((index) => {
|
|
31
|
+
if (activeIndexRef.current === index) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
onActiveIndexChanged?.(index);
|
|
35
|
+
}, [onActiveIndexChanged]);
|
|
36
|
+
const handleOnActiveIndexChanged = useCallback((index) => {
|
|
37
|
+
if (!carouselWidth) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
updateActiveIndex(index);
|
|
41
|
+
panTranslationX.value = withSpring(-index * carouselWidth, SPRING_CONFIG);
|
|
42
|
+
}, [carouselWidth, panTranslationX, updateActiveIndex]);
|
|
43
|
+
const panGesture = useMemo(() => Gesture.Pan()
|
|
44
|
+
.withTestId("carousel-pan-gesture")
|
|
45
|
+
.enabled(enabled)
|
|
46
|
+
.maxPointers(1)
|
|
47
|
+
.activeOffsetX([-20, 20])
|
|
48
|
+
// This method does not work if legacy implementation is enabled
|
|
49
|
+
// Expo.tsx => enableLegacyWebImplementation(true)
|
|
50
|
+
// .onStart(() => {
|
|
51
|
+
// panInitialTranslationX.value = panTranslationX.value;
|
|
52
|
+
// })
|
|
53
|
+
// This method is defined as legacy implementation is enabled
|
|
54
|
+
.onBegin(() => {
|
|
55
|
+
runOnJS(setPanActive)(true);
|
|
56
|
+
panInitialTranslationX.value = panTranslationX.value;
|
|
57
|
+
})
|
|
58
|
+
.onUpdate(({ translationX }) => {
|
|
59
|
+
if (panInitialTranslationX.value === undefined || !carouselWidth) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const tX = panInitialTranslationX.value + translationX;
|
|
63
|
+
const index = clamp(0, data.length - 1, Math.round(-tX / carouselWidth));
|
|
64
|
+
panTranslationX.value = tX;
|
|
65
|
+
runOnJS(updateActiveIndex)(index);
|
|
66
|
+
})
|
|
67
|
+
.onEnd(({ translationX, velocityX }) => {
|
|
68
|
+
if (panInitialTranslationX.value === undefined || !carouselWidth) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const tX = panInitialTranslationX.value + translationX;
|
|
72
|
+
const indexDelta = Math.round(translationX / carouselWidth);
|
|
73
|
+
const velocityIndex = Math.abs(indexDelta) > 0 ? 0 : clamp(-1, 1, Math.abs(velocityX) > 2 ? -velocityX : 0);
|
|
74
|
+
const index = clamp(0, data.length - 1, Math.round(-tX / carouselWidth) + velocityIndex);
|
|
75
|
+
panTranslationX.value = withSpring(-index * carouselWidth, SPRING_CONFIG);
|
|
76
|
+
panInitialTranslationX.value = undefined;
|
|
77
|
+
runOnJS(updateActiveIndex)(index);
|
|
78
|
+
runOnJS(setPanActive)(true);
|
|
79
|
+
}), [carouselWidth, data.length, enabled, panInitialTranslationX, panTranslationX, updateActiveIndex]);
|
|
80
|
+
const animatedStyle = useAnimatedStyle(() => ({ transform: [{ translateX: panTranslationX.value }] }), [panTranslationX]);
|
|
81
|
+
return (React.createElement(View, { style: [style.container, customStyle?.container], testID: "carousel" },
|
|
82
|
+
React.createElement(View, { style: style.carousel, testID: "carousel-layout", onLayout: handleOnLayout }, carouselWidth && (React.createElement(GestureHandlerRootView, { style: { flex: 1 } },
|
|
83
|
+
React.createElement(GestureDetector, { gesture: panGesture },
|
|
84
|
+
React.createElement(Animated.View, { style: [style.carouselTrack, { width: carouselWidth * data.length }, animatedStyle], testID: "carousel-track" }, data.map((item, index) => (React.createElement(View, { key: index, style: [style.carouselItem, { width: carouselWidth }], testID: "carousel-item" }, children({ index, item }))))))))),
|
|
85
|
+
bullets && (React.createElement(View, { style: style.bullets, testID: "carousel-bullets" }, bullets({ activeIndex, count: data.length, onChange: handleOnActiveIndexChanged })))));
|
|
86
|
+
};
|
|
87
|
+
export { Carousel };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const style: {
|
|
2
|
+
bullets: {
|
|
3
|
+
bottom: number;
|
|
4
|
+
justifyContent: "center";
|
|
5
|
+
position: "absolute";
|
|
6
|
+
width: string;
|
|
7
|
+
};
|
|
8
|
+
carousel: {
|
|
9
|
+
flex: number;
|
|
10
|
+
};
|
|
11
|
+
carouselItem: {
|
|
12
|
+
flex: number;
|
|
13
|
+
};
|
|
14
|
+
carouselTrack: {
|
|
15
|
+
flex: number;
|
|
16
|
+
flexDirection: "row";
|
|
17
|
+
height: string;
|
|
18
|
+
};
|
|
19
|
+
container: {
|
|
20
|
+
flex: number;
|
|
21
|
+
overflow: "hidden";
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export { style };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
const style = StyleSheet.create({
|
|
3
|
+
bullets: {
|
|
4
|
+
bottom: 0,
|
|
5
|
+
justifyContent: "center",
|
|
6
|
+
position: "absolute",
|
|
7
|
+
width: "100%",
|
|
8
|
+
},
|
|
9
|
+
carousel: {
|
|
10
|
+
flex: 1,
|
|
11
|
+
},
|
|
12
|
+
carouselItem: {
|
|
13
|
+
flex: 1,
|
|
14
|
+
},
|
|
15
|
+
carouselTrack: {
|
|
16
|
+
flex: 1,
|
|
17
|
+
flexDirection: "row",
|
|
18
|
+
height: "100%",
|
|
19
|
+
},
|
|
20
|
+
container: {
|
|
21
|
+
flex: 1,
|
|
22
|
+
overflow: "hidden",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
export { style };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
interface RenderItemFunctionArgs<T> {
|
|
4
|
+
readonly item: T;
|
|
5
|
+
readonly index: number;
|
|
6
|
+
}
|
|
7
|
+
interface RenderItemFunction<T> {
|
|
8
|
+
(args: RenderItemFunctionArgs<T>): JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
interface RenderBulletsFunctionArgs {
|
|
11
|
+
readonly activeIndex: number;
|
|
12
|
+
readonly count: number;
|
|
13
|
+
readonly onChange: (index: number) => void;
|
|
14
|
+
}
|
|
15
|
+
interface RenderBulletsFunction {
|
|
16
|
+
(args: RenderBulletsFunctionArgs): JSX.Element;
|
|
17
|
+
}
|
|
18
|
+
interface CarouselStyle {
|
|
19
|
+
readonly container?: StyleProp<ViewStyle>;
|
|
20
|
+
}
|
|
21
|
+
interface CarouselProps<T> {
|
|
22
|
+
readonly data: T[];
|
|
23
|
+
readonly children: RenderItemFunction<T>;
|
|
24
|
+
readonly bullets: RenderBulletsFunction;
|
|
25
|
+
readonly onActiveIndexChanged?: (index: number) => void;
|
|
26
|
+
readonly style?: CarouselStyle;
|
|
27
|
+
}
|
|
28
|
+
declare const Carousel2: <T>({ data, children, bullets, onActiveIndexChanged, style: customStyle }: CarouselProps<T>) => JSX.Element;
|
|
29
|
+
export type { RenderItemFunction, RenderBulletsFunction };
|
|
30
|
+
export { Carousel2 };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { Gesture, GestureDetector, GestureHandlerRootView } from "react-native-gesture-handler";
|
|
4
|
+
import Animated, { useSharedValue, withSpring, useAnimatedStyle, runOnJS } from "react-native-reanimated";
|
|
5
|
+
import { style } from "./Carousel.style";
|
|
6
|
+
const SPRING_CONFIG = {
|
|
7
|
+
damping: 25,
|
|
8
|
+
mass: 1,
|
|
9
|
+
stiffness: 300,
|
|
10
|
+
};
|
|
11
|
+
const clamp = (min, max, value) => {
|
|
12
|
+
"worklet";
|
|
13
|
+
return Math.min(max, Math.max(min, value));
|
|
14
|
+
};
|
|
15
|
+
const Carousel2 = ({ data, children, bullets, onActiveIndexChanged, style: customStyle }) => {
|
|
16
|
+
const [carouselDimensions, setCarouselDimensions] = useState({
|
|
17
|
+
width: 0,
|
|
18
|
+
height: 0,
|
|
19
|
+
});
|
|
20
|
+
const handleOnLayout = useCallback(({ nativeEvent: { layout: { width, height }, }, }) => setCarouselDimensions({ width, height }), []);
|
|
21
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
22
|
+
const activeIndexRef = useRef(activeIndex);
|
|
23
|
+
activeIndexRef.current = activeIndex;
|
|
24
|
+
const updateActiveIndex = useCallback((index) => {
|
|
25
|
+
if (activeIndexRef.current === index) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
setActiveIndex(index);
|
|
29
|
+
onActiveIndexChanged?.(index);
|
|
30
|
+
}, [onActiveIndexChanged]);
|
|
31
|
+
const panTranslationX = useSharedValue(0);
|
|
32
|
+
const panInitialTranslationX = useSharedValue(undefined);
|
|
33
|
+
const handleOnActiveIndexChanged = useCallback((index) => {
|
|
34
|
+
updateActiveIndex(index);
|
|
35
|
+
panTranslationX.value = withSpring(-index * carouselDimensions.width, SPRING_CONFIG);
|
|
36
|
+
}, [carouselDimensions.width, panTranslationX, updateActiveIndex]);
|
|
37
|
+
const panGesture = useMemo(() => Gesture.Pan()
|
|
38
|
+
.maxPointers(1)
|
|
39
|
+
.activeOffsetX([-20, 20])
|
|
40
|
+
// .failOffsetY([-20, 20])
|
|
41
|
+
// This method does not work if legacy implementation is enabled
|
|
42
|
+
// Expo.tsx => enableLegacyWebImplementation(true)
|
|
43
|
+
// .onStart(() => {
|
|
44
|
+
// panInitialTranslationX.value = panTranslationX.value;
|
|
45
|
+
// })
|
|
46
|
+
// This method is defined as legacy implementation is enabled
|
|
47
|
+
.onBegin(() => {
|
|
48
|
+
panInitialTranslationX.value = panTranslationX.value;
|
|
49
|
+
})
|
|
50
|
+
.onUpdate(({ translationX }) => {
|
|
51
|
+
if (panInitialTranslationX.value === undefined) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const tX = panInitialTranslationX.value + translationX;
|
|
55
|
+
const index = clamp(0, data.length - 1, Math.round(-tX / carouselDimensions.width));
|
|
56
|
+
panTranslationX.value = tX;
|
|
57
|
+
runOnJS(updateActiveIndex)(index);
|
|
58
|
+
})
|
|
59
|
+
.onEnd(({ translationX, velocityX }) => {
|
|
60
|
+
if (panInitialTranslationX.value === undefined) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const tX = panInitialTranslationX.value + translationX;
|
|
64
|
+
const indexDelta = Math.round(translationX / carouselDimensions.width);
|
|
65
|
+
const velocityIndex = Math.abs(indexDelta) > 0 ? 0 : clamp(-1, 1, Math.abs(velocityX) > 2 ? -velocityX : 0);
|
|
66
|
+
const index = clamp(0, data.length - 1, Math.round(-tX / carouselDimensions.width) + velocityIndex);
|
|
67
|
+
panTranslationX.value = withSpring(-index * carouselDimensions.width, SPRING_CONFIG);
|
|
68
|
+
panInitialTranslationX.value = undefined;
|
|
69
|
+
runOnJS(updateActiveIndex)(index);
|
|
70
|
+
}), [carouselDimensions.width, data.length, panInitialTranslationX, panTranslationX, updateActiveIndex]);
|
|
71
|
+
const animatedStyle = useAnimatedStyle(() => ({ transform: [{ translateX: panTranslationX.value }] }), [panTranslationX]);
|
|
72
|
+
return (React.createElement(View, { style: [style.container, customStyle?.container] },
|
|
73
|
+
React.createElement(View, { style: style.carousel, onLayout: handleOnLayout },
|
|
74
|
+
React.createElement(GestureHandlerRootView, { style: { flex: 1 } },
|
|
75
|
+
React.createElement(GestureDetector, { gesture: panGesture },
|
|
76
|
+
React.createElement(Animated.View, { style: [style.carouselTrack, { width: carouselDimensions.width * data.length }, animatedStyle] }, data.map((item, index) => (React.createElement(View, { key: index, style: [style.carouselItem, { width: carouselDimensions.width }] }, children({ index, item })))))))),
|
|
77
|
+
React.createElement(View, { style: style.bullets }, bullets({ activeIndex, count: data.length, onChange: handleOnActiveIndexChanged }))));
|
|
78
|
+
};
|
|
79
|
+
export { Carousel2 };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { View } from "react-native";
|
|
4
|
+
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
5
|
+
import { useSharedValue } from "react-native-reanimated";
|
|
6
|
+
import { useScrollViewRef } from "../../../../../infrastructure/ui/components/layouts/layout/dummyLayout/useScrollViewRef";
|
|
7
|
+
const TOUCH_SLOP = 5;
|
|
8
|
+
const TIME_TO_ACTIVATE_PAN = 400;
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
const DragComponent = (props) => {
|
|
11
|
+
const { scrollViewRef, panGestureRef } = useScrollViewRef();
|
|
12
|
+
const touchStart = useSharedValue({ x: 0, y: 0, time: 0 });
|
|
13
|
+
const gesture = Gesture.Pan()
|
|
14
|
+
.manualActivation(true)
|
|
15
|
+
.onTouchesDown((e) => {
|
|
16
|
+
touchStart.value = {
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
x: e.changedTouches[0].x,
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
y: e.changedTouches[0].y,
|
|
21
|
+
time: Date.now(),
|
|
22
|
+
};
|
|
23
|
+
})
|
|
24
|
+
.onTouchesMove((e, state) => {
|
|
25
|
+
if (Date.now() - touchStart.value.time > TIME_TO_ACTIVATE_PAN) {
|
|
26
|
+
state.activate();
|
|
27
|
+
console.log("activate");
|
|
28
|
+
}
|
|
29
|
+
else if (
|
|
30
|
+
// @ts-ignore
|
|
31
|
+
Math.abs(touchStart.value.x - e.changedTouches[0].x) > TOUCH_SLOP ||
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
Math.abs(touchStart.value.y - e.changedTouches[0].y) > TOUCH_SLOP) {
|
|
34
|
+
state.fail();
|
|
35
|
+
console.log("fail");
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
.onUpdate(() => {
|
|
39
|
+
console.log("pan update");
|
|
40
|
+
})
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
.simultaneousWithExternalGesture(scrollViewRef)
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
.withRef(panGestureRef);
|
|
45
|
+
return (React.createElement(GestureDetector, { gesture: gesture },
|
|
46
|
+
React.createElement(View, null, props.children)));
|
|
47
|
+
};
|
|
48
|
+
export { DragComponent };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
interface BulletsProps {
|
|
3
|
+
readonly activeIndex: number;
|
|
4
|
+
readonly onChange: (index: number) => void;
|
|
5
|
+
readonly count: number;
|
|
6
|
+
readonly maxBullets?: number;
|
|
7
|
+
readonly testID?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Bullets: FC<BulletsProps>;
|
|
10
|
+
export { Bullets };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { animated, useSpring } from "@react-spring/native";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { View, Pressable } from "react-native";
|
|
4
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
5
|
+
import { style } from "./Bullets.style";
|
|
6
|
+
const { colorContent, colorGrayscaleM } = theme();
|
|
7
|
+
const MAX = 5;
|
|
8
|
+
const DIAMETER_MAX = 8;
|
|
9
|
+
const DIAMETER_MIN = 2;
|
|
10
|
+
const Bullet = ({ index, activeIndex, maxBullets, onChange }) => {
|
|
11
|
+
const pivot = Math.floor(maxBullets / 2) + 1;
|
|
12
|
+
const delta = Math.abs(index - activeIndex);
|
|
13
|
+
const diameter = delta > 1 ? DIAMETER_MAX - delta * DIAMETER_MIN : DIAMETER_MAX;
|
|
14
|
+
const color = delta === 0 ? colorContent : colorGrayscaleM;
|
|
15
|
+
const springs = useSpring({ diameter, color });
|
|
16
|
+
return delta >= pivot ? null : (React.createElement(Pressable, { onPress: () => onChange(index) },
|
|
17
|
+
React.createElement(animated.View, { accessibilityState: { selected: delta === 0 }, testID: "bullet", style: [
|
|
18
|
+
style.bullet,
|
|
19
|
+
{
|
|
20
|
+
width: springs.diameter,
|
|
21
|
+
height: springs.diameter,
|
|
22
|
+
backgroundColor: springs.color,
|
|
23
|
+
borderRadius: springs.diameter,
|
|
24
|
+
},
|
|
25
|
+
] })));
|
|
26
|
+
};
|
|
27
|
+
const Bullets = ({ activeIndex, count, maxBullets = MAX, onChange, testID = "bullets" }) => (React.createElement(View, { style: style.bullets, testID: testID }, [...Array(count).keys()].map((index) => (React.createElement(Bullet, { key: index, activeIndex: activeIndex, index: index, maxBullets: maxBullets, onChange: onChange })))));
|
|
28
|
+
export { Bullets };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
3
|
+
const { spaceM } = theme();
|
|
4
|
+
const style = StyleSheet.create({
|
|
5
|
+
bullet: {
|
|
6
|
+
marginHorizontal: 3,
|
|
7
|
+
},
|
|
8
|
+
bullets: {
|
|
9
|
+
alignItems: "center",
|
|
10
|
+
flexDirection: "row",
|
|
11
|
+
justifyContent: "center",
|
|
12
|
+
paddingVertical: spaceM,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
export { style };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
interface BulletsProps {
|
|
3
|
+
readonly activeIndex: number;
|
|
4
|
+
readonly onChange: (index: number) => void;
|
|
5
|
+
readonly count: number;
|
|
6
|
+
readonly maxBullets?: number;
|
|
7
|
+
readonly testID?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Bullets: FC<BulletsProps>;
|
|
10
|
+
export { Bullets };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { View, Pressable } from "react-native";
|
|
3
|
+
import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue } from "react-native-reanimated";
|
|
4
|
+
import { withSpring } from "react-native-reanimated";
|
|
5
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
6
|
+
import { style } from "./Bullets.style";
|
|
7
|
+
const { colorContent, colorGrayscaleM } = theme();
|
|
8
|
+
const MAX = 5;
|
|
9
|
+
const DIAMETER_MAX = 8;
|
|
10
|
+
const DIAMETER_MIN = 2;
|
|
11
|
+
const Bullet = ({ index, activeIndex, maxBullets, onChange }) => {
|
|
12
|
+
const pivot = Math.floor(maxBullets / 2) + 1;
|
|
13
|
+
// const delta = Math.abs(index - activeIndex);
|
|
14
|
+
const delta = useSharedValue(0);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
delta.value = Math.abs(index - activeIndex);
|
|
17
|
+
}, [activeIndex, delta, index]);
|
|
18
|
+
const diameter = useDerivedValue(() => withSpring(delta.value > 1 ? DIAMETER_MAX - delta.value * DIAMETER_MIN : DIAMETER_MAX), [delta]);
|
|
19
|
+
const color = useDerivedValue(() => withSpring(delta.value === 0 ? colorContent : colorGrayscaleM), [delta]);
|
|
20
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
21
|
+
width: diameter.value,
|
|
22
|
+
height: diameter.value,
|
|
23
|
+
backgroundColor: color.value,
|
|
24
|
+
borderRadius: diameter.value,
|
|
25
|
+
}), [diameter, color]);
|
|
26
|
+
return delta.value >= pivot ? null : (React.createElement(Pressable, { onPress: () => onChange(index) },
|
|
27
|
+
React.createElement(Animated.View, { accessibilityState: { selected: delta.value === 0 }, style: [style.bullet, animatedStyle], testID: "bullet" })));
|
|
28
|
+
};
|
|
29
|
+
const Bullets = ({ activeIndex, count, maxBullets = MAX, onChange, testID = "bullets" }) => (React.createElement(View, { style: style.bullets, testID: testID }, [...Array(count).keys()].map((index) => (React.createElement(Bullet, { key: index, activeIndex: activeIndex, index: index, maxBullets: maxBullets, onChange: onChange })))));
|
|
30
|
+
export { Bullets };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FC, ReactNode } from "react";
|
|
2
|
-
import { StyleProp, ViewStyle } from "react-native";
|
|
3
2
|
interface SliderProps {
|
|
4
3
|
readonly children: ReactNode[];
|
|
5
4
|
readonly active?: number;
|
|
@@ -8,13 +7,9 @@ interface SliderProps {
|
|
|
8
7
|
readonly minDistanceForAction?: number;
|
|
9
8
|
readonly gesturesEnabled?: boolean;
|
|
10
9
|
readonly paginationEnabled?: boolean;
|
|
11
|
-
readonly paginationStyle?: StyleProp<ViewStyle>;
|
|
12
|
-
readonly paginationItemStyle?: StyleProp<ViewStyle>;
|
|
13
|
-
readonly paginationActiveItemStyle?: StyleProp<ViewStyle>;
|
|
14
10
|
readonly onSliderStart?: () => void;
|
|
15
11
|
readonly onSliderEnd?: () => void;
|
|
16
12
|
readonly onChanged?: (index: number) => void;
|
|
17
|
-
readonly paginationRenderItem?: (index: number) => ReactNode;
|
|
18
13
|
}
|
|
19
14
|
declare const Slider: FC<SliderProps>;
|
|
20
15
|
export { Slider };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
import { Animated, I18nManager, PanResponder, StyleSheet, View
|
|
3
|
-
import {
|
|
2
|
+
import { Animated, I18nManager, PanResponder, StyleSheet, View } from "react-native";
|
|
3
|
+
import { Bullets } from "./Bullets";
|
|
4
4
|
import { style } from "./Slider.style";
|
|
5
5
|
const DEFAULT_WIDTH = 200;
|
|
6
|
-
const Slider = ({ children, active = 0, loop = false, minDistanceToCapture = 5, minDistanceForAction = 0.2, gesturesEnabled = true, paginationEnabled = true,
|
|
6
|
+
const Slider = ({ children, active = 0, loop = false, minDistanceToCapture = 5, minDistanceForAction = 0.2, gesturesEnabled = true, paginationEnabled = true, onSliderStart, onSliderEnd, onChanged, }) => {
|
|
7
7
|
const flatennedChildren = children.flat();
|
|
8
8
|
const count = flatennedChildren.length;
|
|
9
9
|
const [width, setWidth] = useState(0);
|
|
@@ -127,6 +127,6 @@ const Slider = ({ children, active = 0, loop = false, minDistanceToCapture = 5,
|
|
|
127
127
|
},
|
|
128
128
|
style.sliderAreaStyle,
|
|
129
129
|
]), ...panResponder.panHandlers }, flatennedChildren.map((child, index) => (React.createElement(View, { key: index, style: { width }, testID: "slider-child" }, child)))),
|
|
130
|
-
paginationEnabled && (React.createElement(
|
|
130
|
+
paginationEnabled && (React.createElement(Bullets, { activeIndex: getActiveIndex(), count: count, testID: "slider-bullets", onChange: (index) => goTo(index) }))));
|
|
131
131
|
};
|
|
132
132
|
export { Slider };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TouchableWithoutFeedback, View } from "react-native";
|
|
3
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
4
|
+
import { style } from "./SliderDots.style";
|
|
5
|
+
const { colorContent } = theme();
|
|
6
|
+
const SliderDot = ({ diameter, color }) => (React.createElement(View, { style: [style.sliderDot, { width: diameter, height: diameter, backgroundColor: color, borderRadius: diameter }] }));
|
|
7
|
+
const SliderDots = () => {
|
|
8
|
+
return (React.createElement(View, { style: style.sliderDots },
|
|
9
|
+
React.createElement(TouchableWithoutFeedback, null,
|
|
10
|
+
React.createElement(SliderDot, { color: colorContent, diameter: 8 })),
|
|
11
|
+
React.createElement(TouchableWithoutFeedback, null,
|
|
12
|
+
React.createElement(SliderDot, { color: colorContent, diameter: 8 })),
|
|
13
|
+
React.createElement(TouchableWithoutFeedback, null,
|
|
14
|
+
React.createElement(SliderDot, { color: colorContent, diameter: 8 }))));
|
|
15
|
+
};
|
|
16
|
+
export { SliderDots };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
3
|
+
const { spaceM } = theme();
|
|
4
|
+
const style = StyleSheet.create({
|
|
5
|
+
sliderDot: {
|
|
6
|
+
marginHorizontal: 3,
|
|
7
|
+
},
|
|
8
|
+
sliderDots: {
|
|
9
|
+
alignItems: "center",
|
|
10
|
+
flexDirection: "row",
|
|
11
|
+
justifyContent: "center",
|
|
12
|
+
paddingVertical: spaceM,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
export { style };
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import React, { useCallback } from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
4
3
|
import { style } from "./Sticky.style";
|
|
5
|
-
const { spaceXL } = theme();
|
|
6
4
|
const Sticky = ({ children, style: customStyle, onLayout }) => {
|
|
7
5
|
const handleOnLayout = useCallback(({ nativeEvent: { layout: { width, height }, }, }) => onLayout?.({ width, height }), [onLayout]);
|
|
8
|
-
return (React.createElement(View, { style: [style.sticky,
|
|
6
|
+
return (React.createElement(View, { style: [style.sticky, customStyle], onLayout: handleOnLayout }, children));
|
|
9
7
|
};
|
|
10
8
|
export { Sticky };
|
|
@@ -5,6 +5,7 @@ declare const style: StyleSheet.NamedStyles<any> | StyleSheet.NamedStyles<{
|
|
|
5
5
|
backgroundColor: string;
|
|
6
6
|
bottom: number;
|
|
7
7
|
elevation: number;
|
|
8
|
+
paddingBottom: number;
|
|
8
9
|
paddingTop: number;
|
|
9
10
|
shadowColor: string;
|
|
10
11
|
shadowOffset: {
|
|
@@ -20,6 +21,7 @@ declare const style: StyleSheet.NamedStyles<any> | StyleSheet.NamedStyles<{
|
|
|
20
21
|
backgroundColor: string;
|
|
21
22
|
bottom: number;
|
|
22
23
|
elevation: number;
|
|
24
|
+
paddingBottom: number;
|
|
23
25
|
paddingTop: number;
|
|
24
26
|
shadowColor: string;
|
|
25
27
|
shadowOffset: {
|
|
@@ -35,6 +37,7 @@ declare const style: StyleSheet.NamedStyles<any> | StyleSheet.NamedStyles<{
|
|
|
35
37
|
backgroundColor: string;
|
|
36
38
|
bottom: number;
|
|
37
39
|
elevation: number;
|
|
40
|
+
paddingBottom: number;
|
|
38
41
|
paddingTop: number;
|
|
39
42
|
shadowColor: string;
|
|
40
43
|
shadowOffset: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Platform, StyleSheet } from "react-native";
|
|
2
2
|
import { theme } from "../../../../../infrastructure/ui/theme/theme";
|
|
3
|
-
const { colorBase, elevationColor, elevationLayerL, elevationOffset, elevationOpacityM, elevationRadius,
|
|
3
|
+
const { colorBase, elevationColor, elevationLayerL, elevationOffset, elevationOpacityM, elevationRadius, spaceM, spaceL, } = theme();
|
|
4
4
|
const style = StyleSheet.create({
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
6
|
// @ts-ignore
|
|
@@ -8,7 +8,8 @@ const style = StyleSheet.create({
|
|
|
8
8
|
backgroundColor: colorBase,
|
|
9
9
|
bottom: 0,
|
|
10
10
|
elevation: elevationLayerL,
|
|
11
|
-
|
|
11
|
+
paddingBottom: spaceL,
|
|
12
|
+
paddingTop: spaceM,
|
|
12
13
|
shadowColor: elevationColor,
|
|
13
14
|
shadowOffset: elevationOffset,
|
|
14
15
|
shadowOpacity: elevationOpacityM,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lookiero/checkout",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0-beta.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -57,8 +57,10 @@
|
|
|
57
57
|
"react": "^18.2.0",
|
|
58
58
|
"react-dom": "^18.2.0",
|
|
59
59
|
"react-native": "^0.71.4",
|
|
60
|
+
"react-native-gesture-handler": "^2.12.0",
|
|
60
61
|
"react-native-get-random-values": "^1.8.0",
|
|
61
62
|
"react-native-web": "^0.18.11",
|
|
63
|
+
"react-native-reanimated": "^3.3.0",
|
|
62
64
|
"react-router-dom": "^6.8.1",
|
|
63
65
|
"react-router-native": "^6.8.1"
|
|
64
66
|
},
|
|
@@ -77,8 +79,8 @@
|
|
|
77
79
|
"@pact-foundation/pact-node": "^10.17.6",
|
|
78
80
|
"@react-native-firebase/analytics": "10.5.1",
|
|
79
81
|
"@react-native-firebase/app": "10.5.0",
|
|
80
|
-
"@testing-library/react-native": "^11.5.0",
|
|
81
82
|
"@testing-library/jest-native": "^5.4.2",
|
|
83
|
+
"@testing-library/react-native": "^11.5.0",
|
|
82
84
|
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
|
|
83
85
|
"@types/jest": "^29.2.4",
|
|
84
86
|
"@types/pino-pretty": "^5.0.0",
|
|
@@ -116,8 +118,10 @@
|
|
|
116
118
|
"react-error-overlay": "^6.0.9",
|
|
117
119
|
"react-native": "^0.71.3",
|
|
118
120
|
"react-native-adjust": "^4.33.0",
|
|
121
|
+
"react-native-gesture-handler": "^2.12.0",
|
|
119
122
|
"react-native-get-random-values": "^1.8.0",
|
|
120
123
|
"react-native-web": "^0.18.11",
|
|
124
|
+
"react-native-reanimated": "^3.3.0",
|
|
121
125
|
"react-router-dom": "^6.8.1",
|
|
122
126
|
"react-router-native": "^6.8.1",
|
|
123
127
|
"react-test-renderer": "^18.0.0",
|