@natachah/vanilla-frontend 0.0.3 → 0.0.5

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.
@@ -94,6 +94,24 @@
94
94
 
95
95
  <p>To work properly the <code>&lt;button&gt;</code> of the dropdown must have an <code>aria-controls=&quot;IdOfTheContent&quot;</code>, an <code>aria-expanded</code> and an <code>aria-pressed</code> attributes.</p>
96
96
 
97
+ <p>You can also add some buttons into the list to make them look as a vertical group.</p>
98
+
99
+ <doc-demo>
100
+ <div class="dropdown demo-dropdown">
101
+ <button aria-controls="mySecondDropdown" aria-expanded="false" aria-pressed="false">
102
+ Dropdown
103
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
104
+ <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"></path>
105
+ </svg>
106
+ </button>
107
+ <ul id="mySecondDropdown" tabindex="0" style="--button-background: var(--color-body);" hidden>
108
+ <li><button>Button longer</button></li>
109
+ <li><button>Button</button></li>
110
+ <li><button>Button</button></li>
111
+ </ul>
112
+ </div>
113
+ </doc-demo>
114
+
97
115
  <h2>States</h2>
98
116
 
99
117
  <p>The <code>&lt;button&gt;</code> inside the dropdown will work as the default button component.</p>
@@ -208,7 +226,7 @@
208
226
 
209
227
  <doc-code data-type="js">
210
228
  new Toggle(myDropdown, {
211
- closable:false
229
+ closable:false
212
230
  })
213
231
  </doc-code>
214
232
 
@@ -243,8 +261,8 @@
243
261
  <doc-code data-type="js">
244
262
  const dropdown = document.getElementById('myDropdown')
245
263
  dropdown.addEventListener('dropdown:changed', (e) => {
246
- const value = e.detail.isOpen
247
- console.log(value)
264
+ const value = e.detail.isOpen
265
+ console.log(value)
248
266
  })
249
267
  </doc-code>
250
268
 
@@ -48,23 +48,23 @@
48
48
  </div>
49
49
 
50
50
  <h2 id="handle">Handle</h2>
51
- <p>You can decide which part of the item is draggable with the <code>data-handle</code> attribute</p>
51
+ <p>You can decide which part of the item is draggable with the <code>data-handle="sortable"</code> attribute</p>
52
52
  <doc-demo>
53
53
  <ul class="demo-sortable">
54
54
  <li draggable=" false">
55
- <span data-handle>
55
+ <span data-handle="sortable">
56
56
  HANDLE
57
57
  </span>
58
58
  Lorem, ipsum.
59
59
  </li>
60
60
  <li draggable="false">
61
- <span data-handle>
61
+ <span data-handle="sortable">
62
62
  HANDLE
63
63
  </span>
64
64
  Impedit, quod!
65
65
  </li>
66
66
  <li draggable="false">
67
- <span data-handle>
67
+ <span data-handle="sortable">
68
68
  HANDLE
69
69
  </span>
70
70
  Repudiandae, rerum.
@@ -75,19 +75,19 @@
75
75
  <doc-code>
76
76
  <ul id="mySortableListWithHandle">
77
77
  <li draggable="false">
78
- <span data-handle>
78
+ <span data-handle="sortable">
79
79
  Handle
80
80
  </span>
81
81
  Lorem, ipsum.
82
82
  </li>
83
83
  <li draggable="false">
84
- <span data-handle>
84
+ <span data-handle="sortable">
85
85
  Handle
86
86
  </span>
87
87
  Impedit, quod!
88
88
  </li>
89
89
  <li draggable="false">
90
- <span data-handle>
90
+ <span data-handle="sortable">
91
91
  Handle
92
92
  </span>
93
93
  Repudiandae, rerum.
@@ -135,9 +135,9 @@
135
135
  <doc-code data-type="js">
136
136
  const mySortable = document.getElementById('mySortableList')
137
137
  mySortable.addEventListener('sortable:drag', (e) => {
138
- const theCollectionOfItems = e.detail.items
139
- const thecurrentItem = e.detail.current
140
- ...
138
+ const theCollectionOfItems = e.detail.items
139
+ const thecurrentItem = e.detail.current
140
+ ...
141
141
  })
142
142
  </doc-code>
143
143
 
@@ -0,0 +1,89 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Documentations: Javascript > Tabpanel</title>
8
+ </head>
9
+
10
+ <body data-preload>
11
+ <doc-layout>
12
+
13
+ <h1>Tabpanel</h1>
14
+ <p>The tabpanel component make you able to make some elements visible by some <code>&lt;button&gt;</code>.</p>
15
+ <p>The button must have an <code>aria-controls=&quot;IdOfElement&quot;</code>, an <code>aria-expanded</code> and a <code>aria-pressed</code> attributes.</p>
16
+
17
+
18
+
19
+ <div class="code-group">
20
+ <div role="tablist">
21
+ <button role="tab" aria-controls="html">HTML</button>
22
+ <button role="tab" aria-controls="js">JS</button>
23
+ </div>
24
+ <doc-code id="html" data-type="html" role="tabpanel">
25
+ <div id="myPanel">
26
+ <div role="tablist">
27
+ <button role="tab" aria-controls="one">One</button>
28
+ <button role="tab" aria-controls="two">Two</button>
29
+ </div>
30
+ <div id="one" role="tabpanel">
31
+ This is the first panel
32
+ </div>
33
+ <div id="two" role="tabpanel">
34
+ This is the seconde panel
35
+ </div>
36
+ </div>
37
+ </doc-code>
38
+ <doc-code id="js" data-type="js" role="tabpanel">
39
+ import Tabpanel from '@natachah/vanilla-frontend/js/_tabpanel.js'
40
+ const tabpanel = document.getElementById('myPanel')
41
+ if (tabpanel) new Tabpanel(tabpanel)
42
+ </doc-code>
43
+ </div>
44
+
45
+ <blockquote class="tip">
46
+ <p>These website use the Tabpanel to show you the code of each component !</p>
47
+ </blockquote>
48
+
49
+ <h2>Javascript</h2>
50
+ <p>To enable this component you need to import the javascript file and create a new Tabpanel object.</p>
51
+
52
+ <h3>Events</h3>
53
+ <table>
54
+ <thead>
55
+ <tr>
56
+ <th>Event</th>
57
+ <th>Description</th>
58
+ <th>Value</th>
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+ <tr>
63
+ <td data-label="Event">
64
+ <p>tabpanel:changed</p>
65
+ </td>
66
+ <td data-label="Description">
67
+ <p>This event is fired when the panel as been changed</p>
68
+ </td>
69
+ <td data-label="Value">
70
+ <p><code>current</code> as a <code>HTMLElement</code> of the current button</p>
71
+ </td>
72
+ </tr>
73
+ </tbody>
74
+ </table>
75
+
76
+ <doc-code data-type="js">
77
+ const myPanel = document.getElementById('myPanel')
78
+ myPanel.addEventListener('tabpanel:changed', (e) => {
79
+ const thecurrentButton = e.detail.current
80
+ console.log('It has changed !')
81
+ })
82
+ </doc-code>
83
+
84
+
85
+ </doc-layout>
86
+ <script type="module" src="/main.js"></script>
87
+ </body>
88
+
89
+ </html>
@@ -136,12 +136,12 @@
136
136
  </blockquote>
137
137
 
138
138
  <h2>Handle</h2>
139
- <p>You can decide which part of the item toggle the open/close method with the <code>data-handle</code> attribute</p>
139
+ <p>You can decide which part of the item toggle the open/close method with the <code>data-handle="tree"</code> attribute</p>
140
140
  <doc-demo>
141
141
  <ul class="demo-tree" role="tree">
142
142
  <li role="treeitem">
143
143
  <span aria-expanded="false" aria-owns="sublist">
144
- <span data-handle>
144
+ <span data-handle="tree">
145
145
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
146
146
  <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"></path>
147
147
  </svg>
@@ -162,7 +162,7 @@
162
162
  ...
163
163
  <li role="treeitem">
164
164
  <span aria-expanded="false" aria-owns="treelist">
165
- <span data-handle>
165
+ <span data-handle="tree">
166
166
  HANDLE
167
167
  </span>
168
168
  Inventore, perspiciatis
@@ -209,8 +209,8 @@
209
209
  <doc-code data-type="js">
210
210
  const myTree = document.getElementById('myTree')
211
211
  myTree.addEventListener('tree:changed', (e) => {
212
- const isOpen = e.detail.isOpen
213
- ...
212
+ const isOpen = e.detail.isOpen
213
+ ...
214
214
  })
215
215
  </doc-code>
216
216
 
@@ -89,6 +89,7 @@ class DocLayout extends HTMLElement {
89
89
  <li><a href="/pages/javascript/scroll.html">Scroll</a></li>
90
90
  <li><a href="/pages/javascript/sidebar.html">Sidebar</a></li>
91
91
  <li><a href="/pages/javascript/sortable.html">Sortable</a></li>
92
+ <li><a href="/pages/javascript/tabpanel.html">Tabpanel</a></li>
92
93
  <li><a href="/pages/javascript/toggle.html">Toggle</a></li>
93
94
  <li><a href="/pages/javascript/tree.html">Tree</a></li>
94
95
  </ul>
package/js/_sortable.js CHANGED
@@ -27,9 +27,11 @@ export default class Sortable extends BaseComponent {
27
27
  super(el, options, 'sortable')
28
28
 
29
29
  // Define the properties
30
- this._withHandle = this._element.querySelector('[data-handle]') ? true : false
30
+ this._withHandle = this._element.querySelector('[data-handle=sortable]') ? true : false
31
31
  this._current = null
32
32
 
33
+ console.log(this)
34
+
33
35
  // Init the event listener
34
36
  this.#init()
35
37
 
@@ -49,7 +51,7 @@ export default class Sortable extends BaseComponent {
49
51
  this.items.forEach((item) => {
50
52
 
51
53
  // Toggle the [dragable] attribute
52
- item.addEventListener('mousedown', (e) => { if (!this._withHandle || e.target.hasAttribute('data-handle')) item.draggable = true })
54
+ item.addEventListener('mousedown', (e) => { if (!this._withHandle || (e.target.hasAttribute('data-handle') && e.target.getAttribute('data-handle') === 'sortable')) item.draggable = true })
53
55
  item.addEventListener('mouseup', () => item.draggable = false)
54
56
 
55
57
  // Drag and drop events
@@ -126,6 +128,9 @@ export default class Sortable extends BaseComponent {
126
128
  // Check for errors
127
129
  if (!(item instanceof HTMLElement)) throw new Error(ErrorMessage.instanceOf('item', 'HTMLElement'))
128
130
 
131
+ // Do nothing if there is NO current
132
+ if (!this._current) return
133
+
129
134
  // Reset the current property
130
135
  this._current = null
131
136
 
package/js/_tree.js CHANGED
@@ -28,7 +28,7 @@ export default class Tree extends BaseComponent {
28
28
  // Define the properties
29
29
  this._type = this._element.role == 'tree' ? 'list' : 'grid'
30
30
 
31
- this._withHandle = this._element.querySelector('[data-handle]') ? true : false
31
+ this._withHandle = this._element.querySelector('[data-handle=tree]') ? true : false
32
32
 
33
33
  this._items = this._element.querySelectorAll('[aria-expanded]')
34
34
 
@@ -45,7 +45,7 @@ export default class Tree extends BaseComponent {
45
45
  #init() {
46
46
 
47
47
  this._items.forEach(item => item.addEventListener('click', (e) => {
48
- if (!this._withHandle || e.target.hasAttribute('data-handle')) {
48
+ if (!this._withHandle || (e.target.hasAttribute('data-handle') && e.target.getAttribute('data-handle') === 'tree')) {
49
49
  e.stopPropagation()
50
50
  this.toggle(item)
51
51
  }
@@ -34,9 +34,9 @@ beforeAll(() => {
34
34
  '<li draggable="false">Three</li>' +
35
35
  '</ul>' +
36
36
  '<table id="fakeTable">' +
37
- '<tr draggable="false"><td data-handle>DRAG</td><td>One</td></tr>' +
38
- '<tr draggable="false"><td data-handle>DRAG</td><td>Two</td></tr>' +
39
- '<tr draggable="false"><td data-handle>DRAG</td><td>Three</td></tr>' +
37
+ '<tr draggable="false"><td data-handle="sortable">DRAG</td><td>One</td></tr>' +
38
+ '<tr draggable="false"><td data-handle="sortable">DRAG</td><td>Two</td></tr>' +
39
+ '<tr draggable="false"><td data-handle="sortable">DRAG</td><td>Three</td></tr>' +
40
40
  '</table>'
41
41
 
42
42
  fakeListSortable = new Sortable(document.getElementById('fakeList'))
@@ -70,7 +70,7 @@ describe('Mousedown & Mouseup', () => {
70
70
 
71
71
  test('With handle & Mouseup toggle the [draggable] attribute', () => {
72
72
  const item = document.querySelector('#fakeTable tr')
73
- const handle = document.querySelector('#fakeTable tr:first-child [data-handle]')
73
+ const handle = document.querySelector('#fakeTable tr:first-child [data-handle=sortable]')
74
74
  const customMousedown = new MouseEvent('mousedown')
75
75
  Object.defineProperty(customMousedown, 'target', { value: handle }) // Define the mousedown event with custom target
76
76
  expect(item.draggable).toBeFalsy()
@@ -116,7 +116,8 @@ describe('#Drop()', () => {
116
116
 
117
117
  test('Emmit the sortable:drop event', () => {
118
118
  const eventSpy = vi.spyOn(fakeListSortable, 'emmitEvent')
119
- expect(eventSpy).not.toHaveBeenCalled()
119
+ fireEvent(fakeListItem, new MouseEvent('mousedown')) // First drag item
120
+ fireEvent(fakeListItem, new MouseEvent('dragstart')) // First drag item
120
121
  fireEvent(fakeListItem, new MouseEvent('dragend'))
121
122
  expect(eventSpy).toHaveBeenCalledWith('drop', { current: fakeListItem, items: fakeListSortable.items })
122
123
  })
@@ -41,8 +41,8 @@ beforeAll(() => {
41
41
  '</ul>' +
42
42
  '<table id="fakeGridTree" role="treegrid">' +
43
43
  '<tr aria-level="1"><td></td></tr>' +
44
- '<tr aria-level="1" aria-expanded="false" aria-owns="lvl2"><td data-handle></td></tr>' +
45
- '<tr id="lvl2" aria-level="2" aria-expanded="false" aria-owns="lvl3" hidden><td data-handle></td></tr>' +
44
+ '<tr aria-level="1" aria-expanded="false" aria-owns="lvl2"><td data-handle="tree"></td></tr>' +
45
+ '<tr id="lvl2" aria-level="2" aria-expanded="false" aria-owns="lvl3" hidden><td data-handle="tree"></td></tr>' +
46
46
  '<tr id="lvl3" aria-level="3" hidden><td></td></tr>' +
47
47
  '<tr aria-level="1"><td></td></tr>' +
48
48
  '</table>'
@@ -53,7 +53,7 @@ beforeAll(() => {
53
53
  fakeRow = fakeGridTree._element.querySelector('tr[aria-level="1"][aria-expanded]')
54
54
 
55
55
  customClick = new MouseEvent('click')
56
- Object.defineProperty(customClick, 'target', { value: fakeRow.querySelector('[data-handle]') }) // Define the click event with custom target
56
+ Object.defineProperty(customClick, 'target', { value: fakeRow.querySelector('[data-handle=tree]') }) // Define the click event with custom target
57
57
 
58
58
  })
59
59
 
@@ -130,10 +130,10 @@ describe('#Toggle()', () => {
130
130
  const lvl3 = document.getElementById('lvl3')
131
131
 
132
132
  const customClickLvl2 = new MouseEvent('click')
133
- Object.defineProperty(customClickLvl2, 'target', { value: lvl2.querySelector('[data-handle]') }) // Define the click event with custom target
133
+ Object.defineProperty(customClickLvl2, 'target', { value: lvl2.querySelector('[data-handle=tree]') }) // Define the click event with custom target
134
134
 
135
135
  const customClickLvl3 = new MouseEvent('click')
136
- Object.defineProperty(customClickLvl3, 'target', { value: lvl3.querySelector('[data-handle]') }) // Define the click event with custom target
136
+ Object.defineProperty(customClickLvl3, 'target', { value: lvl3.querySelector('[data-handle=tree]') }) // Define the click event with custom target
137
137
 
138
138
  fireEvent(fakeRow, customClick)
139
139
  fireEvent(lvl2, customClickLvl2)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@natachah/vanilla-frontend",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "A vanilla frontend framework",
5
5
  "keywords": [
6
6
  "html5",
@@ -125,7 +125,7 @@
125
125
  margin: 0;
126
126
 
127
127
  // Simple item
128
- &:not(:has(> a:first-child:last-child)) {
128
+ &:not(:has(> a:first-child:last-child, > button:first-child:last-child)) {
129
129
  @include as-item($name, (), $properties);
130
130
  }
131
131
 
@@ -135,15 +135,23 @@
135
135
  @include as-item($name, $states, $properties);
136
136
  }
137
137
 
138
+ // Item with button
139
+ &:has(> button:first-child:last-child) > button {
140
+ width: 100%;
141
+ text-align: left;
142
+ }
143
+
138
144
  // Remove extra border
139
145
  & + *,
140
- & + * > a {
146
+ & + * > a,
147
+ & + * > button {
141
148
  border-top: none !important;
142
149
  }
143
150
 
144
151
  // Remove radius on middle child
145
152
  &:not(:first-child, :last-child),
146
- &:not(:first-child, :last-child) > a {
153
+ &:not(:first-child, :last-child) > a,
154
+ &:not(:first-child, :last-child) > button {
147
155
  border-radius: 0 !important;
148
156
  }
149
157
 
@@ -152,14 +160,16 @@
152
160
 
153
161
  // Remove radius bottom on first child
154
162
  &:first-child,
155
- &:first-child > a {
163
+ &:first-child > a,
164
+ &:first-child > button {
156
165
  border-end-start-radius: 0 !important;
157
166
  border-end-end-radius: 0 !important;
158
167
  }
159
168
 
160
169
  // Remove radius top on last child
161
170
  &:last-child,
162
- &:last-child > a {
171
+ &:last-child > a,
172
+ &:last-child > button {
163
173
  border-start-start-radius: 0 !important;
164
174
  border-start-end-radius: 0 !important;
165
175
  }