Codelet logoCodelet

Small screens

What the workbench does differently under a 640px viewport, and the helpers that answer the same question your own code can ask

The workbench's narrow layout is CSS, server-rendered along with everything else — there's nothing to turn on and nothing that flashes the wide layout first. isMobile(), mobileQuery and onMobileChange() are exported from both codelet and codelet/workbench, for code of your own that wants to ask the same question.

import { isMobile, mobileQuery, onMobileChange } from "codelet/workbench";

isMobile(); // true under a 640px viewport, false anywhere without a DOM
mobileQuery; // "(max-width: 640px)" — the media query itself

const stop = onMobileChange((mobile) => {
  console.log(mobile ? "narrow now" : "wide now");
});

isMobile() is a viewport check, not a device check — what matters is the room the chrome has, not whether the reader is holding a phone. It answers false on the server, so a server-rendered page always assumes the wide layout until the client's own media query says otherwise.

#What changes

  • One thing at a time. The sidebar and the secondary side bar become full-width sheets over the editor instead of columns beside it. Opening a file closes whichever sheet was open.
  • The activity bar moves to the foot as a labelled tab bar — one row of equal-width items, icon over name. Past the first few containers the rest collapse into one overflow item; the command palette takes a share of the row too, and the gear's own rows — the theme control, and whatever an extension contributed to it — go into that overflow rather than behind a second button.
  • The empty editor pane offers an "Open a file" button that opens the sidebar, since there's no persistent tree beside it to look at the way there is wide.
  • The editor's font size drops a point, from 13px to 12px, swapping live as the viewport crosses the breakpoint rather than being fixed at mount.

#Touch in the explorer

There's no HTML5 drag on a touch screen, so a hold on a row stands in for it: a press that stays put arms a drag, and a move before that cancels it as a scroll instead. The row's context menu isn't on the hold — reach it through a button per row (shown only narrow) or a second tap.

The tab strip works the same way: a hold on it arms drag-to-reorder, and a lift without a move opens the tab's context menu. A second tap within a short window opens that menu too, without needing to find the hold.