akveo / react-native-ui-kitten

:boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
https://akveo.github.io/react-native-ui-kitten/
MIT License
10.36k stars 958 forks source link

Custom Card Body #1255

Open HridayK97 opened 4 years ago

HridayK97 commented 4 years ago

💬 Question

Looking at the documentation, it seems like the Card component is designed for only as the main content. Is there a way to enable a custom flex content inside as well? I tried using a custom layout with 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
artyorsh commented 4 years ago

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

parkerqueen commented 4 years ago

@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,
    },
});
eyalyoli commented 4 years ago

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

artyorsh commented 4 years ago

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

eyalyoli commented 4 years ago

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.

artyorsh commented 4 years ago

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

eyalyoli commented 4 years ago

@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.

artyorsh commented 4 years ago

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

eyalyoli commented 4 years ago

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 commented 4 years ago

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

eyalyoli commented 4 years ago

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.

jackstudd commented 3 years ago

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

iMarvinS commented 3 years ago

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

siarheipashkevich commented 1 year ago

Any updates?

c-goettert commented 1 year ago

I am still facing these issues..

DamianUS commented 1 year ago

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

thomaslc66 commented 7 months ago

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.