Reading OrderLoading saved progress…

Reading Order

Implement readingOrder(elements) — take a list of absolutely-positioned boxes scattered on a canvas and return them in the order a person would read them: left to right, top to bottom. This is the order a screen reader announces a layout, the order "Tab" walks a form, and the order a serializer emits when it flattens a 2D design back into a 1D stream. Each input is a plain data object with coordinates — not a real DOM node — so there is no layout engine to lean on; the ordering is yours to compute from the numbers.

Signature

type Box = {
  id: string;     // a label so you can identify each box in the output
  top: number;    // distance from the top edge of the canvas, in pixels
  left: number;   // distance from the left edge of the canvas, in pixels
};

// Returns a NEW array containing the same box objects, ordered for reading.
// Does not mutate the input array or any box.
function readingOrder(elements: Box[]): Box[];

A box is a plain object. There may be other fields on it (width, text, …); you only sort by top and left.

Examples

// A 2x2 grid. Reading order goes across the top row, then the bottom row.
readingOrder([
  { id: 'D', top: 100, left: 100 },
  { id: 'B', top: 0,   left: 100 },
  { id: 'C', top: 100, left: 0   },
  { id: 'A', top: 0,   left: 0   },
]);
// → ids in order: ['A', 'B', 'C', 'D']
// Two boxes on the SAME row (equal top): the smaller left comes first.
readingOrder([
  { id: 'right', top: 50, left: 300 },
  { id: 'left',  top: 50, left: 20  },
]);
// → ids in order: ['left', 'right']
// Stacked in one column (equal left, different top): top-most first.
readingOrder([
  { id: 'bottom', top: 200, left: 0 },
  { id: 'top',    top: 0,   left: 0 },
]);
// → ids in order: ['top', 'bottom']

Notes

  • Primary key is top, secondary key is left. Sort by top ascending first; when two boxes share the same top, break the tie by left ascending. A box higher on the canvas always reads before a box lower down, regardless of horizontal position.
  • Return a new array; do not mutate the input. The caller may still need the original order. Building the result without disturbing elements is part of the contract.
  • Ties must be broken deterministically. Two boxes with the same top and the same left must always come out in the same relative order across runs — never randomly reordered.
  • Coordinates are plain numbers, not DOM nodes. You will not call getBoundingClientRect, read the DOM, or use any browser API. The whole problem is sorting numbers.
  • Don't worry about overlapping boxes, box sizes (width/height), or "almost-aligned" rows where tops differ by a pixel or two — those land in the harder follow-up, Reading Order II. Here, same-row means exactly equal top.
Loading editor…