Giter Site home page Giter Site logo

purescript-reactnative's Introduction

purescript-reactnative

Latest release Travis Build

Purescript bindings for react-native

Goals

React-native is a fast moving javascript project which is frequently released (monthly at the time of writing). Much too fast for me to realistically keep all the purescript bindings continually up-to-date, so the goals are:

  • Keep up to date with purescript language releases.

  • Keep the official React Native docs as the best place to go for help. This will be acheived by:

  • Using record types for property passing.

  • Use newtype | foreign import data + smart constructors for property types.

  • Have unsafe versions of all the component functions, so if the library is lagging behind or the component does not yet have a safe version, it's still possible to use the library without too much hassle.

  • Stay event framework agnostic. This is acheived by using EffectFnX to model the event callbacks. I have also made a very small and simple library for working with react event handling (based on ReaderT) purescript-dispatcher-react.

Examples and Naming conventions

All component functions follow the naming convention of:

  • image - The most common properties
  • image_ - Only mandatory properties
  • image' - Mandatory properties and all optional properties - uses purescript row constraints to allow a single record to be passed in.
  • imageU - Unsafe, takes any properties

Enum property types will either be accessible through functions with the name of the enum:

newtype FlexDirection = FlexDirection String

row :: FlexDirection
row = FlexDirection "row"

rowReverse :: FlexDirection
rowReverse = FlexDirection "row-reverse"

column :: FlexDirection
column = FlexDirection "column"

columnReverse :: FlexDirection
columnReverse = FlexDirection "column-reverse"`

or a record which has a field for each value in the enum:

newtype KeyboardDismissMode = KeyboardDismissMode String
keyboardDismissMode :: {
    none :: KeyboardDismissMode
  , interactive :: KeyboardDismissMode
  , onDrag :: KeyboardDismissMode
}
keyboardDismissMode = {
    none: KeyboardDismissMode "none"
  , interactive: KeyboardDismissMode "interactive"
  , onDrag: KeyboardDismissMode "on-drag"
}

If you want to examples check out the code in the purescript-reactnative port of the Movies example app which comes with the react-native source code.

https://github.com/doolse/purescript-reactnative-example

Styles

Styles are defined using arrays of StyleProps and you can create a stylesheet simply by creating a record which contains these styles defined with staticStyles:

sheet :: { searchBar :: Styles
, searchBarInput :: Styles
, spinner :: Styles
, icon :: Styles
}
sheet = {
  searchBar: staticStyles [
    flexDirection row,
    alignItems center,
    backgroundColor $ rgbi 0xa9a9a9,
    height 56
  ],
  searchBarInput: staticStyles [
    flex 1,
    fontSize 20,
    fontWeight bold,
    color white,
    height 50,
    padding 0,
    backgroundColor transparent
  ],
  spinner: staticStyles [
    width 30,
    height 30,
    marginRight 16
  ],
  icon: staticStyles [
    width 24,
    height 24,
    marginHorizontal 8
  ]
}

Platform specific code

The decision to not do anything special with the type system concerning platform specific components is because:

  • a) Usually it very obvious from the component name
  • b) It would be a significant amount of extra work and type signature noise and I don't think the benefits justify it.

Having said that, platform specific properties have been separated into sub properties for clarity. For example:

type ViewProps eff = {
    style :: Styles
    -- More platform neutral properties
  , ios :: {
        shouldRasterizeIOS :: Boolean
    },
  , android :: {
        needsOffscreenAlphaCompositing :: Boolean
    }
}
import ReactNative.Components (iosProps,androidProps)

main = view' {accessible:true, android:androidProps {collapsable:true}, ios:iosProps {shouldRasterizeIOS:true} }

Getting started - Hello World

This is a barebones starter "in accordance with the ancient traditions of our people" meant to parallel the example on facebook's react-native docs.

Firstly, install the react native cli if you don't have it already, and then start a barebones react-native project:

npm install -g react-native-cli
react-native init HelloWorld

Also add in the basic purescript project structure to the project.

cd HelloWorld
pulp init --force

Install purescript react native dependency:

bower install purescript-reactnative --save

Replace the contents of src/Main.purs with

module Main where

import Prelude

import Effect (Effect)
import React (ReactClass, statelessComponent)
import ReactNative.API (registerComponent)
import ReactNative.Components.Text (text_)

app :: forall p. ReactClass {|p}
app = statelessComponent render
  where
  render _ = text_ "Hello World"
 
main :: Effect Unit
main = do
  registerComponent "HelloWorld" app

Then from your project root, build the purescript project and output it to index.js

pulp build --to index.js

And that's it! Fire up an emulator (e.g. android avd) or connect a device and launch your app:

react-native run-android

Component support table

The plan is to initially support a subset of the components fully, and provide unsafe functions for many of the others. Type safe versions of the components are created based off the react-native documentation, this table shows the current status:

Component Supported
View [x]
SafeAreaView [x]
Text [x]
TextInput [x]
Switch [x]
Touchable* [x]
Picker [x]
Slider [x]
ActivityIndicator [x]
ListView [x]
ScrollView [x]
Image [x]
RefreshControl [x]
Button [x]
NavigatorIOS [x] *
DrawerLayoutAndroid [x]
ToolbarAndroid [x]
Modal [x]
ProgressBarAndroid [x]
DatePickerIOS -
KeyboardAvoidingView -
MapView -
ProgressViewIOS -
SegmentedControlIOS -
StatusBar -
SnapshotViewIOS -
TabBarIOS -
TabBarIOSItem -
ViewPagerAndroid -
WebView -
API Version
alert [x]
color [x]
ListViewDataSource [x]

Anything marked with * may not have 100% coverage of API calls yet.

Contributors

purescript-reactnative's People

Contributors

bfleischhacker avatar dharanii avatar doolse avatar jvliwanag avatar miuirussia avatar sectore avatar will-evans avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-reactnative's Issues

Purescript 0.12 Support

Hey folks. I spent a little while trying to get this library working with purescript 0.12 over the weekend and ran into some problems. As far as I can tell the main thing that needs doing is removing the dependency on purescript-effect. Is that correct?

Navigator is deprecated

The Navigator component is deprecated in RN > 0.44.0, so it gives an error when trying to use purescript-reactnative with newer versions of React Native.

Webview to be spun out of react-native

RN webview now lives at:
https://github.com/react-native-community/react-native-webview

Tried running react native 0.58 and found two issues. Currently purescript-reactnative by virtue of importing webview directly from react native emits a yellow box warning. (The other issue should be handled by #27)

Not sure how to go with this though. Two options:

1 - Remove Webview bindings from this project. Let's maybe create a separate purescript-reactnative-webview
2 - Add a dependency to the js react-native-community/react-native-webview.

I think option 2 would mean users of this library would always need to install that js dep though even if they don't use the webview. So I'm leaning towards option 1.

Screenshot

I'd like to highlight this project on purescript.org as an example of using PureScript to target different JS runtimes. Would you be okay with that?

If so, could you please provide a screenshot of the project in action which I can use on the site? An ideal image would also provide some connection to PureScript, such as the source for the demo being in the background.

Update documentation for v0.12

It'd be great if we could update the documentation that's on the README.md so that it can pass the v0.12 version of the compiler.

Once I figure things out, I might issue a PR to do just that. For the time being, I'm still trying to figure it out.

How to call asynchronous functions from `createLifecycleComponent`'s eval function ?

I have been trying for hours to make a call to a JS function that returns a Promise from within an action evaluator.
My code looks like this:

1- Linking.js:

const RN = require('react-native');
exports.getInitialURLImpl = function(v) {
   return RN.Linking.getInitialURL();
}

2- Linking.purs:

foreign import data LINKING :: Effect
foreign import getInitialURLImpl :: forall eff. Unit -> Eff eff (Promise String)

getInitialURL :: forall eff. Aff (linking :: LINKING | eff) String
getInitialURL = liftEff (getInitialURLImpl unit) >>= toAff

3- Main.purs:

initialState = {}
data Action = HandleDeepLinking
app :: forall p. ReactClass p
app = createLifecycleComponent (didMount $ HandleDeepLinking) initialState render2 eval
  where
    eval (HandleDeepLinking) = void $ launchAff do
        x <- getInitialURL
        liftEff $ alert "test" (Just x)
        pure unit

The above fails at runtime:
screen shot 2018-06-09 at 4 10 34 am

Help!!!
@doolse

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.