View Switching
When your window has several peer pages and shows one at a time, put the pages in a view stack and give the user a switcher to pick between them. Five switchers are on this page: a segmented bar, the same bar pinned to the bottom edge for a narrow window, a strip of tabs, a compact toolbar control and a swipeable pager. All of them adapt to the window, so a wide desktop gets the full switcher and a narrow phone gets a collapsed one.
Each block below is a stack of windows. The first one RUNS the widget: the preview
is the live browser port, so it follows the light and dark toggle the way a real
window would, and the HTML tab beside it holds the very markup that paints it —
one import '@gjsify/adwaita-web' registers every element in it. Then comes
one window per kind of implementation — Native TypeScript, the @girs program
that runs unchanged on GJS, Node, Bun and Deno, with the matching Blueprint
declaration beside it, UI frameworks, the same widget written in Solid, Vue and
React through @gjsify/gtk-host — or, where the widget is built imperatively rather
than declared, the recorded reason it has no such snippet — and NativeScript,
the port that runs on a phone. That last window splits the way the first one does. An
XML template holds the tree, and the TypeScript beside it is the loader.
Libadwaita is the reference here, typed by
@girs/adw-1.
@gjsify/adwaita-web
and @gjsify/adwaita-nativescript
follow its naming, and where one of them differs, its own window says so.
View Switcher
Section titled “View Switcher”The standard switcher: one segmented control whose buttons each carry a page’s
icon and label, driving a paired view stack. Its policy decides the
button layout. wide puts the icon and label side by side; narrow stacks the
icon above the label so the bar fits a slim window. An adaptive layout normally
swaps between the two on a breakpoint.
View Switcher Bar
Section titled “View Switcher Bar”The narrow-window half of the same pattern. When the window is too slim for a
switcher in the header bar, put one at the bottom edge instead — that is a view
switcher bar, pinned into a toolbar view’s bottom slot and bound to the same
stack. reveal is a request, not a state: a stack with fewer than two pages
stays collapsed however loudly it is asked, so a bar over a one-page stack simply
does not appear.
Tab View
Section titled “Tab View”Reach for a tab view when the pages are not fixed. Unlike a view switcher, tabs are meant to be added, closed and reordered while the app runs. The tab bar draws one chip per page, each with a title and a close button, and raises the selected chip onto the view background. Turn on autohide and the bar disappears once a single page is left, so a one-tab document looks chrome-free.
Inline View Switcher
Section titled “Inline View Switcher”When a full switcher is too wide for the space, use the inline one. It is built from a linked toggle group and drives the same kind of view stack, but its display mode lets each toggle show labels, icons or both. That makes it fit a header bar or a tight toolbar.
Carousel
Section titled “Carousel”For onboarding screens and galleries, use a carousel: pages sit side by side and the user flicks, scrolls or clicks a page indicator to move between them. Two indicator widgets bind to a carousel, dots (shown here) and lines. Both track the fractional scroll position and grow the marker nearest the current page.
A carousel answers to three gestures. Touch and a touchpad scroll it
natively — the browser owns those, momentum and snapping included. A mouse
drag is the one the browser has no gesture for, so it is implemented: press
inside the carousel and pull, and the pages follow the cursor. Where it lands is
Adw.SwipeTracker’s decision, not the browser’s — the drag’s velocity is
projected and the nearest reachable page wins, so a short flick pages and a slow
half-drag settles back.
Three knobs are worth knowing. The scroll wheel pages the carousel by
default; set allow-scroll-wheel="false" to leave wheel events to the page
instead. Mouse drag is on by default; allow-mouse-drag="false" leaves
dragging to touch, as it does upstream. Long swipes are off by default; turn
them on to let one flick skip several pages — with the caveat that a touchpad
flick can already cross more than one page here. The setting is applied (each page
gets scroll-snap-stop: always when long swipes are off), but the browser does not
honour it for that gesture; GTK, which runs the same input through its own tracker,
does.
Related
Section titled “Related”- Navigation: pages, split views and the navigation stack the switchers sit above.
- Layout: the
Clampand boxes that size a switched view. - Adwaita Storybook: the same widgets in a live component browser you can poke at.