vident 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad2b06ce20d99e816db5362f70a9ef4e068c9f6452d629253eb2283efc7e4b7e
4
- data.tar.gz: 5d91a89eef5349d1ba7922875cef900c696684d2a627a5c958a7f5ed5d237ba9
3
+ metadata.gz: 8273577ce2815171e9bfbf610942f55aa5a898bd99501120337d984ca2aa69a6
4
+ data.tar.gz: 419e5282ed761f30d81173126985a9438be98575f130100f29279bfcbfbfca79
5
5
  SHA512:
6
- metadata.gz: 19e30e85766415738689f4a746ade4c21fe4d649b83212f2f8cfeb829e93a4b7109d625ad46fb3391446afb9e7b6865a9542a78bac1be4f2cfca3644769b7902
7
- data.tar.gz: f4f93452b54d1971ea135a39eb079f4a3e559b5057400154dbaf5998a2e22c072c70f6dd7cf786c14648de891ebeca2b959a5a9be670b7c8ea70a5249e91e207
6
+ metadata.gz: a009432e990316030f91efc0762a6a1a3b575061fd600c75eb046a8cdc8ffb2e1b1d5422b040fde2dccb861029d933bb1d762cf3943e7fc2cde6309301a42acc
7
+ data.tar.gz: 7d1f36e57e431b895ebd7bbd5175940aad3ef80651a6401fc7d17fcb624f01ad8e4d4953a68ff85e87685f66d86c8d8da7c81bb1f6cdaabd1b5bf0890636ee4f
data/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/).
7
7
 
8
8
 
9
+ ## [3.1.0] - 2026-05-26
10
+
11
+ ### Added
12
+
13
+ - Cross-controller parser forms accept a component class (or instance) wherever they accept a controller-path String — e.g. `stimulus_target: [Row, :summary]`, `stimulus_controllers: [Row]`, `stimulus_action: [:click, Row, :toggle]` — so references to another component's controller stay refactor-safe instead of hard-coded identifier strings. The same holds for the class-level builders (`Parent.stimulus_target(Row, :summary)`); the String cross-controller form is still rejected there.
14
+
15
+
9
16
  ## [3.0.0] - 2026-05-04
10
17
 
11
18
  A bare `String` now means the same thing across every Stimulus primitive — a controller path. The 2.x ambiguity where a `String` could variously mean controller path, outlet name, CSS selector, or fully-qualified action descriptor (depending on primitive and position) is gone, closing a class of silent-failure footguns. See `UPGRADING.md` "Upgrading to Vident 3.0" for symptom → fix on each breaking change.
data/README.md CHANGED
@@ -602,7 +602,7 @@ class CustomComponent < Vident::ViewComponent::Base
602
602
  end
603
603
  ```
604
604
 
605
- All stimulus props accept Symbol paths as well as Strings (e.g. `stimulus_controllers: [:custom, :"admin/users"]`). `stimulus_values:` and `stimulus_classes:` additionally accept Array entries (for cross-controller: `[["admin/users", :name, "value"]]`) and pre-built `Vident::Stimulus::Value` / `Vident::Stimulus::ClassMap` instances, so you can compose attribute sets outside the component and pass them in.
605
+ All stimulus props accept Symbol paths as well as Strings (e.g. `stimulus_controllers: [:custom, :"admin/users"]`). `stimulus_values:` and `stimulus_classes:` additionally accept Array entries (for cross-controller: `[["admin/users", :name, "value"]]`) and pre-built `Vident::Stimulus::Value` / `Vident::Stimulus::ClassMap` instances, so you can compose attribute sets outside the component and pass them in. Anywhere a controller-path String is accepted in a cross-controller slot you may pass the component class (or instance) instead — `[OtherComponent, :name, "value"]`, `stimulus_controllers: [OtherComponent]`, `stimulus_target: [OtherComponent, :row]` — which keeps the reference refactor-safe rather than a hard-coded identifier string.
606
606
 
607
607
  or you can use tag helpers to generate HTML with Stimulus attributes:
608
608
 
@@ -40,13 +40,13 @@ module Vident
40
40
  method_name: Naming.js_name(method_sym),
41
41
  event: event.to_s
42
42
  )
43
- in [String => ctrl_path, Symbol => method_sym]
43
+ in [ctrl_path, Symbol => method_sym] if Controller.path_arg?(ctrl_path)
44
44
  new(
45
45
  controller: Controller.parse(ctrl_path, implied: implied),
46
46
  method_name: Naming.js_name(method_sym),
47
47
  event: nil
48
48
  )
49
- in [Symbol => event, String => ctrl_path, Symbol => method_sym]
49
+ in [Symbol => event, ctrl_path, Symbol => method_sym] if Controller.path_arg?(ctrl_path)
50
50
  new(
51
51
  controller: Controller.parse(ctrl_path, implied: implied),
52
52
  method_name: Naming.js_name(method_sym),
@@ -22,7 +22,7 @@ module Vident
22
22
  name: name_sym.to_s.dasherize,
23
23
  css: normalize_css(css_input)
24
24
  )
25
- in [String => ctrl_path, Symbol => name_sym, css_input]
25
+ in [ctrl_path, Symbol => name_sym, css_input] if Controller.path_arg?(ctrl_path)
26
26
  new(
27
27
  controller: Controller.parse(ctrl_path, implied: implied),
28
28
  name: name_sym.to_s.dasherize,
@@ -18,13 +18,25 @@ module Vident
18
18
  new(path: implied.path, name: implied.name, alias_name: as)
19
19
  when 1
20
20
  raw = args[0]
21
- path = raw.to_s
22
- new(path: path, name: Naming.stimulize_path(path), alias_name: as)
21
+ if raw.respond_to?(:stimulus_identifier)
22
+ name = raw.stimulus_identifier
23
+ path = raw.respond_to?(:stimulus_identifier_path) ? raw.stimulus_identifier_path : name
24
+ new(path: path, name: name, alias_name: as)
25
+ else
26
+ path = raw.to_s
27
+ new(path: path, name: Naming.stimulize_path(path), alias_name: as)
28
+ end
23
29
  else
24
30
  raise ::Vident::ParseError, "Controller.parse: expected 0 or 1 positional args, got #{args.size}"
25
31
  end
26
32
  end
27
33
 
34
+ # Whether `value` is accepted in a cross-controller path slot: a path
35
+ # String, or a Vident component (class or instance) that names itself.
36
+ def self.path_arg?(value)
37
+ value.is_a?(String) || value.respond_to?(:stimulus_identifier)
38
+ end
39
+
28
40
  def identifier = name
29
41
 
30
42
  def to_s = name
@@ -34,14 +34,14 @@ module Vident
34
34
  new(controller: implied, name: sym.to_s.dasherize, selector: sel.css)
35
35
  in [String => str, Selector => sel]
36
36
  new(controller: implied, name: Naming.stimulize_path(str), selector: sel.css)
37
- in [String => parent_path, Symbol => child_sym]
37
+ in [parent_path, Symbol => child_sym] if Controller.path_arg?(parent_path)
38
38
  child_name = child_sym.to_s.dasherize
39
39
  new(
40
40
  controller: Controller.parse(parent_path, implied: implied),
41
41
  name: child_name,
42
42
  selector: auto_selector(child_name, component_id: component_id)
43
43
  )
44
- in [String => parent_path, Symbol => child_sym, Selector => sel]
44
+ in [parent_path, Symbol => child_sym, Selector => sel] if Controller.path_arg?(parent_path)
45
45
  new(
46
46
  controller: Controller.parse(parent_path, implied: implied),
47
47
  name: child_sym.to_s.dasherize,
@@ -24,7 +24,7 @@ module Vident
24
24
  name: name_sym.to_s.dasherize,
25
25
  serialized: serialize(raw)
26
26
  )
27
- in [String => ctrl_path, Symbol => name_sym, raw]
27
+ in [ctrl_path, Symbol => name_sym, raw] if Controller.path_arg?(ctrl_path)
28
28
  new(
29
29
  controller: Controller.parse(ctrl_path, implied: implied),
30
30
  name: name_sym.to_s.dasherize,
@@ -16,7 +16,7 @@ module Vident
16
16
  case args
17
17
  in [Symbol => sym]
18
18
  new(controller: implied, name: Naming.js_name(sym))
19
- in [String => ctrl_path, Symbol => sym]
19
+ in [ctrl_path, Symbol => sym] if Controller.path_arg?(ctrl_path)
20
20
  new(
21
21
  controller: Controller.parse(ctrl_path, implied: implied),
22
22
  name: Naming.js_name(sym)
@@ -25,7 +25,7 @@ module Vident
25
25
  name: name_sym.to_s.dasherize,
26
26
  serialized: serialize(raw)
27
27
  )
28
- in [String => ctrl_path, Symbol => name_sym, raw]
28
+ in [ctrl_path, Symbol => name_sym, raw] if Controller.path_arg?(ctrl_path)
29
29
  new(
30
30
  controller: Controller.parse(ctrl_path, implied: implied),
31
31
  name: name_sym.to_s.dasherize,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vident
4
- VERSION = "3.0.0"
4
+ VERSION = "3.1.0"
5
5
  end
@@ -67,7 +67,7 @@ class DropdownComponent < ApplicationComponent
67
67
  end
68
68
  ```
69
69
 
70
- Cross-controller references elsewhere (actions/targets/values/classes/outlets) use the `"path/to/controller"` **string** form — Vident stimulizes it for you.
70
+ Cross-controller references elsewhere (actions/targets/values/classes/outlets) take the controller in one of two forms: a `"path/to/controller"` **string** (Vident stimulizes it for you), or the **component class/instance** itself in that slot — `OtherComponent` in place of `"other_component"`. The component form is refactor-safe: rename the class and the reference follows, with no identifier string to drift.
71
71
 
72
72
  ### 1.2 Actions
73
73
 
@@ -118,6 +118,7 @@ The alias resolves at render time — unknown aliases raise `Vident::Declaration
118
118
  | `:my_thing` | `implied#myThing` (no explicit event) |
119
119
  | `[:click, :my_thing]` | `click->implied#myThing` |
120
120
  | `[:click, "other/ctrl", :my_thing]` | `click->other--ctrl#myThing` |
121
+ | `[:click, OtherCtrl, :my_thing]` | same, via the component class (refactor-safe) |
121
122
  | `"click->other--ctrl#myThing"` | pass-through, parsed into its parts |
122
123
  | `{event: :click, method: :submit, options: [:once, :prevent]}` | `click:once:prevent->implied#submit` |
123
124
  | `-> { [:click, :my_thing] if @editable }` | proc, evaluated in component instance; `nil`/`false` returns drop the entry |
@@ -179,6 +180,7 @@ Vident `targets` DSL:
179
180
  | ------------------------------ | -------------------------------------------------- |
180
181
  | `:button` | `data-implied-target="button"` on the root |
181
182
  | `["other/ctrl", :row]` | `data-other--ctrl-target="row"` on the root |
183
+ | `[OtherCtrl, :row]` | same, via the component class (refactor-safe) |
182
184
  | Same shapes on `child_element` | `data-implied-target="..."` on the child |
183
185
 
184
186
  ```ruby
@@ -224,6 +226,7 @@ end
224
226
  stimulus_values: [
225
227
  [:foo, "bar"], # implied-foo-value="bar"
226
228
  ["other/ctrl", :baz, 42], # other--ctrl-baz-value="42"
229
+ [OtherCtrl, :baz, 42], # same, via the component class
227
230
  ]
228
231
  ```
229
232
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vident
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou