@onetype/framework 2.0.25 → 2.0.27

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.
Files changed (65) hide show
  1. package/addons/core/assets/back/functions/utils/transform.js +1 -1
  2. package/addons/render/directives/front/js/functions/process/data.js +0 -1
  3. package/addons/render/transforms/addon.js +2 -0
  4. package/addons/render/transforms/functions/data.js +21 -0
  5. package/addons/render/transforms/functions/run.js +11 -0
  6. package/addons/render/transforms/item/functions/load.js +55 -0
  7. package/addons/render/transforms/item/functions/run.js +12 -0
  8. package/addons/render/transforms/items/directives/transform.js +15 -18
  9. package/lib/items/elements/global/heading/heading.css +1 -1
  10. package/lib/items/elements/global/markdown/markdown.js +207 -3
  11. package/lib/items/elements/{sections → navigation}/navbar/navbar.css +9 -9
  12. package/lib/items/elements/{sections → navigation}/navbar/navbar.js +2 -2
  13. package/lib/items/elements/navigation/sidebar/sidebar.css +101 -0
  14. package/lib/items/elements/navigation/sidebar/sidebar.js +56 -0
  15. package/lib/items/elements/{global → navigation}/tabs/tabs.css +6 -6
  16. package/lib/items/elements/{global → navigation}/tabs/tabs.js +2 -2
  17. package/lib/items/elements/sections/pricing/pricing.css +148 -0
  18. package/lib/items/elements/sections/pricing/pricing.js +76 -0
  19. package/lib/items/transforms/accordion/accordion.js +139 -141
  20. package/lib/items/transforms/chart/area.js +130 -133
  21. package/lib/items/transforms/chart/bar.js +116 -119
  22. package/lib/items/transforms/chart/bubble.js +142 -145
  23. package/lib/items/transforms/chart/doughnut.js +104 -107
  24. package/lib/items/transforms/chart/line.js +127 -130
  25. package/lib/items/transforms/chart/pie.js +102 -105
  26. package/lib/items/transforms/chart/radar.js +134 -137
  27. package/lib/items/transforms/chart/scatter.js +127 -130
  28. package/lib/items/transforms/codeflask/codeflask.js +10 -12
  29. package/lib/items/transforms/codemirror/codemirror.js +186 -189
  30. package/lib/items/transforms/comparison/comparison.js +130 -133
  31. package/lib/items/transforms/heatmap/heatmap.js +406 -407
  32. package/lib/items/transforms/interact/interact.js +240 -241
  33. package/lib/items/transforms/particles/particles.js +282 -283
  34. package/lib/items/transforms/sparkline/sparkline.js +207 -208
  35. package/lib/items/transforms/swiper/swiper.js +115 -118
  36. package/lib/items/transforms/tabs/tabs.js +383 -384
  37. package/lib/items/transforms/typed/typed.js +146 -147
  38. package/lib/load.js +8 -16
  39. package/lib/src/mixins/addons.js +10 -10
  40. package/lib/styles/variables.css +1 -1
  41. package/package.json +1 -1
  42. package/addons/render/transforms/functions/load/assets.js +0 -49
  43. /package/{addons/render/directives/front/js/items → lib/items/directives}/100-if.js +0 -0
  44. /package/{addons/render/directives/front/js/items → lib/items/directives}/1000-render.js +0 -0
  45. /package/{addons/render/directives/front/js/items → lib/items/directives}/110-show.js +0 -0
  46. /package/{addons/render/directives/front/js/items → lib/items/directives}/160-slot.js +0 -0
  47. /package/{addons/render/directives/front/js/items → lib/items/directives}/200-for.js +0 -0
  48. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-blur.js +0 -0
  49. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-change.js +0 -0
  50. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-click-outside.js +0 -0
  51. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-click.js +0 -0
  52. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-double-click.js +0 -0
  53. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-focus.js +0 -0
  54. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-input.js +0 -0
  55. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-keydown.js +0 -0
  56. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-keyup.js +0 -0
  57. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-mouse-enter.js +0 -0
  58. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-mouse-leave.js +0 -0
  59. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-mouse-move.js +0 -0
  60. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-scroll.js +0 -0
  61. /package/{addons/render/directives/front/js/items → lib/items/directives}/500-submit.js +0 -0
  62. /package/{addons/render/directives/front/js/items → lib/items/directives}/650-fetch.js +0 -0
  63. /package/{addons/render/directives/front/js/items → lib/items/directives}/660-form.js +0 -0
  64. /package/{addons/render/directives/front/js/items → lib/items/directives}/700-text.js +0 -0
  65. /package/{addons/render/directives/front/js/items → lib/items/directives}/750-html.js +0 -0
@@ -18,7 +18,7 @@ assets.Fn('utils.transform', function(contents, type = 'js')
18
18
  return code;
19
19
  });
20
20
 
21
- return code.filter(content => content && content.trim()).join('\n\n');
21
+ return '(function(){\n' + code.filter(content => content && content.trim()).join('\n\n') + '\n})();';
22
22
  }
23
23
 
24
24
  if (type === 'css')
@@ -60,7 +60,6 @@ directives.Fn('process.data', function(attributes, node, compile)
60
60
  }
61
61
  }
62
62
 
63
-
64
63
  attribute.value = onetype.DataDefineOne(attribute.value, definition);
65
64
  data[attribute.name] = attribute;
66
65
 
@@ -8,4 +8,6 @@ const transforms = onetype.Addon('transforms', (addon) =>
8
8
  addon.Field('css', ['array', []]);
9
9
  addon.Field('config', ['object', {}]);
10
10
  addon.Field('code', ['function']);
11
+ addon.Field('destroy', ['function', null]);
12
+ addon.Field('structure', ['function', null]);
11
13
  });
@@ -0,0 +1,21 @@
1
+ transforms.Fn('data', function(config, node)
2
+ {
3
+ const data = {};
4
+
5
+ Object.entries(config).forEach(([name, definition]) =>
6
+ {
7
+ name = name.toLowerCase();
8
+
9
+ const raw = node.getAttribute(name);
10
+ const value = raw !== null ? onetype.Function(raw, {}, false) : undefined;
11
+
12
+ data[name] = onetype.DataDefineOne(typeof value === 'undefined' ? raw : value, definition);
13
+
14
+ if(raw !== null)
15
+ {
16
+ node.removeAttribute(name);
17
+ }
18
+ });
19
+
20
+ return data;
21
+ });
@@ -0,0 +1,11 @@
1
+ transforms.Fn('run', function(id, node, data = null)
2
+ {
3
+ const item = transforms.ItemGet(id);
4
+
5
+ if(!item)
6
+ {
7
+ return;
8
+ }
9
+
10
+ item.Fn('run', node, data);
11
+ });
@@ -0,0 +1,55 @@
1
+ transforms.Fn('item.load', function(item)
2
+ {
3
+ const loaded = transforms.StoreGet('loaded') || {};
4
+
5
+ transforms.StoreSet('loaded', loaded);
6
+
7
+ this.methods.script = (url) =>
8
+ {
9
+ if(loaded[url])
10
+ {
11
+ return loaded[url];
12
+ }
13
+
14
+ loaded[url] = new Promise((resolve, reject) =>
15
+ {
16
+ const element = document.createElement('script');
17
+
18
+ element.src = url;
19
+ element.async = true;
20
+ element.onload = resolve;
21
+ element.onerror = () => reject(new Error(`Failed to load: ${url}`));
22
+
23
+ document.head.appendChild(element);
24
+ });
25
+
26
+ return loaded[url];
27
+ };
28
+
29
+ this.methods.style = (url) =>
30
+ {
31
+ if(loaded[url])
32
+ {
33
+ return loaded[url];
34
+ }
35
+
36
+ loaded[url] = new Promise((resolve, reject) =>
37
+ {
38
+ const element = document.createElement('link');
39
+
40
+ element.rel = 'stylesheet';
41
+ element.href = url;
42
+ element.onload = resolve;
43
+ element.onerror = () => reject(new Error(`Failed to load: ${url}`));
44
+
45
+ document.head.appendChild(element);
46
+ });
47
+
48
+ return loaded[url];
49
+ };
50
+
51
+ const js = (item.Get('js') || []).map(url => this.methods.script(url));
52
+ const css = (item.Get('css') || []).map(url => this.methods.style(url));
53
+
54
+ return Promise.all([...js, ...css]);
55
+ });
@@ -0,0 +1,12 @@
1
+ transforms.Fn('item.run', function(item, node, data = null)
2
+ {
3
+ if(data === null)
4
+ {
5
+ data = transforms.Fn('data', item.Get('config'), node);
6
+ }
7
+
8
+ item.Fn('load').then(() =>
9
+ {
10
+ item.Get('code').call({}, data, node, item);
11
+ });
12
+ });
@@ -4,11 +4,11 @@ onetype.AddonReady('directives', function()
4
4
  id: 'ot-transform',
5
5
  icon: 'auto_fix_high',
6
6
  name: 'Transform',
7
- description: 'Apply transform functions to elements for advanced functionality. Enables custom element behaviors and third-party integrations.',
7
+ description: 'Apply transform functions to elements for advanced functionality.',
8
8
  trigger: 'node',
9
9
  order: 1100,
10
10
  type: '1',
11
- code: async function(data, item, compile, node, identifier)
11
+ code: function(data, item, compile, node, identifier)
12
12
  {
13
13
  const transformer = transforms.ItemGet(node.tagName.toLowerCase());
14
14
 
@@ -17,27 +17,24 @@ onetype.AddonReady('directives', function()
17
17
  return;
18
18
  }
19
19
 
20
- // Don't stop children processing - let each transform handle itself
21
- // compile.children = false;
20
+ const target = document.createElement('div');
22
21
 
23
- const html = node.outerHTML.replace(new RegExp(`^<${node.tagName.toLowerCase()}\\b`), `<div`) .replace(new RegExp(`</${node.tagName.toLowerCase()}>$`), `</div>`);
24
- const compiled = item.Compile(html, compile.data);
22
+ Array.from(node.attributes).forEach(attr =>
23
+ {
24
+ target.setAttribute(attr.name, attr.value);
25
+ });
25
26
 
26
- data = directives.Fn('process.data', transformer.Get('config'), compiled.element.firstElementChild, compiled);
27
+ while(node.firstChild)
28
+ {
29
+ target.appendChild(node.firstChild);
30
+ }
27
31
 
28
- node.style.display = 'none';
32
+ let raw = Object.entries(directives.Fn('process.data', transformer.Get('config'), target, compile));
33
+ raw = Object.fromEntries(raw.map(([key, attr]) => [key, attr.value]));
29
34
 
30
- await transforms.Fn('load.assets', transformer);
35
+ transforms.Fn('run', node.tagName.toLowerCase(), target, raw);
31
36
 
32
- // Use Promise to handle async properly
33
- return new Promise((resolve) => {
34
- setTimeout(() => {
35
- const targetNode = compiled.element.firstElementChild;
36
- transformer.Get('code').call({}, data, transformer, compile, targetNode, identifier);
37
- node.replaceWith(targetNode);
38
- resolve();
39
- }, 0);
40
- });
37
+ node.replaceWith(target);
41
38
  }
42
39
  });
43
40
  });
@@ -81,7 +81,7 @@
81
81
 
82
82
  .e-49fb116e > .holder.size-m > .title
83
83
  {
84
- font-size: 28px;
84
+ font-size: 25px;
85
85
  font-weight: 700;
86
86
  }
87
87
 
@@ -1,5 +1,211 @@
1
1
  onetype.AddonReady('elements', (elements) =>
2
2
  {
3
+ const parse = function(content)
4
+ {
5
+ if(!content)
6
+ {
7
+ return '';
8
+ }
9
+
10
+ let html = '';
11
+ let buffer = [];
12
+ let block = false;
13
+
14
+ const line = (h) =>
15
+ {
16
+ html += `<div class="line">${h}</div>`;
17
+ };
18
+
19
+ const spacer = () =>
20
+ {
21
+ };
22
+
23
+ const transform = (text) =>
24
+ {
25
+ text = code(text);
26
+ text = inline(text);
27
+ text = media(text);
28
+ text = heading(text);
29
+ text = rule(text);
30
+ text = quote(text);
31
+ text = format(text);
32
+ text = list(text);
33
+ text = table(text);
34
+ text = paragraph(text);
35
+
36
+ return text;
37
+ };
38
+
39
+ const code = (text) =>
40
+ {
41
+ text = text.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, c) =>
42
+ {
43
+ c = c.replace(/</g, '&lt;').replace(/>/g, '&gt;').trim();
44
+
45
+ return `<pre class="codeblock"><code${lang ? ` data-lang="${lang}"` : ''}>${c}</code></pre>`;
46
+ });
47
+
48
+ text = text.replace(/`([^`]+)`/g, '<code class="inline">$1</code>');
49
+
50
+ return text;
51
+ };
52
+
53
+ const inline = (text) =>
54
+ {
55
+ return text;
56
+ };
57
+
58
+ const media = (text) =>
59
+ {
60
+ text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" />');
61
+ text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
62
+
63
+ return text;
64
+ };
65
+
66
+ const heading = (text) =>
67
+ {
68
+ text = text.replace(/^#### (.+)$/gm, '<h4>$1</h4>');
69
+ text = text.replace(/^### (.+)$/gm, '<h3>$1</h3>');
70
+ text = text.replace(/^## (.+)$/gm, '<h2>$1</h2>');
71
+ text = text.replace(/^# (.+)$/gm, '<h1>$1</h1>');
72
+
73
+ return text;
74
+ };
75
+
76
+ const rule = (text) =>
77
+ {
78
+ return text.replace(/^---$/gm, '<hr />');
79
+ };
80
+
81
+ const quote = (text) =>
82
+ {
83
+ text = text.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>');
84
+ text = text.replace(/<\/blockquote>\n<blockquote>/g, '\n');
85
+
86
+ return text;
87
+ };
88
+
89
+ const format = (text) =>
90
+ {
91
+ text = text.replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>');
92
+ text = text.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
93
+ text = text.replace(/\*(.+?)\*/g, '<em>$1</em>');
94
+ text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');
95
+
96
+ return text;
97
+ };
98
+
99
+ const list = (text) =>
100
+ {
101
+ text = text.replace(/^[\t ]*[-*] (.+)$/gm, '<uli>$1</uli>');
102
+ text = text.replace(/((?:<uli>.*<\/uli>\n?)+)/g, (match) =>
103
+ {
104
+ return `<ul>${match.replace(/<\/?uli>/g, (t) => t.replace('uli', 'li'))}</ul>`;
105
+ });
106
+
107
+ text = text.replace(/^[\t ]*\d+\. (.+)$/gm, '<oli>$1</oli>');
108
+ text = text.replace(/((?:<oli>.*<\/oli>\n?)+)/g, (match) =>
109
+ {
110
+ return `<ol>${match.replace(/<\/?oli>/g, (t) => t.replace('oli', 'li'))}</ol>`;
111
+ });
112
+
113
+ return text;
114
+ };
115
+
116
+ const table = (text) =>
117
+ {
118
+ return text.replace(/^(\|.+\|)\n(\|[-| :]+\|)\n((?:\|.+\|\n?)+)/gm, (_, header, _align, body) =>
119
+ {
120
+ const heads = header.split('|').filter(c => c.trim()).map(c => `<th>${c.trim()}</th>`).join('');
121
+ const rows = body.trim().split('\n').map(row =>
122
+ {
123
+ const cells = row.split('|').filter(c => c.trim()).map(c => `<td>${c.trim()}</td>`).join('');
124
+ return `<tr>${cells}</tr>`;
125
+ }).join('');
126
+
127
+ return `<table><thead><tr>${heads}</tr></thead><tbody>${rows}</tbody></table>`;
128
+ });
129
+ };
130
+
131
+ const paragraph = (text) =>
132
+ {
133
+ text = text.replace(/(<\/(table|ul|ol|blockquote|pre|h[1-4])>)(.)/g, '$1\n$3');
134
+ text = text.replace(/(.)(<(table|ul|ol|blockquote|pre|h[1-4]|hr|img)[\s>])/g, '$1\n$2');
135
+
136
+ const blk = /^<(h[1-4]|ul|ol|pre|blockquote|hr|table|img|li|\/)/;
137
+
138
+ return text.split('\n').map(l =>
139
+ {
140
+ const trimmed = l.trim();
141
+
142
+ if(!trimmed || blk.test(trimmed))
143
+ {
144
+ return trimmed;
145
+ }
146
+
147
+ return `<p>${trimmed}</p>`;
148
+ }).filter(l => l).join('\n');
149
+ };
150
+
151
+ const flush = () =>
152
+ {
153
+ if(!buffer.length)
154
+ {
155
+ return;
156
+ }
157
+
158
+ line(transform(buffer.join('\n')));
159
+ buffer = [];
160
+ };
161
+
162
+ const lines = content.split('\n');
163
+
164
+ for(let i = 0; i < lines.length; i++)
165
+ {
166
+ const trimmed = lines[i].trim();
167
+
168
+ if(trimmed.startsWith('```'))
169
+ {
170
+ buffer.push(lines[i]);
171
+ block = !block;
172
+
173
+ if(!block)
174
+ {
175
+ flush();
176
+ }
177
+
178
+ continue;
179
+ }
180
+
181
+ if(block)
182
+ {
183
+ buffer.push(lines[i]);
184
+ continue;
185
+ }
186
+
187
+ if(trimmed.startsWith('|') || /^[\t ]*[-*] .+/.test(trimmed) || /^[\t ]*\d+\. .+/.test(trimmed) || trimmed.startsWith('> '))
188
+ {
189
+ buffer.push(lines[i]);
190
+ continue;
191
+ }
192
+
193
+ flush();
194
+
195
+ if(!trimmed)
196
+ {
197
+ spacer();
198
+ continue;
199
+ }
200
+
201
+ line(transform(trimmed));
202
+ }
203
+
204
+ flush();
205
+
206
+ return html;
207
+ };
208
+
3
209
  elements.ItemAdd({
4
210
  id: 'global-markdown',
5
211
  icon: 'article',
@@ -15,9 +221,7 @@ onetype.AddonReady('elements', (elements) =>
15
221
  },
16
222
  render: function()
17
223
  {
18
- this.html = elements.Fn('markdown', this.content);
19
-
20
- return `<div class="holder">${this.html}</div>`;
224
+ return `<div class="holder">${parse(this.content)}</div>`;
21
225
  }
22
226
  });
23
227
  });
@@ -1,9 +1,9 @@
1
- .e-7eb56bb9
1
+ .e-64d8716d
2
2
  {
3
3
  display: flex;
4
4
  }
5
5
 
6
- .e-7eb56bb9 > .holder
6
+ .e-64d8716d > .holder
7
7
  {
8
8
  display: flex;
9
9
  align-items: center;
@@ -16,7 +16,7 @@
16
16
 
17
17
  /* Logo */
18
18
 
19
- .e-7eb56bb9 > .holder > .logo
19
+ .e-64d8716d > .holder > .logo
20
20
  {
21
21
  display: flex;
22
22
  align-items: center;
@@ -26,7 +26,7 @@
26
26
  flex-shrink: 0;
27
27
  }
28
28
 
29
- .e-7eb56bb9 > .holder > .logo > .logo-icon
29
+ .e-64d8716d > .holder > .logo > .logo-icon
30
30
  {
31
31
  height: 16px;
32
32
  }
@@ -34,7 +34,7 @@
34
34
 
35
35
  /* Tabs */
36
36
 
37
- .e-7eb56bb9 > .holder > .tabs
37
+ .e-64d8716d > .holder > .tabs
38
38
  {
39
39
  display: flex;
40
40
  align-items: center;
@@ -43,7 +43,7 @@
43
43
  height: 100%;
44
44
  }
45
45
 
46
- .e-7eb56bb9 > .holder .tab
46
+ .e-64d8716d > .holder .tab
47
47
  {
48
48
  display: flex;
49
49
  align-items: center;
@@ -57,12 +57,12 @@
57
57
  color: var(--ot-text-2);
58
58
  }
59
59
 
60
- .e-7eb56bb9 > .holder .tab > i
60
+ .e-64d8716d > .holder .tab > i
61
61
  {
62
62
  font-size: 16px;
63
63
  }
64
64
 
65
- .e-7eb56bb9 > .holder .tab:hover
65
+ .e-64d8716d > .holder .tab:hover
66
66
  {
67
67
  color: var(--ot-text-1);
68
68
  background: var(--ot-bg-2);
@@ -70,7 +70,7 @@
70
70
 
71
71
  /* Right */
72
72
 
73
- .e-7eb56bb9 > .holder > .right
73
+ .e-64d8716d > .holder > .right
74
74
  {
75
75
  display: flex;
76
76
  align-items: center;
@@ -1,11 +1,11 @@
1
1
  onetype.AddonReady('elements', (elements) =>
2
2
  {
3
3
  elements.ItemAdd({
4
- id: 'sections-navbar',
4
+ id: 'navigation-navbar',
5
5
  icon: 'menu',
6
6
  name: 'Navbar',
7
7
  description: 'Top navigation bar with logo and links.',
8
- category: 'Section',
8
+ category: 'Navigation',
9
9
  author: 'OneType',
10
10
  config: {
11
11
  items: {
@@ -0,0 +1,101 @@
1
+ .e-210c16c7
2
+ {
3
+ display: flex;
4
+ width: 220px;
5
+ flex-shrink: 0;
6
+ height: calc(100vh - 48px);
7
+ }
8
+
9
+ .e-210c16c7 > .holder
10
+ {
11
+ display: flex;
12
+ flex-direction: column;
13
+ width: 100%;
14
+ padding: var(--ot-spacing-m) 0;
15
+ gap: var(--ot-spacing-m);
16
+ }
17
+
18
+ /* Group */
19
+
20
+ .e-210c16c7 > .holder > .group
21
+ {
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 2px;
25
+ }
26
+
27
+ /* Title */
28
+
29
+ .e-210c16c7 > .holder > .group > .title
30
+ {
31
+ font-size: 11px;
32
+ font-weight: 600;
33
+ color: var(--ot-text-2);
34
+ text-transform: uppercase;
35
+ letter-spacing: 0.5px;
36
+ padding: 0 var(--ot-spacing-m);
37
+ margin-bottom: var(--ot-spacing-x);
38
+ opacity: 0.6;
39
+ }
40
+
41
+ /* Item */
42
+
43
+ .e-210c16c7 > .holder > .group > .item
44
+ {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 8px;
48
+ padding: 0 var(--ot-spacing-m);
49
+ height: var(--ot-height-s);
50
+ text-decoration: none;
51
+ color: var(--ot-text-2);
52
+ font-size: var(--ot-size-m);
53
+ font-weight: 500;
54
+ border-radius: var(--ot-radius-s);
55
+ margin: 0 var(--ot-spacing-s);
56
+ cursor: pointer;
57
+ transition: color 0.15s ease, background 0.15s ease;
58
+ }
59
+
60
+ .e-210c16c7 > .holder > .group > .item > i
61
+ {
62
+ font-size: 18px;
63
+ opacity: 0.6;
64
+ }
65
+
66
+ .e-210c16c7 > .holder > .group > .item > .count
67
+ {
68
+ margin-left: auto;
69
+ font-size: 11px;
70
+ color: var(--ot-text-2);
71
+ opacity: 0.5;
72
+ }
73
+
74
+ .e-210c16c7 > .holder > .group > .item:hover
75
+ {
76
+ color: var(--ot-text-1);
77
+ background: var(--ot-bg-2);
78
+ }
79
+
80
+ .e-210c16c7 > .holder > .group > .item.active
81
+ {
82
+ color: var(--ot-text-1);
83
+ background: var(--ot-bg-3);
84
+ }
85
+
86
+ .e-210c16c7 > .holder > .group > .item.active > i
87
+ {
88
+ opacity: 1;
89
+ }
90
+
91
+ /* Variants */
92
+
93
+ .e-210c16c7 > .holder.bg-2
94
+ {
95
+ background: var(--ot-bg-2);
96
+ }
97
+
98
+ .e-210c16c7 > .holder.border
99
+ {
100
+ border-right: 1px solid var(--ot-bg-2-border);
101
+ }
@@ -0,0 +1,56 @@
1
+ onetype.AddonReady('elements', (elements) =>
2
+ {
3
+ elements.ItemAdd({
4
+ id: 'navigation-sidebar',
5
+ icon: 'side_navigation',
6
+ name: 'Sidebar',
7
+ description: 'Vertical navigation sidebar with grouped items and slots.',
8
+ category: 'Navigation',
9
+ author: 'OneType',
10
+ config: {
11
+ groups: {
12
+ type: 'array',
13
+ value: []
14
+ },
15
+ active: {
16
+ type: 'string',
17
+ value: ''
18
+ },
19
+ variant: {
20
+ type: 'array',
21
+ value: [],
22
+ options: ['bg-2', 'border']
23
+ },
24
+ _click: {
25
+ type: 'function'
26
+ }
27
+ },
28
+ render: function()
29
+ {
30
+ this.handleClick = (item) =>
31
+ {
32
+ this.active = item.value;
33
+
34
+ if(this._click)
35
+ {
36
+ this._click(item);
37
+ }
38
+ };
39
+
40
+ return `
41
+ <nav :class="'holder ' + variant.join(' ')">
42
+ <slot name="top"></slot>
43
+ <div ot-for="group in groups" class="group">
44
+ <p ot-if="group.title" class="title">{{ group.title }}</p>
45
+ <a ot-for="item in group.items" :class="'item' + (item.value === active ? ' active' : '')" :href="item.href || 'javascript:void(0)'" ot-click="handleClick(item)">
46
+ <i ot-if="item.icon">{{ item.icon }}</i>
47
+ <span>{{ item.label }}</span>
48
+ <span ot-if="item.count !== undefined" class="count">{{ item.count }}</span>
49
+ </a>
50
+ </div>
51
+ <slot name="bottom"></slot>
52
+ </nav>
53
+ `;
54
+ }
55
+ });
56
+ });