Class: Vident2::Stimulus::Action

Inherits:
Literal::Data
  • Object
show all
Defined in:
lib/vident2/stimulus/action.rb

Overview

‘data-action` fragment: single action descriptor like `“click->admin–users#handleClick”`.

Fields folded in from v1’s ‘StimulusAction::Descriptor` — there’s no separate Descriptor class in V2; Hash DSL input parses directly into an ‘Action`.

Constant Summary collapse

VALID_OPTIONS =

Stimulus action options (‘:once`, `:prevent`, etc.). Keep in sync with stimulus.hotwired.dev/reference/actions#options.

%i[once prevent stop passive !passive capture self].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_descriptor(h, implied:) ⇒ Object

‘.parse(method:, controller:, options:, keyboard:, window:)` Keyword-descriptor entry point, used by the DSL Hash form.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/vident2/stimulus/action.rb', line 97

def self.from_descriptor(h, implied:)
  invalid_options = Array(h[:options]) - VALID_OPTIONS
  unless invalid_options.empty?
    raise ::Vident2::ParseError,
      "Action.parse: invalid option(s) #{invalid_options.inspect}. Valid: #{VALID_OPTIONS.inspect}"
  end

  method_raw = h.fetch(:method)
  method_name = method_raw.is_a?(Symbol) ? Naming.js_name(method_raw) : method_raw.to_s
  controller = h[:controller] ? Controller.parse(h[:controller], implied: implied) : implied
  new(
    controller: controller,
    method_name: method_name,
    event: h[:event]&.to_s,
    modifiers: Array(h[:options]),
    keyboard: h[:keyboard],
    window: h.fetch(:window, false)
  )
end

.parse(*args, implied:, component_id: nil) ⇒ Object

‘.parse(*args, implied:)` grammar mirrors v1 `StimulusAction#parse_arguments`:

(Symbol)                        -> :method on implied controller, no event
(String)                        -> pre-qualified "event->ctrl#method" / "ctrl#method"
(Hash)                          -> keyword descriptor (method:/event:/...)
(Symbol, Symbol)                -> (event, method) on implied
(String, Symbol)                -> (controller_path, method) — no event
(Symbol, String, Symbol)        -> (event, controller_path, method)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/vident2/stimulus/action.rb', line 34

def self.parse(*args, implied:, component_id: nil)
  case args
  in [Hash => h]
    from_descriptor(h, implied: implied)
  in [Symbol => method_sym]
    new(
      controller: implied,
      method_name: Naming.js_name(method_sym),
      event: nil
    )
  in [String => s]
    parse_qualified_string(s)
  in [Symbol => event, Symbol => method_sym]
    new(
      controller: implied,
      method_name: Naming.js_name(method_sym),
      event: event.to_s
    )
  in [String => ctrl_path, Symbol => method_sym]
    new(
      controller: Controller.parse(ctrl_path, implied: implied),
      method_name: Naming.js_name(method_sym),
      event: nil
    )
  in [Symbol => event, String => ctrl_path, Symbol => method_sym]
    new(
      controller: Controller.parse(ctrl_path, implied: implied),
      method_name: Naming.js_name(method_sym),
      event: event.to_s
    )
  else
    raise ::Vident2::ParseError, "Action.parse: invalid arguments #{args.inspect}"
  end
end

.parse_qualified_string(s) ⇒ Object

Pre-qualified string form, e.g. ‘“click->admin/users#show”` or `“admin–users#show”`. Pass-through: the controller segment is NOT re-stimulized. Flagged for deprecation.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/vident2/stimulus/action.rb', line 120

def self.parse_qualified_string(s)
  if s.include?("->")
    event_part, ctrl_method = s.split("->", 2)
    ctrl, method = ctrl_method.split("#", 2)
    new(
      controller: Controller.new(path: ctrl, name: ctrl),
      method_name: method,
      event: event_part
    )
  else
    ctrl, method = s.split("#", 2)
    new(
      controller: Controller.new(path: ctrl, name: ctrl),
      method_name: method,
      event: nil
    )
  end
end

.to_data_hash(actions) ⇒ Object

Actions space-join under a single ‘:action` key, preserving order.



90
91
92
93
# File 'lib/vident2/stimulus/action.rb', line 90

def self.to_data_hash(actions)
  return {} if actions.empty?
  {action: actions.map(&:to_s).join(" ")}
end

Instance Method Details

#to_data_pairObject



84
# File 'lib/vident2/stimulus/action.rb', line 84

def to_data_pair = [:action, to_s]

#to_hObject Also known as: to_hash



86
# File 'lib/vident2/stimulus/action.rb', line 86

def to_h = {action: to_s}

#to_sObject

Serialised descriptor, e.g. ‘“click.esc:prevent@window->foo–bar#handle”`.



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/vident2/stimulus/action.rb', line 70

def to_s
  head =
    if event
      ev = event.to_s
      ev = "#{ev}.#{keyboard}" if keyboard
      ev = "#{ev}#{modifiers.map { |o| ":#{o}" }.join}" if modifiers.any?
      ev = "#{ev}@window" if window
      "#{ev}->"
    else
      ""
    end
  "#{head}#{controller.name}##{method_name}"
end