turbo_boost-elements 0.0.8 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/builds/@turbo-boost/elements.js +65 -26
- data/app/assets/builds/@turbo-boost/elements.js.map +4 -4
- data/app/commands/turbo_boost/elements/toggle_command.rb +0 -1
- data/app/javascript/devtools/elements/tooltip_element.js +15 -7
- data/app/javascript/devtools/supervisor.js +1 -0
- data/app/javascript/elements/index.js +6 -2
- data/app/javascript/elements/{toggle_target_focus.js → toggle_elements/target_element/focus.js} +0 -0
- data/app/javascript/elements/toggle_elements/target_element/index.js +138 -0
- data/app/javascript/elements/toggle_elements/toggle_element/index.js +83 -0
- data/app/javascript/{devtools/toggle.js → elements/toggle_elements/trigger_element/devtool.js} +135 -57
- data/app/javascript/elements/toggle_elements/trigger_element/index.js +177 -0
- data/app/javascript/elements/{turbo_boost_element.js → turbo_boost_element/index.js} +2 -2
- data/app/javascript/utils/dom.js +13 -6
- data/lib/turbo_boost/elements/engine.rb +1 -0
- data/lib/turbo_boost/elements/tag_builders/base_tag_builder.rb +18 -2
- data/lib/turbo_boost/elements/tag_builders/toggle_tags_builder.rb +16 -12
- data/lib/turbo_boost/elements/version.rb +1 -1
- metadata +10 -9
- data/app/javascript/elements/toggle_target_element.js +0 -84
- data/app/javascript/elements/toggle_trigger_element.js +0 -122
@@ -84,29 +84,37 @@ export default class TooltipElement extends HTMLElement {
|
|
84
84
|
display: block;
|
85
85
|
font-size: 0.8rem;
|
86
86
|
font-weight: lighter;
|
87
|
-
margin-bottom:
|
88
|
-
margin-top:
|
87
|
+
margin-bottom: 12px;
|
88
|
+
margin-top: 8px;
|
89
89
|
padding-bottom: 4px;
|
90
90
|
padding-top: 4px;
|
91
91
|
width: 100%;
|
92
92
|
}
|
93
93
|
|
94
|
+
slot[name="content-top"],
|
95
|
+
slot[name="content"],
|
96
|
+
slot[name="content-bottom"] {
|
97
|
+
display: block;
|
98
|
+
font-weight: normal;
|
99
|
+
}
|
100
|
+
|
94
101
|
slot[name="content-top"] {
|
95
102
|
color: ${this.color};
|
96
|
-
|
103
|
+
margin-bottom: 8px;
|
104
|
+
}
|
105
|
+
|
106
|
+
slot[name="content"],
|
107
|
+
slot[name="content-bottom"] {
|
97
108
|
opacity: 0.7;
|
109
|
+
padding-left: 12px;
|
98
110
|
}
|
99
111
|
|
100
112
|
slot[name="content"] {
|
101
113
|
color: ${this.color};
|
102
|
-
font-weight: normal;
|
103
|
-
opacity: 0.7;
|
104
114
|
}
|
105
115
|
|
106
116
|
slot[name="content-bottom"] {
|
107
117
|
color: red;
|
108
|
-
font-weight: normal;
|
109
|
-
opacity: 0.7;
|
110
118
|
}
|
111
119
|
`
|
112
120
|
}
|
@@ -81,6 +81,7 @@ addEventListener('turbo:load', autoRestart)
|
|
81
81
|
addEventListener('turbo-frame:load', autoRestart)
|
82
82
|
addEventListener(TurboBoost.Commands.events.success, autoRestart)
|
83
83
|
addEventListener(TurboBoost.Commands.events.finish, autoRestart)
|
84
|
+
addEventListener('turbo-boost:devtools-connect', autoRestart)
|
84
85
|
addEventListener('turbo-boost:devtools-close', stop)
|
85
86
|
|
86
87
|
function register (name, label) {
|
@@ -1,5 +1,9 @@
|
|
1
|
-
import
|
2
|
-
import
|
1
|
+
import TurboBoostElement from './turbo_boost_element'
|
2
|
+
import ToggleTargetElement from './toggle_elements/target_element'
|
3
|
+
import ToggleTriggerElement from './toggle_elements/trigger_element'
|
3
4
|
|
5
|
+
// Valid custom element names: https://html.spec.whatwg.org/#valid-custom-element-name
|
6
|
+
|
7
|
+
customElements.define('turbo-boost', TurboBoostElement)
|
4
8
|
customElements.define('turbo-boost-toggle-target', ToggleTargetElement)
|
5
9
|
customElements.define('turbo-boost-toggle-trigger', ToggleTriggerElement)
|
data/app/javascript/elements/{toggle_target_focus.js → toggle_elements/target_element/focus.js}
RENAMED
File without changes
|
@@ -0,0 +1,138 @@
|
|
1
|
+
import ToggleElement from '../toggle_element'
|
2
|
+
import './focus'
|
3
|
+
|
4
|
+
export default class ToggleTargetElement extends ToggleElement {
|
5
|
+
connectedCallback () {
|
6
|
+
super.connectedCallback()
|
7
|
+
|
8
|
+
this.mouseenterHandler = this.onMouseenter.bind(this)
|
9
|
+
this.addEventListener('mouseenter', this.mouseenterHandler)
|
10
|
+
|
11
|
+
this.collapseHandler = this.collapse.bind(this)
|
12
|
+
this.collapseNowHandler = this.collapseNow.bind(this)
|
13
|
+
|
14
|
+
this.collapseOn.forEach(entry => {
|
15
|
+
const parts = entry.split('@')
|
16
|
+
const name = parts[0]
|
17
|
+
|
18
|
+
if (parts.length > 1) {
|
19
|
+
const target = parts[1].match(/^self|window$/) ? self : self[parts[1]]
|
20
|
+
target.addEventListener(name, this.collapseNowHandler)
|
21
|
+
} else {
|
22
|
+
this.addEventListener(name, this.collapseHandler)
|
23
|
+
}
|
24
|
+
})
|
25
|
+
}
|
26
|
+
|
27
|
+
disconnectedCallback () {
|
28
|
+
this.removeEventListener('mouseenter', this.mouseenterHandler)
|
29
|
+
|
30
|
+
this.collapseOn.forEach(entry => {
|
31
|
+
const parts = entry.split('@')
|
32
|
+
const name = parts[0]
|
33
|
+
|
34
|
+
if (parts.length > 1) {
|
35
|
+
const target = parts[1].match(/^self|window$/) ? self : self[parts[1]]
|
36
|
+
target.removeEventListener(name, this.collapseNowHandler)
|
37
|
+
} else {
|
38
|
+
this.removeEventListener(name, this.collapseHandler)
|
39
|
+
}
|
40
|
+
})
|
41
|
+
}
|
42
|
+
|
43
|
+
// TODO: get cached content working properly
|
44
|
+
// perhaps use a mechanic other than morph
|
45
|
+
|
46
|
+
// TODO: implement cache (similar to Turbo Drive restoration visit)
|
47
|
+
cacheHTML () {
|
48
|
+
// this.cachedHTML = this.innerHTML
|
49
|
+
}
|
50
|
+
|
51
|
+
// TODO: implement cache (similar to Turbo Drive restoration visit)
|
52
|
+
renderCachedHTML () {
|
53
|
+
// if (!this.cachedHTML) return
|
54
|
+
// this.innerHTML = this.cachedHTML
|
55
|
+
}
|
56
|
+
|
57
|
+
onMouseenter () {
|
58
|
+
clearTimeout(this.collapseTimeout)
|
59
|
+
}
|
60
|
+
|
61
|
+
collapse (delay = 250) {
|
62
|
+
clearTimeout(this.collapseTimeout)
|
63
|
+
if (typeof delay !== 'number') delay = 250
|
64
|
+
|
65
|
+
if (delay > 0)
|
66
|
+
return (this.collapseTimeout = setTimeout(() => this.collapse(0), delay))
|
67
|
+
|
68
|
+
this.innerHTML = ''
|
69
|
+
try {
|
70
|
+
this.expanded = false
|
71
|
+
this.triggerElement.hideDevtool()
|
72
|
+
} catch {}
|
73
|
+
}
|
74
|
+
|
75
|
+
collapseNow (event) {
|
76
|
+
if (event.target.closest('turbo-boost-devtool-tooltip')) return
|
77
|
+
this.collapse(0)
|
78
|
+
}
|
79
|
+
|
80
|
+
collapseMatches () {
|
81
|
+
document.querySelectorAll(this.collapseSelector).forEach(el => {
|
82
|
+
if (el === this) return
|
83
|
+
if (el.collapse) el.collapse(0)
|
84
|
+
})
|
85
|
+
}
|
86
|
+
|
87
|
+
get collapseSelector () {
|
88
|
+
return (
|
89
|
+
this.triggerElement.collapseSelector ||
|
90
|
+
this.getAttribute('collapse-selector')
|
91
|
+
)
|
92
|
+
}
|
93
|
+
|
94
|
+
focus () {
|
95
|
+
clearTimeout(this.focusTimeout)
|
96
|
+
this.focusTimeout = setTimeout(() => {
|
97
|
+
if (this.focusElement) this.focusElement.focus()
|
98
|
+
}, 50)
|
99
|
+
}
|
100
|
+
|
101
|
+
get focusSelector () {
|
102
|
+
let value = this.getAttribute('focus-selector')
|
103
|
+
if (this.triggerElement)
|
104
|
+
value = this.triggerElement.getAttribute('focus-selector') || value
|
105
|
+
return value
|
106
|
+
}
|
107
|
+
|
108
|
+
get focusElement () {
|
109
|
+
return this.querySelector(this.focusSelector)
|
110
|
+
}
|
111
|
+
|
112
|
+
get triggerElement () {
|
113
|
+
return (
|
114
|
+
document.getElementById(this.labeledBy) ||
|
115
|
+
document.querySelector(
|
116
|
+
`turbo-boost-toggle-trigger[aria-controls="${this.id}"]`
|
117
|
+
)
|
118
|
+
)
|
119
|
+
}
|
120
|
+
|
121
|
+
get labeledBy () {
|
122
|
+
return this.getAttribute('aria-labeledby')
|
123
|
+
}
|
124
|
+
|
125
|
+
get collapseOn () {
|
126
|
+
const value = this.getAttribute('collapse-on')
|
127
|
+
if (!value) return []
|
128
|
+
return JSON.parse(value)
|
129
|
+
}
|
130
|
+
|
131
|
+
get expanded () {
|
132
|
+
return this.triggerElement.expanded
|
133
|
+
}
|
134
|
+
|
135
|
+
set expanded (value) {
|
136
|
+
return (this.triggerElement.expanded = value)
|
137
|
+
}
|
138
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import TurboBoostElement from '../../turbo_boost_element'
|
2
|
+
|
3
|
+
const html = `
|
4
|
+
<turbo-boost>
|
5
|
+
<slot name="busy" hidden></slot>
|
6
|
+
<slot></slot>
|
7
|
+
</turbo-boost>
|
8
|
+
`
|
9
|
+
|
10
|
+
export const busyDelay = 100 // milliseconds - time to wait before showing busy element
|
11
|
+
export const busyDuration = 400 // milliseconds - minimum time that busy element is shown
|
12
|
+
|
13
|
+
export default class ToggleElement extends TurboBoostElement {
|
14
|
+
constructor () {
|
15
|
+
super(html)
|
16
|
+
}
|
17
|
+
|
18
|
+
// TODO: Should we timeout after a theoretical max wait time?
|
19
|
+
// The idea being that a server error occurred and the toggle failed.
|
20
|
+
showBusyElement () {
|
21
|
+
clearTimeout(this.showBusyElementTimeout)
|
22
|
+
clearTimeout(this.hideBusyElementTimeout)
|
23
|
+
|
24
|
+
if (!this.busyElement) return
|
25
|
+
|
26
|
+
this.busyStartedAt = Date.now() + busyDelay
|
27
|
+
this.showBusyElementTimeout = setTimeout(() => {
|
28
|
+
this.busySlotElement.hidden = false
|
29
|
+
this.defaultSlotElement.hidden = true
|
30
|
+
}, busyDelay)
|
31
|
+
}
|
32
|
+
|
33
|
+
hideBusyElement () {
|
34
|
+
clearTimeout(this.showBusyElementTimeout)
|
35
|
+
clearTimeout(this.hideBusyElementTimeout)
|
36
|
+
|
37
|
+
if (!this.busyElement) return
|
38
|
+
|
39
|
+
let delay = busyDuration - (Date.now() - this.busyStartedAt)
|
40
|
+
if (delay < 0) delay = 0
|
41
|
+
|
42
|
+
delete this.busyStartedAt
|
43
|
+
this.hideBusyElementTimeout = setTimeout(() => {
|
44
|
+
this.busySlotElement.hidden = true
|
45
|
+
this.defaultSlotElement.hidden = false
|
46
|
+
}, delay)
|
47
|
+
}
|
48
|
+
|
49
|
+
get busyElement () {
|
50
|
+
return this.querySelector(':scope > [slot="busy"]')
|
51
|
+
}
|
52
|
+
|
53
|
+
get busySlotElement () {
|
54
|
+
return this.shadowRoot.querySelector('slot[name="busy"]')
|
55
|
+
}
|
56
|
+
|
57
|
+
get defaultSlotElement () {
|
58
|
+
return this.shadowRoot.querySelector('slot:not([name])')
|
59
|
+
}
|
60
|
+
|
61
|
+
// indicates if an rpc call is active/busy
|
62
|
+
get busy () {
|
63
|
+
return this.getAttribute('busy') === 'true'
|
64
|
+
}
|
65
|
+
|
66
|
+
// indicates if an rpc call is active/busy
|
67
|
+
set busy (value) {
|
68
|
+
value = !!value
|
69
|
+
if (this.busy === value) return
|
70
|
+
this.setAttribute('busy', value)
|
71
|
+
if (value) this.showBusyElement()
|
72
|
+
else this.hideBusyElement()
|
73
|
+
}
|
74
|
+
|
75
|
+
get busyStartedAt () {
|
76
|
+
if (!this.dataset.busyStartedAt) return 0
|
77
|
+
return Number(this.dataset.busyStartedAt)
|
78
|
+
}
|
79
|
+
|
80
|
+
set busyStartedAt (value) {
|
81
|
+
this.dataset.busyStartedAt = value
|
82
|
+
}
|
83
|
+
}
|
data/app/javascript/{devtools/toggle.js → elements/toggle_elements/trigger_element/devtool.js}
RENAMED
@@ -1,15 +1,17 @@
|
|
1
|
+
// Icons courtesy of https://feathericons.com/
|
1
2
|
import {
|
2
3
|
appendHTML,
|
3
4
|
addHighlight,
|
5
|
+
attempt,
|
4
6
|
coordinates,
|
5
7
|
removeHighlight
|
6
|
-
} from '
|
7
|
-
import supervisor from '
|
8
|
+
} from '../../../utils/dom'
|
9
|
+
import supervisor from '../../../devtools/supervisor'
|
8
10
|
|
9
11
|
let activeToggle
|
10
12
|
|
11
13
|
document.addEventListener('turbo-boost:devtools-start', () =>
|
12
|
-
supervisor.register('toggle', 'toggles
|
14
|
+
supervisor.register('toggle', 'toggles')
|
13
15
|
)
|
14
16
|
|
15
17
|
function appendTooltip (title, subtitle, content, options = {}) {
|
@@ -25,7 +27,7 @@ function appendTooltip (title, subtitle, content, options = {}) {
|
|
25
27
|
`)
|
26
28
|
}
|
27
29
|
|
28
|
-
export default class
|
30
|
+
export default class Devtool {
|
29
31
|
constructor (triggerElement) {
|
30
32
|
this.name = 'toggle'
|
31
33
|
this.command = triggerElement.dataset.turboCommand
|
@@ -33,47 +35,79 @@ export default class ToggleDevtool {
|
|
33
35
|
this.targetElement = triggerElement.targetElement // SEE: app/javascript/elements/toggle_target_element.js
|
34
36
|
this.morphElement = triggerElement.morphElement
|
35
37
|
|
36
|
-
|
38
|
+
let hideTimeout
|
39
|
+
const debouncedHide = () => {
|
40
|
+
clearTimeout(hideTimeout)
|
41
|
+
hideTimeout = setTimeout(this.hide({ active: false }), 25)
|
42
|
+
}
|
43
|
+
|
44
|
+
this.eventListeners['turbo-boost:devtool-enable'] = event => {
|
45
|
+
// LeaderLine.positionByWindowResize = false
|
37
46
|
const { name } = event.detail
|
38
|
-
if (name
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
44
|
-
})
|
47
|
+
if (name !== this.name) return
|
48
|
+
|
49
|
+
addHighlight(this.triggerElement, {
|
50
|
+
outline: '3px dashed blueviolet',
|
51
|
+
outlineOffset: '2px'
|
52
|
+
})
|
45
53
|
|
46
|
-
|
54
|
+
this.hide({ active: false })
|
55
|
+
if (this.active) this.show()
|
56
|
+
}
|
57
|
+
|
58
|
+
this.eventListeners['turbo-boost:devtool-disable'] = event => {
|
47
59
|
const { name } = event.detail
|
48
60
|
if (name === this.name) removeHighlight(this.triggerElement)
|
49
|
-
})
|
50
|
-
|
51
|
-
let hideTimeout
|
52
|
-
const debouncedHide = () => {
|
53
|
-
clearTimeout(hideTimeout)
|
54
|
-
hideTimeout = setTimeout(this.hide(true), 25)
|
55
61
|
}
|
56
62
|
|
57
|
-
|
63
|
+
this.eventListeners['click'] = event => {
|
58
64
|
if (event.target.closest('turbo-boost-devtool-tooltip')) return
|
59
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)
|
78
|
+
})
|
79
|
+
}
|
80
|
+
|
81
|
+
unregisterEventListeners () {
|
82
|
+
Object.entries(this.eventListeners).forEach(([type, listener]) => {
|
83
|
+
removeEventListener(type, listener)
|
60
84
|
})
|
85
|
+
}
|
61
86
|
|
62
|
-
|
63
|
-
|
64
|
-
addEventListener(TurboBoost.Commands.events.success, debouncedHide)
|
65
|
-
addEventListener(TurboBoost.Commands.events.finish, debouncedHide)
|
87
|
+
get eventListeners () {
|
88
|
+
return this._eventListeners || (this._eventListeners = {})
|
66
89
|
}
|
67
90
|
|
68
91
|
get enabled () {
|
69
92
|
return supervisor.enabled(this.name)
|
70
93
|
}
|
71
94
|
|
95
|
+
get active () {
|
96
|
+
return activeToggle === this
|
97
|
+
}
|
98
|
+
|
99
|
+
set active (value) {
|
100
|
+
if (value) activeToggle = this
|
101
|
+
else activeToggle = null
|
102
|
+
}
|
103
|
+
|
72
104
|
show () {
|
73
105
|
if (!this.enabled) return
|
74
|
-
|
75
|
-
|
76
|
-
this.
|
106
|
+
|
107
|
+
if (this.active) return
|
108
|
+
this.active = true
|
109
|
+
|
110
|
+
this.hide({ active: true })
|
77
111
|
|
78
112
|
addHighlight(this.targetElement, {
|
79
113
|
outline: '3px dashed darkcyan',
|
@@ -85,9 +119,12 @@ export default class ToggleDevtool {
|
|
85
119
|
outlineOffset: '3px'
|
86
120
|
})
|
87
121
|
|
88
|
-
|
89
|
-
|
90
|
-
this.createTriggerTooltip(
|
122
|
+
this.renderingTooltip = this.createRenderingTooltip()
|
123
|
+
this.targetTooltip = this.createTargetTooltip()
|
124
|
+
this.triggerTooltip = this.createTriggerTooltip(
|
125
|
+
this.targetTooltip,
|
126
|
+
this.renderingTooltip
|
127
|
+
)
|
91
128
|
|
92
129
|
document
|
93
130
|
.querySelectorAll('.leader-line')
|
@@ -115,38 +152,55 @@ export default class ToggleDevtool {
|
|
115
152
|
if (this.targetElement)
|
116
153
|
data.target = {
|
117
154
|
partial: this.targetElement.partial,
|
118
|
-
|
155
|
+
dom_id: this.targetElement.id,
|
119
156
|
status: 'OK'
|
120
157
|
}
|
121
158
|
|
122
159
|
console.table(data)
|
123
160
|
}
|
124
161
|
|
125
|
-
hide (
|
126
|
-
document.querySelectorAll('.leader-line').forEach(el => el.remove())
|
162
|
+
hide ({ active: active = false }) {
|
127
163
|
document
|
128
164
|
.querySelectorAll('turbo-boost-devtool-tooltip')
|
129
|
-
.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
|
+
})
|
130
172
|
|
131
173
|
document.querySelectorAll('[data-turbo-boost-highlight]').forEach(el => {
|
132
174
|
if (!el.tagName.match(/turbo-boost-toggle-trigger/i)) removeHighlight(el)
|
133
175
|
})
|
134
176
|
|
135
|
-
|
177
|
+
this.active = active
|
136
178
|
}
|
137
179
|
|
138
|
-
|
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
|
+
|
139
186
|
if (!this.triggerElement.morphs)
|
140
187
|
return console.debug(
|
141
|
-
`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}'`
|
142
189
|
)
|
143
190
|
|
144
|
-
const title =
|
191
|
+
const title = `
|
192
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline-block;" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19l7-7 3 3-7 7-3-3z"></path><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"></path><path d="M2 2l7.586 7.586"></path><circle cx="11" cy="11" r="2"></circle></svg>
|
193
|
+
RENDERING
|
194
|
+
`
|
145
195
|
const subtitle = `
|
146
|
-
|
147
|
-
|
196
|
+
<b>partial</b>: ${this.triggerElement.renders || 'unknown'}<br>
|
197
|
+
<b>morphs</b>: ${this.triggerElement.morphs || 'unknown'}<br>
|
198
|
+
`
|
199
|
+
const content = `
|
200
|
+
<div slot="content-top" style="font-size:85%; font-style:italic; font-weight:100;">
|
201
|
+
The <b>TRIGGER</b> toggles the <b>TARGET</b> then renders the partial & morphs the element.<br>
|
202
|
+
</div>
|
148
203
|
`
|
149
|
-
const content = '<div slot="content"></div>'
|
150
204
|
const tooltip = appendTooltip(title, subtitle, content, {
|
151
205
|
backgroundColor: 'lightyellow',
|
152
206
|
color: 'chocolate'
|
@@ -175,20 +229,31 @@ export default class ToggleDevtool {
|
|
175
229
|
`Unable to create the target tooltip! No element matches the DOM id: '${this.triggerElement.controls}'`
|
176
230
|
)
|
177
231
|
|
178
|
-
const title =
|
232
|
+
const title = `
|
233
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline-block;" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="6"></circle><circle cx="12" cy="12" r="2"></circle></svg>
|
234
|
+
TARGET
|
235
|
+
`
|
179
236
|
const subtitle = `
|
180
|
-
id
|
181
|
-
labeled
|
237
|
+
<b>id</b>: ${this.targetElement.id}<br>
|
238
|
+
<b>aria-labeled-by</b>: ${this.targetElement.labeledBy}<br>
|
182
239
|
`
|
183
|
-
|
240
|
+
let content = this.targetElement.viewStack
|
184
241
|
.reverse()
|
185
242
|
.map((view, index) => {
|
186
243
|
return this.triggerElement.sharedViews.includes(view)
|
187
|
-
? `<div slot="content
|
244
|
+
? `<div slot="content">${index + 1}. ${view}</div>`
|
188
245
|
: `<div slot="content-bottom">${index + 1}. ${view}</div>`
|
189
246
|
}, this)
|
190
247
|
.join('')
|
191
248
|
|
249
|
+
content = `
|
250
|
+
<div slot="content-top">
|
251
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline-block;" 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="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
|
252
|
+
<b>View Stack</b>
|
253
|
+
</div>
|
254
|
+
${content}
|
255
|
+
`
|
256
|
+
|
192
257
|
const tooltip = appendTooltip(title, subtitle, content, {
|
193
258
|
backgroundColor: 'lightcyan',
|
194
259
|
color: 'darkcyan',
|
@@ -210,22 +275,35 @@ export default class ToggleDevtool {
|
|
210
275
|
return tooltip
|
211
276
|
}
|
212
277
|
|
213
|
-
createTriggerTooltip (targetTooltip,
|
278
|
+
createTriggerTooltip (targetTooltip, renderingTooltip) {
|
214
279
|
if (!this.triggerElement) return
|
215
|
-
const title =
|
280
|
+
const title = `
|
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>
|
282
|
+
TRIGGER
|
283
|
+
`
|
216
284
|
const subtitle = `
|
217
|
-
id
|
218
|
-
controls
|
285
|
+
<b>id</b>: ${this.triggerElement.id}<br>
|
286
|
+
<b>aria-controls</b>: ${this.triggerElement.controls}<br>
|
287
|
+
<b>aria-expanded</b>: ${this.triggerElement.expanded}<br>
|
288
|
+
<b>remember</b>: ${this.triggerElement.remember}<br>
|
219
289
|
`
|
220
|
-
|
290
|
+
let content = this.triggerElement.viewStack
|
221
291
|
.reverse()
|
222
292
|
.map((view, index) => {
|
223
293
|
return this.triggerElement.sharedViews.includes(view)
|
224
|
-
? `<div slot="content
|
294
|
+
? `<div slot="content">${index + 1}. ${view}</div>`
|
225
295
|
: `<div slot="content-bottom">${index + 1}. ${view}</div>`
|
226
296
|
}, this)
|
227
297
|
.join('')
|
228
298
|
|
299
|
+
content = `
|
300
|
+
<div slot="content-top">
|
301
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline-block;" 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="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
|
302
|
+
<b>View Stack</b>
|
303
|
+
</div>
|
304
|
+
${content}
|
305
|
+
`
|
306
|
+
|
229
307
|
const tooltip = appendTooltip(title, subtitle, content, {
|
230
308
|
backgroundColor: 'lavender',
|
231
309
|
color: 'blueviolet'
|
@@ -257,16 +335,16 @@ export default class ToggleDevtool {
|
|
257
335
|
}
|
258
336
|
}
|
259
337
|
|
260
|
-
if (
|
261
|
-
tooltip.lineToRendering = new LeaderLine(tooltip,
|
338
|
+
if (renderingTooltip) {
|
339
|
+
tooltip.lineToRendering = new LeaderLine(tooltip, renderingTooltip, {
|
262
340
|
...this.leaderLineOptions,
|
263
341
|
color: 'blueviolet',
|
264
|
-
middleLabel: 'renders
|
342
|
+
middleLabel: 'renders & morphs',
|
265
343
|
size: 2.1
|
266
344
|
})
|
267
345
|
|
268
|
-
|
269
|
-
|
346
|
+
renderingTooltip.drag.onMove = () => {
|
347
|
+
renderingTooltip.line.position()
|
270
348
|
if (tooltip.lineToTarget) tooltip.lineToTarget.position()
|
271
349
|
tooltip.lineToRendering.position()
|
272
350
|
}
|