@swan-io/lake 8.6.1 → 8.7.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/package.json +1 -1
- package/src/components/BottomPanel.js +2 -1
- package/src/components/FixedListView.js +2 -1
- package/src/components/FlatList.d.ts +3 -2
- package/src/components/FlatList.js +8 -8
- package/src/components/Form.d.ts +1 -0
- package/src/components/LakeScrollView.js +2 -1
- package/src/components/PlainListView.js +2 -1
- package/src/components/Popover.js +2 -1
- package/src/components/ScrollView.d.ts +23 -0
- package/src/components/ScrollView.js +99 -0
- package/src/components/SectionList.d.ts +3 -2
- package/src/components/SectionList.js +8 -8
- package/src/components/SidebarNavigationTracker.d.ts +1 -1
- package/src/components/SidebarNavigationTracker.js +2 -1
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
|
-
import { Pressable,
|
|
3
|
+
import { Pressable, StyleSheet, View } from "react-native";
|
|
4
4
|
import { commonStyles } from "../constants/commonStyles";
|
|
5
5
|
import { backgroundColor, radii, shadows } from "../constants/design";
|
|
6
6
|
import { useBodyClassName } from "../hooks/useBodyClassName";
|
|
7
7
|
import { FocusTrap } from "./FocusTrap";
|
|
8
8
|
import { LoadingView } from "./LoadingView";
|
|
9
9
|
import { Portal } from "./Portal";
|
|
10
|
+
import { ScrollView } from "./ScrollView";
|
|
10
11
|
import { Suspendable } from "./Suspendable";
|
|
11
12
|
import { TransitionView } from "./TransitionView";
|
|
12
13
|
const BACKGROUND_COLOR = "rgba(0, 0, 0, 0.6)";
|
|
@@ -35,7 +35,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
35
35
|
*
|
|
36
36
|
*/
|
|
37
37
|
import { cloneElement, Fragment, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
|
|
38
|
-
import {
|
|
38
|
+
import { StyleSheet, View, } from "react-native";
|
|
39
39
|
import { match } from "ts-pattern";
|
|
40
40
|
import { v4 as uuid } from "uuid";
|
|
41
41
|
import { backgroundColor, colors, invariantColors, radii, shadows, spacings, } from "../constants/design";
|
|
@@ -48,6 +48,7 @@ import { BorderedIcon } from "./BorderedIcon";
|
|
|
48
48
|
import { Icon } from "./Icon";
|
|
49
49
|
import { LakeHeading } from "./LakeHeading";
|
|
50
50
|
import { LakeText } from "./LakeText";
|
|
51
|
+
import { ScrollView } from "./ScrollView";
|
|
51
52
|
import { Space } from "./Space";
|
|
52
53
|
const HORIZONTAL_SAFE_AREA = 10;
|
|
53
54
|
export const SCROLLBAR_RESERVED_SPACE = 20;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ForwardedRef, ReactNode } from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { StyleProp, ViewStyle, WebRole } from "react-native";
|
|
3
|
+
import { ScrollViewProps, ScrollViewRef } from "./ScrollView";
|
|
4
|
+
export type FlatListRef = ScrollViewRef;
|
|
4
5
|
export type ListRenderItemInfo<T> = {
|
|
5
6
|
item: T;
|
|
6
7
|
index: number;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment, forwardRef, useEffect, useRef } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { ScrollView } from "./ScrollView";
|
|
4
5
|
const styles = StyleSheet.create({
|
|
5
6
|
scrollTracker: {
|
|
6
7
|
position: "absolute",
|
|
7
8
|
pointerEvents: "none",
|
|
8
|
-
left: 0,
|
|
9
|
-
bottom: 0,
|
|
10
9
|
right: 0,
|
|
10
|
+
bottom: 0,
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
|
-
const FlatListWithRef = ({ ItemSeparatorComponent, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, contentContainerStyle, data, horizontal = false, keyExtractor, onEndReached, onEndReachedThresholdPx = 200, onKeyDown, onScroll, renderItem, role, scrollEventThrottle =
|
|
13
|
+
const FlatListWithRef = ({ ItemSeparatorComponent, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, contentContainerStyle, data, horizontal = false, keyExtractor, onEndReached, onEndReachedThresholdPx = 200, onKeyDown, onScroll, renderItem, role, scrollEventThrottle = 16, showsScrollIndicators = true, style, }, forwardedRef) => {
|
|
14
14
|
const scrollTrackerRef = useRef(null);
|
|
15
15
|
const scrollTrackerStyle = horizontal
|
|
16
|
-
? { width: onEndReachedThresholdPx }
|
|
17
|
-
: { height: onEndReachedThresholdPx };
|
|
16
|
+
? { top: 0, width: onEndReachedThresholdPx }
|
|
17
|
+
: { left: 0, height: onEndReachedThresholdPx };
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
const element = scrollTrackerRef.current;
|
|
20
20
|
if (element != null) {
|
|
@@ -32,8 +32,8 @@ const FlatListWithRef = ({ ItemSeparatorComponent, ListEmptyComponent, ListFoote
|
|
|
32
32
|
}
|
|
33
33
|
// re-create an observer only on list length change
|
|
34
34
|
}, [data.length]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
35
|
-
return (_jsxs(ScrollView, { contentContainerStyle: contentContainerStyle, horizontal: horizontal, onKeyDown: onKeyDown, onScroll: onScroll, ref: forwardedRef, role: role, scrollEventThrottle: scrollEventThrottle,
|
|
35
|
+
return (_jsxs(ScrollView, { contentContainerStyle: contentContainerStyle, horizontal: horizontal, onKeyDown: onKeyDown, onScroll: onScroll, ref: forwardedRef, role: role, scrollEventThrottle: scrollEventThrottle, showsScrollIndicators: showsScrollIndicators, style: style, children: [ListHeaderComponent, data.length <= 0
|
|
36
36
|
? ListEmptyComponent
|
|
37
|
-
: data.map((item, index) => (_jsxs(Fragment, { children: [index !== 0 && ItemSeparatorComponent, renderItem({ item, index })] }, keyExtractor(item, index)))), _jsx(View, { ref: scrollTrackerRef, style: [styles.scrollTracker, scrollTrackerStyle] })
|
|
37
|
+
: data.map((item, index) => (_jsxs(Fragment, { children: [index !== 0 && ItemSeparatorComponent, renderItem({ item, index })] }, keyExtractor(item, index)))), ListFooterComponent, _jsx(View, { role: "none", ref: scrollTrackerRef, style: [styles.scrollTracker, scrollTrackerStyle] })] }));
|
|
38
38
|
};
|
|
39
39
|
export const FlatList = forwardRef(FlatListWithRef);
|
package/src/components/Form.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const Form: import("react").MemoExoticComponent<import("react").F
|
|
|
14
14
|
onKeyDownCapture?: ((event: NativeSyntheticEvent<import("react").KeyboardEvent<Element>>) => void) | undefined;
|
|
15
15
|
onKeyUp?: ((event: NativeSyntheticEvent<import("react").KeyboardEvent<Element>>) => void) | undefined;
|
|
16
16
|
onKeyUpCapture?: ((event: NativeSyntheticEvent<import("react").KeyboardEvent<Element>>) => void) | undefined;
|
|
17
|
+
onScroll?: ((event: NativeSyntheticEvent<import("react").UIEvent<Element, UIEvent>>) => void) | undefined;
|
|
17
18
|
collapsable?: boolean | undefined;
|
|
18
19
|
needsOffscreenAlphaCompositing?: boolean | undefined;
|
|
19
20
|
renderToHardwareTextureAndroid?: boolean | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useState } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
4
|
import { backgroundColor } from "../constants/design";
|
|
5
|
+
import { ScrollView } from "./ScrollView";
|
|
5
6
|
const HORIZONTAL_SAFE_AREA = 20;
|
|
6
7
|
const styles = StyleSheet.create({
|
|
7
8
|
root: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { cloneElement, Fragment, useCallback, useEffect, useId, useMemo, useRef, useState, } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
4
|
import { commonStyles } from "../constants/commonStyles";
|
|
5
5
|
import { backgroundColor, breakpoints, colors, spacings } from "../constants/design";
|
|
6
6
|
import { useHover } from "../hooks/useHover";
|
|
@@ -8,6 +8,7 @@ import { isNotNullish, isNullish } from "../utils/nullish";
|
|
|
8
8
|
import { PlainListViewPlaceholder, } from "./FixedListView";
|
|
9
9
|
import { LakeHeading } from "./LakeHeading";
|
|
10
10
|
import { ResponsiveContainer } from "./ResponsiveContainer";
|
|
11
|
+
import { ScrollView } from "./ScrollView";
|
|
11
12
|
const INHERIT = "inherit";
|
|
12
13
|
const styles = StyleSheet.create({
|
|
13
14
|
root: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { Pressable,
|
|
3
|
+
import { Pressable, StyleSheet, View, } from "react-native";
|
|
4
4
|
import { match, P } from "ts-pattern";
|
|
5
5
|
import { animations, backgroundColor, radii, shadows, spacings, } from "../constants/design";
|
|
6
6
|
import { useContextualLayer } from "../hooks/useContextualLayer";
|
|
@@ -9,6 +9,7 @@ import { noop } from "../utils/function";
|
|
|
9
9
|
import { BottomPanel } from "./BottomPanel";
|
|
10
10
|
import { FocusTrap } from "./FocusTrap";
|
|
11
11
|
import { Portal } from "./Portal";
|
|
12
|
+
import { ScrollView } from "./ScrollView";
|
|
12
13
|
import { TransitionView } from "./TransitionView";
|
|
13
14
|
const styles = StyleSheet.create({
|
|
14
15
|
container: {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { NativeScrollEvent, NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle } from "react-native";
|
|
3
|
+
export type ScrollViewRef = {
|
|
4
|
+
scrollTo: (event: {
|
|
5
|
+
x?: number;
|
|
6
|
+
y?: number;
|
|
7
|
+
animated?: boolean;
|
|
8
|
+
}) => void;
|
|
9
|
+
};
|
|
10
|
+
export type ScrollViewProps = ViewProps & {
|
|
11
|
+
contentContainerStyle?: StyleProp<ViewStyle>;
|
|
12
|
+
horizontal?: boolean;
|
|
13
|
+
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
14
|
+
scrollEventThrottle?: number;
|
|
15
|
+
showsScrollIndicators?: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare const ScrollView: import("react").ForwardRefExoticComponent<ViewProps & {
|
|
18
|
+
contentContainerStyle?: StyleProp<ViewStyle>;
|
|
19
|
+
horizontal?: boolean | undefined;
|
|
20
|
+
onScroll?: ((event: NativeSyntheticEvent<NativeScrollEvent>) => void) | undefined;
|
|
21
|
+
scrollEventThrottle?: number | undefined;
|
|
22
|
+
showsScrollIndicators?: boolean | undefined;
|
|
23
|
+
} & import("react").RefAttributes<ScrollViewRef>>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useCallback, useImperativeHandle, useRef, } from "react";
|
|
3
|
+
import { StyleSheet, View, } from "react-native";
|
|
4
|
+
import { useMergeRefs } from "../hooks/useMergeRefs";
|
|
5
|
+
const styles = StyleSheet.create({
|
|
6
|
+
base: {
|
|
7
|
+
WebkitOverflowScrolling: "touch",
|
|
8
|
+
flexDirection: "column",
|
|
9
|
+
flexGrow: 1,
|
|
10
|
+
flexShrink: 1,
|
|
11
|
+
overflowX: "hidden",
|
|
12
|
+
overflowY: "auto",
|
|
13
|
+
transform: "translateZ(0)",
|
|
14
|
+
},
|
|
15
|
+
horizontal: {
|
|
16
|
+
flexDirection: "row",
|
|
17
|
+
overflowX: "auto",
|
|
18
|
+
overflowY: "hidden",
|
|
19
|
+
},
|
|
20
|
+
contentHorizontal: {
|
|
21
|
+
flexDirection: "row",
|
|
22
|
+
},
|
|
23
|
+
hideScrollbars: {
|
|
24
|
+
scrollbarWidth: "none",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
const normalizeScrollEvent = (event) => {
|
|
28
|
+
const target = event.target;
|
|
29
|
+
const contentOffset = {
|
|
30
|
+
get x() {
|
|
31
|
+
return target.scrollLeft;
|
|
32
|
+
},
|
|
33
|
+
get y() {
|
|
34
|
+
return target.scrollTop;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const contentSize = {
|
|
38
|
+
get height() {
|
|
39
|
+
return target.scrollHeight;
|
|
40
|
+
},
|
|
41
|
+
get width() {
|
|
42
|
+
return target.scrollWidth;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const layoutMeasurement = {
|
|
46
|
+
get height() {
|
|
47
|
+
return target.offsetHeight;
|
|
48
|
+
},
|
|
49
|
+
get width() {
|
|
50
|
+
return target.offsetWidth;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
nativeEvent: { contentOffset, contentSize, layoutMeasurement },
|
|
55
|
+
timeStamp: Date.now(),
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
const shouldEmitScrollEvent = (state, eventThrottle) => !state.scrolling || (eventThrottle > 0 && Date.now() - state.lastTick >= eventThrottle);
|
|
59
|
+
export const ScrollView = forwardRef(({ children, contentContainerStyle, horizontal = false, onScroll, scrollEventThrottle = 16, showsScrollIndicators = true, style, ...viewProps }, forwardedRef) => {
|
|
60
|
+
const innerRef = useRef(null);
|
|
61
|
+
const stateRef = useRef({ lastTick: 0, scrolling: false });
|
|
62
|
+
const timeoutRef = useRef(null);
|
|
63
|
+
const mergedRef = useMergeRefs(innerRef, forwardedRef);
|
|
64
|
+
const handleOnScroll = useCallback((event) => {
|
|
65
|
+
event.stopPropagation();
|
|
66
|
+
// A scroll happened, so the scroll resets the scrollend timeout.
|
|
67
|
+
if (timeoutRef.current != null) {
|
|
68
|
+
clearTimeout(timeoutRef.current);
|
|
69
|
+
}
|
|
70
|
+
timeoutRef.current = setTimeout(() => {
|
|
71
|
+
stateRef.current.scrolling = false;
|
|
72
|
+
onScroll === null || onScroll === void 0 ? void 0 : onScroll(normalizeScrollEvent(event));
|
|
73
|
+
}, 100);
|
|
74
|
+
if (shouldEmitScrollEvent(stateRef.current, scrollEventThrottle)) {
|
|
75
|
+
stateRef.current.scrolling = true;
|
|
76
|
+
stateRef.current.lastTick = Date.now();
|
|
77
|
+
onScroll === null || onScroll === void 0 ? void 0 : onScroll(normalizeScrollEvent(event));
|
|
78
|
+
}
|
|
79
|
+
}, [onScroll, scrollEventThrottle]);
|
|
80
|
+
const scrollTo = useCallback(({ x = 0, y = 0, animated = true }) => {
|
|
81
|
+
const element = innerRef.current;
|
|
82
|
+
if (element != null) {
|
|
83
|
+
if (typeof element.scroll === "function") {
|
|
84
|
+
element.scroll({ top: y, left: x, behavior: !animated ? "auto" : "smooth" });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
element.scrollTop = y;
|
|
88
|
+
element.scrollLeft = x;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, []);
|
|
92
|
+
useImperativeHandle(innerRef, () => ({ scrollTo }));
|
|
93
|
+
return (_jsx(View, { ...viewProps, ref: mergedRef, onScroll: handleOnScroll, style: [
|
|
94
|
+
styles.base,
|
|
95
|
+
style,
|
|
96
|
+
horizontal && styles.horizontal,
|
|
97
|
+
!showsScrollIndicators && styles.hideScrollbars,
|
|
98
|
+
], children: _jsx(View, { style: [horizontal && styles.contentHorizontal, contentContainerStyle], children: children }) }));
|
|
99
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ForwardedRef, ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { StyleProp, ViewStyle, WebRole } from "react-native";
|
|
3
3
|
import { ListRenderItemInfo } from "./FlatList";
|
|
4
|
-
|
|
4
|
+
import { ScrollViewProps, ScrollViewRef } from "./ScrollView";
|
|
5
|
+
export type SectionListRef = ScrollViewRef;
|
|
5
6
|
type Section<T> = {
|
|
6
7
|
title: string;
|
|
7
8
|
data: T[];
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment, forwardRef, useEffect, useId, useRef } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { ScrollView } from "./ScrollView";
|
|
4
5
|
const styles = StyleSheet.create({
|
|
5
6
|
scrollTracker: {
|
|
6
7
|
position: "absolute",
|
|
7
8
|
pointerEvents: "none",
|
|
8
|
-
bottom: 0,
|
|
9
|
-
left: 0,
|
|
10
9
|
right: 0,
|
|
10
|
+
bottom: 0,
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
|
-
const SectionListWithRef = ({ ItemSeparatorComponent, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, contentContainerStyle, horizontal = false, keyExtractor, onEndReached, onEndReachedThresholdPx = 200, onKeyDown, onScroll, renderItem, renderSectionHeader, role, scrollEventThrottle =
|
|
13
|
+
const SectionListWithRef = ({ ItemSeparatorComponent, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, contentContainerStyle, horizontal = false, keyExtractor, onEndReached, onEndReachedThresholdPx = 200, onKeyDown, onScroll, renderItem, renderSectionHeader, role, scrollEventThrottle = 16, sections, showsScrollIndicators = true, style, }, forwardedRef) => {
|
|
14
14
|
const groupId = useId();
|
|
15
15
|
const scrollTrackerRef = useRef(null);
|
|
16
16
|
const scrollTrackerStyle = horizontal
|
|
17
|
-
? { width: onEndReachedThresholdPx }
|
|
18
|
-
: { height: onEndReachedThresholdPx };
|
|
17
|
+
? { top: 0, width: onEndReachedThresholdPx }
|
|
18
|
+
: { left: 0, height: onEndReachedThresholdPx };
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
const element = scrollTrackerRef.current;
|
|
21
21
|
if (element != null) {
|
|
@@ -33,8 +33,8 @@ const SectionListWithRef = ({ ItemSeparatorComponent, ListEmptyComponent, ListFo
|
|
|
33
33
|
}
|
|
34
34
|
// re-create an observer only on list length change
|
|
35
35
|
}, [sections.length]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
36
|
-
return (_jsxs(ScrollView, { contentContainerStyle: contentContainerStyle, horizontal: horizontal, onKeyDown: onKeyDown, onScroll: onScroll, ref: forwardedRef, role: role, scrollEventThrottle: scrollEventThrottle,
|
|
36
|
+
return (_jsxs(ScrollView, { contentContainerStyle: contentContainerStyle, horizontal: horizontal, onKeyDown: onKeyDown, onScroll: onScroll, ref: forwardedRef, role: role, scrollEventThrottle: scrollEventThrottle, showsScrollIndicators: showsScrollIndicators, style: style, children: [ListHeaderComponent, sections.length <= 0
|
|
37
37
|
? ListEmptyComponent
|
|
38
|
-
: sections.map(section => (_jsxs(Fragment, { children: [renderSectionHeader === null || renderSectionHeader === void 0 ? void 0 : renderSectionHeader(section), section.data.map((item, index) => (_jsxs(Fragment, { children: [index !== 0 && ItemSeparatorComponent, renderItem({ item, index })] }, keyExtractor(item, index))))] }, `group-${groupId}-${section.title}`))), _jsx(View, { ref: scrollTrackerRef, style: [styles.scrollTracker, scrollTrackerStyle] })
|
|
38
|
+
: sections.map(section => (_jsxs(Fragment, { children: [renderSectionHeader === null || renderSectionHeader === void 0 ? void 0 : renderSectionHeader(section), section.data.map((item, index) => (_jsxs(Fragment, { children: [index !== 0 && ItemSeparatorComponent, renderItem({ item, index })] }, keyExtractor(item, index))))] }, `group-${groupId}-${section.title}`))), ListFooterComponent, _jsx(View, { role: "none", ref: scrollTrackerRef, style: [styles.scrollTracker, scrollTrackerStyle] })] }));
|
|
39
39
|
};
|
|
40
40
|
export const SectionList = forwardRef(SectionListWithRef);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { ScrollView } from "./ScrollView";
|
|
4
5
|
const styles = StyleSheet.create({
|
|
5
6
|
track: {
|
|
6
7
|
position: "absolute",
|