Skip to content

feat(docs-rs): Render knobs controls for playground code blocks in build pipeline #770

@ssilvius

Description

@ssilvius

Goal

Wire up the full pipeline so that playground code blocks render both a preview (Web Component) and a <rafters-knobs> controls panel, while live blocks render preview-only (no knobs). Update the builder, template, and markdown rendering to support this.

Exact Implementation Requirements

Builder Changes (`builder.rs`)

  • In `build_page()`, handle both `is_live()` and `is_playground()` code blocks
  • For `live` blocks: existing behavior (preview + source code)
  • For `playground` blocks: preview + knobs + source code
    • Use `generate_knobs_config()` from the transformed block
    • Render `` in the HTML
  • Track whether any playground blocks exist on the page
  • If any playground blocks exist, include `knobs.js` script in the page

Template Changes (`templates.rs`)

  • Add `has_playground: bool` to the `Context` struct
  • In `BASE_TEMPLATE`, conditionally include knobs JS:
    {% if has_playground %}<script src="{{ base_url }}assets/knobs.js"></script>{% endif %}

Asset Changes (`assets.rs`)

  • In `generate_assets()`, write `knobs.js` to the assets directory

Markdown Rendering (`builder.rs` `render_markdown`)

  • For playground blocks, insert preview container + knobs element + source code:
    <div class="preview-container" id="{block_id}">
      <{custom-element} ...>{content}</{custom-element}>
    </div>
    <rafters-knobs for="{block_id}" config='{knobs_config}'></rafters-knobs>
    Followed by the syntax-highlighted source code block

Behavior Requirements

  • `live` blocks: unchanged behavior (preview + source)
  • `playground` blocks: preview + knobs controls + source
  • Pages with zero playground blocks: no `knobs.js` loaded
  • The preview container gets an `id` attribute matching the `for` attribute on ``

Acceptance Criteria

Functional Tests Required

#[tokio::test]
async fn playground_block_includes_knobs() {
    // Create a temp site with a playground code block
    // Build it
    // Verify output HTML contains <rafters-knobs> element
    // Verify knobs.js is included
}

#[tokio::test]
async fn live_block_excludes_knobs() {
    // Create a temp site with a live code block (not playground)
    // Build it
    // Verify output HTML does NOT contain <rafters-knobs>
    // Verify knobs.js is NOT included
}

What NOT to Include

File Locations

  • `crates/rafters-static/src/builder.rs` - pipeline integration
  • `crates/rafters-static/src/templates.rs` - add `has_playground` to Context
  • `crates/rafters-static/src/assets.rs` - write knobs.js asset

Integration Requirements

Dependencies

Success Criteria

  • Playground blocks render preview + knobs + source
  • Live blocks render preview + source (no knobs)
  • Source-only blocks render just source (no change)
  • `knobs.js` only loaded when playground blocks exist
  • `cargo test --workspace` passes
  • `cargo clippy --workspace --all-targets` clean

This issue is complete when: A page with ```````tsx playground``````` renders an interactive preview with variant/size/boolean knobs, while ```````tsx live``````` renders preview-only.

Context & References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions