Class: Ruwi::Component

Inherits:
Object
  • Object
show all
Defined in:
lib/ruwi/runtime/component.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(props = {}, event_handlers = {}, parent_component = nil) ⇒ Component

Returns a new instance of Component.



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ruwi/runtime/component.rb', line 33

def initialize(props = {}, event_handlers = {}, parent_component = nil)
  @props = props
  @is_mounted = false
  @vdom = nil
  @host_el = nil
  @state = initialize_state
  @template = self.class.class_variable_get(:@@template)
  @event_handlers = event_handlers
  @parent_component = parent_component
  @dispatcher = Ruwi::Dispatcher.new
  @subscriptions = []
end

Instance Attribute Details

#propsObject (readonly)

Returns the value of attribute props.



46
47
48
# File 'lib/ruwi/runtime/component.rb', line 46

def props
  @props
end

#stateObject (readonly)

Returns the value of attribute state.



46
47
48
# File 'lib/ruwi/runtime/component.rb', line 46

def state
  @state
end

Instance Method Details

#elementsArray<JS::Object>

Get VDOM elements

Returns:

  • (Array<JS::Object>)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ruwi/runtime/component.rb', line 68

def elements
  return [] if @vdom.nil?

  if @vdom.type == Ruwi::Vdom::DOM_TYPES[:FRAGMENT]
    Ruwi::Vdom.extract_children(@vdom).flat_map do |child|
      if child.type == Ruwi::Vdom::DOM_TYPES[:COMPONENT]
        child.component.elements
      else
        [child.el]
      end
    end
  else
    [@vdom.el]
  end
end

#emit(event_name, payload = nil) ⇒ Object

Emit an event

Parameters:

  • event_name (String)

    Event name

  • payload (Object, nil) (defaults to: nil)

    Event payload



162
163
164
# File 'lib/ruwi/runtime/component.rb', line 162

def emit(event_name, payload = nil)
  @dispatcher.dispatch(event_name, payload) if @dispatcher
end

#first_elementJS::Object?

Get the first element

Returns:

  • (JS::Object, nil)


86
87
88
# File 'lib/ruwi/runtime/component.rb', line 86

def first_element
  elements[0]
end

#mount(host_el, index = nil) ⇒ Object

Mount component

Parameters:

  • host_el (JS::Object)

    Host element

  • index (Integer, nil) (defaults to: nil)

    Insert position



133
134
135
136
137
138
139
140
141
142
# File 'lib/ruwi/runtime/component.rb', line 133

def mount(host_el, index = nil)
  raise "Component is already mounted" if @is_mounted

  @vdom = template
  Ruwi::Dom::MountDom.execute(@vdom, host_el, index, self)
  wire_event_handlers

  @host_el = host_el
  @is_mounted = true
end

#offsetInteger

Get offset within host element

Returns:

  • (Integer)


92
93
94
95
96
97
98
99
# File 'lib/ruwi/runtime/component.rb', line 92

def offset
  if @vdom.type == Ruwi::Vdom::DOM_TYPES[:FRAGMENT]
    children = @host_el[:children].to_a
    children.index(first_element) || 0
  else
    0
  end
end

#on_mountedObject



48
49
50
51
52
53
54
55
# File 'lib/ruwi/runtime/component.rb', line 48

def on_mounted
  on_mounted_proc = self.class.class_variable_get(:@@on_mounted)
  if on_mounted_proc.arity == 0
    instance_exec(&on_mounted_proc)
  else
    on_mounted_proc.call(self)
  end
end

#on_unmountedObject



57
58
59
60
61
62
63
64
# File 'lib/ruwi/runtime/component.rb', line 57

def on_unmounted
  on_unmounted_proc = self.class.class_variable_get(:@@on_unmounted)
  if on_unmounted_proc.arity == 0
    instance_exec(&on_unmounted_proc)
  else
    on_unmounted_proc.call(self)
  end
end

#templateRuwi::Vdom

Returns:



122
123
124
125
126
127
128
# File 'lib/ruwi/runtime/component.rb', line 122

def template
  if @template.arity == 0
    instance_exec(&@template)
  else
    @template.call(self)
  end
end

#unmountObject

Unmount component



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ruwi/runtime/component.rb', line 145

def unmount
  raise "Component is not mounted" unless @is_mounted

  Ruwi::Dom::DestroyDom.execute(@vdom)

  # Safely handle subscriptions, filtering out nil values
  @subscriptions.compact.each { |unsubscription| unsubscription.call }

  @vdom = nil
  @host_el = nil
  @is_mounted = false
  @subscriptions = []
end

#update_props(new_props) ⇒ Object

Update props

Parameters:

  • new_props (Hash)

    New props



113
114
115
116
117
118
119
# File 'lib/ruwi/runtime/component.rb', line 113

def update_props(new_props)
  merged_props = @props.merge(new_props)
  return if @props == merged_props

  @props = merged_props
  patch
end

#update_state(new_state) ⇒ Object

Update state

Parameters:

  • new_state (Hash)

    New state



103
104
105
106
107
108
109
# File 'lib/ruwi/runtime/component.rb', line 103

def update_state(new_state)
  merged_state = @state.merge(new_state)
  return if @state == merged_state

  @state = merged_state
  patch
end