Skip to content

Commit

Permalink
feat: support flat and elevated mode (#3799)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewalczak authored and teneeto committed May 10, 2023
1 parent b885bd0 commit d34e4d3
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 133 deletions.
102 changes: 59 additions & 43 deletions example/src/Examples/SurfaceExample.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,74 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import { ScrollView, StyleSheet, View } from 'react-native';

import { MD3Elevation, Surface, Text, MD3Colors } from 'react-native-paper';
import {
MD3Elevation,
Surface,
Text,
MD3Colors,
List,
} from 'react-native-paper';

import { useExampleTheme } from '..';
import { isWeb } from '../../utils';
import ScreenWrapper from '../ScreenWrapper';

const SurfaceExample = () => {
const { isV3 } = useExampleTheme();

const v2Elevation = [1, 2, 4, 8, 12];
const baseElevation = isV3 ? Array.from({ length: 6 }) : v2Elevation;
const elevationValues = isV3 ? Array.from({ length: 6 }) : v2Elevation;

return (
<ScreenWrapper
contentContainerStyle={[styles.content, isWeb && styles.webContent]}
const renderSurface = (index: number, mode: 'flat' | 'elevated') => (
<Surface
key={index}
style={[
styles.surface,
isV3 ? styles.v3Surface : { elevation: v2Elevation[index] },
]}
mode={mode}
{...(isV3 && { elevation: index as MD3Elevation })}
>
{baseElevation.map((e, i) => (
<Surface
key={i}
style={[
styles.surface,
isV3 ? styles.v3Surface : { elevation: v2Elevation[i] },
]}
{...(isV3 && { elevation: i as MD3Elevation })}
>
<Text variant="bodyLarge">
{isV3 ? `Elevation ${i === 1 ? '(default)' : ''} ${i}` : `${e}`}
</Text>
</Surface>
))}
<Text variant="bodyLarge">
{isV3
? `Elevation ${index === 1 ? '(default)' : ''} ${index}`
: `${elevationValues[index]}`}
</Text>
</Surface>
);

return (
<ScreenWrapper>
<List.Section title="Elevated surface">
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{elevationValues.map((_, index) => renderSurface(index, 'elevated'))}
</ScrollView>
</List.Section>

<List.Section title="Flat surface">
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{elevationValues.map((_, index) => renderSurface(index, 'flat'))}
</ScrollView>
</List.Section>

<View style={styles.horizontalSurfacesContainer}>
<Surface style={styles.horizontalSurface}>
<Text style={styles.centerText}>Left</Text>
</Surface>
<Surface style={styles.horizontalSurface}>
<Text style={styles.centerText}>Right</Text>
</Surface>
</View>
<View style={styles.verticalSurfacesContainer}>
<Surface style={styles.verticalSurface}>
<Text style={styles.centerText}>Top</Text>
</Surface>
<Surface style={styles.verticalSurface}>
<Text style={styles.centerText}>Bottom</Text>
</Surface>
</View>
<List.Section title="Layout">
<View style={styles.content}>
<View style={styles.horizontalSurfacesContainer}>
<Surface style={styles.horizontalSurface}>
<Text style={styles.centerText}>Left</Text>
</Surface>
<Surface style={styles.horizontalSurface}>
<Text style={styles.centerText}>Right</Text>
</Surface>
</View>
<View style={styles.verticalSurfacesContainer}>
<Surface style={styles.verticalSurface}>
<Text style={styles.centerText}>Top</Text>
</Surface>
<Surface style={styles.verticalSurface}>
<Text style={styles.centerText}>Bottom</Text>
</Surface>
</View>
</View>
</List.Section>
</ScreenWrapper>
);
};
Expand All @@ -59,11 +80,6 @@ const styles = StyleSheet.create({
padding: 24,
alignItems: 'center',
},
webContent: {
flexDirection: 'row',
flexWrap: 'wrap',
padding: 0,
},
surface: {
margin: 24,
height: 80,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { Animated, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import useLatestCallback from 'use-latest-callback';

import { useInternalTheme } from '../core/theming';
import type { $RemoveChildren, ThemeProp } from '../types';
import type { $Omit, $RemoveChildren, ThemeProp } from '../types';
import Button from './Button/Button';
import Icon, { IconSource } from './Icon';
import Surface from './Surface';
import Text from './Typography/Text';

const DEFAULT_MAX_WIDTH = 960;

export type Props = $RemoveChildren<typeof Surface> & {
export type Props = $Omit<$RemoveChildren<typeof Surface>, 'mode'> & {
/**
* Whether banner is currently visible.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import {
import color from 'color';

import { useInternalTheme } from '../../core/theming';
import type { ThemeProp } from '../../types';
import type { $Omit, ThemeProp } from '../../types';
import ActivityIndicator from '../ActivityIndicator';
import Icon, { IconSource } from '../Icon';
import Surface from '../Surface';
import TouchableRipple from '../TouchableRipple/TouchableRipple';
import Text from '../Typography/Text';
import { ButtonMode, getButtonColors } from './utils';

export type Props = React.ComponentProps<typeof Surface> & {
export type Props = $Omit<React.ComponentProps<typeof Surface>, 'mode'> & {
/**
* Mode of the button. You can change the mode to adjust the styling to give it desired emphasis.
* - `text` - flat button without background or outline, used for the lowest priority actions, especially when presenting multiple options.
Expand Down
4 changes: 2 additions & 2 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import useLatestCallback from 'use-latest-callback';

import { useInternalTheme } from '../../core/theming';
import type { ThemeProp } from '../../types';
import type { $Omit, ThemeProp } from '../../types';
import Surface from '../Surface';
import CardActions from './CardActions';
import CardContent from './CardContent';
Expand Down Expand Up @@ -41,7 +41,7 @@ type HandlePressType = 'in' | 'out';

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

export type Props = React.ComponentProps<typeof Surface> & {
export type Props = $Omit<React.ComponentProps<typeof Surface>, 'mode'> & {
/**
* Mode of the Card.
* - `elevated` - Card with elevation.
Expand Down
4 changes: 2 additions & 2 deletions src/components/Chip/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {

import { useInternalTheme } from '../../core/theming';
import { white } from '../../styles/themes/v2/colors';
import type { EllipsizeProp, ThemeProp } from '../../types';
import type { $Omit, EllipsizeProp, ThemeProp } from '../../types';
import type { IconSource } from '../Icon';
import Icon from '../Icon';
import MaterialCommunityIcon from '../MaterialCommunityIcon';
Expand All @@ -23,7 +23,7 @@ import TouchableRipple from '../TouchableRipple/TouchableRipple';
import Text from '../Typography/Text';
import { getChipColors } from './helpers';

export type Props = React.ComponentProps<typeof Surface> & {
export type Props = $Omit<React.ComponentProps<typeof Surface>, 'mode'> & {
/**
* Mode of the chip.
* - `flat` - flat chip without outline.
Expand Down
4 changes: 2 additions & 2 deletions src/components/FAB/AnimatedFAB.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import color from 'color';

import { useInternalTheme } from '../../core/theming';
import type { $RemoveChildren, ThemeProp } from '../../types';
import type { $Omit, $RemoveChildren, ThemeProp } from '../../types';
import type { IconSource } from '../Icon';
import Icon from '../Icon';
import Surface from '../Surface';
Expand All @@ -32,7 +32,7 @@ import { getCombinedStyles, getFABColors } from './utils';
export type AnimatedFABIconMode = 'static' | 'dynamic';
export type AnimatedFABAnimateFrom = 'left' | 'right';

export type Props = $RemoveChildren<typeof Surface> & {
export type Props = $Omit<$RemoveChildren<typeof Surface>, 'mode'> & {
/**
* Icon to display for the `FAB`.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/components/FAB/FAB.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from 'react-native';

import { useInternalTheme } from '../../core/theming';
import type { $RemoveChildren, ThemeProp } from '../../types';
import type { $Omit, $RemoveChildren, ThemeProp } from '../../types';
import { forwardRef } from '../../utils/forwardRef';
import ActivityIndicator from '../ActivityIndicator';
import CrossFadeIcon from '../CrossFadeIcon';
Expand All @@ -34,7 +34,7 @@ type IconOrLabel =
label: string;
};

export type Props = $RemoveChildren<typeof Surface> & {
export type Props = $Omit<$RemoveChildren<typeof Surface>, 'mode'> & {
// For `icon` and `label` props their types are duplicated due to the generation of documentation.
// Appropriate type for them is `IconOrLabel` contains the both union and intersection types.
/**
Expand Down
4 changes: 2 additions & 2 deletions src/components/Snackbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import useLatestCallback from 'use-latest-callback';

import { useInternalTheme } from '../core/theming';
import type { $RemoveChildren, ThemeProp } from '../types';
import type { $Omit, $RemoveChildren, ThemeProp } from '../types';
import Button from './Button/Button';
import type { IconSource } from './Icon';
import IconButton from './IconButton/IconButton';
import MaterialCommunityIcon from './MaterialCommunityIcon';
import Surface from './Surface';
import Text from './Typography/Text';

export type Props = React.ComponentProps<typeof Surface> & {
export type Props = $Omit<React.ComponentProps<typeof Surface>, 'mode'> & {
/**
* Whether the Snackbar is currently visible.
*/
Expand Down
Loading

0 comments on commit d34e4d3

Please sign in to comment.