Довідник API для Vue
Повний довідник @reelkit/vue : компоненти, композабли та утиліти.
Reel
Тег: <Reel>
Props
ReelProps
| Prop | Тип | Типове значення | Опис |
|---|---|---|---|
count | number | required | Загальна кількість слайдів |
direction | 'vertical' | 'horizontal' | 'vertical' | Напрямок прокручування |
size | [number, number] | undefined | undefined | Ширина й висота у вигляді [width, height]. Якщо не задано, вимірюється автоматично через ResizeObserver |
initialIndex | number | 0 | Початковий індекс слайда |
loop | boolean | false | Вмикає нескінченний цикл |
transition | TransitionTransformFn | slideTransition | Функція ефекту переходу. Вбудовані: slideTransition, fadeTransition, flipTransition, cubeTransition, zoomTransition |
transitionDuration | number | 300 | Тривалість анімації в мілісекундах |
swipeDistanceFactor | number | 0.12 | Поріг свайпу (0–1) |
enableGestures | boolean | true | Вмикає навігацію перетягуванням дотиком або мишею |
enableNavKeys | boolean | true | Вмикає навігацію стрілками клавіатури |
enableWheel | boolean | false | Вмикає навігацію колесом миші |
wheelDebounceMs | number | 200 | Дебаунс події колеса в мілісекундах |
rangeExtractor | (index: number, count: number) => number[] | defaultRangeExtractor | Власна функція, що визначає, які індекси рендеряться |
keyExtractor | (index: number, indexInRange: number) => string | index => index.toString() | Власна функція ключів для рендерингу слайдів (корисно з циклом) |
ariaLabel | string | undefined | Доступна назва області каруселі |
reelStyle | Record<string, string | number> | undefined | Вбудовані стилі для кореневого контейнера |
reelClass | string | Array | Object | undefined | Класи CSS для кореневого контейнера |
onNavKeyPress | (increment: -1 | 1) => void | undefined | Пропс-колбек, що замінює стандартну навігацію стрілками вгору й вниз. Якщо його передати, навігацію реалізуєте ви самі (наприклад, викликаєте reelRef.value.next()). Не передавайте, щоб лишити стандартну поведінку. |
Events
| Event | Payload | Опис |
|---|---|---|
beforeChange | (index: number, nextIndex: number, indexInRange: number) | Видається перед початком переходу між слайдами |
afterChange | (index: number, indexInRange: number) | Видається після завершення переходу між слайдами |
slideDragStart | (index: number) | Видається на початку перетягування |
slideDragEnd | (index: number) | Видається, коли перетягування завершується (палець або кнопку відпустили) |
slideDragCanceled | (index: number) | Видається, коли перетягування скасовано (слайд повертається назад) |
tap | (event: GestureCommonEvent) | Видається на одиночний дотик |
doubleTap | (event: GestureCommonEvent) | Видається на подвійний дотик |
longPress | (event: GestureCommonEvent) | Видається на початку довгого натискання |
longPressEnd | (event: GestureEvent) | Видається після завершення довгого натискання |
Slots
<Reel :count="items.length">
<template #item="{ index, indexInRange, size }">
<!-- index : number — absolute slide index (0 to count-1) -->
<!-- indexInRange : number — position in the visible window (0, 1, or 2) -->
<!-- size : [number,number] — [width, height] of the container -->
<MySlide :index="index" :size="size" />
</template>
<!-- default slot: overlay content rendered on top of the slides -->
<ReelIndicator />
</Reel>| Slot | Властивості області слота | Опис |
|---|---|---|
#item | { index: number, indexInRange: number, size: [number, number] } | Рендерить кожен видимий слайд. Викликається для кожного індексу у віртуалізованому діапазоні |
default | none | Вміст оверлея поверх усіх слайдів (індикатори, елементи керування тощо) |
ReelExpose
Імперативний API, доступний через шаблонний ref:
<script setup lang="ts">
import { ref } from 'vue';
import { Reel, type ReelExpose } from '@reelkit/vue';
const reelRef = ref<ReelExpose | null>(null);
function prev() { reelRef.value?.prev(); }
function next() { reelRef.value?.next(); }
function jump(i: number) { reelRef.value?.goTo(i, true); }
</script>
<template>
<Reel ref="reelRef" :count="100">
<template #item="{ index }">
<div>Slide {{ index }}</div>
</template>
</Reel>
</template>| Метод | Тип | Опис |
|---|---|---|
next() | () => void | Перейти до наступного слайда |
prev() | () => void | Перейти до попереднього слайда |
goTo(index, animate?) | (number, boolean?) => Promise<void> | Перехід до слайда за індексом |
adjust() | () => void | Перерахувати позиції слайдів (корисно після зміни макета) |
observe() | () => void | Почати слухати події жестів, клавіатури та колеса |
unobserve() | () => void | Припинити слухати події жестів, клавіатури та колеса |
ReelIndicator
Тег: <ReelIndicator>
Props
ReelIndicatorProps
| Prop | Тип | Типове значення | Опис |
|---|---|---|---|
count | number | undefined | auto | Загальна кількість елементів. Береться з контексту батьківського Reel, якщо компонент вкладений у нього; передавайте явно за окремого використання |
active | number | undefined | auto | Поточний активний індекс. Береться з контексту батьківського Reel, якщо компонент вкладений у нього; передавайте явно за окремого використання |
direction | 'vertical' | 'horizontal' | 'vertical' | Орієнтація індикатора |
radius | number | 3 | Радіус точки в пікселях |
visible | number | 5 | Максимум одночасно видимих точок звичайного розміру |
gap | number | 4 | Відстань між точками в пікселях |
activeColor | string | '#fff' | Колір активної точки |
inactiveColor | string | 'rgba(255, 255, 255, 0.5)' | Колір неактивної точки |
edgeScale | number | 0.5 | Коефіцієнт масштабу крайніх точок за межами видимого |
onDotClick | (index: number) => void | undefined | Власний обробник кліку. Якщо не задано всер едині Reel, типово відбувається перехід до індексу натиснутої точки |
indicatorClass | string | Array | Object | undefined | Класи CSS для кореневого елемента tablist |
indicatorStyle | CSSProperties | undefined | Вбудовані стилі, додані до кореневого елемента tablist |
Events
| Event | Payload | Опис |
|---|---|---|
dotClick | (index: number) | Видається на клік по точці; передає індекс точки |
SwipeToClose
Тег: <SwipeToClose> — загортає свій типовий слот у контейнер, чутливий до дотику, який можна закрити свайпом.
Props
SwipeToCloseProps
| Prop | Тип | Типове значення | Опис |
|---|---|---|---|
direction | 'up' | 'down' | required | Напрямок свайпу, що закриває. Беріть "up" для Lightbox й "down" для історій |
enabled | boolean | true | Чи активний жест свайпу для закриття |
threshold | number | 0.2 | Частка висоти області перегляду, потрібна для закриття (0–1) |
Events
| Event | Payload | Опис |
|---|---|---|
close | () | Видається, коли свайп перевищує поріг і анімація закриття завершилася |
Slots
| Slot | Опис |
|---|---|
default | Вміст, який треба загорнути в обробку свайпу для закриття |
Observe
Тег: <Observe :signals="[…]"> — перемальовує свій типовий слот, щойно змінюється один із сигналів, і більше нічого навколо.
Читання сигналу ядра у функції рендеру чи в шаблоні само по собі не підписує на нього. Звична відповідь — toVueRef, але він прив’язує сигнал до компонента, який його викликав, тож сигнал, що змінюється часто, перемальовує цілий компонент. Observe — вужча межа: обгорніть нею ту частину, що показує значення, і ре шта компонента лишиться на місці. Саме цим користується плеєр історій, щоб оновлювати заголовок і смугу прогресу, не перемальовуючи жоден зі слайдерів.
| Prop | Тип | Опис |
|---|---|---|
signals | readonly Subscribable[] | Сигнали, за якими стежити. Інший набір змінює підписку, той самий — зберігає її. На демонтажі все звільняється. |
Тип пропсів експортовано як ObserveProps.
<script setup lang="ts">
import { Observe, createTimerController, toVueRef } from '@reelkit/vue';
const timer = createTimerController({ duration: 5000 });
// toVueRef binds the signal to THIS component: every tick re-renders all of
// it. Fine for a small component, wasteful when something heavy sits beside
// the part that changes.
const progress = toVueRef(timer.progress);
</script>
<template>
<section>
<!-- Only the slot below re-renders on a tick; the list keeps its DOM. -->
<Observe :signals="[timer.progress]">
<progress :value="timer.progress.value" max="1" />
</Observe>
<ExpensiveList :items="items" />
<!-- The same value through toVueRef, for comparison. -->
<p>{{ Math.round(progress * 100) }}%</p>
</section>
</template>Беріть toVueRef, коли за сигналом стежить цілий компонент, і Observe, коли лише його частина.
SoundProvider
Тег: <SoundProvider> — постачальник контексту, що створює екземпляр SoundController і надає його нащадкам через RK_SOUND_KEY. Свій типовий слот рендерить прозоро.
<template>
<SoundProvider>
<Reel :count="items.length">
<template #item="{ index }">
<VideoSlide :index="index" />
</template>
<MuteButton />
</Reel>
</SoundProvider>
</template>RK_REEL_KEY & useReelContext
An InjectionKey<ReelContextValue> який надає <Reel> своїм нащадкам. Використовується всередині <ReelIndicator> для автоматичного під’єднання. Викликайте useReelContext() у власних компонентах, яким потрібен контекст слайдера.
<script setup lang="ts">
import { useReelContext } from '@reelkit/vue';
const ctx = useReelContext();
function jump(index: number) {
ctx?.goTo(index, true);
}
</script>| Властивість | Тип | Опис |
|---|---|---|
index | Signal<number> | Реактивний індекс поточного слайда |
count | Signal<number> | Реактивна загальна кількість елементів |
goTo | (index: number, animate?: boolean) => Promise<void> | Програмний перехід до слайда |
Composables
useBodyLock
Блокує прокручування body документа, коли передане значення — true. Використовує підрахунок посилань, тож кілька одночасних викликачів блокують і розблоковують незалежно. Автоматично розблоковує при демонтажі.
import { ref } from 'vue';
import { useBodyLock } from '@reelkit/vue';
const isOpen = ref(false);
useBodyLock(isOpen);
// Also accepts a static boolean
useBodyLock(true);| Parameter | Тип | Опис |
|---|---|---|
locked | Ref<boolean> | boolean | Чи блокувати прокручування body. Приймає реактивний ref або звичайне булеве значення |
useFullscreen
UseFullscreenOptions → UseFullscreenReturn
Композабл для роботи з Fullscreen API з кросбраузерною підтримкою. Автоматично виходить із повного екрана при демонтажі.
import { ref } from 'vue';
import { useFullscreen } from '@reelkit/vue';
const containerRef = ref<HTMLElement | null>(null);
const { isFullscreen, request, exit, toggle } = useFullscreen({
elementRef: containerRef,
});| Return | Тип | Опис |
|---|---|---|
isFullscreen | Signal<boolean> | Сигнал ядра, що відображає поточний стан повного екрана (читайте .value) |
request | () => Promise<void> | Запитує повний екран для елемента за посиланням. Якщо в повному екрані вже інший елемент, спершу відбувається вихід із нього (з очікуванням). |
exit | () => Promise<void> | Вийти з повного екрана |
toggle | () => Promise<void> | Перемкнути стан повного екрана |
useSoundState
Дає доступ до поточного SoundController з контексту. Викликати треба всередині <SoundProvider>. Поза ним кидає помилку.
import { useSoundState } from '@reelkit/vue';
// Inside a SoundProvider descendant
const sound = useSoundState();
sound.muted; // Signal<boolean>
sound.toggle(); // Toggle muted stateuseOverlayUrlState
OverlayUrlStateOptions
Будує контролер стану в URL для оверлея, який ви передаєте в <LightboxUrlOverlay> як його :controller prop.
See Стан в URL у посібнику для Vue — там покроковий розбір і приклади.
| Option | Тип | Типове значення | Опис |
|---|---|---|---|
param | string | required | Параметр запиту, що несе активний слайд, наприклад "photo". |
adapter | UrlAdapter | History API | Система навігації, через яку читати й писати. У застосунку з роутером передайте адаптер на його базі, щоб власне місцеположення роутера не застаріло. |
codec | { decode(raw) => Id | null; encode(id) => string } | required | Формат передавання: текст параметра ↔ стабільна ідентичність, незалежно в ід колекції. Іде разом із локатором як узгоджена пара з однаковим Id — розгорніть ...urlIndexKey(() => props.images.length) для типової галереї з ?photo=3 або передайте власний (base64, slug), щоб закладка пережила зміну порядку галереї. |
locator | { locate(id) => number | null; locateAsync?(id) => Promise<number | null>; identify(index) => id } | required | Зіставляє ідентичність із позицією і сам відповідає за свою чинність: locate (синхронно), locateAsync (запасний варіант для посторінкової галереї), identify (для запису). Для звичайної галереї за індексом розгорніть ...urlIndexKey(() => props.images.length) — він дає цей локатор разом із відповідним кодеком і обмежує ?photo=3 живою кількістю, тож застарілий ?photo=99 сам зникає з URL замість того, щоб відкрити слайд, якого ніхто не називав. Передавайте геттер, а не число: setup у Vue виконується один раз, і захоплена довжина застаріла б, поки посторінкова стрічка росте. Посторінкова стрічка або галерея з адресацією за ідентичністю передає власну узгоджену пару кодек + локатор. |
useVueRouterUrlAdapter
A UrlAdapter на базі Vue Router. Передайте його як опцію adapter у useOverlayUrlState у застосунку з роутером, щоб роутер лишався єдиним джерелом правди про навігацію: запис history.pushState повз роутер лишає його місцеположення застарілим, і наступна навігація втрачає параметр. Запис торкається лише запиту, тож шлях, хеш і повторювані ключі на кшталт ?tag=a&tag=b лишаються недоторканими. Кожна зміна повідомляє, чи роутер додав запис на тій самій сторінці, замінив його чи пройшов історією, тож галерея, відкрита з <router-link>, закривається одним кроком назад.
Постачається з окрем ого підшляху, тож застосунок без роутера ніколи не тягне vue-router у свій бандл. vue-router — необов’язкова peer-залежність версії 4.1 або новішої: адаптер передає свою позначку власності через навігаційну опцію роутера state, яку старіші випуски ігнорують. Зі старішим роутером нічого не ламається — закриття просто прибирає параметр на місці замість кроку назад.
import { useVueRouterUrlAdapter } from '@reelkit/vue/vue-router-url-adapter';
const adapter = useVueRouterUrlAdapter();
const photo = useOverlayUrlState({
param: 'photo',
adapter,
...urlIndexKey(() => props.images.length),
});toVueRef
Місток від сигналу ядра Subscribable (будь-який Signal from @reelkit/core) into a read-only Vue Ref. Беріть його щоразу, коли значення сигналу ядра має спричиняти перерендер у Vue — прямі читання signal.value у функціях рендерингу чи шаблонах не реактивні самі собою.
Підписка звільняється автоматично через onScopeDispose, so this must be called inside a Vue setup() чи інший контекст, обізнаний про область ефектів.
import { defineComponent, h } from 'vue';
import { toVueRef, useSoundState } from '@reelkit/vue';
export const MuteIcon = defineComponent({
setup() {
const sound = useSoundState();
const muted = toVueRef(sound.muted); // Readonly<Ref<boolean>>
return () => h('span', muted.value ? '🔇' : '🔊');
},
});asGenericPropKeys
Створює компонент, узагальнений за елементами, які він отримує, — так, як ReelPlayerOverlay і StoriesOverlay. Vue 3.3 приймає setup-функцію з параметром типу, defineComponent(<T>(props: Props<T>) => …, options), але зберігає цей параметр лише тоді, коли options.props перелічує назви пропсів. Передайте їй об’єкт пропсів — і Vue прочитає типи пропсів назад з об’єкта, тож T втрачається. asGenericPropKeys передає об’єкт пропсів без змін, а перевірка типів бачить список назв: T виводиться з того, що прив’язу є батьківський компонент, а значення за замовчуванням, валідація й приведення boolean і далі працюють під час виконання.
Аргумент типу — це тип пропсів із базовим елементом, а компонент потребує Vue 3.3 або новішої. Слоти й події не можуть використовувати T: щоб типізувати область видимості слота, анотуйте її в шаблоні.
import { defineComponent, h, type PropType } from 'vue';
import { asGenericPropKeys } from '@reelkit/vue';
interface Item {
id: string;
}
interface FeedProps<T extends Item> {
items: T[];
loop?: boolean;
}
const feedProps = {
items: { type: Array as PropType<Item[]>, required: true as const },
loop: { type: Boolean, default: false },
};
export const Feed = defineComponent(
<T extends Item = Item>(props: FeedProps<T>) =>
() =>
h('ul', props.items.map((item) => h('li', item.id))),
{ name: 'Feed', props: asGenericPropKeys<FeedProps<Item>>(feedProps) },
);hasRenderedNodes
hasRenderedNodes(nodes) визначає, чи результат слота щось виведе на сторінку, — для компонента, що повертається до власного рендерингу, коли батько лишає слот порожнім, як це роблять оверлеї. Слот, чий вміст стоїть за хибним v-if, однаково повертає вузол-коментар, тож перевірка довжини масиву вважала б його заповненим і відкинула б запасний варіант. hasRenderedNodes розгортає фрагменти, ігнорує вузли-коментарі й повертає false для null або undefined, тож hasRenderedNodes(slots.controls?.(scope)) — та перевірка, за якою варто розгалужуватися.
Accessibility
<Reel> рендериться як role="region" з aria-roledescription="carousel". Передайте aria-label (пропс має назву ariaLabel у TypeScript), щоб дати області назву для екранного читача. Ввічлива жива область оголошує «Слайд N з M» на кожну зміну слайда. Неактивні слайди отримують атрибут inert , тож фокус і навігація допоміжних технологій їх пропускають.
<ReelIndicator> рендериться як role="tablist" з рухомим tabindex на точках; стрілки переміщують фокус, а Enter або Space активує слайд.
Будуєте власне модальне вікно навколо <Reel>? captureFocusForReturn, createFocusTrap, та getFocusableElements — вони реекспортовані з @reelkit/vue для повернення й утримання фокуса.
Експорти пакета
Усі публічні експорти з @reelkit/vue:
// Components
import {
Reel,
ReelIndicator,
SwipeToClose,
SoundProvider,
Observe,
} from '@reelkit/vue';
// Types
import type {
ReelExpose,
ReelContextValue,
SwipeToCloseDirection,
SwipeToCloseProps,
UseFullscreenOptions,
UseFullscreenReturn,
} from '@reelkit/vue';
// Context & composables
import {
RK_REEL_KEY,
useReelContext,
RK_SOUND_KEY,
useBodyLock,
useFullscreen,
useSoundState,
toVueRef,
} from '@reelkit/vue';
// Generic components
import { asGenericPropKeys } from '@reelkit/vue';
// Utilities (re-exported from @reelkit/core)
import {
createDefaultKeyExtractorForLoop,
defaultRangeExtractor,
} from '@reelkit/vue';
// Core re-exports
import {
// Signals & reactivity
createSignal, createComputed, reaction, batch, createDeferred,
// Transitions
slideTransition, fadeTransition, flipTransition,
cubeTransition, zoomTransition, getSlideProgress,
// Content loading & preloading
createContentLoadingController, createContentPreloader,
observeMediaLoading,
// Sound
createSoundController, syncMutedToVideo,
// Fullscreen
fullscreenSignal, requestFullscreen, exitFullscreen,
// DOM & cleanup
observeDomEvent, createDisposableList, createBodyLock, sharedBodyLock,
// Size detection
observeElementSize, getViewportSize, observeViewportSize,
isMobileWidth, fitAspectRatio, isTouchDevice,
// Autoplay & download
createTimerController, createSlideshowController, downloadFile,
// Focus management
captureFocusForReturn, createFocusTrap, getFocusableElements,
// Gestures
createGestureController,
// Video
captureFrame, createSharedVideo,
// Animation
animate,
// Utilities
noop, clamp, abs, first, last, extractRange,
lerp, isNegative, generate,
} from '@reelkit/vue';