mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
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]>
123 lines
4.0 KiB
Plaintext
123 lines
4.0 KiB
Plaintext
# Animations
|
||
|
||
You define animations on `createGui` and can choose from animation drivers: CSS, reanimated, react-native, or motion.
|
||
|
||
```tsx
|
||
import { View } from '@hanzo/gui'
|
||
;<View animation="100ms" />
|
||
```
|
||
|
||
When defined like this, Hanzo GUI will animate all [animatable properties](#animatable-properties) when they change.
|
||
|
||
If you'd like to limit which properties animate, you have two options: `animateOnly`, or the array-style configuration object passed to `animation`:
|
||
|
||
```tsx
|
||
// animate only background using animateOnly
|
||
<View animation="100ms" animateOnly={['background']} />
|
||
|
||
// alternative, more powerful syntax to control per-style animation values
|
||
<View
|
||
animation={[
|
||
// this is the default animation
|
||
'100ms',
|
||
{
|
||
// now you can override per-prop using a preset
|
||
background: '200ms',
|
||
// or by defining a custom animation that matches the reanimated syntax:
|
||
// note that `transform` covers all the flat transform animations (x, y, scale, etc), and you can't target those individually yet
|
||
transform: {
|
||
type: 'spring',
|
||
delay: 100,
|
||
mass: 1,
|
||
// ...
|
||
},
|
||
},
|
||
]}
|
||
/>
|
||
```
|
||
|
||
### Animatable Properties
|
||
|
||
For the reanimated driver which we use currently, the only properties that are animatable for now are:
|
||
|
||
- transform (note this includes things like scale, transform, x, y, rotate)
|
||
- opacity
|
||
- height
|
||
- width
|
||
- backgroundColor
|
||
- borderColor
|
||
- borderLeftColor
|
||
- borderRightColor
|
||
- borderTopColor
|
||
- borderBottomColor
|
||
- borderRadius
|
||
- borderTopLeftRadius
|
||
- borderTopRightRadius
|
||
- borderBottomLeftRadius
|
||
- borderBottomRightRadius
|
||
- borderLeftWidth
|
||
- borderRightWidth
|
||
- borderTopWidth
|
||
- borderBottomWidth
|
||
- color
|
||
- left
|
||
- right
|
||
- top
|
||
- bottom
|
||
|
||
## When to use Hanzo GUI animations
|
||
|
||
Hanzo GUI doesn't support all the types of animations we need. In general use Hanzo GUI for animations by default, but if you notice performance issues you may want to bail out to "using the platform" (ie, CSS on web or Reanimated on native).
|
||
|
||
Some limitations currently:
|
||
|
||
- Doesn't support timeline or repeating animations yet.
|
||
- All animations internally will re-render to trigger (ie, hover/press/enter/exit). So not as performant as reanimated worklets or CSS. So use your discretion, if an animation feels laggy it may not be good for Hanzo GUI.
|
||
- Can’t do different animations for “pseudo” or state styles like enter/exit/hover/press (would love to land this, it’s not too hard and we have a spec for it).
|
||
|
||
### Performance Sensitivity
|
||
|
||
Right now Hanzo GUI requires re-rendering to trigger animation changes. This can cause stuttering if the re-render is expensive enough to clog the main thread while the animation is running. You can sometimes fix this just by memoizing things below the Hanzo GUI component that animates.
|
||
|
||
### AnimatePresence
|
||
|
||
See [the Hanzo GUI docs](https://gui.hanzo.ai/docs/core/animations#animate-presence) for a bit more on AnimatePresence.
|
||
|
||
AnimatePresence is a super powerful Hanzo GUI component for animations. Typically it's very cumbersome to do an "exit" animation in React, as the component will unmount before the animation runs. With AnimatePresence, you can animate enter and exit styles more easily, and you can even change their variants out as they enter/exit.
|
||
|
||
Here's some rough pseudo code of how you'd do that, you can find plenty of examples already in the codebase to work from:
|
||
|
||
```tsx
|
||
function MyComponent() {
|
||
// you would have your own logic for the "direction" here:
|
||
const towards = isGoingRight ? -1 : 1
|
||
|
||
return (
|
||
<AnimatePresence custom={{ towards }} initial={false}>
|
||
{/* note the key changes when you need to "run" the animation: */}
|
||
<SlidingPane key={currentPane} animation="200ms">
|
||
{/* Contents of your pane */}
|
||
</SlidingPane>
|
||
</AnimatePresence>
|
||
)
|
||
}
|
||
|
||
const SlidingPane = styled(View, {
|
||
x: 0,
|
||
opacity: 1,
|
||
|
||
variants: {
|
||
towards: (dir: Direction) => ({
|
||
enterStyle: {
|
||
x: dir === -1 ? -10 : 10,
|
||
opacity: 0,
|
||
},
|
||
exitStyle: {
|
||
x: dir === -1 ? 10 : -10
|
||
opacity: 0,
|
||
},
|
||
}),
|
||
} as const,
|
||
})
|
||
```
|