mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Add snippet-library search, sort, empty states, storage monitor (M6, §02/§09D)
This commit is contained in:
@@ -236,6 +236,45 @@ relative date and size), in a fixed-width leading slot so it never shifts adjace
|
||||
_(Consulted via /council → GOV.UK Tag, Carbon status-indicator-pattern, APG. This bullet is the
|
||||
contract; cite it, not the external source.)_
|
||||
|
||||
**Resolved — library search (Carbon active-search).** The snippet-library search (spec
|
||||
§02) is an **unlabelled active-search input** pinned above the list: `type="search"` with a
|
||||
leading magnifier and `aria-label="Search snippets"` (no visible label — the icon +
|
||||
placeholder name it), filtering the list on **each keystroke** (no Search button, no results
|
||||
page). A **clear (✕)** appears only when the box is non-empty; it empties the box **and
|
||||
returns focus to the input** (NN/g #3 user control). Matching is case-insensitive substring
|
||||
across **name + comment + draft spec text** (the pure `snippetMatchesQuery` in
|
||||
`core/snippet-sort.ts`). Search affects **visibility only** — it never changes
|
||||
`activeSnippetId` or any data. A **polite `aria-live` region announces the result count,
|
||||
including no results** (Carbon: _"always include the number of results, including no
|
||||
results"_); it stays silent for the default unfiltered list. _(Consulted via /council →
|
||||
Carbon search/active-search, NN/g #3. This bullet is the contract; cite it, not the source.)_
|
||||
|
||||
**Resolved — library sort (APG menu-button + NN/g recognition).** The Sort control (spec
|
||||
§02) reuses the **disclosure popover** primitive (the settings-popover model above), **not**
|
||||
an ARIA menu — but its trigger shows the **current state for recognition** ("Sort: Modified
|
||||
↓"), per NN/g #6 (recognition over recall), instead of a bare gear. Fields are **Modified /
|
||||
Created / Name / Size**; the active field shows a **direction arrow** (↓ desc / ↑ asc) in both
|
||||
the trigger and the field row, and the arrow's meaning is mirrored into the field's
|
||||
`aria-label` ("Modified, descending") so it isn't carried by the glyph alone. **Selection
|
||||
model** (spec §02): re-selecting the **active** field flips direction; selecting a
|
||||
**different** field switches to it and **resets to descending** — encapsulated in
|
||||
`SnippetStore.setSort` and tested in core. APG disclosure keyboard/focus is inherited from
|
||||
the shared popover (Enter/Space open; **Esc closes and returns focus to the trigger**; outside
|
||||
click closes; one open at a time). Field+direction **persist across sessions** (ux-prefs;
|
||||
default Modified/desc); search is **not** persisted (it's a transient view narrowing).
|
||||
_(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 — 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
|
||||
**one** subscriber is the live region (`role="alert"` on the editor, where focus is); the
|
||||
|
||||
@@ -10,7 +10,7 @@ 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"); when there are genuinely no snippets, it shows "No snippets found".
|
||||
- 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.
|
||||
|
||||
## List Item
|
||||
@@ -78,5 +78,5 @@ A small indicator at the bottom of the library shows how much of the snippet sto
|
||||
|
||||
- Displays current usage against the total budget (used vs. total), where the practical snippet budget is about 5 MB.
|
||||
- A fill indicator reflects the percentage used.
|
||||
- The indicator enters escalating warning states as usage climbs (a cautionary state past roughly 70% and a critical state past roughly 90%).
|
||||
- The indicator enters escalating warning states as usage climbs (a cautionary state past roughly 80% and a critical state past roughly 95%).
|
||||
- When storage is full, a save may fail; the system warns the user that the snippet could not be saved rather than silently losing data, so the user can delete snippets to free space.
|
||||
|
||||
Reference in New Issue
Block a user