Skip to content

Drop stimulus_identifier_path lock from task-card twins - #31

Closed
stevegeek wants to merge 12 commits into
mainfrom
drop-task-card-stimulus-identifier-lock
Closed

Drop stimulus_identifier_path lock from task-card twins#31
stevegeek wants to merge 12 commits into
mainfrom
drop-task-card-stimulus-identifier-lock

Conversation

@stevegeek

Copy link
Copy Markdown
Owner

Summary

  • The Phlex and ViewComponent task-card twins on the docs site had a locked stimulus_identifier_path so they'd both emit data-controller="task-card-component". That bridges two engines at the wrong layer — the Ruby class lies about its namespace.
  • Bridge in JS instead: register the same controller class under both natural identifiers (phlex--task-card-component and view-component--task-card-component). The Source tabs on the docs site now show clean exemplary code with no override.
  • The divergence sanity check in rake website:demos strips the engine-namespace prefix before comparing, so it still catches real semantic drift between the two engines without flagging the (now expected) identifier difference.

Test plan

  • bundle exec standardrb clean
  • bundle exec rake test — 1065 runs, 0 failures, 2 skips (conditional engine tests)
  • bundle exec rake website:demos regenerates fragments; rendered HTML now shows data-controller="phlex--task-card-component"
  • CI matrix green on push

🤖 Generated with Claude Code

stevegeek and others added 12 commits April 25, 2026 11:35
The previous wording "Type-safe Rails components with first-class
Stimulus" implied the gem ships a library of components, when in fact
it's a toolkit for building your own.

https://claude.ai/code/session_01DFmrJHuYK2ybJ9WAEqzzzr
"Pick the engine that fits the file" was awkward — clarify that the
choice is per-app or framework preference.

https://claude.ai/code/session_01DFmrJHuYK2ybJ9WAEqzzzr
vident:install now generates app/components/application_phlex_component.rb
and/or application_view_component.rb based on which engine gems are loaded,
matching the ApplicationRecord/ApplicationController pattern.

New per-engine scaffold generators:
  bin/rails g vident:phlex:component Dashboard::TaskCard
  bin/rails g vident:view_component:component Dashboard::TaskCard

Each emits the .rb component (with one example prop and a stimulus block),
a Stimulus controller sidecar, and a unit test. ViewComponent also gets
the .html.erb template. Flags: --skip-stimulus, --skip-controller,
--skip-test, --typescript/-t, --parent.

Plus a vident:component umbrella dispatcher: dispatches to the right
engine when only one is loaded, or requires --engine=phlex|view_component
when both are present.

Per-engine generators ship with their respective gems via gemspec
file-glob updates.

https://claude.ai/code/session_01DFmrJHuYK2ybJ9WAEqzzzr
The deploy-dashboard release card was esoteric. Replaced with a more
relatable task card example that exercises the same DSL features —
typed unions, dynamic classes proc, values_from_props, child_element
with stimulus_target/action/params, plus an _Array(String) tags prop
to demo array props.

The card has a Phlex twin (Phlex::TaskCardComponent) and a
ViewComponent twin (ViewComponent::TaskCardComponent + .html.erb),
both locked to the same stimulus_identifier_path so they emit
equivalent HTML and one Stimulus controller drives both.

Demo include now renders both engine sources into the DOM and the
Source tab hosts an inline Phlex / ViewComponent toggle. The choice
is synced across all demos on the page and persisted in
localStorage. Default engine: ViewComponent. Both source code blocks
stay crawlable; the Live and Rendered HTML panels render once
(Phlex's output is the canonical bytes).

Old release_card demo fragments removed. The dummy app's
Dashboard::ReleaseCardComponent is unchanged — it's still used by
the broader dashboard tests and the Claude skill examples.

https://claude.ai/code/session_01DFmrJHuYK2ybJ9WAEqzzzr
Five small follow-ups from the reviewer pass:

- Strip a trailing `Component` from generator input names so
  `g vident:component TaskCardComponent` produces the same files as
  `g vident:component TaskCard` rather than `TaskCardComponentComponent`.
  Matches ViewComponent's own generator behaviour.

- `vident:install` no longer overwrites an existing
  `application_phlex_component.rb` / `application_view_component.rb`
  on re-run; the existing file is preserved unless `--force` is passed,
  mirroring the same semantics as the Claude skill file.

- CHANGELOG: document the new component scaffold generators, the
  umbrella dispatcher, and the Application*Component install behaviour.

- README: explain how to scaffold a component and what flags are
  available, alongside the existing `vident:install` section.

- SKILL.md: lead the "Component scaffolding" section with the new
  generator commands so Claude Code uses them by default.

- Drop a stray `require "vident"` from the ViewComponent task card
  twin for consistency with the Phlex twin.

Generator tests grow accordingly: 26 runs / 162 assertions across
all four generator test files.

https://claude.ai/code/session_01DFmrJHuYK2ybJ9WAEqzzzr
- Move WEBSITE_DIR out of the namespace block (Lint/ConstantDefinitionInBlock)
  and drop a redundant `+"..."` interpolation unfreeze in lib/tasks/website.rake.
- Ignore website/_includes/demos/* in standardrb. The
  task_card_view_component_source.rb fragment concatenates a `.rb` and a
  `.erb` for display, so it isn't valid Ruby.
- Drop a self-evident SKILL_SOURCE comment and two scenario-restating
  comments in install_generator_test.rb.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Clarify hero text: Vident builds components, not provides them
The Phlex and ViewComponent twins on the docs site had a locked
identifier so they'd both emit `data-controller="task-card-component"`
and share one Stimulus controller registration. That's bridging two
engines at the wrong layer — the Ruby class is now lying about its
namespace.

Bridge in JS instead: register the same controller class under both
natural identifiers (`phlex--task-card-component` and
`view-component--task-card-component`). The Source tabs on the docs
site now show clean exemplary code with no override.

The divergence sanity check in `rake website:demos` strips the engine
namespace prefix before comparing, so it still catches real semantic
drift between the two engines without flagging the (now expected)
identifier difference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying vident with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2997ebf
Status: ✅  Deploy successful!
Preview URL: https://adbc44ac.vident.pages.dev
Branch Preview URL: https://drop-task-card-stimulus-iden.vident.pages.dev

View logs

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.

2 participants