Skip to content

Hub pages 2/4: {card-group}, {link-card}, and {explore} - #3826

Draft
florent-leborgne wants to merge 1 commit into
feature/hub-layout-herofrom
feature/hub-card-explore
Draft

Hub pages 2/4: {card-group}, {link-card}, and {explore}#3826
florent-leborgne wants to merge 1 commit into
feature/hub-layout-herofrom
feature/hub-card-explore

Conversation

@florent-leborgne

@florent-leborgne florent-leborgne commented Aug 10, 2026

Copy link
Copy Markdown
Member

Part 2 of 4, based on #3825. Implements elastic/docs-content-internal#1384 ({card-group}), #1385 ({link-card}) and #1549 ({explore}).

Demo: https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/3826/examples/products/docs-builder

The three ship together because {explore} is what switches the other two into their second rendering mode. Split apart, this would add a mode switch nothing can trigger.

The mode switch

Nesting decides it. There is no option.

Directive Standalone Inside {explore}
{card-group} Heading and an auto-filling card grid One collapsible accordion in a stack
{link-card} Bordered card with description and inline aside Titled link column, description dropped, aside as a badge cluster

Driving this from the ancestor rather than a per-directive option means every card grid elsewhere on the site keeps working unchanged. An author wraps existing groups in {explore} and the rendering follows.

The first accordion in a stack is expanded and the rest are collapsed. Toggling uses native <details> and <summary>, so it works without JavaScript.

Implementation choices

HubDirectiveViewModel. Hub links come from directive options and YAML bodies, so they never reach Markdig's link renderer. {link-card} alone has six anchors, and each view was repeating the external, anchor and preload rules by hand. This centralises them into one LinkAttributes call. {hero} moves onto it too.

Heading levels. An accordion title renders as <h3> and a column title as <h4>, so an Explore stack keeps a complete outline: section h2, accordion h3, column h4. A <span> would leave the accordion group missing from the page outline.

Machine-readable output. The LLM export keeps the whole structure, because the curated grouping of links is what a hub page is for. The search body deliberately gets nothing from these three: section, card and link titles are the tokens that would let a hub outrank the pages it links to.

From the designs

  • Column links take the site's standard link affordance: blue, underlined, and bulleted. The prototype styled them as a quiet dark index.
  • The aside label keeps the casing the writer chose, for example "Card directives". The prototype forced uppercase.

Example page

docs/examples/products/docs-builder.md grows from a hero into a full hub, exercising every mode: a standalone highlight grid, a :variant: solutions grid with icons and accent variants, and a three-accordion {explore} stack with four columns, inline asides and badge clusters.

Its solution cards use docs-content:// cross-links to the published Elastic documentation, which also covers the cross-link form.

Testing

./build.sh unit-test passes. dotnet format and npm run fmt:check are clean. A full docs build reports 0 errors and 0 warnings.

tests/authoring/Blocks/Hub/CardsAndExplore.fs covers both rendering modes, the solutions variant, the first-accordion-open rule, the dropped description, the aside label, the heading levels, icon and variant accents, and four failure paths.

Screenshots to add or update

None attached. The accordion stack and the two card layouts are worth checking on the preview.

@florent-leborgne
florent-leborgne force-pushed the feature/hub-card-explore branch from ba2cdd4 to 72fb5a2 Compare August 11, 2026 07:56
@florent-leborgne
florent-leborgne force-pushed the feature/hub-card-explore branch from 72fb5a2 to b5e2d23 Compare August 11, 2026 08:46
@florent-leborgne
florent-leborgne force-pushed the feature/hub-card-explore branch from b5e2d23 to 47c33d0 Compare August 11, 2026 13:31
@florent-leborgne
florent-leborgne force-pushed the feature/hub-card-explore branch from 47c33d0 to a8a4319 Compare August 11, 2026 15:15
@florent-leborgne
florent-leborgne force-pushed the feature/hub-card-explore branch from a8a4319 to bc28c12 Compare August 11, 2026 15:48
These three ship together because {explore} is what switches the other two into
their second rendering mode. A reviewer cannot judge the mechanism from any one
of them alone.

{card-group} is a section heading and a card grid. {link-card} is one card, with
a title, a description, a primary link list, and an optional aside. Its body is a
fixed YAML schema rather than markdown, so a missing title or invalid YAML fails
the build. {explore} wraps card groups into a stack of collapsible accordions.

Nesting drives the mode switch, not an option. Inside {explore} a card group
renders as an accordion and a link card renders as a titled link column, with the
description dropped and the aside rendered as a badge cluster under its own
authored label. Driving this from the ancestor rather than a per-directive option
means every card grid elsewhere on the site keeps working unchanged.

Adds HubDirectiveViewModel, which centralises the attributes a hub link needs.
Hub links come from options and YAML bodies, so they never pass through Markdig's
link renderer and each view was repeating the external, anchor, and preload rules
by hand. {hero} moves onto it too.

The LLM export keeps the whole structure. The curated grouping of links is what a
hub page is for, and the nav tree in llms.txt is neither ordered nor curated, so
it is not a substitute. The search body deliberately gets nothing from these three
directives: section, card, and link titles are the tokens that would let a hub
outrank the pages it links to on a specific query.

Adds doesNotContainHtml to the authoring assertions, for content a directive
drops on purpose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant