styled()
Extend and build custom and optimizable components.
Create a new component by extending an existing one:
import { GetProps, Stack, styled } from 'tamagui' // or '@tamagui/core'export const Circle = styled(Stack, {name: 'Circle', // useful for debugging, and Component themesborderRadius: 100_000_000,})// helper to get props for any TamaguiComponentexport type CircleProps = GetProps<typeof Circle>
Usage:
<Circle x={10} y={10} backgroundColor="red" />
Note, tamagui
and @tamagui/core
both export many of the same helpers, like styled. If you are using tamagui
, you don't need to ever add @tamagui/core
to your package.json or import it and can instead import directly from tamagui
itself and don't need the following.
If using just core
but passing in React Native components, be sure to run setupReactNative
once first, typically near your entry file:
import { setupReactNative, styled } from 'tamagui' // or '@tamagui/core'import { Image } from 'react-native'// this allows tamagui to optimize for react-native components// it's not required. `tamagui` automatically sets this up, but core doesn'tsetupReactNative({ Image })const MyImage = styled(Image, {backgroundColor: 'red'})
This requirement allows core to be light and not depend on react-native for web-only use cases.
The tamagui
package applies this polyfill automatically as it uses React Native.
You can pass any prop that is supported by the component you are extending, even variants of the parent component. Tamagui will figure out the style props up-front, turn them into classNames, and then pass the non-style props down to the component as defaultProps.
Variants
Let's add some variants:
import { Stack, styled } from 'tamagui' // or '@tamagui/core'export const Circle = styled(Stack, {borderRadius: 100_000_000,variants: {pin: {top: {position: 'absolute',top: 0,},},centered: {true: {alignItems: 'center',justifyContent: 'center',},},size: {'...size': (size, { tokens }) => {return {width: tokens.size[size] ?? size,height: tokens.size[size] ?? size,}},},} as const,})
Please use as const
for the variants definition until Typescript gains the ability to infer
generics as const .
We can use these like so:
<Circle pin="top" centered size="$lg" />
To learn more about to use them and all the special types, see the docs on variants.
Compatibility
The styled()
function supports Tamagui views, React Native views, and any other React component that accepts a style
prop. If you wrap an external component that Tamagui doesn't recognize, Tamagui will assume it only supports the style
prop and not optimize it.
If it does accept className
, you can opt-in to className, CSS media queries, and compile-time optimization by adding acceptsClassName
:
import { styled } from 'tamagui' // or '@tamagui/core'import { SomeCustomComponent } from 'some-library'export const TamaguiCustomComponent = styled(SomeCustomComponent, {acceptsClassName: true,})