Files
gui/apps/gui.hanzo.ai/data/blog/hanzogui-enters-beta-themes-and-animations.mdx
2026-09-04 09:04:51 -07:00

345 lines
11 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Gui Beta
publishedAt: '2022-04-23'
description: Animations, a new theme system, starter apps, and much more.
by: nate
---
<IntroParagraph>
Gui is a universal UI kit for React Native and Web, making it much easier to ship
performant, beautiful apps across all platforms using the same code. It makes hard
things easy - like themes, responsive styling, and animation.
</IntroParagraph>
**At its core are three libraries**:
<IntroParagraph>
<UL>
<LI>
A style library (`@hanzogui/core`) for creating React Native + Web components.
</LI>
<LI>An optimizing compiler (`@hanzogui/static`) for incredible performance.</LI>
<LI>A component kit (`hanzogui`) built using both of the above.</LI>
</UL>
</IntroParagraph>
It's been six months since the first alpha,
[several hundreds of bugfixes](https://github.com/hanzoai/gui/releases/tag/v1.0.0-beta.0),
[three demo apps](https://github.com/hanzogui), ten new components, and now a few
big new core features. Plus, a [refreshed site](/), a
[benchmark suite](/docs/intro/benchmarks), a host of type improvements, and
compatibility with more versions of Next.js, Webpack, and React Native.
What's new?
### Get started faster 🚀
Introducing `npm create hanzogui`, to get started much faster with a bootstrapped
monorepo that uses Expo, Next.js, Solito and Gui.
A big shout out to [Fernando Rojo](https://twitter.com/fernandotherojo) for
creating [Solito](https://solito.dev), a great library for sharing all your
views between Expo and Next.js, and the bootstrap repo.
---
### Themes 2.0 🎨
Theme internally have been completely redone, and they're really fun. They work
better, nest better, and come with a nice preset in `@hanzogui/themes`.
Theme objects now default to names that map to standard style names (with
optional pseudo suffixes), so `color`, plus the alternates `colorHover`,
`colorFocus`, and `colorPress` are definable.
Building off that, themes can nest unlimited times - `dark` and `light` can have
`dark_blue` and `light_blue`, and then different tints below that, like
`dark_blue_alt1`.
<HeroContainer alignItems="flex-start">
<XStack py="$4" px="$6" ai="center" gap="$11">
<XStack scale={0.8}>
<YStack pos="relative" z={0} zi={3} mr={-200}>
<MediaPlayerDemo theme="blue" alt={1} />
</YStack>
<YStack pos="relative" z={0} zi={2} mr={-200}>
<MediaPlayerDemo theme="blue" alt={2} />
</YStack>
<YStack pos="relative" z={0} zi={1} mr={-200}>
<MediaPlayerDemo theme="blue" alt={3} />
</YStack>
</XStack>
<XStack scale={0.8}>
<YStack pos="relative" z={0} zi={3} mr={-200}>
<MediaPlayerDemo theme="pink" alt={1} />
</YStack>
<YStack pos="relative" z={0} zi={2} mr={-200}>
<MediaPlayerDemo theme="pink" alt={2} />
</YStack>
<YStack pos="relative" z={0} zi={1} mr={-200}>
<MediaPlayerDemo theme="pink" alt={3} />
</YStack>
</XStack>
<Spacer size="$6" />
</XStack>
</HeroContainer>
The `theme` prop is now also available on every component, including ones you
create using the `styled` factory function.
Components now apply any sub-theme that matches their name - so `Button`, will
look for `dark_blue_Button` if it exists, giving complete control the UI at the
theme level, across every component. PLus, icons, buttons and more components
have been upgraded to better handle passing themes down automatically.
**I'm really happy with how this landed**. This release could have focused more
on new components, but it became obvious while working on [Tooltip](/ui/tooltip)
/ [Popover](/ui/popover) / [Sheet](/ui/sheet) that _getting animations and
themes right needed to happen first_ to avoid future pain.
We now have a very solid foundation.
[Read the docs for much more on themes](/docs/intro/themes).
---
### Animations
Animations are making their way, experimentally, into `@hanzogui/core`. They are
unstable, but we want to get feedback and use them more in practice.
<OffsetBox my="$4">
<XStack py="$4">
<ExampleAnimations />
</XStack>
</OffsetBox>
They're implemented as pluggable drivers, starting with two:
- [CSS](/docs/core/animations#css)
- [Reanimated](/docs/core/animations#css)
Which means you can swap entire animation drivers depending on your platform.
Want lighter bundles on web, but spring animations on native? Install both
packages and swap them out based on your environment.
We've also added a new pseudo `enterStyle` that works if you have an `animation`
prop set, giving you easy styling on mount (and see the next section for
`exitStyle`).
[Read the docs on animations](/docs/core/animations) to get started.
#### AnimatePresence
In early form, we've added
[AnimatePresence](/docs/core/animations#animate-presence), which is directly
forked off Framer Motion. It works with `exitStyle` and variants to make
once-complex animations quite easy.
<HeroContainer noPad>
<AnimationsPresenceDemo />
</HeroContainer>
```tsx hero template=AnimationsPresence
```
---
### New Components
We've added quite a few new components, and a good portion more are nearing
release. Since the alpha we've introduced: [Inputs](/ui/inputs),
[Label](/ui/label), [Switch](/ui/switch), [Image](/ui/image),
[Separator](/ui/separator), [ThemeInverse](/docs/core/theme#theme-inverse),
[Popover](/ui/popover), [Tooltip](/ui/tooltip), [Drawer](/ui/drawer),
[Square and Circle](/ui/shapes), [HTML Elements](/ui/html-elements).
Here's the new Switch component working with spring animations:
<HeroContainer>
<SwitchDemo />
</HeroContainer>
```tsx hero template=Switch
```
[Join our Discord to vote for new components](https://discord.gg/4qh6tdcVDa).
---
### Styled Factory Upgrades
The `styled()` factory function as well gets many upgrades, it accepts React
Native components directly and automatically interprets their props, as well as
many fixes - full media query support, _much_ faster/accurate types, and better
compilation.
---
### Popover
Popover was introduced in alpha, but we've redone it for the beta. It's still
early stage, but the API is significantly improved. It now gives you much more
control over the target, content and trigger. Importantly, it works using
Gui primitives, and automatically wraps your content in
[AnimatePresence](/docs/core/animations#animate-presence) supporting beautiful
and simple enter/exit animations.
The core of Popover is now powered by the wonderful
[Floating UI](https://floating-ui.com/), saving us a lot of complexity and
giving it more reliable and powerful behaviors.
It's also been split out optionally into it's own package at `@hanzogui/popover`.
Show the code below to see the improved component-based API.
<HeroContainer>
<PopoverDemo />
</HeroContainer>
---
### Tooltip
Tooltip likewise was rebuilt in a similar fashion to Popover - a compound
component API, full animation support, and powered by
[Floating UI's React DOM Interactions](https://floating-ui.com/docs/react-dom-interactions).
<HeroContainer>
<TooltipDemo />
</HeroContainer>
---
### Other Component Updates
[LinearGradient](/ui/linear-gradient), [Image](/ui/image), and
[Button](/ui/button) have received lots of love. LinearGradient now fully
supports all theme values and the compiler will help it extract any style
properties. Image should still be considered beta, but has gone through many
rounds of bugfixes and improvements. And Button now handles passing more text
properties down, themes and sizes icons more reliably, and has many fixes for
variants like `circular`.
---
### Focus Styles
We landed experimental support for the `focusStyle` prop, which works much like
`pressStyle` and `hoverStyle`. You can see it in action on `Input`:
<HeroContainer>
<InputsDemo />
</HeroContainer>
```tsx hero template=Inputs
```
---
### ThemeReset
Sometimes you want to reset the current theme to the grandparent.
[ThemeReset](/docs/core/theme#theme-reset) does just this. Note: it's not SSR
compatible if you use automatic light/dark themes (it will still work, but it
won't fully render until JS runs). There's a fix for this that is a bit
involved, but we think it's still useful to release it as experimental.
---
### Theme Generation
Use the themes from the Gui site itself without any setup at all, simply
install `@hanzogui/themes` and add `themes` and `tokens` to `createGui()` in
your `hanzogui.config.ts`.
Likewise, we've released `@hanzogui/shorthands`, nice preset default shorthands.
---
### Feather Icons
We've released [@hanzogui/lucide-icons-2](/ui/lucide-icons), which have numerous
adjustments to work well with themes and sizing.
You can import and use them directly, or pass them to Buttons:
```tsx
import { Play } from '@hanzogui/lucide-icons-2'
import { Button } from '@hanzo/gui'
// theme and size are properly passed from Button to icons automatically
export default () => <Button size="$6" icon={Play} />
```
---
### And much more...
- ✨ Many docs improvements: new pages, more examples, more props documented,
and search.
- ✨ `asChild` prop that lets you simply pass all style props down to a child.
- ✨ Support for media query prefers color scheme
- 🐛
[Hundreds of bug-fixes](https://github.com/hanzoai/gui/releases/tag/v1.0.0-beta.0).
- 🐛 Much improved install experience and many bugs fixed with Next, Webpack,
Monorepos.
---
### Breaking changes
- Sub themes now must be named with `_` (underscore) separators.
- In hanzogui.config.ts, `tokens.font` => `fonts`.
- Popover and Tooltip are redone in with Radix-style nested components
- We've exported a small `TooltipSimple` component that mimics the old Tooltip
- HoverablePopover has been removed in favor of just Tooltip or customizing
Popover
---
### Going forward
There's a ton of progress here, but likewise a ton more to go. There's many
components, docs, and features to be written, and alongside that I'd like to get
better at community and sharing progress from here on out.
What really excites me with this release is the foundation laid. Gui now has
_such_ a rich set of primitives - from animations, themes, and sizing, to
performance across every feature, to all the helpers and hooks adopted since
alpha that make animated, sizable and Radix-like compound API's a breeze, all
the way to Floating UI and all the powerful primitives that brings. Everything
feels like it's working together well (✊🪵).
Seeing Tooltip come to life somewhat easily in the latest refactor by just
importing a few hooks/components and giving it an `animation` prop with
`AnimatePresence` was really inspiring.
For the the first time I feel like building and shipping _an actually beautiful,
cross platform app, without needing huge funding_ is within reach. That's cool.
🍻
---
### Acknowledgements
This release once again is inspired by or forks code from a variety of other
libraries and developers.
I'd like to thank:
- [Fenando Rojo](https://twitter.com/fernandotherojo) and
[Moti](https://moti.fyi) for the elegant reanimated animation driver that
served as the starting point of `@hanzogui/animations-reanimated`, as well as
for putting together [Solito](https://solito.dev) that powers the first
template in create-gui.
- [Matt Perry](https://twitter.com/mattgperry) and
[Framer Motion](https://github.com/framer/motion) for the base of
AnimatePresence in `@hanzogui/animate-presence`.
- [Radix](https://www.radix-ui.com) for their rad quality, the innovative
composing components API's, and `asChild`.