Skip to content

Voice widget: compact rows (Direction B) — preview vs cards (#407)#409

Closed
Devon-White wants to merge 6 commits into
devin/1781277017-voice-widget-refinementsfrom
devin/voice-widget-rows
Closed

Voice widget: compact rows (Direction B) — preview vs cards (#407)#409
Devon-White wants to merge 6 commits into
devin/1781277017-voice-widget-refinementsfrom
devin/voice-widget-rows

Conversation

@Devon-White

@Devon-White Devon-White commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

@Devon-White Devon-White force-pushed the devin/voice-widget-rows branch from 194bf1e to 7cf63f3 Compare June 15, 2026 12:55
@Devon-White Devon-White changed the base branch from Devon/call-widget to devin/1781277017-voice-widget-refinements June 15, 2026 12:55
@Devon-White Devon-White force-pushed the devin/voice-widget-rows branch from 7cf63f3 to 8d076a4 Compare June 15, 2026 13:00
Add a compact-ROWS preview of the TTS voice browser, a sibling to the
cards (Direction A) that reuses the cards' shared foundation rather than
forking it. New component fern/components/voice-widget-rows renders a
bordered, rounded list of hairline-divided two-line rows (ElevenLabs
voice-picker style): cleaned name + sample-text info tooltip over a muted
plain-middot meta line (language · gender · provider · model), 38px ghost
play button with equalizer when playing, labeled "Copy config".

Reuse mechanism: export the data layer + display-time helpers from
voice-widget/index.tsx (loadBundle/bundleCache, the Row type, cleanName,
friendlyLanguage, normalizeGender, normalizeModel, modelKeyOf, the
no-preview/allowlist/lock baseRows filtering inputs, plus the shared
Select/uniq/pageNumbers/useIsMobile and page-size constants) and import
them into the rows. The rows implement only the row rendering, the row
skeleton, and the thin filter/group/page orchestration glue.

- Model is the neutral inline-<code> (--code-bg + --fg-secondary, never
  --code-fg) so it doesn't read as the accent-colored Copy link.
- Provider always shown in the meta; the provider prop hides the provider
  filter + personalizes the title (reused foundation behavior).
- Skeleton rows in the same list container at matching row height (59px
  per row incl. divider) → verified zero layout shift; fade/rise-in and
  equalizer/shimmer reduced-motion-gated.
- Theming light+dark (accent flips blue↔turquoise, model stays neutral),
  list semantics (<ul role=list> → <li> → <article aria-label>), play/copy
  aria-labels, focusable aria-describedby tooltip, :focus-visible rings,
  AA-contrast muted labels via --fg-secondary, single-column mobile.
- Styles scoped under .vw.vw-rows and self-contained so they neither
  depend on nor collide with the cards' globally-loaded stylesheet.

Register VoiceWidgetRows in the components barrel + add its css to
docs.yml, and swap the TTS index + provider subpages to embed it (same
props) so the deployed preview shows the rows.
- Move the info trigger out of the name block to the right, just left of Copy (room there).
- The list's overflow:hidden was clipping the popover (esp. row 1, where it opens above the
  list). Switch the list to overflow:visible and round the first/last rows so the on-hover
  corners still follow the container — mirrors the cards (card overflow:visible, grid never clips).
- Right-anchor the popover (+ caret) so, from its new right-side position, it extends leftward
  into the row and never spills off the right edge.

(Fern's <Tooltip>/<Icon> are not importable in custom components — confirmed no @fern-* package —
so this is our own popover, same as the cards; the bug was the list clip, not the component.)
…n fonts (match cards)

- Drop the row's hover/focus z-index. It made the row a stacking context above the sticky toolbar
  (z-index:2), so a row scrolled partly under it painted OVER it on hover. The row stays below the
  toolbar; the sample-text popover (z-index:30) still escapes above it on its own (verified in a
  faithful repro — the rows root has no container-type, and the popover still beats the toolbar).
- Inherit the docs body font (Lexend + fallbacks) instead of system-ui, which tofu'd non-Latin
  voice names (Arabic, Amharic/Ethiopic) on Firefox.
…Latin names

The docs body font (Lexend, Latin-only) can't render the catalog's ~190 non-Latin
names across ~24 scripts; Firefox then falls back to the system font list and tofu's
on any script the OS lacks. Load Noto through the Google Fonts CSS API (one @font-face
per script, each with its own unicode-range) so only the slices whose glyphs appear
download — no build-time knowledge of the runtime CDN catalog needed. Wired into
--vw-i18n-font (body font first so Latin stays Lexend) and scoped to .vw-name/.vw-tooltip.
Adds lang attributes for screen-reader pronunciation + language-appropriate glyphs.
Mirrors the cards fix.
Drop the normalizeModel import + call now that the cards module no longer remaps model
names; render r.model as-is.
…rds)

Same fix as the cards: the ▶/■ characters are emoji-capable and render as an OS color emoji
on some platforms. Use inline SVG IconPlay/IconStop (currentColor-filled); equalizer animation
unchanged.
@Devon-White

Copy link
Copy Markdown
Collaborator Author

Superseded by #414, which ships the rows design as a single clean PR off main (card design dropped per the design decision). The work here is folded into #414.

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