sidebarius 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mikhail Prugov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,250 @@
1
+ # Sidebarius
2
+
3
+ [![npm version](https://badge.fury.io/js/sidebarius.svg)](https://www.npmjs.com/package/sidebarius)
4
+ [![Npm package total downloads](https://badgen.net/npm/dt/sidebarius)](https://www.npmjs.com/package/sidebarius)
5
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
6
+
7
+ **Sidebarius** is a **lightweight**, **dependency-free** JavaScript tool for creating a "sticky" sidebar that adapts to scroll movements. This allows for dynamic interfaces with elements that stay in view as the user scrolls the page.
8
+
9
+ ## [Demo](https://phenomenonus.github.io/sidebarius/) 👈
10
+
11
+ ## Table of Contents
12
+
13
+ - [Installation](#installation)
14
+ - [Usage](#usage)
15
+ - [Vanilla JS](#vanilla-js)
16
+ - [React Typescript](#react-typescript)
17
+ - [API](#api)
18
+ - [Limitations](#limitations)
19
+ - [Links](#links)
20
+ - [Copyright and license](#copyright-and-license)
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ Install the package via npm:
27
+
28
+ ```bash
29
+ npm install sidebarius
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Usage
35
+
36
+ ### Vanilla JS
37
+
38
+ ```html
39
+ <main>
40
+ <aside id="container">
41
+ <div id="container_inner"><!-- Sidebar content --></div>
42
+ </aside>
43
+ <section><!-- Section content --></section>
44
+ </main>
45
+
46
+ <!-- Import globally, or use ES Modules as shown below -->
47
+ <!-- <script src="./sidebarius.iife.min.js"></script> -->
48
+
49
+ <script type="module">
50
+ import Sidebarius from './sidebarius.esm.min.js'; // Or use the global import (see commented line above)
51
+
52
+ const sidebarius = new Sidebarius(
53
+ document.getElementById('container'),
54
+ document.getElementById('container_inner'),
55
+ 16, // spaceBottom (optional, default is 0)
56
+ 16, // spaceTop (optional, default is 0)
57
+ callback, // optional callback
58
+ );
59
+
60
+ sidebarius.start();
61
+
62
+ function callback(state, direction, strategy) {
63
+ console.log('STATE: ' + ['None', 'ContainerBottom', 'ColliderTop', 'ColliderBottom', 'TranslateY', 'Rest'][state]);
64
+ console.log('DIRECTION: ' + ['None', 'Down', 'Up'][direction]);
65
+ console.log('STRATEGY: ' + ['None', 'Both', 'Top'][strategy]);
66
+ }
67
+ </script>
68
+ ```
69
+
70
+ > [Latest release](https://github.com/phenomenonus/sidebarius/releases/latest/)
71
+
72
+ ---
73
+
74
+ ### React Typescript
75
+
76
+ ```ts
77
+ import React, { useRef, useEffect, FC, HTMLAttributes, CSSProperties } from 'react';
78
+ import Sidebarius from 'sidebarius';
79
+
80
+ type SidebarContainerProps = Omit<HTMLAttributes<HTMLElement>, 'style'> & {
81
+ style?: Omit<CSSProperties, 'padding'>;
82
+ };
83
+
84
+ type SidebarContainerInnerProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {
85
+ style?: Omit<CSSProperties, 'margin'>;
86
+ };
87
+
88
+ interface SidebarProps {
89
+ container?: SidebarContainerProps;
90
+ containerInner?: SidebarContainerInnerProps;
91
+ }
92
+
93
+ const Sidebar: FC<SidebarProps> = ({ container = {}, containerInner = {}, children }) => {
94
+ const containerRef = useRef<HTMLElement | null>(null);
95
+ const containerInnerRef = useRef<HTMLDivElement | null>(null);
96
+
97
+ useEffect(() => {
98
+ if (!containerRef.current || !containerInnerRef.current) return;
99
+
100
+ const sidebarius = new Sidebarius(
101
+ containerRef.current,
102
+ containerInnerRef.current,
103
+ 16, // spaceBottom
104
+ 16, // spaceTop
105
+ );
106
+
107
+ sidebarius.start();
108
+
109
+ return () => {
110
+ sidebarius.stop();
111
+ };
112
+ }, []);
113
+
114
+ return (
115
+ <aside ref={containerRef} {...container}>
116
+ <div ref={containerInnerRef} {...containerInner}>
117
+ {children}
118
+ </div>
119
+ </aside>
120
+ );
121
+ };
122
+
123
+ export default Sidebar;
124
+ ```
125
+
126
+ ---
127
+
128
+ ## API
129
+
130
+ | Method | Description |
131
+ | ---------------------------------- | ----------------------------------------------------------- |
132
+ | `start()` | Starts the sticky scrolling behavior. |
133
+ | `stop()` | Stops the sticky scrolling behavior. |
134
+ | `setSpaces(bottomSpace, spaceTop)` | Sets the distance to the collider and triggers a re-render. |
135
+
136
+ ---
137
+
138
+ ### Constructor Parameters
139
+
140
+ ```javascript
141
+ constructor(
142
+ container: HTMLElement,
143
+ containerInner: HTMLElement,
144
+ spaceBottom: number = 0,
145
+ spaceTop: number = 0,
146
+ callback: Callback = () => {}
147
+ );
148
+ ```
149
+
150
+ | Parameter | Type | Description |
151
+ | ---------------- | ----------- | ----------------------------------------------------------------------------------- |
152
+ | `container` | HTMLElement | The parent element (Container) that holds the sticky element. |
153
+ | `containerInner` | HTMLElement | The element endowed with stickiness and scrolling abilities relative to its parent. |
154
+ | `spaceBottom` | number | The space between the bottom of the viewport and the visible area. Default is 0. |
155
+ | `spaceTop` | number | The space between the top of the viewport and the visible area. Default is 0. |
156
+ | `callback` | Callback | A function called **before** changes to the ContainerInner occur. See [Callback]() |
157
+
158
+ ---
159
+
160
+ ### Callback
161
+
162
+ ```ts
163
+ type Callback = (state: State, direction: Direction, strategy: Strategy) => void;
164
+ ```
165
+
166
+ > See also: [State](#state), [Direction](#direction), [Strategy](#strategy)
167
+
168
+ ---
169
+
170
+ ### State
171
+
172
+ Defines the positioning states of the ContainerInner.
173
+
174
+ | Value | Description |
175
+ | ----- | -------------------------------------------------------------------------------------------------- |
176
+ | 0 | None: Default behavior of ContainerInner. |
177
+ | 1 | ContainerBottom: ContainerInner is affixed to the bottom of the Container. |
178
+ | 2 | ColliderTop: ContainerInner is fixed at the top of the viewport area, including SpaceTop. |
179
+ | 3 | ColliderBottom: ContainerInner is fixed at the bottom of the viewport area, including SpaceBottom. |
180
+ | 4 | TranslateY: ContainerInner is offset along the Y-axis relative to the Container. |
181
+ | 5 | Rest: Rendering is paused until the state changes. |
182
+
183
+ ---
184
+
185
+ ### Direction
186
+
187
+ Defines the direction of the viewport.
188
+
189
+ | Value | Description |
190
+ | ----- | -------------------------------------- |
191
+ | 0 | None: No movement in the viewport. |
192
+ | 1 | Down: The viewport is moving downward. |
193
+ | 2 | Up: The viewport is moving upward. |
194
+
195
+ ---
196
+
197
+ ### Strategy
198
+
199
+ Defines the sticky behavior strategy.
200
+
201
+ | Value | Description |
202
+ | ----- | ------------------------------------------------------------- |
203
+ | 0 | None: No sticky behavior is applied. |
204
+ | 1 | Both: Sticky behavior is applied on both edges of the Y-axis. |
205
+ | 2 | Top: Sticky behavior is applied only at the top edge. |
206
+
207
+ ---
208
+
209
+ ## Limitations
210
+
211
+ 1. **Container** cannot use the CSS property `padding` (must be 0).
212
+ 2. **ContainerInner** cannot use the CSS property `margin` (must be 0).
213
+
214
+ ---
215
+
216
+ ## Concept
217
+
218
+ ![Preview](./assets/concept.jpg)
219
+
220
+ > [Viewport concepts](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/CSSOM_view/Viewport_concepts) | [Viewport](https://www.w3.org/TR/CSS2/visuren.html#viewport) | [Collider](https://socs.binus.ac.id/2017/03/09/collision-detection-in-2d-part-2/)
221
+
222
+ ---
223
+
224
+ ![Strategy](./assets/strategy.jpg)
225
+
226
+ > [Strategy](#strategy)
227
+
228
+ ---
229
+
230
+ ## Links
231
+
232
+ - [DOM](https://developer.mozilla.org/en-US/docs/Glossary/DOM)
233
+ - [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)
234
+ - [dimensions of elements](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements)
235
+ - [coordinate systems](https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_view/Coordinate_systems)
236
+ - [viewport](https://developer.mozilla.org/en-US/docs/Glossary/Viewport)
237
+ - [position](https://developer.mozilla.org/en-US/docs/Web/CSS/position)
238
+ - [this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)
239
+ - [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame)
240
+ - [resizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)
241
+ - [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
242
+ - [removeEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener)
243
+
244
+ ---
245
+
246
+ ## Copyright and license
247
+
248
+ Copyright 2026 [Mikhail Prugov](https://github.com/phenomenonus). Code released under the [MIT License](./LICENSE).
249
+
250
+ Sidebarius is a lightweight JavaScript package for creating a sticky sidebar that adapts to scroll movements. This allows for dynamic interfaces with elements that stay in view as the user scrolls the page.
@@ -0,0 +1,347 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Sidebarius
5
+ * @version 1.0.0
6
+ * @link https://github.com/phenomenonus/sidebarius
7
+ * @author Mikhail Prugov
8
+ * @copyright 2026
9
+ * @license The MIT License (MIT)
10
+ */
11
+ class Sidebarius {
12
+ /**
13
+ * @param container - The {@link Prop.Container|Container} element (parent) that holds the sticky element.
14
+ * @param containerInner - The {@link Prop.ContainerInner|ContainerInner} element that will be endowed with stickiness and scrolling abilities relative to its parent (container).
15
+ * @param spaceBottom - The space between the bottom of the {@link https://developer.mozilla.org/en-US/docs/Glossary/Viewport|viewport} and the bottom of the `visible area` or `collider`. Default is 0.
16
+ * @param spaceTop - The space between the top of the {@link https://developer.mozilla.org/en-US/docs/Glossary/Viewport|viewport} and the top of the `visible area` or `collider`. Default is 0.
17
+ * @param {Callback} callback - This callback is called **before** the {@link Prop.ContainerInner|ContainerInner} changes, such as resizing, scrolling, or other layout changes.
18
+ */
19
+ constructor(container, containerInner, spaceBottom = 0, spaceTop = 0, callback = () => { }) {
20
+ var t = this;
21
+ t["d" /* Prop.Container */] = container;
22
+ t["g" /* Prop.ContainerInner */] = containerInner;
23
+ t["o" /* Prop.ListOfRules */] = { left: '', top: '', position: '', width: '', transform: '' };
24
+ t["x" /* Prop.PrevSpaceBottom */] = t["E" /* Prop.SpaceBottom */] = spaceBottom;
25
+ t["y" /* Prop.PrevSpaceTop */] = t["F" /* Prop.SpaceTop */] = spaceTop;
26
+ t["a" /* Prop.Callback */] = callback;
27
+ t["P" /* Method.Init */]();
28
+ t["J" /* Method.CalcDims */] = t["J" /* Method.CalcDims */].bind(t);
29
+ t["K" /* Method.CalcScroll */] = t["K" /* Method.CalcScroll */].bind(t);
30
+ t["U" /* Method.ResizeListener */] = t["U" /* Method.ResizeListener */].bind(t);
31
+ t["V" /* Method.ScrollListener */] = t["V" /* Method.ScrollListener */].bind(t);
32
+ t["D" /* Prop.ResizeObserver */] = new ResizeObserver(t["U" /* Method.ResizeListener */]);
33
+ }
34
+ /**
35
+ * Start sticky scrolling behavior. Use {@link stop} method to stop sticky scrolling behavior.
36
+ */
37
+ start() {
38
+ this["I" /* Method.AddListeners */](); // calls _calcDims method by default, cause is used ResizeObserver
39
+ }
40
+ /**
41
+ * Stop sticky scrolling behavior. Use {@link start} method to start sticky scrolling behavior again.
42
+ */
43
+ stop() {
44
+ var t = this;
45
+ t["R" /* Method.RemoveListeners */]();
46
+ t["P" /* Method.Init */]();
47
+ t["S" /* Method.Render */](0 /* State.None */);
48
+ }
49
+ /**
50
+ * Set the distance to the collider. It triggers re-rendering.
51
+ *
52
+ * @param {number} bottomSpace - The {@link Prop.SpaceBottom|SpaceBottom}.
53
+ * @param {number} spaceTop - The {@link Prop.SpaceTop|SpaceTop}.
54
+ */
55
+ setSpaces(bottomSpace, spaceTop) {
56
+ var s = this;
57
+ s["E" /* Prop.SpaceBottom */] = bottomSpace;
58
+ s["F" /* Prop.SpaceTop */] = spaceTop;
59
+ s["P" /* Method.Init */]();
60
+ s["U" /* Method.ResizeListener */]();
61
+ }
62
+ [("P" /* Method.Init */)]() {
63
+ var t = this;
64
+ t["b" /* Prop.ColliderHeight */] =
65
+ t["c" /* Prop.ColliderTop */] =
66
+ t["e" /* Prop.ContainerBottom */] =
67
+ t["f" /* Prop.ContainerHeight */] =
68
+ t["h" /* Prop.ContainerLeft */] =
69
+ t["i" /* Prop.ContainerTop */] =
70
+ t["j" /* Prop.ContainerWidth */] =
71
+ t["k" /* Prop.Event */] =
72
+ t["l" /* Prop.IsRunningRequest */] =
73
+ t["p" /* Prop.MaxBottomWithTranslateY */] =
74
+ t["q" /* Prop.MaxTopWithTranslateY */] =
75
+ t["r" /* Prop.MaxTranslateY */] =
76
+ t["s" /* Prop.PrevColliderTop */] =
77
+ t["t" /* Prop.PrevContainerLeft */] =
78
+ t["u" /* Prop.PrevContainerTop */] =
79
+ t["v" /* Prop.PrevContainerWidth */] =
80
+ t["w" /* Prop.PrevElementHeight */] =
81
+ t["z" /* Prop.PrevState */] =
82
+ t["A" /* Prop.PrevStrategy */] =
83
+ t["B" /* Prop.PrevViewportScrollX */] =
84
+ t["C" /* Prop.PrevViewportScrollY */] =
85
+ t["G" /* Prop.Strategy */] =
86
+ t["H" /* Prop.TranslateY */] =
87
+ 0;
88
+ }
89
+ ["U" /* Method.ResizeListener */]() {
90
+ this["k" /* Prop.Event */] = 1 /* Event.Resize */;
91
+ this["T" /* Method.Request */]();
92
+ }
93
+ ["V" /* Method.ScrollListener */]() {
94
+ if (this["k" /* Prop.Event */] === 0 /* Event.None */)
95
+ this["k" /* Prop.Event */] = 2 /* Event.Scroll */;
96
+ this["T" /* Method.Request */]();
97
+ }
98
+ ["L" /* Method.GetCoords */](element) {
99
+ const coords = { left: element.offsetLeft, top: element.offsetTop };
100
+ while ((element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent)) {
101
+ coords.top += element.offsetTop;
102
+ coords.left += element.offsetLeft;
103
+ }
104
+ return coords;
105
+ }
106
+ ["S" /* Method.Render */](state) {
107
+ var t = this;
108
+ let r = {};
109
+ if (state === 1 /* State.ContainerBottom */) {
110
+ t["H" /* Prop.TranslateY */] = t["r" /* Prop.MaxTranslateY */];
111
+ r = {
112
+ position: 'relative',
113
+ transform: `translate3d(0px, ${t["H" /* Prop.TranslateY */]}px, 0px)`,
114
+ };
115
+ }
116
+ else if (state === 3 /* State.ColliderBottom */) {
117
+ t["H" /* Prop.TranslateY */] = 0;
118
+ r = {
119
+ top: t["b" /* Prop.ColliderHeight */] + t["F" /* Prop.SpaceTop */] - t["g" /* Prop.ContainerInner */].offsetHeight + 'px',
120
+ left: t["h" /* Prop.ContainerLeft */] - window.scrollX + 'px',
121
+ position: 'fixed',
122
+ width: t["j" /* Prop.ContainerWidth */] + 'px',
123
+ };
124
+ }
125
+ else if (state === 2 /* State.ColliderTop */) {
126
+ t["H" /* Prop.TranslateY */] = 0;
127
+ r = {
128
+ left: t["h" /* Prop.ContainerLeft */] - window.scrollX + 'px',
129
+ top: t["F" /* Prop.SpaceTop */] + 'px',
130
+ position: 'fixed',
131
+ width: t["j" /* Prop.ContainerWidth */] + 'px',
132
+ };
133
+ }
134
+ else if (state === 0 /* State.None */) {
135
+ t["H" /* Prop.TranslateY */] = 0;
136
+ }
137
+ else if (state === 4 /* State.TranslateY */) {
138
+ if (t["z" /* Prop.PrevState */] === 2 /* State.ColliderTop */) {
139
+ t["H" /* Prop.TranslateY */] = t["s" /* Prop.PrevColliderTop */] - t["i" /* Prop.ContainerTop */];
140
+ }
141
+ else if (t["z" /* Prop.PrevState */] === 3 /* State.ColliderBottom */) {
142
+ t["H" /* Prop.TranslateY */] =
143
+ t["s" /* Prop.PrevColliderTop */] + t["b" /* Prop.ColliderHeight */] - t["i" /* Prop.ContainerTop */] - t["w" /* Prop.PrevElementHeight */];
144
+ }
145
+ else if (t["z" /* Prop.PrevState */] === 1 /* State.ContainerBottom */) {
146
+ t["H" /* Prop.TranslateY */] = t["r" /* Prop.MaxTranslateY */];
147
+ }
148
+ r = {
149
+ position: 'relative',
150
+ transform: `translate3d(0px, ${t["H" /* Prop.TranslateY */]}px, 0px)`,
151
+ };
152
+ }
153
+ for (const key in t["o" /* Prop.ListOfRules */]) {
154
+ t["g" /* Prop.ContainerInner */].style[key] =
155
+ r[key] ?? t["o" /* Prop.ListOfRules */][key];
156
+ }
157
+ }
158
+ ["M" /* Method.GetDirection */]() {
159
+ if (this["C" /* Prop.PrevViewportScrollY */] === window.scrollY)
160
+ return 0 /* Direction.None */;
161
+ return this["C" /* Prop.PrevViewportScrollY */] < window.scrollY ? 1 /* Direction.Down */ : 2 /* Direction.Up */;
162
+ }
163
+ ["N" /* Method.GetState */](direction) {
164
+ var t = this;
165
+ if (t["z" /* Prop.PrevState */] === 2 /* State.ColliderTop */) {
166
+ if (t["c" /* Prop.ColliderTop */] <= t["i" /* Prop.ContainerTop */]) {
167
+ return 0 /* State.None */;
168
+ }
169
+ if (t["c" /* Prop.ColliderTop */] + t["g" /* Prop.ContainerInner */].offsetHeight >= t["e" /* Prop.ContainerBottom */]) {
170
+ return 1 /* State.ContainerBottom */;
171
+ }
172
+ if (t["A" /* Prop.PrevStrategy */] === 2 /* Strategy.Top */ && t["g" /* Prop.ContainerInner */].offsetHeight > t["b" /* Prop.ColliderHeight */]) {
173
+ t["A" /* Prop.PrevStrategy */] = t["G" /* Prop.Strategy */];
174
+ return 4 /* State.TranslateY */;
175
+ }
176
+ if (t["G" /* Prop.Strategy */] === 1 /* Strategy.Both */ && direction === 1 /* Direction.Down */) {
177
+ return 4 /* State.TranslateY */;
178
+ }
179
+ // If the parent container block changes its position and etc.
180
+ if (t["B" /* Prop.PrevViewportScrollX */] !== window.scrollX ||
181
+ t["t" /* Prop.PrevContainerLeft */] !== t["h" /* Prop.ContainerLeft */] ||
182
+ t["v" /* Prop.PrevContainerWidth */] !== t["j" /* Prop.ContainerWidth */] ||
183
+ t["u" /* Prop.PrevContainerTop */] !== t["i" /* Prop.ContainerTop */] ||
184
+ t["x" /* Prop.PrevSpaceBottom */] !== t["E" /* Prop.SpaceBottom */] ||
185
+ t["y" /* Prop.PrevSpaceTop */] !== t["F" /* Prop.SpaceTop */]) {
186
+ return 2 /* State.ColliderTop */;
187
+ }
188
+ }
189
+ else if (t["z" /* Prop.PrevState */] === 3 /* State.ColliderBottom */) {
190
+ if (t["c" /* Prop.ColliderTop */] <= t["i" /* Prop.ContainerTop */]) {
191
+ return 0 /* State.None */;
192
+ }
193
+ if (t["c" /* Prop.ColliderTop */] + t["b" /* Prop.ColliderHeight */] >= t["e" /* Prop.ContainerBottom */]) {
194
+ return 1 /* State.ContainerBottom */;
195
+ }
196
+ if (t["g" /* Prop.ContainerInner */].offsetHeight <= t["b" /* Prop.ColliderHeight */]) {
197
+ return 2 /* State.ColliderTop */;
198
+ }
199
+ if (direction === 2 /* Direction.Up */ || t["w" /* Prop.PrevElementHeight */] !== t["g" /* Prop.ContainerInner */].offsetHeight) {
200
+ return 4 /* State.TranslateY */;
201
+ }
202
+ // If the parent container block changes its position and etc.
203
+ if (t["B" /* Prop.PrevViewportScrollX */] !== window.scrollX ||
204
+ t["t" /* Prop.PrevContainerLeft */] !== t["h" /* Prop.ContainerLeft */] ||
205
+ t["v" /* Prop.PrevContainerWidth */] !== t["j" /* Prop.ContainerWidth */] ||
206
+ t["u" /* Prop.PrevContainerTop */] !== t["i" /* Prop.ContainerTop */] ||
207
+ t["x" /* Prop.PrevSpaceBottom */] !== t["E" /* Prop.SpaceBottom */] ||
208
+ t["y" /* Prop.PrevSpaceTop */] !== t["F" /* Prop.SpaceTop */]) {
209
+ return 3 /* State.ColliderBottom */;
210
+ }
211
+ }
212
+ else if (t["z" /* Prop.PrevState */] === 1 /* State.ContainerBottom */) {
213
+ if (t["c" /* Prop.ColliderTop */] <= t["i" /* Prop.ContainerTop */]) {
214
+ return 0 /* State.None */;
215
+ }
216
+ if (direction === 2 /* Direction.Up */ && t["c" /* Prop.ColliderTop */] <= t["q" /* Prop.MaxTopWithTranslateY */]) {
217
+ return 2 /* State.ColliderTop */;
218
+ }
219
+ if (t["g" /* Prop.ContainerInner */].offsetHeight < t["e" /* Prop.ContainerBottom */] - t["c" /* Prop.ColliderTop */]) {
220
+ return 2 /* State.ColliderTop */;
221
+ }
222
+ if (t["v" /* Prop.PrevContainerWidth */] !== t["j" /* Prop.ContainerWidth */] ||
223
+ t["w" /* Prop.PrevElementHeight */] !== t["g" /* Prop.ContainerInner */].offsetHeight) {
224
+ return 1 /* State.ContainerBottom */;
225
+ }
226
+ }
227
+ else if (t["z" /* Prop.PrevState */] === 0 /* State.None */) {
228
+ // If the page loads with the scroll position below the bottom of the container
229
+ if (t["c" /* Prop.ColliderTop */] >= t["e" /* Prop.ContainerBottom */] ||
230
+ (t["c" /* Prop.ColliderTop */] + t["b" /* Prop.ColliderHeight */] >= t["e" /* Prop.ContainerBottom */] && t["G" /* Prop.Strategy */] !== 2 /* Strategy.Top */)) {
231
+ return 1 /* State.ContainerBottom */;
232
+ }
233
+ if (t["g" /* Prop.ContainerInner */].offsetHeight < t["b" /* Prop.ColliderHeight */] && t["c" /* Prop.ColliderTop */] >= t["i" /* Prop.ContainerTop */]) {
234
+ return 2 /* State.ColliderTop */;
235
+ }
236
+ if (t["G" /* Prop.Strategy */] === 1 /* Strategy.Both */ &&
237
+ t["c" /* Prop.ColliderTop */] + t["b" /* Prop.ColliderHeight */] >= t["p" /* Prop.MaxBottomWithTranslateY */]) {
238
+ return 3 /* State.ColliderBottom */;
239
+ }
240
+ }
241
+ else if (t["z" /* Prop.PrevState */] === 4 /* State.TranslateY */) {
242
+ if (t["f" /* Prop.ContainerHeight */] - t["H" /* Prop.TranslateY */] < t["g" /* Prop.ContainerInner */].offsetHeight) {
243
+ return 1 /* State.ContainerBottom */;
244
+ }
245
+ if (t["g" /* Prop.ContainerInner */].offsetHeight < t["b" /* Prop.ColliderHeight */] ||
246
+ t["c" /* Prop.ColliderTop */] <= t["i" /* Prop.ContainerTop */] + t["H" /* Prop.TranslateY */]) {
247
+ return 2 /* State.ColliderTop */;
248
+ }
249
+ if (t["H" /* Prop.TranslateY */] < t["r" /* Prop.MaxTranslateY */] &&
250
+ t["c" /* Prop.ColliderTop */] + t["b" /* Prop.ColliderHeight */] > t["p" /* Prop.MaxBottomWithTranslateY */] + t["H" /* Prop.TranslateY */]) {
251
+ return 3 /* State.ColliderBottom */;
252
+ }
253
+ }
254
+ return 5 /* State.Rest */;
255
+ }
256
+ ["O" /* Method.GetStrategy */]() {
257
+ var t = this;
258
+ if (t["f" /* Prop.ContainerHeight */] <= t["g" /* Prop.ContainerInner */].offsetHeight)
259
+ return 0 /* Strategy.None */;
260
+ if (t["b" /* Prop.ColliderHeight */] < t["g" /* Prop.ContainerInner */].offsetHeight)
261
+ return 1 /* Strategy.Both */;
262
+ return 2 /* Strategy.Top */;
263
+ }
264
+ ["J" /* Method.CalcDims */]() {
265
+ var t = this;
266
+ const containerCoords = t["L" /* Method.GetCoords */](t["d" /* Prop.Container */]);
267
+ t["h" /* Prop.ContainerLeft */] = containerCoords.left;
268
+ t["i" /* Prop.ContainerTop */] = containerCoords.top;
269
+ t["f" /* Prop.ContainerHeight */] = t["d" /* Prop.Container */].clientHeight;
270
+ t["e" /* Prop.ContainerBottom */] = t["i" /* Prop.ContainerTop */] + t["f" /* Prop.ContainerHeight */];
271
+ t["j" /* Prop.ContainerWidth */] = t["d" /* Prop.Container */].clientWidth;
272
+ t["b" /* Prop.ColliderHeight */] = window.innerHeight - t["F" /* Prop.SpaceTop */] - t["E" /* Prop.SpaceBottom */];
273
+ t["r" /* Prop.MaxTranslateY */] = t["d" /* Prop.Container */].clientHeight - t["g" /* Prop.ContainerInner */].offsetHeight;
274
+ t["p" /* Prop.MaxBottomWithTranslateY */] = t["i" /* Prop.ContainerTop */] + t["g" /* Prop.ContainerInner */].offsetHeight;
275
+ t["q" /* Prop.MaxTopWithTranslateY */] = t["i" /* Prop.ContainerTop */] + t["r" /* Prop.MaxTranslateY */];
276
+ t["G" /* Prop.Strategy */] = t["O" /* Method.GetStrategy */]();
277
+ if (t["G" /* Prop.Strategy */] === 0 /* Strategy.None */) {
278
+ if (t["A" /* Prop.PrevStrategy */] !== t["G" /* Prop.Strategy */])
279
+ t["S" /* Method.Render */](0 /* State.None */);
280
+ }
281
+ else {
282
+ t["K" /* Method.CalcScroll */]();
283
+ }
284
+ t["v" /* Prop.PrevContainerWidth */] = t["j" /* Prop.ContainerWidth */];
285
+ t["t" /* Prop.PrevContainerLeft */] = t["h" /* Prop.ContainerLeft */];
286
+ t["u" /* Prop.PrevContainerTop */] = t["i" /* Prop.ContainerTop */];
287
+ t["w" /* Prop.PrevElementHeight */] = t["g" /* Prop.ContainerInner */].offsetHeight;
288
+ t["A" /* Prop.PrevStrategy */] = t["G" /* Prop.Strategy */];
289
+ t["x" /* Prop.PrevSpaceBottom */] = t["E" /* Prop.SpaceBottom */];
290
+ t["y" /* Prop.PrevSpaceTop */] = t["F" /* Prop.SpaceTop */];
291
+ }
292
+ ["K" /* Method.CalcScroll */]() {
293
+ var t = this;
294
+ if (t["G" /* Prop.Strategy */] === 0 /* Strategy.None */)
295
+ return;
296
+ t["c" /* Prop.ColliderTop */] = window.scrollY + t["F" /* Prop.SpaceTop */];
297
+ const direction = t["M" /* Method.GetDirection */]();
298
+ const state = t["N" /* Method.GetState */](direction);
299
+ if (state !== 5 /* State.Rest */) {
300
+ t["a" /* Prop.Callback */](state, direction, t["G" /* Prop.Strategy */]);
301
+ t["S" /* Method.Render */](state);
302
+ t["z" /* Prop.PrevState */] = state;
303
+ }
304
+ else if (t["A" /* Prop.PrevStrategy */] !== t["G" /* Prop.Strategy */]) {
305
+ t["a" /* Prop.Callback */](state, direction, t["G" /* Prop.Strategy */]);
306
+ }
307
+ t["s" /* Prop.PrevColliderTop */] = t["c" /* Prop.ColliderTop */];
308
+ t["B" /* Prop.PrevViewportScrollX */] = window.scrollX;
309
+ t["C" /* Prop.PrevViewportScrollY */] = window.scrollY;
310
+ }
311
+ ["T" /* Method.Request */]() {
312
+ var t = this;
313
+ if (t["l" /* Prop.IsRunningRequest */] === 1)
314
+ return;
315
+ t["l" /* Prop.IsRunningRequest */] = 1;
316
+ window.requestAnimationFrame(() => {
317
+ (t["k" /* Prop.Event */] === 1 /* Event.Resize */ && t["J" /* Method.CalcDims */]()) ||
318
+ (t["k" /* Prop.Event */] === 2 /* Event.Scroll */ && t["K" /* Method.CalcScroll */]());
319
+ t["k" /* Prop.Event */] = 0 /* Event.None */;
320
+ t["l" /* Prop.IsRunningRequest */] = 0;
321
+ });
322
+ }
323
+ ["Q" /* Method.ObserveTreeNodesFromCurrentToBody */](containerInner) {
324
+ while (containerInner) {
325
+ this["D" /* Prop.ResizeObserver */].observe(containerInner);
326
+ if (containerInner.tagName === 'BODY')
327
+ break;
328
+ containerInner = containerInner.parentElement;
329
+ }
330
+ }
331
+ ["I" /* Method.AddListeners */]() {
332
+ window.addEventListener('scroll', this["V" /* Method.ScrollListener */], {
333
+ capture: false,
334
+ passive: true,
335
+ });
336
+ this["Q" /* Method.ObserveTreeNodesFromCurrentToBody */](this["g" /* Prop.ContainerInner */]);
337
+ }
338
+ ["R" /* Method.RemoveListeners */]() {
339
+ window.removeEventListener('scroll', this["V" /* Method.ScrollListener */], {
340
+ capture: false,
341
+ });
342
+ this["D" /* Prop.ResizeObserver */].disconnect();
343
+ }
344
+ }
345
+
346
+ module.exports = Sidebarius;
347
+ //# sourceMappingURL=sidebarius.cjs.js.map