react-native-ui-kitten icon indicating copy to clipboard operation
react-native-ui-kitten copied to clipboard

Custom Card Body

Open HridayK97 opened this issue 4 years ago • 17 comments

💬 Question

Looking at the documentation, it seems like the Card component is designed for only <Text> as the main content. Is there a way to enable a custom flex <View> content inside as well? I tried using a custom layout with <View> as the child, but the layout is not showing up correctly, and flex is not having the expected behavior.

UI Kitten and Eva version

Package Version
@eva-design/eva 2.0.0
@ui-kitten/components 5.0.0

HridayK97 avatar Oct 01 '20 18:10 HridayK97

What do you mean with custom flex? Could you please also provide a sample code?

artyorsh avatar Oct 08 '20 13:10 artyorsh

@artyorsh

If you run the code below, you'd see the child components of Card do not follow the flexDirection: 'row' property but rather stubbornly get rendered in a column.

import React from 'react';
import { Image, StyleSheet, View } from 'react-native';
import { Card, Text } from '@ui-kitten/components';

export const WriterItem = (props) => {
    return (
        <Card style={styles.card}>
            <View>
                <Image source={props.source} style={styles.cover}></Image>
            </View>
            <Text category="h5">The Vampire</Text>
        </Card>
    );
};

const styles = StyleSheet.create({
    card: {
        width: '95%',
        display: 'flex',
        flexDirection: 'row',
    },
    cover: {
        width: 60,
        height: 60,
    },
});

parkerqueen avatar Oct 11 '20 11:10 parkerqueen

I'm having wired behavior same as @parkerqueen with flex props on a card. It doesn't respect all flex related props!

eyalyoli avatar Nov 01 '20 20:11 eyalyoli

This all happens due to this line. I agree that this is not expected behavior and as a workaround which covers every styling use cases my only suggestion would be using the structure like this:

const MyCard = ({ contentContainerStyle, children, ...props }) => (
  <Card {...props}>
    <View style={[{ marginHorizontal: -24, marginVertical: -16 }, contentContainerStyle]}>
      {children}
    </View>
  </Card>
);

Also covers https://github.com/akveo/react-native-ui-kitten/issues/1037. See an example

artyorsh avatar Nov 02 '20 21:11 artyorsh

What you suggested dosen't work on android. At least flex direction had no effect. I found out that when you set a fixed height & width for the root body view, it solves the problems of flex direction. I tried using '100%' on height & width it doesn't work. And you can't use flex=1 for cards body :facepalm:. So it is a fixed size only.

eyalyoli avatar Nov 03 '20 08:11 eyalyoli

@eyalyoli I had just launched the example by the link I shared to clarify this and it worked. Could you please try that?

artyorsh avatar Nov 03 '20 08:11 artyorsh

@artyorsh sorry for not beign specific. Using your code and chaning it to:

<MyCard 
            style={{ marginVertical: 8, flex:1 }}
            contentContainerStyle={{ flex:1, flexDirection: 'row', justifyContent:'center', alignItems:'center' }}>
...
</MyCard>

flex on the card takes effect, but not on the body. This works as if card's body had no height. But when you set height=400 you'll get the needed results. I was wrong, the same issue effects web view.

Hope you could help with that.

eyalyoli avatar Nov 03 '20 10:11 eyalyoli

@eyalyoli could you please clarify then which result you need to achieve?

artyorsh avatar Nov 03 '20 11:11 artyorsh

This is the behaviour of card (top) vs view (bottom) with the same prop styling: image

I tried to make the view in the same structure as the card. The problem is that flex: 1 is not working as you would think in a View. Card code:

<MyCard
            style={{ marginVertical: 8, flex: 1 }}
            contentContainerStyle={{
              flex: 1,
              flexDirection: 'row',
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <Image
              style={{ width: 80, height: 80 }}
              source={{
                uri:
                  'https://akveo.github.io/react-native-ui-kitten/images/Artboard-1.png',
              }}
            />
            <Text style={{ margin: 12 }} category="h5">
              Title
            </Text>
            <Text style={{ margin: 12 }}>
              Text Text
            </Text>
</MyCard>

View code:

 <View style={{ marginVertical: 8, flex: 1 }}> //this is the card
            <View //this is the root view that used in the card
              style={{
                flex: 1,
                flexDirection: 'row',
                justifyContent: 'center',
                alignItems: 'center',
                borderWidth: 2,
              }}>
              <Image
                style={{ width: 80, height: 80 }}
                source={{
                  uri:
                    'https://akveo.github.io/react-native-ui-kitten/images/Artboard-1.png',
                }}
              />
              <Text style={{ margin: 12 }} category="h5">
                Title
              </Text>
              <Text style={{ margin: 12 }}>
              Text Text
            </Text>
            </View>
</View>

This is just an example of a more complex case in which I have an image as a header & other information in the body of a card and I need to make it scale dynamiclly with different screen sizes (using flex).

eyalyoli avatar Nov 03 '20 12:11 eyalyoli

@artyorsh should I reopen this as a bug? I noticed that when flex in footer seems to work fine.

eyalyoli avatar Nov 11 '20 08:11 eyalyoli

Ok, for everyone who needs complex card content that is very responsive to screen size, I managed to do so using my own card implementation.

<View
      style={[
        {
          borderRadius: 15,
          borderWidth: 1,
          margin: 20,
          borderColor: theme["color-basic-300"],
          overflow: "hidden",
          flex: 1,
        },
        style,
      ]}
    >
      <View>{header()}</View>
      <View> // 1
        <View>{children}</View>
        <Divider />
        <View>{footer()}</View>
      </View>
    </View>

You can do whatever you need with the sizes and flexboxes, I wrapped the footer and the chidren with a view (marked 1) becuase my header is just an image. This will look very similar to kitten's card component.

eyalyoli avatar Nov 16 '20 07:11 eyalyoli

Any updates ? Adding a props we can pass to the card's body container would solve the issue

jackstudd avatar Mar 16 '21 07:03 jackstudd

Is there any progress on this issue? This is a very strange behaviour which breaks most of my layouts...

iMarvinS avatar May 20 '21 20:05 iMarvinS

Any updates?

siarheipashkevich avatar May 03 '23 18:05 siarheipashkevich

I am still facing these issues..

c-goettert avatar Jul 01 '23 12:07 c-goettert

+1, the header does not respect flex properties either.

DamianUS avatar Aug 26 '23 19:08 DamianUS

Holly.... Was starting to use this UI library. Saw this issue, from 2020 with still no solution and not resolved. Will switch to something else directly.

thomaslc66 avatar Apr 20 '24 10:04 thomaslc66