Skip to content

Conversation

@kamilkedzierski
Copy link
Contributor

Motivation

image

There is an issue with the Chip component when a Chip with mode="outlined" is used next to one with mode="flat" (see screenshot). The Chip with mode="flat" displays a kind of "shadow" at the bottom.

This problem is caused by the Surface component, which splits styles provided via props into outerLayerViewStyles and innerLayerViewStyles. Specifically, it is caused by the backgroundColor, which has the same value in both outerLayerViewStyles and innerLayerViewStyles (see below, reference):

  const outerLayerViewStyles = {
        ...(isElevated && getStyleForShadowLayer(elevation, 0)),
        ...outerLayerStyles,
        ...borderRadiusStyles,
        backgroundColor: bgColor,
      };

  const innerLayerViewStyles = {
    ...(isElevated && getStyleForShadowLayer(elevation, 1)),
    ...filteredStyles,
    ...borderRadiusStyles,
    flex: flattenedStyles.height ? 1 : undefined,
    backgroundColor: bgColor,
  };

A Chip with mode="outlined" is 2dp larger in width and height than one with mode="flat" due to its borderWidth of 1dp. When both modes are placed next to each other, the outer View of the Surface component adjusts to fill the height difference, but the inner View does not. Since the background color for a disabled Chip uses RGBA (with opacity), the inner and outer background colors create overlapping layers, resulting in the visible "shadow" at the bottom.

Possible solutions

1. Adding flexGrow: 1 to the Surface used inside Chip component

Adding flexGrow: 1 would resolve the issue by allowing the inner View of the Surface to grow and match the height of the outer View. However, because outerLayerStylesProperties includes flexGrow, it won't be applied to the inner layer out of the box. To manage this, we could pass separate props like innerLayerStyles and outerLayerStyles. However, this approach might affect other components using Surface, making it a more complex solution.

2. Setting borderWidth:1 for both modes and within the flat mode setting the borderColor to transparent (implemented here)

IMO this is the least impactful solution. It ensures both modes have matching dimensions (width and height) and restricts the change to the Chip component itself.

Related issue

#4457

Test plan

You can test it by changing ChipExample.tsx

 <View style={styles.container}>
      <Chip mode="outlined" selected={false}>
          Not selected, enabled
      </Chip>
      <Chip mode="flat" selected disabled>
          Selected, disabled
      </Chip>
 </View>
const styles = StyleSheet.create({
  container: {
    marginTop: 16,
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
});

image

@callstack-bot
Copy link

callstack-bot commented Jul 24, 2024

Hey @kamilkedzierski, thank you for your pull request 🤗. The documentation from this branch can be viewed here.

@kamilkedzierski kamilkedzierski changed the title fix: fixed Chip "shadow" and height issue fix: fixed Chip "shadow" and height issue Jul 24, 2024
@kamilkedzierski kamilkedzierski added this to the 5.12.4 milestone Jul 24, 2024
@lukewalczak lukewalczak modified the milestones: 5.12.4, 5.12.5 Jul 27, 2024
@kamilkedzierski kamilkedzierski modified the milestones: 5.12.5, 5.12.6 Jul 29, 2024
@lukewalczak lukewalczak self-assigned this Apr 17, 2025
@lukewalczak lukewalczak merged commit 8208811 into callstack:main Apr 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants