├── .npmrc ├── playground ├── tsconfig.json ├── server │ └── tsconfig.json ├── nuxt.config.ts ├── package.json ├── pages │ ├── index.vue │ └── horizontal-scroll.vue └── app.vue ├── .vscode └── settings.json ├── test ├── fixtures │ └── basic │ │ ├── package.json │ │ ├── app.vue │ │ └── nuxt.config.ts └── basic.test.ts ├── tsconfig.json ├── src ├── runtime │ ├── locomotive.ts │ └── locomotive.client.ts └── module.ts ├── .editorconfig ├── CHANGELOG.md ├── eslint.config.mjs ├── .gitignore ├── package.json └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.experimental.useFlatConfig": true 3 | } 4 | -------------------------------------------------------------------------------- /playground/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "basic", 4 | "type": "module" 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/app.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /playground/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | modules: ['../src/module'], 3 | devtools: { enabled: true }, 4 | }) 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json", 3 | "exclude": [ 4 | "dist", 5 | "node_modules", 6 | "playground", 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /src/runtime/locomotive.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtPlugin } from '#app' 2 | 3 | export default defineNuxtPlugin(({ vueApp }) => { 4 | vueApp.directive('locomotive', {}) 5 | }) 6 | -------------------------------------------------------------------------------- /test/fixtures/basic/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import MyModule from '../../../src/module' 2 | 3 | export default defineNuxtConfig({ 4 | modules: [ 5 | MyModule, 6 | ], 7 | }) 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 2 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "nuxt-locomotive-scroll-playground", 4 | "type": "module", 5 | "scripts": { 6 | "dev": "nuxi dev", 7 | "build": "nuxi build", 8 | "generate": "nuxi generate" 9 | }, 10 | "dependencies": { 11 | "nuxt": "^3.11.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | ## v0.0.1 5 | 6 | 7 | ### 🩹 Fixes 8 | 9 | - Tsconfig path ([d96f90d](https://github.com/arashsheyda/nuxt-locomotive-scroll/commit/d96f90d)) 10 | 11 | ### 🏡 Chore 12 | 13 | - Update readme ([82f3fe5](https://github.com/arashsheyda/nuxt-locomotive-scroll/commit/82f3fe5)) 14 | 15 | ### ❤️ Contributors 16 | 17 | - Arash 18 | 19 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { createConfigForNuxt } from '@nuxt/eslint-config/flat' 3 | 4 | // Run `npx @eslint/config-inspector` to inspect the resolved config interactively 5 | export default createConfigForNuxt({ 6 | features: { 7 | // Rules for module authors 8 | tooling: true, 9 | // Rules for formatting 10 | stylistic: true, 11 | }, 12 | dirs: { 13 | src: [ 14 | './playground', 15 | ], 16 | }, 17 | }) 18 | .append( 19 | // your custom flat config here... 20 | ) 21 | -------------------------------------------------------------------------------- /test/basic.test.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { describe, it, expect } from 'vitest' 3 | import { setup, $fetch } from '@nuxt/test-utils/e2e' 4 | 5 | describe('ssr', async () => { 6 | await setup({ 7 | rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)), 8 | }) 9 | 10 | it('renders the index page', async () => { 11 | // Get response to a server-rendered page with `$fetch`. 12 | const html = await $fetch('/') 13 | expect(html).toContain('
basic
') 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | 4 | # Logs 5 | *.log* 6 | 7 | # Temp directories 8 | .temp 9 | .tmp 10 | .cache 11 | 12 | # Yarn 13 | **/.yarn/cache 14 | **/.yarn/*state* 15 | 16 | # Generated dirs 17 | dist 18 | 19 | # Nuxt 20 | .nuxt 21 | .output 22 | .data 23 | .vercel_build_output 24 | .build-* 25 | .netlify 26 | 27 | # Env 28 | .env 29 | 30 | # Testing 31 | reports 32 | coverage 33 | *.lcov 34 | .nyc_output 35 | 36 | # VSCode 37 | .vscode/* 38 | !.vscode/settings.json 39 | !.vscode/tasks.json 40 | !.vscode/launch.json 41 | !.vscode/extensions.json 42 | !.vscode/*.code-snippets 43 | 44 | # Intellij idea 45 | *.iml 46 | .idea 47 | 48 | # OSX 49 | .DS_Store 50 | .AppleDouble 51 | .LSOverride 52 | .AppleDB 53 | .AppleDesktop 54 | Network Trash Folder 55 | Temporary Items 56 | .apdisk 57 | -------------------------------------------------------------------------------- /src/module.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit' 2 | 3 | // Module options TypeScript interface definition 4 | export interface ModuleOptions {} 5 | 6 | export default defineNuxtModule({ 7 | meta: { 8 | name: 'nuxt-locomotive-scroll', 9 | configKey: 'locomotive', 10 | }, 11 | // Default configuration options of the Nuxt module 12 | defaults: {}, 13 | setup(_options, _nuxt) { 14 | const { resolve } = createResolver(import.meta.url) 15 | 16 | addPlugin({ 17 | src: resolve('runtime/locomotive.client'), 18 | name: 'locomotive-scroll', 19 | mode: 'client', 20 | }) 21 | 22 | // to resolve "ERROR [worker] Cannot read properties of undefined (reading 'getSSRProps')" error 23 | addPlugin({ 24 | src: resolve('runtime/locomotive'), 25 | name: 'locomotive-scroll', 26 | mode: 'server', 27 | }) 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /src/runtime/locomotive.client.ts: -------------------------------------------------------------------------------- 1 | import LocomotiveScroll from 'locomotive-scroll' 2 | import 'locomotive-scroll/dist/locomotive-scroll.css' 3 | import type { InstanceOptions } from 'locomotive-scroll' 4 | 5 | import { defineNuxtPlugin } from 'nuxt/app' 6 | 7 | export default defineNuxtPlugin({ 8 | name: 'locomotive-scroll', 9 | setup({ vueApp }) { 10 | vueApp.directive('locomotive', { 11 | mounted(el, binding) { 12 | const scroll = new LocomotiveScroll({ 13 | el: el, 14 | smooth: true, 15 | ...binding.value, 16 | }) 17 | 18 | el.locomotive = scroll 19 | }, 20 | beforeUnmount(el) { 21 | el.locomotive.destroy() 22 | el.locomotive = undefined 23 | }, 24 | }) 25 | }, 26 | }) 27 | 28 | declare module '@vue/runtime-core' { 29 | interface GlobalDirective { 30 | locomotive: Directive 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /playground/pages/index.vue: -------------------------------------------------------------------------------- 1 | 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-locomotive-scroll", 3 | "version": "0.0.1", 4 | "description": "A Nuxt module to easily integrate Locomotive Scroll into your Nuxt application.", 5 | "repository": "arashsheyda/nuxt-locomotive-scroll", 6 | "license": "MIT", 7 | "type": "module", 8 | "exports": { 9 | ".": { 10 | "types": "./dist/types.d.ts", 11 | "import": "./dist/module.mjs", 12 | "require": "./dist/module.cjs" 13 | } 14 | }, 15 | "main": "./dist/module.cjs", 16 | "types": "./dist/types.d.ts", 17 | "files": [ 18 | "dist" 19 | ], 20 | "scripts": { 21 | "prepack": "nuxt-module-build build", 22 | "dev": "nuxi dev playground", 23 | "dev:build": "nuxi build playground", 24 | "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground", 25 | "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags", 26 | "lint": "eslint .", 27 | "test": "vitest run", 28 | "test:watch": "vitest watch", 29 | "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit" 30 | }, 31 | "dependencies": { 32 | "@nuxt/kit": "^3.11.2", 33 | "locomotive-scroll": "^4.1.4" 34 | }, 35 | "devDependencies": { 36 | "@nuxt/devtools": "^1.2.0", 37 | "@nuxt/eslint-config": "^0.3.10", 38 | "@nuxt/module-builder": "^0.6.0", 39 | "@nuxt/schema": "^3.11.2", 40 | "@nuxt/test-utils": "^3.12.1", 41 | "@types/locomotive-scroll": "^4.1.3", 42 | "@types/node": "^20.12.11", 43 | "changelogen": "^0.5.5", 44 | "eslint": "^9.2.0", 45 | "nuxt": "^3.11.2", 46 | "sass": "^1.77.2", 47 | "typescript": "latest", 48 | "vitest": "^1.6.0", 49 | "vue-tsc": "^2.0.16" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /playground/pages/horizontal-scroll.vue: -------------------------------------------------------------------------------- 1 | 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | > thanks to [starter-kit-nuxt-locomotive-scroll nuxt v2](https://github.com/DidoMarchet/starter-kit-nuxt-locomotive-scroll) by [DidoMarchet](https://github.com/DidoMarchet/) 3 | 4 | # Nuxt Locomotive Scroll 5 | 6 | A Nuxt module to easily integrate [Locomotive Scroll](https://github.com/locomotivemtl/locomotive-scroll) into your Nuxt application. 7 | 8 | [![npm version][npm-version-src]][npm-version-href] 9 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 10 | [![License][license-src]][license-href] 11 | [![Nuxt][nuxt-src]][nuxt-href] 12 | 13 | 14 | - [✨  Release Notes](/CHANGELOG.md) 15 | - [🏀 Online playground](https://stackblitz.com/github/arashsheyda/nuxt-locomotive-scroll?file=playground%2Fapp.vue) 16 | - [📖  Documentation](https://docs.arashsheyda.me/nuxt-locomotive-scroll) 17 | 18 | ## Features 19 | 20 | - 🚀  Easy to use 21 | - 🎨  Customizable 22 | 23 | ## Quick Setup 24 | 25 | Install the module to your Nuxt application with one command: 26 | 27 | ```bash 28 | npx nuxi module add locomotive-scroll 29 | ``` 30 | 31 | That's it! You can now use Nuxt Locomotive Scroll in your Nuxt app ✨ or you can install it manually: 32 | 33 | ```bash 34 | # npm 35 | npm install nuxt-locomotive-scroll 36 | 37 | # yarn 38 | yarn add nuxt-locomotive-scroll 39 | 40 | # pnpm 41 | pnpm add nuxt-locomotive-scroll 42 | ``` 43 | 44 | and add `nuxt-locomotive-scroll` to the `modules` section of `nuxt.config`. 45 | 46 | ```ts 47 | export default defineNuxtConfig({ 48 | modules: [ 49 | 'nuxt-locomotive-scroll', 50 | ], 51 | }) 52 | ``` 53 | 54 | ## Usage 55 | 56 | Just add `v-locomotive` directive to the element you want to animate. 57 | 58 | ```vue 59 | 64 | ``` 65 | 66 | you can check the [playground](https://github.com/arashsheyda/nuxt-locomotive-scroll/tree/main/playground) for more examples. 67 | 68 | ## Contribution 69 | 70 |
71 | Local development 72 | 73 | ```bash 74 | # Install dependencies 75 | npm install 76 | 77 | # Generate type stubs 78 | npm run dev:prepare 79 | 80 | # Develop with the playground 81 | npm run dev 82 | 83 | # Build the playground 84 | npm run dev:build 85 | 86 | # Run ESLint 87 | npm run lint 88 | 89 | # Run Vitest 90 | npm run test 91 | npm run test:watch 92 | 93 | # Release new version 94 | npm run release 95 | ``` 96 | 97 |
98 | 99 | 100 | 101 | [npm-version-src]: https://img.shields.io/npm/v/nuxt-locomotive-scroll/latest.svg?style=flat&colorA=020420&colorB=00DC82 102 | [npm-version-href]: https://npmjs.com/package/nuxt-locomotive-scroll 103 | 104 | [npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-locomotive-scroll.svg?style=flat&colorA=020420&colorB=00DC82 105 | [npm-downloads-href]: https://npmjs.com/package/nuxt-locomotive-scroll 106 | 107 | [license-src]: https://img.shields.io/npm/l/nuxt-locomotive-scroll.svg?style=flat&colorA=020420&colorB=00DC82 108 | [license-href]: https://npmjs.com/package/nuxt-locomotive-scroll 109 | 110 | [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js 111 | [nuxt-href]: https://nuxt.com 112 | -------------------------------------------------------------------------------- /playground/app.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 108 | --------------------------------------------------------------------------------