diff --git a/src/components/FAB/Extended.tsx b/src/components/FAB/Extended.tsx index 5a35159f4f..3cc17107ba 100644 --- a/src/components/FAB/Extended.tsx +++ b/src/components/FAB/Extended.tsx @@ -68,6 +68,18 @@ export type Props = { * Function to execute on press. */ onPress?: (e: GestureResponderEvent) => void; + /** + * Function to execute on long press. + */ + onLongPress?: (e: GestureResponderEvent) => void; + /** + * Function to execute as soon as the touch is released. + */ + onPressOut?: (e: GestureResponderEvent) => void; + /** + * The number of milliseconds a user must touch the element before executing `onLongPress`. + */ + delayLongPress?: number; /** * Accessibility label. Falls back to `label` if unset. */ @@ -161,6 +173,9 @@ const Extended = ({ expanded, visible = true, onPress, + onLongPress, + onPressOut, + delayLongPress, 'aria-label': ariaLabel = label, 'aria-checked': ariaChecked, 'aria-selected': ariaSelected, @@ -266,6 +281,9 @@ const Extended = ({ size={size} visible={visible} onPress={onPress} + onLongPress={onLongPress} + onPressOut={onPressOut} + delayLongPress={delayLongPress} aria-label={ariaLabel} aria-checked={ariaChecked} aria-selected={ariaSelected} diff --git a/src/components/FAB/FAB.tsx b/src/components/FAB/FAB.tsx index b6e862aa08..5b92548c47 100644 --- a/src/components/FAB/FAB.tsx +++ b/src/components/FAB/FAB.tsx @@ -45,6 +45,18 @@ export type Props = { * Function to execute on press. */ onPress?: (e: GestureResponderEvent) => void; + /** + * Function to execute on long press. + */ + onLongPress?: (e: GestureResponderEvent) => void; + /** + * Function to execute as soon as the touch is released. + */ + onPressOut?: (e: GestureResponderEvent) => void; + /** + * The number of milliseconds a user must touch the element before executing `onLongPress`. + */ + delayLongPress?: number; /** * Accessibility label. Falls back to nothing if unset. */ @@ -122,6 +134,9 @@ const FAB = ({ size = 'default', visible = true, onPress, + onLongPress, + onPressOut, + delayLongPress, containerColor, contentColor, 'aria-label': ariaLabel, @@ -142,6 +157,9 @@ const FAB = ({ size={size} visible={visible} onPress={onPress} + onLongPress={onLongPress} + onPressOut={onPressOut} + delayLongPress={delayLongPress} containerColor={containerColor} contentColor={contentColor} aria-label={ariaLabel} diff --git a/src/components/FAB/Shell.tsx b/src/components/FAB/Shell.tsx index 26bd118885..7b4c1b8501 100644 --- a/src/components/FAB/Shell.tsx +++ b/src/components/FAB/Shell.tsx @@ -91,6 +91,18 @@ export type ShellProps = { * Function to execute on press. */ onPress?: (e: GestureResponderEvent) => void; + /** + * Function to execute on long press. + */ + onLongPress?: (e: GestureResponderEvent) => void; + /** + * Function to execute as soon as the touch is released. + */ + onPressOut?: (e: GestureResponderEvent) => void; + /** + * The number of milliseconds a user must touch the element before executing `onLongPress`. + */ + delayLongPress?: number; /** * Accessibility label. Falls back to `label` if unset. */ @@ -197,6 +209,9 @@ const Shell = ({ elevation = Tokens.stateElevation.enabled, visible = true, onPress, + onLongPress, + onPressOut, + delayLongPress, 'aria-label': ariaLabel = label, 'aria-checked': ariaChecked, 'aria-selected': ariaSelected, @@ -327,6 +342,9 @@ const Shell = ({ borderless background={background} onPress={onPress} + onLongPress={onLongPress} + onPressOut={onPressOut} + delayLongPress={delayLongPress} onFocus={onFocus} onBlur={onBlur} aria-label={ariaLabel} diff --git a/src/components/__tests__/FAB.test.tsx b/src/components/__tests__/FAB.test.tsx index eedcb3e0f3..b206c2fed0 100644 --- a/src/components/__tests__/FAB.test.tsx +++ b/src/components/__tests__/FAB.test.tsx @@ -1,8 +1,10 @@ import { expect, it, jest } from '@jest/globals'; import { fireEvent, userEvent } from '@testing-library/react-native'; +import PaperProvider from '../../core/PaperProvider'; import { render, screen } from '../../test-utils'; import FAB from '../FAB'; +import Tooltip from '../Tooltip/Tooltip'; it('renders FAB with default props', async () => { const tree = (await render()).toJSON(); @@ -101,3 +103,36 @@ it('forwards event object to onPress', async () => { }); expect(onPress).toHaveBeenCalledWith({ key: 'value' }); }); + +it('calls onLongPress and onPressOut when FAB is long pressed', async () => { + const user = userEvent.setup(); + const onLongPress = jest.fn(); + const onPressOut = jest.fn(); + await render( + + ); + await user.longPress(screen.getByRole('button', { name: 'Add item' }), { + duration: 400, + }); + expect(onLongPress).toHaveBeenCalledTimes(1); + expect(onPressOut).toHaveBeenCalledTimes(1); +}); + +it('shows Tooltip when FAB is long pressed', async () => { + const user = userEvent.setup(); + await render( + + + {}} /> + + + ); + await user.longPress(screen.getByRole('button', { name: 'Add item' })); + expect(screen.getByText('Press Me')).toBeOnTheScreen(); +});