├── .husky ├── .npmignore ├── pre-commit └── commit-msg ├── example ├── ruby-version ├── .bundle │ └── config ├── app.json ├── src │ ├── discount.png │ └── App.tsx ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── drawable │ │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── nativedialog │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ └── AndroidManifest.xml │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── build.gradle │ ├── gradle.properties │ ├── gradlew.bat │ └── gradlew ├── ios │ ├── NativeDialogExample │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ ├── appAccent.colorset │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── Info.plist │ │ ├── AppDelegate.m │ │ └── LaunchScreen.storyboard │ ├── NativeDialogExample-Bridging-Header.h │ ├── File.swift │ ├── NativeDialogExample.xcworkspace │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcworkspacedata │ ├── Podfile │ └── NativeDialogExample.xcodeproj │ │ └── xcshareddata │ │ └── xcschemes │ │ └── NativeDialogExample.xcscheme ├── Gemfile ├── index.tsx ├── babel.config.js ├── package.json ├── metro.config.js └── Gemfile.lock ├── docs ├── dialog.md ├── inputdialog.md ├── itemsdialog.md ├── ratingdialog.md └── numberpickerdialog.md ├── tsconfig.build.json ├── babel.config.js ├── ios ├── NativeDialog-Bridging-Header.h ├── NativeDialog.m ├── NativeDialog.xcodeproj │ └── xcshareddata │ │ └── xcschemes │ │ └── NativeDialog.xcscheme ├── NativeDialog │ ├── Extensions.swift │ ├── NumberPickerDialogOptions.swift │ ├── RatingDialogOptions.swift │ ├── NumberPickerViewController.xib │ ├── InputViewController.xib │ ├── RatingViewController.xib │ ├── InputDialogOptions.swift │ ├── ItemsDialogOptions.swift │ ├── ItemsViewController.xib │ └── DialogOptions.swift └── NativeDialog.swift ├── android ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ └── layout │ │ │ ├── dialog_number_picker.xml │ │ │ ├── dialog_input.xml │ │ │ └── dialog_rating.xml │ │ └── java │ │ └── com │ │ └── github │ │ └── mohaka │ │ └── nativedialog │ │ ├── NativeDialogPackage.java │ │ ├── NumberPickerDialogOptions.java │ │ ├── Utilities.java │ │ ├── RatingDialogOptions.java │ │ ├── ItemsDialogOptions.java │ │ ├── InputDialogOptions.java │ │ ├── DialogOptions.java │ │ └── NativeDialogModule.java └── build.gradle ├── .yarnrc ├── images └── create-bridging-header.gif ├── tsconfig.json ├── react-native-native-dialog.podspec ├── scripts └── bootstrap.js ├── .gitignore ├── LICENSE ├── .circleci └── config.yml ├── package.json ├── src ├── index.d.ts └── index.js ├── README.md └── CONTRIBUTING.md /.husky/.npmignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /example/ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.4 2 | -------------------------------------------------------------------------------- /docs/dialog.md: -------------------------------------------------------------------------------- 1 | # `showDialog()` Component API 2 | -------------------------------------------------------------------------------- /docs/inputdialog.md: -------------------------------------------------------------------------------- 1 | # `showInputDialog()` Component API 2 | -------------------------------------------------------------------------------- /docs/itemsdialog.md: -------------------------------------------------------------------------------- 1 | # `showItemsDialog()` Component API 2 | -------------------------------------------------------------------------------- /docs/ratingdialog.md: -------------------------------------------------------------------------------- 1 | # `showRatingDialog()` Component API 2 | -------------------------------------------------------------------------------- /docs/numberpickerdialog.md: -------------------------------------------------------------------------------- 1 | # `showNumberPickerDialog()` Component API 2 | -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "extends": "./tsconfig", 4 | "exclude": ["example"] 5 | } 6 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint && yarn typescript 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /ios/NativeDialog-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint -E HUSKY_GIT_PARAMS 5 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NativeDialogExample", 3 | "displayName": "NativeDialog Example" 4 | } 5 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/src/discount.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/src/discount.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Example 3 | 4 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | # Override Yarn command so we can automatically setup the repo on running `yarn` 2 | 3 | yarn-path "scripts/bootstrap.js" 4 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /images/create-bridging-header.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/images/create-bridging-header.gif -------------------------------------------------------------------------------- /example/ios/NativeDialogExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/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.4' 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2' 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/index.tsx: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/App'; 3 | import { name as appName } from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heysem-useinsider/react-native-native-dialog/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/ios/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // NativeDialogExample 4 | // 5 | // Created by Heysem Katibi on 9/9/19. 6 | // Copyright © 2019 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'NativeDialogExample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | 5 | include ':reactnativenativedialog' 6 | project(':reactnativenativedialog').projectDir = new File(rootProject.projectDir, '../../android') 7 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | presets: ['module:metro-react-native-babel-preset'], 6 | plugins: [ 7 | [ 8 | 'module-resolver', 9 | { 10 | extensions: ['.tsx', '.ts', '.js', '.json'], 11 | alias: { 12 | [pak.name]: path.join(__dirname, '..', pak.source), 13 | }, 14 | }, 15 | ], 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /android/src/main/res/layout/dialog_number_picker.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/nativedialog/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.nativedialog; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "NativeDialogExample"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /android/src/main/res/layout/dialog_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-native-dialog-example", 3 | "description": "Example app for react-native-native-dialog", 4 | "version": "0.0.1", 5 | "private": true, 6 | "scripts": { 7 | "android": "react-native run-android", 8 | "ios": "react-native run-ios", 9 | "start": "react-native start" 10 | }, 11 | "dependencies": { 12 | "react": "17.0.2", 13 | "react-native": "0.67.3" 14 | }, 15 | "devDependencies": { 16 | "@babel/core": "^7.12.9", 17 | "@babel/runtime": "^7.12.5", 18 | "babel-plugin-module-resolver": "^4.0.0", 19 | "metro-react-native-babel-preset": "^0.66.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '11.0' 5 | 6 | target 'NativeDialogExample' do 7 | config = use_native_modules! 8 | 9 | use_react_native!( 10 | :path => config[:reactNativePath], 11 | # to enable hermes on iOS, change `false` to `true` and then install pods 12 | :hermes_enabled => false 13 | ) 14 | 15 | pod 'react-native-native-dialog', :path => '../..' 16 | 17 | post_install do |installer| 18 | react_native_post_install(installer) 19 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "react-native-awesome-module": ["./src/index"] 6 | }, 7 | "allowUnreachableCode": false, 8 | "allowUnusedLabels": false, 9 | "esModuleInterop": true, 10 | "importsNotUsedAsValues": "error", 11 | "forceConsistentCasingInFileNames": true, 12 | "jsx": "react", 13 | "lib": ["esnext"], 14 | "module": "esnext", 15 | "moduleResolution": "node", 16 | "noFallthroughCasesInSwitch": true, 17 | "noImplicitReturns": true, 18 | "noImplicitUseStrict": false, 19 | "noStrictGenericChecks": false, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "resolveJsonModule": true, 23 | "skipLibCheck": true, 24 | "strict": true, 25 | "target": "esnext" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /react-native-native-dialog.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "react-native-native-dialog" 7 | s.version = package["version"] 8 | s.summary = package["description"] 9 | s.homepage = package["homepage"] 10 | s.license = package["license"] 11 | s.authors = package["author"] 12 | 13 | s.platforms = { :ios => "10.0" } 14 | s.swift_version = '4.2' 15 | s.source = { :git => "https://github.com/mohakapt/react-native-native-dialog.git", :tag => "#{s.version}" } 16 | s.requires_arc = true 17 | 18 | s.source_files = "ios/**/*.{h,m,mm,swift}" 19 | s.resources = "ios/**/*.{xib}" 20 | 21 | s.dependency "React-Core" 22 | s.dependency "PopupDialog" 23 | s.dependency "Cosmos" 24 | s.dependency "RatingStar" 25 | end 26 | 27 | -------------------------------------------------------------------------------- /scripts/bootstrap.js: -------------------------------------------------------------------------------- 1 | const os = require('os'); 2 | const path = require('path'); 3 | const child_process = require('child_process'); 4 | 5 | const root = path.resolve(__dirname, '..'); 6 | const args = process.argv.slice(2); 7 | const options = { 8 | cwd: process.cwd(), 9 | env: process.env, 10 | stdio: 'inherit', 11 | encoding: 'utf-8', 12 | }; 13 | 14 | if (os.type() === 'Windows_NT') { 15 | options.shell = true 16 | } 17 | 18 | let result; 19 | 20 | if (process.cwd() !== root || args.length) { 21 | // We're not in the root of the project, or additional arguments were passed 22 | // In this case, forward the command to `yarn` 23 | result = child_process.spawnSync('yarn', args, options); 24 | } else { 25 | // If `yarn` is run without arguments, perform bootstrap 26 | result = child_process.spawnSync('yarn', ['bootstrap'], options); 27 | } 28 | 29 | process.exitCode = result.status; 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # node.js 48 | # 49 | node_modules/ 50 | npm-debug.log 51 | yarn-debug.log 52 | yarn-error.log 53 | 54 | # BUCK 55 | buck-out/ 56 | \.buckd/ 57 | android/app/libs 58 | android/keystores/debug.keystore 59 | 60 | # Expo 61 | .expo/* 62 | 63 | # generated by bob 64 | lib/ 65 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/Images.xcassets/appAccent.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "0.204", 10 | "red" : "0.140" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "1.000", 27 | "green" : "0.778", 28 | "red" : "0.027" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /android/src/main/res/layout/dialog_rating.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 23 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Haytham KATBY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const blacklist = require('metro-config/src/defaults/exclusionList'); 3 | const escape = require('escape-string-regexp'); 4 | const pak = require('../package.json'); 5 | 6 | const root = path.resolve(__dirname, '..'); 7 | 8 | const modules = Object.keys({ 9 | ...pak.peerDependencies, 10 | }); 11 | 12 | module.exports = { 13 | projectRoot: __dirname, 14 | watchFolders: [root], 15 | 16 | // We need to make sure that only one version is loaded for peerDependencies 17 | // So we blacklist them at the root, and alias them to the versions in example's node_modules 18 | resolver: { 19 | blacklistRE: blacklist( 20 | modules.map( 21 | (m) => 22 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) 23 | ) 24 | ), 25 | 26 | extraNodeModules: modules.reduce((acc, name) => { 27 | acc[name] = path.join(__dirname, 'node_modules', name); 28 | return acc; 29 | }, {}), 30 | }, 31 | 32 | transformer: { 33 | getTransformOptions: async () => ({ 34 | transform: { 35 | experimentalImportSupport: false, 36 | inlineRequires: true, 37 | }, 38 | }), 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "30.0.3" 6 | minSdkVersion = 23 7 | compileSdkVersion = 31 8 | targetSdkVersion = 31 9 | ndkVersion = "21.4.7075529" 10 | } 11 | repositories { 12 | google() 13 | mavenCentral() 14 | } 15 | dependencies { 16 | classpath('com.android.tools.build:gradle:7.1.2') 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | maven { 25 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 26 | url("$rootDir/../node_modules/react-native/android") 27 | } 28 | maven { 29 | // Android JSC is installed from npm 30 | url("$rootDir/../node_modules/jsc-android/dist") 31 | } 32 | mavenCentral { 33 | // We don't want to fetch react-native from Maven Central as there are 34 | // older versions over there. 35 | content { 36 | excludeGroup "com.facebook.react" 37 | } 38 | } 39 | google() 40 | maven { url 'https://www.jitpack.io' } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | -------------------------------------------------------------------------------- /ios/NativeDialog.m: -------------------------------------------------------------------------------- 1 | // 2 | // NativeDialog.m 3 | // react-native-native-dialog 4 | // 5 | // Created by Haytham Katby on 12/2/18. 6 | // Copyright © 2018 Facebook. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RCT_EXTERN_MODULE(NativeDialog, NSObject) 12 | 13 | - (dispatch_queue_t)methodQueue 14 | { 15 | return dispatch_get_main_queue(); 16 | } 17 | 18 | RCT_EXTERN_METHOD(showDialog: (NSDictionary* )options 19 | resolver: (RCTPromiseResolveBlock)resolve 20 | rejecter: (RCTPromiseRejectBlock)reject) 21 | 22 | 23 | RCT_EXTERN_METHOD(showInputDialog: (NSDictionary* )options 24 | resolver: (RCTPromiseResolveBlock)resolve 25 | rejecter: (RCTPromiseRejectBlock)reject) 26 | 27 | 28 | RCT_EXTERN_METHOD(showItemsDialog:(NSDictionary* ) options 29 | resolver: (RCTPromiseResolveBlock)resolve 30 | rejecter: (RCTPromiseRejectBlock)reject) 31 | 32 | RCT_EXTERN_METHOD(showNumberPickerDialog:(NSDictionary* ) options 33 | resolver: (RCTPromiseResolveBlock)resolve 34 | rejecter: (RCTPromiseRejectBlock)reject) 35 | 36 | 37 | RCT_EXTERN_METHOD(showRatingDialog:(NSDictionary* ) options 38 | resolver: (RCTPromiseResolveBlock)resolve 39 | rejecter: (RCTPromiseRejectBlock)reject) 40 | @end 41 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | if (project == rootProject) { 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.4' 10 | } 11 | } 12 | } 13 | 14 | apply plugin: 'com.android.library' 15 | 16 | def safeExtGet(prop, fallback) { 17 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 18 | } 19 | 20 | android { 21 | compileSdkVersion safeExtGet('compileSdkVersion', 29) 22 | defaultConfig { 23 | minSdkVersion safeExtGet('minSdkVersion', 16) 24 | targetSdkVersion safeExtGet('targetSdkVersion', 29) 25 | 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | } 32 | } 33 | 34 | compileOptions { 35 | sourceCompatibility JavaVersion.VERSION_1_8 36 | targetCompatibility JavaVersion.VERSION_1_8 37 | } 38 | lint { 39 | disable 'GradleCompatible' 40 | } 41 | } 42 | 43 | repositories { 44 | maven { 45 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 46 | url("$rootDir/../node_modules/react-native/android") 47 | } 48 | google() 49 | } 50 | 51 | dependencies { 52 | //noinspection GradleDynamicVersion 53 | implementation "com.facebook.react:react-native:+" // From node_modules 54 | implementation "androidx.appcompat:appcompat:${safeExtGet('appCompatVersion', '1.4.1')}" 55 | implementation "androidx.fragment:fragment:${safeExtGet('appCompatVersion', '1.4.1')}" 56 | } 57 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/nativedialog/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.nativedialog; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactNativeHost; 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.soloader.SoLoader; 10 | import com.github.mohaka.nativedialog.NativeDialogPackage; 11 | 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = 17 | new ReactNativeHost(this) { 18 | @Override 19 | public boolean getUseDeveloperSupport() { 20 | return BuildConfig.DEBUG; 21 | } 22 | 23 | @Override 24 | protected List getPackages() { 25 | @SuppressWarnings("UnnecessaryLocalVariable") 26 | List packages = new PackageList(this).getPackages(); 27 | // Packages that cannot be autolinked yet can be added manually here, for NativeDialogExample: 28 | // packages.add(new MyReactNativePackage()); 29 | packages.add(new NativeDialogPackage()); 30 | return packages; 31 | } 32 | 33 | @Override 34 | protected String getJSMainModuleName() { 35 | return "index"; 36 | } 37 | }; 38 | 39 | @Override 40 | public ReactNativeHost getReactNativeHost() { 41 | return mReactNativeHost; 42 | } 43 | 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | SoLoader.init(this, /* native exopackage */ false); 48 | NativeDialogPackage.setDialogTheme(R.style.AlertDialog, R.style.LightAlertDialog); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | NativeDialog Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/mohaka/nativedialog/NativeDialogPackage.java: -------------------------------------------------------------------------------- 1 | package com.github.mohaka.nativedialog; 2 | 3 | import androidx.annotation.StyleRes; 4 | 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.bridge.NativeModule; 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ViewManager; 9 | 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class NativeDialogPackage implements ReactPackage { 15 | static int dialogTheme = 0; 16 | static int lightDialogTheme = 0; 17 | 18 | static int dateDialogTheme = 0; 19 | static int lightDateDialogTheme = 0; 20 | 21 | public static void setDialogTheme(@StyleRes int dialogTheme) { 22 | NativeDialogPackage.dialogTheme = dialogTheme; 23 | NativeDialogPackage.lightDialogTheme = dialogTheme; 24 | } 25 | 26 | public static void setDialogTheme(@StyleRes int dialogTheme, @StyleRes int lightDialogTheme) { 27 | NativeDialogPackage.dialogTheme = dialogTheme; 28 | NativeDialogPackage.lightDialogTheme = lightDialogTheme; 29 | } 30 | 31 | public static void setDatePickerDialogTheme(@StyleRes int dateDialogTheme) { 32 | NativeDialogPackage.dateDialogTheme = dateDialogTheme; 33 | NativeDialogPackage.lightDateDialogTheme = dateDialogTheme; 34 | } 35 | 36 | public static void setDatePickerDialogTheme(@StyleRes int dateDialogTheme, @StyleRes int lightDateDialogTheme) { 37 | NativeDialogPackage.dateDialogTheme = dateDialogTheme; 38 | NativeDialogPackage.lightDateDialogTheme = lightDateDialogTheme; 39 | } 40 | 41 | @Override 42 | public List createNativeModules(ReactApplicationContext reactContext) { 43 | return Arrays.asList(new NativeDialogModule(reactContext)); 44 | } 45 | 46 | @Override 47 | public List createViewManagers(ReactApplicationContext reactContext) { 48 | return Collections.emptyList(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/mohaka/nativedialog/NumberPickerDialogOptions.java: -------------------------------------------------------------------------------- 1 | package com.github.mohaka.nativedialog; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.widget.NumberPicker; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | import androidx.appcompat.app.AlertDialog; 11 | 12 | import com.facebook.react.bridge.ReadableMap; 13 | 14 | public class NumberPickerDialogOptions extends DialogOptions { 15 | private int value; 16 | private int minValue; 17 | private int maxValue; 18 | 19 | public NumberPickerDialogOptions() { 20 | } 21 | 22 | public NumberPickerDialogOptions(ReadableMap map, Context context) { 23 | this.populate(map, context); 24 | } 25 | 26 | public int getValue() { 27 | return value; 28 | } 29 | 30 | public void setValue(int value) { 31 | this.value = value; 32 | } 33 | 34 | public int getMinValue() { 35 | return minValue; 36 | } 37 | 38 | public void setMinValue(int minValue) { 39 | this.minValue = minValue; 40 | } 41 | 42 | public int getMaxValue() { 43 | return maxValue; 44 | } 45 | 46 | public void setMaxValue(int maxValue) { 47 | this.maxValue = maxValue; 48 | } 49 | 50 | @Override 51 | public void populate(ReadableMap map, Context context) { 52 | super.populate(map, context); 53 | if (map.hasKey("value")) setValue(map.getInt("value")); 54 | if (map.hasKey("minValue")) setMinValue(map.getInt("minValue")); 55 | if (map.hasKey("maxValue")) setMaxValue(map.getInt("maxValue")); 56 | } 57 | 58 | @NonNull 59 | @Override 60 | public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 61 | AlertDialog.Builder builder = buildDialog(); 62 | 63 | builder.setView(R.layout.dialog_number_picker); 64 | 65 | AlertDialog alertDialog = builder.create(); 66 | alertDialog.setCanceledOnTouchOutside(isCancelOnTouchOutside()); 67 | alertDialog.show(); 68 | 69 | NumberPicker picNumber = alertDialog.findViewById(R.id.picNumber); 70 | picNumber.setMinValue(getMinValue()); 71 | picNumber.setMaxValue(getMaxValue()); 72 | picNumber.setValue(getValue()); 73 | 74 | return alertDialog; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | default: 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/project 8 | 9 | commands: 10 | attach_project: 11 | steps: 12 | - attach_workspace: 13 | at: ~/project 14 | 15 | jobs: 16 | install-dependencies: 17 | executor: default 18 | steps: 19 | - checkout 20 | - attach_project 21 | - restore_cache: 22 | keys: 23 | - dependencies-{{ checksum "package.json" }} 24 | - dependencies- 25 | - restore_cache: 26 | keys: 27 | - dependencies-example-{{ checksum "example/package.json" }} 28 | - dependencies-example- 29 | - run: 30 | name: Install dependencies 31 | command: | 32 | yarn install --cwd example --frozen-lockfile 33 | yarn install --frozen-lockfile 34 | - save_cache: 35 | key: dependencies-{{ checksum "package.json" }} 36 | paths: node_modules 37 | - save_cache: 38 | key: dependencies-example-{{ checksum "example/package.json" }} 39 | paths: example/node_modules 40 | - persist_to_workspace: 41 | root: . 42 | paths: . 43 | 44 | lint: 45 | executor: default 46 | steps: 47 | - attach_project 48 | - run: 49 | name: Lint files 50 | command: | 51 | yarn lint 52 | 53 | typescript: 54 | executor: default 55 | steps: 56 | - attach_project 57 | - run: 58 | name: Typecheck files 59 | command: | 60 | yarn typescript 61 | 62 | unit-tests: 63 | executor: default 64 | steps: 65 | - attach_project 66 | - run: 67 | name: Run unit tests 68 | command: | 69 | yarn test --coverage 70 | - store_artifacts: 71 | path: coverage 72 | destination: coverage 73 | 74 | build-package: 75 | executor: default 76 | steps: 77 | - attach_project 78 | - run: 79 | name: Build package 80 | command: | 81 | yarn prepare 82 | 83 | workflows: 84 | build-and-test: 85 | jobs: 86 | - install-dependencies 87 | - lint: 88 | requires: 89 | - install-dependencies 90 | - typescript: 91 | requires: 92 | - install-dependencies 93 | - unit-tests: 94 | requires: 95 | - install-dependencies 96 | - build-package: 97 | requires: 98 | - install-dependencies 99 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-native-dialog", 3 | "version": "3.0.7", 4 | "description": "A React Native module that exposes some of the common native dialogs to React Native.", 5 | "main": "src/index", 6 | "module": "src/index", 7 | "types": "src/index.d.ts", 8 | "react-native": "src/index", 9 | "source": "src/index", 10 | "files": [ 11 | "src", 12 | "lib", 13 | "android", 14 | "ios", 15 | "cpp", 16 | "react-native-native-dialog.podspec", 17 | "!lib/typescript/example", 18 | "!android/build", 19 | "!ios/build", 20 | "!**/__tests__", 21 | "!**/__fixtures__", 22 | "!**/__mocks__" 23 | ], 24 | "scripts": { 25 | "typescript": "tsc --noEmit", 26 | "prepare": "bob build", 27 | "release": "release-it", 28 | "example": "yarn --cwd example", 29 | "pods": "cd example && pod-install --quiet", 30 | "bootstrap": "yarn example && yarn && yarn pods" 31 | }, 32 | "keywords": [ 33 | "react-native", 34 | "ios", 35 | "android", 36 | "dialog", 37 | "native-dialog" 38 | ], 39 | "repository": "https://github.com/mohakapt/react-native-native-dialog", 40 | "author": "Heysem Katibi (https://github.com/mohakapt)", 41 | "license": "MIT", 42 | "bugs": { 43 | "url": "https://github.com/mohakapt/react-native-native-dialog/issues" 44 | }, 45 | "homepage": "https://github.com/mohakapt/react-native-native-dialog#readme", 46 | "publishConfig": { 47 | "registry": "https://registry.npmjs.org/" 48 | }, 49 | "devDependencies": { 50 | "@release-it/conventional-changelog": "^2.0.0", 51 | "@types/react": "^17.0.39", 52 | "@types/react-native": "^0.67.2", 53 | "husky": "^6.0.0", 54 | "pod-install": "^0.1.0", 55 | "react": "17.0.2", 56 | "react-native": "0.67.3", 57 | "react-native-builder-bob": "^0.18.0", 58 | "release-it": "^14.2.2", 59 | "typescript": "^4.1.3" 60 | }, 61 | "peerDependencies": { 62 | "react": "*", 63 | "react-native": "*" 64 | }, 65 | "release-it": { 66 | "git": { 67 | "commitMessage": "chore: release ${version}", 68 | "tagName": "v${version}" 69 | }, 70 | "npm": { 71 | "publish": true 72 | }, 73 | "github": { 74 | "release": true 75 | }, 76 | "plugins": { 77 | "@release-it/conventional-changelog": { 78 | "preset": "angular" 79 | } 80 | } 81 | }, 82 | "react-native-builder-bob": { 83 | "source": "src", 84 | "output": "lib", 85 | "targets": [ 86 | "commonjs", 87 | "module", 88 | [ 89 | "typescript", 90 | { 91 | "project": "tsconfig.build.json" 92 | } 93 | ] 94 | ] 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /ios/NativeDialog.xcodeproj/xcshareddata/xcschemes/NativeDialog.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | #ifdef FB_SONARKIT_ENABLED 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | #import 21 | static void InitializeFlipper(UIApplication *application) { 22 | FlipperClient *client = [FlipperClient sharedClient]; 23 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 24 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 25 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 26 | [client addPlugin:[FlipperKitReactPlugin new]]; 27 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 28 | [client start]; 29 | } 30 | #endif 31 | 32 | @implementation AppDelegate 33 | 34 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 35 | { 36 | #ifdef FB_SONARKIT_ENABLED 37 | InitializeFlipper(application); 38 | #endif 39 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 40 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 41 | moduleName:@"NativeDialogExample" 42 | initialProperties:nil]; 43 | 44 | if (@available(iOS 13.0, *)) { 45 | rootView.backgroundColor = [UIColor systemBackgroundColor]; 46 | } else { 47 | rootView.backgroundColor = [UIColor whiteColor]; 48 | } 49 | 50 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 51 | UIViewController *rootViewController = [UIViewController new]; 52 | rootViewController.view = rootView; 53 | self.window.rootViewController = rootViewController; 54 | [self.window makeKeyAndVisible]; 55 | return YES; 56 | } 57 | 58 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 59 | { 60 | #if DEBUG 61 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 62 | #else 63 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 64 | #endif 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/mohaka/nativedialog/Utilities.java: -------------------------------------------------------------------------------- 1 | package com.github.mohaka.nativedialog; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.os.Build; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | 10 | /** 11 | * Created by MoHaKa on 27.11.2015. 12 | */ 13 | public class Utilities { 14 | private Context context; 15 | 16 | public static Utilities with(Context context) { 17 | Utilities reVal = new Utilities(); 18 | reVal.context = context; 19 | return reVal; 20 | } 21 | 22 | // Check system requirements 23 | public static boolean hasJellyBean() { 24 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; 25 | } 26 | 27 | public static boolean hasJellyBeanMR1() { 28 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; 29 | } 30 | 31 | public static boolean hasKitKat() { 32 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 33 | } 34 | 35 | public static boolean hasLollipop() { 36 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 37 | } 38 | 39 | public static boolean hasMarshmallow() { 40 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; 41 | } 42 | 43 | public static boolean isEmpty(final Collection c) { 44 | return c == null || c.isEmpty(); 45 | } 46 | 47 | public static boolean isEmpty(final Object[] a) { 48 | return a == null || a.length == 0; 49 | } 50 | 51 | public static String toString(final Object[] a) { 52 | if (isEmpty(a)) return null; 53 | 54 | StringBuilder reVal = new StringBuilder(); 55 | for (int i = 0; i < a.length; i++) { 56 | reVal.append(a[i].toString()); 57 | 58 | if (i != a.length - 1) 59 | reVal.append(","); 60 | } 61 | 62 | return reVal.toString(); 63 | } 64 | 65 | public static boolean isEmpty(final Uri uri) { 66 | return uri == null || uri == Uri.EMPTY; 67 | } 68 | 69 | public static String repeat(String s, int times) { 70 | if (s == null) return null; 71 | if (times <= 0) return ""; 72 | else return s + repeat(s, times - 1); 73 | } 74 | 75 | public static double round(double value, int places) { 76 | if (places < 0) throw new IllegalArgumentException(); 77 | 78 | long factor = (long) Math.pow(10, places); 79 | value = value * factor; 80 | long tmp = Math.round(value); 81 | return (double) tmp / factor; 82 | } 83 | 84 | public static boolean[] toBooleanArray(Object[] array, boolean defaultValue) { 85 | if (array == null) return null; 86 | boolean[] reVal = new boolean[array.length]; 87 | Arrays.fill(reVal, defaultValue); 88 | 89 | for (int i = 0; i < array.length; i++) { 90 | boolean value = defaultValue; 91 | if (array[i] != null && array[i] instanceof Boolean) 92 | value = (boolean) array[i]; 93 | reVal[i] = value; 94 | } 95 | 96 | return reVal; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/mohaka/nativedialog/RatingDialogOptions.java: -------------------------------------------------------------------------------- 1 | package com.github.mohaka.nativedialog; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.RatingBar; 8 | 9 | import androidx.annotation.NonNull; 10 | import androidx.annotation.Nullable; 11 | import androidx.appcompat.app.AlertDialog; 12 | 13 | import com.facebook.react.bridge.ReadableMap; 14 | import com.facebook.react.bridge.ReadableType; 15 | //import com.github.mohaka.ratingstar.RatingStar; 16 | 17 | public class RatingDialogOptions extends DialogOptions { 18 | public final static int MODE_ROSE = 100; 19 | public final static int MODE_BAR = 101; 20 | 21 | private int mode; 22 | private int value; 23 | 24 | public RatingDialogOptions() { 25 | } 26 | 27 | public RatingDialogOptions(ReadableMap map, Context context) { 28 | this.populate(map, context); 29 | } 30 | 31 | public int getMode() { 32 | return mode; 33 | } 34 | 35 | public int getValue() { 36 | return value; 37 | } 38 | 39 | public void setMode(int value) { 40 | this.mode = value; 41 | } 42 | 43 | public void setMode(String mode) { 44 | switch (mode.toLowerCase()) { 45 | case "default": 46 | default: 47 | setMode(MODE_ROSE); 48 | break; 49 | case "bar": 50 | setMode(MODE_BAR); 51 | break; 52 | } 53 | } 54 | 55 | public void setValue(int value) { 56 | this.value = value; 57 | } 58 | 59 | @Override 60 | public void populate(ReadableMap map, Context context) { 61 | super.populate(map, context); 62 | 63 | if (map.hasKey("mode")) setMode(map.getString("mode")); 64 | 65 | if (map.hasKey("value")) { 66 | if (map.getType("value") == ReadableType.Number) 67 | setValue(map.getInt("value")); 68 | else 69 | setValue(Integer.parseInt(map.getString("value"))); 70 | } 71 | } 72 | 73 | @NonNull 74 | @Override 75 | public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 76 | AlertDialog.Builder builder = super.buildDialog(); 77 | builder.setView(R.layout.dialog_rating); 78 | 79 | AlertDialog alertDialog = builder.create(); 80 | alertDialog.setCanceledOnTouchOutside(isCancelOnTouchOutside()); 81 | alertDialog.show(); 82 | 83 | // RatingStar ratingStar = alertDialog.findViewById(R.id.ratingStar); 84 | RatingBar ratingBar = alertDialog.findViewById(R.id.ratingBar); 85 | 86 | // ratingStar.setRating(getValue()); 87 | ratingBar.setRating(getValue()); 88 | 89 | if (getMode() == MODE_BAR) { 90 | // ratingStar.setVisibility(View.GONE); 91 | ratingBar.setVisibility(View.VISIBLE); 92 | } else { 93 | // ratingStar.setVisibility(View.VISIBLE); 94 | ratingBar.setVisibility(View.GONE); 95 | } 96 | 97 | return alertDialog; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.5) 5 | rexml 6 | activesupport (6.1.4.6) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.0) 13 | public_suffix (>= 2.0.2, < 5.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | atomos (0.1.3) 18 | claide (1.1.0) 19 | cocoapods (1.11.2) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.11.2) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 1.4.0, < 2.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.4.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 1.0, < 3.0) 36 | xcodeproj (>= 1.21.0, < 2.0) 37 | cocoapods-core (1.11.2) 38 | activesupport (>= 5.0, < 7) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (1.6.3) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.1.9) 58 | escape (0.0.4) 59 | ethon (0.15.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.15.5) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.10.0) 67 | concurrent-ruby (~> 1.0) 68 | json (2.6.1) 69 | minitest (5.15.0) 70 | molinillo (0.8.0) 71 | nanaimo (0.3.0) 72 | nap (1.1.0) 73 | netrc (0.11.0) 74 | public_suffix (4.0.6) 75 | rexml (3.2.5) 76 | ruby-macho (2.5.1) 77 | typhoeus (1.4.0) 78 | ethon (>= 0.9.0) 79 | tzinfo (2.0.4) 80 | concurrent-ruby (~> 1.0) 81 | xcodeproj (1.21.0) 82 | CFPropertyList (>= 2.3.3, < 4.0) 83 | atomos (~> 0.1.3) 84 | claide (>= 1.0.2, < 2.0) 85 | colored2 (~> 3.1) 86 | nanaimo (~> 0.3.0) 87 | rexml (~> 3.2.4) 88 | zeitwerk (2.5.4) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | cocoapods (~> 1.11, >= 1.11.2) 95 | 96 | RUBY VERSION 97 | ruby 2.7.4p191 98 | 99 | BUNDLED WITH 100 | 2.2.27 101 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /ios/NativeDialog/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // NativeDialog 4 | // 5 | // Created by Heysem Katibi on 3/4/19. 6 | // Copyright © 2019 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | 13 | extension UIColor { 14 | convenience init(hexString: String, alpha: CGFloat = 1.0) { 15 | 16 | let hexString: String = hexString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) 17 | let scanner = Scanner(string: hexString) 18 | 19 | if (hexString.hasPrefix("#")) { 20 | scanner.scanLocation = 1 21 | } 22 | 23 | var color: UInt32 = 0 24 | scanner.scanHexInt32(&color) 25 | 26 | let mask = 0x000000FF 27 | 28 | let r = Int(color >> 16) & mask 29 | let g = Int(color >> 8) & mask 30 | let b = Int(color) & mask 31 | 32 | let red = CGFloat(r) / 255.0 33 | let green = CGFloat(g) / 255.0 34 | let blue = CGFloat(b) / 255.0 35 | 36 | self.init(red: red, green: green, blue: blue, alpha: alpha) 37 | } 38 | 39 | func toHexString() -> String { 40 | var r: CGFloat = 0 41 | var g: CGFloat = 0 42 | var b: CGFloat = 0 43 | var a: CGFloat = 0 44 | 45 | getRed(&r, green: &g, blue: &b, alpha: &a) 46 | let rgb: Int = (Int)(r * 255) << 16 | (Int)(g * 255) << 8 | (Int)(b * 255) << 0 47 | return String(format: "# % 06x", rgb) 48 | } 49 | } 50 | 51 | extension UIViewController { 52 | fileprivate func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { 53 | if let nav = base as? UINavigationController { 54 | return getTopViewController(base: nav.visibleViewController) 55 | } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController { 56 | return getTopViewController(base: selected) 57 | } else if let presented = base?.presentedViewController { 58 | return getTopViewController(base: presented) 59 | } 60 | return base 61 | } 62 | 63 | var topViewController: UIViewController? { 64 | return getTopViewController(base: self) 65 | } 66 | } 67 | 68 | 69 | extension UIApplication { 70 | var topViewController: UIViewController? { 71 | var keyWindow: UIWindow? 72 | if #available(iOS 13.0, *) { 73 | keyWindow = self.connectedScenes 74 | .filter({$0.activationState == .foregroundActive}) 75 | .compactMap({$0 as? UIWindowScene}) 76 | .first?.windows 77 | .filter({$0.isKeyWindow}).first 78 | } else { 79 | keyWindow = self.keyWindow 80 | } 81 | 82 | guard let keyWindow = keyWindow else { return nil } 83 | 84 | return keyWindow.rootViewController?.topViewController 85 | } 86 | 87 | var rootViewController: UIViewController? { 88 | var keyWindow: UIWindow? 89 | if #available(iOS 13.0, *) { 90 | keyWindow = self.connectedScenes 91 | .filter({$0.activationState == .foregroundActive}) 92 | .compactMap({$0 as? UIWindowScene}) 93 | .first?.windows 94 | .filter({$0.isKeyWindow}).first 95 | } else { 96 | keyWindow = self.keyWindow 97 | } 98 | 99 | guard let keyWindow = keyWindow else { return nil } 100 | 101 | return keyWindow.rootViewController 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { OpaqueColorValue } from 'react-native'; 2 | 3 | export type Id = T | T[]; 4 | export type Items = string[] | { id: T, title: string }[]; 5 | export type IosButtonType = 'default' | 'cancel' | 'destructive'; 6 | 7 | interface IosDialogProps { 8 | buttonAlignment?: 'default' | 'vertical' | 'horizontal'; 9 | transitionStyle?: 'bounceUp' | 'bounceDown' | 'zoomIn' | 'fadeIn'; 10 | preferredWidth?: number; 11 | preferredStyle?: 'popupDialog' | 'alert' | 'actionSheet'; 12 | hideStatusBar?: boolean; 13 | 14 | positiveButtonStyle?: IosButtonType; 15 | negativeButtonStyle?: IosButtonType; 16 | neutralButtonStyle?: IosButtonType; 17 | } 18 | 19 | interface AndroidDialogProps { 20 | } 21 | 22 | interface CommonDialogProps extends IosDialogProps, AndroidDialogProps { 23 | title?: string; 24 | message?: string; 25 | 26 | cancellable?: boolean; 27 | cancelOnTouchOutside?: boolean; 28 | 29 | theme?: 'light' | 'dark'; 30 | accentColor?: string | OpaqueColorValue; 31 | 32 | positiveButton?: string; 33 | negativeButton?: string; 34 | neutralButton?: string; 35 | 36 | onDismiss?: () => void; 37 | } 38 | 39 | interface CommonDialogEvents { 40 | onPositivePress?: () => void; 41 | onNegativePress?: () => void; 42 | onNeutralPress?: () => void; 43 | } 44 | 45 | interface InputDialogEvents { 46 | onPositivePress?: (value: string) => void; 47 | onNegativePress?: (value: string) => void; 48 | onNeutralPress?: (value: string) => void; 49 | } 50 | 51 | interface ItemsDialogEvents extends CommonDialogEvents { 52 | onItemSelect?: (selectedId: Id) => void; 53 | } 54 | 55 | interface NumberPickerDialogEvents { 56 | onPositivePress?: (value: number) => void; 57 | onNegativePress?: (value: number) => void; 58 | onNeutralPress?: (value: number) => void; 59 | } 60 | 61 | export interface DialogProps extends CommonDialogProps, CommonDialogEvents { 62 | } 63 | 64 | export interface InputDialogProps extends CommonDialogProps, InputDialogEvents { 65 | value?: string; 66 | placeholder?: string; 67 | keyboardType?: 'default' | 'number-pad' | 'decimal-pad' | 'numeric' | 'email-address' | 'phone-pad'; 68 | maxLength?: number; 69 | autoCorrect?: boolean; 70 | autoFocus?: boolean; 71 | autoCapitalize?: 'characters' | 'words' | 'sentences' | 'none'; 72 | selectTextOnFocus?: boolean; 73 | secureTextEntry?: boolean; 74 | allowEmptyEntry?: boolean; 75 | } 76 | 77 | export interface ItemsDialogProps extends CommonDialogProps, ItemsDialogEvents { 78 | mode?: 'default' | 'single' | 'multiple'; 79 | items: Items; 80 | selectedItems?: Id; 81 | } 82 | 83 | export interface NumberPickerDialogProps extends CommonDialogProps, NumberPickerDialogEvents { 84 | value: number; 85 | minValue?: number; 86 | maxValue?: number; 87 | } 88 | 89 | export interface RatingDialogProps extends CommonDialogProps, CommonDialogEvents { 90 | mode?: 'rose' | 'bar'; 91 | value: 0 | 1 | 2 | 3 | 4 | 5; 92 | } 93 | 94 | declare const showDialog: (props: DialogProps) => void; 95 | declare const showInputDialog: (props: InputDialogProps) => void; 96 | declare const showItemsDialog: (props: ItemsDialogProps) => void; 97 | declare const showNumberPickerDialog: (props: NumberPickerDialogProps) => void; 98 | declare const showRatingDialog: (props: RatingDialogProps) => void; 99 | 100 | export { 101 | showDialog, 102 | showInputDialog, 103 | showItemsDialog, 104 | showNumberPickerDialog, 105 | showRatingDialog, 106 | }; 107 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/NativeDialog/NumberPickerDialogOptions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NumberPickerViewController.swift 3 | // NativeDialog 4 | // 5 | // Created by Heysem Katibi on 5.04.2020. 6 | // Copyright © 2020 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import PopupDialog 12 | 13 | class NumberPickerViewController: UIViewController { 14 | 15 | @IBOutlet weak var titleLabel: UILabel! 16 | @IBOutlet weak var messageLabel: UILabel! 17 | @IBOutlet var pickerView: UIPickerView! 18 | 19 | var dialogOptions: NumberPickerDialogOptions! 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | self.updateTheme() 24 | 25 | titleLabel.text = dialogOptions.title 26 | messageLabel.text = dialogOptions.message 27 | 28 | pickerView.delegate = dialogOptions 29 | } 30 | 31 | override func viewWillAppear(_ animated: Bool) { 32 | super.viewWillAppear(animated) 33 | 34 | let selectedRow = self.dialogOptions.value - self.dialogOptions.minValue 35 | pickerView.selectRow(selectedRow, inComponent: 0, animated: false) 36 | } 37 | 38 | private func updateTheme() { 39 | self.view.tintColor = dialogOptions.accentColor 40 | 41 | if dialogOptions.theme == .dark { 42 | titleLabel.textColor = .white 43 | messageLabel.textColor = UIColor(white: 0.8, alpha: 1) 44 | 45 | if #available(iOS 13.0, *) { 46 | pickerView.overrideUserInterfaceStyle = .dark 47 | } 48 | } else { 49 | titleLabel.textColor = .black 50 | messageLabel.textColor = UIColor(white: 0.2, alpha: 1) 51 | 52 | if #available(iOS 13.0, *) { 53 | pickerView.overrideUserInterfaceStyle = .light 54 | } 55 | } 56 | } 57 | 58 | } 59 | 60 | class NumberPickerDialogOptions: DialogOptions, UIPickerViewDataSource, UIPickerViewDelegate { 61 | let value: Int 62 | let minValue: Int 63 | let maxValue: Int 64 | 65 | private var newValue: Int 66 | 67 | override init(options: [String: Any]) { 68 | self.value = options["value"] as? Int ?? 0 69 | self.minValue = options["minValue"] as? Int ?? 0 70 | self.maxValue = options["maxValue"] as? Int ?? 20 71 | 72 | self.newValue = self.value 73 | 74 | super.init(options: options) 75 | } 76 | 77 | override func buildPopupDialog() -> PopupDialog { 78 | let bundle = Bundle(for: NumberPickerViewController.self) 79 | let pickerVC = NumberPickerViewController(nibName: "NumberPickerViewController", bundle: bundle) 80 | pickerVC.dialogOptions = self 81 | 82 | let popupController = PopupDialog(viewController: pickerVC, buttonAlignment: buttonAlignment, transitionStyle: transitionStyle, preferredWidth: preferredWidth, tapGestureDismissal: cancelOnTouchOutside, panGestureDismissal: cancellable, hideStatusBar: hideStatusBar) { 83 | self.dismissHandler?() 84 | } 85 | 86 | injectButtons(dialog: popupController) 87 | return popupController 88 | } 89 | 90 | override func positiveButtonTouched() { 91 | self.finishHandler?(.positive, ["value": self.newValue]) 92 | } 93 | 94 | override func negativeButtonTouched() { 95 | self.finishHandler?(.negative, ["value": self.newValue]) 96 | } 97 | 98 | override func neutralButtonTouched() { 99 | self.finishHandler?(.neutral, ["value": self.newValue]) 100 | } 101 | 102 | func numberOfComponents(in pickerView: UIPickerView) -> Int { 103 | return 1 104 | } 105 | 106 | func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 107 | return abs(self.maxValue - self.minValue) + 1 108 | } 109 | 110 | func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 111 | let color = (self.theme == .dark) ? UIColor.white : UIColor.black 112 | 113 | if #available(iOS 13.0, *) { } else { 114 | pickerView.subviews.filter { $0.frame.height < 1 }.forEach { 115 | $0.backgroundColor = color.withAlphaComponent(0.2) 116 | } 117 | } 118 | 119 | let title = String(self.minValue + row) 120 | return NSAttributedString(string: title, attributes: [.foregroundColor: color]) 121 | } 122 | 123 | func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 124 | self.newValue = self.minValue + row 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /example/ios/NativeDialogExample.xcodeproj/xcshareddata/xcschemes/NativeDialogExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 81 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /ios/NativeDialog/RatingDialogOptions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RatingViewController.swift 3 | // NativeDialog 4 | // 5 | // Created by Heysem Katibi on 5.04.2020. 6 | // Copyright © 2020 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import PopupDialog 12 | import RatingStar 13 | import Cosmos 14 | 15 | enum RatingMode { 16 | case rose 17 | case bar 18 | } 19 | 20 | class RatingViewController: UIViewController, UIGestureRecognizerDelegate { 21 | 22 | @IBOutlet weak var titleLabel: UILabel! 23 | @IBOutlet weak var messageLabel: UILabel! 24 | @IBOutlet var bottomMargin: NSLayoutConstraint! 25 | @IBOutlet var ratingStar: UIRatingStar! 26 | @IBOutlet var cosmosView: CosmosView! 27 | 28 | var dialogOptions: RatingDialogOptions! 29 | 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | self.updateTheme() 33 | 34 | titleLabel.text = dialogOptions.title 35 | messageLabel.text = dialogOptions.message 36 | 37 | 38 | ratingStar.value = dialogOptions.value 39 | ratingStar.delegate = dialogOptions 40 | 41 | cosmosView.rating = Double(dialogOptions.value) 42 | cosmosView.settings.starSize = 42 43 | cosmosView.didFinishTouchingCosmos = { newValue in self.dialogOptions.ratingChanged(newValue: Int(newValue))} 44 | 45 | if dialogOptions.mode == .bar { 46 | cosmosView.isHidden = false 47 | ratingStar.isHidden = true 48 | bottomMargin.constant = 30 49 | } else { 50 | cosmosView.isHidden = true 51 | ratingStar.isHidden = false 52 | bottomMargin.constant = 6 53 | } 54 | } 55 | 56 | private func updateTheme() { 57 | let accentColor = dialogOptions.accentColor ?? UIApplication.shared.rootViewController?.view.tintColor ?? UIColor(hexString: "#007aff") 58 | let textColor: UIColor 59 | let messageColor: UIColor 60 | let starColor: UIColor 61 | 62 | switch dialogOptions.theme { 63 | case .dark: 64 | textColor = .white 65 | messageColor = UIColor(white: 0.8, alpha: 1) 66 | starColor = UIColor.white.withAlphaComponent(0.2) 67 | break 68 | 69 | case .light: 70 | textColor = .black 71 | messageColor = UIColor(white: 0.2, alpha: 1) 72 | starColor = UIColor.black.withAlphaComponent(0.2) 73 | break 74 | 75 | default: 76 | if #available(iOS 13.0, *) { 77 | textColor = .label 78 | messageColor = .tertiaryLabel 79 | starColor = UIColor.label.withAlphaComponent(0.2) 80 | } else { 81 | textColor = .black 82 | messageColor = UIColor(white: 0.2, alpha: 1) 83 | starColor = UIColor.black.withAlphaComponent(0.2) 84 | } 85 | break 86 | } 87 | 88 | self.view.tintColor = accentColor 89 | 90 | ratingStar.selectionColor = accentColor 91 | cosmosView.backgroundColor = .clear 92 | cosmosView.settings.filledColor = accentColor 93 | cosmosView.settings.filledBorderColor = accentColor 94 | 95 | titleLabel.textColor = textColor 96 | messageLabel.textColor = messageColor 97 | 98 | ratingStar.starColor = starColor 99 | cosmosView.settings.emptyColor = starColor 100 | cosmosView.settings.emptyBorderColor = starColor 101 | } 102 | 103 | } 104 | 105 | class RatingDialogOptions: DialogOptions, UIRatingStarDelegate { 106 | let mode: RatingMode 107 | let value: Int 108 | 109 | private var newValue: Int 110 | 111 | override init(options: [String: Any]) { 112 | switch (options["mode"] as? String ?? "rose").lowercased() { 113 | case "rose": 114 | self.mode = .rose 115 | break 116 | default: 117 | self.mode = .bar 118 | break 119 | } 120 | 121 | self.value = options["value"] as? Int ?? 0 122 | self.newValue = self.value 123 | 124 | super.init(options: options) 125 | } 126 | 127 | override func buildPopupDialog() -> PopupDialog { 128 | let bundle = Bundle(for: RatingViewController.self) 129 | let ratingVC = RatingViewController(nibName: "RatingViewController", bundle: bundle) 130 | ratingVC.dialogOptions = self 131 | 132 | let popupController = PopupDialog(viewController: ratingVC, buttonAlignment: buttonAlignment, transitionStyle: transitionStyle, preferredWidth: preferredWidth, tapGestureDismissal: cancelOnTouchOutside, panGestureDismissal: cancellable, hideStatusBar: hideStatusBar) { 133 | self.dismissHandler?() 134 | } 135 | 136 | injectButtons(dialog: popupController) 137 | return popupController 138 | } 139 | 140 | override func positiveButtonTouched() { 141 | self.finishHandler?(.positive, ["value": self.newValue]) 142 | } 143 | 144 | override func negativeButtonTouched() { 145 | self.finishHandler?(.negative, ["value": self.newValue]) 146 | } 147 | 148 | override func neutralButtonTouched() { 149 | self.finishHandler?(.neutral, ["value": self.newValue]) 150 | } 151 | 152 | func ratingChanged(newValue: Int) { 153 | self.newValue = newValue 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /ios/NativeDialog/NumberPickerViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button, PlatformColor, View } from 'react-native'; 3 | import NativeDialog from 'react-native-native-dialog'; 4 | 5 | export default function App() { 6 | const onTouched = (style: 'alert' | 'popupDialog', theme: 'light' | 'dark') => { 7 | // NativeDialog.showDialog({ 8 | // title: 'Do you want to update your iCloud Backup before erasing?', 9 | // message: 'If you erase without updating your backup, you may lose photos and other data that are not yet uploaded to iCloud.', 10 | // 11 | // positiveButton: 'Back Up Then Erase', 12 | // negativeButton: 'Erase Now', 13 | // neutralButton: 'Cancel', 14 | // 15 | // negativeButtonStyle: 'default', 16 | // neutralButtonStyle: 'cancel', 17 | // 18 | // transitionStyle: 'bounceUp', 19 | // preferredStyle: style, 20 | // 21 | // theme, 22 | // accentColor: '#ff4a9e', 23 | // 24 | // onPositivePress: (input: string) => console.warn('positive - ', input), 25 | // onNegativePress: (input: string) => console.warn('negative - ', input), 26 | // onNeutralPress: (input: string) => console.warn('neutral - ', input), 27 | // 28 | // onDismiss: () => console.warn('dismiss'), 29 | // }); 30 | 31 | // NativeDialog.showInputDialog({ 32 | // title: 'Do you want to update your iCloud Backup before erasing?', 33 | // message: 'If you erase without updating your backup, you may lose photos and other data that are not yet uploaded to iCloud.', 34 | // 35 | // positiveButton: 'Back Up Then Erase', 36 | // negativeButton: 'Erase Now', 37 | // neutralButton: 'Cancel', 38 | // 39 | // negativeButtonStyle: 'default', 40 | // neutralButtonStyle: 'cancel', 41 | // 42 | // transitionStyle: 'bounceUp', 43 | // preferredStyle: style, 44 | // 45 | // theme, 46 | // accentColor: PlatformColor('systemBackground'), 47 | // 48 | // value: 'asdf', 49 | // placeholder: 'Enter your password', 50 | // keyboardType: 'number-pad', 51 | // 52 | // autoFocus: true, 53 | // allowEmptyEntry: false, 54 | // maxLength: 5, 55 | // 56 | // onPositivePress: (input: string) => console.warn('positive - ', input), 57 | // onNegativePress: (input: string) => console.warn('negative - ', input), 58 | // onNeutralPress: (input: string) => console.warn('neutral - ', input), 59 | // 60 | // onDismiss: () => console.warn('dismiss'), 61 | // }); 62 | 63 | // NativeDialog.showItemsDialog({ 64 | // title: 'How would you like to pay for your meal today?', 65 | // 66 | // mode: 'default', 67 | // items: [ 68 | // { id: 'cc', title: 'Credit Card' }, 69 | // { id: 'dc', title: 'Debit Card' }, 70 | // { id: 'pp', title: 'PayPal' }, 71 | // { id: 'c', title: 'Cash' }, 72 | // ], 73 | // selectedItems: ['pp', 'c'], 74 | // 75 | // preferredStyle: style, 76 | // 77 | // theme, 78 | // accentColor: '#1cc35d', 79 | // 80 | // positiveButton: 'Select', 81 | // negativeButton: 'Cancel', 82 | // 83 | // onItemSelect: (selectedId: string) => { 84 | // console.warn(selectedId); 85 | // }, 86 | // onNegativePress: () => console.warn('negative'), 87 | // onDismiss: () => console.warn('dismiss'), 88 | // }); 89 | 90 | // NativeDialog.showNumberPickerDialog({ 91 | // title: 'Pick a Number', 92 | // 93 | // preferredStyle: style, 94 | // theme, 95 | // accentColor: '#ff4a9e', 96 | // 97 | // minValue: -6, 98 | // maxValue: 6, 99 | // value: 5, 100 | // positiveButton: 'Pick', 101 | // 102 | // onPositivePress: (input: string) => console.warn('positive - ', input), 103 | // onNegativePress: (input: string) => console.warn('negative - ', input), 104 | // onNeutralPress: (input: string) => console.warn('neutral - ', input), 105 | // 106 | // onDismiss: () => console.warn('dismiss'), 107 | // 108 | // }); 109 | 110 | // NativeDialog.showDatePickerDialog({ 111 | // theme, 112 | // date: '01/01/1996', 113 | // }); 114 | 115 | NativeDialog.showRatingDialog({ 116 | title: 'Rate The App', 117 | 118 | preferredStyle: style, 119 | // theme, 120 | // accentColor: '#d93b3b', 121 | 122 | mode: 'rose', 123 | value: 2, 124 | 125 | positiveButton: 'Submit', 126 | negativeButton: 'Don\'t Ask Again', 127 | neutralButton: 'Remind Me Later', 128 | 129 | onPositivePress: (input: string) => console.warn('positive - ', input), 130 | onNegativePress: (input: string) => console.warn('negative - ', input), 131 | onNeutralPress: (input: string) => console.warn('neutral - ', input), 132 | 133 | onDismiss: () => console.warn('dismiss'), 134 | }); 135 | }; 136 | 137 | return ( 138 | 139 |