Vue Integration
MotionRail provides a first-class Vue 3 component (SFC) with full TypeScript support.
Installation
bash
npm install motionrail vueBasic Usage
vue
<script setup>
import { MotionRail } from 'motionrail/vue';
import 'motionrail/style.css';
const options = { breakpoints: [{ columns: 3, gap: '20px' }] };
</script>
<template>
<MotionRail :options="options">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</MotionRail>
</template>Props
options
- Type:
MotionRailOptions - Required: No
- Default:
{}
Configuration options for the carousel. See Configuration for all available options.
vue
<script setup>
const options = {
autoplay: true,
delay: 3000,
breakpoints: [
{ columns: 1, gap: '16px' },
{ width: 768, columns: 2, gap: '16px' }
]
};
</script>
<template>
<MotionRail :options="options">
<!-- items -->
</MotionRail>
</template>Template Ref Access
Use template refs to access the MotionRail instance and container:
vue
<script setup>
import { ref } from 'vue';
import { MotionRail } from 'motionrail/vue';
const carouselRef = ref(null);
const handleNext = () => {
carouselRef.value?.instance?.next();
};
const handlePrev = () => {
carouselRef.value?.instance?.prev();
};
</script>
<template>
<div>
<MotionRail ref="carouselRef" :options="{}">
<div>Item 1</div>
<div>Item 2</div>
</MotionRail>
<button @click="handlePrev">Previous</button>
<button @click="handleNext">Next</button>
</div>
</template>Exposed Properties
The component exposes two properties via defineExpose:
instance: The MotionRail class instance (for API methods)container: The container HTMLDivElement
vue
<script setup>
import { ref, onMounted } from 'vue';
const carouselRef = ref(null);
onMounted(() => {
// Access the MotionRail instance
console.log(carouselRef.value.instance);
// Access the container element
console.log(carouselRef.value.container);
});
</script>
<template>
<MotionRail ref="carouselRef" :options="{}">
<!-- items -->
</MotionRail>
</template>Complete Example
vue
<script setup>
import { ref } from 'vue';
import { MotionRail } from 'motionrail/vue';
import 'motionrail/style.css';
const carouselRef = ref(null);
const currentState = ref(null);
const options = {
autoplay: true,
delay: 3000,
breakpoints: [
{ columns: 1, gap: '16px' },
{ width: 768, columns: 2, gap: '16px' },
{ width: 1024, columns: 3, gap: '20px' }
],
onChange: (state) => {
currentState.value = state;
}
};
const handleNext = () => {
carouselRef.value?.instance?.next();
};
const handlePrev = () => {
carouselRef.value?.instance?.prev();
};
const handlePlay = () => {
carouselRef.value?.instance?.play();
};
const handlePause = () => {
carouselRef.value?.instance?.pause();
};
</script>
<template>
<div>
<MotionRail
ref="carouselRef"
:options="options"
class="my-carousel"
>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
</MotionRail>
<div class="controls">
<button @click="handlePrev">Previous</button>
<button @click="handleNext">Next</button>
<button @click="handlePlay">Play</button>
<button @click="handlePause">Pause</button>
</div>
<div v-if="currentState" class="state-info">
<p>Visible items: {{ currentState.visibleItemIndexes.join(', ') }}</p>
<p>Total items: {{ currentState.totalItems }}</p>
</div>
</div>
</template>Dynamic Children
The Vue component automatically calls update() when slot content changes:
vue
<script setup>
import { ref } from 'vue';
import { MotionRail } from 'motionrail/vue';
const items = ref(['Item 1', 'Item 2', 'Item 3']);
const addItem = () => {
items.value.push(`Item ${items.value.length + 1}`);
};
const removeItem = () => {
items.value.pop();
};
</script>
<template>
<div>
<MotionRail :options="{ breakpoints: [{ columns: 3, gap: '20px' }] }">
<div v-for="(item, index) in items" :key="index">
{{ item }}
</div>
</MotionRail>
<button @click="addItem">Add Item</button>
<button @click="removeItem">Remove Item</button>
</div>
</template>TypeScript
Full TypeScript support with <script setup lang="ts">:
vue
<script setup lang="ts">
import { ref } from 'vue';
import { MotionRail } from 'motionrail/vue';
import type { MotionRailOptions, MotionRailState } from 'motionrail';
const carouselRef = ref<{ instance: any; container: HTMLDivElement } | null>(null);
const currentState = ref<MotionRailState | null>(null);
const options: MotionRailOptions = {
autoplay: true,
breakpoints: [{ columns: 3, gap: '20px' }],
onChange: (state: MotionRailState) => {
currentState.value = state;
}
};
const handleNext = (): void => {
carouselRef.value?.instance?.next();
};
</script>
<template>
<MotionRail ref="carouselRef" :options="options">
<div>Item 1</div>
<div>Item 2</div>
</MotionRail>
</template>Attributes
All attributes are passed to the root div element:
vue
<template>
<MotionRail
:options="{}"
class="my-carousel"
style="max-width: 1200px"
aria-label="Product carousel"
>
<!-- items -->
</MotionRail>
</template>Bundle Size
Vue integration: 1.22 kB (gzipped: 0.62 kB)
Next Steps
- Configuration - All configuration options
- API Methods - Programmatic control
- Extensions - Add more functionality