Skip to content

Commit

Permalink
Merge branch 'release/v1.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
troberts-28 committed Jun 23, 2024
2 parents 8536205 + c97e904 commit 0659940
Show file tree
Hide file tree
Showing 27 changed files with 28,421 additions and 20,939 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ node_modules
example/src*
dist
*.tgz
android
android
ios
.yarn
92 changes: 83 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Includes iOS-style haptic and audio feedback 🍏
- [Props 💅](#props-)
- [TimerPicker ⏲️](#timerpicker-️)
- [Custom Styles 👗](#custom-styles-)
- [Custom FlatList](#custom-flatlist)
- [TimerPickerModal ⏰](#timerpickermodal-)
- [Custom Styles 👕](#custom-styles--1)
- [Methods 🔄](#methods-)
Expand Down Expand Up @@ -123,6 +124,30 @@ const [alarmString, setAlarmString] = useState<
string | null
>(null);

const formatTime = ({
hours,
minutes,
seconds,
}: {
hours?: number;
minutes?: number;
seconds?: number;
}) => {
const timeParts = [];

if (hours !== undefined) {
timeParts.push(hours.toString().padStart(2, "0"));
}
if (minutes !== undefined) {
timeParts.push(minutes.toString().padStart(2, "0"));
}
if (seconds !== undefined) {
timeParts.push(seconds.toString().padStart(2, "0"));
}

return timeParts.join(":");
};

return (
<View style={{backgroundColor: "#514242", alignItems: "center", justifyContent: "center"}}>
<Text style={{fontSize: 18, color: "#F1F1F1"}}>
Expand Down Expand Up @@ -201,6 +226,30 @@ const [alarmString, setAlarmString] = useState<
string | null
>(null);

const formatTime = ({
hours,
minutes,
seconds,
}: {
hours?: number;
minutes?: number;
seconds?: number;
}) => {
const timeParts = [];

if (hours !== undefined) {
timeParts.push(hours.toString().padStart(2, "0"));
}
if (minutes !== undefined) {
timeParts.push(minutes.toString().padStart(2, "0"));
}
if (seconds !== undefined) {
timeParts.push(seconds.toString().padStart(2, "0"));
}

return timeParts.join(":");
};

return (
<View style={{backgroundColor: "#F1F1F1", alignItems: "center", justifyContent: "center"}}>
<Text style={{fontSize: 18, color: "#202020"}}>
Expand Down Expand Up @@ -400,6 +449,7 @@ return (
| LinearGradient | Linear Gradient Component | [expo-linear-gradient](https://www.npmjs.com/package/expo-linear-gradient).LinearGradient or [react-native-linear-gradient](https://www.npmjs.com/package/react-native-linear-gradient).default | - | false |
| Haptics | Haptics Namespace (required for Haptic feedback) | [expo-haptics](https://www.npmjs.com/package/expo-haptics) | - | false |
| Audio | Audio Class (required for audio feedback i.e. click sound) | [expo-av](https://www.npmjs.com/package/expo-av).Audio | - | false |
| FlatList | FlatList component used internally to implement each picker (hour, minutes and seconds). More info [below](#custom-flatlist) | [react-native](https://reactnative.dev/docs/flatlist).FlatList | `FlatList` from `react-native` | false |
| clickSoundAsset | Custom sound asset for click sound (required for offline click sound - download default [here](https://drive.google.com/uc?export=download&id=10e1YkbNsRh-vGx1jmS1Nntz8xzkBp4_I)) | require(.../somefolderpath) or {uri: www.someurl} | - | false |
| pickerContainerProps | Props for the picker container | `React.ComponentProps<typeof View>` | - | false |
| pickerGradientOverlayProps | Props for both gradient overlays | `Partial<LinearGradientProps>` | - | false |
Expand Down Expand Up @@ -429,6 +479,29 @@ The following custom styles can be supplied to re-style the component in any way

Note the minor limitations to the allowed styles for `pickerContainer` and `pickerItemContainer`. These are made because these styles are used for internal calculations and all possible `backgroundColor`/`height` types are not supported.


#### Custom FlatList

The library offers the ability to provide a custom component for the `<FlatList />`, instead of the default React Native component. This allows for more flexibility and integration with libraries like [react-native-gesture-handler](react-native-gesture-handler) or other components built on top of it, like [https://ui.gorhom.dev/components/bottom-sheet](https://ui.gorhom.dev/components/bottom-sheet).

E.g. if you want to place the timer picker within that bottom-sheet component, the scrolling detection from the bottom-sheet [would interfere](https://ui.gorhom.dev/components/bottom-sheet/troubleshooting#adding-horizontal-flatlist-or-scrollview-is-not-working-properly-on-android) with the one inside the timer picker, but it can be easily solved by providing the `FlatList` component from `react-native-gesture-handler` like this:

```Jsx
import { FlatList } from 'react-native-gesture-handler';
import { TimerPicker } from "react-native-timer-picker";

// ...

<TimerPicker
{...props}
FlatList={FlatList}
/>

```

**Important**:
The custom component needs to have the same interface as React Native's `<FlatList />` in order for it to work as expected. A complete reference of the current usage can be found [here](/src/components/DurationScroll/index.tsx)

### TimerPickerModal ⏰

The TimerPickerModal component accepts all [TimerPicker props](#timerpicker-️), and the below additional props.
Expand Down Expand Up @@ -520,9 +593,16 @@ Contributions to this project are more than welcome.
To get this project running locally:
1. Clone the Git repo.
2. Run `yarn setup` from the project root (this installs the dev dependencies and the example's additional dependencies)
3. Run `yarn start` to start the example in Expo Go.
4. Start adding cool stuff! Your changes should be immediately reflected in the Expo Go app.
2. Run `yarn` to install the base dependencies
3. Run `yarn setup` from the project root (this installs the example's additional dependencies)
4. Run `yarn start` to start the example in Expo Go.
5. Start adding cool stuff! Your changes should be immediately reflected in the Expo Go app.
You can also run the library in bare React Native:
1. Clone the Git repo.
2. Run `yarn` to install the base dependencies
3. Run `yarn setup-dev`.
4. Run `yarn start-bare:android` or `start-bare:ios` to start the project on an emulator/device.
### GitHub Guidelines
Expand All @@ -534,12 +614,6 @@ There are two permenant branches: `main` and `develop`. You should never work di
<br>
## Limitations ⚠
Nesting the `TimerPicker` component inside a vertical ScrollView is not supported. React Native will throw an error and the picker will not be scrollable. The modal component works fine in this scenario however.
<br>
## License 📝
This project is licensed under the [MIT License](LICENSE).
2 changes: 2 additions & 0 deletions example-bare/.bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
1 change: 0 additions & 1 deletion example-bare/.gitattributes

This file was deleted.

74 changes: 22 additions & 52 deletions example-bare/.gitignore
Original file line number Diff line number Diff line change
@@ -1,42 +1,3 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/

# Native
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

# @generated expo-cli sync-e7dcf75f4e856f7b6f3239b3f3a7dd614ee755a8
# The following patterns were generated by expo-cli

# OSX
#
.DS_Store
Expand All @@ -59,7 +20,7 @@ DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
ios/.xcode.env.local

# Android/IntelliJ
#
Expand All @@ -69,28 +30,37 @@ build/
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore

# node.js
#
node_modules/
npm-debug.log
yarn-error.log

# BUCK
buck-out/
\.buckd/
*.keystore
!debug.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/

# Bundle artifacts
**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/screenshots
**/fastlane/test_output

# Bundle artifact
*.jsbundle

# CocoaPods
# Ruby / CocoaPods
/ios/Pods/
/vendor/bundle/

# Expo
.expo/
web-build/
dist/
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*

# @end expo-cli
# testing
/coverage
1 change: 1 addition & 0 deletions example-bare/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
63 changes: 34 additions & 29 deletions example-bare/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useMemo, useState } from "react";

import {
ScrollView,
StyleSheet,
Expand All @@ -7,7 +8,7 @@ import {
View,
useWindowDimensions,
} from "react-native";

import LinearGradient from "react-native-linear-gradient";
import { TimerPicker, TimerPickerModal } from "react-native-timer-picker";

import { formatTime } from "./utils/formatTime";
Expand Down Expand Up @@ -55,21 +56,22 @@ export default function App() {
</View>
</TouchableOpacity>
<TimerPickerModal
visible={showPickerExample1}
setIsVisible={setShowPickerExample1}
closeOnOverlayPress
LinearGradient={LinearGradient}
modalProps={{
overlayOpacity: 0.2,
}}
modalTitle="Set Alarm"
onCancel={() => setShowPickerExample1(false)}
onConfirm={(pickedDuration) => {
setAlarmStringExample1(formatTime(pickedDuration));
setShowPickerExample1(false);
}}
modalTitle="Set Alarm"
onCancel={() => setShowPickerExample1(false)}
closeOnOverlayPress
setIsVisible={setShowPickerExample1}
styles={{
theme: "dark",
}}
modalProps={{
overlayOpacity: 0.2,
}}
visible={showPickerExample1}
/>
</View>
);
Expand Down Expand Up @@ -110,18 +112,19 @@ export default function App() {
</View>
</TouchableOpacity>
<TimerPickerModal
visible={showPickerExample2}
setIsVisible={setShowPickerExample2}
closeOnOverlayPress
LinearGradient={LinearGradient}
modalTitle="Set Alarm"
onCancel={() => setShowPickerExample2(false)}
onConfirm={(pickedDuration) => {
setAlarmStringExample2(formatTime(pickedDuration));
setShowPickerExample2(false);
}}
modalTitle="Set Alarm"
onCancel={() => setShowPickerExample2(false)}
closeOnOverlayPress
setIsVisible={setShowPickerExample2}
styles={{
theme: "light",
}}
visible={showPickerExample2}
/>
</View>
);
Expand All @@ -136,23 +139,24 @@ export default function App() {
{ width: screenWidth },
]}>
<TimerPicker
padWithNItems={2}
hourLabel=":"
minuteLabel=":"
secondLabel=""
disableInfiniteScroll={true}
hideSeconds={true}
hourLabel="hr"
initialHours={0}
initialMinutes={0}
initialSeconds={0}
LinearGradient={LinearGradient}
minuteLabel="min"
styles={{
theme: "dark",
backgroundColor: "#202020",
pickerItem: {
fontSize: 34,
},
pickerLabel: {
fontSize: 32,
marginTop: 0,
},
theme: "light",
backgroundColor: "#ffffff",
pickerItem: { fontSize: 18 },
pickerLabel: { fontSize: 18 },
pickerContainer: {
marginRight: 6,
justifyContent: "center",
columnGap: 16,
},
pickerLabelContainer: { right: -16 },
}}
/>
</View>
Expand All @@ -168,9 +172,10 @@ export default function App() {
{ width: screenWidth },
]}>
<TimerPicker
padWithNItems={3}
hideHours
LinearGradient={LinearGradient}
minuteLabel="min"
padWithNItems={3}
secondLabel="sec"
styles={{
theme: "light",
Expand Down
9 changes: 9 additions & 0 deletions example-bare/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source 'https://rubygems.org'

# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"

# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
# bound in the template on Cocoapods with next React Native release.
gem 'cocoapods', '>= 1.13', '< 1.15'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
Loading

0 comments on commit 0659940

Please sign in to comment.