reflex_behaviors 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require ReflexBehaviors::Engine.root.join("lib/reflex_behaviors/tag_builders")
3
+ require_relative "../../../lib/reflex_behaviors/tag_builders"
4
4
 
5
5
  module ReflexBehaviors::ApplicationHelper
6
- def idomatic_partial_path(partial_path)
7
- partial_path.to_s.gsub("/_", "/").split(".").first
8
- end
9
-
10
6
  def current_partial_path
11
7
  path = nil
12
8
  prefix = "app/views/"
@@ -20,15 +16,6 @@ module ReflexBehaviors::ApplicationHelper
20
16
  path[(path.index(prefix) + prefix.length), path.rindex("/")]
21
17
  end
22
18
 
23
- def reflex_render(**kwargs)
24
- kwargs[:partial] = idomatic_partial_path(kwargs[:partial])
25
- kwargs[:assigns] ||= {}
26
- kwargs[:assigns].each { |key, val| kwargs[:assigns][key] = transportable_value(val) }
27
- kwargs[:locals] ||= {}
28
- kwargs[:locals].each { |key, val| kwargs[:locals][key] = transportable_value(val) }
29
- kwargs.to_json
30
- end
31
-
32
19
  def method_missing(name, ...)
33
20
  prefixes = %w[toggle_]
34
21
  prefixes.each do |prefix|
@@ -52,9 +39,4 @@ module ReflexBehaviors::ApplicationHelper
52
39
  def toggle_tag_builder
53
40
  @toggle_tag_builder ||= ReflexBehaviors::TagBuilders::ToggleTagsBuilder.new(self)
54
41
  end
55
-
56
- def transportable_value(value)
57
- return value.to_s unless value.respond_to?(:to_sgid_param)
58
- value.try(:persisted?) ? value.to_sgid_param : nil
59
- end
60
42
  end
@@ -22,6 +22,7 @@ export default class TooltipElement extends HTMLElement {
22
22
  <style>${this.stylesheet}</style>
23
23
  <div>
24
24
  <slot name="title"></slot>
25
+ <slot name="subtitle"></slot>
25
26
  <slot name="content-top"></slot>
26
27
  <slot name="content"></slot>
27
28
  <slot name="content-bottom"></slot>
@@ -52,18 +53,29 @@ export default class TooltipElement extends HTMLElement {
52
53
  opacity: 0.9;
53
54
  outline-offset: 1px;
54
55
  outline: dashed 3px ${this.color};
55
- padding: 8px 12px 8px 12px;
56
+ padding: 12px;
56
57
  position: relative;
57
58
  white-space: nowrap;
58
59
  }
59
60
 
60
61
  slot[name="title"] {
61
- border-bottom: dotted 1px ${this.color};
62
62
  color: ${this.color};
63
- display: inline-block;
63
+ display: block;
64
64
  font-weight: bold;
65
+ width: 100%;
66
+ }
67
+
68
+ slot[name="subtitle"] {
69
+ border-bottom: dotted 1px ${this.color};
70
+ border-top: dotted 1px ${this.color};
71
+ color: ${this.color};
72
+ display: block;
73
+ font-size: 0.8rem;
74
+ font-weight: lighter;
65
75
  margin-bottom: 8px;
66
- padding-bottom: 8px;
76
+ margin-top: 4px;
77
+ padding-bottom: 4px;
78
+ padding-top: 4px;
67
79
  width: 100%;
68
80
  }
69
81
 
@@ -12,29 +12,31 @@ document.addEventListener('reflex-behaviors:devtools-start', () =>
12
12
  supervisor.register('toggle', 'toggles<small>(trigger/target)</small>')
13
13
  )
14
14
 
15
- function appendTooltip (title, content, options = {}) {
15
+ function appendTooltip (title, subtitle, content, options = {}) {
16
16
  let { backgroundColor, color, position } = options
17
17
  color = color || 'white'
18
18
  position = position || 'top'
19
19
  return appendHTML(`
20
20
  <reflex-behaviors-devools-tooltip position="${position}" background-color="${backgroundColor}" color="${color}">
21
21
  <div slot='title'>${title}</div>
22
+ <div slot='subtitle'>${subtitle}</div>
22
23
  ${content}
23
24
  </reflex-behaviors-devools-tooltip>
24
25
  `)
25
26
  }
26
27
 
27
28
  export default class ToggleDevtool {
28
- constructor (trigger) {
29
+ constructor (triggerElement) {
29
30
  this.name = 'toggle'
30
- this.reflex = trigger.dataset.turboReflex
31
- this.trigger = trigger
32
- this.target = trigger.target
31
+ this.reflex = triggerElement.dataset.turboReflex
32
+ this.triggerElement = triggerElement // SEE: app/javascript/elements/toggle_trigger_element.js
33
+ this.targetElement = triggerElement.targetElement // SEE: app/javascript/elements/toggle_target_element.js
34
+ this.morphElement = triggerElement.morphElement
33
35
 
34
36
  document.addEventListener('reflex-behaviors:devtool-enable', event => {
35
37
  const { name } = event.detail
36
38
  if (name === this.name) {
37
- addHighlight(this.trigger, {
39
+ addHighlight(this.triggerElement, {
38
40
  outline: '3px dashed blueviolet',
39
41
  outlineOffset: '2px'
40
42
  })
@@ -43,7 +45,7 @@ export default class ToggleDevtool {
43
45
 
44
46
  document.addEventListener('reflex-behaviors:devtool-disable', event => {
45
47
  const { name } = event.detail
46
- if (name === this.name) removeHighlight(this.trigger)
48
+ if (name === this.name) removeHighlight(this.triggerElement)
47
49
  })
48
50
 
49
51
  let hideTimeout
@@ -73,45 +75,47 @@ export default class ToggleDevtool {
73
75
  activeToggle = this
74
76
  this.hide()
75
77
 
76
- addHighlight(this.target, {
78
+ addHighlight(this.targetElement, {
77
79
  outline: '3px dashed darkcyan',
78
80
  outlineOffset: '-2px'
79
81
  })
80
82
 
81
- addHighlight(this.trigger.renderingElement, {
83
+ addHighlight(this.triggerElement.morphElement, {
82
84
  outline: '3px dashed chocolate',
83
85
  outlineOffset: '3px'
84
86
  })
85
87
 
86
- const renderingTooltip = this.createRenderingTooltip()
88
+ const morphTooltip = this.createMorphTooltip()
87
89
  const targetTooltip = this.createTargetTooltip()
88
- this.createTriggerTooltip(targetTooltip, renderingTooltip)
90
+ this.createTriggerTooltip(targetTooltip, morphTooltip)
89
91
 
90
92
  document
91
93
  .querySelectorAll('.leader-line')
92
94
  .forEach(el => (el.style.zIndex = 100000))
93
95
 
94
96
  const data = {
95
- rendering: {
96
- partial: this.trigger.renderingPartial,
97
- id: this.trigger.renderingInfo.id,
98
- status: this.trigger.renderingElement ? 'OK' : 'Not Found'
97
+ morph: {
98
+ partial: this.triggerElement.renders,
99
+ id: this.triggerElement.morphs,
100
+ status: this.morphElement ? 'OK' : 'Not Found'
99
101
  },
100
102
  trigger: { partial: null, id: null, status: 'Not Found' },
101
103
  target: { partial: null, id: null, status: 'Not Found' }
102
104
  }
103
105
 
104
- if (this.trigger)
106
+ if (this.triggerElement) {
105
107
  data.trigger = {
106
- partial: this.trigger.partial,
107
- id: this.trigger.id,
108
+ partial: this.triggerElement.partial,
109
+ id: this.triggerElement.id,
108
110
  status: 'OK'
109
111
  }
112
+ data.target.id = this.triggerElement.controls
113
+ }
110
114
 
111
- if (this.target)
115
+ if (this.targetElement)
112
116
  data.target = {
113
- partial: this.target.partial,
114
- id: this.target.id,
117
+ partial: this.targetElement.partial,
118
+ id: this.targetElement.id,
115
119
  status: 'OK'
116
120
  }
117
121
 
@@ -133,21 +137,24 @@ export default class ToggleDevtool {
133
137
  if (clearActiveToggle) activeToggle = null
134
138
  }
135
139
 
136
- createRenderingTooltip () {
137
- if (!this.trigger.renderingElement)
140
+ createMorphTooltip () {
141
+ if (!this.triggerElement.morphs)
138
142
  return console.debug(
139
- `Unable to create the rendering tooltip! No element matches the DOM id: '${this.trigger.renderingInfo.id}'`
143
+ `Unable to create the morph tooltip! No element matches the DOM id: '${this.triggerElement.morphs}'`
140
144
  )
141
145
 
142
- const title = `RENDERING (id: ${this.trigger.renderingElement.id ||
143
- 'unknown'})`
144
- const content = `<div slot="content">partial: ${this.trigger.renderingPartial}</div>`
145
- const tooltip = appendTooltip(title, content, {
146
+ const title = 'PARTIAL'
147
+ const subtitle = `
148
+ id: ${this.triggerElement.morphs || 'unknown'}<br>
149
+ partial: ${this.triggerElement.renders || 'unknown'}
150
+ `
151
+ const content = '<div slot="content"></div>'
152
+ const tooltip = appendTooltip(title, subtitle, content, {
146
153
  backgroundColor: 'lightyellow',
147
154
  color: 'chocolate'
148
155
  })
149
156
 
150
- const coords = coordinates(this.trigger.renderingElement)
157
+ const coords = coordinates(this.morphElement)
151
158
  const top = Math.ceil(
152
159
  coords.top + coords.height / 2 - tooltip.offsetHeight / 2
153
160
  )
@@ -155,7 +162,7 @@ export default class ToggleDevtool {
155
162
  tooltip.style.top = `${top}px`
156
163
  tooltip.style.left = `${left}px`
157
164
 
158
- tooltip.line = new LeaderLine(tooltip, this.trigger.renderingElement, {
165
+ tooltip.line = new LeaderLine(tooltip, this.morphElement, {
159
166
  ...this.leaderLineOptions,
160
167
  color: 'chocolate'
161
168
  })
@@ -165,34 +172,38 @@ export default class ToggleDevtool {
165
172
  }
166
173
 
167
174
  createTargetTooltip () {
168
- if (!this.target)
175
+ if (!this.targetElement)
169
176
  return console.debug(
170
- `Unable to create the target tooltip! No element matches the DOM id: '${this.trigger.controls}'`
177
+ `Unable to create the target tooltip! No element matches the DOM id: '${this.triggerElement.controls}'`
171
178
  )
172
179
 
173
- const title = `TARGET (id: ${this.target.id})`
174
- const content = this.target.viewStack
180
+ const title = 'TARGET'
181
+ const subtitle = `
182
+ id: ${this.targetElement.id}<br>
183
+ labeled by: ${this.targetElement.labeledBy}
184
+ `
185
+ const content = this.targetElement.viewStack
175
186
  .reverse()
176
187
  .map((view, index) => {
177
- return this.trigger.sharedViews.includes(view)
188
+ return this.triggerElement.sharedViews.includes(view)
178
189
  ? `<div slot="content-top">${index + 1}. ${view}</div>`
179
190
  : `<div slot="content-bottom">${index + 1}. ${view}</div>`
180
191
  }, this)
181
192
  .join('')
182
193
 
183
- const tooltip = appendTooltip(title, content, {
194
+ const tooltip = appendTooltip(title, subtitle, content, {
184
195
  backgroundColor: 'lightcyan',
185
196
  color: 'darkcyan',
186
197
  position: 'bottom'
187
198
  })
188
199
 
189
- const coords = coordinates(this.target)
200
+ const coords = coordinates(this.targetElement)
190
201
  const top = Math.ceil(coords.top + tooltip.offsetHeight)
191
202
  const left = Math.ceil(coords.left + coords.width + tooltip.offsetWidth / 3)
192
203
  tooltip.style.top = `${top}px`
193
204
  tooltip.style.left = `${left}px`
194
205
 
195
- tooltip.line = new LeaderLine(tooltip, this.target, {
206
+ tooltip.line = new LeaderLine(tooltip, this.targetElement, {
196
207
  ...this.leaderLineOptions,
197
208
  color: 'darkcyan'
198
209
  })
@@ -201,30 +212,34 @@ export default class ToggleDevtool {
201
212
  return tooltip
202
213
  }
203
214
 
204
- createTriggerTooltip (targetTooltip, renderingTooltip) {
205
- if (!this.trigger) return
206
- const title = `TRIGGER (controls: ${this.trigger.controls})`
207
- const content = this.trigger.viewStack
215
+ createTriggerTooltip (targetTooltip, morphTooltip) {
216
+ if (!this.triggerElement) return
217
+ const title = 'TRIGGER'
218
+ const subtitle = `
219
+ id: ${this.triggerElement.id}<br>
220
+ controls: ${this.triggerElement.controls}
221
+ `
222
+ const content = this.triggerElement.viewStack
208
223
  .reverse()
209
224
  .map((view, index) => {
210
- return this.trigger.sharedViews.includes(view)
225
+ return this.triggerElement.sharedViews.includes(view)
211
226
  ? `<div slot="content-top">${index + 1}. ${view}</div>`
212
227
  : `<div slot="content-bottom">${index + 1}. ${view}</div>`
213
228
  }, this)
214
229
  .join('')
215
230
 
216
- const tooltip = appendTooltip(title, content, {
231
+ const tooltip = appendTooltip(title, subtitle, content, {
217
232
  backgroundColor: 'lavender',
218
233
  color: 'blueviolet'
219
234
  })
220
235
 
221
- const coords = coordinates(this.trigger)
236
+ const coords = coordinates(this.triggerElement)
222
237
  const top = Math.ceil(coords.top - tooltip.offsetHeight * 2)
223
238
  const left = Math.ceil(coords.left + coords.width + tooltip.offsetWidth / 3)
224
239
  tooltip.style.top = `${top}px`
225
240
  tooltip.style.left = `${left}px`
226
241
 
227
- tooltip.line = new LeaderLine(this.trigger, tooltip, {
242
+ tooltip.line = new LeaderLine(this.triggerElement, tooltip, {
228
243
  ...this.leaderLineOptions,
229
244
  color: 'blueviolet'
230
245
  })
@@ -244,16 +259,16 @@ export default class ToggleDevtool {
244
259
  }
245
260
  }
246
261
 
247
- if (renderingTooltip) {
248
- tooltip.lineToRendering = new LeaderLine(tooltip, renderingTooltip, {
262
+ if (morphTooltip) {
263
+ tooltip.lineToRendering = new LeaderLine(tooltip, morphTooltip, {
249
264
  ...this.leaderLineOptions,
250
265
  color: 'blueviolet',
251
- middleLabel: 'renders',
266
+ middleLabel: 'renders and morphs',
252
267
  size: 2.1
253
268
  })
254
269
 
255
- renderingTooltip.drag.onMove = () => {
256
- renderingTooltip.line.position()
270
+ morphTooltip.drag.onMove = () => {
271
+ morphTooltip.line.position()
257
272
  if (tooltip.lineToTarget) tooltip.lineToTarget.position()
258
273
  tooltip.lineToRendering.position()
259
274
  }
@@ -261,6 +276,7 @@ export default class ToggleDevtool {
261
276
 
262
277
  tooltip.drag = new PlainDraggable(tooltip)
263
278
  tooltip.drag.onMove = () => {
279
+ console.log('nate', tooltip.line)
264
280
  tooltip.line.position()
265
281
  if (tooltip.lineToTarget) tooltip.lineToTarget.position()
266
282
  if (tooltip.lineToRendering) tooltip.lineToRendering.position()
@@ -8,7 +8,6 @@ export default class ReflexElement extends HTMLElement {
8
8
 
9
9
  connectedCallback () {
10
10
  this.ensureId()
11
- this.dataset.elementOrigin = 'hopsoft/reflex_behaviors'
12
11
  }
13
12
 
14
13
  ensureId () {
@@ -27,8 +26,9 @@ export default class ReflexElement extends HTMLElement {
27
26
  }
28
27
 
29
28
  get viewStack () {
30
- if (!this.dataset.viewStack) return []
31
- return JSON.parse(this.dataset.viewStack)
29
+ const value = this.getAttribute('view-stack')
30
+ if (!value) return []
31
+ return JSON.parse(value)
32
32
  }
33
33
 
34
34
  get partial () {
@@ -1,3 +1,83 @@
1
1
  import ReflexElement from './reflex_element'
2
2
 
3
- export default class ToggleTargetElement extends ReflexElement {}
3
+ export default class ToggleTargetElement extends ReflexElement {
4
+ connectedCallback () {
5
+ super.connectedCallback()
6
+
7
+ this.addEventListener('mouseenter', () =>
8
+ clearTimeout(this.collapseTimeout)
9
+ )
10
+
11
+ this.collapseOn.forEach(name =>
12
+ this.addEventListener(name, () => this.collapse())
13
+ )
14
+ }
15
+
16
+ // TODO: get cached content working properly
17
+ // perhaps use a mechanic other than morph
18
+
19
+ cacheHTML () {
20
+ // this.cachedHTML = this.innerHTML
21
+ }
22
+
23
+ renderCachedHTML () {
24
+ // if (!this.cachedHTML) return
25
+ // this.innerHTML = this.cachedHTML
26
+ }
27
+
28
+ collapse () {
29
+ clearTimeout(this.collapseTimeout)
30
+ this.collapseTimeout = setTimeout(() => {
31
+ this.innerHTML = ''
32
+ try {
33
+ this.currentTriggerElement.expanded = false
34
+ this.currentTriggerElement.hideDevtool()
35
+ } catch {}
36
+ }, 250)
37
+ }
38
+
39
+ collapseMatches () {
40
+ document.querySelectorAll(this.collapseSelector).forEach(el => {
41
+ if (el === this) return
42
+ if (el.collapse) el.collapse()
43
+ })
44
+ }
45
+
46
+ get collapseSelector () {
47
+ if (
48
+ this.currentTriggerElement &&
49
+ this.currentTriggerElement.collapseSelector
50
+ )
51
+ return this.currentTriggerElement.collapseSelector
52
+ return this.getAttribute('collapse-selector')
53
+ }
54
+
55
+ focus () {
56
+ clearTimeout(this.focusTimeout)
57
+ this.focusTimeout = setTimeout(() => {
58
+ if (!this.focusElement) return
59
+ this.focusElement.focus()
60
+ this.focusElement.scrollIntoView({ block: 'center', behavior: 'smooth' })
61
+ }, 50)
62
+ }
63
+
64
+ get focusSelector () {
65
+ if (this.currentTriggerElement && this.currentTriggerElement.focusSelector)
66
+ return this.currentTriggerElement.focusSelector
67
+ return this.getAttribute('focus-selector')
68
+ }
69
+
70
+ get focusElement () {
71
+ return this.querySelector(this.focusSelector)
72
+ }
73
+
74
+ get labeledBy () {
75
+ return this.getAttribute('aria-labeledby')
76
+ }
77
+
78
+ get collapseOn () {
79
+ const value = this.getAttribute('collapse-on')
80
+ if (!value) return []
81
+ return JSON.parse(value)
82
+ }
83
+ }
@@ -5,14 +5,38 @@ import ToggleDevtool from '../devtools/toggle'
5
5
  export default class ToggleTriggerElement extends ReflexElement {
6
6
  connectedCallback () {
7
7
  super.connectedCallback()
8
+
9
+ if (this.targetElement) {
10
+ this.targetElement.setAttribute('aria-labeledby', this.id)
11
+ }
12
+
13
+ this.addEventListener(TurboReflex.events.start, () => {
14
+ this.busy = true
15
+ this.targetElement.currentTriggerElement = this
16
+ this.targetElement.renderCachedHTML()
17
+ })
18
+
19
+ this.addEventListener(TurboReflex.events.success, () => {
20
+ this.busy = false
21
+ this.targetElement.focus()
22
+ this.targetElement.collapseMatches()
23
+ this.targetElement.cacheHTML()
24
+ })
25
+
26
+ this.addEventListener(TurboReflex.events.finish, () => (this.busy = false))
27
+
28
+ this.initializeDevtool()
29
+ }
30
+
31
+ initializeDevtool () {
8
32
  const mouseenter = () => this.devtool.show()
9
33
 
10
- document.addEventListener('reflex-behaviors:devtools-start', () => {
34
+ addEventListener('reflex-behaviors:devtools-start', () => {
11
35
  this.devtool = new ToggleDevtool(this)
12
36
  this.addEventListener('mouseenter', mouseenter)
13
37
  })
14
38
 
15
- document.addEventListener('reflex-behaviors:devtools-stop', () => {
39
+ addEventListener('reflex-behaviors:devtools-stop', () => {
16
40
  this.removeEventListener('mouseenter', mouseenter)
17
41
  delete this.devtool
18
42
  })
@@ -20,79 +44,76 @@ export default class ToggleTriggerElement extends ReflexElement {
20
44
  if (DevtoolSupervisor.started) DevtoolSupervisor.restart()
21
45
  }
22
46
 
23
- collapse () {
24
- try {
25
- this.target.remove()
26
- this.setAttribute('aria-expanded', false)
27
- } catch (error) {
28
- console.error('Failed to collapse toggle-trigger target!', error)
29
- }
47
+ hideDevtool () {
48
+ if (this.devtool) this.devtool.hide(true)
30
49
  }
31
50
 
51
+ // a list of views shared between the trigger and target
32
52
  get sharedViews () {
33
- if (!this.target) return []
34
- if (!this.target.viewStack) return []
53
+ if (!this.targetElement) return []
54
+ if (!this.targetElement.viewStack) return []
35
55
  const reducer = (memo, view) => {
36
- if (this.target.viewStack.includes(view)) memo.push(view)
56
+ if (this.targetElement.viewStack.includes(view)) memo.push(view)
37
57
  return memo
38
58
  }
39
59
  return this.viewStack.reduce(reducer.bind(this), [])
40
60
  }
41
61
 
42
- get renderingInfo () {
43
- if (!this.dataset.render) return {}
44
- return JSON.parse(this.dataset.render)
62
+ // the partial to render
63
+ get renders () {
64
+ return this.getAttribute('renders')
65
+ }
66
+
67
+ // the renderered partial's top wrapping dom_id
68
+ get morphs () {
69
+ return this.getAttribute('morphs')
45
70
  }
46
71
 
47
- get renderingPartial () {
48
- return this.renderingInfo.partial
72
+ // the morph element
73
+ get morphElement () {
74
+ if (!this.morphs) return null
75
+ return document.getElementById(this.morphs)
49
76
  }
50
77
 
51
- get renderingElement () {
52
- const { id } = this.renderingInfo
53
- if (!id) return null
54
- return document.getElementById(id)
78
+ // the target's dom_id
79
+ get controls () {
80
+ return this.getAttribute('aria-controls')
81
+ }
82
+
83
+ // the target element
84
+ get targetElement () {
85
+ if (!this.controls) return null
86
+ return document.getElementById(this.controls)
87
+ }
88
+
89
+ get collapseSelector () {
90
+ return this.getAttribute('collapse-selector')
55
91
  }
56
92
 
93
+ get focusSelector () {
94
+ return this.getAttribute('focus-selector')
95
+ }
96
+
97
+ // indicates if the target is expanded
57
98
  get expanded () {
58
99
  return this.getAttribute('aria-expanded') === 'true'
59
100
  }
60
101
 
61
- get controls () {
62
- return this.getAttribute('aria-controls')
102
+ set expanded (value) {
103
+ this.setAttribute('aria-expanded', !!value)
63
104
  }
64
105
 
65
- get target () {
66
- return document.getElementById(this.controls)
106
+ // indicates if the target is expanded
107
+ get collapsed () {
108
+ return !this.expanded
67
109
  }
68
110
 
69
- get active () {
70
- return this.getAttribute('data-active') === 'true'
111
+ // indicates if an rpc call is active/busy
112
+ get busy () {
113
+ return this.getAttribute('busy') === 'true'
71
114
  }
72
115
 
73
- set active (value) {
74
- this.setAttribute('data-active', !!value)
116
+ set busy (value) {
117
+ this.setAttribute('busy', !!value)
75
118
  }
76
119
  }
77
-
78
- addEventListener(
79
- TurboReflex.events.start,
80
- event => (event.target.active = true)
81
- )
82
- addEventListener(
83
- TurboReflex.events.success,
84
- event => (event.target.active = false)
85
- )
86
- addEventListener(
87
- TurboReflex.events.finish,
88
- event => (event.target.active = false)
89
- )
90
-
91
- addEventListener('click', event => {
92
- if (event.target.tagName.match(/reflex-behaviors-devtool/i)) return
93
- setTimeout(() => {
94
- const selector =
95
- 'toggle-trigger[aria-controls][aria-expanded="true"][data-auto-collapse="true"]'
96
- document.querySelectorAll(selector).forEach(trigger => trigger.collapse())
97
- })
98
- })
@@ -21,19 +21,22 @@ class ReflexBehaviors::ApplicationReflex < TurboReflex::Base
21
21
  protected
22
22
 
23
23
  def render_payload
24
- return {} if element.dataset.render.blank?
25
- @render_payload ||= JSON.parse(element.dataset.render).deep_symbolize_keys.tap do |payload|
26
- payload[:assigns] = {} if payload[:assigns].blank?
27
- payload[:assigns].each { |key, value| payload[:assigns][key] = hydrated_value(value) }
28
-
29
- payload[:locals] = {} if payload[:locals].blank?
30
- payload[:locals].each { |key, value| payload[:locals][key] = hydrated_value(value) }
31
- end
24
+ return {} if element.renders.blank?
25
+ @render_payload ||= {partial: idomatic_partial_path(element.renders)}.tap do |payload|
26
+ if element.assigns.present?
27
+ payload[:assigns] = JSON.parse(element.assigns)
28
+ payload[:assigns].each { |key, value| payload[:assigns][key] = hydrate_value(value) }
29
+ end
30
+ if element.locals.present?
31
+ payload[:locals] = JSON.parse(element.locals)
32
+ payload[:locals].each { |key, value| payload[:locals][key] = hydrate_value(value) }
33
+ end
34
+ end.deep_symbolize_keys
32
35
  end
33
36
 
34
37
  private
35
38
 
36
- def hydrated_value(value)
39
+ def hydrate_value(value)
37
40
  hydrated = begin
38
41
  GlobalID::Locator.locate_signed(value)
39
42
  rescue
@@ -41,4 +44,8 @@ class ReflexBehaviors::ApplicationReflex < TurboReflex::Base
41
44
  end
42
45
  hydrated.blank? ? nil : hydrated
43
46
  end
47
+
48
+ def idomatic_partial_path(partial_path)
49
+ partial_path.to_s.gsub("/_", "/").split(".").first
50
+ end
44
51
  end