Props
Accessibility
Ready
Localization
TapAreas with link role announce to assistive technologies that the link opens in a new tab when setting target to 'blank'. Localize the default label with DefaultLabelProvider. Learn more
Variants
Basic TapArea
import { Avatar, Box, TapArea, Text } from 'gestalt'; export default function TapAreaExample() { return ( <Box padding={8} height="100%" display="flex" alignItems="center" justifyContent="center" > <Box rounding={4} borderStyle="sm" width={170}> <TapArea rounding={4}> <Box alignItems="center" direction="column" display="flex" padding={3} > <Avatar name="Alberto" size="xl" src="https://i.ibb.co/NsK2w5y/Alberto.jpg" verified /> <Text weight="bold">Alberto's Profile</Text> </Box> </TapArea> </Box> </Box> ); }
TapArea with Link/Button
import { useState } from 'react'; import { Box, Image, Link, Mask, TapArea, Text } from 'gestalt'; export default function TapAreaExample() { const [touches, setTouches] = useState(0); return ( <Box padding={8} height="100%" display="flex" alignItems="center" justifyContent="center" > <Box width={200}> <TapArea onTap={() => setTouches(touches + 1)} rounding={2}> <Box color="selected" rounding={4} borderStyle="sm"> <Mask rounding={2}> <Image alt="Antelope Canyon" naturalHeight={1} naturalWidth={1} src="https://i.ibb.co/DwYrGy6/stock14.jpg" /> </Mask> <Box paddingY={2}> <Link href="https://www.pinterest.com/search/pins/?rs=ac&len=2&q=antelope%20canyon%20arizona&eq=Antelope%20Canyon" onClick={({ event }) => event.stopPropagation()} rounding="pill" target="blank" > <Text align="center" color="inverse"> Find More on Pinterest </Text> </Link> </Box> </Box> </TapArea> <Box paddingY={2}> <Text color="subtle" align="center"> Touched {touches} {touches === 1 ? 'time' : 'times'} </Text> </Box> </Box> </Box> ); }
If you have a Link
or Button
inside of TapArea, you can apply e.stopPropagation()
so the onTap
doesn't get triggered.
TapArea with link interaction can be paired with GlobalEventsHandlerProvider. See GlobalEventsHandlerProvider to learn more about link navigation.
Roles & compress behavior
import { useState } from 'react'; import { Box, Flex, Image, Label, Mask, Switch, TapArea, Text, Tooltip, } from 'gestalt'; export default function Example() { const [disabled, setDisabled] = useState(false); const [compressed, setCompressed] = useState('compress'); const [touches, setTouches] = useState(0); const [tabIndex, setTabIndex] = useState(false); return ( <Box padding={8} height="100%" display="flex" alignItems="center" justifyContent="center" > <Flex alignItems="start" direction="column" gap={{ column: 6, row: 0 }}> <Flex gap={6} wrap> <Tooltip text="Default TapArea"> <TapArea tapStyle={compressed} disabled={disabled} onTap={() => setTouches(touches + 1)} tabIndex={tabIndex ? -1 : 0} > <Box padding={3} column={12} borderStyle="lg" width={200}> <Mask rounding={2}> <Image alt="Antelope Canyon" naturalHeight={1} naturalWidth={1} src="https://i.ibb.co/DwYrGy6/stock14.jpg" /> </Mask> <Text align="center"> Touched {touches} {touches === 1 ? 'time' : 'times'} </Text> </Box> </TapArea> </Tooltip> <Tooltip text="Link TapArea"> <TapArea tapStyle={compressed} disabled={disabled} role="link" target="blank" href="https://www.pinterest.com" tabIndex={tabIndex ? -1 : 0} > <Box padding={3} column={12} borderStyle="lg" width={200}> <Mask rounding={2}> <Image alt="Antelope Canyon" naturalHeight={1} naturalWidth={1} src="https://i.ibb.co/DwYrGy6/stock14.jpg" /> </Mask> <Text align="center">Visit Pinterest.com</Text> </Box> </TapArea> </Tooltip> </Flex> <Flex gap={{ column: 0, row: 2 }}> <Switch onChange={() => setCompressed(compressed === 'compress' ? 'none' : 'compress') } id="compress-buttons" switched={compressed === 'compress'} /> <Box paddingX={2} flex="grow"> <Label htmlFor="compress-buttons"> <Text>Compress TapArea</Text> </Label> </Box> </Flex> <Flex gap={{ column: 0, row: 2 }}> <Switch onChange={() => setDisabled(!disabled)} id="disable-buttons" switched={disabled} /> <Box paddingX={2} flex="grow"> <Label htmlFor="disable-buttons"> <Text>Disable TapArea</Text> </Label> </Box> </Flex> <Flex gap={{ column: 0, row: 2 }}> <Switch onChange={() => setTabIndex(!tabIndex)} id="unreachable-buttons" switched={tabIndex} /> <Box paddingX={2} flex="grow"> <Label htmlFor="unreachable-buttons"> <Text>Remove from keyboard navigation with tabIndex</Text> </Label> </Box> </Flex> </Flex> </Box> ); }
Height & width
import { Box, Flex, TapArea, Text } from 'gestalt'; export default function Example() { return ( <Box padding={8} height="100%" display="flex" alignItems="center" justifyContent="center" > <Flex gap={6} wrap maxWidth={500} height={250}> <Box borderStyle="sm" margin={3} width="100%" height="100%"> <TapArea fullHeight> <Box height="100%" color="secondary"> <Text align="center">Full parent height</Text> </Box> </TapArea> </Box> <Box borderStyle="sm" margin={3} width="100%" height="100%"> <TapArea> <Box height="100%" color="secondary"> <Text align="center">Child height only</Text> </Box> </TapArea> </Box> </Flex> </Box> ); }
Inline usage
import { Box, Flex, TapArea, Text } from 'gestalt'; export default function Example() { return ( <Box padding={8} height="100%" display="flex" alignItems="center" justifyContent="center" > <Box color="warningBase" height={250} padding={3} maxWidth={500}> <Flex direction="column" gap={{ column: 6, row: 0 }}> <Flex.Item> <Text color="inverse" inline> Other content </Text> <Box borderStyle="sm" margin={3} column={6}> <TapArea> <Box height="100%" color="secondary"> <Text align="center">Default behavior (block)</Text> </Box> </TapArea> </Box> </Flex.Item> <Flex.Item> <Text color="inverse" inline> Other content </Text> <Box borderStyle="sm" display="inlineBlock" margin={3} column={6}> <TapArea> <Box height="100%" color="secondary"> <Text align="center">Inline behavior</Text> </Box> </TapArea> </Box> </Flex.Item> </Flex> </Box> </Box> ); }
While TapArea doesn't provide an inline
prop, this behavior can be achieved by wrapping with <Box display="inlineBlock">
.
Mouse cursor
mouseCursor="copy"
copy
mouseCursor="grab"
grab
mouseCursor="grabbing"
grabbing
mouseCursor="move"
move
mouseCursor="noDrop"
noDrop
mouseCursor="pointer"
pointer
mouseCursor="zoomIn"
zoomIn
mouseCursor="zoomOut"
zoomOut
Rounding
rounding={0}
0
rounding={1}
1
rounding={2}
2
rounding={3}
3
rounding={4}
4
rounding={5}
5
rounding={6}
6
rounding={7}
7
rounding={8}
8
rounding="circle"
circle
rounding="pill"
pill
Ref
import { useRef, useState } from 'react'; import { Box, Button, Flex, TapArea, Text } from 'gestalt'; export default function TapAreaRefExample() { const ref = useRef(null); const [focus, setFocus] = useState(0); return ( <Box padding={4} height="100%" display="flex" alignItems="center" justifyContent="center" > <Flex gap={{ column: 4, row: 2 }} direction="column" alignItems="center"> <Button text="Focus the TapArea" onClick={() => ref.current?.focus()} /> <TapArea ref={ref} rounding="pill" onFocus={() => setFocus(focus + 1)}> <Box borderStyle="sm" padding={2} rounding="pill"> <Text>TapArea is focused {focus} times</Text> </Box> </TapArea> </Flex> </Box> ); }
Accessibility: label, controls, expanded, & popup
import { Fragment, useRef, useState } from 'react'; import { Box, Flex, Image, Layer, Mask, Popover, TapArea, Text } from 'gestalt'; export default function MenuButtonExample() { const [selected, setSelected] = useState(false); const anchorRef = useRef(null); return ( <Box padding={8} height="100%" display="flex" alignItems="center" justifyContent="center" > <Fragment> <TapArea accessibilityLabel="Open the options menu" accessibilityControls="menu" accessibilityExpanded={selected} accessibilityHaspopup onTap={() => setSelected(!selected)} > <Box ref={anchorRef} borderStyle="sm" display="inlineBlock" alignItems="center" rounding={1} padding={2} > <Flex gap={{ column: 0, row: 2 }}> <Box height={50} width={50}> <Mask rounding={1}> <Image alt="Antelope Canyon" naturalHeight={1} naturalWidth={1} src="https://i.ibb.co/FY2MKr5/stock6.jpg" /> </Mask> </Box> <Text weight="bold" align="center"> Menu </Text> </Flex> </Box> </TapArea> {selected && ( <Layer> <Popover anchor={anchorRef.current} idealDirection="down" onDismiss={() => setSelected(false)} positionRelativeToAnchor={false} size="md" > <Box id="menu" direction="column" display="flex" padding={2}> <Box padding={2}> <Text weight="bold">Option 1</Text> </Box> <Box padding={2}> <Text weight="bold">Option 2</Text> </Box> </Box> </Popover> </Layer> )} </Fragment> </Box> ); }
External handlers
TapArea consumes external handlers from GlobalEventsHandlerProvider.
Handlers:
- onNavigation: executed when TapArea role="link" is clicked
See GlobalEventsHandlerProvider for more information.
Component quality checklist
Quality item | Status | Status description |
---|---|---|
Figma Library | Component is not currently available in Figma. | |
Responsive Web | Ready | Component responds to changing viewport sizes in web and mobile web. |
Related
GlobalEventsHandlerProvider
GlobalEventsHandlerProvider allows external link navigation control across all children components with link behavior.