I found the UI demo script to be the most helpful.
It sounds like you’re asking specifically about UI.Pages. If so: it does nothing other than draw little lines on the right edge of the screen, one of which will be highlighted. You initialize it with two numbers: pages = UI.Pages.new(selected_page, num_pages), then you update which little line is highlighted via pages:set_index (or pages:set_index_delta, which makes it easy to map the delta from enc(n, delta) to your page). You can read out which index is selected via pages.index. That’s it, that’s the whole thing. Typically what you’ll do in parallel is change what content you render on the screen based on pages.index. Perhaps you’ll have an array of lua objects each representing a screen, and you’ll use pages.index to look up which one you should delegate to for rendering. Maybe you’ll have some other system
up to you! If you’d like, you can take a peek at how my app does it here: https://github.com/21echoes/pedalboard/blob/master/pedalboard.lua#L115 look for usages of pages (the UI.Pages instance), pages_table (the array of lua objects that are the actual page look and behavior), and their related functions (current_page, pages_table[i]:redraw(), pages_table[i]:enc(n, delta), pages_table[i]:key(n, z), etc.). I also read the Passersby script a lot when I was first getting the hang of it – It does a lot less separate-classes/abstraction stuff than mine, and may be a bit easier to follow.
“Shifting focus” is more typically done with UI.Tabs, which imply more than one on the screen at a time. It’s superficially similar to Pages, but rather than just a number for the active one and a number for the total, you give it an array of strings that render as titles for separate horizontal sections of your screen. But, like UI.Pages, that’s… about it. How you choose to use tabs:set_index or :set_index_delta is up to you! My app does it with K2/K3 so I could use E2/E3 for controlling the content of each tab, but different apps take very different approaches. UI.Tabs also has no notion of the content “inside” the tab (other than the title), so you’ll, like pages_table, likely want some parallel data structure that manages the tab content and behavior. My approach was a render_tab_content(index) function which calculated the bounds of the tab and delegated rendering to other objects, providing the x_offset and width to them to alter their implementation as needed.