One Choice over the action ids; the probability distribution is the order, so a single question ranks the whole menu. Reordering a menu fights muscle memory, which is what pinTop is for — toggle it and watch the first two slots stop moving.
instructions · backticked paths scope what it readspick prop// app/providers.tsx — the state every question on this page receives
<JevProvider
resolve={askJev}
scope={{ app: { product: "Northwind Analytics", user: "ana", role: "analyst", familiarity: "returning" } }}
initialAmbient={{ recent_actions: [], time_spent: "short" }}
>'use client';import { Rank, useJev, type DecisionCost } from 'jev-ui';import { useState } from 'react';// … demo scaffolding — answer panel and the menu catalogueexport function DropdownDemo() { const { setState, state } = useJev(); const [situation, setSituation] = useState(SITUATIONS[0]!); const [protectOrder, setProtectOrder] = useState(true); const [cost, setCost] = useState<DecisionCost | undefined>(); const { pick, ask } = usePick(); function choose(next: (typeof SITUATIONS)[number]) { setSituation(next); // Absolute, not appended: a deterministic action log keeps fixtures replayable. setState({ recent_actions: next.recent }); } return ( <> <section className="card" data-testid="demo-live" style={{ display: 'grid', gap: 14 }}> // … the controls that drive the demo <div style={{ fontSize: 13, color: 'var(--muted)' }} data-testid="dropdown-recent"> recent: {(state.recent_actions ?? []).length > 0 ? (state.recent_actions ?? []).join(' → ') : '(nothing yet)'} </div> <Rank id="menu_order" items={ACTIONS} idOf={(action) => action.id} labelOf={(action) => `${action.label} — ${action.hint}`} mode="compete" pinTop={protectOrder ? 2 : 0} pick={undefined} // every channel — the default ← set by the controls above onResolved={setCost} ask="Which of these menu actions is the user most likely to want next, given what they just did in `recent_actions`?" ← set by the controls above > {(ranked, meta) => ( <ol data-testid="menu" data-status={meta.status} style={{ margin: 0, paddingLeft: 20 }}> {ranked.map((entry) => ( <li key={entry.id} data-testid={`menu-item-${entry.id}`} style={{ marginBottom: 4 }}> <span style={{ fontWeight: entry.pinned ? 400 : 600 }}>{entry.item.label}</span> {entry.pinned ? ( <span style={{ fontSize: 11, color: 'var(--muted)' }} data-testid={`pinned-${entry.id}`}> {' '} · pinned </span> ) : null} <span style={{ fontSize: 11, color: 'var(--muted)' }}> · {entry.score.toFixed(3)}</span> </li> ))} </ol> )} </Rank> </section> // … omitted </> );}