# Tamagui Complete Documentation
## components/accordion/1.0.0
---
title: Accordion
description: A vertically stacked set of interactive headings with content.
name: accordion
component: Accordion
package: accordion
---
```tsx hero template=Accordion
```
## Installation
Accordion is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/accordion
```
## Anatomy
Import all parts and piece them together.
```jsx
import { Accordion } from 'tamagui';
export default () => (
)
```
## API Reference
### Accordion
Contains all the parts of an accordion.
Determines whether one or multiple items can be opened at the same time.
),
},
{
name: 'value',
required: false,
type: 'string',
description: (
The controlled value of the item to expand when type is{' '}
"single". Must be used in conjunction with{' '}
onValueChange.
),
},
{
name: 'defaultValue',
required: false,
type: 'string',
description: (
The value of the item to expand when initially rendered and type is{' '}
"single". Use when you do not need to control the state of the
items.
),
},
{
name: 'onValueChange',
required: false,
type: '(value: string) => void',
typeSimple: 'function',
description: (
Event handler called when the expanded state of an item changes and{' '}
type is "single".
),
},
{
name: 'value',
required: false,
default: '[]',
type: 'string[]',
description: (
The controlled value of the item to expand when type is{' '}
"multiple". Must be used in conjunction with{' '}
onValueChange.
),
},
{
name: 'defaultValue',
required: false,
default: '[]',
type: 'string[]',
description: (
The value of the item to expand when initially rendered when type{' '}
is "multiple". Use when you do not need to control the state of the
items.
),
},
{
name: 'onValueChange',
required: false,
type: '(value: string[]) => void',
typeSimple: 'function',
description: (
Event handler called when the expanded state of an item changes and{' '}
type is "multiple".
),
},
{
name: 'collapsible',
required: false,
default: 'false',
type: 'boolean',
description: (
When type is "single", allows closing content when
clicking trigger for an open item.
),
},
{
name: 'disabled',
required: false,
type: 'boolean',
default: 'false',
description: (
When true, prevents the user from interacting with the accordion
and all its items.
),
},
{
name: 'dir',
required: false,
type: '"ltr" | "rtl"',
typeSimple: 'enum',
default: '"ltr"',
description:
'The reading direction of the accordion when applicable. If omitted, assumes LTR (left-to-right) reading mode.',
},
]}
/>
### Item
Contains all the parts of a collapsible section.
When true, prevents the user from interacting with the item.
),
},
{
name: 'value',
required: true,
type: 'string',
description: 'A unique value for the item.',
},
]}
/>
### Header
Wraps an `Accordion.Trigger`. Use the `asChild` prop to update it to the appropriate heading level for your page.
### Trigger
Toggles the collapsed state of its associated item. It should be nested inside of an `Accordion.Header`.
### Content
Contains the collapsible content for an item.
Used to force mounting when more control is needed. Useful when controlling
animation with React animation libraries.
),
},
]}
/>
## Examples
### Expanded by default
Use the `defaultValue` prop to define the open item by default.
```jsx line=1
……
```
### Allow collapsing all items
Use the `collapsible` prop to allow all items to close.
```jsx line=1
……
```
### Multiple items open at the same time
Set the `type` prop to `multiple` to enable opening multiple items at once.
```jsx line=1
……
```
## Accessibility
Adheres to the [Accordion WAI-ARIA design pattern](https://www.w3.org/TR/wai-aria-practices-1.1/#accordion).
## components/alert-dialog/1.0.0
---
title: AlertDialog
description: Show an alert prompt in a dialog
name: alertDialog
component: AlertDialog
package: alert-dialog
demoName: AlertDialog
---
```tsx hero template=AlertDialog
```
## Installation
Alert Dialog is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/alert-dialog
```
In order to use this component independently of `tamagui`, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { AlertDialog } from 'tamagui' // or '@tamagui/alert-dialog'
export default () => (
{/* ... */}
)
```
## API Reference
### AlertDialog
Contains every component for the AlertDialog. Shares all [Dialog Props](/docs/components/dialog#api), except modal which is on by default. Adds:
### AlertDialog.Trigger
Just [Tamagui Props](/docs/intro/props).
### AlertDialog.Portal
Renders AlertDialog into appropriate container. Beyond [Tamagui Props](/docs/intro/props), adds:
### AlertDialog.Content
Main container for AlertDialog content, this is where you should apply animations.
Beyond [Tamagui Props](/docs/intro/props), adds:
### AlertDialog.Overlay
Displays behind Content. Beyond [Tamagui Props](/docs/intro/props), adds:
### AlertDialog.Title
Required. Can wrap in VisuallyHidden to hide.
Defaults to H2, see [Headings](/docs/components/headings).
### AlertDialog.Description
Required. Can wrap in VisuallyHidden to hide.
Defaults to Paragraph, see [Paragraph](/docs/components/text).
### AlertDialog.Cancel
Closes the AlertDialog, accepts all YStack props. Recommended to use with your own component and `asChild`.
### PortalProvider
## Examples
### Inside native modals
If you're using native modals (maybe from react-navigation), you'll notice the Dialogs won't show up inside the modal. To get around this, you should wrap your screen inside `PortalProvider`, like so:
```tsx
import { PortalProvider } from 'tamagui'
// this component used in react-navigation/expo-router with `presentation: "modal"`
export function Page() {
return (
{/* rest of your page, including the Dialog... */}
)
}
```
## components/anchor/1.0.0
---
title: Anchor
description: Link to external websites.
name: html
component: Anchor
---
## Usage
The Anchor component provides a way to link to external websites. It extends [SizableText](/docs/components/text#sizable-text), adding the `href`, `target`, and `rel` attributes.
On native, it will use React Native `Linking.openURL`, on web it will render to an `a` element with `href` set appropriately.
## API Reference
### Anchor
Inherits [Tamagui props](/docs/intro/props) as well as:
## components/avatar/1.0.0
---
title: Avatar
description: Display aspect-fixed images with a fallback while loading
name: avatar
component: Avatar
package: avatar
demoName: Avatar
---
```tsx hero template=Avatar
```
## Installation
Avatar is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/avatar
```
## Usage
```tsx
import { Avatar } from 'tamagui'
export default () => (
)
```
## API Reference
### Avatar
Avatar extends [Square](/docs/components/shapes#shape-props), giving it all the [Tamagui standard props](/docs/intro/props) as well as `size` and `circular`.
### Avatar.Fallback
Avatar.Fallback extends [YStack](/docs/components/stacks), plus:
### Avatar.Image
Avatar.Image extends [Image](/docs/components/image).
## components/button/1.0.0-alpha
---
title: Button
description: A simple button component
name: button
component: Button
demoName: Button
---
# Button
A simple, sizable button.
```tsx hero template=Button
```
### Usage
```tsx
import { Button } from 'tamagui'
export default () =>
```
### Sizing
Sizing buttons provides a unique challenge especially for a compiler, because
you need to adjust many different properties - not just on the outer frame, but
on the text wrapped inside. Tamagui supports adjusting the padding, border
radius, font size and icons sizes all in one with the `size` prop.
```tsx
import { Button } from 'tamagui'
export default () =>
```
Given your theme defines a size `6`, the button will adjust all of the
properties appropriately. You can also pass a plain number to get an arbitrary
size.
### Icon Theming
You can pass icons as either elements or components. If passing components,
Tamagui will automatically pass the `size` and `color` prop to them based on
your theme.
### Button props
Button extends View, inheriting all the
[Tamagui standard props](/docs/intro/props), adding:
## components/button/1.0.0-beta.0
---
title: Button
description: A simple button component
name: button
component: Button
demoName: Button
---
# Button
A simple, sizable button.
```tsx hero template=Button
```
### Usage
```tsx
import { Button } from 'tamagui'
export default () =>
```
### Sizing
Sizing buttons provides a unique challenge especially for a compiler, because
you need to adjust many different properties - not just on the outer frame, but
on the text wrapped inside. Tamagui supports adjusting the padding, border
radius, font size and icons sizes all in one with the `size` prop.
```tsx
import { Button } from 'tamagui'
export default () =>
```
Given your theme defines a size `6`, the button will adjust all of the
properties appropriately. You can also pass a plain number to get an arbitrary
size.
### Icon Theming
You can pass icons as either elements or components. If passing components,
Tamagui will automatically pass the `size` and `color` prop to them based on
your theme.
### Button props
Button extends View, inheriting all the
[Tamagui standard props](/docs/intro/props), plus:
## components/button/1.0.0
---
title: Button
description: A simple button component
name: button
component: Button
package: button
demoName: Button
---
# Button
A simple, sizable button.
```tsx hero template=Button
```
### Usage
```tsx
import { Button } from 'tamagui'
export default () =>
```
### Sizing
Sizing buttons provides a unique challenge especially for a compiler, because you need to adjust many different properties - not just on the outer frame, but on the text wrapped inside. Tamagui supports adjusting the padding, border radius, font size and icons sizes all in one with the `size` prop.
```tsx
import { Button } from 'tamagui'
export default () =>
```
Given your theme defines a size `6`, the button will adjust all of the properties appropriately. You can also pass a plain number to get an arbitrary size.
### Icon Theming
You can pass icons as either elements or components. If passing components, Tamagui will automatically pass the `size` and `color` prop to them based on your theme.
You can [use the source of Button itself](https://github.com/tamagui/tamagui/blob/master/packages/button/src/Button.tsx) to see in more detail what variants you can override, and how we use this pattern internally to create our Button component.
### Customization (Advanced)
Button only supports a limited subset of text props directly, and doesn't accept `hoverStyle` text props. If you need more control, you can do a simple customization using some exported helpers.
Please note that this pattern is a bit antithetical to the multiple-components APIs that Tamagui generally prefers. In a future release we hope to fix this, but that change should be easy to migrate to.
```tsx
import { forwardRef } from 'react'
import {
ButtonFrame,
ButtonText,
GetProps,
ButtonProps as TamaguiButtonProps,
styled,
themeable,
useButton,
} from 'tamagui'
const CustomButtonFrame = styled(ButtonFrame, {
// ...
})
const CustomButtonText = styled(ButtonText, {
// ...
})
// to capture the custom variant types you define
type CustomButtonFrameProps = GetProps
type CustomButtonTextProps = GetProps
export type CustomButtonProps = TamaguiButtonProps &
CustomButtonFrameProps &
CustomButtonTextProps
export const Button = CustomButtonFrame.styleable((propsIn, ref) => {
const { props } = useButton(propsIn, { Text: CustomButtonText })
return
})
```
### Button props
Buttons extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
## components/button/1.28.0
---
title: Button
description: An incredibly flexible button.
name: button
component: Button
package: button
demoName: Button
---
```tsx hero template=Button
```
## Usage
When using the simple Button API, it's as simple as this:
```tsx
import { Button } from 'tamagui'
export default () =>
```
### Sizing
Sizing buttons provides a unique challenge especially for a compiler, because you need to adjust many different properties - not just on the outer frame, but on the text wrapped inside. Tamagui supports adjusting the padding, border radius, font size and icons sizes all in one with the `size` prop.
```tsx
import { Button } from 'tamagui'
export default () =>
```
Given your theme defines a size `6`, the button will adjust all of the properties appropriately. You can also pass a plain number to get an arbitrary size.
### Icon Theming
You can pass icons as either elements or components. If passing components, Tamagui will automatically pass the `size` and `color` prop to them based on your theme.
You can [use the source of Button itself](https://github.com/tamagui/tamagui/blob/main/code/ui/button/src/Button.tsx) to see in more detail what variants you can override, and how we use this pattern internally to create our Button component.
### Creating your own Button
Tamagui now has all the features necessary to make creating a custom Button easy enough that you may want to roll your own button. Learn how to do it with our dedicated guide, [How to Build a Button](/docs/guides/how-to-build-a-button).
The previous `useButton` API is deprecated and will be removed in a future version. It's
brittle and is easily replaced with the new compound component APIs as described in
the guide.
## API Reference
### Button
Buttons extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
## components/card/1.0.0
---
title: Card
description: Sizable, themeable cards with a flexible API.
name: card
component: Card
package: card
demoName: Card
---
```tsx hero template=Card
```
## Installation
Card is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/card
```
## Anatomy
```tsx
import { Card } from 'tamagui' // or '@tamagui/card'
export default () => (
{/* any other components */}
)
```
## API Reference
### Card
Frame of the card, extends [ThemeableStack props](/docs/components/stacks#themeablestack), adding:
### Card.Header
Extends [ThemeableStack](/docs/components/stacks#themeablestack), adding:
### Card.Footer
Extends [ThemeableStack](/docs/components/stacks#themeablestack), adding:
### Card.Background
Extends [YStack](/docs/components/stacks), set to `fullscreen` and zIndex below Header/Footer.
## components/checkbox/1.3.0
---
title: Checkbox
description: A simple checkbox component
name: checkbox
component: Checkbox
package: checkbox
demoName: Checkbox
---
# Checkbox
Use in forms to toggle between two states.
```tsx hero template=Checkbox
```
## Installation
Checkbox is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/checkbox
```
## Usage
```tsx
import { Check } from '@tamagui/lucide-icons'
import { Checkbox } from 'tamagui'
export default () => (
)
```
## API Reference
### Checkbox
`Checkbox` extend ThemeableStack inheriting all the [props](/docs/components/stacks#themeablestack), plus:
void',
description: 'Callback that fires when the checkbox state is changed.',
},
{
name: 'sizeAdjust',
type: 'number',
description: `Adjust the checkbox size scaling by this number.`,
},
{
name: 'scaleIcon',
type: 'number',
description: `Scale the indicator icon more than usual by this number.`,
},
{
name: 'scaleSize',
type: 'number',
default: '0.5',
description: `The Tamagui size tokens should map to the height of a button at any given step. This means you want somewhat smaller checkboxes typically.`,
},
{
name: 'unstyled',
required: false,
type: `boolean`,
description: `Removes all default Tamagui styles.`,
},
]}
/>
### Checkbox.Indicator
`Checkbox.Indicator` extend ThemeableStack inheriting all the [props](/docs/components/stacks#themeablestack), plus:
## components/checkbox/1.85.0
---
title: Checkbox
description: A simple checkbox component
name: checkbox
component: Checkbox
package: checkbox
demoName: Checkbox
---
# Checkbox
Toggle state in forms.StyledUnstyledHeadless
```tsx hero template=Checkbox
````
```tsx hero template=CheckboxUnstyled
````
```tsx hero template=CheckboxHeadless
````
## Installation
Checkbox is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/checkbox
````
Checkbox is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/checkbox
```
To use the headless switch, you want to import it from the
`@tamagui/switch-headless` package. This package has no dependency on
`@tamagui/core`, but still works off the react-native APIs.
This means can bring your own style library.
```bash
npm install @tamagui/switch-headless
```
## Usage
```tsx
import { Check } from '@tamagui/lucide-icons'
import { Checkbox } from 'tamagui'
export default () => (
)
```
Use the `createCheckbox` export to create a fully custom checkbox that still
uses the Tamagui styling system. This is similar to setting `unstyled`, but goes
a bit further. It doesn't add any types for `size` or `unstyled`, and it won't
automatically apply the `active` theme. If does pass the `checked` prop down as
indicated in the types of `createCheckbox`.
```tsx template=CheckboxUnstyled
```
Using the `useCheckbox` API, you can make your own Checkbox from scratch.
```tsx template=CheckboxHeadless
```
## API Reference
### Checkbox
`Checkbox` extend ThemeableStack inheriting all the
[props](/docs/components/stacks#themeablestack), plus:
void',
description: 'Callback that fires when the checkbox state is changed.',
},
{
name: 'sizeAdjust',
type: 'number',
description: `Adjust the checkbox size scaling by this number.`,
},
{
name: 'scaleIcon',
type: 'number',
description: `Scale the indicator icon more than usual by this number.`,
},
{
name: 'scaleSize',
type: 'number',
default: '0.5',
description: `The Tamagui size tokens should map to the height of a button at any given step. This means you want somewhat smaller checkboxes typically.`,
},
{
name: 'unstyled',
required: false,
type: `boolean`,
description: `Removes all default Tamagui styles.`,
},
]}
/>
### Checkbox.Indicator
`Checkbox.Indicator` extend ThemeableStack inheriting all the
[props](/docs/components/stacks#themeablestack), plus:
## components/checkbox/1.89.0
---
title: Checkbox
description: Toggle state in forms.
name: checkbox
component: Checkbox
package: checkbox
demoName: Checkbox
---
StyledUnstyledHeadless
```tsx hero template=Checkbox
````
```tsx hero template=CheckboxUnstyled
````
```tsx hero template=CheckboxHeadless
````
## Installation
Checkbox is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/checkbox
````
Checkbox is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/checkbox
```
To use the headless switch, you want to import it from the
`@tamagui/switch-headless` package. This package has no dependency on
`@tamagui/core`, but still works off the react-native APIs.
This means can bring your own style library.
```bash
npm install @tamagui/switch-headless
```
## Usage
```tsx
import { Check } from '@tamagui/lucide-icons'
import { Checkbox } from 'tamagui'
export default () => (
)
```
Use the `createCheckbox` export to create a fully custom checkbox that still
uses the Tamagui styling system. This is similar to setting `unstyled`, but goes
a bit further. It doesn't add any types for `size` or `unstyled`, and it won't
automatically apply the `active` theme. If does pass the `checked` prop down as
indicated in the types of `createCheckbox`.
```tsx template=CheckboxUnstyled
```
Using the `useCheckbox` API, you can make your own Checkbox from scratch.
```tsx template=CheckboxHeadless
```
## API Reference
### Checkbox
`Checkbox` extend ThemeableStack inheriting all the
[props](/docs/components/stacks#themeablestack), plus:
void',
description: 'Callback that fires when the checkbox state is changed.',
},
{
name: 'sizeAdjust',
type: 'number',
description: `Adjust the checkbox size scaling by this number.`,
},
{
name: 'scaleIcon',
type: 'number',
description: `Scale the indicator icon more than usual by this number.`,
},
{
name: 'scaleSize',
type: 'number',
default: '0.5',
description: `The Tamagui size tokens should map to the height of a button at any given step. This means you want somewhat smaller checkboxes typically.`,
},
{
name: 'unstyled',
required: false,
type: `boolean`,
description: `Removes all default Tamagui styles.`,
},
]}
/>
### Checkbox.Indicator
`Checkbox.Indicator` extend ThemeableStack inheriting all the
[props](/docs/components/stacks#themeablestack), plus:
## components/dialog/1.0.0
---
title: Dialog
description: Show a modal with configurable layout and accessible actions.
name: dialog
component: Dialog
package: dialog
demoName: Dialog
---
```tsx hero template=Dialog
```
Dialog does not work on native, instead you can Adapt it to a Sheet as shown in the demo
code above.
## Installation
Dialog is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/dialog
```
In order to use this component independently of `tamagui`, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Dialog } from 'tamagui' // or '@tamagui/dialog'
export default () => (
)
```
## API Reference
### Dialog
Contains every component for the dialog. Beyond [Tamagui Props](/docs/intro/props), adds:
void',
},
{
name: 'modal',
type: 'boolean',
default: 'true',
description: `Renders into root of app instead of inline`,
},
{
name: 'disableRemoveScroll',
type: 'boolean',
required: false,
description: `Used to disable the automatic removal of scrolling from the page when open.`,
},
]}
/>
### Dialog.Trigger
Just [Tamagui Props](/docs/intro/props).
### Dialog.Portal
Renders Dialog into appropriate container. Beyond [Tamagui Props](/docs/intro/props), adds:
### Dialog.Content
Main container for Dialog content, this is where you should apply animations.
Beyond [Tamagui Props](/docs/intro/props), adds:
### Dialog.Overlay
Displays behind Content. Beyond [Tamagui Props](/docs/intro/props), adds:
### Dialog.Title
Required. Can wrap in VisuallyHidden to hide.
Defaults to H2, see [Headings](/docs/components/headings).
### Dialog.Description
Required. Can wrap in VisuallyHidden to hide.
Defaults to Paragraph, see [Paragraph](/docs/components/text).
### Dialog.Close
Closes the Dialog, accepts the same props as YStack. Recommended to use with your own component and `asChild`.
Just [Tamagui Props](/docs/intro/props).
### Dialog.FocusScope
Provides access to the underlying FocusScope component used by Dialog for focus management. Can be used to control focus behavior from a parent component.
void',
description: `Event handler called when auto-focusing on mount. Can be prevented`,
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description: `Event handler called when auto-focusing on unmount. Can be prevented`,
},
]}
/>
### Dialog.Sheet
When used with `Adapt`, Dialog will render as a sheet when that breakpoint is active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Dialog.Sheet.Frame` to insert the contents given to `Dialog.Content`
```tsx
import { Dialog } from 'tamagui' // or '@tamagui/dialog'
export default () => (
)
```
Note that Dialog.Sheet currently doesn't preserve state of the contents when it
transitions between Sheet and Portal. In the future, we can do this on the web using
react-reparenting.
### PortalProvider
## Examples
### Inside native modals
If you're using native modals (maybe from react-navigation), you'll notice the Dialogs won't show up inside the modal. To get around this, you should wrap your screen inside `PortalProvider`, like so:
```tsx
import { PortalProvider } from 'tamagui'
// this component used in react-navigation/expo-router with `presentation: "modal"`
export function Page() {
return (
{/* rest of your page, including the Dialog... */}
)
}
```
## components/dialog/1.131.0
---
title: Dialog
description: Show a modal with configurable layout and accessible actions.
name: dialog
component: Dialog
package: dialog
demoName: Dialog
---
```tsx hero template=Dialog
```
Dialog is a great way to show content inside a new floating window above
content. Be sure to open the code example above for a copy-paste implementation.
## Installation
Dialog is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/dialog
```
If you aren't using `tamagui` and instead using the `@tamagui/dialog` package
separately, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Dialog } from 'tamagui' // or '@tamagui/dialog'
export default () => (
)
```
## Scoping
Dialog supports scoping which lets you mount one or more Dialog instances at the
root of your app, while having a deeply nested child Trigger or Content attach
to the proper parent Dialog instance.
In performance sensitive areas you may want to take advantage of this, it allows
you to only need to render the Dialog.Trigger inside the sensitive area as
Dialogs aren't the cheapest component - they has a lot of functionality.
Here's the basic anatomy of using `scope` and placing your Dialog higher up for
performance:
```tsx fileName=_layout.tsx
import { Dialog } from 'tamagui'
// in your root layout:
export default ({ children }) => (
)
```
```tsx fileName=UserProfile.tsx
export default () => (
)
```
Note that the `Trigger` scope ties to the `Dialog` scope.
## Dismissal Behavior
By default, dialogs can be dismissed by:
- Clicking outside the dialog content (on the overlay)
- Pressing the Escape key
- Clicking a Dialog.Close element
### Modal vs Non-Modal Dialogs
- **Modal dialogs** (`modal={true}`, which is the default):
- In v1, have `disableOutsidePointerEvents` set to `true` by default
- Still dismiss on outside click, but prevent interaction with elements behind the dialog
- Prevent right-click dismissal (right-clicks on the overlay are ignored)
- **Non-modal dialogs** (`modal={false}`):
- Allow interaction with elements behind the dialog
- Dismiss on any outside click
- Do not trap focus
### Preventing Outside Dismissal
To prevent a dialog from closing when clicking outside:
```tsx
{
event.preventDefault()
}}
>
{/* Dialog contents */}
```
## API Reference
### Dialog
Contains every component for the dialog. Beyond
[Tamagui Props](/docs/intro/props), adds:
void',
},
{
name: 'modal',
type: 'boolean',
default: 'true',
description: `Renders into root of app instead of inline`,
},
{
name: 'disableRemoveScroll',
type: 'boolean',
required: false,
description: `Used to disable the automatic removal of scrolling from the page when open.`,
},
]}
/>
### Dialog.Trigger
Just [Tamagui Props](/docs/intro/props).
### Dialog.Portal
Renders Dialog into appropriate container. Beyond
[Tamagui Props](/docs/intro/props), adds:
### Dialog.Content
Main container for Dialog content, this is where you should apply animations.
Beyond [Tamagui Props](/docs/intro/props), adds:
### Dialog.Overlay
Displays behind Content. Beyond [Tamagui Props](/docs/intro/props), adds:
### Dialog.Title
Required. Can wrap in VisuallyHidden to hide.
Defaults to H2, see [Headings](/docs/components/headings).
### Dialog.Description
Required. Can wrap in VisuallyHidden to hide.
Defaults to Paragraph, see [Paragraph](/docs/components/text).
### Dialog.Close
Closes the Dialog, accepts the same props as YStack. Recommended to use with
your own component and `asChild`.
Just [Tamagui Props](/docs/intro/props).
### Dialog.FocusScope
Provides access to the underlying FocusScope component used by Dialog for focus
management. Can be used to control focus behavior from a parent component.
void',
description: `Event handler called when auto-focusing on mount. Can be prevented`,
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description: `Event handler called when auto-focusing on unmount. Can be prevented`,
},
]}
/>
### Dialog.Sheet
When used with `Adapt`, Dialog will render as a sheet when that breakpoint is
active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Dialog.Sheet.Frame` to insert the contents
given to `Dialog.Content`
```tsx
import { Dialog } from 'tamagui' // or '@tamagui/dialog'
export default () => (
)
```
Note that Dialog.Sheet currently doesn't preserve state of the contents when
it transitions between Sheet and Portal. In the future, we can do this on the
web using react-reparenting.
### PortalProvider
## Examples
### Inside native modals
If you're using native modals (maybe from react-navigation), you'll notice the
Dialogs won't show up inside the modal. To get around this, you should wrap your
screen inside `PortalProvider`, like so:
```tsx
import { PortalProvider } from 'tamagui'
// this component used in react-navigation/expo-router with `presentation: "modal"`
export function Page() {
return (
{/* rest of your page, including the Dialog... */}
)
}
```
## components/focus-scope/1.128.0
---
title: FocusScope
description: Manage focus behavior within elements accessibly.
name: focus-scope
component: FocusScope
package: focus-scope
---
A utility component for managing keyboard focus within a container. Controls
focus trapping, auto-focus behavior, and focus cycling for accessible
interactive components.
Note that this is a web-only component, on native it is a no-op.
## Installation
FocusScope is already installed in `tamagui`, or you can install it
independently:
```bash
npm install @tamagui/focus-scope
```
## Usage
Wrap any content that needs focus management:
```tsx
import { Button, FocusScope, XStack } from 'tamagui'
export default () => (
)
```
## Focus Trapping
Use `trapped` to prevent focus from escaping the scope:
```tsx
import { Button, Dialog, FocusScope, XStack, YStack } from 'tamagui'
export default () => (
)
```
## Focus Looping
Enable `loop` to cycle focus between first and last elements:
```tsx
import { Button, FocusScope, XStack } from 'tamagui'
export default () => (
{/* Tab from "Last" goes to "First" */}
)
```
## Animation-Friendly Focusing
Use `focusOnIdle` to prevent reflows during animations:
```tsx
import { Button, FocusScope, XStack } from 'tamagui'
export default () => (
)
```
## Advanced Control with FocusScopeController
Use the controller pattern for managing focus from parent components:
```tsx
import { Button, FocusScope, XStack, YStack } from 'tamagui'
import { useState } from 'react'
export default () => {
const [trapped, setTrapped] = useState(false)
return (
)
}
```
## Function as Children
For advanced use cases, pass a function to get access to focus props:
```tsx
import { FocusScope, View } from 'tamagui'
export default () => (
{({ onKeyDown, tabIndex, ref }) => (
Custom focus container
)}
)
```
## API Reference
### FocusScope
void',
description:
'Event handler called when auto-focusing on mount. Can be prevented',
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description:
'Event handler called when auto-focusing on unmount. Can be prevented',
},
{
name: 'forceUnmount',
type: 'boolean',
default: 'false',
description:
'If unmount is animated, you want to force re-focus at start of animation not after',
},
{
name: 'children',
type: 'React.ReactNode | ((props: FocusProps) => React.ReactNode)',
description:
'Content to apply focus management to, or function that receives focus props',
},
]}
/>
### FocusScope.Controller
Provides context-based control over FocusScope behavior:
void',
description:
'Override onMountAutoFocus handler for all child FocusScope.Controller.Scope components',
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description:
'Override onUnmountAutoFocus handler for all child FocusScope.Controller.Scope components',
},
{
name: 'forceUnmount',
type: 'boolean',
description:
'Override forceUnmount behavior for all child FocusScope.Controller.Scope components',
},
]}
/>
The FocusScope component automatically inherits props from the nearest
FocusScope.Controller, with controller props taking precedence over direct
props.
## Usage in Other Components
Many Tamagui components export FocusScope for advanced focus control:
```tsx
import { Dialog, Popover, Select } from 'tamagui'
// Available on:
// And more...
```
## Accessibility
FocusScope follows accessibility best practices:
- Manages `tabindex` appropriately for focus flow
- Respects user's reduced motion preferences
- Maintains focus visible indicators
- Provides proper ARIA support when used with other components
- Handles edge cases like disabled elements and hidden content
FocusScope is primarily designed for web platforms. On React Native, it
renders children without focus management since native platforms handle focus
differently.
## Examples
### Modal Focus Management
```tsx
import { Button, Dialog, FocusScope, Input, XStack, YStack } from 'tamagui'
export default () => (
)
```
### Custom Focus Container
```tsx
import { Button, FocusScope, styled, XStack } from 'tamagui'
const FocusContainer = styled(XStack, {
borderWidth: 2,
borderColor: 'transparent',
borderRadius: '$4',
padding: '$4',
variants: {
focused: {
true: {
borderColor: '$blue10',
shadowColor: '$blue10',
shadowRadius: 10,
shadowOpacity: 0.3,
},
},
},
})
export default () => (
{({ onKeyDown, tabIndex, ref }) => (
)}
)
```
## components/form/1.3.0
---
title: Form
description: A simple form component for native and web.
name: form
component: Form
package: form
demoName: Form
---
```tsx hero template=Forms
```
## Installation
Form is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/form
```
## Anatomy
```tsx
import { Form } from 'tamagui' // or '@tamagui/form'
export default () => (
)
```
## API Reference
### Form
void',
required: true,
description: `Must use Form.Trigger to ensure onSubmit will callback.`,
},
]}
/>
### Form.Trigger
Wrap this around your submitting element to make the form submit. We recommend using `asChild` to a child element of your choosing for more control.
Accepts [Tamagui Props](/docs/intro/props).
## components/group/1.0.0
---
title: Group
description: Render horizontal or vertical groups easily.
name: group
component: Group
demoName: Group
---
# Group
Layout buttons and more with groups.
```tsx hero template=Group
```
## Usage
Instead of a generic `Group`, Tamagui prefers `XGroup` and `YGroup` for consistency with stacks.
By default, Groups will control the border radius of their children automatically - the first and last children will get their start/end radius set to match group radius. If it's a `YGroup`, it will adjust top/bottom radius. `XGroup` adjusts the left/right radius.
You can use Groups with or without `Group.Item`, depending on if you want to spacing and separators to be handled based on direct children, or on each Item rendered.
```tsx
import { Button, XGroup } from 'tamagui'
// usage with Item:
export default () => (
)
```
For a simpler use case and backwards compat, you can also use it without `Group.Item`, which will just apply borders and spacing based on direct children. Note that Group will detect if any `Group.Item` is inside it, and automatically switch modes. If no Item, it spaces direct children:
```tsx
import { Button, XGroup } from 'tamagui'
// usage without Item:
export default () => (
)
```
## Sizing
The `size` property will use your tokens to grab the appropriate radius for borderRadius values which it will pass to the first and last child as style props for borderRadius.
```tsx
import { Button, XGroup } from 'tamagui'
export default () => (
)
```
## Disabled
The `disabled` property will pass to children
## Group API
### Group
`XGroup` and `YGroup` extend [YStack](/docs/components/stacks), getting [Tamagui standard props](/docs/intro/props), plus:
### Group.Item
Wrap each of `XGroup` or `YGroup`'s children in one of these. It lets Tamagui apply the needed styles to them.
Accepts only a `children` prop.
## components/group/1.11.2
---
title: Group
description: Render horizontal or vertical groups easily.
name: group
component: Group
demoName: Group
---
# Group
Layout buttons and more with groups
```tsx hero template=Group
```
## Usage
You can use `Group` by itself with the `orientation` property determining the direction it assumes.
By default, Groups will control the border radius of their children automatically - the first and last children will get their start/end radius set to match group radius. If it's a `YGroup`, it will adjust top/bottom radius. `XGroup` adjusts the left/right radius.
You can use Groups with or without `Group.Item`, depending on if you want to spacing and separators to be handled based on direct children, or on each Item rendered.
```tsx
import { Button, XGroup } from 'tamagui'
// usage with Item:
export default () => (
)
```
For a simpler use case and backwards compat, you can also use it without `Group.Item`, which will just apply borders and spacing based on direct children. Note that Group will detect if any `Group.Item` is inside it, and automatically switch modes. If no Item, it spaces direct children:
```tsx
import { Button, XGroup } from 'tamagui'
// usage without Item:
export default () => (
)
```
## Sizing
The `size` property will use your tokens to grab the appropriate radius for borderRadius values which it will pass to the first and last child as style props for borderRadius.
```tsx
import { Button, XGroup } from 'tamagui'
export default () => (
)
```
## Disabled
The `disabled` property will pass to children
## API Reference
### Group
`Group`, `XGroup` and `YGroup` extend [YStack](/docs/components/stacks), getting [Tamagui standard props](/docs/intro/props), plus:
### Group.Item
Wrap each of `XGroup` or `YGroup`'s children in one of these. It lets Tamagui apply the needed styles to them.
Accepts only a `children` prop.
## components/group/1.56.1
---
title: Group
description: Render horizontal or vertical groups easily.
name: group
component: Group
demoName: Group
---
```tsx hero template=Group
```
## Installation
Group is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/group
```
## Usage
You can use `Group` by itself with the `orientation` property determining the direction it assumes.
By default, Groups will control the border radius of their children automatically - the first and last children will get their start/end radius set to match group radius. If it's a `YGroup`, it will adjust top/bottom radius. `XGroup` adjusts the left/right radius.
You can use Groups with or without `Group.Item`, depending on if you want to spacing and separators to be handled based on direct children, or on each Item rendered.
```tsx
import { Button, XGroup } from 'tamagui'
// usage with Item:
export default () => (
)
```
For a simpler use case and backwards compat, you can also use it without `Group.Item`, which will just apply borders and spacing based on direct children. Note that Group will detect if any `Group.Item` is inside it, and automatically switch modes. If no Item, it spaces direct children:
```tsx
import { Button, XGroup } from 'tamagui'
// usage without Item:
export default () => (
)
```
## Sizing
The `size` property will use your tokens to grab the appropriate radius for borderRadius values which it will pass to the first and last child as style props for borderRadius.
```tsx
import { Button, XGroup } from 'tamagui'
export default () => (
)
```
## Disabled
The `disabled` property will pass to children
## API Reference
### Group
`Group`, `XGroup` and `YGroup` extend [YStack](/docs/components/stacks), getting [Tamagui standard props](/docs/intro/props), plus:
### Group.Item
Wrap each of `XGroup` or `YGroup`'s children in one of these. It lets Tamagui apply the needed styles to them. It accepts the following props:
## components/group/1.6.0
---
title: Group
description: Render horizontal or vertical groups easily.
name: group
component: Group
demoName: Group
---
# Group
Layout buttons and more with groups.
```tsx hero template=Group
```
## Usage
You can use `Group` by itself with the `axis` property determining the direction it assumes.
By default, Groups will control the border radius of their children automatically - the first and last children will get their start/end radius set to match group radius. If it's a `YGroup`, it will adjust top/bottom radius. `XGroup` adjusts the left/right radius.
You can use Groups with or without `Group.Item`, depending on if you want to spacing and separators to be handled based on direct children, or on each Item rendered.
```tsx
import { Button, XGroup } from 'tamagui'
// usage with Item:
export default () => (
)
```
For a simpler use case and backwards compat, you can also use it without `Group.Item`, which will just apply borders and spacing based on direct children. Note that Group will detect if any `Group.Item` is inside it, and automatically switch modes. If no Item, it spaces direct children:
```tsx
import { Button, XGroup } from 'tamagui'
// usage without Item:
export default () => (
)
```
## Sizing
The `size` property will use your tokens to grab the appropriate radius for borderRadius values which it will pass to the first and last child as style props for borderRadius.
```tsx
import { Button, XGroup } from 'tamagui'
export default () => (
)
```
## Disabled
The `disabled` property will pass to children
## Group API
### Group
`Group`, `XGroup`and`YGroup` extend [YStack](/docs/components/stacks), getting [Tamagui standard props](/docs/intro/props), plus:
### Group.Item
Wrap each of `XGroup` or `YGroup`'s children in one of these. It lets Tamagui apply the needed styles to them.
Accepts only a `children` prop.
## components/group/1.7.0
---
title: Group
description: Render horizontal or vertical groups easily.
name: group
component: Group
demoName: Group
---
# Group
Layout buttons and more with groups.
```tsx hero template=Group
```
## Usage
You can use `Group` by itself with the `axis` property determining the direction it assumes.
By default, Groups will control the border radius of their children automatically - the first and last children will get their start/end radius set to match group radius. If it's a `YGroup`, it will adjust top/bottom radius. `XGroup` adjusts the left/right radius.
You can use Groups with or without `Group.Item`, depending on if you want to spacing and separators to be handled based on direct children, or on each Item rendered.
```tsx
import { Button, XGroup } from 'tamagui'
// usage with Item:
export default () => (
)
```
For a simpler use case and backwards compat, you can also use it without `Group.Item`, which will just apply borders and spacing based on direct children. Note that Group will detect if any `Group.Item` is inside it, and automatically switch modes. If no Item, it spaces direct children:
```tsx
import { Button, XGroup } from 'tamagui'
// usage without Item:
export default () => (
)
```
## Sizing
The `size` property will use your tokens to grab the appropriate radius for borderRadius values which it will pass to the first and last child as style props for borderRadius.
```tsx
import { Button, XGroup } from 'tamagui'
export default () => (
)
```
## Disabled
The `disabled` property will pass to children
## Group API
### Group
`Group`, `XGroup`and`YGroup` extend [YStack](/docs/components/stacks), getting [Tamagui standard props](/docs/intro/props), plus:
### Group.Item
Wrap each of `XGroup` or `YGroup`'s children in one of these. It lets Tamagui apply the needed styles to them.
Accepts only a `children` prop.
## components/headings/1.0.0
---
title: Headings
description: Heading components that mimic HTML equivalents
name: html
component: Headings
package: text
demoName: Headings
---
```tsx hero template=Headings
```
## Installation
Headings is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/text
```
```tsx
import { H1, H2, H3, H4, H5, H6, Heading } from 'tamagui'
export default () => (
<>
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Heading
>
)
```
The headings all extend from the base `Heading` component. Note, this is just our own theme for Inter headings, but you can change the styles for any font completely.
Tamagui expects for your [font.size](/docs/core/configuration#font-tokens) to have the keys 1-10 so headings work with your font tokens automatically.
## How it works
The `Heading` component is defined as follows:
```tsx
export const Heading = styled(Paragraph, {
tag: 'span',
name: 'Heading',
accessibilityRole: 'header',
fontFamily: '$heading',
size: '$8',
margin: 0,
})
```
Note that Heading, and H1-H6 all default to the `heading` font family that must be defined in your tamagui.config.ts.
Because [Paragraph](/docs/components/text#paragraph) extends [SizableText](/docs/components/text#sizabletext), you get automatic styles based on your font theme. Let's see how `SizableText` defines the size variant, roughly, which gives a good idea of how Tamagui works, and how you could create or change your own headings at a lower level.
```tsx
import { Text } from 'tamagui' // or '@tamagui/core'
const SizableText = styled(Text, {
name: 'SizableText',
fontFamily: '$body',
color: '$color',
variants: {
size: {
'...fontSize': (val, { font, props }) => {
const fontSize = font.size[val]
const lineHeight = font.lineHeight[val]
const fontWeight = font.weight[val]
const letterSpacing = font.letterSpacing[val]
const fontStyle = font.style?.[val]
const textTransform = font.transform?.[val]
return {
fontStyle,
textTransform,
fontWeight,
letterSpacing,
fontSize,
lineHeight,
}
},
},
},
defaultVariants: {
// note tamagui uses a generic "true" token that your sizes should set to be the same as the default on your scale
size: '$true',
},
})
```
## API Reference
### Heading
Headings extend [SizableText props](/docs/components/text#sizabletext) inheriting all the [Tamagui standard props](/docs/intro/props).
## components/html-elements/1.0.0
---
title: HTML Elements
description: Render semantic HTML with these elements.
name: html-elements
component: Layouts
---
To assist in creating accessible web apps, the following components are exported, all mapping directly to DOM elements of the lowercase names:
- `Section` (`section`)
- `Article` (`article`)
- `Main` (`main`)
- `Header` (`header`)
- `Aside` (`aside`)
- `Footer` (`footer`)
- `Nav` (`nav`)
## Installation
It's exported by `tamagui`, or:
```bash
npm install @tamagui/elements
```
## HTML element props
All HTML components extend View, inheriting all the [Tamagui standard props](/docs/intro/props).
## components/image/1.0.0
---
title: Image
description: React Native Web Image + Tamagui style props.
name: html
component: Image
package: image
demoName: Image
---
# Image
React Native Web Image + Tamagui style props.
```tsx hero template=Image
```
### Props
[Tamagui props](/docs/intro/props) + [React Native Web Image props](https://necolas.github.io/react-native-web/docs/image/).
## components/image/1.13.0
---
title: Image
description: React Native Web Image + Tamagui style props.
name: html
component: Image
package: image
demoName: Image
---
```tsx hero template=Image
```
## Installation
Image is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/image
```
## Usage
Note that you need to set `source` like so - the `width` and `height` properties apply as styles around the image, but the actual image needs `source.width` and `source.height` for React Native:
```tsx
export default () => (
)
```
## API Reference
### Image
[Tamagui props](/docs/intro/props) + [React Native Web Image props](https://necolas.github.io/react-native-web/docs/image/).
## components/inputs/1.0.0
---
title: Input & Textarea
name: inputs
description: Flexible form fields in styled and unstyled forms.
component: Input
demoName: Inputs
---
```tsx hero template=Inputs
```
Using the same base component TextInput, from [React Native](https://reactnative.dev/docs/textinput) or [React Native Web](https://necolas.github.io/react-native-web/docs/text-input/), Tamagui simply wraps these components to allow the full set of style props, as well as scaling all the styles up or down using the `size` property, much like Button.
## Installation
Input is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/input
```
## Input
A one-line input field:
```tsx
import { Input } from 'tamagui'
export const App = () => (
// Accepts size and style properties directly
)
```
## TextArea
For multi-line inputs:
```tsx
import { TextArea } from 'tamagui'
export const App = () => (
// Accepts size and style properties directly
)
```
## components/intro/1.0.0
---
title: Tamagui UI
---
Tamagui UI is a complete suite of components that render nicely on both React web and React native and come in both
styled and unstyled forms.
You can install each component separately, or all of them at once with:
```bash
yarn add tamagui
```
## Setup
The package `tamagui` is a superset of `@tamagui/core`, so if you've already installed core you can change all the references to `tamagui`.
You'll need to add a provider to the root of your app (unlike core, where that is optional), as it will set up the root portal for components like dialogs and popovers.
```tsx
import { createTamagui,TamaguiProvider, View } from 'tamagui'
import { defaultConfig } from '@tamagui/config/v4' // for quick config install this
const config = createTamagui(defaultConfig)
export default () => (
)
```
For a full guide configuration with `createTamagui`, check [the core configuration docs](/docs/core/configuration).
## components/label/1.0.0
---
title: Label
description: Label form elements with accessibility.
name: label
component: Label
package: label
demoName: Label
---
```tsx hero template=Label
```
## Installation
Label is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/label
```
## Usage
```tsx
import { Label } from 'tamagui'
export default () => (
<>
>
)
```
## Accessibility
Use with Input or other form elements to automatically get correct labelling by id and aria-labelledby. You can also use the provided `useLabelContext` hook to build your own controls.
## API Reference
### Label
Labels extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
## components/linear-gradient/1.0.0-alpha
---
title: Linear Gradient
description: Linear Gradient that works with Tamagui style props.
name: html
component: LinearGradient
demoName: LinearGradient
---
# Linear Gradient
Linear Gradient that works with Tamagui style props.In beta, currently doesn't resolve theme values for the colors property.
```tsx hero template=LinearGradient
```
### Usage
We've included `` so it can accept Tamagui style props, and to patch a bug with the current expo version with some Webpack configurations.
## components/linear-gradient/1.0.0
---
title: Linear Gradient
description: Linear gradients that works with Tamagui style props
name: html
component: LinearGradient
demoName: LinearGradient
---
```tsx hero template=LinearGradient
```
## Installation
LinearGradient is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/linear-gradient
```
To use this package you'll need to add `expo-linear-gradient` to your app. This works [with vanilla React Native](https://github.com/expo/expo/tree/sdk-47/packages/expo-linear-gradient) or Expo.
## Usage
Because LinearGradient requires a more complex to install native package, we've left it out of the `tamagui` export until Metro supports async import. Import it either separately or using the path `/linear-gradient`:
```tsx
import { LinearGradient } from '@tamagui/linear-gradient'
import { LinearGradient } from 'tamagui/linear-gradient'
```
LinearGradient is a YStack that accepts all Tamagui style props as well as theme colors, that places `expo-linear-gradient` inside it set to absoluteFill.
## API Reference
### LinearGradient
See the [expo docs](https://docs.expo.dev/versions/latest/sdk/linear-gradient/) for more complete information.
LinearGradient extends YStack, inheriting [Stack props](/docs/components/stacks) and therefore the [Tamagui standard props](/docs/intro/props), plus:
## components/list-item/1.0.0
---
title: ListItem
description: A component for showing columns of items.
name: list-item
component: ListItem
package: list-item
demoName: ListItem
---
```tsx hero template=ListItem
```
## Installation
ListItem is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/list-item
```
## Usage
```tsx
import { ListItem } from 'tamagui'
export default () => Lorem ipsum
```
## Sizing
Sizing listItems provides a unique challenge especially for a compiler, because you need to adjust many different properties - not just on the outer frame, but on the text wrapped inside. Tamagui supports adjusting the padding, border radius, font size and icons sizes all in one with the `size` prop.
```tsx
import { ListItem } from 'tamagui'
export default () => Lorem ipsum
```
Given your theme defines a size `6`, the listItem will adjust all of the properties appropriately. You can also pass a plain number to get an arbitrary size.
## Icon Theming
You can pass icons as either elements or components. If passing components, Tamagui will automatically pass the `size` and `color` prop to them based on your theme.
## Customization
ListItem only supports a limited subset of text props directly, and doesn't accept `hoverStyle` text props. If you need more control, you can do a simple customization:
```tsx
import { forwardRef } from 'react'
import {
ListItemFrame,
ListItemText,
ListItemTitle,
ListItemSubtitle,
styled,
themeable,
useListItem,
} from 'tamagui'
const CustomListItemFrame = styled(ListItemFrame, {
backgroundColor: 'orange', // or "$color", etc.
})
const CustomListItemTitle = styled(ListItemTitle, {
color: 'blue',
})
const CustomListItemSubtitle = styled(ListItemSubtitle, {
color: 'pink',
})
const CustomListItemText = styled(ListItemText, {
color: 'red',
})
export const ListItem = CustomListItemFrame.styleable((propsIn, ref) => {
const { props } = useListItem(propsIn, {
Title: CustomListItemTitle,
Text: CustomListItemText,
Subtitle: CustomListItemSubtitle,
})
return
})
```
There are 3 different components you can customize: `ListItemText`, `ListItemSubtitle` and `ListItemTitle`.
You can include whichever one you want to customize specifically.
If you only want to customize the the text pieces, you don't have to include `CustomListItemFrame`:
```tsx
// all the text changes from above, with a default ListItemFrame
export const ListItem = themeable(
forwardRef((propsIn, ref) => {
const { props } = useListItem(propsIn, {
Title: CustomListItemTitle,
Text: CustomListItemText,
Subtitle: CustomListItemSubtitle,
})
return
})
)
```
## API Reference
### ListItem
ListItems extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
### ListItem.Title
`ListItem.Title` extend `SizableText` inheriting all the [props](/docs/components/text#sizabletext).
### ListItem.Subtitle
`ListItem.Subtitle` extend `SizableText` inheriting all the [props](/docs/components/text#sizabletext).
### ListItem.Text
`ListItem.Text` extend `SizableText` inheriting all the [props](/docs/components/text#sizabletext). \*/}
## components/lucide-icons/1.0.0
---
title: Lucide Icons
description: Cross-platform compatible SVG based icons
demoName: LucideIcons
---
## Installation
```sh
yarn add react-native-svg @tamagui/lucide-icons
```
## Usage
Use them as regular React components
```tsx
import { Button } from 'tamagui'
import { Plus } from '@tamagui/lucide-icons'
// Button will automatically pass size/theme to icon
export default () => (
)
// or you can control it
export default () => (
}>
Hello world
)
```
They accept your tokens/theme keys for color and size.
## Credit
The great [Lucide Icons](https://lucide.dev/), a superset of the wonderful [Feather Icons](https://feathericons.com/).
## components/new-inputs/1.0.0
---
title: Input & Textarea
name: inputs
component: Input
demoName: Inputs
---
```tsx hero template=Inputs
```
Using Web APIs and relying on bare Tamagui with no `react-native-web` depedency on web compared to old Input component, support scaling all the styles up or down using the `size` property, and full `theme` support.
## Installation
LinearGradient is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/input
```
## Input
A one-line input field:
```tsx
import { Input } from 'tamagui'
export const App = () => (
// Accepts size and style properties directly
)
```
## TextArea
For multi-line inputs:
```tsx
import { TextArea } from 'tamagui'
export const App = () => (
// Accepts size and style properties directly
)
```
## components/popover/1.0.0
---
title: Popover
description: A simple popover component
name: popover
component: Popover
package: popover
demoName: Popover
---
# Popover
Show content with a trigger in a floating pane.
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is pressed, floating above the current content.
Support for native was contributed by a community member, but not guaranteed to work
until we get time to fully test and improve native interactions. We don't recommend the
Popover pattern for phone-sized devices either way, and instead you can adapt it to a
Sheet.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
## Anatomy
```tsx
import { Popover } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'modal',
type: 'boolean',
default: 'true',
required: false,
description: `Renders into root of app instead of inline.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'unstyled',
required: false,
type: `boolean`,
description: `Removes all default Tamagui styles.`,
},
]}
/>
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack, see [Stacks](/docs/components/stacks).
### Popover.Content
Renders as SizableStack which is just a YStack (see [Stacks](/docs/components/stacks)) with an extra `size` prop that accepts any `SizeTokens`.
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover attaches, use Anchor. When used, Anchor is where the Popover will attach, while Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the contents given to `Popover.Content`
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If used alongside `` and Sheet, Tamagui will automatically know to remove this ScrollView when swapping into the Sheet, as the Sheet must use it's own ScrollView that handles special logic for interactions with dragging.
## components/popover/1.110.0
---
title: Popover
description: Show content in a floating pane.
name: popover
component: Popover
package: popover
demoName: Popover
---
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is pressed, floating above the current content.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Popover, Adapt } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
{/* you can also use */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'keepChildrenMounted',
type: 'boolean',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'hoverable',
type: 'boolean | UseFloatingProps',
required: false,
description: `Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }`,
},
]}
/>
If using `modal={true}` (which is `true` by default), refer to the [PortalProvider installation](/ui/popover/1.83.0#portalprovider) for more information.
### Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element. In order for the Arrow to show you must have a Trigger element within your Popover. Arrows extend YStack, see [Stacks](/docs/components/stacks).
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack, see [Stacks](/docs/components/stacks).
### Popover.Content
Renders as SizableStack which is just a YStack (see [Stacks](/docs/components/stacks)) with an extra `size` prop that accepts any `SizeTokens`.
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover attaches, use Anchor. When used, Anchor is where the Popover will attach, while Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the contents given to `Popover.Content`
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If used alongside `` and Sheet, Tamagui will automatically know to remove this ScrollView when swapping into the Sheet, as the Sheet must use it's own ScrollView that handles special logic for interactions with dragging.
## components/popover/1.125.0
---
title: Popover
description: Show content with a trigger in a floating pane.
name: popover
component: Popover
package: popover
demoName: Popover
---
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is pressed, floating above the current content.
Note: Popovers are not a recommended pattern for mobile apps, and so aren't supported on native. Instead you can use Adapt and render them as a Sheet, or just conditionally render them. We landed support for them at one point, but we need the community to contribute tests in order to support them for mobile again.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Popover, Adapt } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
{/* you can also use */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'keepChildrenMounted',
type: 'boolean',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'hoverable',
type: 'boolean | UseFloatingProps',
required: false,
description: `Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }`,
},
{
name: 'resize',
type: 'SizeProps | boolean',
required: false,
description: `Will set maxWidth and maxHeight of Content to fit inside outer window when it won't fit, see floating-ui size().`,
},
]}
/>
For most of these properties, you'll want to reference the [floating-ui docs](https://floating-ui.com/docs/getting-started).
If using `modal={true}` (which is `true` by default), refer to the [PortalProvider installation](/ui/popover/1.83.0#portalprovider) for more information.
### Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element. In order for the Arrow to show you must have a Trigger element within your Popover. Arrows extend YStack, see [Stacks](/docs/components/stacks).
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack, see [Stacks](/docs/components/stacks).
### Popover.Content
Renders as SizableStack which is just a YStack (see [Stacks](/docs/components/stacks)) with an extra `size` prop that accepts any `SizeTokens`.
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover attaches, use Anchor. When used, Anchor is where the Popover will attach, while Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the contents given to `Popover.Content`
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If used alongside `` and Sheet, Tamagui will automatically know to remove this ScrollView when swapping into the Sheet, as the Sheet must use it's own ScrollView that handles special logic for interactions with dragging.
## components/popover/1.128.0
---
title: Popover
description: Show content with a trigger in a floating pane.
name: popover
component: Popover
package: popover
demoName: Popover
---
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is
pressed, floating above the current content.
Note: Popovers are not a recommended pattern for mobile apps, and so aren't
supported on native. Instead you can use Adapt and render them as a Sheet, or
just conditionally render them. We landed support for them at one point, but
we need the community to contribute tests in order to support them for mobile
again.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install
the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Popover, Adapt } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* Optional: Control focus behavior */}
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
{/* you can also use */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'keepChildrenMounted',
type: 'boolean',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'hoverable',
type: 'boolean | UseFloatingProps',
required: false,
description: `Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }`,
},
{
name: 'resize',
type: 'SizeProps | boolean',
required: false,
description: `Will set maxWidth and maxHeight of Content to fit inside outer window when it won't fit, see floating-ui size().`,
},
]}
/>
For most of these properties, you'll want to reference the
[floating-ui docs](https://floating-ui.com/docs/getting-started).
If using `modal={true}` (which is `true` by default), refer to the
[PortalProvider installation](/ui/popover/1.83.0#portalprovider) for more
information.
### Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element.
In order for the Arrow to show you must have a Trigger element within your
Popover. Arrows extend YStack, see [Stacks](/docs/components/stacks).
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack,
see [Stacks](/docs/components/stacks).
### Popover.Content
Extends PopperContent which extends SizableStack which extends a YStack (see
[Stacks](/docs/components/stacks)).
Also extends
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover
attaches, use Anchor. When used, Anchor is where the Popover will attach, while
Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is
active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the
contents given to `Popover.Content`
### Popover.FocusScope
Provides access to the underlying FocusScope component used by Popover for focus
management. Can be used to control focus behavior from a parent component.
void',
description: `Event handler called when auto-focusing on mount. Can be prevented`,
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description: `Event handler called when auto-focusing on unmount. Can be prevented`,
},
]}
/>
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If
used alongside `` and Sheet, Tamagui will automatically know to remove
this ScrollView when swapping into the Sheet, as the Sheet must use it's own
ScrollView that handles special logic for interactions with dragging.
## components/popover/1.129.0
---
title: Popover
description: Show content with a trigger in a floating pane.
name: popover
component: Popover
package: popover
demoName: Popover
---
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is
pressed, floating above the current content.
Note: Popovers are not a recommended pattern for mobile apps, and so aren't
supported on native. Instead you can use Adapt and render them as a Sheet, or
just conditionally render them. We landed support for them at one point, but
we need the community to contribute tests in order to support them for mobile
again.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install
the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Popover, Adapt } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* Optional: Control focus behavior */}
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
{/* you can also use */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'keepChildrenMounted',
type: 'boolean | "lazy"',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render. The "lazy" value will only initially mount the children after a React startTransition, and then keep them mounted thereafter.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'hoverable',
type: 'boolean | UseFloatingProps',
required: false,
description: `Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }`,
},
{
name: 'resize',
type: 'SizeProps | boolean',
required: false,
description: `Will set maxWidth and maxHeight of Content to fit inside outer window when it won't fit, see floating-ui size().`,
},
]}
/>
For most of these properties, you'll want to reference the
[floating-ui docs](https://floating-ui.com/docs/getting-started).
If using `modal={true}` (which is `true` by default), refer to the
[PortalProvider installation](/ui/popover/1.83.0#portalprovider) for more
information.
### Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element.
In order for the Arrow to show you must have a Trigger element within your
Popover. Arrows extend YStack, see [Stacks](/docs/components/stacks).
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack,
see [Stacks](/docs/components/stacks).
### Popover.Content
Extends PopperContent which extends SizableStack which extends a YStack (see
[Stacks](/docs/components/stacks)).
Also extends
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover
attaches, use Anchor. When used, Anchor is where the Popover will attach, while
Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is
active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the
contents given to `Popover.Content`
### Popover.FocusScope
Provides access to the underlying FocusScope component used by Popover for focus
management. Can be used to control focus behavior from a parent component.
void',
description: `Event handler called when auto-focusing on mount. Can be prevented`,
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description: `Event handler called when auto-focusing on unmount. Can be prevented`,
},
]}
/>
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If
used alongside `` and Sheet, Tamagui will automatically know to remove
this ScrollView when swapping into the Sheet, as the Sheet must use it's own
ScrollView that handles special logic for interactions with dragging.
## components/popover/1.131.0
---
title: Popover
description: Show content with a trigger in a floating pane.
name: popover
component: Popover
package: popover
demoName: Popover
---
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is
pressed, floating above the current content. Be sure to open the code example
above for a copy-paste implementation.
Note: Popovers are not a recommended pattern for mobile apps. Instead you can
use Adapt and render them as a Sheet, or just conditionally render them to
some native UI.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
### PortalProvider
_Only_ if you are not using `tamagui` and installing popover independently -
you'll need to set up the portal for it with the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Popover, Adapt } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* Optional: Control focus behavior */}
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
{/* you can also use */}
)
```
## Scoping
Popover support scoping which lets you mount one or more Popover instances at
the root of your app, while having a deeply nested child Trigger or Content
attach to the proper parent Popover instance.
In performance sensitive areas you may want to take advantage of this as it allows
you to only render the Popover.Trigger inside the sensitive area.
Popover isn't the cheapest component - it has a lot of functionality
inside of it like scroll management, focus management, and tracking position.
Here's the basic anatomy of using `scope` and placing your Popover higher up
for performance:
```tsx fileName=_layout.tsx
import { Popover } from 'tamagui'
// in your root layout:
export default ({ children }) => (
{/* ... */}
{/* the rest of of your app, note that it's inside of Popover */}
{children}
)
```
```tsx fileName=UserAvatar.tsx
export default () => (
)
```
Note that the `Trigger` scope ties to the `Popover` scope.
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'keepChildrenMounted',
type: 'boolean | "lazy"',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render. The "lazy" value will only initially mount the children after a React startTransition, and then keep them mounted thereafter.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'hoverable',
type: 'boolean | UseFloatingProps',
required: false,
description: `Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }`,
},
{
name: 'resize',
type: 'SizeProps | boolean',
required: false,
description: `Will set maxWidth and maxHeight of Content to fit inside outer window when it won't fit, see floating-ui size().`,
},
]}
/>
For most of these properties, you'll want to reference the
[floating-ui docs](https://floating-ui.com/docs/getting-started).
If using `modal={true}` (which is `true` by default), refer to the
[PortalProvider installation](/ui/popover/1.83.0#portalprovider) for more
information.
### Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element.
In order for the Arrow to show you must have a Trigger element within your
Popover. Arrows extend YStack, see [Stacks](/docs/components/stacks).
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack,
see [Stacks](/docs/components/stacks).
### Popover.Content
Extends PopperContent which extends SizableStack which extends a YStack (see
[Stacks](/docs/components/stacks)).
Also extends
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover
attaches, use Anchor. When used, Anchor is where the Popover will attach, while
Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is
active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the
contents given to `Popover.Content`
### Popover.FocusScope
Provides access to the underlying FocusScope component used by Popover for focus
management. Can be used to control focus behavior from a parent component.
void',
description: `Event handler called when auto-focusing on mount. Can be prevented`,
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description: `Event handler called when auto-focusing on unmount. Can be prevented`,
},
]}
/>
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If
used alongside `` and Sheet, Tamagui will automatically know to remove
this ScrollView when swapping into the Sheet, as the Sheet must use it's own
ScrollView that handles special logic for interactions with dragging.
## components/popover/1.43.0
---
title: Popover
description: A simple popover component
name: popover
component: Popover
package: popover
demoName: Popover
---
# Popover
Show content with a trigger in a floating pane
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is pressed, floating above the current content.
Support for native was contributed by a community member, but not guaranteed to work
until we get time to fully test. We don't recommend the Popover pattern for phone-sized
devices, and you can adapt it to a Sheet instead.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
## Anatomy
```tsx
import { Popover } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'modal',
type: 'boolean',
default: 'true',
required: false,
description: `Renders into root of app instead of inline.`,
},
{
name: 'keepChildrenMounted',
type: 'boolean',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
]}
/>
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack, see [Stacks](/docs/components/stacks).
### Popover.Content
Renders as SizableStack which is just a YStack (see [Stacks](/docs/components/stacks)) with an extra `size` prop that accepts any `SizeTokens`.
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover attaches, use Anchor. When used, Anchor is where the Popover will attach, while Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the contents given to `Popover.Content`
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If used alongside `` and Sheet, Tamagui will automatically know to remove this ScrollView when swapping into the Sheet, as the Sheet must use it's own ScrollView that handles special logic for interactions with dragging.
## components/popover/1.83.0
---
title: Popover
description: A simple popover component
name: popover
component: Popover
package: popover
demoName: Popover
---
# Popover
Show content with a trigger in a floating pane
```tsx hero template=Popover
```
Popovers are a great way to show content that's only visible when trigger is pressed, floating above the current content.
## Installation
Popover is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/popover
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Popover, Adapt } from 'tamagui' // or '@tamagui/popover'
export default () => (
{/* ScrollView is optional, can just put any contents inside if not scrollable */}
{/* ... */}
{/* ... */}
{/* optionally change to sheet when small screen */}
{/* you can also use */}
)
```
## API Reference
### Popover
Contains every component for the popover.
void',
required: false,
},
{
name: 'modal',
type: 'boolean',
default: 'true',
required: false,
description: `Renders into root of app instead of inline.`,
},
{
name: 'keepChildrenMounted',
type: 'boolean',
required: false,
description: `By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render.`,
},
{
name: 'stayInFrame',
type: 'ShiftProps | boolean',
required: false,
description: `Keeps the Popover inside the frame, see floating-ui shift().`,
},
{
name: 'allowFlip',
type: 'FlipProps | boolean',
required: false,
description: `Moves the Popover to other sides when space allows it, see floating-ui flip().`,
},
{
name: 'offset',
type: 'OffsetOptions',
required: false,
description: `Determines the distance the Popover appears from the target, see floating-ui offset().`,
},
{
name: 'hoverable',
type: 'boolean | UseFloatingProps',
required: false,
description: `Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }`,
},
]}
/>
If using `modal={true}` (which is `true` by default), refer to the [PortalProvider installation](/ui/popover/1.83.0#portalprovider) for more information.
### Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element. In order for the Arrow to show you must have a Trigger element within your Popover. Arrows extend YStack, see [Stacks](/docs/components/stacks).
### Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack, see [Stacks](/docs/components/stacks).
### Popover.Content
Renders as SizableStack which is just a YStack (see [Stacks](/docs/components/stacks)) with an extra `size` prop that accepts any `SizeTokens`.
Used to display the content of the popover.
### Popover.Anchor
Renders as YStack, see [Stacks](/docs/components/stacks).
When you want the Trigger to be in another location from where the Popover attaches, use Anchor. When used, Anchor is where the Popover will attach, while Trigger will open it.
### Popover.Sheet
When used with `Adapt`, Popover will render as a sheet when that breakpoint is active.
See [Sheet](/docs/components/sheet) for more props.
Must use `Adapt.Contents` inside the `Popover.Sheet.Frame` to insert the contents given to `Popover.Content`
### Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If used alongside `` and Sheet, Tamagui will automatically know to remove this ScrollView when swapping into the Sheet, as the Sheet must use it's own ScrollView that handles special logic for interactions with dragging.
## components/portal/1.0.0
---
title: Portal
description: Send items to other areas of the tree.
name: portal
component: Portal
package: portal
---
Portal is included in `tamagui` as it's used by a few components. For now, it's simply using [@gorhom/portal](https://github.com/gorhom/react-native-portal).
## components/progress/1.0.0
---
title: Progress
description: Display a bar to indicate percent completion.
name: progress
component: Progress
package: progress
demoName: Progress
---
# Progress
Show percent completion with a progress bar
```tsx hero template=Progress
```
Adheres to the{' '}
progressbar role requirements
,
]}
/>
## Installation
Progress is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/progress
```
## Usage
The `value` property controls the percent, but you can override it by adjusting the `x` property.
```tsx
import { Button, Progress } from 'tamagui'
export default () => (
)
```
## API Reference
### Progress
Progress extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props), plus:
### Progress.Indicator
`Progress.Indicator` extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props).
## components/progress/1.48.0
---
title: Progress
description: Show percent completion with a progress bar.
name: progress
component: Progress
package: progress
demoName: Progress
---
```tsx hero template=Progress
```
Adheres to the{' '}
progressbar role requirements
,
]}
/>
## Installation
Progress is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/progress
```
## Usage
The `value` property controls the percent, but you can override it by adjusting the `x` property.
```tsx
import { Button, Progress } from 'tamagui'
export default () => (
)
```
## API Reference
### Progress
Progress extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props), plus:
### Progress.Indicator
`Progress.Indicator` extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props).
## components/radio-group/1.2.0
---
title: RadioGroup
description: A group of radio buttons
name: radio-group
component: RadioGroup
package: radio-group
demoName: RadioGroup
---
# RadioGroup
Choose one option from a list in a form.
StyledUnstyledHeadless
```tsx hero template=RadioGroup
````
```tsx hero template=RadioGroupUnstyled
````
```tsx hero template=RadioGroupHeadless
````
## Installation
RadioGroup is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/radio-group
````
RadioGroup is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/radio-group
````
To use the headless radio group, you want to import it from the
`@tamagui/radio-headless` package. This package has no dependency on
`@tamagui/core`, but still works off the react-native APIs.
This means can bring your own style library.
```bash
npm install @tamagui/radio-headless
```
## Usage
```tsx
import { RadioGroup } from 'tamagui'
export default () => (
)
```
Use the `createRadioGroup` export to create a fully custom RadioGroup that still
uses the Tamagui styling system. This is similar to setting `unstyled`, but goes
a bit further. It doesn't add any types for `size` or `unstyled`, and it won't
automatically apply the `active` theme. If does pass the `checked` prop down as
indicated in the types of `createRadioGroup`.
```tsx template=RadioGroupUnstyled
```
Using the `useRadioGroup` and `useRadioGroupItem` API, you can make your own RadioGroup from scratch.
```tsx template=RadioGroupHeadless
```
## API Reference
### RadioGroup
RadioGroup extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'accentColor',
type: 'string',
description: 'Sets `accent-color` style when `native` prop is enabled',
},
]}
/>
### RadioGroup.Item
### RadioGroup.Indicator
RadioGroup.Indicator appears only when the parent Item is checked. it extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props) adding:
## API Reference
### RadioGroup
RadioGroup extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'accentColor',
type: 'string',
description: 'Sets `accent-color` style when `native` prop is enabled',
},
]}
/>
### RadioGroup.Item
### RadioGroup.Indicator
RadioGroup.Indicator appears only when the parent Item is checked. it extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props) adding:
## components/radio-group/1.3.0
---
title: RadioGroup
description: Use in a form to allow selecting one option from multiple.
name: radio-group
component: RadioGroup
package: radio-group
demoName: RadioGroup
---
```tsx hero template=RadioGroup
```
## Installation
RadioGroup is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/radio-group
```
## Usage
```tsx
import { RadioGroup } from 'tamagui'
export default () => (
)
```
## API Reference
### RadioGroup
RadioGroup extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'accentColor',
type: 'string',
description: 'Sets `accent-color` style when `native` prop is enabled',
},
]}
/>
### RadioGroup.Item
### RadioGroup.Indicator
RadioGroup.Indicator appears only when the parent Item is checked. it extends [ThemeableStack](/docs/components/stacks#themeablestack), getting [Tamagui standard props](/docs/intro/props) adding:
## components/scroll-view/1.0.0
---
title: ScrollView
description: React Native ScrollView with Tamagui props.
name: scrollView
component: ScrollView
package: scroll-view
demoName: ScrollView
---
```tsx hero template=ScrollView
```
## Installation
ScrollView is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/scroll-view
```
## Usage
```tsx
import { ScrollView, YStack, ListItem } from 'tamagui'
export default () => (
1234
)
```
## API Reference
### ScrollView
See [React Native ScrollView](https://reactnative.dev/docs/scrollview) and [Tamagui style props](https://tamagui.dev/docs/intro/props).
## components/select/1.0.0
---
title: Select
description: A simple select component
name: select
component: Select
package: select
demoName: Select
---
# Select
Show a menu of items users can select from one of.
```tsx hero template=Select
```
### Anatomy
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
Note that Select only works on Native using the Adapt component to adapt it to a Sheet.
See below for docs.
### API
#### <Select />
Contains every component for the select:
void',
description: `Callback on value change`,
},
{
name: 'open',
type: 'boolean',
description: `Controlled open value`,
},
{
name: 'defaultOpen',
type: 'boolean',
description: `Default open value`,
},
{
name: 'onOpenChange',
type: '(open: boolean) => void',
description: `Callback on open change`,
},
{
name: 'dir',
type: 'Direction',
description: `Direction of text display`,
},
{
name: 'name',
type: 'string',
description: `For use in forms`,
},
]}
/>
#### <Trigger />
Extends [ListItem](/docs/components/list-item) to give sizing, icons, and more.
#### <Value />
Extends [Paragraph](/docs/components/text), adding:
#### <Content />
Main container for Select content, used to contain the up/down arrows, no API beyond children.
#### <ScrollUpButton />
Inside Content first, displays when you can scroll up, stuck to the top.
Extends [YStack](/docs/components/stacks).
#### <ScrollDownButton />
Inside Content last, displays when you can scroll down, stuck to the bottom.
Extends [YStack](/docs/components/stacks).
#### <Viewport />
Extends [ThemeableStack](/docs/components/stacks#themeablestack). Contains scrollable content items as children.
#### <Group />
Extends [YStack](/docs/components/stacks). Use only when grouping together items, alongside a Label as the first child.
#### <Label />
Extends [ListItem](/docs/components/list-item). Used to label Groups.
#### <Item />
Extends [ListItem](/docs/components/list-item). Used to add selectable values ot the list. Must provide an index as React Native doesn't give any escape hatch for us to configure that automatically.
#### <ItemText />
Extends [Paragraph](/docs/components/text). Used inside Item to provide unselectable text that will show above once selected in the parent Select.
#### <Sheet />
When used alongside ``, Select will render as a sheet when that breakpoint is active.
This is the only way to render a Select on Native for now, as mobile apps tend to show Select very differently from web and Tamagui wants to present the right abstractions for each platform.
See [Sheet](/docs/components/sheet) for more props.
Must use `Select.SheetContents` inside the `Select.Sheet.Frame` to insert the contents given to `Select.Content`
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
## components/select/1.128.0
---
title: Select
description: Show a menu of items that users can select from.
name: select
component: Select
package: select
demoName: Select
---
```tsx hero template=Select
```
## Installation
Select is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/select
```
## Anatomy
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
Note that Select only works on Native using the Adapt component to adapt it to
a Sheet. See below for docs.
## API Reference
### Select
Contains every component for the select:
void',
description: `Callback on value change`,
},
{
name: 'open',
type: 'boolean',
description: `Controlled open value`,
},
{
name: 'defaultOpen',
type: 'boolean',
description: `Default open value`,
},
{
name: 'onOpenChange',
type: '(open: boolean) => void',
description: `Callback on open change`,
},
{
name: 'dir',
type: 'Direction',
description: `Direction of text display`,
},
{
name: 'name',
type: 'string',
description: `For use in forms`,
},
{
name: 'native',
type: 'NativeValue',
description: `If passed, will render a native component instead of the custom one. Currently only \`web\` is supported.`,
},
]}
/>
### Select.Trigger
Extends [ListItem](/docs/components/list-item) to give sizing, icons, and more.
#### Select.Value
Extends [Paragraph](/docs/components/text), adding:
#### SelectContent
Main container for Select content, used to contain the up/down arrows, no API beyond children.
#### Select.ScrollUpButton
Inside Content first, displays when you can scroll up, stuck to the top.
Extends [YStack](/docs/components/stacks).
### Select.ScrollDownButton
Inside Content last, displays when you can scroll down, stuck to the bottom.
Extends [YStack](/docs/components/stacks).
### Select.Viewport
Extends [ThemeableStack](/docs/components/stacks#themeablestack). Contains scrollable content items as children.
Make sure to not pass `height` prop as that is managed internally because of
UX reasons and having a fixed height will break that behaviour
### Select.Group
Extends [YStack](/docs/components/stacks). Use only when grouping together items, alongside a Label as the first child.
### Select.Label
Extends [ListItem](/docs/components/list-item). Used to label Groups.
### Select.Item
Extends [ListItem](/docs/components/list-item). Used to add selectable values ot the list. Must provide an index as React Native doesn't give any escape hatch for us to configure that automatically.
### Select.ItemText
Extends [Paragraph](/docs/components/text). Used inside Item to provide unselectable text that will show above once selected in the parent Select.
### Select.FocusScope
Provides access to the underlying FocusScope component used by Select for focus management. Can be used to control focus behavior from a parent component.
void',
description: `Event handler called when auto-focusing on mount. Can be prevented`,
},
{
name: 'onUnmountAutoFocus',
type: '(event: Event) => void',
description: `Event handler called when auto-focusing on unmount. Can be prevented`,
},
]}
/>
### Select.Sheet
When used alongside ``, Select will render as a sheet when that breakpoint is active.
This is the only way to render a Select on Native for now, as mobile apps tend to show Select very differently from web and Tamagui wants to present the right abstractions for each platform.
See [Sheet](/docs/components/sheet) for more props.
Must use `Select.Adapt.Contents` inside the `Select.Sheet.Frame` to insert the contents given to `Select.Content`
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
## components/select/1.19.0
---
title: Select
description: A simple select component
name: select
component: Select
package: select
demoName: Select
---
# Select
Show a menu of items users can select from one of
```tsx hero template=Select
```
## Anatomy
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
Note that Select only works on Native using the Adapt component to adapt it to a Sheet.
See below for docs.
## API Reference
### Select
Contains every component for the select:
void',
description: `Callback on value change`,
},
{
name: 'open',
type: 'boolean',
description: `Controlled open value`,
},
{
name: 'defaultOpen',
type: 'boolean',
description: `Default open value`,
},
{
name: 'onOpenChange',
type: '(open: boolean) => void',
description: `Callback on open change`,
},
{
name: 'dir',
type: 'Direction',
description: `Direction of text display`,
},
{
name: 'name',
type: 'string',
description: `For use in forms`,
},
{
name: 'native',
type: 'NativeValue',
description: `If passed, will render a native component instead of the custom one. Currently only \`web\` is supported.`,
},
]}
/>
### Select.Trigger
Extends [ListItem](/docs/components/list-item) to give sizing, icons, and more.
#### Select.Value
Extends [Paragraph](/docs/components/text), adding:
#### SelectContent
Main container for Select content, used to contain the up/down arrows, no API beyond children.
#### Select.ScrollUpButton
Inside Content first, displays when you can scroll up, stuck to the top.
Extends [YStack](/docs/components/stacks).
### Select.ScrollDownButton
Inside Content last, displays when you can scroll down, stuck to the bottom.
Extends [YStack](/docs/components/stacks).
### Select.Viewport
Extends [ThemeableStack](/docs/components/stacks#themeablestack). Contains scrollable content items as children.
### Select.Group
Extends [YStack](/docs/components/stacks). Use only when grouping together items, alongside a Label as the first child.
### Select.Label
Extends [ListItem](/docs/components/list-item). Used to label Groups.
### Select.Item
Extends [ListItem](/docs/components/list-item). Used to add selectable values ot the list. Must provide an index as React Native doesn't give any escape hatch for us to configure that automatically.
### Select.ItemText
Extends [Paragraph](/docs/components/text). Used inside Item to provide unselectable text that will show above once selected in the parent Select.
### Select.Sheet
When used alongside ``, Select will render as a sheet when that breakpoint is active.
This is the only way to render a Select on Native for now, as mobile apps tend to show Select very differently from web and Tamagui wants to present the right abstractions for each platform.
See [Sheet](/docs/components/sheet) for more props.
Must use `Select.SheetContents` inside the `Select.Sheet.Frame` to insert the contents given to `Select.Content`
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
## components/select/1.40.0
---
title: Select
description: Show a menu of items that users can select from.
name: select
component: Select
package: select
demoName: Select
---
```tsx hero template=Select
```
## Installation
Select is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/select
```
## Anatomy
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
Note that Select only works on Native using the Adapt component to adapt it to
a Sheet. See below for docs.
## API Reference
### Select
Contains every component for the select:
void',
description: `Callback on value change`,
},
{
name: 'open',
type: 'boolean',
description: `Controlled open value`,
},
{
name: 'defaultOpen',
type: 'boolean',
description: `Default open value`,
},
{
name: 'onOpenChange',
type: '(open: boolean) => void',
description: `Callback on open change`,
},
{
name: 'dir',
type: 'Direction',
description: `Direction of text display`,
},
{
name: 'name',
type: 'string',
description: `For use in forms`,
},
{
name: 'native',
type: 'NativeValue',
description: `If passed, will render a native component instead of the custom one. Currently only \`web\` is supported.`,
},
]}
/>
### Select.Trigger
Extends [ListItem](/docs/components/list-item) to give sizing, icons, and more.
#### Select.Value
Extends [Paragraph](/docs/components/text), adding:
#### SelectContent
Main container for Select content, used to contain the up/down arrows, no API beyond children.
#### Select.ScrollUpButton
Inside Content first, displays when you can scroll up, stuck to the top.
Extends [YStack](/docs/components/stacks).
### Select.ScrollDownButton
Inside Content last, displays when you can scroll down, stuck to the bottom.
Extends [YStack](/docs/components/stacks).
### Select.Viewport
Extends [ThemeableStack](/docs/components/stacks#themeablestack). Contains scrollable content items as children.
Make sure to not pass `height` prop as that is managed internally because of
UX reasons and having a fixed height will break that behaviour
### Select.Group
Extends [YStack](/docs/components/stacks). Use only when grouping together items, alongside a Label as the first child.
### Select.Label
Extends [ListItem](/docs/components/list-item). Used to label Groups.
### Select.Item
Extends [ListItem](/docs/components/list-item). Used to add selectable values ot the list. Must provide an index as React Native doesn't give any escape hatch for us to configure that automatically.
### Select.ItemText
Extends [Paragraph](/docs/components/text). Used inside Item to provide unselectable text that will show above once selected in the parent Select.
### Select.Sheet
When used alongside ``, Select will render as a sheet when that breakpoint is active.
This is the only way to render a Select on Native for now, as mobile apps tend to show Select very differently from web and Tamagui wants to present the right abstractions for each platform.
See [Sheet](/docs/components/sheet) for more props.
Must use `Select.Adapt.Contents` inside the `Select.Sheet.Frame` to insert the contents given to `Select.Content`
```tsx
import { Select } from 'tamagui' // or '@tamagui/select'
export default () => (
)
```
## components/separator/1.0.0
---
title: Separator
description: Create borders between components.
name: separator
component: Separator
package: separator
demoName: Separator
---
```tsx hero template=Separator
```
## Installation
Separator is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/separator
```
## Usage
Separator uses the `borderWidth` and `borderColor` attribute for its style, so be sure to override those when extending it.
```tsx
export default () => (
BlogDocsSource
)
```
## API Reference
### Separator props
Separators extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
## components/shapes/1.0.0
---
title: Shapes
description: Easy to use Square and Circle.
name: shapes
component: Square
package: shapes
demoName: Shapes
---
```tsx hero template=Shapes
```
## Installation
Shapes is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/shapes
```
## Usage
Tamagui supports sizing shapes using your `size` tokens, or plain numbers.
```tsx
import { Circle, Square } from 'tamagui'
export default () => (
<>
>
)
```
## API Reference
### Square
`Square` extends Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
### Circle
`Circle` extends [Square](#square), setting `circular` to `true`.
## components/sheet/1.0.0
---
title: Sheet
description: A simple sheet component
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
# Sheet
A bottom sheet that slides up.
```tsx hero template=Sheet
```
### Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
### API
#### <Sheet />
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: 'number[]',
default: `[80, 10]`,
description: `Array of numbers, 0-100 that corresponds to % of the screen it should take up. Should go from most visible to least visible in order. Use "open" prop for fully closed.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
]}
/>
#### <Overlay />
Displays behind Frame. Extends [YStack](/docs/components/stacks).
#### <Frame />
Contains the content. Extends [YStack](/docs/components/stacks).
#### <Handle />
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
#### <Scrollview />
Allows scrolling within Sheet. Extends [Scrollview](/docs/components/scroll-view).
### Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
## components/sheet/1.116.0
---
title: Sheet
description: A simple sheet component
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
# Sheet
A bottom sheet that slides up
```tsx hero template=Sheet
```
## Installation
Sheet is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/sheet
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
## Snap points
By default, snap points are treated as percentages.
```tsx
// 85% and 50%
```
The behavior of snap points can be changed by setting the `snapPointsMode` prop to any of these values:
- **percent** (default) - Snap points are percentages of the parent container or screen as numbers
- **constant** - Snap points are raw pixel values as numbers
- **fit** - The sheet is constrained to the content's natural height without the `snapPoints` prop
- **mixed** - Snap points can be either numbers (pixels), percentages as strings (ex: `"50%"`), or `"fit"` for fit behavior
Snap points should be ordered from largest to smallest (most visible to least visible). When using `mixed` mode with the `"fit"` as a snap point, it must be the first and largest snap point.
## Unstyled
Adding the `unstyled` prop to your Handle, Overlay or Frame will turn off the default styles allowing you to customize without having to override any of the built-in styling.
## Headless with `createSheet`
Using the `createSheet` export, you can create a fully custom sheet without using any of the default styles. This is similar to `unstyled`, but it lets you also control the `open` variant.
Here's an example:
```tsx
import { Stack, styled } from '@tamagui/core'
import { createSheet } from '@tamagui/sheet'
const Handle = styled(Stack, {
variants: {
open: {
true: {
opacity: 0.35,
},
false: {
opacity: 0.5,
},
},
} as const,
})
const Overlay = styled(Stack, {
variants: {
open: {
true: {
opacity: 1,
pointerEvents: 'auto',
},
false: {
opacity: 0,
pointerEvents: 'none',
},
},
} as const,
})
const Frame = styled(Stack, {
backgroundColor: '$background',
// can add open variant as well
})
export const Sheet = createSheet({
Frame,
Handle,
Overlay,
})
```
## Native support
Sheets now support rendering to a native iOS sheet, while still rendering any of your React Native content inside of them.
Because Metro doesn't support conditional imports and we don't want to make `tamagui` enforce installing native dependencies in order to get started, there's an install step.
As of the time of writing, we are using the new `3.0.x` branch which is in beta. Until ready, it does require a bit more setup.
```sh
yarn add react-native-ios-modal@3.0.0-5 react-native-ios-utilities@next @dominicstop/ts-event-emitter
```
Then, rebuild your native iOS app so it picks up the new native dependencies. This is done either through Expo or plain React Native.
Finally, set it up:
```tsx
import { Sheet, setupNativeSheet } from '@tamagui/sheet'
import * as NativeModal from 'react-native-ios-modal'
setupNativeSheet('ios', NativeModal)
// now you can use the `native` prop:
export default (
{/* ... the rest of your sheet */}
)
```
## API Reference
### Sheet
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: '(number | string)[] | undefined',
default: `[80]`,
description: `Array of values representing different sizes for the sheet to snap to. Not used in 'fit' mode. See docs above for usage information.`,
},
{
name: 'snapPointsMode',
type: '"percent" | "constant" | "fit" | "mixed"',
default: '"percent"',
description: `Alters the behavior of the 'snapPoints' prop. See docs above for usage information.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'native',
type: 'boolean | "ios"[]',
description: `(iOS only) Render to a native sheet, must install native dependency first.`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description:
'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.',
},
{
name: 'unmountChildrenWhenHidden',
type: 'boolean',
default: 'false',
description:
'Flag to enable unmounting the children after the exit animation has completed.',
},
]}
/>
If using `modal={true}` (which is `true` by default), refer to the [PortalProvider installation](/ui/sheet/1.59.0#portalprovider) for more information.
### Sheet.Overlay
Displays behind Frame. Extends [YStack](/docs/components/stacks).
### Sheet.Frame
Contains the content. Extends [YStack](/docs/components/stacks).
### Sheet.Handle
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
### Sheet.ScrollView
Allows scrolling within Sheet. Extends [ScrollView](/docs/components/scroll-view).
#### useSheet
Use this to control the sheet programatically.
void',
description: `Control the position of the sheet.`,
},
]}
/>
## Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
## components/sheet/1.123.18
---
title: Sheet
description: A bottom sheet that animates.
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
```tsx hero template=Sheet
```
## Installation
Sheet is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/sheet
```
### Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
### API
#### <Sheet />
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: 'number[]',
default: `[80, 10]`,
description: `Array of numbers, 0-100 that corresponds to % of the screen it should take up. Should go from most visible to least visible in order. Use "open" prop for fully closed.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'native',
type: 'boolean | "ios"[]',
description: `(iOS only) Render to a native sheet, must install native dependency first.`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description:
'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.',
},
]}
/>
#### <Overlay />
Displays behind Frame. Extends [YStack](/docs/components/stacks).
#### <Frame />
Contains the content. Extends [YStack](/docs/components/stacks).
#### <Handle />
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
#### <Scrollview />
Allows scrolling within Sheet. Extends [Scrollview](/docs/components/scroll-view).
### Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
### Native support
We've deprecated the `native` prop in favor of using Adapt.
## components/sheet/1.130.0
---
title: Sheet
description: A bottom sheet that animates.
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
```tsx hero template=Sheet
```
## Installation
Sheet is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/sheet
```
### Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
### API
#### <Sheet />
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: 'number[]',
default: `[80, 10]`,
description: `Array of numbers, 0-100 that corresponds to % of the screen it should take up. Should go from most visible to least visible in order. Use "open" prop for fully closed.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'native',
type: 'boolean | "ios"[]',
description: `(iOS only) Render to a native sheet, must install native dependency first.`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description:
'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.',
},
{
name: 'preferAdaptParentOpenState',
type: 'boolean',
default: 'false',
description: `By default Sheet will prefer the open prop over a parent component that is controlling it via Adapt. In general if you want to Adapt to a sheet, you'd leave the open prop undefined. If you'd like to have the parent override the prop you've set manually on Sheet, set this to true.`,
},
]}
/>
#### <Overlay />
Displays behind Frame. Extends [YStack](/docs/components/stacks).
#### <Frame />
Contains the content. Extends [YStack](/docs/components/stacks).
#### <Handle />
Shows a handle above the frame by default, on tap it will cycle between
`snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
#### <Scrollview />
Allows scrolling within Sheet. Extends
[Scrollview](/docs/components/scroll-view).
### Notes
For Android you need to manually re-propagate any context when using `modal`.
This is because React Native doesn't support portals yet.
### Native support
We've deprecated the `native` prop in favor of using Adapt.
## components/sheet/1.21.0
---
title: Sheet
description: A simple sheet component
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
# Sheet
A bottom sheet that slides up
```tsx hero template=Sheet
```
### Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
### API
#### <Sheet />
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: 'number[]',
default: `[80, 10]`,
description: `Array of numbers, 0-100 that corresponds to % of the screen it should take up. Should go from most visible to least visible in order. Use "open" prop for fully closed.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'native',
type: 'boolean | "ios"[]',
description: `(iOS only) Render to a native sheet, must install native dependency first.`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description:
'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.',
},
]}
/>
#### <Overlay />
Displays behind Frame. Extends [YStack](/docs/components/stacks).
#### <Frame />
Contains the content. Extends [YStack](/docs/components/stacks).
#### <Handle />
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
#### <Scrollview />
Allows scrolling within Sheet. Extends [Scrollview](/docs/components/scroll-view).
### Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
## components/sheet/1.27.0
---
title: Sheet
description: A simple sheet component
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
# Sheet
A bottom sheet that slides up
```tsx hero template=Sheet
```
## Installation
Sheet is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/sheet
```
## Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
## Unstyled
Adding the `unstyled` prop to your Handle, Overlay or Frame will turn off the default styles allowing you to customize without having to override any of the built-in styling.
## Headless with `createSheet`
Using the `createSheet` export, you can create a fully custom sheet without using any of the default styles. This is similar to `unstyled`, but it lets you also control the `open` variant.
Here's an example:
```tsx
import { Stack, styled } from '@tamagui/core'
import { createSheet } from '@tamagui/sheet'
const Handle = styled(Stack, {
variants: {
open: {
true: {
opacity: 0.35,
},
false: {
opacity: 0.5,
},
},
} as const,
})
const Overlay = styled(Stack, {
variants: {
open: {
true: {
opacity: 1,
pointerEvents: 'auto',
},
false: {
opacity: 0,
pointerEvents: 'none',
},
},
} as const,
})
const Frame = styled(Stack, {
backgroundColor: '$background',
// can add open variant as well
})
export const Sheet = createSheet({
Frame,
Handle,
Overlay,
})
```
## Native support
Sheets now support rendering to a native iOS sheet, while still rendering any of your React Native content inside of them.
Because Metro doesn't support conditional imports and we don't want to make `tamagui` enforce installing native dependencies in order to get started, there's an install step:
```sh
yarn add react-native-ios-modal
pod install
# rebuild your app (expo ios, or use react-native cli)
```
And set it up as follows:
```tsx
import { Sheet, setupNativeSheet } from '@tamagui/sheet'
import { ModalView } from 'react-native-ios-modal'
setupNativeSheet('ios', ModalView)
export default (
{/* The rest of your sheet views, see Anatomy, example and props API */}
)
```
## API Reference
### Sheet
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: 'number[]',
default: `[80, 10]`,
description: `Array of numbers, 0-100 that corresponds to % of the screen it should take up. Should go from most visible to least visible in order. Use "open" prop for fully closed.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'native',
type: 'boolean | "ios"[]',
description: `(iOS only) Render to a native sheet, must install native dependency first.`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description:
'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.',
},
]}
/>
### Sheet.Overlay
Displays behind Frame. Extends [YStack](/docs/components/stacks).
### Sheet.Frame
Contains the content. Extends [YStack](/docs/components/stacks).
### Sheet.Handle
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
### Sheet.ScrollView
Allows scrolling within Sheet. Extends [Scrollview](/docs/components/scroll-view).
#### useSheet
Use this to control the sheet programatically.
void',
description: `Control the position of the sheet.`,
},
]}
/>
## Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
## components/sheet/1.59.0
---
title: Sheet
description: A simple sheet component
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
# Sheet
A bottom sheet that slides up
```tsx hero template=Sheet
```
## Installation
Sheet is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/sheet
```
### PortalProvider
When rendering into root of app instead of inline, you'll first need to install the `@tamagui/portal` package:
```bash
npm install @tamagui/portal
```
Then add `PortalProvider` to the root of your app:
```tsx fileName="App.tsx"
import { PortalProvider } from '@tamagui/portal'
import YourApp from './components/YourApp'
function App() {
return (
)
}
export default App
```
## Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
## Snap points
By default, snap points are treated as percentages.
```tsx
// 85% and 50%
```
The behavior of snap points can be changed by setting the `snapPointsMode` prop to any of these values:
- **percent** (default) - Snap points are percentages of the parent container or screen as numbers
- **constant** - Snap points are raw pixel values as numbers
- **fit** - The sheet is constrained to the content's natural height without the `snapPoints` prop
- **mixed** - Snap points can be either numbers (pixels), percentages as strings (ex: `"50%"`), or `"fit"` for fit behavior
Snap points should be ordered from largest to smallest (most visible to least visible). When using `mixed` mode with the `"fit"` as a snap point, it must be the first and largest snap point.
## Unstyled
Adding the `unstyled` prop to your Handle, Overlay or Frame will turn off the default styles allowing you to customize without having to override any of the built-in styling.
## Headless with `createSheet`
Using the `createSheet` export, you can create a fully custom sheet without using any of the default styles. This is similar to `unstyled`, but it lets you also control the `open` variant.
Here's an example:
```tsx
import { Stack, styled } from '@tamagui/core'
import { createSheet } from '@tamagui/sheet'
const Handle = styled(Stack, {
variants: {
open: {
true: {
opacity: 0.35,
},
false: {
opacity: 0.5,
},
},
} as const,
})
const Overlay = styled(Stack, {
variants: {
open: {
true: {
opacity: 1,
pointerEvents: 'auto',
},
false: {
opacity: 0,
pointerEvents: 'none',
},
},
} as const,
})
const Frame = styled(Stack, {
backgroundColor: '$background',
// can add open variant as well
})
export const Sheet = createSheet({
Frame,
Handle,
Overlay,
})
```
## Native support
Sheets now support rendering to a native iOS sheet, while still rendering any of your React Native content inside of them.
Because Metro doesn't support conditional imports and we don't want to make `tamagui` enforce installing native dependencies in order to get started, there's an install step:
```sh
yarn add react-native-ios-modal
pod install
# rebuild your app (expo ios, or use react-native cli)
```
And set it up as follows:
```tsx
import { Sheet, setupNativeSheet } from '@tamagui/sheet'
import { ModalView } from 'react-native-ios-modal'
setupNativeSheet('ios', ModalView)
export default (
{/* The rest of your sheet views, see Anatomy, example and props API */}
)
```
## API Reference
### Sheet
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: '(number | string)[] | undefined',
default: `[80]`,
description: `Array of values representing different sizes for the sheet to snap to. Not used in 'fit' mode. See docs above for usage information.`,
},
{
name: 'snapPointsMode',
type: '"percent" | "constant" | "fit" | "mixed"',
default: '"percent"',
description: `Alters the behavior of the 'snapPoints' prop. See docs above for usage information.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'native',
type: 'boolean | "ios"[]',
description: `(iOS only) Render to a native sheet, must install native dependency first.`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description:
'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.',
},
{
name: 'unmountChildrenWhenHidden',
type: 'boolean',
default: 'false',
description:
'Flag to enable unmounting the children after the exit animation has completed.',
},
]}
/>
If using `modal={true}` (which is `true` by default), refer to the [PortalProvider installation](/ui/sheet/1.59.0#portalprovider) for more information.
### Sheet.Overlay
Displays behind Frame. Extends [YStack](/docs/components/stacks).
### Sheet.Frame
Contains the content. Extends [YStack](/docs/components/stacks).
### Sheet.Handle
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
### Sheet.ScrollView
Allows scrolling within Sheet. Extends [ScrollView](/docs/components/scroll-view).
#### useSheet
Use this to control the sheet programatically.
void',
description: `Control the position of the sheet.`,
},
]}
/>
## Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
## components/sheet/1.9.18
---
title: Sheet
description: A simple sheet component
name: sheet
component: Sheet
package: sheet
demoName: Sheet
---
# Sheet
A bottom sheet that slides up.
```tsx hero template=Sheet
```
### Anatomy
```tsx
import { Sheet } from 'tamagui' // or '@tamagui/sheet'
export default () => (
{/* ...inner contents */}
)
```
### API
#### <Sheet />
Contains every component for the sheet.
void',
description: `Called on change open, controlled or uncontrolled.`,
},
{
name: 'position',
type: 'number',
description: `Controlled position, set to an index of snapPoints.`,
},
{
name: 'defaultPosition',
type: 'number',
description: `Uncontrolled default position on mount.`,
},
{
name: 'snapPoints',
type: 'number[]',
default: `[80, 10]`,
description: `Array of numbers, 0-100 that corresponds to % of the screen it should take up. Should go from most visible to least visible in order. Use "open" prop for fully closed.`,
},
{
name: 'onPositionChange',
type: '(position: number) => void',
description: `Called on change position, controlled or uncontrolled.`,
},
{
name: 'dismissOnOverlayPress',
type: 'boolean',
default: 'true',
description: `Controls tapping on the overlay to close, defaults to true.`,
},
{
name: 'animationConfig',
type: 'Animated.SpringAnimationConfig',
default: 'true',
description: `Customize the spring used, passed to react-native Animated.spring().`,
},
{
name: 'disableDrag',
type: 'boolean',
description: `Disables all touch events to drag the sheet.`,
},
{
name: 'modal',
type: 'boolean',
description: `Renders sheet into the root of your app instead of inline.`,
},
{
name: 'dismissOnSnapToBottom',
type: 'boolean',
description: `Adds a snap point to the end of your snap points set to "0", that when snapped to will set open to false (uncontrolled) and call onOpenChange with false (controlled).`,
},
{
name: 'forceRemoveScrollEnabled',
type: 'boolean',
default: 'false',
description: `By default. Tamagui uses react-remove-scroll to prevent anything outside the sheet scrolling. This can cause some issues so you can override the behavior with this prop (either true or false).`,
},
{
name: 'portalProps',
type: 'Object',
description: `YStack props that can be passed to the Portal that sheet uses when in modal mode.`,
},
{
name: 'moveOnKeyboardChange',
type: 'boolean',
default: 'false',
description: 'Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible.'
}
]}
/>
#### <Overlay />
Displays behind Frame. Extends [YStack](/docs/components/stacks).
#### <Frame />
Contains the content. Extends [YStack](/docs/components/stacks).
#### <Handle />
Shows a handle above the frame by default, on tap it will cycle between `snapPoints` but this can be overridden with `onPress`.
Extends [XStack](/docs/components/stacks).
#### <Scrollview />
Allows scrolling within Sheet. Extends [Scrollview](/docs/components/scroll-view).
### Notes
For Android you need to manually re-propagate any context when using `modal`. This is because React Native doesn't support portals yet.
## components/slider/1.0.0
---
title: Slider
description: A simple slider component
name: slider
component: Slider
package: slider
demoName: Slider
---
# Slider
Drag to set values, vertically or horizontally
```tsx hero template=Slider
```
## Installation
Slider is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/slider
```
## Usage
Slider comes as multiple components that ship with default styles and are sizable. The `size` prop on `` will automatically pass size down to all the sub-components.
```tsx
import { Slider } from 'tamagui'
export default () => (
)
```
You can also optionally style any component, either using inline style props or by wrapping with `styled`:
```tsx
import { Slider, styled } from 'tamagui'
const CustomSliderTrack = styled(Slider.Track, {
backgroundColor: 'red',
})
export default () => (
)
```
## API Reference
### Slider
Contains every component for the slider.
### Slider.Track
`Slider.Track` Inherits `SizableStack`, extending all the default [props](/docs/intro/props).
### Slider.TrackActive
`Slider.Track` Inherits `Stack`, extending all the default [props](/docs/intro/props).
### Slider.Thumb
`Slider.Track` Inherits `SizableStack`, extending all the default [props](/docs/intro/props), adding:
## components/slider/1.45.0
---
title: Slider
description: Drag to set values, vertically or horizontally.
name: slider
component: Slider
package: slider
demoName: Slider
---
```tsx hero template=Slider
```
## Installation
Slider is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/slider
```
## Usage
Slider comes as multiple components that ship with default styles and are sizable. The `size` prop on `` will automatically pass size down to all the sub-components.
```tsx
import { Slider } from 'tamagui'
export default () => (
)
```
You can also optionally style any component, either using inline style props or by wrapping with `styled`:
```tsx
import { Slider, styled } from 'tamagui'
const CustomSliderTrack = styled(Slider.Track, {
backgroundColor: 'red',
})
export default () => (
)
```
## API Reference
### Slider
Contains every component for the slider.
void`,
description: `Called on slide start.`,
},
{
name: 'onSlideMove',
required: false,
type: `(event: GestureReponderEvent, value: number) => void`,
description: `Called on slide move.`,
},
{
name: 'onSlideEnd',
required: false,
type: `(event: GestureReponderEvent, value: number) => void`,
description: `Called on slide end.`,
},
]}
/>
### Slider.Track
`Slider.Track` Inherits `SizableStack`, extending all the default [props](/docs/intro/props).
### Slider.TrackActive
`Slider.TrackActive` Inherits `Stack`, extending all the default [props](/docs/intro/props).
### Slider.Thumb
`Slider.Thumb` Inherits `SizableStack`, extending all the default [props](/docs/intro/props), adding:
## components/spinner/1.0.0
---
title: Spinner
description: Render a loading indicator.
name: spinner
component: Spinner
demoName: Spinner
---
```tsx hero template=Spinner
```
## Installation
Spinner is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/spinner
```
Note that due to the fact that Spinner is an extension of React Native [ActivityIndicator](https://reactnative.dev/docs/activityindicator), and that only accepts size `small` or `large`, we are currently limited to just these sizes.
```tsx
import { Button, Spinner } from 'tamagui'
export default () =>
```
## API Reference
### Spinner
Spinner extends [YStack](/docs/components/stacks), getting [Tamagui standard props](/docs/intro/props), plus:
## components/stacks/1.0.0
---
title: Stacks
description: An optional base for creating flex-based layouts.
name: stacks
component: Stacks
package: stacks
demoName: Stacks
---
```tsx hero template=Stacks
```
Tamagui UI includes optional stack views - XStack, YStack and ZStack. They extend directly off the [View](/docs/core/stack-and-text) from `@tamagui/core`.
Stack props accept [every prop from react-native-web](https://necolas.github.io/react-native-web/docs/view/) View, as well as all [the style properties Tamagui supports](/docs/intro/props).
In this example you'd show three `YStack` elements spaced out.
## Installation
Stacks is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/stacks
```
```tsx
import { XStack, YStack } from 'tamagui'
export default () => (
)
```
To see all the style properties supported, see the [Props](/docs/intro/props) documentation.
### Fuller example
An example using a wide variety of style properties:
```tsx
import { Text, XStack, YStack } from 'tamagui'
export default () => (
HelloWorld
)
```
## API Reference
### XStack, YStack, ZStack
Beyond the [Tamagui Props](/docs/intro/props), the stacks add just two variants:
Sets position: absolute, top: 0, left: 0, right: 0, bottom: 0.
),
},
{
name: 'elevation',
required: false,
type: 'number | tokens.size',
description: (
Sets a natural looking shadow that expands out and away as the size gets bigger.
),
},
]}
/>
## components/switch/1.0.0
---
title: Switch
description: A simple switch component
name: switch
component: Switch
package: switch
demoName: Switch
---
# Switch
Use in forms to toggle between two states.
```tsx hero template=Switch
```
### Usage
```tsx
import { Switch } from 'tamagui'
export default () => (
)
```
### Switch props
Switchs extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'unstyled',
type: 'boolean',
default: 'false',
description: `When true, remove all default tamagui styling.`,
},
]}
/>
## components/switch/1.28.0
---
title: Switch
description: A simple switch component
name: switch
component: Switch
package: switch
demoName: Switch
---
# Switch
Use in forms to toggle between two states.
```tsx hero template=Switch
```
## Installation
Switch is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/switch
```
## Usage
```tsx
import { Switch } from 'tamagui' // or '@tamagui/switch'
export default () => (
)
```
## API Reference
### Switch
Switchs extend Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'unstyled',
type: 'boolean',
default: 'false',
description: `When true, remove all default tamagui styling.`,
},
{
name: 'native',
type: 'NativeValue<"mobile" | "ios" | "android">',
description: `Render to a native switch. (Not supported on web)`,
},
{
name: 'nativeProps',
type: 'SwitchProps (from `react-native`)',
description: `Props to pass to the native Switch;`,
},
]}
/>
### Switch.Thumb
`Switch.Thumb` extends Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
## components/switch/1.58.0
---
title: Switch
description: A simple switch component
name: switch
component: Switch
package: switch
demoName: Switch
---
# Switch
Use in forms to toggle between two states.
```tsx hero template=Switch
```
## Installation
Switch is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/switch
```
## Usage
```tsx
import { Switch } from 'tamagui' // or '@tamagui/switch'
export default () => (
)
```
## Headless with `createSwitch`
Using the `createSwitch` export, you can create a fully custom switch without using any of the default styles. This is similar to `unstyled`, but it doesn't assume the props `size` or `unstyled` exist, and it won't automatically apply the `active` theme.
You must pass `SwitchContext` as the `context` option to your Frame and Thumb styled components.
If you define a `checked` variant, it will apply those styles.
Here's an example:
```tsx
import { Stack, styled } from '@tamagui/core'
import { createSwitch } from '@tamagui/switch'
const Frame = styled(Stack, {
variants: {
checked: {
true: {
backgroundColor: 'yellow'
},
false: {
backgroundColor: 'green',
},
},
} as const,
})
const Thumb = styled(Stack, {
variants: {
checked: {
true: {
opacity: 1,
},
false: {
opacity: 0.5,
},
},
} as const,
})
export const Switch = createSwitch({
Frame,
Thumb,
})
```
## API Reference
### Switch
`Switch` extends Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'unstyled',
type: 'boolean',
default: 'false',
description: `When true, remove all default tamagui styling.`,
},
{
name: 'native',
type: 'NativeValue<"mobile" | "ios" | "android">',
description: `Render to a native switch. (Not supported on web)`,
},
{
name: 'nativeProps',
type: 'SwitchProps (from `react-native`)',
description: `Props to pass to the native Switch;`,
},
]}
/>
### Switch.Thumb
`Switch.Thumb` extends Stack views inheriting all the [Tamagui standard props](/docs/intro/props), plus:
## components/switch/1.89.0
---
title: Switch
description: A toggle between two states.
name: switch
component: Switch
package: switch
demoName: Switch
---
StyledUnstyledHeadless
```tsx hero template=Switch
````
```tsx hero template=SwitchUnstyled
````
```tsx hero template=SwitchHeadless
````
## Installation
Switch is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/switch
````
Switch is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/switch
```
To use the headless switch, you want to import it from the
`@tamagui/switch-headless` package. This package has no dependency on
`@tamagui/core`, but still works off the react-native APIs.
This means can bring your own style library.
```bash
npm install @tamagui/switch-headless
```
## Usage
```tsx
import { Switch } from 'tamagui' // or '@tamagui/switch'
export default () => (
)
```
Using the `createSwitch` export, you can create an unstyled switch without using
any of the default styles. This is similar to the `unstyled` prop, but it
doesn't assume the props `size` or `unstyled` exist, and it won't automatically
apply the `active` theme.
You must pass `SwitchContext` as the `context` option to your Frame and Thumb
styled components.
If you define a `checked` variant, it will apply those styles.
```tsx template=SwitchUnstyled
```
Using the `useSwitch` API, you can make your own Switch from scratch.
```tsx template=SwitchHeadless
```
## API Reference
### Switch
`Switch` extends Stack views inheriting all the
[Tamagui standard props](/docs/intro/props), plus:
void',
},
{
name: 'unstyled',
type: 'boolean',
default: 'false',
description: `When true, remove all default tamagui styling.`,
},
{
name: 'native',
type: 'NativeValue<"mobile" | "ios" | "android">',
description: `Render to a native switch. (Not supported on web)`,
},
{
name: 'nativeProps',
type: 'SwitchProps (from `react-native`)',
description: `Props to pass to the native Switch;`,
},
]}
/>
### Switch.Thumb
`Switch.Thumb` extends Stack views inheriting all the
[Tamagui standard props](/docs/intro/props), plus:
{/* TODO: document createSwitch and useSwitch's API */}
## components/tabs/1.125.35
---
title: Tabs
description: Use in pages to manage sub-pages.
name: tabs
component: Tabs
package: tabs
demoName: Tabs
---
StyledHeadless
```tsx hero template=Tabs
```
Note: Tabs have landed on v1.7 and not fully ready for runtime. Send us your feedback and we'll address it. We're marking it Beta a such as there may be hopefully minimal breaking changes as we get feedback on the API.
## Installation
Tabs is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/tabs
```
## Usage
```tsx
import { SizableText, Tabs } from "tamagui";
export default () => (
Tab 1Tab 2
Tab 1
Tab 2
);
```
## API Reference
### Tabs
Root tabs component. Extends [Stack](/docs/components/stack). Passing the `size` prop to this component will have effect on the descendants.
void",
description: `A function called when a new tab is selected`,
},
{
name: "orientation",
type: '"horizontal" | "vertical"',
default: "horizontal",
description: `The orientation the tabs are layed out`,
},
{
name: "dir",
type: '"ltr" | "rtl"',
description: `The direction of navigation between toolbar items`,
},
{
name: "activationMode",
type: '"manual" | "automatic"',
default: "automatic",
description: `Whether or not a tab is activated automatically or manually. Not applicable on mobile`,
},
]}
/>
### Tabs.List
Container for the trigger buttons. Supports scrolling by extending [Group](/docs/components/group). You can disable passing border radius to children by passing `disablePassBorderRadius`.
### Tabs.Trigger
Extends [Button](/docs/components/button), adding:
void`,
description: `Used for making custom indicators when trigger interacted with`,
},
{
name: "unstyled",
type: `boolean`,
description: `When true, remove all default tamagui styling`,
},
]}
/>
### Tabs.Content
Where each tab's content will be shown. Extends [ThemeableStack](/docs/components/stacks#themeablestack), adding:
## Examples
### Animations
Here is a demo with more advanced animations using [AnimatePresence](/docs/core/animations#animatepresence-and-exitstyle) and [Trigger](#trigger)'s `onInteraction` prop.
```tsx hero template=TabsAdvanced
```
```tsx hero template=TabsHeadless
```
### Customization Options
When using `createTabs`, you need to provide three styled components:
- `TabsFrame`: The root container component
- `TabFrame`: The tab trigger component
- `ContentFrame`: The content container component
The created tabs component will maintain all the accessibility features and keyboard navigation while allowing you to have complete control over the visual presentation.
The headless API gives you the foundation to build completely custom tab interfaces while maintaining accessibility and interaction patterns. You can integrate it with your design system and add any custom behaviors you need.
## components/tabs/1.7.0
---
title: Tabs
description: Use in pages to manage sub-pages.
name: tabs
component: Tabs
package: tabs
demoName: Tabs
---
```tsx hero template=Tabs
```
Note: Tabs have landed on v1.7 and not fully ready for runtime. Send us your feedback and we'll address it. We're marking it Beta a such as there may be hopefully minimal breaking changes as we get feedback on the API.
## Usage
```tsx
import { SizableText, Tabs } from 'tamagui'
export default () => (
Tab 1Tab 2
Tab 1
Tab 2
)
```
## API Reference
### Tabs
Root tabs component. Extends [Stack](/docs/components/stack). Passing the `size` prop to this component will have effect on the descendants.
void',
description: `A function called when a new tab is selected`,
},
{
name: 'orientation',
type: '"horizontal" | "vertical"',
default: 'horizontal',
description: `The orientation the tabs are layed out`,
},
{
name: 'dir',
type: '"ltr" | "rtl"',
description: `The direction of navigation between toolbar items`,
},
{
name: 'activationMode',
type: '"manual" | "automatic"',
default: 'automatic',
description: `Whether or not a tab is activated automatically or manually. Not applicable on mobile`,
},
]}
/>
### Tabs.List
Container for the trigger buttons. Supports scrolling by extending [Group](/docs/components/group). You can disable passing border radius to children by passing `disablePassBorderRadius`.
### Tabs.Trigger
Extends [Button](/docs/components/button), adding:
void`,
description: `Used for making custom indicators when trigger interacted with`,
},
{
name: 'unstyled',
type: `boolean`,
description: `When true, remove all default tamagui styling`,
},
]}
/>
### Tabs.Content
Where each tab's content will be shown. Extends [ThemeableStack](/docs/components/stacks#themeablestack), adding:
## Examples
### Animations
Here is a demo with more advanced animations using [AnimatePresence](/docs/core/animations#animatepresence-and-exitstyle) and [Trigger](#trigger)'s `onInteraction` prop.
```tsx hero template=TabsAdvanced
```
## components/tamagui-image/1.0.0
---
title: Image
description: Web compatible and super light image component with Tamagui style props.
name: html
component: Image
package: image-next
demoName: WebNativeImageDemo
---
```tsx hero template=WebNativeImage
```
## Installation
Image is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/image-next
```
## Usage
```tsx
export default () => (
)
```
## API Reference
### Image
[Tamagui props](/docs/intro/props) + [Web img props](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) + [React Native Image props](https://necolas.github.io/react-native-web/docs/image/).
All web [img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
props are supported on web, and all native
[Image](https://necolas.github.io/react-native-web/docs/image/) props are
supported on native. on native we are still using web img APIs, but not all
web img props are supported. like `decoding`
#### Some common props
## components/text/1.0.0-alpha
---
title: Text
description: Text, Sized Text and Paragraph show one way to build a design system.
name: text
component: Paragraph
demoName: Text
---
# Text
Text, Sized Text and Paragraph show one way to build a design system.
```tsx hero template=Text
```
### Usage
Text in Tamagui matches to Text in react-native-web, just with the added [Tamagui Props](/docs/intro/props).
It explicitly doesn't inherit your theme color or other font properties, as it's meant to be plain and used for extension. Below, we'll show `SizableText` which extends Text, and `Paragraph` which extends SizableText. Generally, Paragraph is the useful view as it will use theme values, while you can extend Text if you'd like to derive your own design system.
```tsx
import { Text, XStack, YStack } from 'tamagui'
export default () => (
<>
Lorem ipsum
>
)
```
SizableText and Paragraph default to the "body" fontFamily defined in your config.
Headings all default to "heading".
## SizableText
[Seeing how SizableText is defined](https://github.com/tamagui/tamagui/blob/master/packages/tamagui/src/views/SizableText.tsx) is helpful for understanding Tamagui. They serve as a good example of how you can extend and compose components.
SizableText simply adds a single `size` property to maniplulate all of:
- fontSize
- lineHeight
- fontWeight
- letterSpacing
Based on the values set in your tokens. It uses [spread variants](/docs/core/styled#spread-variants) feature. Then Paragraph extends that and ensures it defaults to values from your theme - fontSize, lineHeight, color and fontFamily.
## Paragraph
Finally Paragraph extends `SizableText` and simply sets some default values from your theme:
```tsx
export const Paragraph = styled(SizableText, {
fontFamily: '$body',
color: '$color',
// note tamagui uses a generic "true" token that your sizes should set to be the same as the default on your scale
size: '$true',
})
```
## components/text/1.0.0
---
title: Text
description: Text primitives with themes custom to each font.
name: text
component: Paragraph
package: text
demoName: Text
---
```tsx hero template=Text
```
## Installation
Text is already installed in `tamagui`, or you can install it independently:
```bash
npm install @tamagui/text
```
## Usage
```tsx
export default () => (
<>
TextSizable TextParagraph
>
)
```
## Text
Text in Tamagui matches to Text in react-native-web, just with the added [Tamagui Props](/docs/intro/props).
It explicitly doesn't inherit your theme color or other font properties, as it's meant to be plain and used for extension. Below, we'll show `SizableText` which extends Text, and `Paragraph` which extends SizableText. Generally, Paragraph is the useful view as it will use theme values, while you can extend Text if you'd like to derive your own design system.
```tsx
import { Text, XStack, YStack } from 'tamagui'
export default () => (
<>
Lorem ipsum
>
)
```
## SizableText
Tamagui lets you define font sizing, spacing, line height, letter spacing and other properties with `createFont`, of which you can have many different configurations. We've found a nice pattern is to "align" all your keys across these sub-objects.
SizableText adds a `size` property thats defined using a [spread variant](/docs/core/styled#spread-variants) which looks for a matching key on each of these properties (using `@tamagui/get-font-sized`):
- color
- fontStyle
- textTransform
- fontFamily
- fontWeight
- letterSpacing
- fontSize
- lineHeight
So, if you've defined `small`, `medium` and `large` keys on each createFont category, you can use it like so:
```tsx
```
[Source code for SizableText](https://github.com/tamagui/tamagui/blob/main/code/ui/text/src/SizableText.tsx).
## Paragraph
Paragraph extends SizableText and is defined as:
```tsx
export const Paragraph = styled(SizableText, {
name: 'Paragraph',
tag: 'p',
userSelect: 'auto',
color: '$color',
size: '$true',
whiteSpace: 'normal',
})
```
Note: Paragraph renders to a `p` tag on web, which can cause issues when you nest them
during SSR. If you don't mind rendering to a span, use `SizableText`, otherwise, be
careful when nesting items inside a Paragraph.
## components/toast/1.11.3
---
title: Toast
description: A toast component with native features
name: toast
component: Toast
package: toast
demoName: Toast
---
# Toast Use to show feedback to user interactions
```tsx hero template=Toast
```
## Installation
Run the following command:
```
yarn add @tamagui/toast burnt
```
then, rebuild your React Native app. React Native requires sub-dependencies with native dependencies always be hoisted to your apps package.json and Toast relies on the amazing [Burnt](https://github.com/nandorojo/burnt) library by Fernando Rojo to provide its native functionality.
## Usage
To display the toast natively, you should either pass an array of native platforms (`native: ["ios", "web"]`), a single platform or `true` for all platforms.
```tsx
import { Button } from 'tamagui' // or '@tamagui/button'
import { Toast, ToastProvider, useToast } from '@tamagui/toast'
export default () => (
)
const CurrentToast = () => {
const { currentToast } = useToast()
// only show the component if it's present and not handled by native toast
if (!currentToast || currentToast.isHandledNatively) return null
return (
{currentToast.title}{currentToast.message}
)
}
const MyPage = () => {
const { show } = useToast()
return (
)
}
```
## API
### ToastProvider
Your toasts should be wrapped within a `ToastProvider`. This is usually done at the root of your application.
`,
description: `Options for the burnt package if you're using native toasts on mobile`,
},
{
name: `notificationOptions`,
required: false,
type: `NotificationOptions`,
description: `Options for the notification API if you're using native toasts on web`,
},
]}
/>
### ToastViewport
The portal for toasts to be directed to. Should be used inside [ToastProvider](#toastprovider). Beyond [Stack Props](/docs/components/stacks/1.0.0), adds:
### Toast
Contains the Title, Description, Action and Close component. Should be used inside [ToastProvider](#toastprovider). Extends [Stack](/docs/components/stack#api) and adds:
#### Toast.Title
Should be used inside [Toast](#toast). Extends [SizableText](/docs/components/text/1.0.0#sizabletext).
#### Toast.Description
Should be used inside [Toast](#toast). Extends [SizableText](/docs/components/text/1.0.0#sizabletext).
#### Toast.Close
Should be used inside [Toast](#toast). Extends [Stack](/docs/components/stacks/1.0.0). You can pass `asChild` to this component and use a custom `