Skip to content

feat(embed): ss:aside-empty slot + native empty-sidebar affordance#144

Merged
benvinegar merged 2 commits into
mainfrom
feat/aside-empty-slot
Jun 25, 2026
Merged

feat(embed): ss:aside-empty slot + native empty-sidebar affordance#144
benvinegar merged 2 commits into
mainfrom
feat/aside-empty-slot

Conversation

@benvinegar

Copy link
Copy Markdown
Member

What

The sidebar session list was blank when no sessions existed. It now shows a lightweight native "Connect an agent" row — the first item of an otherwise-empty list — with a plug icon and one muted helper line (Your sessions will appear here once an agent connects.). Clicking it scrolls to the empty-board pane (ss:empty) that holds the connect instructions.

This is wrapped in a new host-overridable ss:aside-empty slot, same pattern as ss:empty / ss:aside-foot:

  • Self-hosted gets the native affordance via the slot fallback (nothing projected -> fallback renders).
  • Embedders project a slot="ss:aside-empty" child to replace the fallback with their own empty-list nudge.
  • Once a session exists, neither renders — the normal list shows as before.

Look & feel

Reuses the existing .sess row chrome (padding / radius / cursor / hover) so it is visually indistinguishable from a real list row — no border, no box, no CTA button. 13px label in the primary text color, a 16px plug icon in the accent color, and a 12px helper line in the tertiary text token. Flat, sentence case, theme-token colors (light + dark). Generic fallback — no deployment-specific copy or links.

Changes

  • viewer/src/host.ts — register asideEmpty: "ss:aside-empty" in SLOTS (auto-derives SlotName).
  • viewer/embed.d.ts — re-export the new slot for typed embedder consumers.
  • viewer/src/icons.tsx — add a Lucide plug icon (PlugIcon), matching the existing inline icon set.
  • viewer/src/App.tsx — wrap the session list empty region in <slot name={SLOTS.asideEmpty}> with an AsideEmptyRow fallback, gated on initialLoaded() && sessions.length === 0 (matches #onboard's no-flash gating).
  • viewer/src/styles.css — minimal, token-based styles for the icon/label/helper; the row itself is .sess.
  • e2e/embed-aside-empty-slot.spec.ts — three chromium scenarios: (a) fallback renders with nothing projected, (b) projected content replaces the fallback through the shadow boundary, (c) neither renders once a session exists.

Validation

  • npm run lint — green
  • npm run format:check — green
  • npm run typecheck — green (node + workers + viewer)
  • npm test — green (256/256)
  • npm run build — green (viewer + embed bundles)
  • npm run test:e2e — chromium green (3/3 new tests). WebKit is blocked in this environment by missing system libs (libicu74 / libxml2 / libflite1); this is pre-existing and affects the existing embed-slots.spec.ts webkit run identically (no passwordless sudo to install them).

Changeset

minor — new slot + user-visible affordance.

Add a host-overridable ss:aside-empty slot for the sidebar's empty state.
When the session list is empty (post-load), it now shows a lightweight native
'Connect an agent' row — the first item of an otherwise-empty list — with a
plug icon and one muted helper line, instead of a blank list area. Clicking it
scrolls to the empty-board pane (ss:empty) holding the connect instructions.

The row reuses .sess row chrome (padding/radius/cursor/hover) so it reads as a
real list row; an embedder projects a slot="ss:aside-empty" child to replace
the fallback with its own nudge. Once a session exists, neither renders.

- Register asideEmpty in SLOTS / SlotName and re-export in embed.d.ts.
- Add lucide plug icon; gate the slot on initialLoaded() && no sessions.
- e2e: fallback renders, projection replaces it, neither renders with a session.
…on style

- Hide the native 'Connect an agent' fallback when readonly (matches the
  footer connect link and the 'Nothing here yet' readonly empty pane); the
  slot itself stays mounted so embedders can still project a readonly nudge.
- Comment the #onboard scrollIntoView no-op when ss:main is projected.
- Align e2e assertion with the reference test (toBeHidden) and type the
  serveEmbed helper's page param.
@benvinegar benvinegar merged commit 3046bc9 into main Jun 25, 2026
9 checks passed
@benvinegar benvinegar deleted the feat/aside-empty-slot branch June 25, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant