Skip to content

Let the host control which page EsheetRenderer is showing #147

Description

@horner

Problem

EsheetRenderer keeps the active page in local component state:

// packages/renderer/src/lib/components/RendererBody.tsx
const [currentPagesIdx, setCurrentPagesIdx] = React.useState(0);

Nothing outside the renderer can read or set it. EsheetRendererProps has no
pageId/pageIndex/initialPage, EsheetRendererHandle has no page getter or setter,
and getUIStore() doesn't expose it either.

Why this matters

We're using a multi-page FormDefinition as a tabbed record UI — one page per tab, with
topNavigation drawing the tab strip. That works nicely, and it means adding a tab is a
config commit rather than an app change.

But the host can't participate in navigation at all. Concretely, we had to drop a
"recently visited pages" dropdown, because there is no way to say "go to the Diagnosis
page". The same gap blocks:

  • deep links / restoring the last-viewed page from a URL or localStorage
  • a host-owned "jump to page" control anywhere outside the renderer
  • analytics or presence that needs to know which page a user is on
  • programmatically landing on a specific page after a search hit

Suggested API

Something small and conventional would cover all of the above — either a controlled pair:

<EsheetRenderer
  formDataInput={form}
  pageId={activePageId}
  onPageChange={setActivePageId}
  topNavigation
/>

…or, if a controlled prop is too invasive, exposing it on the existing imperative handle:

export interface EsheetRendererHandle {
  // ...
  getCurrentPageId: () => string | null;
  setCurrentPage: (pageIdOrIndex: string | number) => void;
}

The handle version is probably the smaller change and is enough for our case. An
onPageChange callback would still be useful on its own, since today the host has no way
to observe navigation either.

Happy to send a PR if you'd like — just say which shape you prefer.

Version

@esheet/renderer@0.0.5

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions