@refokus-agency/navigation 1.0.2
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 +21 -0
- package/README.md +233 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/nav-anim/config.d.ts +12 -0
- package/dist/nav-anim/config.js +13 -0
- package/dist/nav-anim/index.d.ts +10 -0
- package/dist/nav-anim/index.js +25 -0
- package/dist/nav-anim/initial-animation.d.ts +14 -0
- package/dist/nav-anim/initial-animation.js +26 -0
- package/dist/nav-anim/scroll-behaviour.d.ts +9 -0
- package/dist/nav-anim/scroll-behaviour.js +83 -0
- package/dist/navigation.browser.js +74 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 YOUR_NAME_HERE
|
|
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,233 @@
|
|
|
1
|
+
# @refokus-agency/navigation
|
|
2
|
+
|
|
3
|
+
A TypeScript package for implementing smooth navbar animations with GSAP, featuring scroll-based show/hide behavior and customizable animation settings.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- โจ Smooth GSAP-powered animations
|
|
8
|
+
- ๐ Scroll-based navbar show/hide behavior
|
|
9
|
+
- โ๏ธ Configurable animation settings
|
|
10
|
+
- ๐ฏ Attribute-based element selection
|
|
11
|
+
- ๐ฆ ES Module-only package (no CommonJS support)
|
|
12
|
+
- ๐ง Modern TypeScript configuration with strict mode
|
|
13
|
+
- ๐งช Testing setup with Vitest
|
|
14
|
+
- ๐จ Code formatting with Prettier
|
|
15
|
+
- ๐ Linting with ESLint (flat config)
|
|
16
|
+
- ๐๏ธ Build pipeline with TypeScript compiler
|
|
17
|
+
- ๐ Source maps for debugging
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- Node.js >= 22.0.0
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @refokus-agency/navigation
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Basic Setup
|
|
32
|
+
|
|
33
|
+
1. Add the `r-navbar` attribute to your navbar element(s):
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<nav r-navbar>
|
|
37
|
+
<!-- Your navbar content -->
|
|
38
|
+
</nav>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. Initialize the navbar animation system:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { initNavbarAnimation } from '@refokus-agency/navigation';
|
|
45
|
+
|
|
46
|
+
// Initialize with custom options
|
|
47
|
+
const success = initNavbarAnimation({
|
|
48
|
+
animationDuration: 0.3,
|
|
49
|
+
animationEasing: 'power2.inOut',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (success) {
|
|
53
|
+
console.log('Navbar animation initialized');
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### How It Works
|
|
58
|
+
|
|
59
|
+
- **Initial Animation**: Navbar slides in smoothly on page load
|
|
60
|
+
- **Scroll Down**: Navbar hides when scrolling down past threshold (50px)
|
|
61
|
+
- **Scroll Up**: Navbar shows when scrolling up
|
|
62
|
+
- **Multiple Navbars**: Supports multiple navbar elements with the same attribute
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
### Available Scripts
|
|
67
|
+
|
|
68
|
+
#### Building
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm run build # Compile TypeScript
|
|
72
|
+
npm run build:clean # Clean and rebuild
|
|
73
|
+
npm run build:watch # Watch mode
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Testing
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm test # Run tests
|
|
80
|
+
npm run test:watch # Watch mode
|
|
81
|
+
npm run test:coverage # With coverage
|
|
82
|
+
npm run test:ui # With UI
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Code Quality
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm run check-types # Type checking
|
|
89
|
+
npm run lint # Lint and fix
|
|
90
|
+
npm run format # Format code
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Project Structure
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
src/
|
|
97
|
+
โโโ index.ts # Main entry point
|
|
98
|
+
โโโ nav-anim/
|
|
99
|
+
โโโ index.ts # Navbar animation initialization
|
|
100
|
+
โโโ config.ts # Configuration constants
|
|
101
|
+
โโโ initial-animation.ts # Initial slide-in animation
|
|
102
|
+
โโโ scroll-behaviour.ts # Scroll-based show/hide logic
|
|
103
|
+
โโโ __tests__/
|
|
104
|
+
โโโ index.test.ts # Initialization tests
|
|
105
|
+
โโโ scroll-behaviour.test.ts # Scroll behavior tests
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
The package uses the following default configuration:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
{
|
|
114
|
+
position: {
|
|
115
|
+
hidden: '-100%', // Y position when hidden
|
|
116
|
+
visible: '0%' // Y position when visible
|
|
117
|
+
},
|
|
118
|
+
scroll: {
|
|
119
|
+
threshold: 50 // Minimum scroll distance to trigger animation
|
|
120
|
+
},
|
|
121
|
+
selectors: {
|
|
122
|
+
navbar: '[r-navbar]' // Attribute selector for navbar elements
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Publishing
|
|
128
|
+
|
|
129
|
+
This package uses automated semantic versioning and publishing through GitHub Actions. The release process is triggered automatically on pushes to the `main` branch (or manually via the **Release** workflow's `workflow_dispatch`) and publishes to the **public npm registry** (`registry.npmjs.org`) under the `@refokus-agency` scope.
|
|
130
|
+
|
|
131
|
+
### Release Process
|
|
132
|
+
|
|
133
|
+
The publishing workflow (`.github/workflows/main-release.yml`, named **Release**) calls the `refokus-agency/platform` reusable workflows (`ci.yml` then `release.yml`) and handles:
|
|
134
|
+
|
|
135
|
+
1. **Automatic Triggering**: Release checks run on push to the `main` branch.
|
|
136
|
+
|
|
137
|
+
2. **Authentication**: Publishing to npm uses **OIDC Trusted Publishing** โ there is **no `NPM_TOKEN`** secret. The caller grants `permissions: id-token: write`, which lets npm mint a short-lived credential at publish time. For this to work, a **Trusted Publisher** must be configured for `@refokus-agency/navigation` on [npmjs.com](https://docs.npmjs.com/trusted-publishers) (Package settings โ Trusted Publisher), pointing at this repository (`refokus-agency/navigation`) with the **workflow filename `release.yml`**. Note: `release.yml` is the **reusable workflow in the `refokus-agency/platform` repo** โ *not* a file in this repo (this repo only has `main-release.yml`). npm matches the OIDC token's `job_workflow_ref` claim, which for a reusable workflow resolves to the reusable's path, so enter exactly `release.yml`.
|
|
138
|
+
|
|
139
|
+
### Semantic Versioning
|
|
140
|
+
|
|
141
|
+
> **โ ๏ธ WARNING:**
|
|
142
|
+
> This repository uses automated semantic versioning and publishing.
|
|
143
|
+
> **Do not publish manually with `npm publish`.**
|
|
144
|
+
> All releases are handled by GitHub Actions via semantic-release.
|
|
145
|
+
>
|
|
146
|
+
> To trigger a release, push to the `main` branch or use the GitHub Actions workflow manually.
|
|
147
|
+
>
|
|
148
|
+
> Ensure your commits follow [Conventional Commits](https://www.conventionalcommits.org/) to enable correct versioning and changelog generation.
|
|
149
|
+
> In order to do that, you MUST run `npm run commit` to use the Commitizen wizard and stay compliant with our versioning standards.
|
|
150
|
+
|
|
151
|
+
The project uses [semantic-release](https://semantic-release.gitbook.io/) for automated version management based on conventional commits:
|
|
152
|
+
|
|
153
|
+
- **Major version** (`x.0.0`): Breaking changes (commits with `BREAKING CHANGE:` or `!:`)
|
|
154
|
+
- **Minor version** (`0.x.0`): New features (commits with `feat:`)
|
|
155
|
+
- **Patch version** (`0.0.x`): Bug fixes (commits with `fix:`)
|
|
156
|
+
|
|
157
|
+
### Commit Message Format
|
|
158
|
+
|
|
159
|
+
Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Feature
|
|
163
|
+
feat: add new functionality
|
|
164
|
+
|
|
165
|
+
# Bug fix
|
|
166
|
+
fix: resolve issue with feature
|
|
167
|
+
|
|
168
|
+
# Breaking change
|
|
169
|
+
feat!: remove deprecated API
|
|
170
|
+
# or
|
|
171
|
+
feat: add new API
|
|
172
|
+
BREAKING CHANGE: old API has been removed
|
|
173
|
+
|
|
174
|
+
# Documentation
|
|
175
|
+
docs: update README
|
|
176
|
+
|
|
177
|
+
# Style changes
|
|
178
|
+
style: format code
|
|
179
|
+
|
|
180
|
+
# Refactoring
|
|
181
|
+
refactor: restructure code
|
|
182
|
+
|
|
183
|
+
# Performance
|
|
184
|
+
perf: improve performance
|
|
185
|
+
|
|
186
|
+
# Tests
|
|
187
|
+
test: add unit tests
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Publishing to public npm
|
|
191
|
+
|
|
192
|
+
The package is published to the **public npm registry** under the `@refokus-agency` scope, so consumers can `npm install @refokus-agency/navigation` with no auth or registry configuration. The release:
|
|
193
|
+
|
|
194
|
+
- Targets the public npm registry (`https://registry.npmjs.org`) via `publishConfig`
|
|
195
|
+
- Publishes as a **public** scoped package (`access: public`)
|
|
196
|
+
- Authenticates with **OIDC Trusted Publishing** โ no `NPM_TOKEN` secret; the workflow requires `id-token: write`
|
|
197
|
+
- Keeps npm **provenance disabled** because the repository is currently private (provenance requires a public repo). When the repo is made public, flip `provenance: true` on the `release.yml` caller to enable signed provenance
|
|
198
|
+
|
|
199
|
+
> **Peer dependency:** `gsap` is a **peer dependency** and is not bundled. Consumers must install it themselves (`npm install gsap`), or provide it globally as Webflow/CDN setups already do.
|
|
200
|
+
|
|
201
|
+
### Manual Release
|
|
202
|
+
|
|
203
|
+
To trigger a release manually:
|
|
204
|
+
|
|
205
|
+
1. Go to the GitHub repository
|
|
206
|
+
2. Navigate to the **Actions** tab
|
|
207
|
+
3. Select the **Release** workflow
|
|
208
|
+
4. Click **Run workflow**
|
|
209
|
+
5. Choose the branch (usually `main`)
|
|
210
|
+
6. Click **Run workflow**
|
|
211
|
+
|
|
212
|
+
### Prerequisites
|
|
213
|
+
|
|
214
|
+
Before publishing, ensure:
|
|
215
|
+
|
|
216
|
+
- All tests pass (`npm test`)
|
|
217
|
+
- Code is properly formatted (`npm run format`)
|
|
218
|
+
- Linting passes (`npm run lint`)
|
|
219
|
+
- Type checking passes (`npm run check-types`)
|
|
220
|
+
- Commit messages follow conventional commits format
|
|
221
|
+
|
|
222
|
+
### Release Notes
|
|
223
|
+
|
|
224
|
+
Semantic-release automatically:
|
|
225
|
+
|
|
226
|
+
- Generates changelog based on commit messages
|
|
227
|
+
- Creates GitHub releases with release notes
|
|
228
|
+
- Tags releases in Git
|
|
229
|
+
- Updates package version in `package.json`
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
See [LICENSE](LICENSE) file.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { initNavbarAnimation, type InitNavbarAnimationOptions, } from './nav-anim/index.ts';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type NavbarAnimationOptions = {
|
|
2
|
+
animationDuration: number;
|
|
3
|
+
animationEasing: string;
|
|
4
|
+
};
|
|
5
|
+
export type InitNavbarAnimationOptions = Partial<NavbarAnimationOptions>;
|
|
6
|
+
/**
|
|
7
|
+
* Initializes navbar animation system
|
|
8
|
+
* @returns Whether initialization was successful
|
|
9
|
+
*/
|
|
10
|
+
export declare function initNavbarAnimation(options?: InitNavbarAnimationOptions): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { NAVBAR_CONFIG } from "./config.js";
|
|
2
|
+
import { performInitialAnimation } from "./initial-animation.js";
|
|
3
|
+
import { initScrollBehavior } from "./scroll-behaviour.js";
|
|
4
|
+
const DEFAULT_OPTIONS = {
|
|
5
|
+
animationDuration: 0.3,
|
|
6
|
+
animationEasing: 'power2.inOut',
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Initializes navbar animation system
|
|
10
|
+
* @returns Whether initialization was successful
|
|
11
|
+
*/
|
|
12
|
+
export function initNavbarAnimation(options = {}) {
|
|
13
|
+
const navbarElements = document.querySelectorAll(NAVBAR_CONFIG.selectors.navbar);
|
|
14
|
+
if (!navbarElements.length)
|
|
15
|
+
return false;
|
|
16
|
+
const resolvedOptions = {
|
|
17
|
+
...DEFAULT_OPTIONS,
|
|
18
|
+
...options,
|
|
19
|
+
};
|
|
20
|
+
const elements = Array.from(navbarElements);
|
|
21
|
+
performInitialAnimation(elements, resolvedOptions);
|
|
22
|
+
initScrollBehavior(elements, resolvedOptions);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NavbarAnimationOptions } from './index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Creates navbar slide animation
|
|
4
|
+
* @param elements - Navbar elements to animate
|
|
5
|
+
* @param targetY - Target Y position
|
|
6
|
+
* @returns GSAP tween instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function createNavbarAnimation(elements: Element[], targetY: string, options: NavbarAnimationOptions): gsap.core.Tween;
|
|
9
|
+
/**
|
|
10
|
+
* Performs initial navbar slide-in animation
|
|
11
|
+
* @param navbarElements - Navbar elements to animate
|
|
12
|
+
* @param options - Animation options
|
|
13
|
+
*/
|
|
14
|
+
export declare function performInitialAnimation(navbarElements: Element[], options: NavbarAnimationOptions): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { gsap } from 'gsap';
|
|
2
|
+
import { NAVBAR_CONFIG } from "./config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates navbar slide animation
|
|
5
|
+
* @param elements - Navbar elements to animate
|
|
6
|
+
* @param targetY - Target Y position
|
|
7
|
+
* @returns GSAP tween instance
|
|
8
|
+
*/
|
|
9
|
+
export function createNavbarAnimation(elements, targetY, options) {
|
|
10
|
+
return gsap.to(elements, {
|
|
11
|
+
y: targetY,
|
|
12
|
+
duration: options.animationDuration,
|
|
13
|
+
ease: options.animationEasing,
|
|
14
|
+
overwrite: true,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Performs initial navbar slide-in animation
|
|
19
|
+
* @param navbarElements - Navbar elements to animate
|
|
20
|
+
* @param options - Animation options
|
|
21
|
+
*/
|
|
22
|
+
export function performInitialAnimation(navbarElements, options) {
|
|
23
|
+
gsap.set(navbarElements, { y: NAVBAR_CONFIG.position.hidden });
|
|
24
|
+
createNavbarAnimation(navbarElements, NAVBAR_CONFIG.position.visible, options);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=initial-animation.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NavbarAnimationOptions } from './index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Removes scroll event listener for cleanup
|
|
4
|
+
*/
|
|
5
|
+
export declare function cleanupNavbarAnimation(): void;
|
|
6
|
+
/**
|
|
7
|
+
* Initializes navbar scroll behavior
|
|
8
|
+
*/
|
|
9
|
+
export declare function initScrollBehavior(elements: Element[], options: NavbarAnimationOptions): void;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { NAVBAR_CONFIG } from "./config.js";
|
|
2
|
+
import { createNavbarAnimation } from "./initial-animation.js";
|
|
3
|
+
let lastScrollY = 0;
|
|
4
|
+
let isNavbarVisible = true;
|
|
5
|
+
let scrollHandlerBound = null;
|
|
6
|
+
let currentOptions = null;
|
|
7
|
+
let navbarElements = [];
|
|
8
|
+
/**
|
|
9
|
+
* Shows the navbar by sliding it down
|
|
10
|
+
*/
|
|
11
|
+
function showNavbar() {
|
|
12
|
+
if (isNavbarVisible || navbarElements.length === 0 || !currentOptions)
|
|
13
|
+
return;
|
|
14
|
+
createNavbarAnimation(navbarElements, NAVBAR_CONFIG.position.visible, currentOptions);
|
|
15
|
+
isNavbarVisible = true;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Hides the navbar by sliding it up
|
|
19
|
+
*/
|
|
20
|
+
function hideNavbar() {
|
|
21
|
+
if (!isNavbarVisible || navbarElements.length === 0 || !currentOptions)
|
|
22
|
+
return;
|
|
23
|
+
createNavbarAnimation(navbarElements, NAVBAR_CONFIG.position.hidden, currentOptions);
|
|
24
|
+
isNavbarVisible = false;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Determines if scroll distance is significant enough to trigger animation
|
|
28
|
+
* @param currentScrollY - Current scroll position
|
|
29
|
+
* @returns Whether scroll is significant
|
|
30
|
+
*/
|
|
31
|
+
function isSignificantScroll(currentScrollY) {
|
|
32
|
+
return (Math.abs(currentScrollY - lastScrollY) >= NAVBAR_CONFIG.scroll.threshold);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Determines if user is scrolling down past threshold
|
|
36
|
+
* @param currentScrollY - Current scroll position
|
|
37
|
+
* @returns Whether user is scrolling down past threshold
|
|
38
|
+
*/
|
|
39
|
+
function isScrollingDownPastThreshold(currentScrollY) {
|
|
40
|
+
return (currentScrollY > lastScrollY &&
|
|
41
|
+
currentScrollY > NAVBAR_CONFIG.scroll.threshold);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Handles scroll events to show/hide navbar based on direction
|
|
45
|
+
*/
|
|
46
|
+
function handleScroll() {
|
|
47
|
+
const currentScrollY = window.scrollY;
|
|
48
|
+
if (!isSignificantScroll(currentScrollY))
|
|
49
|
+
return;
|
|
50
|
+
if (isScrollingDownPastThreshold(currentScrollY)) {
|
|
51
|
+
hideNavbar();
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
showNavbar();
|
|
55
|
+
}
|
|
56
|
+
lastScrollY = currentScrollY;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Removes scroll event listener for cleanup
|
|
60
|
+
*/
|
|
61
|
+
export function cleanupNavbarAnimation() {
|
|
62
|
+
if (scrollHandlerBound) {
|
|
63
|
+
window.removeEventListener('scroll', scrollHandlerBound);
|
|
64
|
+
scrollHandlerBound = null;
|
|
65
|
+
}
|
|
66
|
+
navbarElements = [];
|
|
67
|
+
currentOptions = null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Initializes navbar scroll behavior
|
|
71
|
+
*/
|
|
72
|
+
export function initScrollBehavior(elements, options) {
|
|
73
|
+
if (scrollHandlerBound) {
|
|
74
|
+
window.removeEventListener('scroll', scrollHandlerBound);
|
|
75
|
+
}
|
|
76
|
+
currentOptions = options;
|
|
77
|
+
navbarElements = elements;
|
|
78
|
+
isNavbarVisible = true;
|
|
79
|
+
lastScrollY = window.scrollY;
|
|
80
|
+
scrollHandlerBound = handleScroll;
|
|
81
|
+
window.addEventListener('scroll', scrollHandlerBound, { passive: true });
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=scroll-behaviour.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { gsap as d } from "gsap";
|
|
2
|
+
const t = {
|
|
3
|
+
position: {
|
|
4
|
+
hidden: "-100%",
|
|
5
|
+
visible: "0%"
|
|
6
|
+
},
|
|
7
|
+
scroll: {
|
|
8
|
+
threshold: 50
|
|
9
|
+
},
|
|
10
|
+
selectors: {
|
|
11
|
+
navbar: "[r-navbar]"
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function c(n, i, e) {
|
|
15
|
+
return d.to(n, {
|
|
16
|
+
y: i,
|
|
17
|
+
duration: e.animationDuration,
|
|
18
|
+
ease: e.animationEasing,
|
|
19
|
+
overwrite: !0
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function f(n, i) {
|
|
23
|
+
d.set(n, { y: t.position.hidden }), c(
|
|
24
|
+
n,
|
|
25
|
+
t.position.visible,
|
|
26
|
+
i
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
let a = 0, r = !0, s = null, o = null, l = [];
|
|
30
|
+
function h() {
|
|
31
|
+
r || l.length === 0 || !o || (c(
|
|
32
|
+
l,
|
|
33
|
+
t.position.visible,
|
|
34
|
+
o
|
|
35
|
+
), r = !0);
|
|
36
|
+
}
|
|
37
|
+
function v() {
|
|
38
|
+
!r || l.length === 0 || !o || (c(
|
|
39
|
+
l,
|
|
40
|
+
t.position.hidden,
|
|
41
|
+
o
|
|
42
|
+
), r = !1);
|
|
43
|
+
}
|
|
44
|
+
function m(n) {
|
|
45
|
+
return Math.abs(n - a) >= t.scroll.threshold;
|
|
46
|
+
}
|
|
47
|
+
function b(n) {
|
|
48
|
+
return n > a && n > t.scroll.threshold;
|
|
49
|
+
}
|
|
50
|
+
function p() {
|
|
51
|
+
const n = window.scrollY;
|
|
52
|
+
m(n) && (b(n) ? v() : h(), a = n);
|
|
53
|
+
}
|
|
54
|
+
function w(n, i) {
|
|
55
|
+
s && window.removeEventListener("scroll", s), o = i, l = n, r = !0, a = window.scrollY, s = p, window.addEventListener("scroll", s, { passive: !0 });
|
|
56
|
+
}
|
|
57
|
+
const g = {
|
|
58
|
+
animationDuration: 0.3,
|
|
59
|
+
animationEasing: "power2.inOut"
|
|
60
|
+
};
|
|
61
|
+
function N(n = {}) {
|
|
62
|
+
const i = document.querySelectorAll(
|
|
63
|
+
t.selectors.navbar
|
|
64
|
+
);
|
|
65
|
+
if (!i.length) return !1;
|
|
66
|
+
const e = {
|
|
67
|
+
...g,
|
|
68
|
+
...n
|
|
69
|
+
}, u = Array.from(i);
|
|
70
|
+
return f(u, e), w(u, e), !0;
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
N as initNavbarAnimation
|
|
74
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@refokus-agency/navigation",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A TypeScript package for GSAP-powered navbar animations with scroll-based show/hide behavior",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/**/*",
|
|
17
|
+
"!dist/**/*.map",
|
|
18
|
+
"!dist/**/__tests__/**",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"author": "Refokus Agency",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"navbar",
|
|
25
|
+
"animation",
|
|
26
|
+
"gsap",
|
|
27
|
+
"scroll",
|
|
28
|
+
"typescript",
|
|
29
|
+
"webflow"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/refokus-agency/navigation.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/refokus-agency/navigation/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/refokus-agency/navigation#readme",
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc && npm run build:browser",
|
|
41
|
+
"build:browser": "vite build",
|
|
42
|
+
"build:clean": "rimraf dist && npm run build",
|
|
43
|
+
"build:watch": "tsc --watch",
|
|
44
|
+
"prepublishOnly": "npm run check-types && npm run lint && npm run build:clean",
|
|
45
|
+
"check-types": "tsc --noEmit --strict --skipLibCheck",
|
|
46
|
+
"typecheck": "tsc --noEmit --strict --skipLibCheck",
|
|
47
|
+
"lint": "eslint src --ext .ts --fix",
|
|
48
|
+
"lint:report": "eslint src --ext .ts",
|
|
49
|
+
"format": "prettier --write \"src/**/*.{ts,js,json}\"",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"test:coverage": "vitest run --coverage",
|
|
53
|
+
"test:ui": "vitest --ui",
|
|
54
|
+
"commit": "cz"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"gsap": "^3.14.2"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/js": "^9.39.4",
|
|
61
|
+
"@total-typescript/tsconfig": "^1.0.4",
|
|
62
|
+
"@types/node": "^25.5.0",
|
|
63
|
+
"@types/webidl-conversions": "^7.0.3",
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
|
65
|
+
"@typescript-eslint/parser": "^8.57.0",
|
|
66
|
+
"@vitest/ui": "^3.2.4",
|
|
67
|
+
"commitizen": "^4.3.1",
|
|
68
|
+
"cz-conventional-changelog": "3.3.0",
|
|
69
|
+
"eslint": "^10.0.3",
|
|
70
|
+
"eslint-config-prettier": "^10.1.8",
|
|
71
|
+
"eslint-plugin-n": "^17.21.0",
|
|
72
|
+
"gsap": "^3.14.2",
|
|
73
|
+
"jsdom": "^29.0.0",
|
|
74
|
+
"prettier": "^3.6.2",
|
|
75
|
+
"rimraf": "^6.1.3",
|
|
76
|
+
"typescript": "^5.8.3",
|
|
77
|
+
"vite": "^7.3.1",
|
|
78
|
+
"vitest": "^3.2.4"
|
|
79
|
+
},
|
|
80
|
+
"engines": {
|
|
81
|
+
"node": ">=22.0.0"
|
|
82
|
+
},
|
|
83
|
+
"publishConfig": {
|
|
84
|
+
"registry": "https://registry.npmjs.org",
|
|
85
|
+
"access": "public"
|
|
86
|
+
}
|
|
87
|
+
}
|