@natachah/vanilla-frontend 0.1.3 → 0.1.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.
package/docs/main.js CHANGED
@@ -22,9 +22,9 @@ if (current.startsWith('/pages/')) document.querySelectorAll(`#sidebar a[href*="
22
22
  })
23
23
 
24
24
  // My awsome sidebar !!!
25
- import Sidebar from './../js/_sidebar.js'
25
+ import Drawer from './../js/_drawer.js'
26
26
  const sidebar = document.getElementById('sidebar')
27
- if (sidebar) new Sidebar(sidebar)
27
+ if (sidebar) new Drawer(sidebar)
28
28
 
29
29
  // Code group
30
30
  import Tabpanel from './../js/_tabpanel.js'
@@ -119,7 +119,7 @@
119
119
  </doc-code>
120
120
  <doc-code id="scss" data-type="scss" role="tabpanel">
121
121
  $outline-variations: (
122
- button
122
+ button
123
123
  );
124
124
  </doc-code>
125
125
  </div>
@@ -145,11 +145,25 @@
145
145
  </doc-code>
146
146
  <doc-code id="scss" data-type="scss" role="tabpanel">
147
147
  $color-variations: (
148
- button: (primary)
148
+ button: (primary)
149
149
  );
150
150
  </doc-code>
151
151
  </div>
152
152
 
153
+ <h3>As link</h3>
154
+
155
+ <p>You can create a button that look as a simple link with the attribute <code>role="link"</code>.</p>
156
+
157
+ <doc-demo>
158
+ <button role="link">As link</button>
159
+ <button role="link" disabled>As disabled link</button>
160
+ </doc-demo>
161
+
162
+ <doc-code data-typ="html">
163
+ <button role="link">As link</button>
164
+ <button role="link" disabled>As disabled link</button>
165
+ </doc-code>
166
+
153
167
  <h3>Group</h3>
154
168
  <p>You can group some badge by putting them in a <code>&lt;div&gt;</code> with the class <code>.group</code>.</p>
155
169
 
@@ -77,6 +77,10 @@
77
77
  <input type="file" name="file" accept="image/png, image/jpeg">
78
78
  </doc-demo>
79
79
 
80
+ <blockquote class="info">
81
+ <p>You can change the icon via <code>var(--icon-file)</code>.</p>
82
+ </blockquote>
83
+
80
84
  <p>The type <b>date</b>, <b>time</b> and <b>datetime-local</b> come with default icon.</p>
81
85
  <doc-demo>
82
86
  <input type="date" name="date">
@@ -84,6 +88,10 @@
84
88
  <input type="datetime-local" name="datetime">
85
89
  </doc-demo>
86
90
 
91
+ <blockquote class="info">
92
+ <p>You can change the icon via <code>var(--icon-date)</code> and <code>var(--icon-time)</code>.</p>
93
+ </blockquote>
94
+
87
95
  <blockquote class="warning">
88
96
  <p>Hard to make it 100% similar on all browser.</p>
89
97
  </blockquote>
@@ -113,6 +121,10 @@
113
121
  </select>
114
122
  </doc-demo>
115
123
 
124
+ <blockquote class="info">
125
+ <p>You can change the icon via <code>var(--icon-select)</code>.</p>
126
+ </blockquote>
127
+
116
128
  <h3>Range</h3>
117
129
  <p>The <b>range</b> field look more like a progress bar.</p>
118
130
  <doc-demo>
@@ -174,6 +186,10 @@
174
186
  </fieldset>
175
187
  </doc-code>
176
188
 
189
+ <blockquote class="info">
190
+ <p>You can change the icon via <code>var(--icon-radio)</code>.</p>
191
+ </blockquote>
192
+
177
193
  <h3>Checkbox</h3>
178
194
  <p>The <b>checkbox</b> field must be inside a <code>&lt;fieldset&gt;</code>.</p>
179
195
  <p>By default the checkboxes are displayed inline.</p>
@@ -231,6 +247,10 @@
231
247
  </fieldset>
232
248
  </doc-code>
233
249
 
250
+ <blockquote class="info">
251
+ <p>You can change the icon via <code>var(--icon-check)</code>.</p>
252
+ </blockquote>
253
+
234
254
  <h3>Switch</h3>
235
255
  <p>The <b>checkbox</b> with the <code>role=&quot;switch&quot;</code> attribute will render a switch component.</p>
236
256
  <doc-demo>
@@ -240,6 +260,10 @@
240
260
  <input type="checkbox" role="switch" id="switch" name="switch" value="true"> <label for="switch">I agree to the terms</label>
241
261
  </doc-code>
242
262
 
263
+ <blockquote class="info">
264
+ <p>You can change the icon via <code>var(--icon-switch)</code>.</p>
265
+ </blockquote>
266
+
243
267
  <h2>States</h2>
244
268
  <p>The form fields can have multiple states as <code>:focus</code>, <code>:disabled</code>, <code>:readonly</code> and <code>:validation</code>.</p>
245
269
 
@@ -323,7 +347,7 @@
323
347
  @use '@natachah/vanilla-frontend/scss/components/group';
324
348
  </doc-code>
325
349
  </div>
326
-
350
+
327
351
  </doc-layout>
328
352
  <script type="module" src="/main.js"></script>
329
353
  </body>
@@ -4,19 +4,24 @@
4
4
  <head>
5
5
  <meta charset="UTF-8" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Documentations: Javascript > Sidebar</title>
7
+ <title>Documentations: Javascript > Drawer</title>
8
8
  </head>
9
9
 
10
10
  <body data-preload>
11
11
  <doc-layout>
12
12
 
13
- <h1>Sidebar</h1>
14
- <p>The sidebar component make you able to toggle a sidebar with a button and resize window.</p>
13
+ <h1>Drawer</h1>
14
+ <p>The drawer component make you able to toggle a drawer with a button and resize window.</p>
15
15
 
16
16
  <h2>Javascript</h2>
17
- <p>This component is only in javascript, to use it you must import the javascript file and create a new Sidebar object.</p>
17
+ <p>This component is only in javascript, to use it you must import the javascript file and create a new Drawer object.</p>
18
18
  <p>You can customize the breakpoint when initiate the component.</p>
19
- <p>You can have a <b>Backdrop</b> if you want to make it more like a drawer opening.</p>
19
+ <p>You can have a <b>Backdrop</b> if you want to make it more like a drawer opening on the front of the content.</p>
20
+
21
+ <blockquote>
22
+ <p>Main use case are sidebar menu or main navigation menu.</p>
23
+ <p>This documentation use the drawer as an exemple for the sidebar on the left !</p>
24
+ </blockquote>
20
25
 
21
26
  <div class="code-group">
22
27
  <div role="tablist">
@@ -25,23 +30,19 @@
25
30
  </div>
26
31
  <doc-code id="html" data-type="html" role="tabpanel">
27
32
  <div id="backdrop"></div>
28
- <button aria-expanded="false" aria-pressed="false" aria-controls="sidebar">Toggle</button>
29
- <aside id="sidebar" tabindex="0" hidden>
30
- <button aria-expanded="false" aria-pressed="false" aria-controls="sidebar">Toggle</button>
31
- My sidebar
33
+ <button aria-expanded="false" aria-pressed="false" aria-controls="drawer">Toggle</button>
34
+ <aside id="drawer" tabindex="0" hidden>
35
+ <button aria-expanded="false" aria-pressed="false" aria-controls="drawer">Toggle</button>
36
+ My drawer
32
37
  </aside>
33
38
  </doc-code>
34
39
  <doc-code id="js" data-type="js" role="tabpanel">
35
- import Sidebar from '@natachah/vanilla-frontend/js/utilities/_sidebar.js'
36
- const sidebar = document.getElementById('sidebar')
37
- if (sidebar) new Sidebar(sidebar, { breakpoint : 960 })
40
+ import Drawer from '@natachah/vanilla-frontend/js/utilities/_drawer.js'
41
+ const drawer = document.getElementById('drawer')
42
+ if (drawer) new Drawer(drawer, { breakpoint : 960 })
38
43
  </doc-code>
39
44
  </div>
40
45
 
41
- <blockquote>
42
- <p>This documentation use the sidebar as an exemple !</p>
43
- </blockquote>
44
-
45
46
  </doc-layout>
46
47
  <script type="module" src="/main.js"></script>
47
48
  </body>
@@ -10,28 +10,36 @@
10
10
  <body data-preload>
11
11
  <doc-layout>
12
12
 
13
+ <blockquote class="warning">
14
+ <p>The <code>role=tree</code> and <code>role=treeGrid</code> are not accessible !</p>
15
+ </blockquote>
16
+
13
17
  <h1>Tree</h1>
14
18
  <p>The tree component make you able to make a tree view by adding the <code>role=&quot;tree&quot;</code> attribute on a <code>&lt;ul&gt;</code> or <code>&lt;ol&gt;</code> tag.</p>
15
19
  <p>The <code>&lt;li&gt;</code> must have a <code>role=&quot;treeitem&quot;</code>, and if nested the <code>aria-expanded</code> and <code>aria-owns</code> attributes.</p>
16
20
  <doc-demo>
17
- <ul class="demo-tree" role="tree">
18
- <li role="treeitem">1: Lorem, ipsum</li>
19
- <li role="treeitem">
20
- <span aria-expanded="false" aria-owns="treelist">1: Inventore, perspiciatis (open me)</span>
21
+ <ul class="demo-tree">
22
+ <li>1: Lorem, ipsum</li>
23
+ <li>
24
+ <button role="link" aria-controls="treelist" aria-expanded="false">
25
+ 1: Inventore, perspiciatis (Open)
26
+ </button>
21
27
  <ul id="treelist" hidden>
22
- <li role="treeitem">2: Lorem</li>
23
- <li role="treeitem">
24
- <span aria-expanded="false" aria-owns="subtreelist">2: Adipisci (open me)</span>
28
+ <li>2: Lorem</li>
29
+ <li>
30
+ <button role="link" aria-controls="subtreelist" aria-expanded="false">
31
+ 2: Adipisci (Open)
32
+ </button>
25
33
  <ul id="subtreelist" hidden>
26
- <li role="treeitem">3: Lorem</li>
27
- <li role="treeitem">3: Adipisci</li>
28
- <li role="treeitem">3: Facilis</li>
34
+ <li>3: Lorem</li>
35
+ <li>3: Adipisci</li>
36
+ <li>3: Facilis</li>
29
37
  </ul>
30
38
  </li>
31
- <li role="treeitem">1: Facilis</li>
39
+ <li>1: Facilis</li>
32
40
  </ul>
33
41
  </li>
34
- <li role="treeitem">Dolor, quis</li>
42
+ <li>Dolor, quis</li>
35
43
  </ul>
36
44
  </doc-demo>
37
45
 
@@ -41,47 +49,55 @@
41
49
  <button role="tab" aria-controls="js">JS</button>
42
50
  </div>
43
51
  <doc-code id="html" data-type="html" role="tabpanel">
44
- <ul id="treeList" role="tree">
45
- <li role="treeitem">Lorem, ipsum</li>
46
- <li role="treeitem">
47
- <span aria-expanded="false" aria-owns="treelist">Inventore, perspiciatis</span>
52
+ <ul class="demo-tree">
53
+ <li>1: Lorem, ipsum</li>
54
+ <li>
55
+ <button role="link" aria-controls="treelist" aria-expanded="false">
56
+ 1: Inventore, perspiciatis (Open)
57
+ </button>
48
58
  <ul id="treelist" hidden>
49
- <li role="treeitem">Lorem</li>
50
- <li role="treeitem">
51
- <span aria-expanded="false" aria-owns="subtreelist">Adipisci</span>
59
+ <li>2: Lorem</li>
60
+ <li>
61
+ <button role="link" aria-controls="subtreelist" aria-expanded="false">
62
+ 2: Adipisci (Open)
63
+ </button>
52
64
  <ul id="subtreelist" hidden>
53
- <li role="treeitem">Adipisci: Lorem</li>
54
- <li role="treeitem">Adipisci: Adipisci</li>
55
- <li role="treeitem">Adipisci: Facilis</li>
65
+ <li>3: Lorem</li>
66
+ <li>3: Adipisci</li>
67
+ <li>3: Facilis</li>
56
68
  </ul>
57
69
  </li>
58
- <li role="treeitem">Facilis</li>
70
+ <li>1: Facilis</li>
59
71
  </ul>
60
72
  </li>
61
- <li role="treeitem">Dolor, quis</li>
73
+ <li>Dolor, quis</li>
62
74
  </ul>
63
75
  </doc-code>
64
76
  <doc-code id="js" data-type="js" role="tabpanel">
65
77
  import Tree from "@natachah/vanilla-frontend/js/_tree"
66
- const treeList = document.getElementById('treeList')
78
+ const treeList = document.querySelector('.demo-tree')
67
79
  if (treeList) new Tree(treeList)
68
80
  </doc-code>
69
81
  </div>
70
82
 
83
+ <blockquote class="note">
84
+ <p>Into a <code>&lt;li&gt;</code> you must add a <code>&lt;button&gt;</code> to toggle the children, otherwise it will toggle if you click on any child.</p>
85
+ </blockquote>
86
+
71
87
  <p>This can also be implemented on a <code>&lt;table&gt;</code> but it required the <code>role=&quot;treegrid&quot;</code> attribute.</p>
72
88
  <doc-demo>
73
- <table class="demo-tree" role="treegrid">
89
+ <table class="demo-tree">
74
90
  <tbody>
75
91
  <tr aria-level="1">
76
92
  <td>1: Lorem, ipsum</td>
77
93
  </tr>
78
- <tr aria-level="1" aria-expanded="false" aria-owns="row1 row2 row3">
94
+ <tr aria-level="1" aria-expanded="false" aria-controls="row1 row2 row3">
79
95
  <td>1: Cum, dolorum (open me)</td>
80
96
  </tr>
81
97
  <tr id="row1" aria-level="2" hidden>
82
98
  <td>2: Lorem</td>
83
99
  </tr>
84
- <tr id="row2" aria-level="2" aria-expanded="false" aria-owns="row2-1 row2-2" hidden>
100
+ <tr id="row2" aria-level="2" aria-expanded="false" aria-controls="row2-1 row2-2" hidden>
85
101
  <td>2: Quo (open me)</td>
86
102
  </tr>
87
103
  <tr id="row2-1" aria-level="3" hidden>
@@ -106,14 +122,14 @@
106
122
  <tr aria-level="1">
107
123
  <td>1: Lorem, ipsum</td>
108
124
  </tr>
109
- <tr aria-level="1" aria-expanded="false" aria-owns="row1 row2 row3">
110
- <td>1: Cum, dolorum</td>
125
+ <tr aria-level="1" aria-expanded="false" aria-controls="row1 row2 row3">
126
+ <td>1: Cum, dolorum (open me)</td>
111
127
  </tr>
112
128
  <tr id="row1" aria-level="2" hidden>
113
129
  <td>2: Lorem</td>
114
130
  </tr>
115
- <tr id="row2" aria-level="2" aria-expanded="false" aria-owns="row2-1 row2-2" hidden>
116
- <td>2: Quo</td>
131
+ <tr id="row2" aria-level="2" aria-expanded="false" aria-controls="row2-1 row2-2" hidden>
132
+ <td>2: Quo (open me)</td>
117
133
  </tr>
118
134
  <tr id="row2-1" aria-level="3" hidden>
119
135
  <td>2.1: Quo</td>
@@ -138,41 +154,45 @@
138
154
  <h2>Handle</h2>
139
155
  <p>You can decide which part of the item toggle the open/close method with the <code>data-handle="tree"</code> attribute</p>
140
156
  <doc-demo>
141
- <ul class="demo-tree" role="tree">
142
- <li role="treeitem">
143
- <span aria-expanded="false" aria-owns="sublist">
144
- <span data-handle="tree">
145
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
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
- </svg>
148
- </span>
149
- Inventore, perspiciatis
150
- </span>
151
- <ul id="sublist" hidden>
152
- <li>Some children</li>
153
- <li>Some children</li>
154
- <li>Some children</li>
155
- </ul>
156
- </li>
157
- </ul>
157
+ <table class="demo-tree">
158
+ <tbody>
159
+ <tr aria-level="1" aria-expanded="false" aria-controls="rowExpandable">
160
+ <td>
161
+ <span data-handle="tree">
162
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
163
+ <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>
164
+ </svg>
165
+ (open me)
166
+ </span>
167
+ </td>
168
+ <td>1: Cum, dolorum</td>
169
+ </tr>
170
+ <tr id="rowExpandable" aria-level="2" hidden>
171
+ <td></td>
172
+ <td>1.1: Lorem</td>
173
+ </tr>
174
+ </table>
158
175
  </doc-demo>
159
176
 
160
177
  <doc-code>
161
- <ul role="tree">
162
- ...
163
- <li role="treeitem">
164
- <span aria-expanded="false" aria-owns="treelist">
165
- <span data-handle="tree">
166
- HANDLE
167
- </span>
168
- Inventore, perspiciatis
169
- </span>
170
- <ul id="treelist" hidden>
171
- ...
172
- </ul>
173
- </li>
174
- ...
175
- </ul>
178
+ <table class="demo-tree">
179
+ <tbody>
180
+ <tr aria-level="1" aria-expanded="false" aria-controls="rowExpandable">
181
+ <td>
182
+ <span data-handle="tree">
183
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
184
+ <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>
185
+ </svg>
186
+ (open me)
187
+ </span>
188
+ </td>
189
+ <td>1: Cum, dolorum</td>
190
+ </tr>
191
+ <tr id="rowExpandable" aria-level="2" hidden>
192
+ <td></td>
193
+ <td>1.1: Lorem</td>
194
+ </tr>
195
+ </table>
176
196
  </doc-code>
177
197
 
178
198
  <blockquote class="tip">
@@ -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.3
21
+ 0.1.5
22
22
  </span>
23
23
  </li>
24
24
  <li>
@@ -88,9 +88,9 @@ class DocLayout extends HTMLElement {
88
88
  <li><a href="/pages/javascript/comfort.html">Comfort</a></li>
89
89
  <li><a href="/pages/javascript/consent.html">Consent</a></li>
90
90
  <li><a href="/pages/javascript/cookie.html">Cookie</a></li>
91
+ <li><a href="/pages/javascript/drawer.html">Drawer</a></li>
91
92
  <li><a href="/pages/javascript/form.html">Form helper</a></li>
92
93
  <li><a href="/pages/javascript/scroll.html">Scroll</a></li>
93
- <li><a href="/pages/javascript/sidebar.html">Sidebar</a></li>
94
94
  <li><a href="/pages/javascript/sortable.html">Sortable</a></li>
95
95
  <li><a href="/pages/javascript/tabpanel.html">Tabpanel</a></li>
96
96
  <li><a href="/pages/javascript/toggle.html">Toggle</a></li>
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * ------------------------------------------------------------------
3
- * Sidebar
3
+ * Drawer
4
4
  * ------------------------------------------------------------------
5
- * This class enable the functionality to toggles multiple tabpanel
5
+ * This class enable the functionality to toggles a drawer to show/hide some content
6
+ * Most used case is a sidebar or a main menu to hide on mobile
6
7
  *
7
8
  * @author Natacha Herth
8
9
  * @copyright Natacha Herth, design & web development
@@ -12,7 +13,7 @@
12
13
  import BaseComponent from './utilities/_base-component'
13
14
  import ErrorMessage from "./utilities/_error"
14
15
 
15
- export default class Sidebar extends BaseComponent {
16
+ export default class Drawer extends BaseComponent {
16
17
 
17
18
  static OPTIONS = {
18
19
  breakpoint: 960,
@@ -30,12 +31,12 @@ export default class Sidebar extends BaseComponent {
30
31
  if (options.breakpoint && typeof options.breakpoint !== 'number') throw new Error(ErrorMessage.typeOf('options.breakpoint', 'number'))
31
32
 
32
33
  // Run the SUPER constructor from BaseComponent
33
- super(el, options, 'sidebar')
34
+ super(el, options, 'drawer')
34
35
 
35
36
  // Define the properties
36
37
  this._buttons = document.querySelectorAll(`[aria-controls=${this._element.id}]`) ?? []
37
38
 
38
- this._backdrop = document.getElementById('backdrop')
39
+ this._backdrop = document.getElementById('backdrop') ?? null
39
40
 
40
41
  this._timeout = false
41
42
 
@@ -55,10 +56,10 @@ export default class Sidebar extends BaseComponent {
55
56
  */
56
57
  #init() {
57
58
 
58
- // On load check if need to open/close the sidebar
59
+ // On load check if need to open/close the drawer
59
60
  if (window.innerWidth > this._options.breakpoint && !this._isOpen) this.toggle()
60
61
 
61
- // On resize check if need to open/close the sidebar
62
+ // On resize check if need to open/close the drawer
62
63
  window.onresize = () => {
63
64
  clearTimeout(this._timeout)
64
65
  this._timeout = setTimeout(() => {
@@ -66,19 +67,19 @@ export default class Sidebar extends BaseComponent {
66
67
  }, 250)
67
68
  }
68
69
 
69
- // On click on the button toggle the sidebar
70
- this._buttons.forEach((button) => button.addEventListener('click', () => this.toggle()))
70
+ // On click on the button toggle the drawer
71
+ this._buttons.forEach((button) => button.addEventListener('click', () => this.toggle(true)))
71
72
 
72
- // On click on the backdrop, close the sidebar
73
- this._backdrop.addEventListener('click', () => this.toggle())
73
+ // On click on the backdrop, close the drawer
74
+ if (this._backdrop) this._backdrop.addEventListener('click', () => this.toggle())
74
75
 
75
76
  }
76
77
 
77
78
  /**
78
- * Toggle the sidebar
79
+ * Toggle the drawer
79
80
  *
80
81
  */
81
- toggle() {
82
+ toggle(enableFocus = false) {
82
83
 
83
84
  // Change the state
84
85
  this._isOpen = !this._isOpen
@@ -89,11 +90,11 @@ export default class Sidebar extends BaseComponent {
89
90
  button.setAttribute('aria-expanded', this._isOpen)
90
91
  })
91
92
 
92
- // Change the [hidden] attribute on the sidebar
93
+ // Change the [hidden] attribute on the drawer
93
94
  this._element.hidden = !this._isOpen
94
95
 
95
96
  // Toggle the focus
96
- if (this._focus && this._isOpen) this._focus.focus()
97
+ if (enableFocus && this._focus && this._isOpen) this._focus.focus()
97
98
 
98
99
  }
99
100
 
package/js/_tree.js CHANGED
@@ -25,9 +25,9 @@ export default class Tree extends BaseComponent {
25
25
  super(el, options, 'tree')
26
26
 
27
27
  // Define the properties
28
- this._type = this._element.role == 'tree' ? 'list' : 'grid'
28
+ this._type = this._element.tagName == 'TABLE' ? 'grid' : 'list'
29
29
 
30
- this._withHandle = this._element.querySelector('[data-handle=tree]') ? true : false
30
+ this._withHandle = this._type == 'grid' && this._element.querySelector('[data-handle=tree]') ? true : false
31
31
 
32
32
  this._items = this._element.querySelectorAll('[aria-expanded]')
33
33
 
@@ -67,7 +67,7 @@ export default class Tree extends BaseComponent {
67
67
  item.setAttribute('aria-expanded', !isExpanded)
68
68
 
69
69
  // Get children to toggle
70
- const children = item.hasAttribute('aria-owns') ? item.getAttribute('aria-owns').split(' ').filter(id => document.getElementById(id)).map(id => document.getElementById(id)) : []
70
+ const children = item.hasAttribute('aria-controls') ? item.getAttribute('aria-controls').split(' ').filter(id => document.getElementById(id)).map(id => document.getElementById(id)) : []
71
71
 
72
72
  // Toggle the [hidden] attribute on the children
73
73
  children.forEach(child => child.hidden = isExpanded)
@@ -1,20 +1,20 @@
1
1
  /**
2
2
  * ------------------------------------------------------------------
3
- * TEST for the _sidebar.js
3
+ * TEST for the _drawer.js
4
4
  * ------------------------------------------------------------------
5
5
  * The test will take care of:
6
6
  * - Constructor: Passing the correct parameters
7
7
  * - Constructor: Return the correct properties
8
- * - #Init: On click on the button toggle the sidebar
9
- * - #Init: On click on the backdrop, close the sidebar
8
+ * - #Init: On click on the button toggle the drawer
9
+ * - #Init: On click on the backdrop, close the drawer
10
10
  */
11
11
 
12
12
  import { describe, test, expect, beforeAll } from "vitest"
13
13
  import { fireEvent } from "@testing-library/dom"
14
- import Sidebar from "../_sidebar"
14
+ import Drawer from "../_drawer"
15
15
  import ErrorMessage from "../utilities/_error"
16
16
 
17
- let fakeSidebar
17
+ let fakeDrawer
18
18
 
19
19
  /**
20
20
  * Before all tests
@@ -25,72 +25,72 @@ beforeAll(() => {
25
25
 
26
26
  document.body.innerHTML =
27
27
  '<div id="backdrop"></div>' +
28
- '<button aria-expanded="false" aria-pressed="false" aria-controls="sidebar"></button>' +
29
- '<aside id="sidebar" tabindex="0" hidden><button id="focus"></button></aside>'
28
+ '<button aria-expanded="false" aria-pressed="false" aria-controls="drawer"></button>' +
29
+ '<aside id="drawer" tabindex="0" hidden><button id="focus"></button></aside>'
30
30
 
31
31
  Object.defineProperty(window, 'innerWidth', { configurable: true, value: 1200 })
32
32
 
33
- fakeSidebar = new Sidebar(document.getElementById('sidebar'))
33
+ fakeDrawer = new Drawer(document.getElementById('drawer'))
34
34
 
35
35
  })
36
36
 
37
37
  describe('Structure of the class', () => {
38
38
 
39
39
  test('Constructor: Passing the correct parameters', () => {
40
- expect(() => new Sidebar(document.getElementById('sidebar'), { breakpoint: 'make-error' })).toThrowError(ErrorMessage.typeOf('options.breakpoint', 'number'))
40
+ expect(() => new Drawer(document.getElementById('drawer'), { breakpoint: 'make-error' })).toThrowError(ErrorMessage.typeOf('options.breakpoint', 'number'))
41
41
  })
42
42
 
43
43
  test('Constructor: Return the correct properties', () => {
44
- expect(fakeSidebar._buttons).toStrictEqual(document.querySelectorAll('button[aria-controls="sidebar"]'))
45
- expect(fakeSidebar._backdrop).toStrictEqual(document.getElementById('backdrop'))
46
- expect(fakeSidebar._isOpen).toBeTruthy()
47
- expect(fakeSidebar._focus).toStrictEqual(document.getElementById('focus'))
44
+ expect(fakeDrawer._buttons).toStrictEqual(document.querySelectorAll('button[aria-controls="drawer"]'))
45
+ expect(fakeDrawer._backdrop).toStrictEqual(document.getElementById('backdrop'))
46
+ expect(fakeDrawer._isOpen).toBeTruthy()
47
+ expect(fakeDrawer._focus).toStrictEqual(document.getElementById('focus'))
48
48
  })
49
49
 
50
50
  })
51
51
 
52
52
  describe('#Init(', () => {
53
53
 
54
- test('On click on the button toggle the sidebar', () => {
54
+ test('On click on the button toggle the drawer', () => {
55
55
 
56
- const button = fakeSidebar._buttons[0]
56
+ const button = fakeDrawer._buttons[0]
57
57
 
58
- expect(fakeSidebar._isOpen).toBeTruthy()
59
- expect(fakeSidebar._element.hasAttribute('hidden')).toBeFalsy()
58
+ expect(fakeDrawer._isOpen).toBeTruthy()
59
+ expect(fakeDrawer._element.hasAttribute('hidden')).toBeFalsy()
60
60
  expect(button.getAttribute('aria-pressed')).toBe('true')
61
61
  expect(button.getAttribute('aria-expanded')).toBe('true')
62
62
 
63
63
  fireEvent(button, new MouseEvent('click'))
64
64
 
65
- expect(fakeSidebar._isOpen).toBeFalsy()
66
- expect(fakeSidebar._element.hasAttribute('hidden')).toBeTruthy()
65
+ expect(fakeDrawer._isOpen).toBeFalsy()
66
+ expect(fakeDrawer._element.hasAttribute('hidden')).toBeTruthy()
67
67
  expect(button.getAttribute('aria-pressed')).toBe('false')
68
68
  expect(button.getAttribute('aria-expanded')).toBe('false')
69
69
 
70
70
  fireEvent(button, new MouseEvent('click'))
71
71
 
72
- expect(fakeSidebar._isOpen).toBeTruthy()
73
- expect(fakeSidebar._element.hasAttribute('hidden')).toBeFalsy()
72
+ expect(fakeDrawer._isOpen).toBeTruthy()
73
+ expect(fakeDrawer._element.hasAttribute('hidden')).toBeFalsy()
74
74
  expect(button.getAttribute('aria-pressed')).toBe('true')
75
75
  expect(button.getAttribute('aria-expanded')).toBe('true')
76
76
 
77
77
  })
78
78
 
79
- test('On click on the backdrop, close the sidebar', () => {
79
+ test('On click on the backdrop, close the drawer', () => {
80
80
 
81
81
  Object.defineProperty(window, 'innerWidth', { configurable: true, value: 800 })
82
82
 
83
- const button = fakeSidebar._buttons[0]
83
+ const button = fakeDrawer._buttons[0]
84
84
 
85
- expect(fakeSidebar._isOpen).toBeTruthy()
86
- expect(fakeSidebar._element.hasAttribute('hidden')).toBeFalsy()
85
+ expect(fakeDrawer._isOpen).toBeTruthy()
86
+ expect(fakeDrawer._element.hasAttribute('hidden')).toBeFalsy()
87
87
  expect(button.getAttribute('aria-pressed')).toBe('true')
88
88
  expect(button.getAttribute('aria-expanded')).toBe('true')
89
89
 
90
90
  fireEvent(document.getElementById('backdrop'), new MouseEvent('click'))
91
91
 
92
- expect(fakeSidebar._isOpen).toBeFalsy()
93
- expect(fakeSidebar._element.hasAttribute('hidden')).toBeTruthy()
92
+ expect(fakeDrawer._isOpen).toBeFalsy()
93
+ expect(fakeDrawer._element.hasAttribute('hidden')).toBeTruthy()
94
94
  expect(button.getAttribute('aria-pressed')).toBe('false')
95
95
  expect(button.getAttribute('aria-expanded')).toBe('false')
96
96
 
@@ -30,26 +30,27 @@ let fakeListTree, fakeGridTree, fakeLi, fakeRow, customClick
30
30
  beforeAll(() => {
31
31
 
32
32
  document.body.innerHTML =
33
- '<ul id="fakeListTree" role="tree">' +
34
- '<li role="treeitem"></li>' +
35
- '<li role="treeitem" aria-expanded="false" aria-owns="child">' +
36
- '<ul id="child" role="group" hidden>' +
37
- '<li role="treeitem"></li>' +
33
+ '<ul id="fakeListTree">' +
34
+ '<li></li>' +
35
+ '<li>' +
36
+ '<button role="link" aria-controls="child" aria-expanded="false">Toggle</button>' +
37
+ '<ul id="child" hidden>' +
38
+ '<li></li>' +
38
39
  '</ul>' +
39
40
  '</li>' +
40
- '<li role="treeitem"></li>' +
41
+ '<li></li>' +
41
42
  '</ul>' +
42
- '<table id="fakeGridTree" role="treegrid">' +
43
+ '<table id="fakeGridTree">' +
43
44
  '<tr aria-level="1"><td></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>' +
45
+ '<tr aria-level="1" aria-expanded="false" aria-controls="lvl2"><td data-handle="tree"></td></tr>' +
46
+ '<tr id="lvl2" aria-level="2" aria-expanded="false" aria-controls="lvl3" hidden><td data-handle="tree"></td></tr>' +
46
47
  '<tr id="lvl3" aria-level="3" hidden><td></td></tr>' +
47
48
  '<tr aria-level="1"><td></td></tr>' +
48
49
  '</table>'
49
50
 
50
51
  fakeListTree = new Tree(document.getElementById('fakeListTree'))
51
52
  fakeGridTree = new Tree(document.getElementById('fakeGridTree'))
52
- fakeLi = fakeListTree._element.querySelector('li[aria-expanded]')
53
+ fakeLi = fakeListTree._element.querySelector('li [aria-expanded]')
53
54
  fakeRow = fakeGridTree._element.querySelector('tr[aria-level="1"][aria-expanded]')
54
55
 
55
56
  customClick = new MouseEvent('click')
@@ -61,7 +61,7 @@ export default class Cookie {
61
61
  */
62
62
  set(value) {
63
63
  if (!(value instanceof Object)) throw new Error(ErrorMessage.instanceOf('value', 'Object'))
64
- document.cookie = `${this.#NAME}=${JSON.stringify(value)};SameSite=Lax`
64
+ document.cookie = `${this.#NAME}=${JSON.stringify(value)};SameSite=Lax;Path=/;`
65
65
  }
66
66
 
67
67
  /**
@@ -91,7 +91,7 @@ export default class Cookie {
91
91
  *
92
92
  */
93
93
  delete() {
94
- document.cookie = this.#NAME + "=;SameSite=Lax; expires = Thu, 01 Jan 1970 00:00:00 GMT"
94
+ document.cookie = this.#NAME + "=;SameSite=Lax;Path=/; expires = Thu, 01 Jan 1970 00:00:00 GMT"
95
95
  }
96
96
 
97
97
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@natachah/vanilla-frontend",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "A vanilla frontend framework",
5
5
  "keywords": [
6
6
  "html5",
@@ -117,6 +117,8 @@
117
117
  // Reset
118
118
  margin: 0;
119
119
  padding: 0;
120
+ border-radius: var(--#{$name}-border-radius, map.get($properties, border-radius));
121
+ background-color: var(--#{$name}-background, map.get($properties, background));
120
122
 
121
123
  &:is(ul, ol) {
122
124
  list-style: none;
@@ -85,24 +85,13 @@ summary {
85
85
  }
86
86
 
87
87
  // Change cursor for tree + basic animation on svg
88
- [role=tree],
89
- [role=treegrid] {
90
-
91
- [aria-expanded]:not(:has([data-handle])),
92
- [data-handle] {
93
- cursor: pointer;
94
- }
95
-
96
- @media screen and (prefers-reduced-motion: no-preference) {
97
- [data-handle] > svg {
98
- transition: all .25s ease-in-out;
99
- }
100
- }
101
-
102
- [aria-expanded=true] > [data-handle] > svg {
103
- transform: rotate(90deg);
104
- }
88
+ [aria-controls],
89
+ [data-handle] {
90
+ cursor: pointer;
91
+ }
105
92
 
93
+ [aria-controls][aria-expanded=true] [data-handle] > svg {
94
+ transform: rotate(90deg);
106
95
  }
107
96
 
108
97
  // Reduce animation on scroll for #target
@@ -110,6 +99,11 @@ summary {
110
99
  :has(:target) {
111
100
  scroll-behavior: smooth;
112
101
  }
102
+
103
+ [data-handle] > svg {
104
+ transition: all .25s ease-in-out;
105
+ }
106
+
113
107
  }
114
108
 
115
109
  // Define the bases for the body
@@ -19,7 +19,8 @@
19
19
  }
20
20
  }
21
21
 
22
- a {
22
+ a,
23
+ button[role=link] {
23
24
 
24
25
  cursor: pointer;
25
26
  text-decoration: var(--anchor-decoration, var(--decoration));
@@ -41,7 +42,7 @@ a {
41
42
  }
42
43
 
43
44
  &:disabled,
44
- &:not([href]) {
45
+ &:is(a):not([href]) {
45
46
  pointer-events: none;
46
47
  opacity: var(--anchor-disabled-opacity, var(--disabled-opacity));
47
48
  }
@@ -14,7 +14,7 @@
14
14
 
15
15
  @use "../abstracts/mixins" as *;
16
16
 
17
- button,
17
+ button:not([role=link]),
18
18
  [type=button],
19
19
  [type=reset],
20
20
  [type=submit],
@@ -26,8 +26,6 @@ $customCardProperties: map.merge(default.$item-properties, $customCard);
26
26
 
27
27
  .card {
28
28
 
29
- --card-border-color: red;
30
-
31
29
  // Design as item
32
30
  @include as-item('card', (), $customCardProperties);
33
31
 
@@ -55,7 +55,7 @@ $customDropdownProperties: map.merge(default.$item-properties, $customDropdown);
55
55
  top: calc(100% + var(--dropdown-offset, .5rem));
56
56
 
57
57
  // Simple bloc
58
- &:not(ul, li) {
58
+ &:not(ul, ol) {
59
59
  @include as-item('dropdown', (), $customDropdownProperties);
60
60
  }
61
61
 
@@ -60,11 +60,11 @@ select {
60
60
 
61
61
  [type=date],
62
62
  [type=datetime-local] {
63
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="black" viewBox="0 0 16 16"><path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/></svg>');
63
+ background-image: var(--icon-date);
64
64
  }
65
65
 
66
66
  [type=time] {
67
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/><path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/></svg>');
67
+ background-image: var(--icon-time);
68
68
  }
69
69
 
70
70
  @-moz-document url-prefix() {
@@ -86,7 +86,7 @@ select {
86
86
 
87
87
  [type=file] {
88
88
 
89
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/><path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z"/></svg>');
89
+ background-image: var(--icon-file);
90
90
 
91
91
  // Hide the default button, and make it look like a default input
92
92
  &::file-selector-button {
@@ -99,7 +99,7 @@ select {
99
99
  }
100
100
 
101
101
  select {
102
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><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"/></svg>');
102
+ background-image: var(--icon-select);
103
103
  }
104
104
 
105
105
  [type=color] {
@@ -171,14 +171,14 @@ select {
171
171
 
172
172
  &:checked {
173
173
  background-size: 50%;
174
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" viewBox="0 0 16 16"><circle cx="8" cy="8" r="8"/></svg>');
174
+ background-image: var(--icon-radio);
175
175
  }
176
176
 
177
177
  }
178
178
 
179
179
  [type=checkbox]:not([role=switch]):checked {
180
180
  background-size: 100%;
181
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" viewBox="0 0 16 16"><path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/></svg>');
181
+ background-image: var(--icon-check);
182
182
  }
183
183
 
184
184
 
@@ -189,7 +189,7 @@ select {
189
189
  background-position: .125em center;
190
190
  background-size: auto calc(100% - .25em);
191
191
  background-color: var(--form-background, rgba(black, 25%));
192
- background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" viewBox="0 0 16 16"><circle cx="8" cy="8" r="8"/></svg>');
192
+ background-image: var(--icon-switch);
193
193
 
194
194
  &:checked {
195
195
  background-position: calc(100% - .125em) center;
@@ -66,4 +66,12 @@
66
66
  // Contrasts
67
67
  --color-warning-contrast: black;
68
68
 
69
+ // Icons
70
+ --icon-date: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="black" viewBox="0 0 16 16"><path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/></svg>');
71
+ --icon-time: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/><path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/></svg>');
72
+ --icon-file: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/><path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z"/></svg>');
73
+ --icon-select: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><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"/></svg>');
74
+ --icon-radio: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" viewBox="0 0 16 16"><circle cx="8" cy="8" r="8"/></svg>');
75
+ --icon-check: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" viewBox="0 0 16 16"><path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/></svg>');
76
+ --icon-switch: var(--icon-radio);
69
77
  }
Binary file