Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: correct overriding border radius #3996

Merged
merged 1 commit into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions example/src/Examples/CardExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,19 @@ const CardExample = () => {
</Button>
</Card.Actions>
</Card>
<Card
style={[styles.card, styles.customCardRadius]}
mode={selectedMode}
>
<Card.Title
title="Custom border radius"
subtitle="... for card and cover"
/>
<Card.Cover
source={require('../../assets/images/artist-2.jpg')}
style={styles.customCoverRadius}
/>
</Card>
<Card style={styles.card} mode={selectedMode}>
<Card.Cover
source={require('../../assets/images/strawberries.jpg')}
Expand Down Expand Up @@ -218,6 +231,15 @@ const styles = StyleSheet.create({
button: {
borderRadius: 12,
},
customCardRadius: {
borderTopLeftRadius: 24,
borderBottomRightRadius: 24,
},
customCoverRadius: {
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
borderBottomRightRadius: 24,
},
});

export default CardExample;
25 changes: 17 additions & 8 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import useLatestCallback from 'use-latest-callback';
import { useInternalTheme } from '../../core/theming';
import type { $Omit, ThemeProp } from '../../types';
import hasTouchHandler from '../../utils/hasTouchHandler';
import { splitStyles } from '../../utils/splitStyles';
import Surface from '../Surface';
import CardActions from './CardActions';
import CardContent from './CardContent';
Expand Down Expand Up @@ -242,10 +243,19 @@ const Card = ({
mode: cardMode,
});

const {
borderRadius = (isV3 ? 3 : 1) * roundness,
borderColor = themedBorderColor,
} = (StyleSheet.flatten(style) || {}) as ViewStyle;
const flattenedStyles = (StyleSheet.flatten(style) || {}) as ViewStyle;

const { borderColor = themedBorderColor } = flattenedStyles;

const [, borderRadiusStyles] = splitStyles(
flattenedStyles,
(style) => style.startsWith('border') && style.endsWith('Radius')
);

const borderRadiusCombinedStyles = {
borderRadius: (isV3 ? 3 : 1) * roundness,
...borderRadiusStyles,
};

const content = (
<View
Expand All @@ -259,6 +269,7 @@ const Card = ({
index,
total,
siblings,
borderRadiusStyles,
})
: child
)}
Expand All @@ -268,15 +279,13 @@ const Card = ({
return (
<Surface
style={[
{
borderRadius,
},
isV3 && !isMode('elevated') && { backgroundColor },
!isV3 && isMode('outlined')
? styles.resetElevation
: {
elevation: computedElevation as unknown as number,
},
borderRadiusCombinedStyles,
style,
]}
theme={theme}
Expand All @@ -292,10 +301,10 @@ const Card = ({
testID={`${testID}-outline`}
style={[
{
borderRadius,
borderColor,
},
styles.outline,
borderRadiusCombinedStyles,
]}
/>
)}
Expand Down
15 changes: 14 additions & 1 deletion src/components/Card/CardCover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Image, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import { useInternalTheme } from '../../core/theming';
import { grey200 } from '../../styles/themes/v2/colors';
import type { ThemeProp } from '../../types';
import { splitStyles } from '../../utils/splitStyles';
import { getCardCoverStyle } from './utils';

export type Props = React.ComponentPropsWithRef<typeof Image> & {
Expand Down Expand Up @@ -49,7 +50,19 @@ const CardCover = ({
...rest
}: Props) => {
const theme = useInternalTheme(themeOverrides);
const coverStyle = getCardCoverStyle({ theme, index, total });

const flattenedStyles = (StyleSheet.flatten(style) || {}) as ViewStyle;
const [, borderRadiusStyles] = splitStyles(
flattenedStyles,
(style) => style.startsWith('border') && style.endsWith('Radius')
);

const coverStyle = getCardCoverStyle({
theme,
index,
total,
borderRadiusStyles,
});

return (
<View style={[styles.container, coverStyle, style]}>
Expand Down
16 changes: 16 additions & 0 deletions src/components/Card/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
import type { ViewStyle } from 'react-native';

import color from 'color';

import { black, white } from '../../styles/themes/v2/colors';
import type { InternalTheme } from '../../types';

type CardMode = 'elevated' | 'outlined' | 'contained';

type BorderRadiusStyles = Pick<
ViewStyle,
Extract<keyof ViewStyle, `border${string}Radius`>
>;

export const getCardCoverStyle = ({
theme,
index,
total,
borderRadiusStyles,
}: {
theme: InternalTheme;
borderRadiusStyles: BorderRadiusStyles;
index?: number;
total?: number;
}) => {
const { isV3, roundness } = theme;

if (Object.keys(borderRadiusStyles).length > 0) {
return {
borderRadius: 3 * roundness,
...borderRadiusStyles,
};
}

if (isV3) {
return {
borderRadius: 3 * roundness,
Expand Down
31 changes: 31 additions & 0 deletions src/components/__tests__/Card/Card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ const styles = StyleSheet.create({
customBorderRadius: {
borderRadius: 32,
},
customCoverRadius: {
borderTopLeftRadius: 4,
borderTopRightRadius: 8,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 2,
},
contentStyle: {
flexDirection: 'column-reverse',
},
Expand Down Expand Up @@ -108,6 +114,18 @@ describe('Card', () => {
});
});

describe('CardCover', () => {
it('renders with custom border radius', () => {
const { getByTestId } = render(
<Card>
<Card.Cover testID="card-cover" style={styles.customCoverRadius} />
</Card>
);

expect(getByTestId('card-cover')).toHaveStyle(styles.customCoverRadius);
});
});

describe('CardActions', () => {
it('renders button with passed mode', () => {
const { getByTestId } = render(
Expand Down Expand Up @@ -218,10 +236,20 @@ describe('getCardColors - border color', () => {
});

describe('getCardCoverStyle - border radius', () => {
it('should return custom border radius', () => {
expect(
getCardCoverStyle({
theme: getTheme(),
borderRadiusStyles: styles.customCoverRadius,
})
).toMatchObject(styles.customCoverRadius);
});

it('should return correct border radius based on roundness, for theme version 3', () => {
expect(
getCardCoverStyle({
theme: getTheme(),
borderRadiusStyles: {},
})
).toMatchObject({ borderRadius: 3 * getTheme().roundness });
});
Expand All @@ -230,6 +258,7 @@ describe('getCardCoverStyle - border radius', () => {
expect(
getCardCoverStyle({
theme: getTheme(false, false),
borderRadiusStyles: {},
index: 0,
total: 1,
})
Expand All @@ -240,6 +269,7 @@ describe('getCardCoverStyle - border radius', () => {
expect(
getCardCoverStyle({
theme: getTheme(false, false),
borderRadiusStyles: {},
index: 0,
total: 2,
})
Expand All @@ -253,6 +283,7 @@ describe('getCardCoverStyle - border radius', () => {
expect(
getCardCoverStyle({
theme: getTheme(false, false),
borderRadiusStyles: {},
index: 1,
total: 2,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ exports[`Card renders an outlined card 1`] = `
Array [
Object {
"borderColor": "rgba(121, 116, 126, 1)",
"borderRadius": 12,
},
Object {
"borderWidth": 1,
Expand All @@ -52,6 +51,9 @@ exports[`Card renders an outlined card 1`] = `
"width": "100%",
"zIndex": 2,
},
Object {
"borderRadius": 12,
},
]
}
testID="card-outline"
Expand Down