@natachah/vanilla-frontend 0.1.16 → 0.1.18
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.
- package/docs/pages/javascript/tree.html +19 -1
- package/docs/src/js/doc-layout.js +1 -1
- package/js/_drawer.js +1 -1
- package/js/_dropdown.js +1 -1
- package/js/_sortable.js +15 -7
- package/js/_toggle.js +4 -1
- package/js/_tree.js +87 -10
- package/js/tests/drawer.test.js +1 -1
- package/js/tests/sortable.test.js +5 -5
- package/natachah-vanilla-frontend-0.1.18.tgz +0 -0
- package/package.json +1 -1
- package/natachah-vanilla-frontend-0.1.16.tgz +0 -0
|
@@ -198,7 +198,25 @@
|
|
|
198
198
|
|
|
199
199
|
<h2>Javascript</h2>
|
|
200
200
|
<p>To enable this component you need to import the javascript file and create a new Tree object.</p>
|
|
201
|
-
|
|
201
|
+
<h3>Methods</h3>
|
|
202
|
+
<table>
|
|
203
|
+
<thead>
|
|
204
|
+
<tr>
|
|
205
|
+
<th>Method</th>
|
|
206
|
+
<th>Description</th>
|
|
207
|
+
</tr>
|
|
208
|
+
</thead>
|
|
209
|
+
<tbody>
|
|
210
|
+
<tr>
|
|
211
|
+
<td data-label="Method">
|
|
212
|
+
<p>resetEvents()</p>
|
|
213
|
+
</td>
|
|
214
|
+
<td data-label="Description">
|
|
215
|
+
<p>This method will reset the items and events</p>
|
|
216
|
+
</td>
|
|
217
|
+
</tr>
|
|
218
|
+
</tbody>
|
|
219
|
+
</table>
|
|
202
220
|
<h3>Events</h3>
|
|
203
221
|
<table>
|
|
204
222
|
<thead>
|
|
@@ -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.
|
|
21
|
+
0.1.18
|
|
22
22
|
</span>
|
|
23
23
|
</li>
|
|
24
24
|
<li>
|
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('[tabindex="0"]') ?? this._element.querySelector('a,
|
|
48
|
+
this._focus = this._element.getAttribute('tabindex') === '0' ? this._element : this._element.querySelector('[tabindex="0"]') ?? this._element.querySelector('button, a, input')
|
|
49
49
|
|
|
50
50
|
this._cookie = this._options.cookie ? new Cookie(this._options.cookie) : null
|
|
51
51
|
|
package/js/_dropdown.js
CHANGED
|
@@ -37,7 +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.
|
|
40
|
+
this._focus = this._content.getAttribute('tabindex') === '0' ? this._content : this._content.querySelector('[tabindex="0"]') ?? this._content.querySelector('button, a, input')
|
|
41
41
|
|
|
42
42
|
// Init the event listener
|
|
43
43
|
this.#init()
|
package/js/_sortable.js
CHANGED
|
@@ -26,11 +26,11 @@ export default class Sortable extends BaseComponent {
|
|
|
26
26
|
super(el, options, 'sortable')
|
|
27
27
|
|
|
28
28
|
// Define the properties
|
|
29
|
-
this._items = null
|
|
30
29
|
this._withHandle = this._element.querySelector('[data-handle=sortable]') ? true : false
|
|
31
30
|
this._current = null
|
|
32
31
|
|
|
33
|
-
//
|
|
32
|
+
// Bind this only one time foreach methods
|
|
33
|
+
// * Because I add and remove events
|
|
34
34
|
this.handleMouseDown = this.handleMouseDown.bind(this)
|
|
35
35
|
this.handleMouseUp = this.handleMouseUp.bind(this)
|
|
36
36
|
this.drag = this.drag.bind(this)
|
|
@@ -57,6 +57,17 @@ export default class Sortable extends BaseComponent {
|
|
|
57
57
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Get the list of the items
|
|
62
|
+
* This is used for the emmitEvent
|
|
63
|
+
*
|
|
64
|
+
* @return {object}
|
|
65
|
+
*/
|
|
66
|
+
get _items() {
|
|
67
|
+
return this._element.querySelectorAll('[draggable]')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
60
71
|
/**
|
|
61
72
|
* Init the items and the event listeners
|
|
62
73
|
*
|
|
@@ -64,9 +75,6 @@ export default class Sortable extends BaseComponent {
|
|
|
64
75
|
*/
|
|
65
76
|
#initEvents() {
|
|
66
77
|
|
|
67
|
-
// Get the items
|
|
68
|
-
this._items = this._element.querySelectorAll('[draggable]')
|
|
69
|
-
|
|
70
78
|
// Add the events
|
|
71
79
|
this._items.forEach(item => {
|
|
72
80
|
item.addEventListener('mousedown', this.handleMouseDown)
|
|
@@ -148,7 +156,7 @@ export default class Sortable extends BaseComponent {
|
|
|
148
156
|
item.setAttribute('aria-grabbed', true)
|
|
149
157
|
|
|
150
158
|
// Run custom event
|
|
151
|
-
this.emmitEvent('drag', { items: this.
|
|
159
|
+
this.emmitEvent('drag', { items: this._items, current: item })
|
|
152
160
|
|
|
153
161
|
}
|
|
154
162
|
|
|
@@ -208,7 +216,7 @@ export default class Sortable extends BaseComponent {
|
|
|
208
216
|
item.draggable = false
|
|
209
217
|
|
|
210
218
|
// Run custom event
|
|
211
|
-
this.emmitEvent('drop', { items: this.
|
|
219
|
+
this.emmitEvent('drop', { items: this._items, current: item })
|
|
212
220
|
|
|
213
221
|
}
|
|
214
222
|
|
package/js/_toggle.js
CHANGED
|
@@ -103,7 +103,10 @@ export default class Toggle extends BaseComponent {
|
|
|
103
103
|
// Toggle the [hidden] attribute
|
|
104
104
|
toggable.hidden = this.value !== toggleValue && groupValue !== toggleValue
|
|
105
105
|
|
|
106
|
-
if (!toggable.hidden
|
|
106
|
+
if (!toggable.hidden) {
|
|
107
|
+
const focus = toggable.getAttribute('tabindex') === '0' ? toggable : toggable.querySelector('[tabindex="0"]') ?? toggable.querySelector('button, a, input')
|
|
108
|
+
if (focus) focus.focus()
|
|
109
|
+
}
|
|
107
110
|
|
|
108
111
|
})
|
|
109
112
|
|
package/js/_tree.js
CHANGED
|
@@ -29,7 +29,9 @@ export default class Tree extends BaseComponent {
|
|
|
29
29
|
|
|
30
30
|
this._withHandle = this._type == 'grid' && this._element.querySelector('[data-handle=tree]') ? true : false
|
|
31
31
|
|
|
32
|
-
this
|
|
32
|
+
// Bind this only one time foreach methods
|
|
33
|
+
// * Because I add and remove events
|
|
34
|
+
this.toggle = this.toggle.bind(this)
|
|
33
35
|
|
|
34
36
|
// Init the event listener
|
|
35
37
|
this.#init()
|
|
@@ -43,12 +45,45 @@ export default class Tree extends BaseComponent {
|
|
|
43
45
|
*/
|
|
44
46
|
#init() {
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
// Init the events on the items
|
|
49
|
+
this.#initEvents()
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get the list of the items
|
|
55
|
+
*
|
|
56
|
+
* @return {object}
|
|
57
|
+
*/
|
|
58
|
+
get _items() {
|
|
59
|
+
return this._element.querySelectorAll('[aria-expanded]')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Init the items and the event listeners
|
|
64
|
+
*
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
#initEvents() {
|
|
68
|
+
this._items.forEach(item => {
|
|
69
|
+
item.addEventListener('click', this.toggle)
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Reset the event listeners
|
|
75
|
+
*
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
resetEvents() {
|
|
79
|
+
|
|
80
|
+
// Remove the listeners
|
|
81
|
+
this._items.forEach((item) => {
|
|
82
|
+
item.removeEventListener('click', this.toggle)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Re-initialise the items
|
|
86
|
+
this.#initEvents()
|
|
52
87
|
|
|
53
88
|
}
|
|
54
89
|
|
|
@@ -57,7 +92,21 @@ export default class Tree extends BaseComponent {
|
|
|
57
92
|
*
|
|
58
93
|
* @param {HTMLElement} item - The current item
|
|
59
94
|
*/
|
|
60
|
-
toggle(
|
|
95
|
+
toggle(e) {
|
|
96
|
+
|
|
97
|
+
let item
|
|
98
|
+
|
|
99
|
+
if (e instanceof Event) {
|
|
100
|
+
// If it's an event verify about the handle + if target is an HTML element
|
|
101
|
+
if (!(e.target instanceof Element)) return
|
|
102
|
+
if (this._withHandle && (!e.target.hasAttribute('data-handle') || e.target.getAttribute('data-handle') !== 'tree')) return
|
|
103
|
+
e.stopPropagation()
|
|
104
|
+
item = e.target.closest('[aria-expanded]')
|
|
105
|
+
} else {
|
|
106
|
+
// If it's NOT an event verify that it's an HTML element
|
|
107
|
+
if (!(e instanceof Element)) return
|
|
108
|
+
item = e
|
|
109
|
+
}
|
|
61
110
|
|
|
62
111
|
// Check for errors
|
|
63
112
|
if (!(item instanceof HTMLElement)) throw new Error(ErrorMessage.instanceOf('item', 'HTMLElement'))
|
|
@@ -74,8 +123,36 @@ export default class Tree extends BaseComponent {
|
|
|
74
123
|
|
|
75
124
|
// Set the focus on the required child
|
|
76
125
|
if (!isExpanded) {
|
|
77
|
-
|
|
78
|
-
|
|
126
|
+
|
|
127
|
+
let childToFocus = null
|
|
128
|
+
|
|
129
|
+
const child = children.find(el => {
|
|
130
|
+
|
|
131
|
+
// Check if the child have a tabindex
|
|
132
|
+
if (el.getAttribute('tabindex') === '0') {
|
|
133
|
+
childToFocus = el
|
|
134
|
+
return el
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Otherwise if an element inside the child have the tabindex
|
|
138
|
+
const childWithTabIndex = el.querySelector('[tabindex="0"]')
|
|
139
|
+
if (childWithTabIndex) {
|
|
140
|
+
childToFocus = childWithTabIndex
|
|
141
|
+
return childWithTabIndex
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Otherwise get the first focusable element
|
|
145
|
+
childToFocus = el.querySelector('button, a, input')
|
|
146
|
+
return el
|
|
147
|
+
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Add the focus if open
|
|
151
|
+
// * Need to wait the transition before make it focused
|
|
152
|
+
if (child && childToFocus) {
|
|
153
|
+
childToFocus.focus()
|
|
154
|
+
}
|
|
155
|
+
|
|
79
156
|
}
|
|
80
157
|
|
|
81
158
|
// If type grid, collapse the subchildren
|
package/js/tests/drawer.test.js
CHANGED
|
@@ -26,7 +26,7 @@ beforeAll(() => {
|
|
|
26
26
|
document.body.innerHTML =
|
|
27
27
|
'<div id="backdrop"></div>' +
|
|
28
28
|
'<button aria-expanded="false" aria-pressed="false" aria-controls="drawer"></button>' +
|
|
29
|
-
'<aside id="drawer"
|
|
29
|
+
'<aside id="drawer" hidden><button id="focus"></button></aside>'
|
|
30
30
|
|
|
31
31
|
Object.defineProperty(window, 'innerWidth', { configurable: true, value: 1200 })
|
|
32
32
|
|
|
@@ -29,9 +29,9 @@ beforeAll(() => {
|
|
|
29
29
|
|
|
30
30
|
document.body.innerHTML =
|
|
31
31
|
'<ul id="fakeList">' +
|
|
32
|
-
'<li id="first" draggable="false"
|
|
33
|
-
'<li draggable="false"
|
|
34
|
-
'<li draggable="false"
|
|
32
|
+
'<li id="first" draggable="false">One</li>' +
|
|
33
|
+
'<li draggable="false">Two</li>' +
|
|
34
|
+
'<li draggable="false">Three</li>' +
|
|
35
35
|
'</ul>' +
|
|
36
36
|
'<table id="fakeTable">' +
|
|
37
37
|
'<tr draggable="false"><td data-handle="sortable">DRAG</td><td>One</td></tr>' +
|
|
@@ -101,7 +101,7 @@ describe('Drag()', () => {
|
|
|
101
101
|
expect(eventSpy).not.toHaveBeenCalled()
|
|
102
102
|
fireEvent(fakeListItem, new MouseEvent('mousedown'))
|
|
103
103
|
fireEvent(fakeListItem, new MouseEvent('dragstart'))
|
|
104
|
-
expect(eventSpy).toHaveBeenCalledWith('drag', { current: fakeListItem, items: fakeListSortable.
|
|
104
|
+
expect(eventSpy).toHaveBeenCalledWith('drag', { current: fakeListItem, items: fakeListSortable._items })
|
|
105
105
|
})
|
|
106
106
|
|
|
107
107
|
})
|
|
@@ -119,7 +119,7 @@ describe('Drop()', () => {
|
|
|
119
119
|
fireEvent(fakeListItem, new MouseEvent('mousedown')) // First drag item
|
|
120
120
|
fireEvent(fakeListItem, new MouseEvent('dragstart')) // First drag item
|
|
121
121
|
fireEvent(fakeListItem, new MouseEvent('dragend'))
|
|
122
|
-
expect(eventSpy).toHaveBeenCalledWith('drop', { current: fakeListItem, items: fakeListSortable.
|
|
122
|
+
expect(eventSpy).toHaveBeenCalledWith('drop', { current: fakeListItem, items: fakeListSortable._items })
|
|
123
123
|
})
|
|
124
124
|
|
|
125
125
|
})
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|