@onetype/framework 2.0.39 → 2.0.41

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.
@@ -1,459 +0,0 @@
1
- transforms.ItemAdd({
2
- id: 'tabs',
3
- icon: 'tab',
4
- name: 'Tabs',
5
- description: 'Tabbed interface component for organizing content. Switch between multiple panels with navigation controls.',
6
- config: {
7
- 'position': ['string', 'top'],
8
- 'alignment': ['string', 'left'],
9
- 'active-tab': ['number', 0],
10
- 'animation': ['string', 'fade'],
11
- 'animation-duration': ['number', 300],
12
- 'autoplay': ['boolean', true],
13
- 'autoplay-interval': ['number', 5000],
14
- 'autoplay-pause-on-hover': ['boolean', true],
15
- 'show-indicators': ['boolean', false],
16
- 'vertical': ['boolean', true],
17
- 'closeable': ['boolean', true],
18
- 'scrollable': ['boolean', true]
19
- },
20
- code: function(data, node, transformer)
21
- {
22
- const id = 'tabs-' + onetype.Generate(8);
23
-
24
- this.setup = () =>
25
- {
26
- node.classList.add('tabs');
27
- node.classList.add(id);
28
- node.classList.add('tabs-position-' + data['position']);
29
-
30
- const children = Array.from(node.children);
31
- const navigation = document.createElement('div');
32
- const content = document.createElement('div');
33
-
34
- navigation.className = 'tabs-navigation';
35
- content.className = 'tabs-content';
36
-
37
- if(data['vertical'])
38
- {
39
- node.classList.add('tabs-vertical');
40
- }
41
-
42
- if(data['alignment'])
43
- {
44
- navigation.classList.add('tabs-align-' + data['alignment']);
45
- }
46
-
47
- children.forEach((child, index) =>
48
- {
49
- const title = child.getAttribute('title') || child.getAttribute('data-title') || `Tab ${index + 1}`;
50
- const tabButton = document.createElement('button');
51
- const tabPane = document.createElement('div');
52
-
53
- tabButton.className = 'tab-button';
54
- tabButton.textContent = title;
55
- tabButton.setAttribute('data-tab-index', index);
56
-
57
- tabPane.className = 'tab-pane';
58
- tabPane.setAttribute('data-tab-index', index);
59
-
60
- while(child.firstChild)
61
- {
62
- tabPane.appendChild(child.firstChild);
63
- }
64
-
65
- navigation.appendChild(tabButton);
66
- content.appendChild(tabPane);
67
- });
68
-
69
- node.innerHTML = '';
70
-
71
- if(data['position'] === 'bottom')
72
- {
73
- node.appendChild(content);
74
- node.appendChild(navigation);
75
- }
76
- else
77
- {
78
- node.appendChild(navigation);
79
- node.appendChild(content);
80
- }
81
- };
82
-
83
- this.closeable = () =>
84
- {
85
- if(!data['closeable'])
86
- {
87
- return;
88
- }
89
-
90
- const buttons = node.querySelectorAll('.tab-button');
91
-
92
- buttons.forEach(button =>
93
- {
94
- const closeButton = document.createElement('span');
95
- closeButton.className = 'tab-close';
96
- closeButton.innerHTML = '×';
97
-
98
- closeButton.addEventListener('click', (event) =>
99
- {
100
- event.stopPropagation();
101
- const index = parseInt(button.getAttribute('data-tab-index'));
102
- this.removeTab(index);
103
- });
104
-
105
- button.appendChild(closeButton);
106
- });
107
- };
108
-
109
- this.indicators = () =>
110
- {
111
- if(!data['show-indicators'])
112
- {
113
- return;
114
- }
115
-
116
- const indicators = document.createElement('div');
117
- indicators.className = 'tabs-indicators';
118
-
119
- const buttons = node.querySelectorAll('.tab-button');
120
-
121
- buttons.forEach((button, index) =>
122
- {
123
- const indicator = document.createElement('span');
124
- indicator.className = 'tab-indicator';
125
- indicator.setAttribute('data-tab-index', index);
126
-
127
- indicator.addEventListener('click', () =>
128
- {
129
- this.switchTab(index);
130
- });
131
-
132
- indicators.appendChild(indicator);
133
- });
134
-
135
- node.appendChild(indicators);
136
- };
137
-
138
- this.styles = () =>
139
- {
140
- const duration = data['animation-duration'];
141
- const animation = data['animation'];
142
- const style = document.createElement('style');
143
-
144
- let animationStyles = '';
145
-
146
- if(animation === 'fade')
147
- {
148
- animationStyles = `
149
- .tabs-${id} .tab-pane {
150
- opacity: 0;
151
- transition: opacity ${duration}ms ease-in-out;
152
- }
153
- .tabs-${id} .tab-pane.active {
154
- opacity: 1;
155
- }
156
- `;
157
- }
158
- else if(animation === 'slide')
159
- {
160
- animationStyles = `
161
- .tabs-${id} .tab-pane {
162
- transform: translateX(20px);
163
- opacity: 0;
164
- transition: transform ${duration}ms ease, opacity ${duration}ms ease;
165
- }
166
- .tabs-${id} .tab-pane.active {
167
- transform: translateX(0);
168
- opacity: 1;
169
- }
170
- `;
171
- }
172
- else
173
- {
174
- animationStyles = `
175
- .tabs-${id} .tab-pane {
176
- display: none;
177
- }
178
- .tabs-${id} .tab-pane.active {
179
- display: block;
180
- }
181
- `;
182
- }
183
-
184
- style.textContent = `
185
- .tabs-${id} {
186
- display: flex;
187
- flex-direction: column;
188
- }
189
- .tabs-${id}.tabs-vertical {
190
- flex-direction: row;
191
- }
192
- .tabs-${id} .tabs-navigation {
193
- display: flex;
194
- gap: 8px;
195
- position: relative;
196
- }
197
- .tabs-${id}.tabs-vertical .tabs-navigation {
198
- flex-direction: column;
199
- min-width: 200px;
200
- }
201
- .tabs-${id} .tabs-navigation.tabs-align-center {
202
- justify-content: center;
203
- }
204
- .tabs-${id} .tabs-navigation.tabs-align-right {
205
- justify-content: flex-end;
206
- }
207
- .tabs-${id} .tab-button {
208
- padding: 10px 20px;
209
- background: transparent;
210
- border: none;
211
- cursor: pointer;
212
- transition: all ${duration}ms ease;
213
- position: relative;
214
- display: flex;
215
- align-items: center;
216
- gap: 8px;
217
- }
218
- .tabs-${id} .tab-button.active {
219
- background: rgba(0, 0, 0, 0.1);
220
- }
221
- .tabs-${id} .tab-button:hover {
222
- background: rgba(0, 0, 0, 0.05);
223
- }
224
- .tabs-${id} .tab-close {
225
- display: inline-block;
226
- width: 20px;
227
- height: 20px;
228
- line-height: 20px;
229
- text-align: center;
230
- border-radius: 50%;
231
- transition: all ${duration}ms ease;
232
- }
233
- .tabs-${id} .tab-close:hover {
234
- background: rgba(255, 0, 0, 0.1);
235
- color: red;
236
- }
237
- .tabs-${id} .tabs-content {
238
- position: relative;
239
- flex: 1;
240
- }
241
- ${animationStyles}
242
- .tabs-${id} .tabs-content .tab-pane {
243
- position: absolute;
244
- top: 0;
245
- left: 0;
246
- width: 100%;
247
- height: 100%;
248
- }
249
- .tabs-${id} .tabs-indicators {
250
- display: flex;
251
- gap: 6px;
252
- justify-content: center;
253
- padding: 10px;
254
- }
255
- .tabs-${id} .tab-indicator {
256
- width: 8px;
257
- height: 8px;
258
- border-radius: 50%;
259
- background: rgba(0, 0, 0, 0.3);
260
- cursor: pointer;
261
- transition: all ${duration}ms ease;
262
- }
263
- .tabs-${id} .tab-indicator.active {
264
- background: rgba(0, 0, 0, 0.8);
265
- transform: scale(1.2);
266
- }
267
- .tabs-${id}.tabs-position-bottom {
268
- flex-direction: column-reverse;
269
- }
270
- .tabs-${id}.tabs-vertical.tabs-position-right {
271
- flex-direction: row-reverse;
272
- }
273
- `;
274
-
275
- if(data['scrollable'])
276
- {
277
- style.textContent += `
278
- .tabs-${id} .tabs-navigation {
279
- overflow-x: auto;
280
- scrollbar-width: thin;
281
- }
282
- .tabs-${id}.tabs-vertical .tabs-navigation {
283
- overflow-x: visible;
284
- overflow-y: auto;
285
- }
286
- `;
287
- }
288
-
289
- document.head.appendChild(style);
290
- };
291
-
292
- this.switchTab = (index) =>
293
- {
294
- const buttons = node.querySelectorAll('.tab-button');
295
- const panes = node.querySelectorAll('.tab-pane');
296
- const indicators = node.querySelectorAll('.tab-indicator');
297
-
298
- buttons.forEach((button, buttonIndex) =>
299
- {
300
- if(buttonIndex === index)
301
- {
302
- button.classList.add('active');
303
- }
304
- else
305
- {
306
- button.classList.remove('active');
307
- }
308
- });
309
-
310
- panes.forEach((pane, paneIndex) =>
311
- {
312
- if(paneIndex === index)
313
- {
314
- pane.classList.add('active');
315
- }
316
- else
317
- {
318
- pane.classList.remove('active');
319
- }
320
- });
321
-
322
- indicators.forEach((indicator, indicatorIndex) =>
323
- {
324
- if(indicatorIndex === index)
325
- {
326
- indicator.classList.add('active');
327
- }
328
- else
329
- {
330
- indicator.classList.remove('active');
331
- }
332
- });
333
-
334
- this.currentTab = index;
335
- };
336
-
337
- this.removeTab = (index) =>
338
- {
339
- const buttons = node.querySelectorAll('.tab-button');
340
- const panes = node.querySelectorAll('.tab-pane');
341
- const indicators = node.querySelectorAll('.tab-indicator');
342
-
343
- if(buttons.length <= 1)
344
- {
345
- return;
346
- }
347
-
348
- buttons[index].remove();
349
- panes[index].remove();
350
-
351
- if(indicators.length)
352
- {
353
- indicators[index].remove();
354
- }
355
-
356
- const remainingButtons = node.querySelectorAll('.tab-button');
357
- const remainingPanes = node.querySelectorAll('.tab-pane');
358
- const remainingIndicators = node.querySelectorAll('.tab-indicator');
359
-
360
- remainingButtons.forEach((button, newIndex) =>
361
- {
362
- button.setAttribute('data-tab-index', newIndex);
363
- });
364
-
365
- remainingPanes.forEach((pane, newIndex) =>
366
- {
367
- pane.setAttribute('data-tab-index', newIndex);
368
- });
369
-
370
- remainingIndicators.forEach((indicator, newIndex) =>
371
- {
372
- indicator.setAttribute('data-tab-index', newIndex);
373
- });
374
-
375
- if(this.currentTab === index)
376
- {
377
- this.switchTab(Math.max(0, index - 1));
378
- }
379
- else if(this.currentTab > index)
380
- {
381
- this.currentTab--;
382
- }
383
- };
384
-
385
- this.autoplay = () =>
386
- {
387
- if(!data['autoplay'])
388
- {
389
- return;
390
- }
391
-
392
- const interval = data['autoplay-interval'];
393
- const pauseOnHover = data['autoplay-pause-on-hover'];
394
-
395
- let autoplayTimer = null;
396
-
397
- const startAutoplay = () =>
398
- {
399
- autoplayTimer = setInterval(() =>
400
- {
401
- const buttons = node.querySelectorAll('.tab-button');
402
- const nextIndex = (this.currentTab + 1) % buttons.length;
403
- this.switchTab(nextIndex);
404
- }, interval);
405
- };
406
-
407
- const stopAutoplay = () =>
408
- {
409
- if(autoplayTimer)
410
- {
411
- clearInterval(autoplayTimer);
412
- autoplayTimer = null;
413
- }
414
- };
415
-
416
- if(pauseOnHover)
417
- {
418
- node.addEventListener('mouseenter', stopAutoplay);
419
- node.addEventListener('mouseleave', startAutoplay);
420
- }
421
-
422
- startAutoplay();
423
-
424
- node._tabsAutoplay = {
425
- start: startAutoplay,
426
- stop: stopAutoplay
427
- };
428
- };
429
-
430
- this.events = () =>
431
- {
432
- const buttons = node.querySelectorAll('.tab-button');
433
-
434
- buttons.forEach(button =>
435
- {
436
- button.addEventListener('click', () =>
437
- {
438
- const index = parseInt(button.getAttribute('data-tab-index'));
439
- this.switchTab(index);
440
- });
441
- });
442
- };
443
-
444
- this.initialize = () =>
445
- {
446
- const activeIndex = Math.max(0, Math.min(data['active-tab'], node.querySelectorAll('.tab-button').length - 1));
447
- this.currentTab = activeIndex;
448
- this.switchTab(activeIndex);
449
- };
450
-
451
- this.setup();
452
- this.closeable();
453
- this.indicators();
454
- this.styles();
455
- this.events();
456
- this.initialize();
457
- this.autoplay();
458
- }
459
- });
@@ -1,172 +0,0 @@
1
- transforms.ItemAdd({
2
- id: 'typed',
3
- icon: 'keyboard',
4
- name: 'Typed',
5
- description: 'Typewriter text animation effect. Automatically types and deletes text with customizable speed.',
6
- js: [
7
- 'https://cdn.jsdelivr.net/npm/typed.js@2.1.0/dist/typed.umd.js'
8
- ],
9
- config: {
10
- 'strings': ['array', []],
11
- 'type-speed': ['number', 50],
12
- 'back-speed': ['number', 30],
13
- 'start-delay': ['number', 0],
14
- 'back-delay': ['number', 700],
15
- 'loop': ['boolean', false],
16
- 'loop-count': ['number', 0],
17
- 'show-cursor': ['boolean', true],
18
- 'cursor-char': ['string', '|'],
19
- 'auto-insert-css': ['boolean', true],
20
- 'shuffle': ['boolean', false],
21
- 'smart-backspace': ['boolean', true],
22
- 'fade-out': ['boolean', false],
23
- 'fade-out-delay': ['number', 500],
24
- 'content-type': ['string', 'html']
25
- },
26
- code: function(data, node, transformer)
27
- {
28
- const id = 'typed-' + onetype.Generate(8);
29
-
30
- this.setup = () =>
31
- {
32
- node.classList.add('typed');
33
- node.classList.add(id);
34
-
35
- const strings = data['strings'];
36
- const children = Array.from(node.children);
37
-
38
- const stringsArray = [];
39
-
40
- if(strings && strings.length > 0)
41
- {
42
- stringsArray.push(...strings);
43
- }
44
- else if(children.length > 0)
45
- {
46
- children.forEach(child =>
47
- {
48
- stringsArray.push(child.innerHTML);
49
- });
50
-
51
- node.innerHTML = '';
52
- }
53
- else
54
- {
55
- const existingText = node.textContent || node.innerHTML;
56
- if(existingText.trim())
57
- {
58
- stringsArray.push(existingText);
59
- node.innerHTML = '';
60
- }
61
- }
62
-
63
- if(stringsArray.length === 0)
64
- {
65
- stringsArray.push('Type your text here...');
66
- }
67
-
68
- this.strings = stringsArray;
69
-
70
- const element = document.createElement('span');
71
- element.className = 'typed-element';
72
- node.appendChild(element);
73
- };
74
-
75
- this.styles = () =>
76
- {
77
- if(!data['auto-insert-css'])
78
- {
79
- return;
80
- }
81
-
82
- const style = document.createElement('style');
83
-
84
- style.textContent = `
85
- .typed-${id} {
86
- display: inline-block;
87
- }
88
- .typed-${id} .typed-cursor {
89
- opacity: 1;
90
- animation: typedjsBlink 0.7s infinite;
91
- -webkit-animation: typedjsBlink 0.7s infinite;
92
- animation: typedjsBlink 0.7s infinite;
93
- }
94
- @keyframes typedjsBlink {
95
- 50% { opacity: 0.0; }
96
- }
97
- @-webkit-keyframes typedjsBlink {
98
- 0% { opacity: 1; }
99
- 50% { opacity: 0.0; }
100
- 100% { opacity: 1; }
101
- }
102
- .typed-${id} .typed-fade-out {
103
- opacity: 0;
104
- transition: opacity 0.25s;
105
- }
106
- `;
107
-
108
- document.head.appendChild(style);
109
- };
110
-
111
- this.config = () =>
112
- {
113
- const config = {
114
- strings: this.strings,
115
- typeSpeed: data['type-speed'],
116
- backSpeed: data['back-speed'],
117
- startDelay: data['start-delay'],
118
- backDelay: data['back-delay'],
119
- loop: data['loop'],
120
- showCursor: data['show-cursor'],
121
- cursorChar: data['cursor-char'],
122
- autoInsertCss: false,
123
- shuffle: data['shuffle'],
124
- smartBackspace: data['smart-backspace'],
125
- contentType: data['content-type']
126
- };
127
-
128
- if(data['loop-count'] > 0)
129
- {
130
- config.loopCount = data['loop-count'];
131
- }
132
-
133
- if(data['fade-out'])
134
- {
135
- config.fadeOut = true;
136
- config.fadeOutClass = 'typed-fade-out';
137
- config.fadeOutDelay = data['fade-out-delay'];
138
- }
139
-
140
- return config;
141
- };
142
-
143
- this.initialize = () =>
144
- {
145
- setTimeout(() =>
146
- {
147
- const element = node.querySelector('.typed-element');
148
-
149
- if(!element)
150
- {
151
- return;
152
- }
153
-
154
- const typedInstance = new Typed(element, this.config());
155
-
156
- node._typedInstance = typedInstance;
157
-
158
- node._typedControl = {
159
- start: () => typedInstance.start(),
160
- stop: () => typedInstance.stop(),
161
- toggle: () => typedInstance.toggle(),
162
- destroy: () => typedInstance.destroy(),
163
- reset: () => typedInstance.reset()
164
- };
165
- }, 0);
166
- };
167
-
168
- this.setup();
169
- this.styles();
170
- this.initialize();
171
- }
172
- });