Skip to content

Commit ea15d46

Browse files
committed
chore: bump version to 1.3.0 and update package metadata
feat: enhance onComplete action handling for smooth scroll links - Added parseOnCompleteAction function to handle various onComplete actions - Improved handling of click, focus, dispatch, and call actions - Integrated onComplete actions into the scrollTo method for better user experience - Ensured correct resizing of instances after scroll completion
1 parent 4b43881 commit ea15d46

5 files changed

Lines changed: 659 additions & 58 deletions

File tree

README.md

Lines changed: 198 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
![JavaScript](https://img.shields.io/badge/language-JavaScript-F7DF1E?logo=javascript)
55
[![npm version](https://img.shields.io/npm/v/%40rethink-js%2Frt-smooth-scroll.svg)](https://www.npmjs.com/package/@rethink-js/rt-smooth-scroll)
66
[![jsDelivr hits](https://data.jsdelivr.com/v1/package/npm/@rethink-js/rt-smooth-scroll/badge)](https://www.jsdelivr.com/package/npm/@rethink-js/rt-smooth-scroll)
7-
[![bundle size](https://img.shields.io/bundlephobia/min/%40rethink-js%2Frt-smooth-scroll)](https://bundlephobia.com/package/@rethink-js/rt-smooth-scroll)
87
[![License: MIT](https://img.shields.io/badge/License-MIT-FFD632.svg)](https://opensource.org/licenses/MIT)
98

109
`rt-smooth-scroll` is a lightweight JavaScript library that seamlessly integrates the **Lenis smooth scroll engine** into your sites with:
@@ -15,6 +14,7 @@
1514
- A clean global API under `window.rtSmoothScroll`
1615
- **Smart Scroll-To actions** with indexed selectors and dynamic offsets
1716
- **Automatic Anchor Link Conversion** (hijack native links for smooth scrolling)
17+
- **Scroll-To Completion Hooks** (run actions/functions after a scroll-to completes)
1818
- Per-instance configuration via HTML attributes
1919
- Console logs showing each instance’s final resolved config
2020

@@ -45,7 +45,7 @@
4545
### 1.1 CDN (jsDelivr)
4646

4747
```html
48-
<script src="[https://cdn.jsdelivr.net/npm/@rethink-js/rt-smooth-scroll@latest/dist/index.min.js](https://cdn.jsdelivr.net/npm/@rethink-js/rt-smooth-scroll@latest/dist/index.min.js)"></script>
48+
<script src="https://cdn.jsdelivr.net/npm/@rethink-js/rt-smooth-scroll@latest/dist/index.min.js"></script>
4949
```
5050

5151
### 1.2 npm
@@ -70,7 +70,7 @@ Add the script to your page. With no configuration provided, `rt-smooth-scroll`
7070
Example:
7171

7272
```html
73-
<script src="[https://cdn.jsdelivr.net/npm/@rethink-js/rt-smooth-scroll@latest/dist/index.min.js](https://cdn.jsdelivr.net/npm/@rethink-js/rt-smooth-scroll@latest/dist/index.min.js)"></script>
73+
<script src="https://cdn.jsdelivr.net/npm/@rethink-js/rt-smooth-scroll@latest/dist/index.min.js"></script>
7474
```
7575

7676
> Note: If you do not set any `rt-smooth-scroll-*` config attributes, the root instance uses **Lenis defaults**.
@@ -117,21 +117,27 @@ Important Lenis behavior:
117117

118118
**Core attributes:**
119119

120-
| Attribute | Description |
121-
| ------------------------------------------- | ------------------------------------------------------------ |
122-
| `rt-smooth-scroll-duration` | Lenis `duration` (only applies when `lerp` is not used) |
123-
| `rt-smooth-scroll-lerp` | Lenis `lerp` (0 → 1) |
124-
| `rt-smooth-scroll-orientation` | Lenis `orientation` |
125-
| `rt-smooth-scroll-gesture-orientation` | Lenis `gestureOrientation` |
126-
| `rt-smooth-scroll-normalize-wheel` | Lenis `normalizeWheel` |
127-
| `rt-smooth-scroll-wheel-multiplier` | Lenis `wheelMultiplier` |
128-
| `rt-smooth-scroll-smooth-touch` | Lenis `smoothTouch` |
129-
| `rt-smooth-scroll-sync-touch` | Lenis `syncTouch` |
130-
| `rt-smooth-scroll-sync-touch-lerp` | Lenis `syncTouchLerp` |
131-
| `rt-smooth-scroll-touch-inertia-multiplier` | Lenis `touchInertiaMultiplier` |
132-
| `rt-smooth-scroll-touch-multiplier` | Lenis `touchMultiplier` |
133-
| `rt-smooth-scroll-infinite` | Lenis `infinite` |
134-
| `rt-smooth-scroll-easing` | Named easing function (only applies when `lerp` is not used) |
120+
| Attribute | Description |
121+
| ----------------------------------------- | ------------------------------------------------------------ |
122+
| `rt-smooth-scroll-duration` | Lenis `duration` (only applies when `lerp` is not used) |
123+
| `rt-smooth-scroll-lerp` | Lenis `lerp` (0 → 1) |
124+
| `rt-smooth-scroll-orientation` | Lenis `orientation` |
125+
| `rt-smooth-scroll-gesture-orientation` | Lenis `gestureOrientation` |
126+
| `rt-smooth-scroll-normalize-wheel` | Alias of Lenis `smoothWheel` (legacy naming supported) |
127+
| `rt-smooth-scroll-smooth-wheel` | Lenis `smoothWheel` |
128+
| `rt-smooth-scroll-wheel-multiplier` | Lenis `wheelMultiplier` |
129+
| `rt-smooth-scroll-touch-multiplier` | Lenis `touchMultiplier` |
130+
| `rt-smooth-scroll-sync-touch` | Lenis `syncTouch` |
131+
| `rt-smooth-scroll-sync-touch-lerp` | Lenis `syncTouchLerp` |
132+
| `rt-smooth-scroll-touch-inertia-exponent` | Lenis `touchInertiaExponent` |
133+
| `rt-smooth-scroll-infinite` | Lenis `infinite` |
134+
| `rt-smooth-scroll-auto-resize` | Lenis `autoResize` |
135+
| `rt-smooth-scroll-overscroll` | Lenis `overscroll` |
136+
| `rt-smooth-scroll-anchors` | Lenis `anchors` (boolean or JSON) |
137+
| `rt-smooth-scroll-auto-toggle` | Lenis `autoToggle` |
138+
| `rt-smooth-scroll-allow-nested-scroll` | Lenis `allowNestedScroll` |
139+
| `rt-smooth-scroll-easing` | Named easing function (only applies when `lerp` is not used) |
140+
| `rt-smooth-scroll-options-json` | Merge additional Lenis options via JSON |
135141

136142
**Easing options included:**
137143

@@ -164,6 +170,31 @@ Add attributes to any scroll container:
164170
| `rt-smooth-scroll-id` | Optional instance identifier |
165171
| `rt-smooth-scroll-content` | Selector inside container (defaults to first child if omitted) |
166172

173+
### Advanced Selectors (wrapper/content/eventsTarget)
174+
175+
You can map Lenis DOM targets using selectors:
176+
177+
```html
178+
<body
179+
rt-smooth-scroll
180+
rt-smooth-scroll-wrapper="#page-wrapper"
181+
rt-smooth-scroll-content="#page-content"
182+
rt-smooth-scroll-events-target="#page-wrapper"
183+
></body>
184+
```
185+
186+
Or per instance:
187+
188+
```html
189+
<div
190+
rt-smooth-scroll-instance
191+
rt-smooth-scroll-id="panel"
192+
rt-smooth-scroll-wrapper="#panel-wrapper"
193+
rt-smooth-scroll-content=".panel-content"
194+
rt-smooth-scroll-events-target="#panel-wrapper"
195+
></div>
196+
```
197+
167198
---
168199

169200
## 5. Scroll-To Actions
@@ -211,6 +242,126 @@ Instead of hardcoding pixels, you can pass a selector to `rt-smooth-scroll-offse
211242
</button>
212243
```
213244

245+
### Scroll-To Completion Hooks
246+
247+
When a scroll-to finishes (including the built-in correction pass for layout shifts), you can run an action/function.
248+
249+
**Supported hook attributes:**
250+
251+
- Per-trigger: `rt-smooth-scroll-on-complete`
252+
- Global default: `rt-smooth-scroll-on-complete` on `<html>` or `<body>`
253+
254+
#### 5.1 Per-trigger completion action
255+
256+
Click an element after the scroll completes:
257+
258+
```html
259+
<a rt-smooth-scroll-to="#contact" rt-smooth-scroll-on-complete="#nav-show">
260+
Contact
261+
</a>
262+
```
263+
264+
The shorthand above treats the value as a selector and will `click()` it.
265+
266+
You can also be explicit:
267+
268+
```html
269+
<a
270+
rt-smooth-scroll-to="#contact"
271+
rt-smooth-scroll-on-complete="click:#nav-show"
272+
>
273+
Contact
274+
</a>
275+
```
276+
277+
#### 5.2 Global default completion action
278+
279+
Apply to all scroll-to triggers unless they override it:
280+
281+
```html
282+
<body rt-smooth-scroll rt-smooth-scroll-on-complete="click:#nav-show"></body>
283+
```
284+
285+
#### 5.3 Supported completion action formats
286+
287+
**1) Selector-only (defaults to click)**
288+
289+
```html
290+
<button rt-smooth-scroll-to="#x" rt-smooth-scroll-on-complete="#nav-show">
291+
Go
292+
</button>
293+
```
294+
295+
**2) Typed strings**
296+
297+
- `click:#selector`
298+
- `focus:#selector`
299+
- `dispatch:event-name` (fires `CustomEvent` on `window`)
300+
- `call:functionName` (calls `window[functionName]`)
301+
302+
Examples:
303+
304+
```html
305+
<button rt-smooth-scroll-to="#x" rt-smooth-scroll-on-complete="focus:#search">
306+
Go
307+
</button>
308+
309+
<button
310+
rt-smooth-scroll-to="#x"
311+
rt-smooth-scroll-on-complete="dispatch:rt:smooth-scroll:complete"
312+
>
313+
Go
314+
</button>
315+
316+
<button
317+
rt-smooth-scroll-to="#x"
318+
rt-smooth-scroll-on-complete="call:afterScroll"
319+
>
320+
Go
321+
</button>
322+
```
323+
324+
When using `call:functionName`, your function receives a single object:
325+
326+
```js
327+
window.afterScroll = function (ctx) {
328+
console.log("afterScroll", ctx);
329+
};
330+
```
331+
332+
`ctx` includes:
333+
334+
- `lenis` (the Lenis instance used)
335+
- `trigger` (the element that initiated the scroll)
336+
- `target` (resolved target number/element/window)
337+
- `value` (the raw `rt-smooth-scroll-to` string)
338+
- `id` (the explicit `rt-smooth-scroll-target-id` if provided)
339+
340+
**3) JSON actions (single or array)**
341+
342+
This is the most robust option for multi-step actions:
343+
344+
```html
345+
<button
346+
rt-smooth-scroll-to="#x"
347+
rt-smooth-scroll-on-complete='[
348+
{"type":"click","selector":"#nav-show"},
349+
{"type":"dispatch","name":"rt:smooth-scroll:complete","detail":{"from":"scroll-to"}}
350+
]'
351+
>
352+
Go
353+
</button>
354+
```
355+
356+
Supported JSON action types:
357+
358+
- `{ "type": "click", "selector": "#el" }`
359+
- `{ "type": "focus", "selector": "#el" }`
360+
- `{ "type": "dispatch", "name": "event-name", "detail": any }`
361+
- `{ "type": "call", "name": "functionName", "detail": any }`
362+
363+
For `dispatch` and `call`, `detail` is merged into the context under `detail`.
364+
214365
---
215366

216367
## 6. Anchor Link Conversion
@@ -230,7 +381,24 @@ Add this attribute to your `<body>` or `<html>` tag:
230381
1. **Auto-Detection:** Finds all links pointing to a hash on the current page.
231382
2. **Hijacking:** Converts them to use the `rt-smooth-scroll-to` logic.
232383
3. **Clean URLs:** Removes the `href` attribute so the browser URL bar does **not** update (no `#hash` in URL), keeping your history clean.
233-
4. **Accessibility:** Automatically restores `tabindex="0"`, `role="button"`, `cursor: pointer`, and keyboard `Enter` key support.
384+
4. **Accessibility:** Automatically restores `tabindex="0"`, `role="button"`, `cursor: pointer`, and keyboard `Enter` / `Space` key support.
385+
386+
### Anchor link completion hook (auto-injected)
387+
388+
You can automatically attach a completion hook to every converted anchor link:
389+
390+
```html
391+
<body
392+
rt-smooth-scroll
393+
rt-smooth-scroll-anchor-links="true"
394+
rt-smooth-scroll-anchor-links-on-complete="click:#nav-show"
395+
></body>
396+
```
397+
398+
Rules:
399+
400+
- If a link already has `rt-smooth-scroll-on-complete`, it is not overridden.
401+
- If `rt-smooth-scroll-anchor-links-on-complete` exists, it is copied into each converted link as `rt-smooth-scroll-on-complete`.
234402

235403
---
236404

@@ -297,18 +465,23 @@ This helps you confirm exactly what configuration is applied in the browser.
297465

298466
Lenis treats `duration` and `easing` as **useless if `lerp` is defined**. If you want time-based behavior, ensure you’re not effectively running in lerp-mode.
299467

468+
### My `rt-smooth-scroll-on-complete` didn’t run
469+
470+
Common causes:
471+
472+
- The selector/function name is wrong or not available at runtime.
473+
- Your completion hook depends on DOM that’s not yet mounted/visible.
474+
- If you are using `call:fnName`, ensure `window.fnName` exists before the scroll completes.
475+
- If you are using JSON, ensure it is valid JSON (double quotes, no trailing commas).
476+
300477
---
301478

302479
## 11. License
303480

304481
MIT License
305482

306-
Package: `@rethink-js/rt-smooth-scroll`
307-
<br>
483+
Package: `@rethink-js/rt-smooth-scroll` <br>
308484
GitHub: [https://github.com/Rethink-JS/rt-smooth-scroll](https://github.com/Rethink-JS/rt-smooth-scroll)
309485

310-
---
311-
312-
by **Rethink JS**
313-
<br>
486+
by **Rethink JS** <br>
314487
[https://github.com/Rethink-JS](https://github.com/Rethink-JS)

0 commit comments

Comments
 (0)