reflex_behaviors 0.0.4 → 0.0.6

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.
@@ -0,0 +1,48 @@
1
+ const addedDependencies = []
2
+
3
+ function addScript (src, integrity) {
4
+ if (document.querySelector(`[src='${src}']`)) return
5
+
6
+ if (addedDependencies.includes(src)) return
7
+ addedDependencies.push(src)
8
+
9
+ const script = document.createElement('script')
10
+ script.setAttribute('src', src)
11
+ script.setAttribute('crossorigin', 'anonymous')
12
+ script.setAttribute('referrerpolicy', 'no-referrer')
13
+ if (integrity) script.setAttribute('integrity', integrity)
14
+ document.head.appendChild(script)
15
+ }
16
+
17
+ function removeScript (src) {
18
+ if (!addedDependencies.includes(src)) return
19
+ addedDependencies.splice(addedDependencies.indexOf(src), 1)
20
+
21
+ const el = document.querySelector(`script[src='${src}']`)
22
+ if (el) el.remove()
23
+ }
24
+
25
+ export function addLeaderLineDependency () {
26
+ addScript(
27
+ 'https://cdnjs.cloudflare.com/ajax/libs/leader-line/1.0.7/leader-line.min.js',
28
+ 'sha512-0dNdzMjpT6pJdFGF1DwybFCfm3K/lzHhxaMXC/92J9/DZujHlqYFqmhTOAoD0o+LkeEsVK2ar/ESs7/Q2B6wJg=='
29
+ )
30
+ }
31
+
32
+ export function removeLeaderLineDependency () {
33
+ removeScript(
34
+ 'https://cdnjs.cloudflare.com/ajax/libs/leader-line/1.0.7/leader-line.min.js'
35
+ )
36
+ }
37
+
38
+ export function addPlainDraggableDependency () {
39
+ addScript(
40
+ 'https://cdn.jsdelivr.net/npm/plain-draggable@2.5.14/plain-draggable.min.js'
41
+ )
42
+ }
43
+
44
+ export function removePlainDraggableDependency () {
45
+ removeScript(
46
+ 'https://cdn.jsdelivr.net/npm/plain-draggable@2.5.14/plain-draggable.min.js'
47
+ )
48
+ }
@@ -54,8 +54,22 @@ export default class DevtoolElement extends HTMLElement {
54
54
 
55
55
  get stylesheet () {
56
56
  return `
57
+ :host, :host * {
58
+ cursor: pointer;
59
+ }
60
+
57
61
  div {
58
62
  display: flex;
63
+ position: relative;
64
+ top: -1px;
65
+ }
66
+
67
+ input:checked + label{
68
+ font-weight: bold;
69
+ }
70
+
71
+ label {
72
+ color: indigo;
59
73
  }
60
74
  `
61
75
  }
@@ -1,4 +1,4 @@
1
- import { appendHTML } from '../dom'
1
+ import { appendHTML } from '../../utils/dom'
2
2
 
3
3
  export default class SupervisorElement extends HTMLElement {
4
4
  constructor () {
@@ -7,7 +7,7 @@ export default class SupervisorElement extends HTMLElement {
7
7
  this.attachShadow({ mode: 'open' })
8
8
  this.shadowRoot.innerHTML = this.html
9
9
  this.shadowRoot
10
- .querySelector('button[data-role="closer"]')
10
+ .querySelector('button')
11
11
  .addEventListener('click', () => this.close())
12
12
 
13
13
  this.addEventListener('change', event => {
@@ -51,16 +51,16 @@ export default class SupervisorElement extends HTMLElement {
51
51
  }
52
52
 
53
53
  get closeElement () {
54
- return this.querySelector('button[data-role="closer"]')
54
+ return this.querySelector('button')
55
55
  }
56
56
 
57
57
  get html () {
58
58
  return `
59
59
  <style>${this.stylesheet}</style>
60
- <div data-role="container">
61
- <strong>ReflexBehaviors</strong>
60
+ <div>
61
+ <label>ReflexBehaviors</label>
62
62
  <slot name="devtool"></slot>
63
- <button data-role='closer'>X</button>
63
+ <button>✕</button>
64
64
  </div>
65
65
  `
66
66
  }
@@ -68,45 +68,59 @@ export default class SupervisorElement extends HTMLElement {
68
68
  get stylesheet () {
69
69
  return `
70
70
  :host {
71
- background-color: ghostwhite;
72
- border-radius: 10px;
73
- outline: solid 1px gainsboro;
71
+ background-color: lavender;
72
+ border-radius: 15px;
74
73
  bottom: 20px;
75
74
  display: block;
76
- filter: drop-shadow(0 4px 3px rgba(0,0,0,.07));
75
+ filter: drop-shadow(3px 3px 3px rgba(0,0,0,0.3));
77
76
  left: 50%;
77
+ outline-offset: 1px;
78
+ outline: solid 3px indigo;
78
79
  padding: 5px 10px;
79
80
  position: fixed;
80
81
  transform: translateX(-50%);
81
- z-index: 10000;
82
+ z-index: 8999;
82
83
  }
83
84
 
84
- :host, :host * {
85
+ * {
85
86
  -webkit-user-select: none;
87
+ font-family: helvetica, sans-serif;
88
+ font-size: 1rem;
86
89
  user-select: none;
87
90
  }
88
91
 
89
- strong {
90
- color: silver;
91
- font-weight: 600;
92
+ label {
93
+ color: indigo;
94
+ cursor: grab;
95
+ opacity: 0.5;
92
96
  }
93
97
 
94
- div[data-role="container"] {
98
+ div {
95
99
  display: flex;
96
100
  gap: 0 5px;
101
+ position: relative;
97
102
  }
98
103
 
99
- button[data-role="closer"] {
100
- border: none;
101
- background-color: gainsboro;
104
+ button {
105
+ background-color: thistle;
102
106
  border-radius: 50%;
103
- color: white;
104
- font-size: 12px;
107
+ border: none;
108
+ color: indigo;
109
+ cursor: pointer;
110
+ font-size: 10px;
105
111
  height: 18px;
106
112
  line-height: 18px;
107
113
  margin: 0 -5px 0 10px;
108
- padding: 0 3px;
114
+ outline: solid 1px indigo;
115
+ padding: 0 2px;
116
+ position: relative;
117
+ top: 1px;
109
118
  width: 18px;
119
+ opacity: 0.5;
120
+ }
121
+
122
+ button:hover {
123
+ opacity: 1;
110
124
  }
111
125
  `
112
126
  }
@@ -9,10 +9,6 @@ export default class TooltipElement extends HTMLElement {
9
9
  return this.getAttribute('color') || 'darkslategray'
10
10
  }
11
11
 
12
- get emphasisColor () {
13
- return this.getAttribute('emphasis-color') || 'black'
14
- }
15
-
16
12
  get backgroundColor () {
17
13
  return this.getAttribute('background-color') || 'gainsboro'
18
14
  }
@@ -21,23 +17,14 @@ export default class TooltipElement extends HTMLElement {
21
17
  return this.getAttribute('position') || 'top'
22
18
  }
23
19
 
24
- get cssArrow () {
25
- switch (this.position) {
26
- case 'bottom':
27
- return `transparent transparent ${this.emphasisColor} transparent`
28
- default:
29
- return `${this.emphasisColor} transparent transparent transparent;`
30
- }
31
- }
32
-
33
20
  get html () {
34
21
  return `
35
22
  <style>${this.stylesheet}</style>
36
- <div role="tooltip">
23
+ <div>
37
24
  <slot name="title"></slot>
38
- <hr>
39
- <slot name="normal"></slot>
40
- <slot name="emphasis"></slot>
25
+ <slot name="content-top"></slot>
26
+ <slot name="content"></slot>
27
+ <slot name="content-bottom"></slot>
41
28
  </div>
42
29
  `
43
30
  }
@@ -47,55 +34,55 @@ export default class TooltipElement extends HTMLElement {
47
34
  :host {
48
35
  display: block;
49
36
  position: absolute;
50
- z-index: 10000;
37
+ z-index: 8999;
51
38
  }
52
39
 
53
40
  * {
54
41
  color: ${this.color}
42
+ font-size: 1rem;
55
43
  }
56
44
 
57
- [role="tooltip"] {
45
+ div {
58
46
  background-color: ${this.backgroundColor};
59
- border-radius: 5px;
47
+ border-radius: 15px;
60
48
  filter: drop-shadow(3px 3px 3px rgba(0,0,0,0.3));
61
49
  font-family: monospace;
62
- left: 50px;
63
50
  min-height: 30px;
64
51
  min-width: 100px;
65
52
  opacity: 0.9;
66
- outline: solid 2px ${this.emphasisColor};
53
+ outline-offset: 1px;
54
+ outline: dashed 3px ${this.color};
67
55
  padding: 8px 12px 8px 12px;
56
+ position: relative;
68
57
  white-space: nowrap;
69
58
  }
70
59
 
71
- [role="tooltip"]::after {
72
- border-color: ${this.cssArrow};
73
- border-style: solid;
74
- border-width: 5px;
75
- content: "";
76
- margin-left: -5px;
77
- position: absolute;
78
- top: ${this.position === 'bottom' ? '-10px' : '100%'};
79
- }
80
-
81
60
  slot[name="title"] {
82
- color: ${this.emphasisColor};
61
+ border-bottom: dotted 1px ${this.color};
62
+ color: ${this.color};
63
+ display: inline-block;
83
64
  font-weight: bold;
65
+ margin-bottom: 8px;
66
+ padding-bottom: 8px;
67
+ width: 100%;
84
68
  }
85
69
 
86
- slot[name="emphasis"] {
87
- color: ${this.emphasisColor};
70
+ slot[name="content-top"] {
71
+ color: ${this.color};
88
72
  font-weight: normal;
89
73
  opacity: 0.7;
90
74
  }
91
75
 
92
- hr {
93
- background-color: ${this.emphasisColor};
94
- border: none;
95
- height: 1px;
96
- margin-bottom: 4px;
97
- margin-top: 4px;
98
- opacity: 0.3;
76
+ slot[name="content"] {
77
+ color: ${this.color};
78
+ font-weight: normal;
79
+ opacity: 0.7;
80
+ }
81
+
82
+ slot[name="content-bottom"] {
83
+ color: red;
84
+ font-weight: normal;
85
+ opacity: 0.7;
99
86
  }
100
87
  `
101
88
  }
@@ -1,7 +1,13 @@
1
- import { appendHTML } from './dom'
1
+ import { appendHTML } from '../utils/dom'
2
2
  import DevtoolElement from './elements/devtool_element'
3
3
  import SupervisorElement from './elements/supervisor_element'
4
4
  import TooltipElement from './elements/tooltip_element'
5
+ import {
6
+ addLeaderLineDependency,
7
+ addPlainDraggableDependency,
8
+ removeLeaderLineDependency,
9
+ removePlainDraggableDependency
10
+ } from './dependencies'
5
11
 
6
12
  customElements.define('reflex-behaviors-devtool', DevtoolElement)
7
13
  customElements.define('reflex-behaviors-devtool-supervisor', SupervisorElement)
@@ -9,8 +15,17 @@ customElements.define('reflex-behaviors-devools-tooltip', TooltipElement)
9
15
 
10
16
  let supervisorElement
11
17
 
12
- function stop () {
18
+ function makeDraggable () {
13
19
  if (!supervisorElement) return
20
+ try {
21
+ new PlainDraggable(supervisorElement)
22
+ } catch {
23
+ setTimeout(makeDraggable, 200)
24
+ }
25
+ }
26
+
27
+ function stop () {
28
+ if (stopped()) return
14
29
  supervisorElement.close()
15
30
  supervisorElement.dispatchEvent(
16
31
  new CustomEvent('reflex-behaviors:devtools-stop', {
@@ -18,15 +33,18 @@ function stop () {
18
33
  })
19
34
  )
20
35
  supervisorElement = null
36
+ removeLeaderLineDependency()
37
+ removePlainDraggableDependency()
21
38
  }
22
39
 
23
40
  function start () {
24
- appendHTML(
41
+ if (started()) return
42
+ addLeaderLineDependency()
43
+ addPlainDraggableDependency()
44
+ supervisorElement = appendHTML(
25
45
  '<reflex-behaviors-devtool-supervisor></reflex-behaviors-devtool-supervisor>'
26
46
  )
27
- supervisorElement = document.body.querySelector(
28
- 'reflex-behaviors-devtool-supervisor'
29
- )
47
+ setTimeout(makeDraggable, 200)
30
48
  supervisorElement.dispatchEvent(
31
49
  new CustomEvent('reflex-behaviors:devtools-start', {
32
50
  bubbles: true
@@ -47,15 +65,28 @@ function restart () {
47
65
  })
48
66
  }
49
67
 
68
+ function started () {
69
+ return !!supervisorElement
70
+ }
71
+
72
+ function stopped () {
73
+ return !started()
74
+ }
75
+
50
76
  let restartTimeout
51
77
  function debouncedRestart () {
52
78
  clearTimeout(restartTimeout)
53
79
  restartTimeout = setTimeout(restart, 25)
54
80
  }
55
- addEventListener('turbo:load', debouncedRestart)
56
- addEventListener('turbo-frame:load', debouncedRestart)
57
- addEventListener('turbo-reflex:success', debouncedRestart)
58
- addEventListener('turbo-reflex:finish', debouncedRestart)
81
+
82
+ function autoRestart () {
83
+ if (started()) debouncedRestart()
84
+ }
85
+
86
+ addEventListener('turbo:load', autoRestart)
87
+ addEventListener('turbo-frame:load', autoRestart)
88
+ addEventListener('turbo-reflex:success', autoRestart)
89
+ addEventListener('turbo-reflex:finish', autoRestart)
59
90
 
60
91
  function register (name, label) {
61
92
  if (!supervisorElement) return
@@ -77,7 +108,13 @@ function enabled (name) {
77
108
  export default {
78
109
  enabled,
79
110
  register,
80
- restart: debouncedRestart,
81
111
  start,
82
- stop
112
+ stop,
113
+ restart: debouncedRestart,
114
+ get started () {
115
+ return started()
116
+ },
117
+ get stopped () {
118
+ return stopped()
119
+ }
83
120
  }