turbo_boost-elements 0.0.7 → 0.0.9
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 +128 -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} +74 -26
- data/app/javascript/elements/toggle_elements/trigger_element/index.js +172 -0
- data/app/javascript/elements/{turbo_boost_element.js → turbo_boost_element/index.js} +2 -2
- data/app/javascript/utils/dom.js +7 -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 -82
- data/app/javascript/elements/toggle_trigger_element.js +0 -122
data/app/javascript/utils/dom.js
CHANGED
@@ -54,10 +54,11 @@ export function removeHighlight (element) {
|
|
54
54
|
export function coordinates (element) {
|
55
55
|
if (!element) return {}
|
56
56
|
const rect = element.getBoundingClientRect()
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
const width = element.offsetWidth
|
58
|
+
const height = element.offsetHeight
|
59
|
+
const top = rect.top + window.scrollY
|
60
|
+
const left = rect.left + window.scrollX
|
61
|
+
const right = left + width
|
62
|
+
const bottom = top + height
|
63
|
+
return { top, left, right, bottom, width, height }
|
63
64
|
}
|
@@ -1,11 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class TurboBoost::Elements::TagBuilders::BaseTagBuilder
|
4
|
-
attr_reader :
|
5
|
-
delegate :content_tag, :turbo_boost, to: :view_context
|
4
|
+
attr_reader :controller_pack
|
6
5
|
|
7
6
|
def initialize(view_context)
|
8
7
|
@view_context = view_context
|
8
|
+
@controller_pack = view_context.turbo_boost # TurboBoost::Commands::ControllerPack
|
9
|
+
end
|
10
|
+
|
11
|
+
def render_tag(name, loading: :eager, **kwargs, &block)
|
12
|
+
options = kwargs.select { |_, value| value.present? }
|
13
|
+
options.transform_keys! { |key| key.to_s.dasherize }
|
14
|
+
|
15
|
+
loading = :eager unless loading == :lazy
|
16
|
+
if loading == :eager
|
17
|
+
view_context.tag.public_send(name.to_sym, **options, &block)
|
18
|
+
else
|
19
|
+
view_context.tag.public_send(name.to_sym, **options) {}
|
20
|
+
end
|
9
21
|
end
|
10
22
|
|
11
23
|
def view_stack
|
@@ -15,4 +27,8 @@ class TurboBoost::Elements::TagBuilders::BaseTagBuilder
|
|
15
27
|
memo << location.path[(location.path.index(prefix) + prefix.length)..]
|
16
28
|
end
|
17
29
|
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
attr_reader :view_context
|
18
34
|
end
|
@@ -3,6 +3,17 @@
|
|
3
3
|
require_relative "base_tag_builder"
|
4
4
|
|
5
5
|
class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Elements::TagBuilders::BaseTagBuilder
|
6
|
+
def busy_tag(**kwargs, &block)
|
7
|
+
kwargs[:slot] = "busy"
|
8
|
+
render_tag("turbo-boost", loading: :eager, **kwargs, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
# def content_tag(loading: :eager, **kwargs, &block)
|
12
|
+
# kwargs[:slot] = "content"
|
13
|
+
# kwargs[:hidden] = true
|
14
|
+
# render_tag("turbo-boost", loading: loading, **kwargs, &block)
|
15
|
+
# end
|
16
|
+
|
6
17
|
def trigger_tag(
|
7
18
|
renders:, # REQUIRED, the partial path to render
|
8
19
|
morphs:, # REQUIRED, `dom_id` of the partial's outermost containing element
|
@@ -16,7 +27,7 @@ class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Element
|
|
16
27
|
&block # a Ruby block that emits this trigger's content
|
17
28
|
)
|
18
29
|
kwargs = kwargs.with_indifferent_access
|
19
|
-
kwargs[:id] ||= "#{controls}-toggle-trigger"
|
30
|
+
kwargs[:id] ||= "#{controls}-toggle-trigger-#{SecureRandom.hex(6)}"
|
20
31
|
|
21
32
|
# command
|
22
33
|
kwargs[:data] ||= {}
|
@@ -39,10 +50,7 @@ class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Element
|
|
39
50
|
kwargs[:focus_selector] = focus_selector
|
40
51
|
kwargs[:remember] = !!remember
|
41
52
|
|
42
|
-
|
43
|
-
args = args.transform_keys(&:dasherize)
|
44
|
-
|
45
|
-
content_tag("turbo-boost-toggle-trigger", nil, args, &block)
|
53
|
+
render_tag("turbo-boost-toggle-trigger", loading: :eager, **kwargs, &block)
|
46
54
|
end
|
47
55
|
|
48
56
|
def target_tag(
|
@@ -68,16 +76,12 @@ class TurboBoost::Elements::TagBuilders::ToggleTagsBuilder < TurboBoost::Element
|
|
68
76
|
# rendering
|
69
77
|
kwargs[:view_stack] = view_stack.to_json if Rails.env.development?
|
70
78
|
|
71
|
-
|
72
|
-
|
73
|
-
content_tag("turbo-boost-toggle-target", nil, args.transform_keys!(&:dasherize), &block)
|
74
|
-
else
|
75
|
-
content_tag("turbo-boost-toggle-target", nil, args.transform_keys!(&:dasherize))
|
76
|
-
end
|
79
|
+
loading = (expanded || target_expanded?(id)) ? :eager : :lazy
|
80
|
+
render_tag("turbo-boost-toggle-target", loading: loading, **kwargs, &block)
|
77
81
|
end
|
78
82
|
|
79
83
|
def target_expanded?(dom_id)
|
80
|
-
!!
|
84
|
+
!!controller_pack.state[dom_id]
|
81
85
|
end
|
82
86
|
|
83
87
|
def target_collapsed?(dom_id)
|
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.9
|
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-01-
|
11
|
+
date: 2023-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.0.
|
47
|
+
version: 0.0.11
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.0.
|
54
|
+
version: 0.0.11
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: magic_frozen_string_literal
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,12 +143,13 @@ files:
|
|
143
143
|
- app/javascript/devtools/elements/tooltip_element.js
|
144
144
|
- app/javascript/devtools/index.js
|
145
145
|
- app/javascript/devtools/supervisor.js
|
146
|
-
- app/javascript/devtools/toggle.js
|
147
146
|
- app/javascript/elements/index.js
|
148
|
-
- app/javascript/elements/
|
149
|
-
- app/javascript/elements/
|
150
|
-
- app/javascript/elements/
|
151
|
-
- app/javascript/elements/
|
147
|
+
- app/javascript/elements/toggle_elements/target_element/focus.js
|
148
|
+
- app/javascript/elements/toggle_elements/target_element/index.js
|
149
|
+
- app/javascript/elements/toggle_elements/toggle_element/index.js
|
150
|
+
- app/javascript/elements/toggle_elements/trigger_element/devtool.js
|
151
|
+
- app/javascript/elements/toggle_elements/trigger_element/index.js
|
152
|
+
- app/javascript/elements/turbo_boost_element/index.js
|
152
153
|
- app/javascript/index.js
|
153
154
|
- app/javascript/utils/dom.js
|
154
155
|
- lib/turbo_boost/elements.rb
|
@@ -1,82 +0,0 @@
|
|
1
|
-
import TurboBoostElement from './turbo_boost_element'
|
2
|
-
import './toggle_target_focus'
|
3
|
-
|
4
|
-
export default class ToggleTargetElement extends TurboBoostElement {
|
5
|
-
connectedCallback () {
|
6
|
-
super.connectedCallback()
|
7
|
-
|
8
|
-
this.addEventListener('mouseenter', () =>
|
9
|
-
clearTimeout(this.collapseTimeout)
|
10
|
-
)
|
11
|
-
|
12
|
-
this.collapseOn.forEach(name =>
|
13
|
-
this.addEventListener(name, () => this.collapse())
|
14
|
-
)
|
15
|
-
}
|
16
|
-
|
17
|
-
// TODO: get cached content working properly
|
18
|
-
// perhaps use a mechanic other than morph
|
19
|
-
|
20
|
-
cacheHTML () {
|
21
|
-
// this.cachedHTML = this.innerHTML
|
22
|
-
}
|
23
|
-
|
24
|
-
renderCachedHTML () {
|
25
|
-
// if (!this.cachedHTML) return
|
26
|
-
// this.innerHTML = this.cachedHTML
|
27
|
-
}
|
28
|
-
|
29
|
-
collapse () {
|
30
|
-
clearTimeout(this.collapseTimeout)
|
31
|
-
this.collapseTimeout = setTimeout(() => {
|
32
|
-
this.innerHTML = ''
|
33
|
-
try {
|
34
|
-
this.currentTriggerElement.expanded = false
|
35
|
-
this.currentTriggerElement.hideDevtool()
|
36
|
-
} catch {}
|
37
|
-
}, 250)
|
38
|
-
}
|
39
|
-
|
40
|
-
collapseMatches () {
|
41
|
-
document.querySelectorAll(this.collapseSelector).forEach(el => {
|
42
|
-
if (el === this) return
|
43
|
-
if (el.collapse) el.collapse()
|
44
|
-
})
|
45
|
-
}
|
46
|
-
|
47
|
-
get collapseSelector () {
|
48
|
-
if (
|
49
|
-
this.currentTriggerElement &&
|
50
|
-
this.currentTriggerElement.collapseSelector
|
51
|
-
)
|
52
|
-
return this.currentTriggerElement.collapseSelector
|
53
|
-
return this.getAttribute('collapse-selector')
|
54
|
-
}
|
55
|
-
|
56
|
-
focus () {
|
57
|
-
clearTimeout(this.focusTimeout)
|
58
|
-
this.focusTimeout = setTimeout(() => {
|
59
|
-
if (this.focusElement) this.focusElement.focus()
|
60
|
-
}, 50)
|
61
|
-
}
|
62
|
-
|
63
|
-
get focusSelector () {
|
64
|
-
if (this.currentTriggerElement && this.currentTriggerElement.focusSelector)
|
65
|
-
return this.currentTriggerElement.focusSelector
|
66
|
-
return this.getAttribute('focus-selector')
|
67
|
-
}
|
68
|
-
|
69
|
-
get focusElement () {
|
70
|
-
return this.querySelector(this.focusSelector)
|
71
|
-
}
|
72
|
-
|
73
|
-
get labeledBy () {
|
74
|
-
return this.getAttribute('aria-labeledby')
|
75
|
-
}
|
76
|
-
|
77
|
-
get collapseOn () {
|
78
|
-
const value = this.getAttribute('collapse-on')
|
79
|
-
if (!value) return []
|
80
|
-
return JSON.parse(value)
|
81
|
-
}
|
82
|
-
}
|
@@ -1,122 +0,0 @@
|
|
1
|
-
import TurboBoostElement from './turbo_boost_element'
|
2
|
-
import DevtoolSupervisor from '../devtools/supervisor'
|
3
|
-
import ToggleDevtool from '../devtools/toggle'
|
4
|
-
|
5
|
-
export default class ToggleTriggerElement extends TurboBoostElement {
|
6
|
-
connectedCallback () {
|
7
|
-
super.connectedCallback()
|
8
|
-
|
9
|
-
if (this.targetElement) {
|
10
|
-
this.targetElement.setAttribute('aria-labeledby', this.id)
|
11
|
-
}
|
12
|
-
|
13
|
-
this.addEventListener(TurboBoost.Commands.events.start, () => {
|
14
|
-
this.busy = true
|
15
|
-
this.targetElement.currentTriggerElement = this
|
16
|
-
this.targetElement.renderCachedHTML()
|
17
|
-
})
|
18
|
-
|
19
|
-
this.addEventListener(TurboBoost.Commands.events.success, () => {
|
20
|
-
this.busy = false
|
21
|
-
this.targetElement.focus()
|
22
|
-
this.targetElement.collapseMatches()
|
23
|
-
this.targetElement.cacheHTML()
|
24
|
-
})
|
25
|
-
|
26
|
-
this.addEventListener(
|
27
|
-
TurboBoost.Commands.events.finish,
|
28
|
-
() => (this.busy = false)
|
29
|
-
)
|
30
|
-
|
31
|
-
this.initializeDevtool()
|
32
|
-
}
|
33
|
-
|
34
|
-
initializeDevtool () {
|
35
|
-
const mouseenter = () => this.devtool.show()
|
36
|
-
|
37
|
-
addEventListener('turbo-boost:devtools-start', () => {
|
38
|
-
this.devtool = new ToggleDevtool(this)
|
39
|
-
this.addEventListener('mouseenter', mouseenter)
|
40
|
-
})
|
41
|
-
|
42
|
-
addEventListener('turbo-boost:devtools-stop', () => {
|
43
|
-
this.removeEventListener('mouseenter', mouseenter)
|
44
|
-
delete this.devtool
|
45
|
-
})
|
46
|
-
|
47
|
-
if (DevtoolSupervisor.started) DevtoolSupervisor.restart()
|
48
|
-
}
|
49
|
-
|
50
|
-
hideDevtool () {
|
51
|
-
if (this.devtool) this.devtool.hide(true)
|
52
|
-
}
|
53
|
-
|
54
|
-
// a list of views shared between the trigger and target
|
55
|
-
get sharedViews () {
|
56
|
-
if (!this.targetElement) return []
|
57
|
-
if (!this.targetElement.viewStack) return []
|
58
|
-
const reducer = (memo, view) => {
|
59
|
-
if (this.targetElement.viewStack.includes(view)) memo.push(view)
|
60
|
-
return memo
|
61
|
-
}
|
62
|
-
return this.viewStack.reduce(reducer.bind(this), [])
|
63
|
-
}
|
64
|
-
|
65
|
-
// the partial to render
|
66
|
-
get renders () {
|
67
|
-
return this.getAttribute('renders')
|
68
|
-
}
|
69
|
-
|
70
|
-
// the renderered partial's top wrapping dom_id
|
71
|
-
get morphs () {
|
72
|
-
return this.getAttribute('morphs')
|
73
|
-
}
|
74
|
-
|
75
|
-
// the morph element
|
76
|
-
get morphElement () {
|
77
|
-
if (!this.morphs) return null
|
78
|
-
return document.getElementById(this.morphs)
|
79
|
-
}
|
80
|
-
|
81
|
-
// the target's dom_id
|
82
|
-
get controls () {
|
83
|
-
return this.getAttribute('aria-controls')
|
84
|
-
}
|
85
|
-
|
86
|
-
// the target element
|
87
|
-
get targetElement () {
|
88
|
-
if (!this.controls) return null
|
89
|
-
return document.getElementById(this.controls)
|
90
|
-
}
|
91
|
-
|
92
|
-
get collapseSelector () {
|
93
|
-
return this.getAttribute('collapse-selector')
|
94
|
-
}
|
95
|
-
|
96
|
-
get focusSelector () {
|
97
|
-
return this.getAttribute('focus-selector')
|
98
|
-
}
|
99
|
-
|
100
|
-
// indicates if the target is expanded
|
101
|
-
get expanded () {
|
102
|
-
return this.getAttribute('aria-expanded') === 'true'
|
103
|
-
}
|
104
|
-
|
105
|
-
set expanded (value) {
|
106
|
-
this.setAttribute('aria-expanded', !!value)
|
107
|
-
}
|
108
|
-
|
109
|
-
// indicates if the target is expanded
|
110
|
-
get collapsed () {
|
111
|
-
return !this.expanded
|
112
|
-
}
|
113
|
-
|
114
|
-
// indicates if an rpc call is active/busy
|
115
|
-
get busy () {
|
116
|
-
return this.getAttribute('busy') === 'true'
|
117
|
-
}
|
118
|
-
|
119
|
-
set busy (value) {
|
120
|
-
this.setAttribute('busy', !!value)
|
121
|
-
}
|
122
|
-
}
|