Skip to content

Commit 93c3747

Browse files
authored
Add simple style variants of scrollable components (#843)
* Add simple style variants of scrollable components * Undo change to App.tsx * Use hook with measured size to calculate styles
1 parent 1dfb395 commit 93c3747

17 files changed

+370
-4
lines changed

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"react-native-deck-swiper": "^2.0.12",
6262
"react-native-dropdown-picker": "^5.4.7-beta.1",
6363
"react-native-gesture-handler": "~2.12.0",
64+
"react-native-keyboard-aware-scroll-view": "^0.9.5",
6465
"react-native-markdown-display": "^7.0.0-alpha.2",
6566
"react-native-modal-datetime-picker": "^13.0.0",
6667
"react-native-pager-view": "6.2.0",

packages/core/src/components/SectionList/SectionList.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ interface AdditionalSectionListProps<T> {
1818
listComponent?: ListComponentType;
1919
}
2020

21-
type FlatListSectionListProps<T> = Omit<FlatListProps<T>, "renderItem"> &
21+
export type FlatListSectionListProps<T> = Omit<FlatListProps<T>, "renderItem"> &
2222
AdditionalSectionListProps<T>;
2323

24-
type FlashListSectionListProps<T> = Omit<FlashListProps<T>, "renderItem"> &
24+
export type FlashListSectionListProps<T> = Omit<
25+
FlashListProps<T>,
26+
"renderItem"
27+
> &
2528
AdditionalSectionListProps<T>;
2629

2730
interface SectionListDataItem<T> {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
export { default as SectionList } from "./SectionList";
22
export { default as SectionHeader } from "./SectionHeader";
3+
export type {
4+
FlatListSectionListProps,
5+
FlashListSectionListProps,
6+
} from "./SectionList";
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Why do we need these components?
2+
3+
At it's current state the Draftbit builder has a single interface for setting the styles of a component. With these scrollable components, there are 2 style props `style` and `contentContainerStyle`. To simplify the codegen on the draftbit side and hide the complexity from the user, these components take a single style and distrubte them across both style props appropriately.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from "react";
2+
import { FlashList } from "@shopify/flash-list";
3+
import type { FlashListProps, ContentStyle } from "@shopify/flash-list";
4+
import useSplitContentContainerStyles from "./useSplitContentContainerStyles";
5+
6+
/**
7+
* A FlashList wrapper that takes a single `style` prop and internally extracts
8+
* the appropriate style keys into the `contentContainerStyle`
9+
*/
10+
const SimpleStyleFlashList = <T extends any>({
11+
style: styleProp,
12+
...rest
13+
}: Omit<FlashListProps<T>, "contentContainerStyle">) => {
14+
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
15+
const [measuredHeight, setMeasuredHeight] = React.useState<number>();
16+
17+
const { style, contentContainerStyle } = useSplitContentContainerStyles(
18+
styleProp,
19+
measuredWidth,
20+
measuredHeight
21+
);
22+
23+
return (
24+
<FlashList
25+
onLayout={(event) => {
26+
setMeasuredWidth(event.nativeEvent.layout.width);
27+
setMeasuredHeight(event.nativeEvent.layout.height);
28+
}}
29+
style={style}
30+
contentContainerStyle={contentContainerStyle as ContentStyle}
31+
{...rest}
32+
/>
33+
);
34+
};
35+
36+
export default SimpleStyleFlashList;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from "react";
2+
import { FlatList } from "react-native";
3+
import type { FlatListProps } from "react-native";
4+
import useSplitContentContainerStyles from "./useSplitContentContainerStyles";
5+
6+
/**
7+
* A FlatList wrapper that takes a single `style` prop and internally extracts
8+
* the appropriate style keys into the `contentContainerStyle`
9+
*/
10+
const SimpleStyleFlatList = <T extends any>({
11+
style: styleProp,
12+
...rest
13+
}: Omit<FlatListProps<T>, "contentContainerStyle">) => {
14+
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
15+
const [measuredHeight, setMeasuredHeight] = React.useState<number>();
16+
17+
const { style, contentContainerStyle } = useSplitContentContainerStyles(
18+
styleProp,
19+
measuredWidth,
20+
measuredHeight
21+
);
22+
23+
return (
24+
<FlatList
25+
onLayout={(event) => {
26+
setMeasuredWidth(event.nativeEvent.layout.width);
27+
setMeasuredHeight(event.nativeEvent.layout.height);
28+
}}
29+
style={style}
30+
contentContainerStyle={contentContainerStyle}
31+
{...rest}
32+
/>
33+
);
34+
};
35+
36+
export default SimpleStyleFlatList;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from "react";
2+
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
3+
import type { KeyboardAwareScrollViewProps } from "react-native-keyboard-aware-scroll-view";
4+
import useSplitContentContainerStyles from "./useSplitContentContainerStyles";
5+
6+
/**
7+
* A KeyboardAwareScrollView wrapper that takes a single `style` prop and internally extracts
8+
* the appropriate style keys into the `contentContainerStyle`
9+
*/
10+
const SimpleStyleKeyboardAwareScrollView: React.FC<
11+
Omit<KeyboardAwareScrollViewProps, "contentContainerStyle">
12+
> = ({ style: styleProp, ...rest }) => {
13+
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
14+
const [measuredHeight, setMeasuredHeight] = React.useState<number>();
15+
16+
const { style, contentContainerStyle } = useSplitContentContainerStyles(
17+
styleProp,
18+
measuredWidth,
19+
measuredHeight
20+
);
21+
22+
return (
23+
<KeyboardAwareScrollView
24+
onLayout={(event) => {
25+
setMeasuredWidth(event.nativeEvent.layout.width);
26+
setMeasuredHeight(event.nativeEvent.layout.height);
27+
}}
28+
style={style}
29+
contentContainerStyle={contentContainerStyle}
30+
{...rest}
31+
/>
32+
);
33+
};
34+
35+
export default SimpleStyleKeyboardAwareScrollView;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from "react";
2+
import { MasonryFlashList } from "@shopify/flash-list";
3+
import type { MasonryFlashListProps, ContentStyle } from "@shopify/flash-list";
4+
import useSplitContentContainerStyles from "./useSplitContentContainerStyles";
5+
6+
/**
7+
* A MasonryFlashList wrapper that takes a single `style` prop and internally extracts
8+
* the appropriate style keys into the `contentContainerStyle`
9+
*/
10+
const SimpleStyleMasonryFlashList = <T extends any>({
11+
style: styleProp,
12+
...rest
13+
}: Omit<MasonryFlashListProps<T>, "contentContainerStyle">) => {
14+
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
15+
const [measuredHeight, setMeasuredHeight] = React.useState<number>();
16+
17+
const { style, contentContainerStyle } = useSplitContentContainerStyles(
18+
styleProp,
19+
measuredWidth,
20+
measuredHeight
21+
);
22+
23+
return (
24+
<MasonryFlashList
25+
onLayout={(event) => {
26+
setMeasuredWidth(event.nativeEvent.layout.width);
27+
setMeasuredHeight(event.nativeEvent.layout.height);
28+
}}
29+
style={style}
30+
contentContainerStyle={contentContainerStyle as ContentStyle}
31+
{...rest}
32+
/>
33+
);
34+
};
35+
36+
export default SimpleStyleMasonryFlashList;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from "react";
2+
import { ScrollView } from "react-native";
3+
import type { ScrollViewProps } from "react-native";
4+
import useSplitContentContainerStyles from "./useSplitContentContainerStyles";
5+
6+
/**
7+
* A ScrollView wrapper that takes a single `style` prop and internally extracts
8+
* the appropriate style keys into the `contentContainerStyle`
9+
*/
10+
const SimpleStyleScrollView: React.FC<
11+
Omit<ScrollViewProps, "contentContainerStyle">
12+
> = ({ style: styleProp, ...rest }) => {
13+
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
14+
const [measuredHeight, setMeasuredHeight] = React.useState<number>();
15+
16+
const { style, contentContainerStyle } = useSplitContentContainerStyles(
17+
styleProp,
18+
measuredWidth,
19+
measuredHeight
20+
);
21+
22+
return (
23+
<ScrollView
24+
onLayout={(event) => {
25+
setMeasuredWidth(event.nativeEvent.layout.width);
26+
setMeasuredHeight(event.nativeEvent.layout.height);
27+
}}
28+
style={style}
29+
contentContainerStyle={contentContainerStyle}
30+
{...rest}
31+
/>
32+
);
33+
};
34+
35+
export default SimpleStyleScrollView;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from "react";
2+
import { SectionList } from "../SectionList";
3+
import type {
4+
FlatListSectionListProps,
5+
FlashListSectionListProps,
6+
} from "../SectionList";
7+
import useSplitContentContainerStyles from "./useSplitContentContainerStyles";
8+
9+
/**
10+
* A SectionList wrapper that takes a single `style` prop and internally extracts
11+
* the appropriate style keys into the `contentContainerStyle`
12+
*/
13+
const SimpleStyleSectionList = <T extends { [key: string]: any }>({
14+
style: styleProp,
15+
...rest
16+
}: Omit<
17+
FlatListSectionListProps<T> | FlashListSectionListProps<T>,
18+
"contentContainerStyle"
19+
>) => {
20+
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
21+
const [measuredHeight, setMeasuredHeight] = React.useState<number>();
22+
23+
const { style, contentContainerStyle } = useSplitContentContainerStyles(
24+
styleProp,
25+
measuredWidth,
26+
measuredHeight
27+
);
28+
29+
return (
30+
//@ts-ignore contentContainerStyle has different types for FlashList and FlatList implmentations and confuses TS
31+
<SectionList
32+
onLayout={(event) => {
33+
setMeasuredWidth(event.nativeEvent.layout.width);
34+
setMeasuredHeight(event.nativeEvent.layout.height);
35+
}}
36+
style={style}
37+
contentContainerStyle={contentContainerStyle}
38+
{...rest}
39+
/>
40+
);
41+
};
42+
43+
export default SimpleStyleSectionList;

0 commit comments

Comments
 (0)