turbo_boost-elements 0.0.8 → 0.0.9

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.
@@ -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.8"
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.8
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-19 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,84 +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 (delay = 250) {
30
- if (delay > 0) {
31
- clearTimeout(this.collapseTimeout)
32
- return (this.collapseTimeout = setTimeout(() => this.collapse(0), delay))
33
- }
34
-
35
- this.innerHTML = ''
36
- try {
37
- this.currentTriggerElement.expanded = false
38
- this.currentTriggerElement.hideDevtool()
39
- } catch {}
40
- }
41
-
42
- collapseMatches () {
43
- document.querySelectorAll(this.collapseSelector).forEach(el => {
44
- if (el === this) return
45
- if (el.collapse) el.collapse(0)
46
- })
47
- }
48
-
49
- get collapseSelector () {
50
- if (
51
- this.currentTriggerElement &&
52
- this.currentTriggerElement.collapseSelector
53
- )
54
- return this.currentTriggerElement.collapseSelector
55
- return this.getAttribute('collapse-selector')
56
- }
57
-
58
- focus () {
59
- clearTimeout(this.focusTimeout)
60
- this.focusTimeout = setTimeout(() => {
61
- if (this.focusElement) this.focusElement.focus()
62
- }, 50)
63
- }
64
-
65
- get focusSelector () {
66
- if (this.currentTriggerElement && this.currentTriggerElement.focusSelector)
67
- return this.currentTriggerElement.focusSelector
68
- return this.getAttribute('focus-selector')
69
- }
70
-
71
- get focusElement () {
72
- return this.querySelector(this.focusSelector)
73
- }
74
-
75
- get labeledBy () {
76
- return this.getAttribute('aria-labeledby')
77
- }
78
-
79
- get collapseOn () {
80
- const value = this.getAttribute('collapse-on')
81
- if (!value) return []
82
- return JSON.parse(value)
83
- }
84
- }
@@ -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
- }