Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
185 changes: 111 additions & 74 deletions README.md

Large diffs are not rendered by default.

1,242 changes: 631 additions & 611 deletions src/components/DurationScroll/DurationScroll.tsx

Large diffs are not rendered by default.

104 changes: 56 additions & 48 deletions src/components/DurationScroll/types.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,81 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { RefObject } from "react";
import type React from "react";
import { type RefObject } from "react";

import type { View } from "react-native";

import type { generateStyles } from "../TimerPicker/styles";

export interface DurationScrollProps {
Audio?: any;
FlatList?: any;
Haptics?: any;
LinearGradient?: any;
MaskedView?: any;
aggressivelyGetLatestDuration: boolean;
allowFontScaling?: boolean;
amLabel?: string;
clickSoundAsset?: SoundAsset;
decelerationRate?: number | "normal" | "fast";
disableInfiniteScroll?: boolean;
initialValue?: number;
interval: number;
is12HourPicker?: boolean;
isDisabled?: boolean;
label?: string | React.ReactElement;
limit?: Limit;
maximumValue: number;
onDurationChange: (duration: number) => void;
padNumbersWithZero?: boolean;
padWithNItems: number;
pickerFeedback?: () => void | Promise<void>;
pickerGradientOverlayProps?: Partial<LinearGradientProps>;
pmLabel?: string;
repeatNumbersNTimes?: number;
repeatNumbersNTimesNotExplicitlySet: boolean;
styles: ReturnType<typeof generateStyles>;
testID?: string;
aggressivelyGetLatestDuration: boolean;
allowFontScaling?: boolean;
amLabel?: string;
accessibilityHint?: string;
accessibilityLabel?: string;
Audio?: any;
clickSoundAsset?: SoundAsset;
decelerationRate?: number | "normal" | "fast";
disableInfiniteScroll?: boolean;
FlatList?: any;
formatValue?: (value: number) => string;
Haptics?: any;
initialValue?: number;
interval: number;
is12HourPicker?: boolean;
isDisabled?: boolean;
isScreenReaderEnabled?: boolean;
label?: string | React.ReactElement;
limit?: Limit;
LinearGradient?: any;
MaskedView?: any;
maximumValue: number;
onDurationChange: (duration: number) => void;
padNumbersWithZero?: boolean;
padWithNItems: number;
pickerColumnWidth?: number;
pickerFeedback?: () => void | Promise<void>;
pickerGradientOverlayProps?: Partial<LinearGradientProps>;
pickerLabelGap?: number;
pmLabel?: string;
repeatNumbersNTimes?: number;
repeatNumbersNTimesNotExplicitlySet: boolean;
selectedValue?: number;
styles: ReturnType<typeof generateStyles>;
testID?: string;
}

export interface DurationScrollRef {
latestDuration: RefObject<number>;
reset: (options?: { animated?: boolean }) => void;
setValue: (value: number, options?: { animated?: boolean }) => void;
latestDuration: RefObject<number>;
reset: (options?: { animated?: boolean }) => void;
setValue: (value: number, options?: { animated?: boolean }) => void;
}

type LinearGradientPoint = {
x: number;
y: number;
x: number;
y: number;
};

export type LinearGradientProps = React.ComponentProps<typeof View> & {
colors: string[];
end?: LinearGradientPoint | null;
locations?: number[] | null;
start?: LinearGradientPoint | null;
colors: string[];
end?: LinearGradientPoint | null;
locations?: number[] | null;
start?: LinearGradientPoint | null;
};

export type Limit = {
max?: number;
min?: number;
max?: number;
min?: number;
};

export type SoundAsset =
| number
| {
headers?: Record<string, string>;
overrideFileExtensionAndroid?: string;
uri: string;
};
| number
| {
headers?: Record<string, string>;
overrideFileExtensionAndroid?: string;
uri: string;
};

export type ExpoAvAudioInstance = {
replayAsync: () => Promise<void>;
unloadAsync: () => Promise<void>;
replayAsync: () => Promise<void>;
unloadAsync: () => Promise<void>;
};
114 changes: 58 additions & 56 deletions src/components/PickerItem/PickerItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,69 @@ import { View, Text } from "react-native";
import type { generateStyles } from "../TimerPicker/styles";

interface PickerItemProps {
adjustedLimitedMax: number;
adjustedLimitedMin: number;
allowFontScaling: boolean;
amLabel?: string;
is12HourPicker?: boolean;
item: string;
pmLabel?: string;
styles: ReturnType<typeof generateStyles>;
adjustedLimitedMax: number;
adjustedLimitedMin: number;
allowFontScaling: boolean;
amLabel?: string;
is12HourPicker?: boolean;
item: string;
pickerAmPmPositionStyle?: { left: "50%"; marginLeft: number };
pmLabel?: string;
selectedValue?: number;
styles: ReturnType<typeof generateStyles>;
}

const PickerItem = React.memo<PickerItemProps>(
({
adjustedLimitedMax,
adjustedLimitedMin,
allowFontScaling,
amLabel,
is12HourPicker,
item,
pmLabel,
styles,
}) => {
let stringItem = item;
let intItem: number;
let isAm: boolean | undefined;
({
adjustedLimitedMax,
adjustedLimitedMin,
allowFontScaling,
amLabel,
is12HourPicker,
item,
pickerAmPmPositionStyle,
pmLabel,
selectedValue,
styles,
}) => {
let stringItem = item;
let intItem: number;
let isAm: boolean | undefined;

if (!is12HourPicker) {
intItem = parseInt(item);
} else {
isAm = item.includes("AM");
stringItem = item.replace(/\s[AP]M/g, "");
intItem = parseInt(stringItem);
}

return (
<View
key={item}
style={styles.pickerItemContainer}
testID="picker-item">
<Text
allowFontScaling={allowFontScaling}
style={[
styles.pickerItem,
intItem > adjustedLimitedMax ||
intItem < adjustedLimitedMin
? styles.disabledPickerItem
: {},
]}>
{stringItem}
</Text>
{is12HourPicker && (
<View style={styles.pickerAmPmContainer}>
<Text
allowFontScaling={allowFontScaling}
style={styles.pickerAmPmLabel}>
{isAm ? amLabel : pmLabel}
</Text>
</View>
)}
</View>
);
if (!is12HourPicker) {
intItem = parseInt(item);
} else {
isAm = item.includes("AM");
stringItem = item.replace(/\s[AP]M/g, "");
intItem = parseInt(stringItem);
}

const isSelected = intItem === selectedValue;

return (
<View key={item} style={styles.pickerItemContainer} testID="picker-item">
<Text
allowFontScaling={allowFontScaling}
style={[
styles.pickerItem,
isSelected && styles.selectedPickerItem,
intItem > adjustedLimitedMax || intItem < adjustedLimitedMin
? styles.disabledPickerItem
: {},
]}
>
{stringItem}
</Text>
{is12HourPicker && (
<View style={[styles.pickerAmPmContainer, pickerAmPmPositionStyle]}>
<Text allowFontScaling={allowFontScaling} style={styles.pickerAmPmLabel}>
{isAm ? amLabel : pmLabel}
</Text>
</View>
)}
</View>
);
}
);

export default PickerItem;
Loading