Skip to content

[PLAY-3123] Rails Playground POC - #6359

Draft
kangaree wants to merge 19 commits into
masterfrom
PLAY-2326-rails-playground-poc
Draft

[PLAY-3123] Rails Playground POC#6359
kangaree wants to merge 19 commits into
masterfrom
PLAY-2326-rails-playground-poc

Conversation

@kangaree

@kangaree kangaree commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?
https://runway.powerhrg.com/backlog_items/PLAY-3123

Adds a Rails Playground tab for select kit pages that reuses the existing props panel but renders previews through a server-side pb_rails endpoint. Includes ERB codegen, live preview wiring, and translation for JSX/ERB children so compound kits (card, flex, dialog) behave like their React playground counterparts.

Kits:

  • button
  • badge
  • caption
  • icon
  • title
  • card
  • flex
  • checkbox
  • text_input
  • dialog
  • dropdown

Screenshots: Screenshots to visualize your addition/change
Screenshot 2026-07-06 at 2 35 27 PM

How to test? Steps to confirm the desired behavior:

  1. Go through kits and click playground in rails.

Checklist:

  • LABELS Add a label: enhancement, bug, improvement, new kit, deprecated, or breaking. See Changelog & Labels for details.
  • DEPLOY I have added the milano label to show I'm ready for a review.
  • TESTS I have added test coverage to my code.
  • SEMVER I have added a minor, major, or patch label for release.
  • RC I have added an inactive RC label if not an active RC.

kangaree added 3 commits July 6, 2026 14:20
Adds a Rails Playground tab for select kit pages that reuses the existing props panel but renders previews through a server-side pb_rails endpoint. Includes ERB codegen, live preview wiring, and translation for JSX/ERB children so compound kits (card, flex, dialog) behave like their React playground counterparts.
@kangaree kangaree self-assigned this Jul 6, 2026
@kangaree kangaree added milano 20 MAX - Deploy this PR to a review environment via Milano improvement This is used when your PR contains library upgrades or doc/site improvements. (USED IN CHANGELOG)) minor Semver Target Inactive RC Skip the release candidate process labels Jul 6, 2026
title: "Header Title inside Dialog.Header",
}),
@children.present? ? render_pb_kit("dialog/dialog_body") { @children.to_s.html_safe } : render_pb_kit("dialog/dialog_body", { text: "" }),
render_pb_kit("dialog/dialog_footer", {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid calling html_safe on playground-provided children unless the content came from a trusted renderer? The generic children fallback and dialog subcomponent body here look like they can return raw user-entered HTML. Since LiveExampleRails later executes inline scripts from the rendered HTML, this feels like a risky path for security issues, like we had for the previous playground.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I updated this to escape the playground-provided children.

const data = await response.json();

if (!response.ok) {
setError(data.error || "Failed to render Rails preview");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we clear html here as well when a Rails preview request errors or when a new request starts? Right now a failed prop combo can show an error while still rendering the last successful preview

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated when a new request starts!

Comment thread playbook-website/app/controllers/playground_controller.rb Outdated
kangaree added 3 commits July 7, 2026 12:06
Plain children from the props panel are escaped via TrustedHtml.
Dialog body and other fallbacks use ChildrenRenderer instead of raw html_safe.

@kangaree kangaree left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for your review! I'm still working on your feedback, but wanted to provide some updates for now.

Comment thread playbook-website/app/controllers/playground_controller.rb Outdated
const data = await response.json();

if (!response.ok) {
setError(data.error || "Failed to render Rails preview");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated when a new request starts!

title: "Header Title inside Dialog.Header",
}),
@children.present? ? render_pb_kit("dialog/dialog_body") { @children.to_s.html_safe } : render_pb_kit("dialog/dialog_body", { text: "" }),
render_pb_kit("dialog/dialog_footer", {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I updated this to escape the playground-provided children.

Run inline scripts first. Then one PbKitRegistry rescan and mountComponents call scoped to the preview container. Rescan again when scripts use deferred DOMContentLoaded/load callbacks.
ElisaShapiro
ElisaShapiro previously approved these changes Jul 13, 2026

@ElisaShapiro ElisaShapiro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that pops out to me vs. React side is the code snippet not having its syntax highlighted (doc code snippets + react playground use react-syntax-highlighter) but that's small potatoes compared to the rest (and definitely not a blocker for this, can be explored at any time in the playground POC/beta life-cycle). Really awesome job!

Comment thread playbook-website/app/services/playground/trusted_html.rb
kangaree added 2 commits July 14, 2026 08:41
Allowlist nested child kits, escape remaining text fallbacks, and disable
inline script execution in the playground preview.

@nitro-pr-review nitro-pr-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rails Playground POC looks sound overall: kit allowlisting, nested child-kit checks, HTML escaping, and disabling script re-execution on playground previews cover the main risk paths. No concrete correctness or security issues stood out in the diff under normal usage.

@kangaree

Copy link
Copy Markdown
Contributor Author

Merging master to get the new Icon fixes - #6401.

@github-actions

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 24 hours if no further activity occurs.
If this change is desirable, please accelerate completing it. If it is not, please close the PR. If you're blocked on something, please ensure there's a reference to this PR in a story on your team's board so the team will follow up, and consider closing the PR for now.
Please do not artificially extend the deadline with a dummy comment. If necessary, provide a status update, such as "this change is being actively tested".
Thank you for your contributions and your collaboration in reducing WIP and cycle time.

@github-actions github-actions Bot added the Stale label Jul 30, 2026
@github-actions github-actions Bot closed this Aug 3, 2026
@github-actions
github-actions Bot deleted the PLAY-2326-rails-playground-poc branch August 3, 2026 23:49
Cap request/children size and nesting depth, add a cache-based
per-IP rate limit, and return generic client errors while logging detail.
Reject unknown keys and never forward html_options/data/aria/style.
Apply the same PropFilter to nested JSX/ERB child props.
@kangaree kangaree reopened this Aug 5, 2026
@kangaree kangaree removed the Stale label Aug 5, 2026
@kangaree kangaree changed the title [PLAY-2326] Rails Playground POC [PLAY-3123] Rails Playground POC Aug 6, 2026
@kangaree

Copy link
Copy Markdown
Contributor Author

I addressed feedback:

  • Cap preview input size and redact error details
  • Only allow schema props; block html_options / data / aria / style
  • Reject URL/path/.svg-like icon values so the playground can’t poke Icon’s file/URL paths
  • Tighten ERB children parsing (\A anchor) and only allow known child kit paths

@kangaree kangaree added milano 20 MAX - Deploy this PR to a review environment via Milano and removed milano 20 MAX - Deploy this PR to a review environment via Milano labels Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-review improvement This is used when your PR contains library upgrades or doc/site improvements. (USED IN CHANGELOG)) Inactive RC Skip the release candidate process milano 20 MAX - Deploy this PR to a review environment via Milano minor Semver Target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants