Siblings
Views opened from the same parent are siblings. Zumly moves between them sideways, without zooming out first.
Open a zone and move between zones with the arrows or the dots. Then open an animal: the bar now moves between the animals of that zone. The round button at the bottom left zooms out one level.
The code
// A zone opens on its animals; each animal is a small card
const zone = (id, title, animals) => `
<div class="z-view zone ${id}" data-title="${title}">
<h2>${title}</h2>
<div class="row">${animals.map(([to, name]) =>
`<div class="zoom-me peek-animal" data-to="${to}">${name}</div>`).join('')}</div>
</div>`
const animal = (name, fact) => `
<div class="z-view animal" data-title="${name}"><h2>${name}</h2><p>${fact}</p></div>`
const app = new Zumly({
mount: '.canvas',
initialView: 'ocean',
views: {
ocean: `<div class="z-view ocean" data-title="Ocean">
<h1>Three zones of the ocean</h1>
<div class="row">
<div class="zoom-me peek-zone sunlight" data-to="sunlight">Sunlight</div>
<div class="zoom-me peek-zone twilight" data-to="twilight">Twilight</div>
<div class="zoom-me peek-zone midnight" data-to="midnight">Midnight</div>
</div>
<!-- Opens a view, but is not one of the zones -->
<div class="zoom-me about" data-to="about" data-sibling="false">About</div>
</div>`,
about: `<div class="z-view note" data-title="About"><p>Zones split the ocean by how much sunlight reaches them.</p></div>`,
sunlight: zone('sunlight', 'Sunlight zone', [['turtle', 'Turtle'], ['tuna', 'Tuna']]),
twilight: zone('twilight', 'Twilight zone', [['lanternfish', 'Lanternfish'], ['squid', 'Squid']]),
midnight: zone('midnight', 'Midnight zone', [['anglerfish', 'Anglerfish'], ['gulper', 'Gulper eel']]),
turtle: animal('Turtle', 'Breathes air, dives for hours.'),
tuna: animal('Tuna', 'Swims across whole oceans.'),
lanternfish: animal('Lanternfish', 'Glows to hide its shadow.'),
squid: animal('Squid', 'Rises to the surface at night.'),
anglerfish: animal('Anglerfish', 'Brings its own light.'),
gulper: animal('Gulper eel', 'A mouth bigger than its body.')
},
// A horizontal swipe also moves to the next or previous sibling
lateralNav: { swipe: true }
})
app.init()
Who counts as a sibling
The siblings of a view are the views of the other triggers in its parent. Inside Twilight zone they are the three zones, because the ocean has three zone triggers. Inside Squid they are Lanternfish and Squid, because those are the triggers in Twilight zone.
- Each level has its own group. Zoom in and the bar shows the siblings of the new level; zoom out and it shows the ones above again. You never configure levels.
- Order follows the layout. Siblings come in the order of their triggers, and the slide goes the way they sit: Midnight is to the right of Twilight, so it slides in from the right.
- Leave a trigger out with
data-sibling="false". The About button opens a view, but it is not a zone, so it gets no dot.
Two controls, two directions
| Control | Looks like | Does |
|---|---|---|
Back button (depthNav) | A dot in a ring, bottom left | Zooms out one level |
Sibling bar (lateralNav) | Arrows and dots | Moves sideways, same level |
The bar shows whenever the current view has siblings. With swipe: true, a horizontal swipe moves between them too; where there are none, a swipe left still zooms out.
Both controls, their options and how to replace them are in Navigation controls.
Back after moving sideways
back(), and the browser back button when you use the router, undo what you did, in order. Each level remembers its own sideways moves:
| You did | back() takes you to |
|---|---|
| Twilight → Midnight (sideways) | Twilight |
| Twilight → Midnight → Anglerfish (in) | Midnight, then Twilight, then the ocean |
The back button, a click on the dimmed parent, the wheel and ArrowLeft are different: they always zoom out, whatever you did sideways.
Setting the order yourself
When the layout does not say the order, or a parent has triggers that belong to different groups, list the siblings per parent view:
lateralNav: {
siblings: {
ocean: ['sunlight', 'twilight', 'midnight'],
twilight: ['lanternfish', 'squid']
},
keepAlive: true // siblings you leave stay in the DOM: form fields and scroll survive
}
A parent that is not in the map keeps the automatic group.
One view, many siblings
Triggers can open the same view and tell it apart with their data. Each one is its own sibling: it gets its own dot, named by its data-title, and the view receives that trigger's data as props, whether you click, use the bar, swipe or go back.
<div class="zoom-me" data-to="room" data-id="kitchen" data-title="Kitchen">Kitchen</div>
<div class="zoom-me" data-to="room" data-id="bedroom" data-title="Bedroom">Bedroom</div>
views: {
room: ({ props }) => `<div class="z-view"><h2>${props.title}</h2></div>`
}
From code, pick the sibling by its data: app.goTo('room', { mode: 'lateral', props: { id: 'bedroom' } }). With the router the hash keeps it too: #/house/room?id=kitchen. In a declared order, name it the same way: 'room?id=kitchen'.