Apply shadow to a container in react-native

Viewed 1088

I have a table component that has different styling for the first, last rows and odd vs even elements:

import React from 'react';
import { View, Text } from 'react-native';


export const Table = ({ children }) => {
  // different style for odd and even elements, first and last rows
  let nextChildren = React.Children.toArray(children).filter(child => !!child);

  nextChildren = nextChildren.map(
    (el, i) => (i % 2 === 1 ? el : React.cloneElement(el, { odd: true }))
  );

  nextChildren[0] = React.cloneElement(nextChildren[0], { firstRow: true })

  nextChildren[nextChildren.length - 1] = React.cloneElement(
    nextChildren[nextChildren.length - 1],
    { lastRow: true }
  );

  return <View style={styles.table}>{nextChildren}</View>;
}

It contains several Rows:

export const Row = ({ children, type, firstRow, lastRow, odd, rowStyle, title, subtitle }) => (
  <View
    style={[
      styles.row,
      styles[type],
      rowStyle,
      odd ? styles.odd : {},
      firstRow ? styles.firstRow : {},
      lastRow ? styles.lastRow : {},
    ]}
  >
    {title && <Text style={styles.rowTitle}>{title}</Text>}
    {subtitle && <Text style={styles.rowSubtitle}>{subtitle}</Text>}
    {children}
  </View>
);

It's used like this:

<Table>
  <Row type='column' title='Status' subtitle='status' />
  <Row type='column' title='Transaction Start' subtitle='start' />
  <Row type='column' title='Transaction Done' subtitle='end' />
  <Row type='column' title='From' subtitle='from' />
  <Row type='column' title='To' subtitle='to' />
  <Row type='column' title='Transaction Number' subtitle='aewfibvkadier' />
</Table>

The important style is the first one, table: it's applied to the table container and has both a border (testing reasons) and the shadows applied to it.

import { StyleSheet } from 'react-native';
const GREY10 = '#F8F9FB'
const GREY50 = '#515A64'
const BLACK = '#000000'

const styles = StyleSheet.create({
  table: {
    margin: 12,

    // shadow
    shadowColor: BLACK,
    shadowOpacity: 1,
    shadowRadius: 10,
    shadowOffset: {
      height: 2,
      width: 2,
    },

    // border
    borderColor: BLACK,
    borderWidth: 1,
    borderRadius: 2,
  },
  row: {
    flexDirection: 'row',
    paddingHorizontal: 12,
    paddingVertical: 18,
    borderStyle: 'solid',
  },

  // row styles
  firstRow: {
    borderTopRightRadius: 6,
    borderTopLeftRadius: 6,
  },
  lastRow: {
    borderBottomRightRadius: 6,
    borderBottomLeftRadius: 6,
  },
  odd: {
    backgroundColor: GREY10,
  },

  // row types
  default: {
  },
  column: {
    flexDirection: 'column',
  },

  // styling for things in rows
  rowTitle: {
    color: GREY50,
    marginBottom: 4,
    fontSize: 16,
    lineHeight: 20,
  },
  rowSubtitle: {
    color: BLACK,
    fontSize: 16,
    lineHeight: 20,
  },

})

You'd expect the shadows to applied to the table container, right? WRONG.

enter image description here

Everything BUT the Table container is shadowed. The Text is shadowed if it's on an offwhite Row, the Row is shadowed if it's a white Row, and the border has a shadow! If the border is removed, the wrapping shadow around the Table container (the only shadow I want) is removed as well.

How do I apply the shadow to the container?

1 Answers

Okay, the problem is calculating shadows on similar colors. Make sure colors are exactly right for each component.

const WHITE = '#fff'
const GREY10 = '#F8F9FB'
const BLACK = '#000000'

Background color was WHITE, but it should have been GREY10. Even/odd Rows were nothing/background and GREY10, but should have been GREY10/WHITE (explicitly).

Related