bobjoll 0.0.4

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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/package.json +25 -0
  4. package/scss/layout/_footer.scss +10 -0
  5. package/scss/layout/_header.scss +10 -0
  6. package/scss/modules/_fonts.scss +26 -0
  7. package/scss/modules/_reset.scss +219 -0
  8. package/scss/modules/bourbon/addons/_clearfix.scss +25 -0
  9. package/scss/modules/bourbon/addons/_ellipsis.scss +30 -0
  10. package/scss/modules/bourbon/addons/_position.scss +48 -0
  11. package/scss/modules/bourbon/addons/_prefixer.scss +66 -0
  12. package/scss/modules/bourbon/addons/_size.scss +51 -0
  13. package/scss/modules/bourbon/addons/_timing-functions.scss +34 -0
  14. package/scss/modules/bourbon/addons/_triangle.scss +63 -0
  15. package/scss/modules/bourbon/css3/_calc.scss +4 -0
  16. package/scss/modules/bourbon/css3/_flex-box.scss +287 -0
  17. package/scss/modules/bourbon/css3/_keyframes.scss +36 -0
  18. package/scss/modules/bourbon/css3/_linear-gradient.scss +38 -0
  19. package/scss/modules/bourbon/css3/_placeholder.scss +8 -0
  20. package/scss/modules/bourbon/css3/_selection.scss +42 -0
  21. package/scss/modules/bourbon/css3/_transition.scss +71 -0
  22. package/scss/modules/mixins/_component.scss +9 -0
  23. package/scss/modules/mixins/_grid.scss +75 -0
  24. package/scss/modules/mixins/_helpers.scss +224 -0
  25. package/scss/modules/variables/_colors.scss +447 -0
  26. package/scss/modules/variables/_general.scss +235 -0
  27. package/scss/partials/_accordion-v1-0.scss +165 -0
  28. package/scss/partials/_autocomplete-v1-0.scss +55 -0
  29. package/scss/partials/_general-v1-0.scss +51 -0
  30. package/scss/partials/_grid-v1-0.scss +109 -0
  31. package/scss/partials/_helper-v1-0.scss +299 -0
  32. package/scss/partials/_icon-v2-0.scss +323 -0
  33. package/scss/partials/_list-v1-0.scss +100 -0
  34. package/scss/partials/_modal-v1-0.scss +159 -0
  35. package/scss/partials/_notification-v1-1.scss +297 -0
  36. package/scss/partials/_progress-bar-v1.0.scss +25 -0
  37. package/scss/partials/_range-v1.0.scss +75 -0
  38. package/scss/partials/_tooltipFixed-v1.0.scss +128 -0
  39. package/scss/partials/_typography-v1-0.scss +201 -0
  40. package/scss/partials/animations/_fade.scss +23 -0
  41. package/scss/partials/animations/_rotate.scss +11 -0
  42. package/scss/partials/animations/_scale.scss +23 -0
  43. package/scss/partials/animations/_slide.scss +31 -0
  44. package/scss/partials/button-v4-0/_component.scss +304 -0
  45. package/scss/partials/form/_checkbox-and-radio-v1-0.scss +187 -0
  46. package/scss/partials/form/_dropdowns-v1-0.scss +323 -0
  47. package/scss/partials/form/_general-v1-0.scss +166 -0
  48. package/scss/partials/form/_group-v1-0.scss +157 -0
  49. package/scss/partials/form/_password-v1-0.scss +28 -0
  50. package/scss/partials/form/_switch-v1-0.scss +128 -0
  51. package/scss/partials/form/_upload-v1-0.scss +91 -0
  52. package/ts/library/common.ts +30 -0
  53. package/ts/library/cookie.ts +47 -0
  54. package/ts/library/delegate.ts +122 -0
  55. package/ts/library/dom.ts +124 -0
  56. package/ts/library/event.ts +138 -0
  57. package/ts/library/extend.js +32 -0
  58. package/ts/library/gr/dom.q.ts +12 -0
  59. package/ts/library/gr/social/dependency/twitter_pu.js +66 -0
  60. package/ts/library/gr/social/facebook.ts +154 -0
  61. package/ts/library/gr/social/google.ts +127 -0
  62. package/ts/library/gr/social/index.ts +35 -0
  63. package/ts/library/gr/social/twitter.ts +65 -0
  64. package/ts/library/helpers.ts +9 -0
  65. package/ts/library/number-abbreviate.js +57 -0
  66. package/ts/library/settings.ts +7 -0
  67. package/ts/library/storage.ts +131 -0
  68. package/ts/library/svg4everybody.legacy.js +122 -0
  69. package/ts/partials/accordion-v1.0.ts +104 -0
  70. package/ts/partials/accordionTabs-v1.0.ts +27 -0
  71. package/ts/partials/alert-v1.0.ts +51 -0
  72. package/ts/partials/copy-v1.0.ts +17 -0
  73. package/ts/partials/countdown-v1.0.ts +119 -0
  74. package/ts/partials/dropdown-v1.0.ts +247 -0
  75. package/ts/partials/hbs-v1.0.ts +9 -0
  76. package/ts/partials/modal-v1.0.ts +213 -0
  77. package/ts/partials/notifications-v1.1.ts +376 -0
  78. package/ts/partials/notify-v1.0.ts +746 -0
  79. package/ts/partials/password-v1.0.ts +19 -0
  80. package/ts/partials/popover-v1.0.ts +125 -0
  81. package/ts/partials/progress-bar-v1.0.ts +29 -0
  82. package/ts/partials/scroll-v1.0.ts +169 -0
  83. package/ts/partials/scrollable-v1.0.ts +90 -0
  84. package/ts/partials/tabs-v1.0.ts +79 -0
  85. package/ts/partials/tags-v1.0.ts +21 -0
  86. package/ts/partials/trigger-v2.0.ts +155 -0
  87. package/ts/partials/upload-v1.0.ts +17 -0
  88. package/ts/views/hbs/alert-v1.0/element.html.hbs +35 -0
  89. package/ts/views/hbs/countdown-v1.0/countdown-inner.hbs +39 -0
  90. package/ts/views/hbs/countdown-v1.0/countdown.hbs +4 -0
  91. package/ts/views/hbs/dropdown-v1.0/element.html.hbs +70 -0
  92. package/ts/views/hbs/helpers.js +58 -0
  93. package/ts/views/hbs/modal-v1.0/element.html.hbs +17 -0
  94. package/ts/views/hbs/notification-v1.1/element-disable.html.hbs +26 -0
  95. package/ts/views/hbs/notification-v1.1/element.html.hbs +43 -0
  96. package/ts/views/hbs/notification-v1.1/wrapper.html.hbs +4 -0
@@ -0,0 +1,19 @@
1
+ import { delegate } from 'bobjoll/ts/library/dom';
2
+ import 'bobjoll/ts/library/common';
3
+
4
+ (function() {
5
+ delegate('.password__toggle', 'click', function(this: HTMLElement) {
6
+ const parents = this.parents('.password');
7
+
8
+ if (parents.length > 0) {
9
+ const password = parents[0];
10
+ const input = <HTMLInputElement>password.querySelector('input');
11
+
12
+ if (input) {
13
+ const state = password.classList.toggle('password--show');
14
+
15
+ input.type = state ? 'text' : 'password';
16
+ }
17
+ }
18
+ });
19
+ })();
@@ -0,0 +1,125 @@
1
+ import 'Common';
2
+ import { Settings } from 'Settings';
3
+ import { delegate } from 'bobjoll/ts/library/dom';
4
+
5
+ (function() {
6
+ let timeout: number;
7
+ let active: Element[] = [];
8
+
9
+ delegate('.popover__trigger', 'click', function(this: HTMLElement, e: Event) {
10
+ e.preventDefault();
11
+
12
+ let popover: Element | null = this.parentElement;
13
+
14
+ if (popover && popover.classList.contains('popover')) {
15
+ let popoverActive = popover.classList.contains('active');
16
+
17
+ hide();
18
+
19
+ if (!popoverActive) {
20
+ let popoverEvent = new Event('show');
21
+
22
+ popover.dispatchEvent(popoverEvent);
23
+ popover.classList.add('active');
24
+ this.classList.add('active');
25
+
26
+ active.push(popover);
27
+
28
+ if (popover.classList.contains('popover--mobile-fullscreen')) mobile(popover);
29
+ }
30
+ }
31
+ });
32
+
33
+ delegate('.popover__close', 'click', (e: Event) => {
34
+ e.preventDefault();
35
+
36
+ hide();
37
+ });
38
+
39
+ window.addEventListener('resize', () => {
40
+ if (active && active.length > 0) {
41
+ if(window.innerWidth <= Settings.breakpoints.sm) {
42
+ if (timeout) clearTimeout(timeout);
43
+
44
+ timeout = setTimeout(() => {
45
+ [].forEach.call(active, (element: HTMLElement) => {
46
+ let container = element.querySelector('popover__container');
47
+
48
+ if (container) {
49
+ container.removeAttribute('style');
50
+
51
+ if(window.innerWidth > Settings.breakpoints.sm) container.classList.remove('notransition');
52
+ }
53
+
54
+ mobile(element);
55
+ });
56
+ });
57
+ }
58
+ }
59
+ });
60
+
61
+ window.addEventListener('mouseup', (e: Event) => {
62
+ let target: EventTarget|null = e.target;
63
+
64
+ if (target instanceof HTMLElement) {
65
+ let popover = target.parents('.popover');
66
+
67
+ if (popover.length === 0 && active.length > 0) {
68
+ hide();
69
+ }
70
+ }
71
+ });
72
+
73
+ function mobile(popover: Element) {
74
+ if (popover && window.innerWidth <= Settings.breakpoints.sm) {
75
+ let container: HTMLElement | null = (<HTMLElement>popover.querySelector('.popover__container'));
76
+
77
+ if (container) {
78
+ let containerSpacing: number = 12;
79
+ let containerScrollable: HTMLElement | null = (<HTMLElement>container.querySelector('.scrollable'));
80
+ let containerBounding = container.getBoundingClientRect();
81
+
82
+ if (!container.hasAttribute('style')) {
83
+ container.classList.add('notransition');
84
+ container.style.width = document.body.clientWidth + 'px';
85
+
86
+ if (containerScrollable) {
87
+ let maxHeight: number = (window.innerHeight - containerBounding.top) - containerSpacing;
88
+
89
+ containerScrollable.style.maxHeight = maxHeight + 'px';
90
+ }
91
+
92
+ if (popover.classList.contains('popover--bottom-left')) {
93
+ let left: number = containerBounding.left * -1;
94
+
95
+ container.style.left = left + 'px';
96
+ }
97
+
98
+ if (popover.classList.contains('popover--bottom-right')) {
99
+ let right: number = (document.body.clientWidth - containerBounding.right) * -1;
100
+
101
+ container.style.right = right + 'px'
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ function hide() {
109
+ if (active.length > 0) {
110
+ let popoverEvent = new Event('hide');
111
+
112
+ active.forEach((element: Element, index: number) => {
113
+ let button: Element | null = element.querySelector('.popover__trigger');
114
+
115
+ if (button) button.classList.remove('active');
116
+
117
+ element.classList.remove('active');
118
+ element.dispatchEvent(popoverEvent);
119
+ element.removeAttribute('style');
120
+
121
+ active.splice(index, 1);
122
+ });
123
+ }
124
+ }
125
+ })();
@@ -0,0 +1,29 @@
1
+ import { q } from '../library/dom';
2
+
3
+ export default class ProgressBar {
4
+ public static setValue(selector: string, value: number, completeTitleHtml?: string) {
5
+
6
+ if (value >= 0 && value <= 100) {
7
+ const progressBar = q(selector);
8
+ if (progressBar) {
9
+ (q('.progress-bar__value', progressBar) as HTMLElement).style.width = `${value}%`;
10
+
11
+ if (value === 100) {
12
+ progressBar.dataset.complete = 'true';
13
+
14
+ if (completeTitleHtml) {
15
+
16
+ const progressBarTitle = q('.progress-bar__title', progressBar) as HTMLParagraphElement;
17
+
18
+ progressBarTitle.innerHTML = completeTitleHtml;
19
+
20
+ progressBarTitle.classList.add('progress-bar__title-complete');
21
+ }
22
+
23
+ } else {
24
+ progressBar.dataset.complete = 'false';
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,169 @@
1
+ import 'bobjoll/ts/library/common';
2
+ import { delegate } from 'bobjoll/ts/library/dom';
3
+
4
+ export default class Scroll {
5
+ private static readonly requestAnimationFrame = (
6
+ (window as any).requestAnimationFrame ||
7
+ (window as any).webkitRequestAnimationFrame ||
8
+ (window as any).mozRequestAnimationFrame ||
9
+ (window as any).msRequestAnimationFrame ||
10
+ (window as any).oRequestAnimationFrame
11
+ ).bind(window);
12
+
13
+ private static callbacks: Function[] = [];
14
+ private static instance: Scroll;
15
+ private static position: Number;
16
+
17
+ constructor() {
18
+ Scroll.position = Scroll.getPosition();
19
+ this.addEventListeners();
20
+ }
21
+
22
+ private addEventListeners() {
23
+ const self = this;
24
+
25
+ delegate('.scrollTo', 'click', function (this: HTMLElement, e: Event) {
26
+ e.preventDefault();
27
+
28
+ let id: string | null = self.getTarjetId(this.getAttribute('href')) || '';
29
+
30
+ let tarjetElement: HTMLElement | null = document.getElementById(id) || null;
31
+ if (tarjetElement !== null) {
32
+ self.scrollTo(tarjetElement, 300);
33
+ }
34
+ });
35
+ }
36
+
37
+ private getTarjetId(anchor: string | null) {
38
+ return anchor !== null && anchor.split('#').length > 1
39
+ ? anchor.split('#')[1]
40
+ : anchor || null;
41
+ }
42
+
43
+ public static add(callback: Function) {
44
+ return Scroll.callbacks.push(callback);
45
+ }
46
+
47
+ public static remove(callbackOrIndex: number | Function)  {
48
+ try {
49
+ if ('function' === typeof callbackOrIndex) {
50
+ Scroll.callbacks.slice(Scroll.callbacks.indexOf(callbackOrIndex), 1);
51
+ } else {
52
+ Scroll.callbacks.slice(callbackOrIndex, 1);
53
+ }
54
+ } catch (err) { }
55
+ }
56
+
57
+ public static clear() {
58
+ Scroll.callbacks = [];
59
+ }
60
+
61
+ private static callback() {
62
+ const position = Scroll.getPosition();
63
+
64
+ if (position !== Scroll.position) {
65
+ const direction = position > Scroll.position ? 'down' : 'up';
66
+
67
+ Scroll.callbacks.forEach(function (callback) {
68
+ try {
69
+ callback(position, direction);
70
+ } catch (e) {
71
+ console.warn(e);
72
+ }
73
+ });
74
+
75
+ Scroll.position = Scroll.getPosition();
76
+ }
77
+
78
+ Scroll.requestAnimationFrame(Scroll.callback);
79
+ }
80
+
81
+ public static getPosition() {
82
+ return window.pageYOffset || (document.body)?document.body.scrollTop:0;
83
+ }
84
+
85
+ public scrollTo(destination: HTMLElement | number, duration = 200, easing = 'linear', callback?: Function) {
86
+ const easings: { [key: string]: Function; } = {
87
+ linear(t: number) {
88
+ return t;
89
+ },
90
+ easeInQuad(t: number) {
91
+ return t * t;
92
+ },
93
+ easeOutQuad(t: number) {
94
+ return t * (2 - t);
95
+ },
96
+ easeInOutQuad(t: number) {
97
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
98
+ },
99
+ easeInCubic(t: number) {
100
+ return t * t * t;
101
+ },
102
+ easeOutCubic(t: number) {
103
+ return (--t) * t * t + 1;
104
+ },
105
+ easeInOutCubic(t: number) {
106
+ return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
107
+ },
108
+ easeInQuart(t: number) {
109
+ return t * t * t * t;
110
+ },
111
+ easeOutQuart(t: number) {
112
+ return 1 - (--t) * t * t * t;
113
+ },
114
+ easeInOutQuart(t: number) {
115
+ return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
116
+ },
117
+ easeInQuint(t: number) {
118
+ return t * t * t * t * t;
119
+ },
120
+ easeOutQuint(t: number) {
121
+ return 1 + (--t) * t * t * t * t;
122
+ },
123
+ easeInOutQuint(t: number) {
124
+ return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;
125
+ }
126
+ };
127
+
128
+ const start = window.pageYOffset;
129
+ const startTime = 'now' in window.performance ? performance.now() : new Date().getTime();
130
+
131
+ const documentHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
132
+ const windowHeight = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight;
133
+ const destinationOffset = typeof destination === 'number' ? destination : destination.offsetTop;
134
+ const destinationOffsetToScroll = Math.round(documentHeight - destinationOffset < windowHeight ? documentHeight - windowHeight : destinationOffset);
135
+
136
+ if ('requestAnimationFrame' in window === false) {
137
+ window.scroll(0, destinationOffsetToScroll);
138
+ if (callback) {
139
+ callback();
140
+ }
141
+ return;
142
+ }
143
+
144
+ function scroll() {
145
+ const now = 'now' in window.performance ? performance.now() : new Date().getTime();
146
+ const time = Math.min(1, ((now - startTime) / duration));
147
+ const timeFunction = easings[easing](time);
148
+
149
+ window.scroll(0, Math.ceil((timeFunction * (destinationOffsetToScroll - start)) + start));
150
+
151
+ if (
152
+ Math.ceil(window.pageYOffset) === destinationOffsetToScroll ||
153
+ Math.ceil(window.pageYOffset) === (destinationOffsetToScroll-1) ||
154
+ Math.ceil(window.pageYOffset) === (destinationOffsetToScroll+1)
155
+ ) {
156
+ if (callback) {
157
+ callback();
158
+ }
159
+ return;
160
+ }
161
+
162
+ requestAnimationFrame(scroll);
163
+ }
164
+
165
+ scroll();
166
+ }
167
+ }
168
+
169
+ const scroll = new Scroll();
@@ -0,0 +1,90 @@
1
+
2
+ interface Touch {
3
+ identifier: number;
4
+ target: EventTarget;
5
+ screenX: number;
6
+ screenY: number;
7
+ clientX: number;
8
+ clientY: number;
9
+ pageX: number;
10
+ pageY: number;
11
+ };
12
+
13
+ interface TouchList {
14
+ length: number;
15
+ [key: number]: Touch;
16
+ };
17
+
18
+ interface TouchEvent extends UIEvent {
19
+ touches: TouchList;
20
+ targetTouches: TouchList;
21
+ changedTouches: TouchList;
22
+ originalEvent: any;
23
+ };
24
+
25
+ import { Settings } from 'Settings';
26
+ import { delegate } from 'bobjoll/ts/library/dom';
27
+
28
+ (function() {
29
+ let touch = (('ontouchstart' in window) || ((navigator as any).MaxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0));
30
+ let start: number;
31
+ let timeout: number;
32
+
33
+ if (touch) {
34
+ delegate('.scrollable', 'touchstart', function(this: HTMLElement, e: TouchEvent) {
35
+ e.stopPropagation();
36
+
37
+ if (timeout) clearTimeout(timeout);
38
+
39
+ if (!disable(this)) {
40
+ let touch = getTouchEvent(e);
41
+
42
+ start = touch.pageY;
43
+ }
44
+ });
45
+
46
+ delegate('.scrollable', 'touchmove', function(this: HTMLElement, e: TouchEvent) {
47
+ e.stopPropagation();
48
+
49
+ if (!disable(this)) {
50
+ let touch = getTouchEvent(e);
51
+ let move = start - touch.pageY;
52
+
53
+ if(this.scrollTop + move >= this.scrollHeight - this.clientHeight) {
54
+ e.preventDefault();
55
+ e.returnValue = false;
56
+ }
57
+ }
58
+ });
59
+ }
60
+
61
+ delegate('.scrollable', 'DOMMouseScroll mousewheel', function(this: HTMLElement, e: any) {
62
+ e.stopPropagation();
63
+
64
+ if(!disable(this) && this.scrollHeight > this.clientHeight) {
65
+ var up = (e.type == 'DOMMouseScroll' ? e.detail * -40 : e.wheelDelta) > 0,
66
+ h = this.scrollHeight - this.clientHeight,
67
+ c = this.scrollTop / h;
68
+
69
+ if ((!up && c === 1) || (up && c === 0) || h === 0) {
70
+ e.preventDefault();
71
+ e.returnValue = false;
72
+ }
73
+ }
74
+ });
75
+
76
+ function disable(element: HTMLElement) {
77
+ if(element.classList.contains('scrollable--xs') && window.innerWidth >= Settings.breakpoints.xs) return true;
78
+ if(element.classList.contains('scrollable--sm') && window.innerWidth >= Settings.breakpoints.sm) return true;
79
+ if(element.classList.contains('scrollable--md') && window.innerWidth >= Settings.breakpoints.md) return true;
80
+ if(element.classList.contains('scrollable--lg') && window.innerWidth >= Settings.breakpoints.lg) return true;
81
+
82
+ return false;
83
+ }
84
+
85
+ function getTouchEvent(e: any) {
86
+ let event = e;
87
+
88
+ return event.targetTouches ? event.targetTouches[0] : event.changedTouches[0];
89
+ }
90
+ })();
@@ -0,0 +1,79 @@
1
+ import 'bobjoll/ts/library/common';
2
+ import { delegate } from 'bobjoll/ts/library/dom';
3
+
4
+ class Tabs {
5
+ constructor() {
6
+ this.addEventListeners();
7
+ }
8
+
9
+ public show(id: string) {
10
+ let tab = document.getElementById(id);
11
+
12
+ if (tab) {
13
+ let parents = tab.parents('.tabs');
14
+
15
+ if (parents && parents.length > 0) {
16
+ let tabWrapper = parents[0];
17
+ let tabWrapperButtons = tabWrapper.querySelectorAll('.tabs__link');
18
+
19
+ if (tabWrapperButtons.length > 0) {
20
+ [].forEach.call(tabWrapperButtons, (element: HTMLElement) => {
21
+ if (element.dataset['tab'] !== id || element.classList.contains('active')) {
22
+ element.classList.remove('active');
23
+ }
24
+
25
+ if (element.dataset['tab'] === id) {
26
+ element.classList.add('active');
27
+ }
28
+ });
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ private addEventListeners() {
35
+ const self = this;
36
+
37
+ delegate('.tabs__link', 'click', function (this: HTMLElement, e: Event) {
38
+ let id: string | undefined = this.dataset['tab'];
39
+
40
+ if (id) {
41
+ e.preventDefault();
42
+
43
+ self.show(id);
44
+ }
45
+ });
46
+
47
+ window.addEventListener('resize', () => {
48
+ if ((window as any).tabsTimeout) clearTimeout((window as any).tabsTimeout);
49
+
50
+ (window as any).tabsTimeout = setTimeout(function () {
51
+ let tabs = document.getElementsByClassName('tabs');
52
+
53
+ [].forEach.call(tabs, (element: HTMLElement) => {
54
+ let tabsButtons = element.querySelectorAll('.tabs__link.active'); // Active tab
55
+
56
+ if (tabsButtons.length === 0) {
57
+ let tabsButton = (<HTMLElement>element.querySelector('.tabs__link')); // First tab
58
+
59
+ if (tabsButton) {
60
+ let id = tabsButton.dataset['tab'];
61
+
62
+ if (id) {
63
+ let tabsButtons = element.querySelectorAll('.tabs__link[data-tab="' + id + '"]'); // Tab buttons with same id
64
+
65
+ if (tabsButtons) {
66
+ [].forEach.call(tabsButtons, (element: HTMLElement) => {
67
+ element.classList.add('active');
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ });
74
+ }, 150);
75
+ });
76
+ }
77
+ }
78
+
79
+ export default new Tabs();
@@ -0,0 +1,21 @@
1
+ import { delegate } from 'bobjoll/ts/library/dom';
2
+
3
+ (function() {
4
+ delegate('.tags .remove', 'click', function(this: HTMLElement, e: Event) {
5
+ e.preventDefault();
6
+
7
+ let id: string | null = this.getAttribute('for');
8
+
9
+ if (id) {
10
+ let input = (<HTMLInputElement>document.getElementById(id));
11
+
12
+ if (input) {
13
+ let event = new Event('change');
14
+
15
+ input.checked = false;
16
+
17
+ input.dispatchEvent(event);
18
+ }
19
+ }
20
+ });
21
+ })();
@@ -0,0 +1,155 @@
1
+ import { qq, delegate } from 'bobjoll/ts/library/dom';
2
+ import { KEvent, KEventTarget } from 'bobjoll/ts/library/event';
3
+
4
+ interface TriggerActive {
5
+ [name: string]: {
6
+ id: string;
7
+ permanent: boolean;
8
+ lockscroll: boolean;
9
+ };
10
+ }
11
+
12
+ export class KEventShow extends KEvent {
13
+ constructor(container: HTMLElement) {
14
+ super();
15
+ this.type = 'show';
16
+ this.extra = container;
17
+ }
18
+ }
19
+
20
+ export class KEventHide extends KEvent {
21
+ constructor(container: HTMLElement) {
22
+ super();
23
+ this.type = 'hide';
24
+ this.extra = container;
25
+ }
26
+ }
27
+
28
+ class Trigger extends KEventTarget {
29
+ private static readonly wrapper = document.body;
30
+ private static readonly classActive = 'active';
31
+ private static active: TriggerActive = {};
32
+
33
+ constructor() {
34
+ super();
35
+
36
+ this.addEventListeners();
37
+ }
38
+
39
+ private static getActiveTrigger(permanent: boolean = false) {
40
+ return Object.keys(Trigger.active).reduce((acc: string[], key) => {
41
+ const settings = Trigger.active[key];
42
+
43
+ if (settings && settings.permanent == permanent) {
44
+ acc.push(settings.id);
45
+ }
46
+
47
+ return acc;
48
+ }, []);
49
+ }
50
+
51
+ private static getContainer(id: string) {
52
+ return <HTMLElement>document.getElementById(id) || null;
53
+ }
54
+
55
+ private static getSettings(container: HTMLElement) {
56
+ return {
57
+ id: container.id,
58
+ permanent: container.dataset.permanent ? true : false,
59
+ lockscroll: container.dataset.lockScroll ? true : false,
60
+ };
61
+ }
62
+
63
+ private static update(id?: string) {
64
+ Trigger.wrapper.dataset.trigger = Trigger.getActiveTrigger(true).join(' ') || id || '';
65
+ }
66
+
67
+ public addEventListener(t: 'show', listener: (ev: KEvent) => any, useCapture?: boolean): void;
68
+ public addEventListener(t: 'hide', listener: (ev: KEvent) => any, useCapture?: boolean): void;
69
+ public addEventListener(t: string, listener: (ev: KEvent) => any, useCapture: boolean = true): void {
70
+ super.addEventListener(t, listener, useCapture);
71
+ }
72
+
73
+ public show(id: string) {
74
+ const container = Trigger.getContainer(id);
75
+
76
+ if (container) {
77
+ container.classList.add(Trigger.classActive);
78
+
79
+ qq(`.trigger__button[data-trigger="${id}"]`).forEach(trigger => trigger.classList.add(Trigger.classActive));
80
+
81
+ this.add(container);
82
+
83
+ this.dispatchEvent(new KEventShow(container));
84
+ }
85
+ }
86
+
87
+ public hide(id: string) {
88
+ const container = Trigger.getContainer(id);
89
+
90
+ if (container) {
91
+ container.classList.remove(Trigger.classActive);
92
+
93
+ qq(`.trigger__button[data-trigger="${id}"]`).forEach(trigger => trigger.classList.remove(Trigger.classActive));
94
+
95
+ this.remove(container);
96
+
97
+ this.dispatchEvent(new KEventHide(container));
98
+ }
99
+ }
100
+
101
+ private add(container: HTMLElement) {
102
+ const settings = Trigger.getSettings(container);
103
+
104
+ if (settings.lockscroll) {
105
+ Trigger.wrapper.classList.add('overflow-hidden');
106
+ }
107
+
108
+ Trigger.getActiveTrigger().forEach(id => this.hide(id));
109
+
110
+ Trigger.active[container.id] = settings;
111
+
112
+ Trigger.update(container.id);
113
+ }
114
+
115
+ private remove(container: HTMLElement) {
116
+ if (Trigger.active[container.id]) {
117
+ const settings = Trigger.active[container.id];
118
+
119
+ if (settings.lockscroll) {
120
+ Trigger.wrapper.classList.remove('overflow-hidden');
121
+ }
122
+
123
+ delete Trigger.active[container.id];
124
+ }
125
+
126
+ Trigger.update();
127
+ }
128
+
129
+ private addEventListeners() {
130
+ const self = this;
131
+
132
+ delegate('.trigger__button', 'click', function(this: HTMLButtonElement) {
133
+ const id = this.dataset.trigger || '';
134
+ const action = this.classList.contains('active') ? 'hide' : 'show';
135
+
136
+ self[action](id);
137
+
138
+ this.dispatchEvent(new Event(`toggle`));
139
+ });
140
+
141
+ delegate('.trigger__close', 'click', function(this: HTMLButtonElement) {
142
+ const trigger = this.closest('.trigger');
143
+
144
+ if (trigger) {
145
+ const id = trigger.id;
146
+
147
+ self.hide(id);
148
+ }
149
+
150
+ this.dispatchEvent(new Event(`toggle`));
151
+ });
152
+ }
153
+ }
154
+
155
+ export default new Trigger();