Files
zeekayandHanzo Dev 69c6e860d7 transplant onto tamagui v2.6.0, brand as a re-runnable transform
This repo could never sync. There was NO merge-base with tamagui — 372 commits
here against 15,791 there, unrelated histories — because it began as a
copy-paste rebrand with a flattened layout. Every "sync" since was a hand
re-application that drifted, which is why the tree sat on 7.3.1 while upstream
shipped fixes we then rediscovered by hand.

This commit's PARENT IS TAMAGUI. A future sync is `git merge tama/main` then
`node scripts/rebrand.mjs` — a real merge, because the history is now shared.

174 packages: 166 upstream, our 8 restored (chrome, shell, telemetry, recipes,
get, font-geist-{sans,mono}, @hanzo/booker), bento-get gained. 170/170 build.

Our patches to files UPSTREAM ALSO OWNS are carried, which the package-level
delta missed and which was where the value actually was:
  - useMedia's server snapshot (`initState ?? getMedia()`). Upstream still
    returns undefined there, so every Tamagui Dialog kills a prerender — the
    exact crash hanzo.app spent a day on.
  - data-slot on web host nodes, absent upstream entirely.
Both applied ONTO upstream's newer files (it rewrote useMedia +150/-63 and
createComponent +160/-55), marked `PATCH (ours, carried across the transplant)`.

Seven traps are encoded in scripts/rebrand.mjs, each found by a gate:
skip itself and lockfiles; special-case the double-branded names in BOTH scoped
and bare form; map path strings, not just paths; drop a level for the flattened
group; check disk rather than a stale index.

Rust build artifacts are NOT committed. An earlier draft of this commit swept
apps/desktop/src-tauri/target/debug in via `git add -A` — 3,859 files including
a 272MB .a, over GitHub's 100MB cap, so the push could never have landed. They
are gitignored now.

Co-Authored-By: Hanzo Dev <[email protected]>
2026-07-30 18:25:06 -07:00

485 lines
13 KiB
Plaintext

---
title: Gui Props
description: All the base props
---
Gui supports a superset of the React Native props. Start with:
- [View](https://reactnative.dev/docs/view-style-props), or
- [Text](https://reactnative.dev/docs/text-style-props)
From there, we add [style props](/docs/intro/styles) directly onto the same
object.
Finally, there are a few non-style props Gui adds:
## Event Props
All Gui View-based components have Pressable-like functionality built in. You don't need to wrap in `Pressable` or `TouchableOpacity` - add event handlers directly:
```tsx
<View
onPress={() => console.log('pressed')}
onHoverIn={() => console.log('hovered')}
pressStyle={{ opacity: 0.8 }}
hoverStyle={{ backgroundColor: '$backgroundHover' }}
/>
```
<PropsTable
data={[
{
name: 'onPress',
required: false,
type: '(e: GestureResponderEvent) => void',
description: (
<span>Called when a press is released. Works on both web and native.</span>
),
},
{
name: 'onPressIn',
required: false,
type: '(e: GestureResponderEvent) => void',
description: <span>Called immediately when a press starts.</span>,
},
{
name: 'onPressOut',
required: false,
type: '(e: GestureResponderEvent) => void',
description: <span>Called when a press is released or cancelled.</span>,
},
{
name: 'onLongPress',
required: false,
type: '(e: GestureResponderEvent) => void',
description: (
<span>
Called when a press is held for longer than <code>delayLongPress</code> (default
500ms).
</span>
),
},
{
name: 'onHoverIn',
required: false,
type: '(e: MouseEvent) => void',
description: (
<span>
<strong>Web Only</strong>: Called when the mouse enters the element. Maps to{' '}
<code>onMouseEnter</code>.
</span>
),
},
{
name: 'onHoverOut',
required: false,
type: '(e: MouseEvent) => void',
description: (
<span>
<strong>Web Only</strong>: Called when the mouse leaves the element. Maps to{' '}
<code>onMouseLeave</code>.
</span>
),
},
{
name: 'onFocus',
required: false,
type: '(e: FocusEvent) => void',
description: <span>Called when the element receives focus.</span>,
},
{
name: 'onBlur',
required: false,
type: '(e: FocusEvent) => void',
description: <span>Called when the element loses focus.</span>,
},
{
name: 'delayPressIn',
required: false,
type: 'number',
description: (
<span>
Duration in ms to wait before calling <code>onPressIn</code>.
</span>
),
},
{
name: 'delayPressOut',
required: false,
type: 'number',
description: (
<span>
Duration in ms to wait before calling <code>onPressOut</code> after press is
released.
</span>
),
},
{
name: 'delayLongPress',
required: false,
type: 'number',
description: (
<span>
Duration in ms to wait before calling <code>onLongPress</code>. Default is
500ms.
</span>
),
},
{
name: 'minPressDuration',
required: false,
type: 'number',
description: (
<span>
Minimum duration in ms that a press must be held before <code>onPressOut</code>{' '}
is called.
</span>
),
},
{
name: 'cancelable',
required: false,
type: 'boolean',
description: (
<span>
When true, allows the press to be cancelled by scrolling or other gestures.
</span>
),
},
{
name: 'disabled',
required: false,
type: 'boolean',
description: <span>Disables all press and hover interactions on the element.</span>,
},
{
name: 'focusable',
required: false,
type: 'boolean',
description: (
<span>
Whether the element can receive focus. On web, controls <code>tabIndex</code>.
</span>
),
},
{
name: 'hitSlop',
required: false,
type: `number | Insets`,
description: (
<span>
Extends the pressable area beyond the element bounds. Accepts a number (applies
to all sides) or an object with <code>top</code>, <code>bottom</code>,{' '}
<code>left</code>, <code>right</code>.
</span>
),
},
]}
/>
Use these events alongside style states like `pressStyle`, `hoverStyle`, and `focusStyle` to create interactive components. See the [Style API](/docs/intro/styles) for styling on interaction states.
## Other Props
<PropsTable
data={[
{
name: 'render',
required: false,
type: `string | JSX.Element | ((props, state) => JSX.Element)`,
description: (
<span>
Control which element or component is rendered. Accepts an HTML tag name (e.g., <code>"button"</code>, <code>"a"</code>),
a JSX element, or a render function receiving props and component state. String render props are compiler-optimized.
See <a href="/docs/core/styled#render">styled() render documentation</a> for details.
</span>
),
},
{
name: 'transition',
required: false,
type: 'string',
description: (
<span>
Apply a transition animation as defined in your createGui configuration. See the{' '}
<a href="/docs/core/animations">Animations documentation</a> for more details on configuring animation drivers.
</span>
),
},
{
name: 'animateOnly',
required: false,
type: 'string[]',
description: (
<span>
A list of properties to animate. Note that flat transforms can only be controlled via `transform`. Learn more in the{' '}
<a href="/docs/core/animations#granular-animations">Granular animations</a> section.
</span>
),
},
{
name: 'theme',
required: false,
type: 'string',
description: (
<span>
Apply a theme or sub-theme to this component and the components below it.
</span>
),
},
{
name: 'themeInverse',
required: false,
type: 'boolean',
description: (
<span>
Invert light or dark theme for the sub-tree.
</span>
),
},
{
name: 'themeShallow',
required: false,
type: 'boolean',
description: (
<span>
Used in combination with the theme prop, it prevents the theme from passing to children.
</span>
),
},
{
name: 'forceStyle',
required: false,
type: `'hover' | 'press' | 'focus' | 'focusVisible' | 'focusWithin'`,
description: (
<span>
Forces the pseudo style state to be on.
</span>
),
},
{
name: 'group',
required: false,
type: `boolean | string`,
description: (
<span>
Marks this component as a group for use in styling children based on parents named group.
</span>
),
},
{
name: 'componentName',
required: false,
type: 'string',
description: (
<span>
Equivalent to "name" property on styled() for automatically applying a theme.
</span>
),
},
{
name: 'className',
required: false,
type: 'string',
description: (
<span>
<strong>Web Only</strong>: An escape hatch to set className. This works fully with the compiler, which will concat your defined className with its generated ones.
</span>
),
},
{
name: 'disableClassName',
required: false,
type: 'boolean',
description: (
<span>
<strong>Web Only</strong>: Disables className output of styles, instead using only inline styles.
</span>
),
},
{
name: 'tag',
required: false,
type: 'string',
description: (
<span>
<strong>Web Only</strong>: Renders the final element as the given tag. Note: React Native Web doesn't support tag and as such if using any animation driver except CSS the tag prop will stop working. We'd recommend using "role" for most cases.
</span>
),
},
{
name: 'space',
required: false,
deprecated: true,
type: "boolean | string | GuiConfig['space']",
description: (
<span>
Use gap instead -
Spacing is built into Gui and can accept a number or Token.space value. This will
filter out any nullish child elements and insert a spacer components between the remaining
elements.
</span>
),
},
{
name: 'spaceDirection',
required: false,
deprecated: true,
default: 'both',
type: `'horizontal' | 'vertical' | 'both'`,
description: (
<span>
By default the space inserted is a square, but if you set it to horizontal it will be 0px tall, vertical will be 0px wide.
</span>
),
},
{
name: 'debug',
required: false,
type: `boolean | 'verbose' | 'break'`,
description: (
<span>
When set Gui will output a variety of helpful information on how it parsed and
applied styling. Verbose will output more information, and break will hit a debugger at
the start of render in development mode.
</span>
),
},
{
name: 'untilMeasured',
required: false,
type: `'hide' | 'show'`,
description: (
<span>
Works only alongside group, when children of the group are using container based sizing on native you can hide them until parent is measured.
</span>
),
},
{
name: 'disableOptimization',
required: false,
type: 'boolean',
description: (
<span>
Disable all compiler optimization.
</span>
),
},
{
name: 'tabIndex',
required: false,
type: `string | number`,
description: (
<span>
Used for controlling the order of focus with keyboard or assistive device navigation.
</span>
),
},
{
name: 'role',
required: false,
type: 'Role',
description: (
<span>
Indicates to accessibility services to treat UI component like a specific role.
</span>
),
},
{
name: 'asChild',
required: false,
type: `boolean | 'except-style' | 'except-style-web' | 'web'`,
description: (
<span>
When true, Gui expects a single child element. Instead of rendering its own element, it will pass all props to that child, merging together any event handling props. When "except-style", the same behavior except Gui won't pass styles down from the parent, only non-style props.
</span>
),
},
{
name: 'passThrough',
required: false,
type: 'boolean',
description: (
<span>
Advanced use only. React will "re-parent" components when it's internal tree structure changes.
When making UI that adapts to another look, for better performance and avoiding losing user state (like focus, or uncontrolled text input), you can use passThrough rather than conditionally rendering a wrapping component.
</span>
),
},
]} />
## Event Handlers
Gui supports all React Native events on all platforms. On web, we also support all standard DOM event handlers:
### Cross-Platform Events
- `onPress`, `onLongPress`, `onPressIn`, `onPressOut` - Touch/press events that work on both native and web
**Pointer Events** - Modern events that unify mouse, touch, and pen input. On native, these are mapped to touch events with a normalized event shape including `clientX/Y`, `pointerId`, and `pointerType`:
- `onPointerDown`, `onPointerUp`, `onPointerMove`
- `onPointerEnter`, `onPointerLeave`, `onPointerCancel`
On native, `e.target.setPointerCapture(pointerId)` and `releasePointerCapture(pointerId)` are supported for drag scenarios where you need to receive move events outside the element bounds.
### Web-Only Events
The following events are available on web and automatically ignored on native:
**Mouse Events**
- `onClick`, `onDoubleClick`, `onContextMenu`
- `onMouseEnter`, `onMouseLeave`, `onMouseMove`, `onMouseOver`, `onMouseOut`
- `onMouseDown`, `onMouseUp`
- `onWheel`
**Keyboard Events**
- `onKeyDown`, `onKeyUp`, `onKeyPress`
**Drag and Drop**
- `onDrag`, `onDragStart`, `onDragEnd`
- `onDragEnter`, `onDragLeave`, `onDragOver`
- `onDrop`
**Input Events**
- `onChange`, `onInput`, `onBeforeInput`
**Scroll Events**
- `onScroll`
**Clipboard Events**
- `onCopy`, `onCut`, `onPaste`
**Focus Events**
- `onFocus`, `onBlur`
All event handlers receive the standard React synthetic event as their argument.