Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ac98717
Merge branch 'release/v2.0.0' into develop
troberts-28 Nov 18, 2024
69ae768
📝 adjust performance section in README to reflect automatic adjustmen…
troberts-28 Nov 19, 2024
83a1681
Merge branch 'patch/docs-fix' into develop
troberts-28 Dec 3, 2024
63503e5
Merge branch 'patch/v2.0.1' into develop
troberts-28 Dec 3, 2024
66c0336
Merge branch 'patch/v2.0.2' into develop
troberts-28 Dec 16, 2024
4800a1a
✨ make it possible to supply the `MaskedView` component to fade out o…
troberts-28 Feb 10, 2025
7e1c1a5
📝 ➕ add `MaskedView` dependency to example and update example app to …
troberts-28 Feb 10, 2025
a0f45c0
📝 update docs to include MaskedView component
troberts-28 Feb 10, 2025
0fda1d9
📝 remove bottom/top gradient overlay style props from docs
troberts-28 Feb 10, 2025
9f0d067
💄 minor adjustment to third example to avoid label getting cutoff
troberts-28 Feb 10, 2025
44c172a
Merge branch 'patch/v2.0.3' into develop
troberts-28 Feb 10, 2025
72c2143
⬆️ update expo example dependencies
troberts-28 Feb 19, 2025
5e276b3
Merge branch 'develop' into feature/transparent-fadeout
troberts-28 Feb 19, 2025
66c38e3
Merge pull request #47 from troberts-28/feature/transparent-fadeout
troberts-28 Feb 19, 2025
a4bf21f
⬆️ upgrade yarn version
troberts-28 Feb 19, 2025
bb45dc5
📝 minor wording change for README
troberts-28 Feb 19, 2025
14adf2d
📝 update demo GIFs + README + expo example with updated examples
troberts-28 Feb 20, 2025
9dca3ff
🔖 bump version
troberts-28 Feb 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
874 changes: 0 additions & 874 deletions .yarn/releases/yarn-3.6.4.cjs

This file was deleted.

934 changes: 934 additions & 0 deletions .yarn/releases/yarn-4.6.0.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-3.6.4.cjs
yarnPath: .yarn/releases/yarn-4.6.0.cjs

nmHoistingLimits: workspaces # disable hoisting for all workspaces (causes issues with bare example)

46 changes: 30 additions & 16 deletions README.md

Large diffs are not rendered by default.

Binary file modified demos/example1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified demos/example2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified demos/example3.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified demos/example4.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 13 additions & 7 deletions examples/example-expo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import React, {
} from "react";

import Ionicons from "@expo/vector-icons/Ionicons";
import MaskedView from "@react-native-masked-view/masked-view";
import { Audio } from "expo-av";
import * as Haptics from "expo-haptics";
import { LinearGradient } from "expo-linear-gradient";
import {
Image,
LayoutAnimation,
Platform,
Pressable,
Expand Down Expand Up @@ -98,7 +100,7 @@ export default function App() {
<View style={styles.buttonContainer}>
<Text
style={[styles.button, styles.buttonDark]}>
Set Alarm 🔔
{"Set Alarm 🔔"}
</Text>
</View>
</TouchableOpacity>
Expand Down Expand Up @@ -156,7 +158,7 @@ export default function App() {
<View style={styles.buttonContainer}>
<Text
style={[styles.button, styles.buttonLight]}>
Set Alarm 🔔
{"Set Alarm 🔔"}
</Text>
</View>
</TouchableOpacity>
Expand Down Expand Up @@ -187,7 +189,10 @@ export default function App() {

const renderExample3 = useMemo(() => {
return (
<View
<LinearGradient
colors={["#202020", "#220578"]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={[
styles.container,
styles.page3Container,
Expand All @@ -198,12 +203,13 @@ export default function App() {
Haptics={Haptics}
hourLabel=":"
LinearGradient={LinearGradient}
MaskedView={MaskedView}
minuteLabel=":"
padWithNItems={2}
secondLabel=""
styles={{
theme: "dark",
backgroundColor: "#202020",
backgroundColor: "transparent",
pickerItem: {
fontSize: 34,
},
Expand All @@ -221,12 +227,12 @@ export default function App() {
right: -20,
top: 0,
bottom: 6,
width: 40,
width: 46,
alignItems: "center",
},
}}
/>
</View>
</LinearGradient>
);
}, [screenWidth]);

Expand Down Expand Up @@ -363,7 +369,7 @@ const styles = StyleSheet.create({
backgroundColor: "#F1F1F1",
},
page3Container: {
backgroundColor: "#202020",
flex: 1,
},
page4Container: {
backgroundColor: "#F1F1F1",
Expand Down
1 change: 1 addition & 0 deletions examples/example-expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"@expo/vector-icons": "^14.0.3",
"@react-native-masked-view/masked-view": "0.3.2",
"expo": "~52.0.31",
"expo-av": "~15.0.2",
"expo-haptics": "~14.0.1",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"url": "https://github.com/troberts-28"
},
"license": "MIT",
"version": "2.0.3",
"version": "2.1.0",
"main": "dist/commonjs/index.js",
"module": "dist/module/index.js",
"types": "dist/typescript/index.d.ts",
Expand Down
216 changes: 132 additions & 84 deletions src/components/DurationScroll/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
allowFontScaling = false,
amLabel,
Audio,
bottomPickerGradientOverlayProps,
clickSoundAsset,
disableInfiniteScroll = false,
FlatList = RNFlatList,
Expand All @@ -46,6 +45,7 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
label,
limit,
LinearGradient,
MaskedView,
maximumValue,
onDurationChange,
padNumbersWithZero = false,
Expand All @@ -57,7 +57,6 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
repeatNumbersNTimesNotExplicitlySet,
styles,
testID,
topPickerGradientOverlayProps,
} = props;

const numberOfItems = useMemo(() => {
Expand Down Expand Up @@ -495,6 +494,127 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
latestDuration: latestDuration,
}));

const renderContent = useMemo(() => {
return (
<>
<FlatList
key={flatListRenderKey}
ref={flatListRef}
contentContainerStyle={
styles.durationScrollFlatListContentContainer
}
data={numbersForFlatList}
decelerationRate={0.88}
getItemLayout={getItemLayout}
initialScrollIndex={initialScrollIndex}
keyExtractor={(_, index) => index.toString()}
nestedScrollEnabled
onMomentumScrollEnd={onMomentumScrollEnd}
onScroll={onScroll}
renderItem={renderItem}
scrollEnabled={!isDisabled}
scrollEventThrottle={16}
showsVerticalScrollIndicator={false}
snapToAlignment="start"
// used in place of snapToInterval due to bug on Android
snapToOffsets={[
...Array(numbersForFlatList.length),
].map((_, i) => i * styles.pickerItemContainer.height)}
style={styles.durationScrollFlatList}
testID="duration-scroll-flatlist"
viewabilityConfigCallbackPairs={
viewabilityConfigCallbackPairs
}
windowSize={numberOfItemsToShow}
/>
<View
pointerEvents="none"
style={styles.pickerLabelContainer}>
{typeof label === "string" ? (
<Text
allowFontScaling={allowFontScaling}
style={styles.pickerLabel}>
{label}
</Text>
) : (
label ?? null
)}
</View>
</>
);
}, [
FlatList,
allowFontScaling,
flatListRenderKey,
getItemLayout,
initialScrollIndex,
isDisabled,
label,
numberOfItemsToShow,
numbersForFlatList,
onMomentumScrollEnd,
onScroll,
renderItem,
styles.durationScrollFlatList,
styles.durationScrollFlatListContentContainer,
styles.pickerItemContainer.height,
styles.pickerLabel,
styles.pickerLabelContainer,
viewabilityConfigCallbackPairs,
]);

const renderLinearGradient = useMemo(() => {
if (!LinearGradient) {
return null;
}

let colors: string[];

if (MaskedView) {
// if using masked view, we only care about the opacity
colors = [
"rgba(0,0,0,0)",
"rgba(0,0,0,1)",
"rgba(0,0,0,1)",
"rgba(0,0,0,0)",
];
} else {
const backgroundColor =
styles.pickerContainer.backgroundColor ?? "white";
const transparentBackgroundColor = colorToRgba({
color: backgroundColor,
opacity: 0,
});
colors = [
backgroundColor,
transparentBackgroundColor,
transparentBackgroundColor,
backgroundColor,
];
}

// calculate the gradient height to cover the top item and bottom item
const gradientHeight =
padWithNItems > 0 ? 1 / (padWithNItems * 2 + 1) : 0.3;

return (
<LinearGradient
colors={colors}
locations={[0, gradientHeight, 1 - gradientHeight, 1]}
pointerEvents="none"
style={styles.pickerGradientOverlay}
{...pickerGradientOverlayProps}
/>
);
}, [
LinearGradient,
MaskedView,
padWithNItems,
pickerGradientOverlayProps,
styles.pickerContainer.backgroundColor,
styles.pickerGradientOverlay,
]);

return (
<View
pointerEvents={isDisabled ? "none" : undefined}
Expand All @@ -508,90 +628,18 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
isDisabled && styles.disabledPickerContainer,
]}
testID={testID}>
<FlatList
key={flatListRenderKey}
ref={flatListRef}
contentContainerStyle={
styles.durationScrollFlatListContentContainer
}
data={numbersForFlatList}
decelerationRate={0.88}
getItemLayout={getItemLayout}
initialScrollIndex={initialScrollIndex}
keyExtractor={(_, index) => index.toString()}
nestedScrollEnabled
onMomentumScrollEnd={onMomentumScrollEnd}
onScroll={onScroll}
renderItem={renderItem}
scrollEnabled={!isDisabled}
scrollEventThrottle={16}
showsVerticalScrollIndicator={false}
snapToAlignment="start"
// used in place of snapToInterval due to bug on Android
snapToOffsets={[...Array(numbersForFlatList.length)].map(
(_, i) => i * styles.pickerItemContainer.height
)}
style={styles.durationScrollFlatList}
testID="duration-scroll-flatlist"
viewabilityConfigCallbackPairs={
viewabilityConfigCallbackPairs
}
windowSize={numberOfItemsToShow}
/>
<View pointerEvents="none" style={styles.pickerLabelContainer}>
{typeof label === "string" ? (
<Text
allowFontScaling={allowFontScaling}
style={styles.pickerLabel}>
{label}
</Text>
) : (
label ?? null
)}
</View>
{LinearGradient ? (
{MaskedView ? (
<MaskedView
maskElement={renderLinearGradient}
style={[styles.maskedView]}>
{renderContent}
</MaskedView>
) : (
<>
<LinearGradient
colors={[
styles.pickerContainer.backgroundColor ??
"white",
colorToRgba({
color:
styles.pickerContainer
.backgroundColor ?? "white",
opacity: 0,
}),
]}
end={{ x: 1, y: 1 }}
pointerEvents="none"
start={{ x: 1, y: 0.3 }}
{...pickerGradientOverlayProps}
{...topPickerGradientOverlayProps}
style={[styles.pickerGradientOverlay, { top: 0 }]}
/>
<LinearGradient
colors={[
colorToRgba({
color:
styles.pickerContainer
.backgroundColor ?? "white",
opacity: 0,
}),
styles.pickerContainer.backgroundColor ??
"white",
]}
end={{ x: 1, y: 0.7 }}
pointerEvents="none"
start={{ x: 1, y: 0 }}
{...pickerGradientOverlayProps}
{...bottomPickerGradientOverlayProps}
style={[
styles.pickerGradientOverlay,
{ bottom: -1 },
]}
/>
{renderContent}
{renderLinearGradient}
</>
) : null}
)}
</View>
);
}
Expand Down
3 changes: 1 addition & 2 deletions src/components/DurationScroll/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export interface DurationScrollProps {
FlatList?: CustomFlatList;
Haptics?: any;
LinearGradient?: any;
MaskedView?: any;
aggressivelyGetLatestDuration: boolean;
allowFontScaling?: boolean;
amLabel?: string;
bottomPickerGradientOverlayProps?: Partial<LinearGradientProps>;
clickSoundAsset?: SoundAssetType;
disableInfiniteScroll?: boolean;
initialValue?: number;
Expand All @@ -44,7 +44,6 @@ export interface DurationScrollProps {
repeatNumbersNTimesNotExplicitlySet: boolean;
styles: ReturnType<typeof generateStyles>;
testID?: string;
topPickerGradientOverlayProps?: Partial<LinearGradientProps>;
}

export interface DurationScrollRef {
Expand Down
7 changes: 2 additions & 5 deletions src/components/TimerPicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,9 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
);

const styles = useMemo(
() =>
generateStyles(customStyles, {
padWithNItems: safePadWithNItems,
}),
() => generateStyles(customStyles),

[safePadWithNItems, customStyles]
[customStyles]
);

const [selectedHours, setSelectedHours] = useState(
Expand Down
Loading