Skip to content

Commit

Permalink
feat: create Tooltip component (#3441)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunohkbx authored Nov 14, 2022
1 parent 32cb880 commit bc2a1c4
Show file tree
Hide file tree
Showing 17 changed files with 1,169 additions and 471 deletions.
2 changes: 2 additions & 0 deletions example/src/ExampleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import TextExample from './Examples/TextExample';
import TextInputExample from './Examples/TextInputExample';
import ThemeExample from './Examples/ThemeExample';
import ToggleButtonExample from './Examples/ToggleButtonExample';
import TooltipExample from './Examples/TooltipExample';
import TouchableRippleExample from './Examples/TouchableRippleExample';

import { useExampleTheme } from '.';
Expand Down Expand Up @@ -82,6 +83,7 @@ export const examples: Record<
text: TextExample,
textInput: TextInputExample,
toggleButton: ToggleButtonExample,
tooltipExample: TooltipExample,
touchableRipple: TouchableRippleExample,
theme: ThemeExample,
};
Expand Down
91 changes: 91 additions & 0 deletions example/src/Examples/TooltipExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import * as React from 'react';
import { Platform, StyleSheet } from 'react-native';

import type { StackNavigationProp } from '@react-navigation/stack';
import {
Appbar,
Banner,
FAB,
List,
ToggleButton,
Tooltip,
} from 'react-native-paper';

import ScreenWrapper from '../ScreenWrapper';

type Props = {
navigation: StackNavigationProp<{}>;
};

const MORE_ICON = Platform.OS === 'ios' ? 'dots-horizontal' : 'dots-vertical';

const TooltipExample = ({ navigation }: Props) => {
React.useLayoutEffect(() => {
navigation.setOptions({
header: () => (
<Appbar.Header>
<Tooltip title="Go back">
<Appbar.BackAction onPress={() => navigation.goBack()} />
</Tooltip>
<Appbar.Content title="Tooltips" />
<Tooltip title="Print ⌘ + P">
<Appbar.Action icon="printer" onPress={() => {}} />
</Tooltip>
<Tooltip title="Search">
<Appbar.Action icon="magnify" onPress={() => {}} />
</Tooltip>
<Tooltip title="More options">
<Appbar.Action icon={MORE_ICON} onPress={() => {}} />
</Tooltip>
</Appbar.Header>
),
});
});

const renderFAB = () => {
return (
<FAB size="medium" icon="plus" onPress={() => {}} style={[styles.fab]} />
);
};

return (
<>
<ScreenWrapper>
<Banner visible>
A tooltip is displayed upon tapping and holding a screen element or
component. Continuously display the tooltip as long as the user
long-presses the element.
</Banner>
<List.Section title="Toggle Buttons">
<ToggleButton.Row
value="bold"
style={styles.toggleButtonRow}
onValueChange={() => {}}
>
<ToggleButton icon="format-bold" value="bold" />
<Tooltip title="Align center">
<ToggleButton icon="format-align-center" value="align-center" />
</Tooltip>
</ToggleButton.Row>
</List.Section>
</ScreenWrapper>
<Tooltip title="Press Me">{renderFAB()}</Tooltip>
</>
);
};

TooltipExample.title = 'Tooltip';

export default TooltipExample;

const styles = StyleSheet.create({
fab: {
position: 'absolute',
margin: 16,
right: 0,
bottom: 0,
},
toggleButtonRow: {
paddingHorizontal: 16,
},
});
76 changes: 39 additions & 37 deletions src/components/Appbar/AppbarAction.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import * as React from 'react';
import type {
StyleProp,
TouchableWithoutFeedback,
ViewStyle,
} from 'react-native';
import type { StyleProp, ViewStyle, View } from 'react-native';

import color from 'color';

Expand Down Expand Up @@ -44,7 +40,7 @@ export type Props = React.ComponentPropsWithoutRef<typeof IconButton> & {
*/
isLeading?: boolean;
style?: StyleProp<ViewStyle>;
ref?: React.RefObject<TouchableWithoutFeedback>;
ref?: React.RefObject<View>;
};

/**
Expand Down Expand Up @@ -72,39 +68,45 @@ export type Props = React.ComponentPropsWithoutRef<typeof IconButton> & {
* export default MyComponent;
* ```
*/
const AppbarAction = ({
size = 24,
color: iconColor,
icon,
disabled,
onPress,
accessibilityLabel,
isLeading,
...rest
}: Props) => {
const theme = useInternalTheme();
const AppbarAction = React.forwardRef<View, Props>(
(
{
size = 24,
color: iconColor,
icon,
disabled,
onPress,
accessibilityLabel,
isLeading,
...rest
}: Props,
ref
) => {
const theme = useInternalTheme();

const actionIconColor = iconColor
? iconColor
: theme.isV3
? isLeading
? theme.colors.onSurface
: theme.colors.onSurfaceVariant
: color(black).alpha(0.54).rgb().string();
const actionIconColor = iconColor
? iconColor
: theme.isV3
? isLeading
? theme.colors.onSurface
: theme.colors.onSurfaceVariant
: color(black).alpha(0.54).rgb().string();

return (
<IconButton
size={size}
onPress={onPress}
iconColor={actionIconColor}
icon={icon}
disabled={disabled}
accessibilityLabel={accessibilityLabel}
animated
{...rest}
/>
);
};
return (
<IconButton
size={size}
onPress={onPress}
iconColor={actionIconColor}
icon={icon}
disabled={disabled}
accessibilityLabel={accessibilityLabel}
animated
ref={ref}
{...rest}
/>
);
}
);

AppbarAction.displayName = 'Appbar.Action';

Expand Down
20 changes: 12 additions & 8 deletions src/components/Appbar/AppbarBackAction.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import type { StyleProp, ViewStyle } from 'react-native';
import type { StyleProp, ViewStyle, View } from 'react-native';

import type { $Omit } from './../../types';
import AppbarAction from './AppbarAction';
Expand Down Expand Up @@ -30,6 +30,7 @@ export type Props = $Omit<
*/
onPress?: () => void;
style?: StyleProp<ViewStyle>;
ref?: React.RefObject<View>;
};

/**
Expand All @@ -54,13 +55,16 @@ export type Props = $Omit<
* export default MyComponent;
* ```
*/
const AppbarBackAction = ({ accessibilityLabel = 'Back', ...rest }: Props) => (
<AppbarAction
accessibilityLabel={accessibilityLabel}
{...rest}
icon={AppbarBackIcon}
isLeading
/>
const AppbarBackAction = React.forwardRef<View, Props>(
({ accessibilityLabel = 'Back', ...rest }: Props, ref) => (
<AppbarAction
accessibilityLabel={accessibilityLabel}
{...rest}
icon={AppbarBackIcon}
isLeading
ref={ref}
/>
)
);

AppbarBackAction.displayName = 'Appbar.BackAction';
Expand Down
3 changes: 2 additions & 1 deletion src/components/Appbar/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import color from 'color';
import overlay from '../../styles/overlay';
import { black, white } from '../../styles/themes/v2/colors';
import type { InternalTheme } from '../../types';
import Tooltip from '../Tooltip/Tooltip';
import AppbarAction from './AppbarAction';
import AppbarBackAction from './AppbarBackAction';
import AppbarContent from './AppbarContent';
Expand Down Expand Up @@ -91,7 +92,7 @@ export const renderAppbarContent = ({
.map((child, i) => {
if (
!React.isValidElement(child) ||
![AppbarContent, AppbarAction, AppbarBackAction].includes(
![AppbarContent, AppbarAction, AppbarBackAction, Tooltip].includes(
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
child.type
)
Expand Down
Loading

0 comments on commit bc2a1c4

Please sign in to comment.