turbo_boost-elements 0.0.9 → 0.0.11
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 +4 -4
- data/README.md +1 -1
- data/app/assets/builds/@turbo-boost/elements.js +13 -13
- data/app/assets/builds/@turbo-boost/elements.js.map +3 -3
- data/app/javascript/elements/toggle_elements/target_element/focus.js +3 -4
- data/app/javascript/elements/toggle_elements/target_element/index.js +14 -12
- data/app/javascript/elements/toggle_elements/trigger_element/devtool.js +67 -37
- data/app/javascript/elements/toggle_elements/trigger_element/index.js +10 -5
- data/app/javascript/utils/dom.js +6 -0
- data/lib/turbo_boost/elements/tag_builders/toggle_tags_builder.rb +4 -3
- data/lib/turbo_boost/elements/version.rb +1 -1
- metadata +2 -2
@@ -44,10 +44,9 @@ function focusTrixEditorElement (element) {
|
|
44
44
|
}
|
45
45
|
|
46
46
|
function shouldEnhanceFocus (element) {
|
47
|
-
return
|
48
|
-
|
49
|
-
|
50
|
-
)
|
47
|
+
if (!element.tagName.match(/^input|textarea|trix-editor$/i)) return false
|
48
|
+
const toggleTargetElement = element.closest('turbo-boost-toggle-target')
|
49
|
+
return toggleTargetElement && toggleTargetElement.focusSelector
|
51
50
|
}
|
52
51
|
|
53
52
|
function enhanceFocus (element) {
|
@@ -68,7 +68,7 @@ export default class ToggleTargetElement extends ToggleElement {
|
|
68
68
|
this.innerHTML = ''
|
69
69
|
try {
|
70
70
|
this.expanded = false
|
71
|
-
this.
|
71
|
+
this.triggerElement.hideDevtool()
|
72
72
|
} catch {}
|
73
73
|
}
|
74
74
|
|
@@ -86,28 +86,30 @@ export default class ToggleTargetElement extends ToggleElement {
|
|
86
86
|
|
87
87
|
get collapseSelector () {
|
88
88
|
return (
|
89
|
-
this.
|
89
|
+
this.triggerElement.collapseSelector ||
|
90
90
|
this.getAttribute('collapse-selector')
|
91
91
|
)
|
92
92
|
}
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
this.focusTimeout = setTimeout(() => {
|
97
|
-
if (this.focusElement) this.focusElement.focus()
|
98
|
-
}, 50)
|
94
|
+
applyFocus () {
|
95
|
+
if (this.focusElement) this.focusElement.focus()
|
99
96
|
}
|
100
97
|
|
101
98
|
get focusSelector () {
|
102
|
-
|
103
|
-
|
104
|
-
|
99
|
+
let value = this.getAttribute('focus-selector')
|
100
|
+
if (this.triggerElement)
|
101
|
+
value = this.triggerElement.getAttribute('focus-selector') || value
|
102
|
+
return value
|
105
103
|
}
|
106
104
|
|
107
105
|
get focusElement () {
|
108
106
|
return this.querySelector(this.focusSelector)
|
109
107
|
}
|
110
108
|
|
109
|
+
get triggerElement () {
|
110
|
+
return document.getElementById(this.labeledBy)
|
111
|
+
}
|
112
|
+
|
111
113
|
get labeledBy () {
|
112
114
|
return this.getAttribute('aria-labeledby')
|
113
115
|
}
|
@@ -119,10 +121,10 @@ export default class ToggleTargetElement extends ToggleElement {
|
|
119
121
|
}
|
120
122
|
|
121
123
|
get expanded () {
|
122
|
-
return this.
|
124
|
+
return this.triggerElement.expanded
|
123
125
|
}
|
124
126
|
|
125
127
|
set expanded (value) {
|
126
|
-
return (this.
|
128
|
+
return (this.triggerElement.expanded = value)
|
127
129
|
}
|
128
130
|
}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
import {
|
3
3
|
appendHTML,
|
4
4
|
addHighlight,
|
5
|
+
attempt,
|
5
6
|
coordinates,
|
6
7
|
removeHighlight
|
7
8
|
} from '../../../utils/dom'
|
@@ -34,43 +35,57 @@ export default class Devtool {
|
|
34
35
|
this.targetElement = triggerElement.targetElement // SEE: app/javascript/elements/toggle_target_element.js
|
35
36
|
this.morphElement = triggerElement.morphElement
|
36
37
|
|
37
|
-
document.addEventListener('turbo-boost:devtool-enable', event => {
|
38
|
-
const { name } = event.detail
|
39
|
-
if (name === this.name) {
|
40
|
-
addHighlight(this.triggerElement, {
|
41
|
-
outline: '3px dashed blueviolet',
|
42
|
-
outlineOffset: '2px'
|
43
|
-
})
|
44
|
-
}
|
45
|
-
})
|
46
|
-
|
47
|
-
document.addEventListener('turbo-boost:devtool-disable', event => {
|
48
|
-
const { name } = event.detail
|
49
|
-
if (name === this.name) removeHighlight(this.triggerElement)
|
50
|
-
})
|
51
|
-
|
52
38
|
let hideTimeout
|
53
39
|
const debouncedHide = () => {
|
54
40
|
clearTimeout(hideTimeout)
|
55
41
|
hideTimeout = setTimeout(this.hide({ active: false }), 25)
|
56
42
|
}
|
57
43
|
|
58
|
-
|
44
|
+
this.eventListeners['turbo-boost:devtool-enable'] = event => {
|
45
|
+
// LeaderLine.positionByWindowResize = false
|
46
|
+
const { name } = event.detail
|
47
|
+
if (name !== this.name) return
|
48
|
+
|
49
|
+
addHighlight(this.triggerElement, {
|
50
|
+
outline: '3px dashed blueviolet',
|
51
|
+
outlineOffset: '2px'
|
52
|
+
})
|
53
|
+
|
54
|
+
this.hide({ active: false })
|
55
|
+
if (this.active) this.show()
|
56
|
+
}
|
57
|
+
|
58
|
+
this.eventListeners['turbo-boost:devtool-disable'] = event => {
|
59
|
+
const { name } = event.detail
|
60
|
+
if (name === this.name) removeHighlight(this.triggerElement)
|
61
|
+
}
|
62
|
+
|
63
|
+
this.eventListeners['click'] = event => {
|
59
64
|
if (event.target.closest('turbo-boost-devtool-tooltip')) return
|
60
65
|
debouncedHide()
|
66
|
+
}
|
67
|
+
|
68
|
+
this.eventListeners['turbo:load'] = debouncedHide
|
69
|
+
this.eventListeners['turbo-frame:load'] = debouncedHide
|
70
|
+
this.eventListeners[TurboBoost.Commands.events.finish] = debouncedHide
|
71
|
+
|
72
|
+
this.registerEventListeners()
|
73
|
+
}
|
74
|
+
|
75
|
+
registerEventListeners () {
|
76
|
+
Object.entries(this.eventListeners).forEach(([type, listener]) => {
|
77
|
+
addEventListener(type, listener)
|
61
78
|
})
|
79
|
+
}
|
62
80
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
this.show()
|
67
|
-
}
|
81
|
+
unregisterEventListeners () {
|
82
|
+
Object.entries(this.eventListeners).forEach(([type, listener]) => {
|
83
|
+
removeEventListener(type, listener)
|
68
84
|
})
|
85
|
+
}
|
69
86
|
|
70
|
-
|
71
|
-
|
72
|
-
addEventListener(TurboBoost.Commands.events.success, debouncedHide)
|
73
|
-
addEventListener(TurboBoost.Commands.events.finish, debouncedHide)
|
87
|
+
get eventListeners () {
|
88
|
+
return this._eventListeners || (this._eventListeners = {})
|
74
89
|
}
|
75
90
|
|
76
91
|
get enabled () {
|
@@ -88,8 +103,10 @@ export default class Devtool {
|
|
88
103
|
|
89
104
|
show () {
|
90
105
|
if (!this.enabled) return
|
106
|
+
|
91
107
|
if (this.active) return
|
92
108
|
this.active = true
|
109
|
+
|
93
110
|
this.hide({ active: true })
|
94
111
|
|
95
112
|
addHighlight(this.targetElement, {
|
@@ -102,9 +119,12 @@ export default class Devtool {
|
|
102
119
|
outlineOffset: '3px'
|
103
120
|
})
|
104
121
|
|
105
|
-
|
106
|
-
|
107
|
-
this.createTriggerTooltip(
|
122
|
+
this.renderingTooltip = this.createRenderingTooltip()
|
123
|
+
this.targetTooltip = this.createTargetTooltip()
|
124
|
+
this.triggerTooltip = this.createTriggerTooltip(
|
125
|
+
this.targetTooltip,
|
126
|
+
this.renderingTooltip
|
127
|
+
)
|
108
128
|
|
109
129
|
document
|
110
130
|
.querySelectorAll('.leader-line')
|
@@ -140,10 +160,15 @@ export default class Devtool {
|
|
140
160
|
}
|
141
161
|
|
142
162
|
hide ({ active: active = false }) {
|
143
|
-
document.querySelectorAll('.leader-line').forEach(el => el.remove())
|
144
163
|
document
|
145
164
|
.querySelectorAll('turbo-boost-devtool-tooltip')
|
146
|
-
.forEach(
|
165
|
+
.forEach(tooltip => {
|
166
|
+
attempt(() => tooltip.line.remove())
|
167
|
+
attempt(() => tooltip.drag.remove())
|
168
|
+
attempt(() => tooltip.lineToRendering.remove())
|
169
|
+
attempt(() => tooltip.lineToTarget.remove())
|
170
|
+
attempt(() => tooltip.remove())
|
171
|
+
})
|
147
172
|
|
148
173
|
document.querySelectorAll('[data-turbo-boost-highlight]').forEach(el => {
|
149
174
|
if (!el.tagName.match(/turbo-boost-toggle-trigger/i)) removeHighlight(el)
|
@@ -152,10 +177,15 @@ export default class Devtool {
|
|
152
177
|
this.active = active
|
153
178
|
}
|
154
179
|
|
155
|
-
|
180
|
+
createRenderingTooltip () {
|
181
|
+
if (!this.triggerElement.renders)
|
182
|
+
return console.debug(
|
183
|
+
`Unable to create the rendering tooltip! The trigger element must set the 'renders' attribute.`
|
184
|
+
)
|
185
|
+
|
156
186
|
if (!this.triggerElement.morphs)
|
157
187
|
return console.debug(
|
158
|
-
`Unable to create the
|
188
|
+
`Unable to create the rendering tooltip! The trigger element specified the 'morphs' attrbiute but no element matches the DOM id: '${this.triggerElement.morphs}'`
|
159
189
|
)
|
160
190
|
|
161
191
|
const title = `
|
@@ -245,7 +275,7 @@ export default class Devtool {
|
|
245
275
|
return tooltip
|
246
276
|
}
|
247
277
|
|
248
|
-
createTriggerTooltip (targetTooltip,
|
278
|
+
createTriggerTooltip (targetTooltip, renderingTooltip) {
|
249
279
|
if (!this.triggerElement) return
|
250
280
|
const title = `
|
251
281
|
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline;" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
|
@@ -305,16 +335,16 @@ export default class Devtool {
|
|
305
335
|
}
|
306
336
|
}
|
307
337
|
|
308
|
-
if (
|
309
|
-
tooltip.lineToRendering = new LeaderLine(tooltip,
|
338
|
+
if (renderingTooltip) {
|
339
|
+
tooltip.lineToRendering = new LeaderLine(tooltip, renderingTooltip, {
|
310
340
|
...this.leaderLineOptions,
|
311
341
|
color: 'blueviolet',
|
312
342
|
middleLabel: 'renders & morphs',
|
313
343
|
size: 2.1
|
314
344
|
})
|
315
345
|
|
316
|
-
|
317
|
-
|
346
|
+
renderingTooltip.drag.onMove = () => {
|
347
|
+
renderingTooltip.line.position()
|
318
348
|
if (tooltip.lineToTarget) tooltip.lineToTarget.position()
|
319
349
|
tooltip.lineToRendering.position()
|
320
350
|
}
|
@@ -32,6 +32,7 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
32
32
|
removeEventListener(beforeInvokeEvent, this.beforeInvokeHandler)
|
33
33
|
|
34
34
|
this.devtool.hide({ active: false })
|
35
|
+
this.devtool.unregisterEventListeners()
|
35
36
|
delete this.devtool
|
36
37
|
}
|
37
38
|
|
@@ -45,6 +46,8 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
45
46
|
|
46
47
|
addEventListener('turbo-boost:devtools-stop', () => {
|
47
48
|
this.removeEventListener('mouseenter', mouseenter)
|
49
|
+
this.devtool.hide({ active: false })
|
50
|
+
this.devtool.unregisterEventListeners()
|
48
51
|
delete this.devtool
|
49
52
|
})
|
50
53
|
|
@@ -58,7 +61,6 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
58
61
|
}
|
59
62
|
|
60
63
|
onCommandStart (event) {
|
61
|
-
this.targetElement.currentTriggerElement = this
|
62
64
|
this.targetElement.setAttribute('aria-labeledby', this.id)
|
63
65
|
this.targetElement.collapseMatches()
|
64
66
|
this.targetElement.busy = true
|
@@ -83,13 +85,13 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
83
85
|
this.busy = false
|
84
86
|
this.targetElement.busy = false
|
85
87
|
this.morphToggleElements.forEach(el => (el.busy = false))
|
86
|
-
this.expanded = !this.expanded
|
87
88
|
}, delay - 10)
|
88
89
|
|
89
90
|
// runs after the morph is executed
|
90
91
|
setTimeout(() => {
|
91
|
-
|
92
|
-
|
92
|
+
this.targetElement.setAttribute('aria-labeledby', this.id)
|
93
|
+
this.targetElement.applyFocus()
|
94
|
+
}, delay + 100)
|
93
95
|
}
|
94
96
|
|
95
97
|
// a list of views shared between the trigger and target
|
@@ -144,7 +146,10 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
144
146
|
}
|
145
147
|
|
146
148
|
get focusSelector () {
|
147
|
-
return
|
149
|
+
return (
|
150
|
+
this.getAttribute('focus-selector') ||
|
151
|
+
this.targetElement.getAttribute('focus-selector')
|
152
|
+
)
|
148
153
|
}
|
149
154
|
|
150
155
|
// indicates if the toggle state should be remembered across requests
|
data/app/javascript/utils/dom.js
CHANGED
@@ -22,12 +22,13 @@ class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Element
|
|
22
22
|
focus_selector: nil, # CSS selector for the element to focus when the target is expanded
|
23
23
|
method: :toggle, # method to inovke (:show, :hide, :toggle)
|
24
24
|
disabled: false, # disable the trigger
|
25
|
+
expanded: false, # override to force expansion
|
25
26
|
remember: false, # remember ephemeral UI state between requests
|
26
27
|
**kwargs, # generic support for additional element attributes like `class` etc.
|
27
28
|
&block # a Ruby block that emits this trigger's content
|
28
29
|
)
|
29
30
|
kwargs = kwargs.with_indifferent_access
|
30
|
-
kwargs[:id] ||= "#{controls}-toggle-trigger
|
31
|
+
kwargs[:id] ||= "#{controls}-toggle-trigger"
|
31
32
|
|
32
33
|
# command
|
33
34
|
kwargs[:data] ||= {}
|
@@ -36,7 +37,7 @@ class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Element
|
|
36
37
|
# aria
|
37
38
|
kwargs[:aria] ||= {}
|
38
39
|
kwargs[:aria][:controls] = controls # toggle target
|
39
|
-
kwargs[:aria][:expanded] = target_expanded?(controls)
|
40
|
+
kwargs[:aria][:expanded] = expanded || target_expanded?(controls)
|
40
41
|
kwargs[:aria][:atomic] ||= true
|
41
42
|
kwargs[:aria][:relevant] ||= "all"
|
42
43
|
|
@@ -57,8 +58,8 @@ class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Element
|
|
57
58
|
id, # REQUIRED, the `dom_id` for the element
|
58
59
|
collapse_on: [], # list of events that will collapse this target
|
59
60
|
collapse_selector: nil, # CSS selector for other matching targets to collapse when this target is expanded
|
60
|
-
expanded: false, # override to force expansion
|
61
61
|
focus_selector: nil, # CSS selector for the element to focus when this target is expanded
|
62
|
+
expanded: false, # override to force expansion
|
62
63
|
**kwargs, # generic support for additional element attributes like `class` etc.
|
63
64
|
&block # a Ruby block that emits this target's content
|
64
65
|
)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo_boost-elements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Hopkins (hopsoft)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|