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.
@@ -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
- return {
58
- left: rect.left + window.scrollX,
59
- top: rect.top + window.scrollY,
60
- width: element.offsetWidth,
61
- height: element.offsetHeight
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
  }
@@ -10,6 +10,7 @@ module TurboBoost::Elements
10
10
  end
11
11
 
12
12
  class Engine < ::Rails::Engine
13
+ isolate_namespace TurboBoost::Elements
13
14
  config.turbo_boost_elements = ActiveSupport::OrderedOptions.new
14
15
 
15
16
  ActiveSupport.on_load(:action_controller_base) do
@@ -1,11 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TurboBoost::Elements::TagBuilders::BaseTagBuilder
4
- attr_reader :view_context
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
- args = kwargs.select { |_, value| value.present? }
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
- args = kwargs.select { |_, value| value.present? }
72
- if expanded || target_expanded?(id)
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
- !!turbo_boost.state[dom_id]
84
+ !!controller_pack.state[dom_id]
81
85
  end
82
86
 
83
87
  def target_collapsed?(dom_id)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TurboBoost
4
4
  module Elements
5
- VERSION = "0.0.7"
5
+ VERSION = "0.0.9"
6
6
  end
7
7
  end
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.7
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-18 00:00:00.000000000 Z
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.9
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.9
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/toggle_target_element.js
149
- - app/javascript/elements/toggle_target_focus.js
150
- - app/javascript/elements/toggle_trigger_element.js
151
- - app/javascript/elements/turbo_boost_element.js
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
- }