Skip to content

feat(docs): colocate component docs and redesign UX#634

Merged
netchampfaris merged 10 commits into
mainfrom
v1-release/docs-ux
May 18, 2026
Merged

feat(docs): colocate component docs and redesign UX#634
netchampfaris merged 10 commits into
mainfrom
v1-release/docs-ux

Conversation

@netchampfaris

@netchampfaris netchampfaris commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Docs UX overhaul. Four layers of change:

Authoring layout — colocate component docs

  • Each component owns its docs: src/components/<Name>/<Name>.md (hand-written) + <Name>.api.md (auto-generated by propsgen).
  • A small Vite plugin (docs/.vitepress/plugins/colocatedComponentDocs.ts) writes a thin @include proxy into docs/content/docs/components/<name>.md at config-load time so URLs are unchanged. Proxies are gitignored; legacy.md is preserved via a negation.
  • docs/scripts/propsgen.ts now emits <Folder>.api.md next to the component.

Component transformer — parse with Vue compiler instead of regex

  • componentTransformer.ts rewritten to use @vue/compiler-dom's baseParse for <ComponentPreview> / <PropsTable> tags. Attribute order no longer matters and :data is properly recognised as a directive.
  • Fixed a latent index-shift bug: the script-setup unshift was happening mid-loop, shifting every captured tokenIdx by +1. Imports are now collected during iteration and applied once after the loop.

Story layout — drop the css prop, default in Demo.vue, override in stories

  • <ComponentPreview> no longer accepts a layout-shaping prop (was css).
  • Demo.vue's preview area defaults to flex flex-wrap gap-3 items-center — covers 94 stories with no boilerplate.
  • 38 stories with a non-default layout add an explicit <div> wrapper. Grid overrides get <div class="grid …">; additive overrides (justify-center !py-20, h-screen overflow-hidden, !p-0) are self-sufficient and include the flex base.

Visual redesign

  • Sidebar: pill-style items, uppercase section headers, h-7 rows, homepage moved into the sidebar layout with Overview as the first item.
  • Hero: left-aligned split layout with Shiki syntax highlighting.
  • Showcase: CSS columns masonry layout, with fragment col files.
  • Search popup: redesigned as a command palette; later refactored to use reka-ui Listbox primitives.
  • Misc: removed page transition animation, added kbd Tailwind styles, fixed horizontal overflow from grid min-width default.

Test plan

  • yarn docs:build succeeds and renders all 38 component pages
  • yarn docs:dev serves colocated docs at unchanged URLs (/docs/components/<name>)
  • yarn docs:gen:all writes <Name>.api.md files next to their components, leaves docs/meta/ empty
  • Spot-check component pages with each layout category: default flex (Button), grid override (Alert-Themes), additive override (Breadcrumbs-Example, Calendar-Examples), Toast (no wrapper)
  • Search popup behaves as a command palette (keyboard nav, focus, escape)
  • Homepage and sidebar render correctly at desktop and mobile breakpoints

🤖 Generated with Claude Code

Coverage

Metric Coverage Δ vs main
Lines 44.04% (1889/4289) ±0.00%
Statements 38.96% (2001/5135) ±0.00%
Functions 39.83% (378/949) ±0.00%
Branches 29.42% (595/2022) ±0.00%

Baseline pulled from the latest successful main run.

@github-actions

github-actions Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

🚀 VitePress preview is ready:

https://ui.frappe.io/pr-preview/pr-634/

github-actions Bot added a commit that referenced this pull request Apr 24, 2026
coderabbitai[bot]

This comment was marked as outdated.

github-actions Bot and others added 6 commits May 17, 2026 23:11
- Redesign sidebar to pill-style items with uppercase section headers and h-7 row height
- Move homepage into sidebar layout with Overview as first item
- Redesign hero with left-aligned split layout and Shiki syntax highlighting
- Refactor showcase to CSS columns masonry layout with fragment col files
- Remove VitePress page transition animation
- Add `kbd` global styles to Tailwind plugin
- Fix horizontal overflow from grid min-width default

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces VitePress's MiniSearch-based doc-content search with a
focused page-navigation palette built on the frappe-ui Dialog:

- Sidebar list extracted to a shared module; search and sidebar now
  share the same source of truth and only sidebar entries are
  searchable (no doc content)
- Fuzzy matching via fuzzysort; results regrouped by sidebar section
- Client-side navigation via VitePress router; "Current" badge on
  the active page
- Cmd/Ctrl+Enter (or modifier-click) opens the result in a new tab
- Navbar z-index lowered so the dialog overlay sits above it

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Restore the dedicated home layout (no sidebar, centered hero, grid
  showcase) by reverting the relevant parts of the homepage redesign
- Drop the "Overview" link from the sidebar (only made sense when the
  homepage lived inside the sidebar layout)
- Move the dev-branch badge before the "Docs" link in the navbar so
  the layout reads naturally on the homepage

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace hand-rolled keyboard navigation, active-index state, and ARIA
wiring with ListboxRoot / ListboxFilter / ListboxContent / ListboxGroup
/ ListboxItem. Reka now owns roving focus, arrow-key navigation,
aria-activedescendant, role="option", and aria-selected; we keep only
the bits it can't infer:

- onItemSelect calls router.go() instead of letting reka commit a
  modelValue, so navigation is client-side
- onFilterKeydown intercepts Cmd/Ctrl+Enter — reka's synthetic click
  for keyboard Enter drops modifier flags, so we open in a new tab by
  reading the [data-highlighted] item ourselves
- Each item renders `as="a"` with an href, so Cmd/Ctrl+click opens a
  new tab natively

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move each component's docs page and auto-generated API table from
docs/content/docs/components/<name>.md + docs/meta/<Name>.md to
src/components/<Name>/<Name>.md + <Name>.api.md, so a component's
implementation, stories, types, and docs all live in one folder.

A small Vite plugin (colocatedComponentDocs.ts) writes a thin
@include proxy into docs/content/docs/components/ before VitePress
scans srcDir, so the existing URL structure is unchanged. Proxies
are gitignored; legacy.md (the only hand-written file left in that
dir) is preserved via a negation.

propsgen now emits <Folder>.api.md alongside the component.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the regex pair that drove ComponentPreview/PropsTable detection
with @vue/compiler-dom's baseParse. Attribute order no longer matters,
`:data` is now properly recognised as a directive rather than a magic
attribute name, and a malformed tag falls through cleanly instead of
silently mismatching.

Token mutation now walks state.tokens directly in reverse, and the
script-setup unshift is deferred until after the iteration loop —
doing it mid-loop shifted every captured tokenIdx by +1 and caused
writes to land on the wrong token (latent in the old code, surfaced
once Calendar.md's two previews were both routed through this path).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@netchampfaris netchampfaris changed the title feat(docs): redesign homepage and sidebar UX feat(docs): colocate component docs and redesign UX May 17, 2026
github-actions Bot added a commit that referenced this pull request May 17, 2026
@frappe frappe deleted a comment from coderabbitai Bot May 17, 2026
@netchampfaris

Copy link
Copy Markdown
Contributor Author

/barista review

@barista-for-frappe

Copy link
Copy Markdown

Re-reviewing per @netchampfaris — focused on correctness and API surface.

Concerns — one public-API side-effect in the Tailwind plugin.

  • tailwind/plugin.js (new kbd block in globalStyles) — sets fontFamily: 'inherit', which strips the browser-default monospace appearance from every kbd element in any consumer project that includes frappe-ui's Tailwind plugin. kbd has a well-understood semantic meaning (keyboard key); silently restyling it globally can affect consumer prose/documentation content. Consider scoping to a utility class (.kbd) or keeping fontFamily: monospace/unset if the intent is purely the search-popup use case.

Minor nits — nothing blocking.

  • docs/components/Search/Popup.vue — search is now title-only (fuzzysort over sidebar items) instead of full-text (VitePress local search index). Simpler, but loses within-page content search. Worth a changelog note since docs users will notice.
  • package.jsonfuzzysort is docs-only but lands in dependencies; should be devDependencies.
  • docs/components/Docs/Sidebar.vue — the link === '/' branch in isActive is unreachable: no item in getSidebarList has link: '/'. Dead code.
  • docs/.vitepress/plugins/componentTransformer.ts — the rewrite (regex → baseParse, reverse iteration, deferred applyImports) is a solid correctness improvement. No unit tests cover the transformer; build success is the only validation. A small test on parseSingleTag and the index-shift fix would help guard against future regressions.

Replace the per-tag `css` prop on `<ComponentPreview>` with a sensible
default in Demo.vue (`flex flex-wrap gap-3 items-center`) plus per-story
wrappers where the layout differs.

- Demo.vue: remove the `css` prop; preview area is just a styled canvas
  with the default flex layout.
- 24 component docs: strip `class=` / `css=` from every preview tag.
- 38 stories: explicit wrapper for the non-default cases. Grid-display
  overrides get a plain `<div class="grid …">`; additive overrides
  (`justify-center !py-20`, `h-screen overflow-hidden`, `!p-0`) are
  self-sufficient and include the flex base so the wrapper carries its
  own layout. Toast's `flex-wrap` is now covered by the default.

The 94 stories with no override no longer need a wrapper at all.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actions Bot added a commit that referenced this pull request May 17, 2026
The grid-override wrappers lost their gap and item-alignment when the
class prop went away, because the original Demo.vue used to append the
user's class after `flex gap-3 items-center` — so even when display
flipped to grid, those two utilities still applied. And every wrapper
sat as a flex child of Demo.vue, so `justify-center` only centered
content within the wrapper's content width, not the preview area.

- Prepend `gap-3 items-center` to grid wrappers (skipped when the
  override already pins its own gap).
- Add `w-full` to every story wrapper so `justify-center` and grid
  layouts span the preview area.
- Sidebar's `!p-0` couldn't cancel Demo.vue's outer p-8 from a child;
  replaced with `!-m-8` so the sidebar sits flush.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actions Bot added a commit that referenced this pull request May 18, 2026
The global kbd base rule in tailwind/plugin.js was overriding the
browser-default monospace styling for every kbd element in consumer
projects. Move the styles inline onto the search popup's kbd elements.
github-actions Bot added a commit that referenced this pull request May 18, 2026
Use reka-ui's `@highlight` event to track the highlighted item instead
of probing the DOM, and let the anchor's native modifier-click behavior
handle new-tab opens — only intercept plain clicks for SPA navigation.
Drop the "Current" page marker. Untrack the auto-generated
`docs/content/components.d.ts` so the existing gitignore rule applies.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actions Bot added a commit that referenced this pull request May 18, 2026
@netchampfaris netchampfaris merged commit 2fa3cbf into main May 18, 2026
7 checks passed
github-actions Bot added a commit that referenced this pull request May 18, 2026
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