mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Replace the first-run placeholder seed with an onboarding canvas
This commit is contained in:
@@ -94,6 +94,8 @@ preview, and have it survive reload. Single source kind: inline-data specs only
|
||||
- `stores/SnippetStore.ts` — `useSnippetStore` with `snippets`, `activeSnippetId`,
|
||||
selector-derived `activeSnippet`; load-on-startup; create/select/delete/update actions
|
||||
(debounced auto-save of edits, spec §03B). Seed one sample snippet on first run.
|
||||
_(Superseded later: an empty library now shows the onboarding canvas instead of a
|
||||
placeholder seed — spec §02 → First-Run & Empty Workspace.)_
|
||||
- `components/SnippetLibrary.tsx` — list + "Create New" pinned item + select/delete.
|
||||
- `components/SpecEditor.tsx` — Monaco JSON editor bound to active snippet's spec;
|
||||
debounced write-back to the store. (Worker wiring via Vite `?worker` imports —
|
||||
@@ -111,7 +113,9 @@ preview, and have it survive reload. Single source kind: inline-data specs only
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- Fresh load seeds a sample snippet that renders a bar chart.
|
||||
- Fresh load shows the onboarding canvas (welcome + Create + live example gallery);
|
||||
Create or an example's Add lands you in the editor with a rendered chart. _(M1 originally
|
||||
seeded a sample snippet; replaced by the onboarding canvas — spec §02.)_
|
||||
- Type in the editor → preview updates after the debounce; bad JSON → editor keeps
|
||||
working, preview shows an error, recovers when fixed.
|
||||
- Reload → snippets and selection persist.
|
||||
|
||||
@@ -265,15 +265,38 @@ default Modified/desc); search is **not** persisted (it's a transient view narro
|
||||
_(Consulted via /council → WAI-ARIA APG disclosure + menu-button, NN/g #6. This bullet is the
|
||||
contract; cite it, not the source.)_
|
||||
|
||||
**Resolved — the two library empty states (Carbon's two types).** The snippet list owes
|
||||
**two distinct empty states** (Carbon empty-state types), chosen by cause and never conflated:
|
||||
(a) a **genuinely empty library** (first run) is **positive and concise and guides to the
|
||||
Create action** — title "No snippets yet" + a one-line nudge to create one; (b) **no search
|
||||
matches** says "No snippets match your search" + a hint to try a different term. Both are
|
||||
plain-language and minimal (NN/g aesthetic-and-minimalist; §3 empty ≠ error). The library
|
||||
derives **which** to show from whether a query is active, not from the raw count alone.
|
||||
_(Consulted via /council → Carbon empty-state, NN/g. This bullet is the contract; cite it,
|
||||
not the source.)_
|
||||
**Resolved — the empty-library onboarding canvas (and the list's single empty state).** The
|
||||
snippet list owes **one empty state**: **no search matches** — "No snippets match your search"
|
||||
|
||||
- a hint to try a different term. There is **no separate "empty library" list state**, because
|
||||
a genuinely empty library never shows the list at all: rather than seeding a placeholder
|
||||
snippet (the old behavior), the workspace replaces the **entire pane chrome — toggle strip,
|
||||
library list, editor, and preview — with a full-width onboarding canvas** (spec §02 →
|
||||
First-Run & Empty Workspace): with no snippets, the library controls and pane toggles have
|
||||
nothing to act on. (So the list's own empty copy is reached only mid-search, never on a cold
|
||||
start.) The canvas is a welcome, a primary "Create your first
|
||||
snippet", and a gallery of example snippets; leaving it (creating the first snippet) lays the
|
||||
panes out at a default **25·25·50** split via `PanesStore.applyOnboardingSplit` so the first
|
||||
chart opens with a generous preview. Each card
|
||||
**renders live through the shared `chart-renderer`** (no parallel embed path; each card owns
|
||||
its `RenderHandle` and finalizes on unmount — the per-card nodes are independent, so they
|
||||
don't touch `LivePreview`'s single-host serialization), and adds as an ordinary snippet.
|
||||
Empty stays calm and positive, never an error (NN/g aesthetic-and-minimalist; §3 empty ≠
|
||||
error). Council resolutions for the canvas: (1) **each card preview is decorative** —
|
||||
`aria-hidden`, skipped by screen readers (Carbon empty-states a11y / WCAG decorative
|
||||
images); the card **name + one-line description + a uniquely-labelled `Add` button** ("Add
|
||||
Bar chart", APG button) carry the meaning, so AT users reach no dead end. (2) The canvas is
|
||||
the **single empty surface** — because it replaces the library list outright, there is no
|
||||
competing "No snippets yet" status elsewhere to keep in sync. Its heading **owns the app
|
||||
identity** ("Welcome to Astrolabe") and it carries the only Create nudge, so the empty-state
|
||||
message lives in exactly one place (Carbon "keep words to a minimum"; no duplication).
|
||||
(3) The **primary action dominates** (accent "Create your first snippet" first; the example
|
||||
gallery is framed as a secondary "Or start from an example") — Carbon sanctions starter
|
||||
content as an in-depth first-use empty state only when one action stays primary. (4)
|
||||
**Domain vocabulary stands**: "Vega-Lite", "JSON", "snippet" are kept despite Carbon's
|
||||
avoid-jargon rule, because SOUL #2 (Vega-Lite Native) makes them the user's real language —
|
||||
a deliberate divergence. _(Consulted via /council → Carbon empty-state + content, GOV.UK
|
||||
headings, WAI-ARIA APG button, NN/g. This bullet is the contract; cite it, not the source.)_
|
||||
|
||||
**Resolved — one live region per shared message.** When the same error feeds two surfaces
|
||||
(the §1 "one producer, two subscribers" case — render errors via `PreviewStore`), exactly
|
||||
|
||||
@@ -136,8 +136,9 @@ and is tested (e.g. `storage-estimate.test.ts`), so M6 is wiring, not building f
|
||||
keyboard router, URL routing w/ back-forward, toasts, modal system all present. Gaps:
|
||||
About/Donate modals (deferred), toast fade-out (partial), Settings-modal drift.
|
||||
- **§02 Snippet Library — partial.** List, list-item (status + linked datasets), metadata
|
||||
panel (rename/comment/timestamps), create/duplicate/delete, naming, first-run seed all
|
||||
done. Deferred: search, sort UI+persistence, dual empty states, storage monitor.
|
||||
panel (rename/comment/timestamps), create/duplicate/delete, naming, first-run onboarding
|
||||
canvas (welcome + example gallery, replacing the old placeholder seed), and the list's
|
||||
no-search-matches empty state all done. Deferred: search, sort UI+persistence, storage monitor.
|
||||
- **§03 Editor — mostly complete.** Draft/Published, auto-save, debounced auto-render,
|
||||
publish/revert + confirm, inline errors, Extract-to-Dataset all working. Gap:
|
||||
auto-reformat-on-type (**missing**, see above).
|
||||
|
||||
@@ -10,8 +10,21 @@ The list shows every saved snippet and is always visible. A persistent "Create N
|
||||
- A "Create New Snippet" item is pinned at the top of the list; activating it creates and selects a new snippet (see _Snippet Operations_).
|
||||
- Selecting a snippet makes it the **active snippet**: it loads into the editor and preview, becomes highlighted in the list, and the URL updates to reflect the selected snippet so the state is shareable and survives a page reload (see _Application Shell & Navigation_).
|
||||
- Exactly one snippet is active at a time.
|
||||
- When no snippets match the current search, the list shows an empty-state message ("No snippets match your search", with a hint to try a different term); when there are genuinely no snippets, it shows "No snippets yet" with a nudge to create one.
|
||||
- On first run, when no snippets exist, the app seeds one sample bar-chart snippet so the user starts with a working example.
|
||||
- When no snippets match the current search, the list shows an empty-state message ("No snippets match your search", with a hint to try a different term). This is the list's only empty state: a genuinely empty library never shows the list at all (see next).
|
||||
- When the library is empty (first run, or after the last snippet is deleted), the workspace presents a full-width **onboarding canvas** in place of the panes — including the library list — rather than seeding placeholder content (see _First-Run & Empty Workspace_).
|
||||
|
||||
## First-Run & Empty Workspace
|
||||
|
||||
When the library is empty — on first run, or after the user deletes their last snippet — the app does **not** seed placeholder content. Instead the **onboarding canvas takes the full workspace**, replacing the pane chrome (the pane toggle strip, the library list, the editor, and the preview): with no snippets, the library's create/search/sort/storage controls and the pane toggles have nothing to act on, so the welcome gets the whole width. The user starts from a deliberate choice rather than dropped into the middle of an unfamiliar spec.
|
||||
|
||||
- The canvas briefly identifies what Astrolabe is, then offers two ways to begin.
|
||||
- **Create your first snippet** — the primary action; starts a new snippet from the sample bar-chart template and opens it in the editor (identical to _Create New_ under _Snippet Operations_).
|
||||
- An **example gallery** of a few simple snippets showcasing distinct Vega-Lite capabilities (e.g. a bar chart, a time-series line, a scatter plot, a stacked area, a donut, a binned histogram). Each example shows a **live preview** of the chart and a one-line description.
|
||||
- **Add** on an example creates it as an ordinary snippet and makes it active (opening it in the editor).
|
||||
- **Add all** creates the whole set at once and makes one of them active.
|
||||
- Added examples are **ordinary snippets**: meaningfully named (not auto-generated timestamps), and thereafter editable, duplicable, and deletable like any other — they are the user's, not a special class (_own your data_).
|
||||
- Leaving the canvas by creating the first snippet(s) lays the workspace out at a sensible **default split** (library · editor · preview ≈ 25 · 25 · 50) with all three panes shown, so the first chart opens with a generous preview rather than the generic remembered widths.
|
||||
- The onboarding canvas is shown **only while the library is empty**; as soon as any snippet exists, the normal panes return. Re-emptying the library brings it back.
|
||||
|
||||
## List Item
|
||||
|
||||
|
||||
Reference in New Issue
Block a user