Class: Phlex::Stimulus::Components::Controller Abstract

Inherits:
Base
  • Object
show all
Defined in:
lib/phlex/stimulus/components/controller.rb

Overview

This class is abstract.

Abstract class for Phlex components that wrap Stimulus.js controllers.

Defined Under Namespace

Classes: ActionDefinition, ActionParamDefinition, TargetDefinition

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#attrbool, #class_list, #class_list!, event, #event, #h, #image_exists?, #inspect, #merge, #newline

Class Attribute Details

.controller_nameObject

Name of the Stimulus controller

Signature:

  • String



104
105
106
# File 'lib/phlex/stimulus/components/controller.rb', line 104

def controller_name
  @controller_name
end

Class Method Details

.action(name, &block) ⇒ Object

Register an action with parameters that exists on the Stimulus controller.

action :foo do
  param :id
  param :title, optional: true
end

Signature:

  • (Symbol) ?{ [self: ActionDefinition] -> void } -> void



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/phlex/stimulus/components/controller.rb', line 169

def action(name, &block)
  action_def = ActionDefinition.new(
    component:   self,
    action_name: name.to_s,
  )
  action_defs << action_def
  action_def.instance_eval(&block) if block

  eval_buff = String.new
  eval_buff << <<~RUBY
    def #{action_def.ruby_action_method_name}
      "\#{controller_name}##{name}"
    end
  RUBY

  eval_buff << "\ndef #{action_def.ruby_on_method_name}(event_name"
  action_def.params.each do |param|
    eval_buff << ", #{param.param_name}:"
    eval_buff << ' nil' if param.optional
  end
  eval_buff << ")\n"

  eval_buff << "{ action: event(event_name, #{action_def.ruby_action_method_name}), "
  action_def.params.each do |param|
    eval_buff << "param(#{param.param_name.inspect}) => #{param.param_name}, "
  end
  eval_buff << "}.compact\n"
  eval_buff << "end\n"

  instance_eval eval_buff, __FILE__, __LINE__
end

.action_defsObject

Signature:

  • -> Array[ActionDefinition]



116
117
118
# File 'lib/phlex/stimulus/components/controller.rb', line 116

def action_defs
  @action_defs ||= []
end

.actions(*actions) ⇒ Object

Register actions that exist on the Stimulus controller. Will define typed getter methods for each action.

actions :foo, :bar

Signature:

  • (*Symbol) -> void



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/phlex/stimulus/components/controller.rb', line 207

def actions(*actions)
  actions.each do |action|
    action_def = ActionDefinition.new(
      component:   self,
      action_name: action.to_s,
    )
    action_defs << action_def

    instance_eval <<~RUBY, __FILE__, __LINE__ + 1
      def #{action_def.ruby_action_method_name}
        "\#{controller_name}##{action}"
      end

      def #{action_def.ruby_on_method_name}(event_name)
        { action: event(event_name, #{action_def.ruby_action_method_name}) }
      end
    RUBY
  end
end

.controller_pathObject

Signature:

  • -> String



107
108
109
110
111
112
113
# File 'lib/phlex/stimulus/components/controller.rb', line 107

def controller_path
  name = controller_name
  sections = name.split('--')
  subpath = sections.map(&:underscore).join('/')

  "app/javascript/controllers/#{subpath}_controller.ts"
end

.data_target_keyObject

Returns the full name of the data attribute for the controller's targets eg. "data-summary-target"

Signature:

  • -> String



157
158
159
# File 'lib/phlex/stimulus/components/controller.rb', line 157

def data_target_key
  "data-#{target_key}"
end

.dispatched(event_name) ⇒ Object

Constructs a Stimulus dispatched event name eg.

SummaryController.dispatched('ready') #=> "summary:ready"

Signature:

  • (String) -> String



141
142
143
# File 'lib/phlex/stimulus/components/controller.rb', line 141

def dispatched(event_name)
  "#{controller_name}:#{event_name}"
end

.param(param_name) ⇒ Object

Constructs a Stimulus action parameter name eg.

SummaryController.param('id') #=> "summary-id-param"

Signature:

  • (String) -> String



131
132
133
# File 'lib/phlex/stimulus/components/controller.rb', line 131

def param(param_name)
  "#{controller_name}-#{param_name}-param"
end

.target_defsObject

Signature:

  • -> Array[TargetDefinition]



121
122
123
# File 'lib/phlex/stimulus/components/controller.rb', line 121

def target_defs
  @target_defs ||= []
end

.target_keyObject

Returns the name of the data attribute for the controller's targets without the initial "data-" eg. "summary-target"

Signature:

  • -> String



149
150
151
# File 'lib/phlex/stimulus/components/controller.rb', line 149

def target_key
  "#{controller_name}-target"
end

.targets(*targets) ⇒ Object

Register targets that exist on the Stimulus controller. Will define typed getter methods for each target.

Signature:

  • (*Symbol) -> void



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/phlex/stimulus/components/controller.rb', line 231

def targets(*targets)
  targets.each do |target|
    target_str = target.to_s
    target_def = TargetDefinition.new(
      component:   self,
      target_name: target_str,
    )
    target_defs << target_def

    instance_eval <<~RUBY, __FILE__, __LINE__ + 1
      def #{target_def.ruby_target_method_name}
        #{target_str.inspect}
      end

      def #{target_def.ruby_target_anchor_method_name}
        { target_key => #{target_str.inspect} }
      end
    RUBY
  end
end

Instance Method Details

#controller_nameObject

Signature:

  • -> String



255
256
257
# File 'lib/phlex/stimulus/components/controller.rb', line 255

def controller_name
  self.class.controller_name
end

#view_template(&block) ⇒ Object

Signature:

  • ?{ -> void } -> void



261
262
263
264
265
# File 'lib/phlex/stimulus/components/controller.rb', line 261

def view_template(&block)
  div(data: { controller: self.class.controller_name }) do
    block&.call
  end
end