Lightbox

Повноекранний компонент Lightbox-галереї зображень і відео на основі @reelkit/react-lightbox.

Подивитися демо наживо →

Features

Зображення та відео
Вбудована підтримка слайдів-відео
Дотикові жести
Свайп для гортання
Свайп для закриття
Свайп угору закриває
Навігація з клавіатури
Стрілки + Escape
Повний екран
Кросбраузерний API
Переходи
Зсув, затухання, переворот, наближення
Preloading
Сусідні зображення завантажуються заздалегідь
Перемикач звуку
Звук вмикається й вимикається для кожного слайда
Стани завантаження
Індикатор і власний рендеринг
Обробка помилок
Значок помилки та власний рендеринг
Render Props
6 налаштовних зон рендерингу
Hooks
useVideoSlideRenderer + useFullscreen
Стан в URL
Посилання, якими можна ділитися й зберігати в закладки

Встановлення

bash

Не забудьте імпортувати стилі:

typescript
Icons
Стандартні елементи керування використовують lucide-react для іконок. Якщо ви віддаєте перевагу іншій бібліотеці іконок, скористайтеся renderControls та renderNavigation , щоб передати власні.

Швидкий старт

The LightboxOverlay показує зображення на весь екран. Передайте масив об’єктів LightboxItem і керуйте видимістю через індекс, який може бути null.

tsx

Демо наживо

LightboxPage.tsx

Натисніть мініатюру, щоб відкрити Lightbox. Гортайте стрілками або свайпом.

Слайди-відео (за бажанням)

Підтримка відео вмикається за бажанням і піддається tree-shaking — використання лише зображень нічого не додає до бандла. Імпортуйте useVideoSlideRenderer і передайте повернені значення у LightboxOverlay. Хук сам дає раду станам завантаження, керуванню звуком і життєвим циклом відео.

tsx
Як це працює
  • Хук повертає SoundProvider — загорніть у нього оверлей, щоб перемикання звуку працювало
  • Відео відтворюється автоматично (типово без звуку), коли слайд стає активним
  • Спільний елемент відео повторно використовується між слайдами заради безперервності звуку на iOS
  • Кнопка звуку з’являється на слайдах-відео автоматично, з реактивним перемикачем
  • Елементи без type: 'video' рендеряться як зображення (зворотна сумісність)

Customization

Власні елементи керування

Використовуйте renderControls щоб замінити стандартну кнопку закриття, лічильник і перемикач повного екрана. Складайте з експортованих підкомпонентів:

tsx

Власний інформаційний оверлей

Використовуйте renderInfo щоб замінити стандартний градієнт із заголовком та описом, або передайте renderInfo={() => null} щоб сховати його повністю:

tsx

Власна навігація

Використовуйте renderNavigation щоб замінити стандартні стрілки вперед і назад:

tsx

Власний слайд

Використовуйте renderSlide для повністю власного вмісту слайда. Поверніть null щоб лишити стандартний слайд-зображення:

tsx

Завантаження вмісту та обробка помилок

Lightbox стежить за станом завантаження й помилок кожного слайда. Поки вміст вантажиться, показується індикатор; для медіа, що не завантажилося, — значок зіпсованого зображення. URL з помилками кешуються, тож повторний перехід одразу показує помилку без нової спроби.

Колбеки життєвого циклу

Якщо ви використовуєте renderSlide, call these callbacks to control the loading indicator:

КолбекКоли викликати
onReadyЗображення завантажилося або відео почало грати. Скидає стани завантаження й помилки.
onWaitingВідео буферизується посеред відтворення. Показує індикатор завантаження.
onErrorВміст не завантажився. Показує оверлей помилки й кешує URL як зіпсований.
tsx

Власний інтерфейс завантаження та помилок

Замініть стандартний індикатор і значок помилки власними компонентами:

tsx

Стан в URL

LightboxUrlOverlay — окремий компонент, стан відкриття якого живе в адресному рядку. Побудуйте контролер через useOverlayUrlState from @reelkit/react і передайте його як controller: галерея відкривається сама, коли параметр називає слайд, і закривається, коли параметр зникає. Посиланнями можна ділитися, а кнопка «назад» закриває галерею, а не виводить зі сторінки.

Вбудовані клавіші
Слайди можна адресувати вбудованим ключем — розгорніть urlIndexKey (за позицією) або urlStableIdKey (за стабільним id) into the controller — both re-exported from @reelkit/react. See the посібник зі стану в URL та API ядра.
tsx

Хук приймає один об’єкт опцій і повертає UrlStateController (with set, index, value). Keep it for programmatic control: set — низькорівневий запис, який оверлей робить усередині (зміна слайда та set(null) для закриття). Ним же можна керувати оверлеєм програмно: set(index) відкриває його — так само, як перехід за параметром. Але для відкриття краще звичайне посилання: href можна надіслати, відкрити в новій вкладці, а кнопка «назад» його закриє — і все це без жодного обробника.

Full useOverlayUrlState options (param, adapter, codec, locator): see the довіднику API для React.

LightboxUrlOverlay приймає лише controller (обов’язково), необов’язковий onClose, plus every visual and behavior prop LightboxOverlay takes (images, ariaLabel, transitionFn, the render props, and so on) — but no isOpen.

  • Відкриття коштує одного запису в історії. Гортання слайдів замінює його, тож сто свайпів не додають жодного — один крок назад завжди виходить із галереї. «Назад» закриває, а не гортає фотографії.
  • Надіслане посилання на кшталт ?photo=3 відкриває галерею на цьому слайді. Закриття посилання, що прийшло разом зі сторінкою, прибирає параметр на місці, а не виводить із сайту.
  • «Назад» закриває лише тоді, коли ви відкрили галерею всередині застосунку — посилання додало запис, тож «назад» повертає до галереї. За надісланим посиланням у новій вкладці історії позаду немає, тож кнопка «назад» виведе із сайту; кнопка закриття або Escape прибирає параметр на місці й лишає вас у галереї.
  • Параметр, який не називає жодного слайда — застаріла закладка, змінене вручну значення, — прибирається з URL, а не лишає в адресному рядку слайд, який не відкриється.

У застосунку з роутером передайте адаптер. Прямий запис в історію лишає власне місцеположення роутера застарілим, і наступна навігація втрачає параметр.

tsx

Відкриття — це посилання. Оскільки стан відкриття живе в URL, мініатюра — звичайне посилання без обробника кліку, і вся поведінка браузера дістається безкоштовно: відкрити в новій вкладці, скопіювати адресу, побачити підказку при наведенні. У застосунку з роутером беріть посилання роутера, щоб перехід лишався на клієнті.

tsx

Для посилань, якими діляться, краще стабільна ідентичність. Індекс адресує за позицією, тож збережений у закладках ?photo=3 відкриє інше зображення, щойно список перевпорядкують. urlStableIdKey адресує за стабільним id, scanning the live list — one call covers the common case.

tsx

Pass hashCodec: base64UrlCodec щоб закодувати id в URL у base64url — оборотне маскування, а не криптографічний хеш.

Адресуєте за іншим полем ( slug), or page an infinite feed with locateAsync, and build the codec/locator самі:

tsx

Нескінченні та посторінкові галереї. Синхронний locate відповідає лише за вже завантажені зображення — надіслане посилання на зображення 400 у стрічці, де завантажено 20, нічого не знайде. locateAsync — запасний варіант, що викликається лише коли locate misses.

Shortcut
Keying by the item’s id? Не пишіть кодек і локатор вручну — передайте locateAsync просто в urlStableIdKey({ items, locateAsync }) (він вантажить дані, якщо не знайшов, і повертає індекс). Розгорнутий варіант нижче — для адресації за іншим полем або для повного контролю.
tsx
  • Як саме вантажити — ваша справа: тягніть сторінки поспіль до потрібної або лише одне зображення й додайте його. URL адресує за ідентичністю, а не за позицією, тож findIndex поверне те місце, де елемент опинився.
  • While locateAsync у процесі, Lightbox лишається закритим, а параметр — недоторканим, тож пряме посилання переживає запит. null або відмова прибирає параметр.
  • Відповідь, що приходить після зміни URL, після закриття або після демонтажу, відкидається — повільний запит не відкриє слайд, якого ніхто не просив.
  • Поки триває очікування, нічого не рендериться: цей стан завантаження вже належить сторінці, тож малюйте власний скелетон.
  • Тайм-ауту немає — Lightbox не може знати, яка галерея завдовжки. Завершуйте значенням null коли сторінки скінчилися, інакше оверлей лишиться закритим назавжди.
  • Whatever locateAsync є остаточним — це індекс щойно завантажених даних, узятий як є, без повторного читання images.

Довідник API

Пропси LightboxOverlay

LightboxOverlayProps

PropТипТипове значенняОпис
isOpenbooleanrequiredКерує видимістю Lightbox. Для стану відкриття, керованого URL, беріть окремий LightboxUrlOverlay — дивіться розділ про стан в URL нижче.
imagesLightboxItem[]requiredМасив зображень для показу
ariaLabelstring'Image gallery'Доступна назва області діалогу; екранні читачі оголошують її, коли Lightbox відкривається
initialIndexnumber0Початковий індекс зображення
transitionFnTransitionTransformFnslideTransitionФункція переходу між слайдами. Імпортуйте вбудовану (slideTransition, flipTransition, lightboxFadeTransition, lightboxZoomTransition) або передайте власну. Якщо не задано, використовується slideTransition.
apiRefMutableRefObject<ReelApi>-Ref для доступу до API Reel
renderControls(props: ControlsRenderProps) => ReactNode-Власні елементи керування, замінюють стандартну кнопку закриття, лічильник і перемикач повного екрана
renderNavigation(props: NavigationRenderProps) => ReactNode-Власна навігація, замінює стандартні стрілки вперед і назад
renderInfo(props: InfoRenderProps) => ReactNode-Власний інформаційний оверлей, замінює стандартний градієнт із заголовком та описом. Поверніть null, щоб сховати.
renderSlide(props: SlideRenderProps) => ReactNode | null-Власний рендеринг слайда. Отримує { item, index, size, isActive, onReady, onWaiting, onError }. Поверніть null, щоб лишити стандартний.
renderLoading(props: { item: LightboxItem; activeIndex: number }) => ReactNode-Власний індикатор завантаження, замінює стандартний
renderError(props: { item: LightboxItem; activeIndex: number }) => ReactNode-Власний індикатор помилки, замінює стандартний значок

Пропси LightboxUrlOverlay

LightboxUrlOverlayProps

Приймає всі візуальні та поведінкові пропси вище, крім isOpen, and replaces it with a controller. initialIndex тут ігнорується — слайд обирає position контролера, тож передане поруч значення перезаписувалося б на кожному відкритті.

PropТипТипове значенняОпис
controllerUrlStateControllerrequiredКонтролер із useOverlayUrlState. Його position вирішує, чи оверлей відкритий і який слайд показує; оверлей записує через нього назад на зміну слайда та на закриття.

Колбеки

PropТипОпис
onClose() => voidВикликається, коли Lightbox закривається. Обов’язковий у LightboxOverlay (стан відкриття ваш, тож закриття обробляєте ви); необов’язковий у LightboxUrlOverlay, де закриттям керує URL — передавайте лише щоб зреагувати після закриття.
onSlideChange(index: number) => voidВикликається після зміни слайда

Пропси Reel (передані далі)

Ці пропси передаються далі в Reel component.

PropТипТипове значенняОпис
loopbooleanfalseВмикає нескінченний цикл
enableNavKeysbooleantrueВмикає навігацію з клавіатури
enableWheelbooleantrueВмикає навігацію колесом миші
wheelDebounceMsnumber200Тривалість дебаунсу колеса (мс)
transitionDurationnumber300Тривалість анімації переходу (мс)
swipeDistanceFactornumber0.12Поріг свайпу (0–1)
swipeToCloseDirection'up' | 'down''up'Напрямок жесту свайпу для закриття на мобільних

Types

LightboxItem

typescript

ControlsRenderProps

typescript
typescript

SlideRenderProps

typescript

InfoRenderProps

typescript

Sub-Components

Повторно використовувані підкомпоненти для складання власних елементів керування через renderControls.

CloseButton

Стандартна кнопка закриття у вигляді хрестика.

tsx

Counter

Значок лічильника зображень на кшталт «1 / 3».

tsx

FullscreenButton

Кнопка перемикання повного екрана (іконка Maximize або Minimize).

tsx

SoundButton

Кнопка перемикання звуку для слайдів-відео (іконка Volume2 або VolumeX). Автоматично входить у renderControls from useVideoSlideRenderer. Для окремого використання у власних елементах керування доступ до стану звуку — через useSoundState.

tsx

Hooks

useVideoSlideRenderer

Хук для підтримки відео за бажанням. Повертає renderSlide, renderControls, та SoundProvider — загорніть оверлей у SoundProvider і передайте функції рендерингу.

typescript

useFullscreen

Moved
useFullscreen прибрано з @reelkit/react-lightbox. Import it from @reelkit/react instead.

Хук для керування станом повного екрана з кросбраузерною підтримкою.

tsx

Переходи

Передайте будь-яку TransitionTransformFn via the transitionFn Якщо імпортувати лише той перехід, який використовуєте, решту збирач прибере через tree-shaking. Типово — slideTransition , коли не задано.

FunctionFromОпис
slideTransition@reelkit/react-lightboxЗвичайний горизонтальний зсув (типово)
lightboxFadeTransition@reelkit/react-lightboxПлавне перетікання між зображеннями
flipTransition@reelkit/react-lightboxЕфект 3D-перевороту картки
lightboxZoomTransition@reelkit/react-lightboxНаближення від меншого до звичайного розміру
tsx

Власна функція переходу

Напишіть власну TransitionTransformFn and pass it via transitionFn. Сигнатура повторює переходи слайдера в ядрі.

tsx

Класи CSS

Усі елементи інтерфейсу використовують звичайні класи CSS (не CSS-модулі), які можна перекрити селекторами вищої специфічності в таблиці стилів, підключеній після @reelkit/react-lightbox/styles.css. Для змін кольору, розміру та z-index краще беріть власні властивості CSS, описані в розділі Theming нижче.

ClassComponentОпис
.rk-lightbox-overlayOverlayКореневий контейнер (повноекранне тло)
.rk-lightbox-spinnerOverlayСтандартний індикатор завантаження
.rk-lightbox-img-errorOverlayКонтейнер стану помилки (зіпсоване зображення чи відео)
.rk-lightbox-img-error-textOverlayТекст стану помилки
.rk-lightbox-swipe-hintOverlayПідказка про свайп на мобільних
.rk-lightbox-controls-leftControlsКонтейнер елементів керування вгорі ліворуч
.rk-lightbox-btnControlsКнопки керування (повний екран тощо)
.rk-lightbox-closeControlsКнопка закриття
.rk-lightbox-counterControlsЗначок лічильника зображень
.rk-lightbox-navНавігаціяСтрілки навігації (обидві)
.rk-lightbox-nav-prevНавігаціяСтрілка назад
.rk-lightbox-nav-nextНавігаціяСтрілка вперед
.rk-lightbox-infoInfoКонтейнер заголовка й опису
.rk-lightbox-titleInfoЗаголовок зображення
.rk-lightbox-descriptionInfoОпис зображення
.rk-lightbox-slideSlideКонтейнер слайда
.rk-lightbox-imgSlideЕлемент зображення
.rk-lightbox-video-containerVideoSlideКонтейнер слайда-відео (за бажанням)
.rk-lightbox-video-elementVideoSlideЕлемент відео (за бажанням)
.rk-lightbox-video-posterVideoSlideПостер відео (за бажанням)

Theming

Кожен колір, розмір, z-index і перехід живе у власній властивості CSS. Перевизначайте одну чи кілька на :root (або на будь-якому предку Lightbox), щоб змінити тему, не чіпаючи код компонентів.

TokenТипове значенняControls
--rk-lightbox-overlay-bg#000Full-screen backdrop color
--rk-lightbox-overlay-z9999Overlay z-index
--rk-lightbox-top-shade-height80pxTop gradient scrim height
--rk-lightbox-top-shade-bglinear-gradient(rgba(0,0,0,0.6), transparent)Top gradient scrim color
--rk-lightbox-edge-padding16pxEdge inset for close / nav / top-left controls
--rk-lightbox-controls-gap12pxGap between top-left controls
--rk-lightbox-transition0.2sButton hover transition duration
--rk-lightbox-blur8pxBackdrop blur radius for buttons / chips
--rk-lightbox-btn-bgrgba(0, 0, 0, 0.5)Default background for close, nav, small buttons
--rk-lightbox-btn-bg-hoverrgba(255, 255, 255, 0.2)Hover background for close, nav, small buttons
--rk-lightbox-btn-fg#fffIcon color for close, nav, small buttons
--rk-lightbox-btn-size36pxSmall button size (fullscreen toggle, etc.)
--rk-lightbox-close-size40pxClose button size
--rk-lightbox-nav-size48pxPrev/next arrow size
--rk-lightbox-nav-opacity0.7Idle opacity of prev/next arrows
--rk-lightbox-counter-fg#fffCounter text color
--rk-lightbox-counter-bgrgba(0, 0, 0, 0.5)Counter chip background
--rk-lightbox-counter-size14pxCounter font size
--rk-lightbox-counter-padding6px 12pxCounter chip padding
--rk-lightbox-counter-radius20pxCounter chip border-radius
--rk-lightbox-spinner-size28pxDefault spinner width/height
--rk-lightbox-spinner-trackrgba(255, 255, 255, 0.2)Spinner track color
--rk-lightbox-spinner-fg#fffSpinner indicator color
--rk-lightbox-spinner-duration0.8sSpinner rotation duration
--rk-lightbox-error-fgrgba(255, 255, 255, 0.4)Error icon + text color
--rk-lightbox-error-text-size13pxError message font size
--rk-lightbox-info-bglinear-gradient(transparent, rgba(0,0,0,0.8))Caption scrim gradient
--rk-lightbox-info-padding24pxCaption inner padding
--rk-lightbox-title-size18pxTitle font size
--rk-lightbox-description-size14pxDescription font size
--rk-lightbox-info-fg#fffCaption text color
--rk-lightbox-hint-fgrgba(255, 255, 255, 0.5)Swipe hint text color
--rk-lightbox-hint-bgrgba(0, 0, 0, 0.3)Swipe hint chip background
--rk-lightbox-hint-duration3sSwipe hint fade-in/out total duration
--rk-lightbox-video-bg#000Letterbox background behind <video>

Вставте фрагмент нижче в таблицю стилів, підключену після @reelkit/react-lightbox/styles.css.

css

Accessibility

Корінь оверлея — модальний діалог (role="dialog", aria-modal="true"). Set ariaLabel щоб змінити оголошення для екранного читача; типове значення — «Image gallery». Кожен слайд несе role="group", aria-roledescription="slide", та aria-label="Зображення N з M".

Lightbox захоплює фокус під час відкриття й повертає його на елемент-тригер після закриття. Tab і Shift+Tab циклічно проходять фокусовані елементи всередині; фокус, що вислизнув (клік поза Lightbox, програмна установка), повертається назад. Реалізовано через captureFocusForReturn та createFocusTrap from @reelkit/core.

Клавіатурні скорочення

KeyAction
ArrowLeftPrevious image
ArrowRightNext image
EscapeClose lightbox (or exit fullscreen if active)