reflex_behaviors 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }