carlosroberto555 / react-native-final-form-material

A Material Design library that uses react-native-paper
1 stars 1 forks source link

Update for react-native-paper 3.6.0 and SelectField #1

Open kopax opened 4 years ago

kopax commented 4 years ago

Hi Carlos roberto, I was googling for react-final-form package that use react-native-paper and found your repo.

I would like to know why do you need styled-components here: https://github.com/carlosroberto555/react-native-final-form-material/blob/b0b0bc925ff881f507d2f6c1e1cc2787cbb21a87/package.json#L42

It seems you are not using it anywhere in your code.

I am thinking to do a <SelectField /> would you be interested me to join?

carlosroberto555 commented 4 years ago

I would like to know why do you need styled-components here:

https://github.com/carlosroberto555/react-native-final-form-material/blob/b0b0bc925ff881f507d2f6c1e1cc2787cbb21a87/package.json#L42

It seems you are not using it anywhere in your code.

I have installed the styled-components and never used haha.

I am thinking to do a <SelectField /> would you be interested me to join?

Well, create a PR to merge in my repo :+1: Today we have Input, RadioButton and TextArea

carlosroberto555 commented 4 years ago

I think update the README too

kopax commented 4 years ago

I have installed the styled-components and never used haha.

Then it should be removed

Well, create a PR to merge in my repo +1

I just build and the only thing is I do not use typescript and can't invest the time to learn now, may I just past the component here and you'll update it to typescript when you'll need it?

I think update the README too

Yes I also thought the README was a bit empty :smile:

Considering I will soon not be the only one around here, having some attractivness to earn some contributors would be nice.

Perhaps a logo in the readme and a live documentation/codesandbox would be a nice idea.

If you are interested I personally use react-styleguidist for the react and react-native live documentation, you can see how I configured styleguidist to work with react-native and expo here, this is more my in my knowledge so I may give a hand when I'll have time.

carlosroberto555 commented 4 years ago

I just build and the only thing is I do not use typescript and can't invest the time to learn now, may I just past the component here and you'll update it to typescript when you'll need it?

I'll make the component declaration file to keep compatibility with typescript, and keep your components in pure JS (easy for you mantain).

Yes I also thought the README was a bit empty

Considering I will soon not be the only one around here, having some attractivness to earn some contributors would be nice.

Perhaps a logo in the readme and a live documentation/codesandbox would be a nice idea.

If you are interested I personally use react-styleguidist for the react and react-native live documentation, you can see how I configured styleguidist to work with react-native and expo here, this is more my in my knowledge so I may give a hand when I'll have time.

Nice rsrs. I don't have knowledge with lib docs (and I'm just learning english yet). I'm excited it, and I will be aprove all things you do haha.

kopax commented 4 years ago

Ho @carlosroberto555 ,

this is my <SelectField />, it can of course be improved:

/* eslint-disable */
import React, { memo, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Button, Menu, withTheme } from 'react-native-paper';

const SelectField = ({
  t,
  input: { onChange, ...input },
  meta: { data: { data }, ...meta },
  name,
  validate,
  loading,
  error,
  buttonProps,
  theme: { colors },
  label,
  loadData,
  ...rest
}) => {
  const styles = StyleSheet.create({
    container: {
      width: '100%',
      marginVertical: 12,
    },
    input: {
      backgroundColor: colors.surface,
    },
    error: {
      fontSize: 14,
      color: colors.error,
      paddingHorizontal: 4,
      paddingTop: 4,
    },
  });
  const [visible, setVisible] = useState(false);
  const list = data && data.data ? data.data : data;
  return (
      <View style={styles.container}>
        <Menu
          visible={visible}
          onDismiss={() => setVisible(false)}
          anchor={
            <Button
              icon="chevron-down"
              mode="outlined"
              compact
              color={colors.white}
              style={{
                borderColor: colors.backgroundColor,
              }}
              contentStyle={{
                justifyContent: 'flex-start'
              }}
              onPress={async () => {
                if (list?.length > 0) {
                  setVisible(true);
                } else {
                  await loadData();
                }
              }}
              loading={loading > 0}
              disabled={loading > 0}
              uppercase={false}
              {...buttonProps}
            >
              {data?.find((d) => d.id === input.value)?.description || label}
            </Button>
          }
        >
          {list?.length > 0 && list.map((item) => (
            <Menu.Item
              key={item.id}
              onPress={() => {onChange(item.id); setVisible(false)}}
              title={item.description}
            />
          ))}
        </Menu>
        {meta.error && meta.touched && <Text style={styles.error}>{meta.error}</Text>}
      </View>
  );
};

export default memo(withTheme(SelectField));

I feed it with a <Controller /> that fetch the data asyncrounously, and pass data and loadData props to reload the data, but that's not a requirement, it gives you the global idea.

Some improvements can be done with the theming.

kopax commented 4 years ago

I have updated with a much nicer look:

/* eslint-disable */
import React, { memo, useState } from 'react';
import { StyleSheet, Text, View, Platform } from 'react-native';
import { Menu, withTheme, IconButton } from 'react-native-paper';
import { TextInput, TouchableRipple } from 'react-native-paper';

const SelectField = ({
  t,
  input: { onChange, ...input },
  meta: { data: { data }, ...meta },
  name,
  validate,
  loading,
  error,
  buttonProps,
  theme: { colors },
  label,
  loadData,
  ...rest
}) => {
  const styles = StyleSheet.create({
    container: {
      width: '100%',
      marginVertical: 12,
    },
    error: {
      fontSize: 14,
      color: colors.error,
      paddingHorizontal: 4,
      paddingTop: 4,
    },
    options: {
      width: '100%',
      paddingRight: 0,
      paddingLeft: 0,
      alignItems: 'center',
      paddingBottom: 0,
      flexDirection: 'row',
    },
    caret: {
      position: 'absolute',
      right: 0,
      alignSelf: 'center',
      paddingTop: Platform.select({
        web: 0,
        default: 7,
      }),
    },
    input: {
      width: '100%',
    },
    menu: {
      paddingTop: 60
    },
  });
  const [visible, setVisible] = useState(false);
  const list = data && data.data ? data.data : data;
  return (
    <>
      <View style={styles.container}>
        <Menu
          style={styles.menu}
          visible={visible}
          onDismiss={() => setVisible(false)}
          anchor={
            <TouchableRipple
              onPress={async () => {
                if (list?.length > 0) {
                  setVisible(true);
                } else {
                  await loadData();
                }
              }}
            >
              <View
                style={styles.options}
                pointerEvents="none"
              >
                <TextInput
                  style={styles.input}
                  icon="chevron-down"
                  mode="outlined"
                  label={label}
                  editable={false}
                  disabled={loading > 0}
                  value={data?.find((d) => d.id === input.value)?.description || ''}
                  error={meta.error && meta.touched}
                  {...buttonProps}
                />
                <IconButton
                  color={meta.error && meta.touched ? colors.error : undefined}
                  style={styles.caret}
                  icon={visible ? 'menu-up' : 'menu-down'}
                  size={24}
                />
              </View>
            </TouchableRipple>
          }
        >
          {list?.length > 0 && list.map((item) => (
            <Menu.Item
              key={item.id}
              onPress={() => {onChange(item.id); setVisible(false)}}
              title={item.description}
            />
          ))}
        </Menu>
      </View>
      <View>
        {meta.error && meta.touched && <Text style={styles.error}>{meta.error}</Text>}
      </View>
    </>
  );
};

export default memo(withTheme(SelectField));

Closed select:

image

Open select:

image

kopax commented 4 years ago

I don't have knowledge with lib docs (and I'm just learning english yet). I'm excited it, and I will be aprove all things you do haha.

If you are up for this, I will have a look at this when I'll have free time, most likely this summer.

(BTW, I am not using your lib yet, but I believe one should exist and starting from your work done make some sens)