├── .buckconfig ├── .eslintrc ├── .flowconfig ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── App.js ├── Gemfile ├── __tests__ └── App-test.js ├── _bundle └── config ├── _ruby-version ├── app.json ├── babel.config.js ├── index.js ├── metro.config.js ├── package.json ├── src ├── Slider │ ├── Label.js │ ├── Notch.js │ ├── Rail.js │ ├── RailSelected.js │ └── Thumb.js └── screens │ ├── Slider │ ├── index.js │ └── styles.js │ └── components │ └── TextButton.js ├── tsconfig.json └── yarn.lock /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "airbnb", 4 | "airbnb/hooks", 5 | "plugin:@typescript-eslint/recommended", 6 | "prettier", 7 | // "prettier/react", 8 | // "prettier/@typescript-eslint", 9 | "plugin:prettier/recommended" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "ecmaFeatures": { 14 | "jsx": true 15 | }, 16 | "ecmaVersion": 2018, 17 | "sourceType": "module", 18 | "project": "./tsconfig.json" 19 | }, 20 | "plugins": [ 21 | "@typescript-eslint", 22 | "react", 23 | "prettier" 24 | ], 25 | "rules": { 26 | "func-names": 0, 27 | "camelcase": 0, 28 | "no-continue": 0, 29 | "import/extensions": [ 30 | "error", 31 | "never" 32 | ], 33 | "import/no-unresolved": 0, 34 | "import/prefer-default-export": 0, 35 | "jsx-a11y/accessible-emoji": 0, 36 | "prettier/prettier": [ 37 | "error", 38 | { 39 | "singleQuote": true, 40 | "trailingComma": "all", 41 | "arrowParens": "avoid", 42 | "endOfLine": "auto" 43 | } 44 | ], 45 | "react/jsx-filename-extension": [ 46 | 1, 47 | { 48 | "extensions": [ 49 | ".ts", 50 | ".tsx" 51 | ] 52 | } 53 | ], 54 | "react/jsx-one-expression-per-line": "warn", 55 | "react/prop-types": 0, 56 | "react/require-default-props": 0, 57 | "react/style-prop-object": 0, 58 | "react/jsx-props-no-spreading": 0, 59 | "react/no-array-index-key": 0, 60 | // "semi": ["error", "never"], 61 | "no-plusplus": [ 62 | "error", 63 | { 64 | "allowForLoopAfterthoughts": true 65 | } 66 | ], 67 | "no-shadow": "off", 68 | "no-use-before-define": "off", 69 | "no-unused-expressions": 0, 70 | "no-alert": 0, 71 | "@typescript-eslint/ban-ts-comment": 0, 72 | "@typescript-eslint/explicit-function-return-type": 0, 73 | "@typescript-eslint/explicit-member-accessibility": 0, 74 | "@typescript-eslint/no-shadow": [ 75 | "error" 76 | ], 77 | "@typescript-eslint/no-use-before-define": [ 78 | "error", 79 | { 80 | "functions": true, 81 | "classes": true, 82 | "variables": false 83 | } 84 | ], 85 | "@typescript-eslint/no-var-requires": 0, 86 | "react-hooks/exhaustive-deps": 1, 87 | "consistent-return": 1, 88 | "require-yield": 1, 89 | "no-param-reassign": 0, 90 | "no-nested-ternary": 0 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore polyfills 9 | node_modules/react-native/Libraries/polyfills/.* 10 | 11 | ; Flow doesn't support platforms 12 | .*/Libraries/Utilities/LoadingView.js 13 | 14 | .*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$ 15 | 16 | [untyped] 17 | .*/node_modules/@react-native-community/cli/.*/.* 18 | 19 | [include] 20 | 21 | [libs] 22 | node_modules/react-native/interface.js 23 | node_modules/react-native/flow/ 24 | 25 | [options] 26 | emoji=true 27 | 28 | exact_by_default=true 29 | 30 | format.bracket_spacing=false 31 | 32 | module.file_ext=.js 33 | module.file_ext=.json 34 | module.file_ext=.ios.js 35 | 36 | munge_underscores=true 37 | 38 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 39 | module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' 40 | 41 | suppress_type=$FlowIssue 42 | suppress_type=$FlowFixMe 43 | suppress_type=$FlowFixMeProps 44 | suppress_type=$FlowFixMeState 45 | 46 | [lints] 47 | sketchy-null-number=warn 48 | sketchy-null-mixed=warn 49 | sketchy-number=warn 50 | untyped-type-import=warn 51 | nonstrict-import=warn 52 | deprecated-type=warn 53 | unsafe-getters-setters=warn 54 | unnecessary-invariant=warn 55 | 56 | [strict] 57 | deprecated-type 58 | nonstrict-import 59 | sketchy-null 60 | unclear-type 61 | unsafe-getters-setters 62 | untyped-import 63 | untyped-type-import 64 | 65 | [version] 66 | ^0.176.3 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | 34 | # node.js 35 | # 36 | node_modules/ 37 | npm-debug.log 38 | yarn-error.log 39 | 40 | # BUCK 41 | buck-out/ 42 | \.buckd/ 43 | *.keystore 44 | !debug.keystore 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/ 52 | 53 | **/fastlane/report.xml 54 | **/fastlane/Preview.html 55 | **/fastlane/screenshots 56 | **/fastlane/test_output 57 | 58 | # Bundle artifact 59 | *.jsbundle 60 | 61 | # Ruby / CocoaPods 62 | /vendor/bundle/ 63 | 64 | /android 65 | /ios 66 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import SliderScreen from './src/screens/Slider'; 4 | 5 | const App = () => { 6 | return ; 7 | }; 8 | 9 | export default App; 10 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '2.7.5' 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2' 7 | -------------------------------------------------------------------------------- /__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /_bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /_ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.5 2 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DemoApp", 3 | "displayName": "DemoApp" 4 | } -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: true, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DemoApp", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "react": "18.0.0", 14 | "react-native": "0.69.5", 15 | "rn-range-slider": "^2.2.1" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.12.9", 19 | "@types/react": "~17.0.21", 20 | "@types/react-native": "~0.64.12", 21 | "@types/react-redux": "^7.1.16", 22 | "@typescript-eslint/eslint-plugin": "^4.23.0", 23 | "@typescript-eslint/parser": "^4.23.0", 24 | "eslint": "^7.26.0", 25 | "eslint-config-airbnb": "^18.2.1", 26 | "eslint-config-prettier": "^8.3.0", 27 | "eslint-plugin-import": "^2.22.1", 28 | "eslint-plugin-jsx-a11y": "^6.4.1", 29 | "eslint-plugin-prettier": "^3.4.0", 30 | "eslint-plugin-react": "^7.23.2", 31 | "eslint-plugin-react-hooks": "^4.2.0", 32 | "prettier": "^2.3.0" 33 | }, 34 | "jest": { 35 | "preset": "react-native" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Slider/Label.js: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import { View, Text, StyleSheet } from 'react-native'; 3 | 4 | const Label = ({ text, ...restProps }) => { 5 | return ( 6 | 7 | {text} 8 | 9 | ); 10 | }; 11 | 12 | const styles = StyleSheet.create({ 13 | root: { 14 | alignItems: 'center', 15 | padding: 8, 16 | backgroundColor: '#4499ff', 17 | borderRadius: 4, 18 | }, 19 | text: { 20 | fontSize: 16, 21 | color: '#fff', 22 | }, 23 | }); 24 | 25 | export default memo(Label); 26 | -------------------------------------------------------------------------------- /src/Slider/Notch.js: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import { View, StyleSheet } from 'react-native'; 3 | 4 | const Notch = props => { 5 | return ( 6 | 7 | ); 8 | }; 9 | 10 | export default memo(Notch); 11 | 12 | const styles = StyleSheet.create({ 13 | root: { 14 | width: 8, 15 | height: 8, 16 | borderLeftColor: 'transparent', 17 | borderRightColor: 'transparent', 18 | borderTopColor: '#4499ff', 19 | borderLeftWidth: 4, 20 | borderRightWidth: 4, 21 | borderTopWidth: 8, 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /src/Slider/Rail.js: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import { View, StyleSheet } from 'react-native'; 3 | 4 | const Rail = () => { 5 | return ( 6 | 7 | ); 8 | }; 9 | 10 | export default memo(Rail); 11 | 12 | const styles = StyleSheet.create({ 13 | root: { 14 | flex: 1, 15 | height: 4, 16 | borderRadius: 2, 17 | backgroundColor: '#7f7f7f', 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /src/Slider/RailSelected.js: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import {StyleSheet, View} from 'react-native'; 3 | 4 | const RailSelected = () => { 5 | return ( 6 | 7 | ); 8 | }; 9 | 10 | export default memo(RailSelected); 11 | 12 | const styles = StyleSheet.create({ 13 | root: { 14 | height: 4, 15 | backgroundColor: '#4499ff', 16 | borderRadius: 2, 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /src/Slider/Thumb.js: -------------------------------------------------------------------------------- 1 | import React, {memo} from 'react'; 2 | import {View, StyleSheet} from 'react-native'; 3 | 4 | const THUMB_RADIUS_LOW = 12; 5 | const THUMB_RADIUS_HIGH = 16; 6 | 7 | const Thumb = ({name}) => { 8 | return ; 9 | }; 10 | 11 | const styles = StyleSheet.create({ 12 | rootLow: { 13 | width: THUMB_RADIUS_LOW * 2, 14 | height: THUMB_RADIUS_LOW * 2, 15 | borderRadius: THUMB_RADIUS_LOW, 16 | borderWidth: 2, 17 | borderColor: '#7f7f7f', 18 | backgroundColor: '#aaaaaa', 19 | }, 20 | rootHigh: { 21 | width: THUMB_RADIUS_HIGH * 2, 22 | height: THUMB_RADIUS_HIGH * 2, 23 | borderRadius: THUMB_RADIUS_HIGH, 24 | borderWidth: 2, 25 | borderColor: '#7f7f7f', 26 | backgroundColor: '#ffffff', 27 | }, 28 | }); 29 | 30 | export default memo(Thumb); 31 | -------------------------------------------------------------------------------- /src/screens/Slider/index.js: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {View, Text, ScrollView} from 'react-native'; 3 | import Slider from 'rn-range-slider'; 4 | 5 | import Thumb from '../../Slider/Thumb'; 6 | import Rail from '../../Slider/Rail'; 7 | import RailSelected from '../../Slider/RailSelected'; 8 | import Notch from '../../Slider/Notch'; 9 | import Label from '../../Slider/Label'; 10 | import TextButton from '../components/TextButton'; 11 | 12 | import styles from './styles'; 13 | 14 | const SliderScreen = () => { 15 | const [rangeDisabled, setRangeDisabled] = useState(false); 16 | const [low, setLow] = useState(0); 17 | const [high, setHigh] = useState(100); 18 | const [min, setMin] = useState(0); 19 | const [max, setMax] = useState(100); 20 | const [floatingLabel, setFloatingLabel] = useState(false); 21 | 22 | const renderThumb = useCallback( 23 | (name: 'high' | 'low') => , 24 | [], 25 | ); 26 | const renderRail = useCallback(() => , []); 27 | const renderRailSelected = useCallback(() => , []); 28 | const renderLabel = useCallback(value =>