diff --git a/src/components/structure/Card/Card.tsx b/src/components/structure/Card/Card.tsx index 33e2b26..c1e84ab 100644 --- a/src/components/structure/Card/Card.tsx +++ b/src/components/structure/Card/Card.tsx @@ -1,7 +1,6 @@ import React from 'react' import { View } from 'react-native' import { Heading } from '../../text/Heading/Heading' -import { useStyles } from '../../../theme' import { Link } from '../../actions/Link/Link' import { Box } from '../Box/Box' import { Divider } from '../Divider/Divider' @@ -11,6 +10,7 @@ import { Icon } from '../../images-and-icons/Icon/Icon' import { BodyText } from '../../text/BodyText/BodyText' import { shameStyles } from '../../../theme/shame-styles' import { TextAction } from '../../actions/actions' +import { useStylesBuilder, createStyles } from '../../../theme/styles-builder' import { Section } from './Section/Section' export interface CardProps { @@ -57,21 +57,7 @@ export const Card: React.FC & { Section: typeof Section } = ({ warning = false, mainActions = [], }) => { - const styles = useStyles(theme => ({ - card: { - ...theme.elevation.z2, - - backgroundColor: theme.colors.fill.background.lighter, - borderRadius: fullWidth ? 0 : theme.radius.medium, - }, - cardSubdued: { - backgroundColor: shameStyles.card.subdued.backgroundColor, - }, - cardWarning: { - ...theme.elevation.z0, - backgroundColor: theme.colors.status.warning, - }, - })) + const styles = useStylesBuilder(stylesBuilder) const content = sectioned ?
{children}
: children @@ -84,7 +70,14 @@ export const Card: React.FC & { Section: typeof Section } = ({ )) return ( - + {title ? : null} {items} {mainActions.map((action, index) => ( @@ -94,6 +87,24 @@ export const Card: React.FC & { Section: typeof Section } = ({ ) } +const stylesBuilder = createStyles(({ colors, radius, elevation }) => ({ + card: { + backgroundColor: colors.fill.background.lighter, + borderRadius: radius.medium, + ...elevation.z2, + }, + cardFullWidth: { + borderRadius: 0, + }, + cardSubdued: { + backgroundColor: shameStyles.card.subdued.backgroundColor, + }, + cardWarning: { + ...elevation.z0, + backgroundColor: colors.status.warning, + }, +})) + const CardHeader: React.FC<{ title: string; action?: TextAction }> = ({ title, action }) => ( diff --git a/src/theme/styles-builder.ts b/src/theme/styles-builder.ts new file mode 100644 index 0000000..c0883cd --- /dev/null +++ b/src/theme/styles-builder.ts @@ -0,0 +1,25 @@ +import { StyleSheet } from 'react-native' +import { useContext, useMemo } from 'react' +import { AppProviderContext } from '../components/structure/AppProvider/AppProviderContext' +import { Theme } from './theme-types' + +export type StylesBuilder> = (theme: Theme) => T + +export const createStyles = >( + builder: StylesBuilder, +): StylesBuilder => builder + +/** + * Constructs styles and memoize them according to the current theme. + */ +export const useStylesBuilder = >( + builder: StylesBuilder, +): T => { + const theme = useTheme() + return useMemo(() => builder(theme), [theme]) +} + +/** + * Return the current theme. + */ +export const useTheme = (): Theme => useContext(AppProviderContext).theme