@madj2k/fe-frontend-kit 2.0.31 → 2.0.32
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/index.js +1 -0
- package/index.scss +1 -0
- package/package.json +1 -1
- package/readme.md +46 -0
- package/sass/bootstrap-5.3/10_mixins/_section.scss +18 -0
- package/tools/element-in-viewport/element-in-viewport-2.0.js +117 -0
- package/tools/element-in-viewport/element-in-viewport-2.0.scss +0 -0
- package/tools/element-in-viewport/index.js +2 -0
- package/tools/element-in-viewport/index.scss +1 -0
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { Madj2kResizeEnd } from './tools/resize-end';
|
|
|
6
6
|
export { Madj2kScrolling } from './tools/scrolling';
|
|
7
7
|
export { Madj2kSimpleFadeSlider } from './tools/simple-fade-slider';
|
|
8
8
|
export { Madj2kToggledOverlay } from './tools/toggled-overlay';
|
|
9
|
+
export { Madj2kElementInViewport } from './tools/element-in-viewport';
|
|
9
10
|
|
|
10
11
|
// Menus
|
|
11
12
|
export { Madj2kFlyoutMenu } from './menus/flyout-menu';
|
package/index.scss
CHANGED
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -366,6 +366,52 @@ Usage with Appear-On-Scroll (HTML):
|
|
|
366
366
|
</div>
|
|
367
367
|
```
|
|
368
368
|
|
|
369
|
+
# JS: Element In Viewport
|
|
370
|
+
A lightweight helper class that adds a configurable class to any DOM element once it becomes visible in the viewport.
|
|
371
|
+
Perfect for triggering CSS-based animations (e.g., quote reveals, fade-ins, transitions) when an element enters view.
|
|
372
|
+
* Works with IntersectionObserver API
|
|
373
|
+
* Purely DOM-based (no keyframes required)
|
|
374
|
+
* Fully configurable (threshold, delay, class)
|
|
375
|
+
* Ideal for CMS-driven content (dynamic DOM)
|
|
376
|
+
* Designed for performance and flexibility
|
|
377
|
+
|
|
378
|
+
Init:
|
|
379
|
+
```
|
|
380
|
+
document.querySelectorAll('.js-inview').forEach((el) => {
|
|
381
|
+
new Madj2kElementInViewport(el, {
|
|
382
|
+
visibleClass: 'is-in-viewport',
|
|
383
|
+
threshold: 0.5,
|
|
384
|
+
debug: false
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
HTML-Example
|
|
390
|
+
```
|
|
391
|
+
<section class="my-element js-inview">
|
|
392
|
+
<div class="my-element-content">Lorem ipsum dolor sit amet.</div>
|
|
393
|
+
</section>
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
SCSS-Example
|
|
397
|
+
```
|
|
398
|
+
.my-element {
|
|
399
|
+
.my-element-content {
|
|
400
|
+
opacity: 0;
|
|
401
|
+
transform: translateY(20%);
|
|
402
|
+
transition: opacity 0.6s ease, transform 0.6s ease;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
&.is-in-viewport {
|
|
406
|
+
.my-element-content {
|
|
407
|
+
opacity: 1;
|
|
408
|
+
transform: translateY(0);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
|
|
369
415
|
# JS: Toggled Overlay
|
|
370
416
|
This class toggles the visibility of any target element referenced by the `aria-controls`
|
|
371
417
|
attribute of a trigger element (button, link, etc.). It manages ARIA attributes for accessibility
|
|
@@ -43,6 +43,15 @@
|
|
|
43
43
|
/// [...]
|
|
44
44
|
/// </div>
|
|
45
45
|
///
|
|
46
|
+
/// @example html
|
|
47
|
+
/// <div class="csp-section">
|
|
48
|
+
/// [...]
|
|
49
|
+
/// </div>
|
|
50
|
+
/// <!-- With vertical padding instead of margin -->
|
|
51
|
+
/// <div class="csp-section csp-section-padding">
|
|
52
|
+
/// [...]
|
|
53
|
+
/// </div>
|
|
54
|
+
///
|
|
46
55
|
/// @example scss
|
|
47
56
|
/// .layout-default {
|
|
48
57
|
/// @include section-spacing();
|
|
@@ -56,6 +65,7 @@
|
|
|
56
65
|
$block-class: 'csp-block',
|
|
57
66
|
$not-last-class: 'csp-not-last',
|
|
58
67
|
$utility-append-class: 'sp',
|
|
68
|
+
$padding-append-class: 'padding',
|
|
59
69
|
$csp-blocks: (
|
|
60
70
|
'text',
|
|
61
71
|
'text-image',
|
|
@@ -101,9 +111,17 @@
|
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
.#{$section-class}.#{$not-last-class}:not(:has(+ .#{$section-class})),
|
|
114
|
+
.#{$section-class}.#{$section-class}-#{$padding-append-class},
|
|
115
|
+
.#{$section-class}:has(+ .#{$section-class}-#{$padding-append-class}),
|
|
104
116
|
.#{$section-class}-#{$utility-append-class}.#{$not-last-class}:not(:has(+ .#{$section-class})) {
|
|
105
117
|
margin-bottom: 0;
|
|
106
118
|
}
|
|
119
|
+
|
|
120
|
+
.#{$section-class}-#{$padding-append-class},
|
|
121
|
+
.#{$section-class}-#{$padding-append-class}-#{$utility-append-class} {
|
|
122
|
+
padding-top: rem-calc($spacer-section);
|
|
123
|
+
padding-bottom: rem-calc($spacer-section);
|
|
124
|
+
}
|
|
107
125
|
}
|
|
108
126
|
|
|
109
127
|
// block-spacing
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Madj2kElementInViewport
|
|
3
|
+
*
|
|
4
|
+
* Adds a CSS class to any DOM element once it becomes fully (or partially) visible
|
|
5
|
+
* in the viewport using the IntersectionObserver API.
|
|
6
|
+
*
|
|
7
|
+
* - Purely CSS-triggered transitions via class
|
|
8
|
+
* - Reusable for any type of element (quotes, sections, etc.)
|
|
9
|
+
* - Fully configurable: class name, threshold, delay
|
|
10
|
+
* - Designed for CMS contexts with dynamically loaded content
|
|
11
|
+
*
|
|
12
|
+
* @author Steffen Kroggel <developer@steffenkroggel.de>
|
|
13
|
+
* @copyright 2025 Steffen Kroggel
|
|
14
|
+
* @version 1.0.0
|
|
15
|
+
* @license GNU General Public License v3.0
|
|
16
|
+
* @see https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Single element with defaults
|
|
20
|
+
* const el = document.querySelector('.js-animate-in');
|
|
21
|
+
* new Madj2kElementInViewport(el);
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Single element with custom config
|
|
25
|
+
* new Madj2kElementInViewport(el, {
|
|
26
|
+
* visibleClass: 'is-visible',
|
|
27
|
+
* threshold: 0.75,
|
|
28
|
+
* delay: 200,
|
|
29
|
+
* debug: true
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Multiple elements
|
|
34
|
+
* document.querySelectorAll('.js-element-in-viewport').forEach((el) => {
|
|
35
|
+
* new Madj2kElementInViewport(el, {
|
|
36
|
+
* visibleClass: 'is-in-viewport',
|
|
37
|
+
* threshold: 1
|
|
38
|
+
* });
|
|
39
|
+
* });
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
class Madj2kElementInViewport {
|
|
43
|
+
config = {
|
|
44
|
+
visibleClass: 'is-in-viewport',
|
|
45
|
+
threshold: 0.5,
|
|
46
|
+
delay: 0,
|
|
47
|
+
debug: false
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {HTMLElement} element - DOM element to observe
|
|
52
|
+
* @param {Object} config - configuration options
|
|
53
|
+
* @param {string} [config.visibleClass='in-viewport'] - class to apply when element is in view
|
|
54
|
+
* @param {number} [config.threshold=1.0] - how much of the element must be visible (0–1)
|
|
55
|
+
* @param {number} [config.delay=0] - optional delay before applying class (in ms)
|
|
56
|
+
* @param {boolean} [config.debug=false] - enable debug logs
|
|
57
|
+
*/
|
|
58
|
+
constructor(element, config = {}) {
|
|
59
|
+
if (!(element instanceof HTMLElement)) {
|
|
60
|
+
console.warn('[Madj2kElementInViewport] No valid element provided.');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.element = element;
|
|
65
|
+
this.config = { ...this.config, ...config };
|
|
66
|
+
|
|
67
|
+
this._log('Initialized with config:', this.config);
|
|
68
|
+
this._observe();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Initializes the IntersectionObserver
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
_observe() {
|
|
76
|
+
const observer = new IntersectionObserver(
|
|
77
|
+
([entry], observerInstance) => {
|
|
78
|
+
if (entry.isIntersecting && entry.intersectionRatio >= this.config.threshold) {
|
|
79
|
+
this._log('Element in viewport:', this.element);
|
|
80
|
+
|
|
81
|
+
if (this.config.delay > 0) {
|
|
82
|
+
setTimeout(() => this._activate(observerInstance), this.config.delay);
|
|
83
|
+
} else {
|
|
84
|
+
this._activate(observerInstance);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
threshold: this.config.threshold
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
observer.observe(this.element);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Applies the visible class and stops observing
|
|
98
|
+
* @param {IntersectionObserver} observer
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
_activate(observer) {
|
|
102
|
+
this.element.classList.add(this.config.visibleClass);
|
|
103
|
+
observer.unobserve(this.element);
|
|
104
|
+
this._log(`Class "${this.config.visibleClass}" added.`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Logs debug messages
|
|
109
|
+
* @param {...any} args
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
_log(...args) {
|
|
113
|
+
if (this.config.debug) {
|
|
114
|
+
console.log('[Madj2kElementInViewport]', ...args);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@forward './element-in-viewport-2.0';
|