Lynx/Modules/Zero/ZeroRoot
@sigx/lynx-zero · Beta · Component library

ZeroRoot#

The one wrapper an app needs: the theme host with the overlay outlet inside it. Dialog, Popover, Select and Toast render into that outlet.

Import#

TSX
import { ZeroRoot } from '@sigx/lynx-zero';

Basic usage#

Wrap the app, or each screen, once:

TSX
import '@sigx/lynx-zero-daisyui';
import '@sigx/lynx-zero-daisyui/css/index.css';
import { component } from '@sigx/lynx';
import { ScrollView, ZeroRoot } from '@sigx/lynx-zero';

export const App = component(() => () => (
    <ZeroRoot light="light" dark="dark">
        <ScrollView flex={1}>
            {/* screens */}
        </ScrollView>
    </ZeroRoot>
));

ZeroRoot renders a ThemeProvider around an OverlayHost. Your content comes first and the overlay outlet comes last, because Lynx stacks by document order and has no z-index.

Why overlays need it#

Lynx has no top layer. An overlay rendered in place would be clipped by any ancestor that clips, and covered by anything later in the document. So Dialog, Popover, Select and Toast register a render closure with the nearest outlet (useOverlayPortal), and the outlet renders them at the end of the page.

  • The outlet is a position: fixed layer, which Lynx attaches to the page root. A modal backdrop dims the whole window, including the status-bar and home-indicator strips, even when ZeroRoot sits inside a SafeAreaView, below a navigation header, or in a navigation stack that clips its screens.
  • ZeroRoot's own box is the safe frame. The dialog panel centers in it, toast viewports pin to its edges, and anchored popups flip and clamp inside it, so they never land under a header or in a system-bar strip.
  • The outlet passes touches and pans through to the page when they miss every overlay. A Popover or Select closes on a tap outside it, and a pan beside it scrolls the page. A Dialog backdrop holds the pan.
  • Overlays stack in the order they open, and a light-dismiss closes the innermost one first.

Without a ZeroRoot above them, the overlay components warn in development and render nothing.

To build an overlay of your own on the outlet, see custom overlays.

Props#

ZeroRootProps is ThemeProviderProps. Every prop is passed to the inner ThemeProvider:

PropTypeDescription
initialThemeNamePins this theme, ignoring the system scheme until followSystem().
lightThemeNameTheme while the system is light. Defaults to the registry's light default.
darkThemeNameTheme while the system is dark. Defaults to the registry's dark default.
fontScalenumberInitial in-app text-scale multiplier.
classstringExtra classes on the theme host.
styleRecord<string, string | number>Extra inline style on the theme host.

Slots#

SlotDescription
defaultThe app content. It renders before the overlay outlet.

Without the theme host#

If a ThemeProvider already wraps the tree, render OverlayHost inside it instead of a second ZeroRoot:

TSX
import { OverlayHost, ThemeProvider } from '@sigx/lynx-zero';

<ThemeProvider>
    <OverlayHost>{/* content */}</OverlayHost>
</ThemeProvider>;

See also#

  • Overlays: the outlet, the safe frame and custom overlays in depth.
  • ThemeProvider: the theme host on its own.