@natachah/vanilla-frontend 0.1.15 → 0.1.16

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.
@@ -95,45 +95,27 @@
95
95
  </ul>
96
96
  </doc-code>
97
97
 
98
- <h2>Manually move</h2>
99
- <p>You can manually move the item by adding some button with <code>data-go="up"</code> or <code>data-go="down"</code> attribute</p>
100
- <doc-demo>
101
- <ul class="demo-sortable">
102
- <li draggable="false">
103
- <button data-go="up">UP</button><button data-go="down">Down</button>
104
- Lorem, ipsum.
105
- </li>
106
- <li draggable="false">
107
- <button data-go="up">UP</button><button data-go="down">Down</button>
108
- Impedit, quod!
109
- </li>
110
- <li draggable="false">
111
- <button data-go="up">UP</button><button data-go="down">Down</button>
112
- Repudiandae, rerum.
113
- </li>
114
- </ul>
115
- </doc-demo>
116
-
117
- <doc-code>
118
- <ul id="mySortableListWithBtn">
119
- <li draggable="false">
120
- <button data-go="up">UP</button><button data-go="down">Down</button>
121
- Lorem, ipsum.
122
- </li>
123
- <li draggable="false">
124
- <button data-go="up">UP</button><button data-go="down">Down</button>
125
- Impedit, quod!
126
- </li>
127
- <li draggable="false">
128
- <button data-go="up">UP</button><button data-go="down">Down</button>
129
- Repudiandae, rerum.
130
- </li>
131
- </ul>
132
- </doc-code>
133
-
134
-
135
98
  <h2 id="javascript">Javascript</h2>
136
99
  <p>To enable this component you need to import the javascript file and create a new Sortable object.</p>
100
+ <h3>Methods</h3>
101
+ <table>
102
+ <thead>
103
+ <tr>
104
+ <th>Method</th>
105
+ <th>Description</th>
106
+ </tr>
107
+ </thead>
108
+ <tbody>
109
+ <tr>
110
+ <td data-label="Method">
111
+ <p>resetEvents()</p>
112
+ </td>
113
+ <td data-label="Description">
114
+ <p>This method will reset the items and events</p>
115
+ </td>
116
+ </tr>
117
+ </tbody>
118
+ </table>
137
119
  <h3 id="events">Events</h3>
138
120
  <table>
139
121
  <thead>
@@ -43,7 +43,6 @@ if (sliderFade) {
43
43
  autoplay: 4000
44
44
  })
45
45
  sliderFade.addEventListener('slider:changed', (ev) => {
46
- console.log(ev)
47
46
  const src = mySliderObj._slides[ev.detail.previous].querySelector('img').getAttribute('src')
48
47
  sliderFade.style.backgroundImage = `url("${src}")`
49
48
  })
@@ -18,7 +18,7 @@ class DocLayout extends HTMLElement {
18
18
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pin-angle" viewBox="0 0 16 16">
19
19
  <path d="M9.828.722a.5.5 0 0 1 .354.146l4.95 4.95a.5.5 0 0 1 0 .707c-.48.48-1.072.588-1.503.588-.177 0-.335-.018-.46-.039l-3.134 3.134a6 6 0 0 1 .16 1.013c.046.702-.032 1.687-.72 2.375a.5.5 0 0 1-.707 0l-2.829-2.828-3.182 3.182c-.195.195-1.219.902-1.414.707s.512-1.22.707-1.414l3.182-3.182-2.828-2.829a.5.5 0 0 1 0-.707c.688-.688 1.673-.767 2.375-.72a6 6 0 0 1 1.013.16l3.134-3.133a3 3 0 0 1-.04-.461c0-.43.108-1.022.589-1.503a.5.5 0 0 1 .353-.146m.122 2.112v-.002zm0-.002v.002a.5.5 0 0 1-.122.51L6.293 6.878a.5.5 0 0 1-.511.12H5.78l-.014-.004a5 5 0 0 0-.288-.076 5 5 0 0 0-.765-.116c-.422-.028-.836.008-1.175.15l5.51 5.509c.141-.34.177-.753.149-1.175a5 5 0 0 0-.192-1.054l-.004-.013v-.001a.5.5 0 0 1 .12-.512l3.536-3.535a.5.5 0 0 1 .532-.115l.096.022c.087.017.208.034.344.034q.172.002.343-.04L9.927 2.028q-.042.172-.04.343a1.8 1.8 0 0 0 .062.46z"/>
20
20
  </svg>
21
- 0.1.15
21
+ 0.1.16
22
22
  </span>
23
23
  </li>
24
24
  <li>
@@ -36,7 +36,7 @@ class DocLayout extends HTMLElement {
36
36
  </ul>
37
37
  </nav>
38
38
  </header>
39
- <aside id="sidebar" class="drawer" tabindex="0" hidden>
39
+ <aside id="sidebar" class="drawer" hidden>
40
40
  <header>
41
41
  <a href="/index.html">
42
42
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-rocket" viewBox="0 0 16 16">
package/js/_drawer.js CHANGED
@@ -45,7 +45,7 @@ export default class Drawer extends BaseComponent {
45
45
 
46
46
  this._isOpen = !this._element.hidden
47
47
 
48
- this._focus = this._element.querySelector('a,button') ?? null
48
+ this._focus = this._element.querySelector('[tabindex="0"]') ?? this._element.querySelector('a,button,input') ?? null
49
49
 
50
50
  this._cookie = this._options.cookie ? new Cookie(this._options.cookie) : null
51
51
 
@@ -73,7 +73,7 @@ export default class Drawer extends BaseComponent {
73
73
 
74
74
  // Window is smaller than breakpoint
75
75
  // -> Hide the drawer
76
- if (window.innerWidth < this._options.breakpoint) this.toggle(false)
76
+ if (window.innerWidth <= this._options.breakpoint) this.toggle(false)
77
77
 
78
78
  // On window resize
79
79
  // -> Toggle the drawer
@@ -85,7 +85,7 @@ export default class Drawer extends BaseComponent {
85
85
  if (window.innerWidth > this._options.breakpoint && (!this._isOpen && shouldBeOpen)) this.toggle(true)
86
86
 
87
87
  // Smaller than breakpoint -> Invisible
88
- if (window.innerWidth < this._options.breakpoint && this._isOpen) this.toggle(false)
88
+ if (window.innerWidth <= this._options.breakpoint && this._isOpen) this.toggle(false)
89
89
 
90
90
  }, 250)
91
91
  }
@@ -123,7 +123,12 @@ export default class Drawer extends BaseComponent {
123
123
  }
124
124
 
125
125
  // Add the focus if open
126
- if (this._focus && this._isOpen) this._focus.focus()
126
+ // * Need to wait the transition before make it focused
127
+ if (this._focus && this._isOpen) {
128
+ this._element.addEventListener("transitionend", () => {
129
+ this._focus.focus()
130
+ }, { once: true })
131
+ }
127
132
 
128
133
  }
129
134
 
package/js/_dropdown.js CHANGED
@@ -37,6 +37,7 @@ export default class Dropdown extends BaseComponent {
37
37
  // Define the properties
38
38
  this._button = this._element.querySelector('[aria-controls]')
39
39
  this._content = document.getElementById(this._button.getAttribute('aria-controls'))
40
+ this._focus = this._element.querySelector('[tabindex="0"]') ?? this._element.querySelector('a,button,input') ?? null
40
41
 
41
42
  // Init the event listener
42
43
  this.#init()
@@ -88,8 +89,13 @@ export default class Dropdown extends BaseComponent {
88
89
  // Change visibility of the content
89
90
  this._content.hidden = !value
90
91
 
91
- // Put the focus on the content
92
- if (value) this._content.focus()
92
+ // Add the focus if open
93
+ // * Need to wait the transition before make it focused
94
+ if (this._focus && value) {
95
+ this._element.addEventListener("transitionend", () => {
96
+ this._focus.focus()
97
+ }, { once: true })
98
+ }
93
99
 
94
100
  // Emmit event
95
101
  this.emmitEvent('changed', { isOpen: !this._content.hidden })
package/js/_sortable.js CHANGED
@@ -26,9 +26,17 @@ export default class Sortable extends BaseComponent {
26
26
  super(el, options, 'sortable')
27
27
 
28
28
  // Define the properties
29
+ this._items = null
29
30
  this._withHandle = this._element.querySelector('[data-handle=sortable]') ? true : false
30
31
  this._current = null
31
32
 
33
+ // Lier une seule fois les méthodes à `this`
34
+ this.handleMouseDown = this.handleMouseDown.bind(this)
35
+ this.handleMouseUp = this.handleMouseUp.bind(this)
36
+ this.drag = this.drag.bind(this)
37
+ this.dragging = this.dragging.bind(this)
38
+ this.drop = this.drop.bind(this)
39
+
32
40
  // Init the event listener
33
41
  this.#init()
34
42
 
@@ -44,41 +52,88 @@ export default class Sortable extends BaseComponent {
44
52
  // Prevent default animation at the drop
45
53
  this._element.addEventListener('dragover', (e) => e.preventDefault())
46
54
 
47
- // Events directly on the items
48
- this.items.forEach((item) => {
49
-
50
- // Toggle the [dragable] attribute
51
- item.addEventListener('mousedown', (e) => { if (!this._withHandle || (e.target.hasAttribute('data-handle') && e.target.getAttribute('data-handle') === 'sortable')) item.draggable = true })
52
- item.addEventListener('mouseup', () => item.draggable = false)
55
+ // Init the events on the items
56
+ this.#initEvents()
53
57
 
54
- // Drag and drop events
55
- item.addEventListener('dragstart', () => this.#drag(item))
56
- item.addEventListener('dragenter', () => this.#dragging(item))
57
- item.addEventListener('dragend', () => this.#drop(item))
58
+ }
58
59
 
59
- const btns = item.querySelectorAll('[data-go]')
60
- if (btns) btns.forEach(btn => btn.addEventListener('click', () => this.#move(item, btn.getAttribute('data-go') == 'up')))
60
+ /**
61
+ * Init the items and the event listeners
62
+ *
63
+ * @private
64
+ */
65
+ #initEvents() {
66
+
67
+ // Get the items
68
+ this._items = this._element.querySelectorAll('[draggable]')
69
+
70
+ // Add the events
71
+ this._items.forEach(item => {
72
+ item.addEventListener('mousedown', this.handleMouseDown)
73
+ item.addEventListener('mouseup', this.handleMouseUp)
74
+ item.addEventListener('dragstart', this.drag)
75
+ item.addEventListener('dragenter', this.dragging)
76
+ item.addEventListener('dragend', this.drop)
77
+ })
78
+ }
61
79
 
80
+ /**
81
+ * Reset the event listeners
82
+ *
83
+ * @private
84
+ */
85
+ resetEvents() {
86
+
87
+ // Remove the listeners
88
+ this._items.forEach((item) => {
89
+ item.removeEventListener('mousedown', this.handleMouseDown)
90
+ item.removeEventListener('mouseup', this.handleMouseUp)
91
+ item.removeEventListener('dragstart', this.drag)
92
+ item.removeEventListener('dragenter', this.dragging)
93
+ item.removeEventListener('dragend', this.drop)
62
94
  })
63
95
 
96
+ // Re-initialise the items
97
+ this.#initEvents()
98
+ }
99
+
100
+ /**
101
+ * Handle the mousedown event
102
+ *
103
+ * @private
104
+ */
105
+ handleMouseDown(e) {
106
+ // Avoid if not an element
107
+ if (!(e.target instanceof Element)) return
108
+ const target = e.target.closest('[draggable]')
109
+ if (!this._withHandle || (e.target.hasAttribute('data-handle') && e.target.getAttribute('data-handle') === 'sortable')) target.draggable = true
64
110
  }
65
111
 
66
112
  /**
67
- * Get the list of the items
113
+ * Handle the mouseup event
68
114
  *
69
- * @return {object}
115
+ * @private
70
116
  */
71
- get items() {
72
- return this._element.querySelectorAll('[draggable]')
117
+ handleMouseUp(e) {
118
+ // Avoid if not an element
119
+ if (!(e.target instanceof Element)) return
120
+ const target = e.target.closest('[draggable]')
121
+ target.draggable = false
73
122
  }
74
123
 
75
124
  /**
76
125
  * Drag an item
77
126
  *
78
- * @param {HTMLElement} item - The current item
79
127
  * @private
80
128
  */
81
- #drag(item) {
129
+ drag(e) {
130
+
131
+ // Avoid if not an element
132
+ if (!(e.target instanceof Element)) return
133
+
134
+ // Get the item
135
+ // * Bug with event listeners reset if passing some data
136
+ const item = e.target.closest('[draggable]')
82
137
 
83
138
  // Check for errors
84
139
  if (!(item instanceof HTMLElement)) throw new Error(ErrorMessage.instanceOf('item', 'HTMLElement'))
@@ -100,10 +155,16 @@ export default class Sortable extends BaseComponent {
100
155
  /**
101
156
  * When dragging an item, move it before or after an element
102
157
  *
103
- * @param {HTMLElement} item - The current item
104
158
  * @private
105
159
  */
106
- #dragging(item) {
160
+ dragging(e) {
161
+
162
+ // Avoid if not an element
163
+ if (!(e.target instanceof Element)) return
164
+
165
+ // Get the item
166
+ // * Bug with event listeners reset if passing some data
167
+ const item = e.target.closest('[draggable]')
107
168
 
108
169
  // Check for errors
109
170
  if (!(item instanceof HTMLElement)) throw new Error(ErrorMessage.instanceOf('item', 'HTMLElement'))
@@ -120,10 +181,16 @@ export default class Sortable extends BaseComponent {
120
181
  /**
121
182
  * Drop an item
122
183
  *
123
- * @param {HTMLElement} item - The current item
124
184
  * @private
125
185
  */
126
- #drop(item) {
186
+ drop(e) {
187
+
188
+ // Avoid if not an element
189
+ if (!(e.target instanceof Element)) return
190
+
191
+ // Get the item
192
+ // * Bug with event listeners reset if passing some data
193
+ const item = e.target.closest('[draggable]')
127
194
 
128
195
  // Check for errors
129
196
  if (!(item instanceof HTMLElement)) throw new Error(ErrorMessage.instanceOf('item', 'HTMLElement'))
@@ -145,26 +212,4 @@ export default class Sortable extends BaseComponent {
145
212
 
146
213
  }
147
214
 
148
- /**
149
- * Manually move up and down
150
- *
151
- * @param {HTMLElement} item - The current item
152
- * @private
153
- */
154
- #move(item, goUp = false) {
155
-
156
- const sibling = goUp ? item.previousElementSibling : item.nextElementSibling
157
-
158
- if (sibling) {
159
- this._element.insertBefore(item, goUp ? sibling : sibling.nextElementSibling)
160
- } else if (!goUp) {
161
- this._element.appendChild(item)
162
- }
163
-
164
- // Run custom event
165
- this.emmitEvent('moved', { items: this.items, current: item })
166
-
167
- }
168
-
169
-
170
215
  }
@@ -102,7 +102,6 @@ describe('Structure of the class', () => {
102
102
  })
103
103
 
104
104
  test('Constructor: Return the correct properties', () => {
105
- console.log(document.querySelectorAll('#slider [role=tabpanel]') == fakeSlider._slides)
106
105
  expect(fakeSlider).toHaveProperty('_element')
107
106
  expect(fakeSlider).toHaveProperty('_options')
108
107
  expect(fakeSlider).toHaveProperty('_slides')
@@ -8,12 +8,10 @@
8
8
  * - Constructor: Return the correct properties
9
9
  * - Mousedown & Mouseup: Without handle toggle the [draggable] attribute
10
10
  * - Mousedown & Mouseup: With handle toggle the [draggable] attribute
11
- * - #Drag(): Add the [aria-grabbed] attribute
12
- * - #Drag(): Emmit the sortable:drag event
13
- * - #Drop(): Remove the [aria-grabbed] attribute
14
- * - #Drop(): Emmit the sortable:drop event
15
- * - #Move(): Go down on click and emmit the sortable:moved event
16
- * - #Move(): Go up on click and emmit the sortable:moved event
11
+ * - Drag(): Add the [aria-grabbed] attribute
12
+ * - Drag(): Emmit the sortable:drag event
13
+ * - Drop(): Remove the [aria-grabbed] attribute
14
+ * - Drop(): Emmit the sortable:drop event
17
15
  */
18
16
 
19
17
  import { describe, test, expect, beforeAll, vi } from "vitest"
@@ -54,8 +52,8 @@ describe('Structure of the class', () => {
54
52
  expect(fakeListSortable._withHandle).toBeTypeOf('boolean')
55
53
  expect(fakeListSortable._withHandle).toBe(false)
56
54
  expect(fakeTableSortable._withHandle).toBe(true)
57
- expect(fakeListSortable.items).toBeTypeOf('object')
58
- expect(fakeListSortable.items).toStrictEqual(document.querySelectorAll('#fakeList li'))
55
+ expect(fakeListSortable._items).toBeTypeOf('object')
56
+ expect(fakeListSortable._items).toStrictEqual(document.querySelectorAll('#fakeList li'))
59
57
  })
60
58
 
61
59
  })
@@ -86,7 +84,7 @@ describe('Mousedown & Mouseup', () => {
86
84
 
87
85
  })
88
86
 
89
- describe('#Drag()', () => {
87
+ describe('Drag()', () => {
90
88
 
91
89
  test('Add the [aria-grabbed] attribute', () => {
92
90
  expect(fakeListItem.hasAttribute('aria-grabbed')).toBeFalsy()
@@ -108,7 +106,7 @@ describe('#Drag()', () => {
108
106
 
109
107
  })
110
108
 
111
- describe('#Drop()', () => {
109
+ describe('Drop()', () => {
112
110
 
113
111
  test('Remove the [aria-grabbed] attribute', () => {
114
112
  expect(fakeListItem.hasAttribute('aria-grabbed')).toBeTruthy()
@@ -124,23 +122,4 @@ describe('#Drop()', () => {
124
122
  expect(eventSpy).toHaveBeenCalledWith('drop', { current: fakeListItem, items: fakeListSortable.items })
125
123
  })
126
124
 
127
- })
128
-
129
- describe('#Move()', () => {
130
-
131
- test('Go down on click and emmit the sortable:moved event', () => {
132
- const eventSpy = vi.spyOn(fakeListSortable, 'emmitEvent')
133
- fireEvent(fakeListItem.querySelector('[data-go=down]'), new MouseEvent('click'))
134
- expect(fakeListItem).toBe(document.getElementById('fakeList').children[1])
135
- expect(eventSpy).toHaveBeenCalledWith('moved', { current: fakeListItem, items: fakeListSortable.items })
136
- })
137
-
138
- test('Go up on click and emmit the sortable:moved event', () => {
139
- const eventSpy = vi.spyOn(fakeListSortable, 'emmitEvent')
140
- expect(fakeListItem).toBe(document.getElementById('fakeList').children[1])
141
- fireEvent(fakeListItem.querySelector('[data-go=up]'), new MouseEvent('click'))
142
- expect(fakeListItem).toBe(document.getElementById('fakeList').children[0])
143
- expect(eventSpy).toHaveBeenCalledWith('moved', { current: fakeListItem, items: fakeListSortable.items })
144
- })
145
-
146
125
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@natachah/vanilla-frontend",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "A vanilla frontend framework",
5
5
  "keywords": [
6
6
  "html5",