turbo_boost-elements 0.0.11 → 0.0.13

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.
@@ -1,5 +1,4 @@
1
1
  import ToggleElement from '../toggle_element'
2
- import './focus'
3
2
 
4
3
  export default class ToggleTargetElement extends ToggleElement {
5
4
  connectedCallback () {
@@ -91,19 +90,8 @@ export default class ToggleTargetElement extends ToggleElement {
91
90
  )
92
91
  }
93
92
 
94
- applyFocus () {
95
- if (this.focusElement) this.focusElement.focus()
96
- }
97
-
98
93
  get focusSelector () {
99
- let value = this.getAttribute('focus-selector')
100
- if (this.triggerElement)
101
- value = this.triggerElement.getAttribute('focus-selector') || value
102
- return value
103
- }
104
-
105
- get focusElement () {
106
- return this.querySelector(this.focusSelector)
94
+ return this.getAttribute('focus-selector')
107
95
  }
108
96
 
109
97
  get triggerElement () {
@@ -114,6 +102,10 @@ export default class ToggleTargetElement extends ToggleElement {
114
102
  return this.getAttribute('aria-labeledby')
115
103
  }
116
104
 
105
+ set labeledBy (value) {
106
+ return this.setAttribute('aria-labeledby', value)
107
+ }
108
+
117
109
  get collapseOn () {
118
110
  const value = this.getAttribute('collapse-on')
119
111
  if (!value) return []
@@ -1,3 +1,5 @@
1
+ let focusTimeout
2
+
1
3
  function deactivateTrixAttributes (editor) {
2
4
  const attributes = [
3
5
  'bold',
@@ -43,35 +45,26 @@ function focusTrixEditorElement (element) {
43
45
  ])
44
46
  }
45
47
 
46
- function shouldEnhanceFocus (element) {
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
50
- }
48
+ function debouncedFocus (element) {
49
+ clearTimeout(focusTimeout)
51
50
 
52
- function enhanceFocus (element) {
53
- const trixEditorElement = element.closest('trix-editor')
51
+ focusTimeout = setTimeout(() => {
52
+ if (!element) return
54
53
 
55
- try {
56
- if (trixEditorElement) {
57
- focusTrixEditorElement(trixEditorElement)
58
- } else {
59
- element.selectionStart = element.selectionEnd = element.value.length
54
+ element.focus()
55
+ const trixEditorElement = element.closest('trix-editor')
56
+
57
+ try {
58
+ if (trixEditorElement) {
59
+ focusTrixEditorElement(trixEditorElement)
60
+ } else {
61
+ element.selectionStart = element.selectionEnd = element.value.length
62
+ }
63
+ } catch (_) {
64
+ } finally {
65
+ element.scrollIntoView({ block: 'center', behavior: 'smooth' })
60
66
  }
61
- } catch (_) {
62
- } finally {
63
- setTimeout(
64
- () => element.scrollIntoView({ block: 'center', behavior: 'smooth' }),
65
- 100
66
- )
67
- }
67
+ }, 100)
68
68
  }
69
69
 
70
- addEventListener(
71
- 'focus',
72
- event => {
73
- if (shouldEnhanceFocus(document.activeElement))
74
- enhanceFocus(document.activeElement)
75
- },
76
- true
77
- )
70
+ export default element => debouncedFocus(element)
@@ -1,13 +1,13 @@
1
1
  import ToggleElement, { busyDuration } from '../toggle_element'
2
2
  import Devtool from './devtool'
3
+ import focus from './focus'
4
+
5
+ let currentFocusSelector
3
6
 
4
7
  export default class ToggleTriggerElement extends ToggleElement {
5
8
  connectedCallback () {
6
9
  super.connectedCallback()
7
10
 
8
- if (this.targetElement)
9
- this.targetElement.setAttribute('aria-labeledby', this.id)
10
-
11
11
  const { start: commandStartEvent } = TurboBoost.Commands.events
12
12
  this.commandStartHandler = this.onCommandStart.bind(this)
13
13
  this.addEventListener(commandStartEvent, this.commandStartHandler)
@@ -25,15 +25,19 @@ export default class ToggleTriggerElement extends ToggleElement {
25
25
  }
26
26
 
27
27
  disconnectedCallback () {
28
- const { start: commandStartEvent } = TurboBoost.Commands.events
29
- this.removeEventListener(commandStartEvent, this.commandStartHandler)
28
+ // delay cleanup because the trigger may have been morphed out of the DOM,
29
+ // but it's needed to apply behavior like focus etc...
30
+ setTimeout(() => {
31
+ const { start: commandStartEvent } = TurboBoost.Commands.events
32
+ this.removeEventListener(commandStartEvent, this.commandStartHandler)
30
33
 
31
- const { before: beforeInvokeEvent } = TurboBoost.Streams.invokeEvents
32
- removeEventListener(beforeInvokeEvent, this.beforeInvokeHandler)
34
+ const { before: beforeInvokeEvent } = TurboBoost.Streams.invokeEvents
35
+ removeEventListener(beforeInvokeEvent, this.beforeInvokeHandler)
33
36
 
34
- this.devtool.hide({ active: false })
35
- this.devtool.unregisterEventListeners()
36
- delete this.devtool
37
+ this.devtool.hide({ active: false })
38
+ this.devtool.unregisterEventListeners()
39
+ delete this.devtool
40
+ }, 1000)
37
41
  }
38
42
 
39
43
  initializeDevtool () {
@@ -61,16 +65,21 @@ export default class ToggleTriggerElement extends ToggleElement {
61
65
  }
62
66
 
63
67
  onCommandStart (event) {
64
- this.targetElement.setAttribute('aria-labeledby', this.id)
68
+ currentFocusSelector = this.focusSelector
69
+ this.targetElement.labeledBy = this.id
65
70
  this.targetElement.collapseMatches()
66
71
  this.targetElement.busy = true
67
72
  this.busy = true
68
73
  // TODO: implement cache - this.targetElement.renderCachedHTML()
69
74
  }
70
75
 
76
+ // runs before an invoke turbo stream is executed
71
77
  onBeforeInvoke (event) {
78
+ // return early if we're not the element responsible for this invoke
72
79
  if (event.detail.method !== 'morph') return
73
80
  if (event.target.id !== this.morphs) return
81
+ const selector = `turbo-boost-toggle-target[aria-labeledby="${this.id}"]`
82
+ if (!event.target.querySelector(selector)) return
74
83
 
75
84
  // ensure the busy element is shown long enough for a good user experience
76
85
  // we accomplish this by modifying the event.detail with invoke instructions i.e. { delay }
@@ -88,10 +97,10 @@ export default class ToggleTriggerElement extends ToggleElement {
88
97
  }, delay - 10)
89
98
 
90
99
  // runs after the morph is executed
91
- setTimeout(() => {
92
- this.targetElement.setAttribute('aria-labeledby', this.id)
93
- this.targetElement.applyFocus()
94
- }, delay + 100)
100
+ setTimeout(
101
+ () => focus(this.targetElement.querySelector(currentFocusSelector)),
102
+ delay + 100
103
+ )
95
104
  }
96
105
 
97
106
  // a list of views shared between the trigger and target
@@ -147,8 +156,7 @@ export default class ToggleTriggerElement extends ToggleElement {
147
156
 
148
157
  get focusSelector () {
149
158
  return (
150
- this.getAttribute('focus-selector') ||
151
- this.targetElement.getAttribute('focus-selector')
159
+ this.getAttribute('focus-selector') || this.targetElement.focusSelector
152
160
  )
153
161
  }
154
162
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TurboBoost
4
4
  module Elements
5
- VERSION = "0.0.11"
5
+ VERSION = "0.0.13"
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.11
4
+ version: 0.0.13
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-02-07 00:00:00.000000000 Z
11
+ date: 2023-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -144,10 +144,10 @@ files:
144
144
  - app/javascript/devtools/index.js
145
145
  - app/javascript/devtools/supervisor.js
146
146
  - app/javascript/elements/index.js
147
- - app/javascript/elements/toggle_elements/target_element/focus.js
148
147
  - app/javascript/elements/toggle_elements/target_element/index.js
149
148
  - app/javascript/elements/toggle_elements/toggle_element/index.js
150
149
  - app/javascript/elements/toggle_elements/trigger_element/devtool.js
150
+ - app/javascript/elements/toggle_elements/trigger_element/focus.js
151
151
  - app/javascript/elements/toggle_elements/trigger_element/index.js
152
152
  - app/javascript/elements/turbo_boost_element/index.js
153
153
  - app/javascript/index.js