Lightbox для Angular
Повноекранний Lightbox-галерея зображень і відео для Angular на основі @reelkit/angular-lightbox.
Features
Встановлення
npm install @reelkit/angular-lightbox @reelkit/angular lucide-angularЗареєструйте таблицю стилів один раз:
// Anywhere that runs at startup — main.ts, app.config.ts, a component file.
import '@reelkit/angular-lightbox/styles.css';
// Or, if you keep CSS out of TypeScript, from your global stylesheet:
// @import '@reelkit/angular-lightbox/styles.css';
// Or register it in angular.json:
// "styles": ["node_modules/@reelkit/angular-lightbox/styles.css"]Icons
Стандартні елементи керування використовують lucide-angular for icons. If you prefer a different icon library, use the rkLightboxControls та rkLightboxNavigation щоб передати власні.
Швидкий старт
Імпортуйте стилі та автономний компонент RkLightboxOverlayComponent у imports array.
import { Component } from '@angular/core';
import {
RkLightboxOverlayComponent,
type LightboxItem,
} from '@reelkit/angular-lightbox';
import '@reelkit/angular-lightbox/styles.css';
const images: LightboxItem[] = [
{
src: '/cdn/samples/images/image-01.jpg',
title: 'Mountain River',
description: 'A beautiful mountain river',
},
{
src: '/cdn/samples/images/image-02.jpg',
title: 'Snowy Peaks',
},
{
src: '/cdn/samples/images/image-03.jpg',
title: 'Misty Forest',
description: 'Morning fog over the forest canopy',
},
{
src: '/cdn/samples/images/image-04.jpg',
title: 'Autumn Trail',
},
{
src: '/cdn/samples/images/image-05.jpg',
title: 'Ocean Cliff',
description: 'Dramatic cliffs above the Pacific',
},
{
src: '/cdn/samples/images/image-06.jpg',
title: 'Desert Dunes',
},
];
@Component({
selector: 'app-root',
standalone: true,
imports: [RkLightboxOverlayComponent],
template: `
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:8px">
@for (img of images; track img.src; let i = $index) {
<button (click)="openIndex = i" style="aspect-ratio:4/3;cursor:pointer">
<img [src]="img.src" style="width:100%;height:100%;object-fit:cover" />
</button>
}
</div>
<rk-lightbox-overlay
[isOpen]="openIndex !== null"
[items]="images"
[initialIndex]="openIndex ?? 0"
(closed)="openIndex = null"
/>
`,
})
export class AppComponent {
images = images;
openIndex: number | null = null;
}Де рендериться оверлей
На відміну від lightbox для React і Vue, які переносять свій оверлей у кінець document.body, rk-lightbox-overlay рендериться там, де ви його розмістили, і накриває екран через position: fixed. Не кладіть його всередину предка з transform, perspective, filter або will-change: transform: такий предок стає блоком-контейнером оверлея, тож lightbox отримує розмір предка замість вікна й обрізається його overflow. Предок, що створює власний контекст накладання, також обмежує, наскільки високо --rk-lightbox-overlay-z може підняти lightbox. Натомість токени --rk-lightbox-*, задані на будь-якому предку, доходять до lightbox.
Шаблонні слоти
Чотири директиви шаблонних слотів дають повністю налаштувати інтерфейс оверлея, не форкаючи компонент. Кожен слот отримує строго типізований об’єкт контексту.
| Directive | Тип контексту | Опис |
|---|---|---|
| [rkLightboxControls] | LightboxControlsContext | Замінює верхню смугу керування (кнопка закриття, лічильник, перемикач повного екрана) |
| [rkLightboxNavigation] | LightboxNavContext | Замінює стрілки навігації вперед і назад |
| [rkLightboxInfo] | LightboxInfoContext | Замінює нижній градієнтний оверлей із заголовком та описом |
| [rkLightboxSlide] | LightboxSlideContext | Замінює вміст окремого слайда (обов’язково д ля слайдів-відео) |
| [rkLightboxLoading] | LightboxLoadingContext | Власний індикатор завантаження; клас директиви — RkLightboxLoadingDirective |
| [rkLightboxError] | LightboxErrorContext | Власний індикатор помилки; клас директиви — RkLightboxErrorDirective |
import {
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkLightboxNavigationDirective,
RkLightboxInfoDirective,
RkCloseButtonComponent,
RkCounterComponent,
RkFullscreenButtonComponent,
type LightboxItem,
type LightboxControlsContext,
type LightboxNavContext,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-root',
standalone: true,
imports: [
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkLightboxNavigationDirective,
RkLightboxInfoDirective,
RkCloseButtonComponent,
RkCounterComponent,
RkFullscreenButtonComponent,
],
template: `
<rk-lightbox-overlay [isOpen]="isOpen" [items]="images" (closed)="isOpen = false">
<!-- Custom controls bar -->
<ng-template rkLightboxControls
let-onClose="onClose"
let-activeIndex="activeIndex"
let-count="count"
let-isFullscreen="isFullscreen"
let-onToggleFullscreen="onToggleFullscreen">
<div style="position:absolute;top:0;left:0;right:0;padding:12px;
display:flex;align-items:center;justify-content:space-between">
<rk-close-button (clicked)="onClose()" />
<rk-counter [currentIndex]="activeIndex + 1" [count]="count" />
<rk-fullscreen-button
[isFullscreen]="isFullscreen"
(toggled)="onToggleFullscreen()" />
</div>
</ng-template>
<!-- Custom navigation -->
<ng-template rkLightboxNavigation
let-onPrev="onPrev"
let-onNext="onNext"
let-activeIndex="activeIndex"
let-count="count">
<button (click)="onPrev()" [disabled]="activeIndex === 0">←</button>
<button (click)="onNext()" [disabled]="activeIndex === count - 1">→</button>
</ng-template>
<!-- Custom info overlay -->
<ng-template rkLightboxInfo let-item let-index="index">
<div style="position:absolute;bottom:0;left:0;right:0;padding:16px;
background:linear-gradient(transparent,rgba(0,0,0,0.6))">
<h3 style="color:#fff">{{ item.title }}</h3>
<p style="color:rgba(255,255,255,0.7)">{{ item.description }}</p>
</div>
</ng-template>
</rk-lightbox-overlay>
`,
})
export class AppComponent {
images: LightboxItem[] = [];
isOpen = false;
}Підтримка відео
Слайди-відео вмикаються через шаблонний слот rkLightboxSlide та RkLightboxVideoSlideComponent. Так відеоплеєр не потрапляє в бандл галерей, яким потрібні лише зображення.
Вбудована кнопка звуку з'являється лише тоді, коли SoundStateService надано над <rk-lightbox-overlay>: саме цей спільний екземпляр дає перемиканню дістатися до відео, адже сл айд рендериться з вашого шаблону. Без нього керуйте елементом напряму через setLightboxVideoMuted.
import {
RkLightboxOverlayComponent,
RkLightboxSlideDirective,
RkLightboxVideoSlideComponent,
type LightboxItem,
type LightboxSlideContext,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-root',
standalone: true,
imports: [
RkLightboxOverlayComponent,
RkLightboxSlideDirective,
RkLightboxVideoSlideComponent,
],
template: `
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxSlide
let-item
let-index="index"
let-size="size"
let-isActive="isActive"
let-autoAdvance="autoAdvance"
let-onReady="onReady"
let-onEnded="onEnded">
@if (item.type === 'video') {
<!-- With autoAdvance the video plays once and reports its end -->
<rk-lightbox-video-slide
[src]="item.src"
[poster]="item.poster"
[slideKey]="'lightbox-' + index"
[size]="size"
[isActive]="isActive"
[loop]="!autoAdvance"
[onReady]="onReady"
[onEnded]="onEnded"
/>
} @else {
<img [src]="item.src"
[style.width.px]="size[0]"
[style.height.px]="size[1]"
style="object-fit:contain" />
}
</ng-template>
</rk-lightbox-overlay>
`,
})
export class AppComponent {
isOpen = false;
items: LightboxItem[] = [
{ src: '/photo.jpg', title: 'Photo' },
{ src: '/clip.mp4', type: 'video', poster: '/clip-thumb.jpg', title: 'Video' },
];
}Повний екран
Використовуйте fullscreenSignal, requestFullscreen, та exitFullscreen from @reelkit/angular щоб стежити за станом повного екрана або перемикати його.
import { fullscreenSignal, requestFullscreen, exitFullscreen } from '@reelkit/angular';
@Component({ ... })
export class AppComponent {
readonly isFullscreen = fullscreenSignal();
toggle(container: HTMLElement): void {
if (this.isFullscreen()) {
exitFullscreen();
} else {
requestFullscreen(container);
}
}
}Стан в URL
Подивитися демо наживо →RkLightboxUrlOverlayComponent — окремий компонент, стан відкриття якого живе в адресному рядку. Побудуйте контролер через createOverlayUrlState і передайте його як [controller]: галерея відкривається сама, коли параметр називає слайд, і закривається, коли параметр зникає. Посиланнями можна ділитися, а кнопка «назад» закриває галерею, а не виводить зі сторінки.
Вбудовані клавіші
Слайди можна адресувати вбудованим ключем — розгорніть urlIndexKey (за позицією) або urlStableIdKey (за стабільним id) into the controller — both re-exported from @reelkit/angular. See the посібник зі стану в URL та API ядра.
import { RkLightboxUrlOverlayComponent } from '@reelkit/angular-lightbox';
import { createOverlayUrlState, urlIndexKey, urlStableIdKey } from '@reelkit/angular';
@Component({
imports: [RkLightboxUrlOverlayComponent, RouterLink],
template: `
@for (image of images(); track image.src; let i = $index) {
<a [routerLink]="[]" [queryParams]="{ photo: i }">
<img [src]="image.src" alt="" />
</a>
}
<rk-lightbox-url-overlay [controller]="photo" [items]="images()" />
`,
})
export class GalleryComponent {
protected readonly images = signal(photos);
protected readonly photo = createOverlayUrlState({
param: 'photo',
...urlIndexKey(() => this.images().length),
});
}Викликайте його в контексті впровадження — в ініціалізаторі поля або в конструкторі. Він під’єднується одразу й звільняється через DestroyRef, so a component destroyed while the gallery is open leaves no listener behind. Full options live in the довіднику API для Angular.
- Відкриття додає один запис в історію. Гортання слайдів замінює його, тож N кроків не додають записів, і один крок назад завжди виводить із галереї.
- «Назад» закриває лише тоді, коли галерею відкрили всередині застосунку — посилання додало запис. За надісланим посиланням у новій вкладці історії позаду немає, тож кнопка «назад» виведе із сайту; кнопка ✕ або Escape прибирає параметр на місці й лишає вас на сторінці.
- Параметр, який не називає жодного слайда — застаріла закладка, змінене вручну значення, — прибирається з URL, а не лишається наполягати на слайді, що не відкриється.
- Шаблонні слоти працюють без змін: url-компонент сам виконує шість запитів слотів і передає кожен шаблон у галерею, тож
rkLightboxControlsта сусідні директиви живуть усередині нього точно так само, як усерединіrk-lightbox-overlay. - У застосунку з роутеро м передайте адаптер на базі
Router. Запис в історію повз Router лишає його місцеположення застарілим, і наступна навігація втрачає параметр.
У застосунку з роутером передайте адаптер. Запис в історію повз Router лишає його місцеположення застарілим, і наступна навігація втрачає параметр, тож збудуйте адаптер на базі Router and pass it as adapter:
import { createRouterUrlAdapter } from '@reelkit/angular/ng-router-url-adapter';
const adapter = createRouterUrlAdapter();
const photo = createOverlayUrlState({
param: 'photo',
adapter,
...urlIndexKey(() => this.images().length),
});Стабільні посилання. Індекс адресує за позицією — збережений у закладках ?photo=3 відкриє інше зображення, щойно список перевпорядкують. urlStableIdKey адресує за стабільним id, scanning the live list — one call covers the common case.
const photo = createOverlayUrlState({
param: 'photo',
...urlStableIdKey({ items: () => this.images() }),
});Pass hashCodec: base64UrlCodec щоб закодувати id в URL у base64url — оборотне маскування, а не криптографічний хеш.
Адресуєте за іншим полем ( slug), or page an infinite feed with locateAsync, and build the codec (формат передавання) та locator (пошук) самі:
const photo = createOverlayUrlState({
param: 'photo',
codec: { decode: (raw) => raw, encode: (id) => id },
locator: {
locate: (id) => this.images().findIndex((x) => x.id === id),
identify: (index) => this.images()[index].id,
},
});Нескінченні та посторінкові галереї. locate синхронний, тож відповідає лише за вже завантажені зображення — надіслане посилання на зображення 400 у стрічці, де завантажено 20, нічого не знайде. locateAsync — запасний варіант, що викликається лише коли locate не знаходить: завантажте потрібні сторінки й поверніть індекс, який ця ідентичність отримала. Поки він у процесі, галерея лишається закритою, а параметр — недоторканим, тож пряме посилання переживає запит; null або відмова прибирає параметр.
Shortcut
Keying by the item’s id? Не пишіть кодек і локатор вручну — передайте locateAsync просто в urlStableIdKey({ items, locateAsync }) (він вантажить дані, якщо не знайшов, і повертає індекс). Розгорнутий варіант нижче — для адресації за іншим полем або для повного контролю.
const photo = createOverlayUrlState({
param: 'photo',
codec: { decode: (raw) => raw, encode: (id) => id },
locator: {
locate: (id) => this.images().findIndex((x) => x.id === id),
identify: (index) => this.images()[index].id,
locateAsync: async (id) => {
const loaded = await loadById(id); // or loadUntil(id) — fetch just that one, or page up to it
if (!loaded) return null; // exhausted — link names no item
this.images.set(loaded); // commit; the overlay renders from this
return loaded.findIndex((x) => x.id === id); // wherever it landed
},
},
});Автоперехід
Задайте [autoAdvance]="true", щоб галерея після відкриття гралася як слайдшоу. Типово вимкнено, тож наявний Lightbox рендериться й поводиться як раніше.
- Зображення лишаються на екрані
autoAdvanceInterval(типово 5000 мс), відлічуваних із моменту, коли зображення завантажилося, тож повільне зображення ніколи не пропускається, перш ніж його хтось побачив. Для зображення, що не завантажилося, відлік іде від помилки. - Відео програються один раз замість циклу й переходять далі, коли закінчуються. У шаблоні
rkLightboxSlideприв’яжіть[loop]="!autoAdvance"і[onEnded]="onEnded"наrk-lightbox-video-slide, як у розділі Підтримка відео. - Воно чекає, поки миша лежить на елементі керування (кнопці, посиланні чи підписі), під час свайпу і поки сторінка прихована, а потім продовжує з місця зупинки.
- Ручне перемикання (стрілки, клавіші, колесо, свайп) запускає інтервал нового слайда з нуля; слайдшоу лишається увімкненим.
- На останньому слайді воно зупиняється, якщо не задано
loop. Кнопка відтворення й паузи серед елементів керування показує стан і дає глядачеві його перемкнути.
Слайдшоу працює поза зоною Angular, тож його кадри анімації не запускають виявлення змін. Власний шаблон rkLightboxControls отримує isAutoAdvancing і, лише коли autoAdvance увімкнено, onToggleAutoAdvance — рендерте rk-play-pause-button, коли він є. Сам таймінг — це createSlideshowController з @reelkit/core; див. посібник з автовідтворення і API ядра.
import { Component } from '@angular/core';
import {
RkCloseButtonComponent,
RkLightboxControlsDirective,
RkLightboxOverlayComponent,
RkPlayPauseButtonComponent,
type LightboxItem,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-gallery',
imports: [
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkPlayPauseButtonComponent,
RkCloseButtonComponent,
],
template: `
<rk-lightbox-overlay
[isOpen]="isOpen"
[items]="items"
[autoAdvance]="true"
[autoAdvanceInterval]="4000"
(closed)="isOpen = false"
>
<!-- Optional: a custom bar shows the toggle only when its handler is there -->
<ng-template rkLightboxControls let-ctx>
@if (ctx.onToggleAutoAdvance) {
<rk-play-pause-button
[playing]="ctx.isAutoAdvancing"
(toggled)="ctx.onToggleAutoAdvance()"
/>
}
<rk-close-button (clicked)="ctx.onClose()" />
</ng-template>
</rk-lightbox-overlay>
`,
})
export class GalleryComponent {
isOpen = false;
items: LightboxItem[] = [{ src: '/beach.jpg' }, { src: '/forest.jpg' }];
}Завантаження
Задайте [showDownload]="true", щоб додати до елементів керування кнопку завантаження. Вона зберігає активний елемент за його downloadUrl, а якщо його немає — за src, під іменем downloadName, а якщо його немає — під останнім сегментом URL.
Файл завантажується через fetch і зберігається, бо браузер ігнорує атрибут download на посиланні на інше джерело й відкрив би файл замість збереження. Коли fetch не вдається — зазвичай це сервер на іншому джерелі, що не надсилає заголовків CORS, — файл відкривається в новій вкладці, де глядач усе ще може його зберегти. Віддавайте файли з Access-Control-Allow-Origin, щоб зберігати одним кліком. Поки триває завантаження, кнопка вимкнена.
Власний шаблон rkLightboxControls отримує isDownloading і, лише коли showDownload увімкнено, onDownload — рендерте rk-download-button, коли він є. Помічник — це downloadFile з @reelkit/core; див. посібник із завантаження.
import { Component } from '@angular/core';
import {
RkCloseButtonComponent,
RkDownloadButtonComponent,
RkLightboxControlsDirective,
RkLightboxOverlayComponent,
type LightboxItem,
} from '@reelkit/angular-lightbox';
@Component({
selector: 'app-gallery',
imports: [
RkLightboxOverlayComponent,
RkLightboxControlsDirective,
RkDownloadButtonComponent,
RkCloseButtonComponent,
],
template: `
<rk-lightbox-overlay
[isOpen]="isOpen"
[items]="items"
[showDownload]="true"
(closed)="isOpen = false"
>
<!-- Optional: a custom bar shows the button only when its handler is there -->
<ng-template rkLightboxControls let-ctx>
@if (ctx.onDownload) {
<rk-download-button
[downloading]="ctx.isDownloading"
(pressed)="ctx.onDownload()"
/>
}
<rk-close-button (clicked)="ctx.onClose()" />
</ng-template>
</rk-lightbox-overlay>
`,
})
export class GalleryComponent {
isOpen = false;
items: LightboxItem[] = [
{
src: '/beach-1600.jpg',
// Save the original rather than the resized preview
downloadUrl: '/beach-original.jpg',
downloadName: 'beach.jpg',
},
];
}Кнопки керування
| Компонент | Селектор | Входи / виходи | Опис |
|---|---|---|---|
RkPlayPauseButtonComponent | rk-play-pause-button | [playing], (toggled) | Перемикач слайдшоу (іконка Play або Pause, aria-pressed під час відтворення). Стандартні елементи керування показують його з autoAdvance. |
RkDownloadButtonComponent | rk-download-button | [downloading], (pressed) | Кнопка за вантаження, вимкнена, поки downloading. Стандартні елементи керування показують її з showDownload. |
RkSoundButtonComponent | rk-sound-button | [muted], (toggled) | Перемикач звуку для відео-елементів. Стандартні елементи керування показують його на слайді-відео; розмістіть його у власному шаблоні rkLightboxControls, щоб зберегти. |
Входи RkLightboxUrlOverlayComponent
Приймає всі входи rk-lightbox-overlay except isOpen, replaced by a controller. Outputs are the same closed та slideChange; the URL drives closing, so closed тут радше сповіщення, ніж механізм.
| Input | Тип | Типове значення | Опис |
|---|---|---|---|
controller | UrlStateController | required | Контролер із createOverlayUrlState. Його position вирішує, чи галерея відкрита і який слайд показує; компонент записує через нього назад на зміну слайда та на закриття. |
Входи RkLightboxOverlayComponent
| Input | Тип | Типове значення | Опис |
|---|---|---|---|
isOpen | boolean | required | Керує видимістю; якщо false, оверлей прибирається з DOM |
items | LightboxItem[] | required | Масив елементів Lightbox (зображення або відео) |
initialIndex | number | 0 | Індекс початково видимого елемента, від нуля |
transitionFn | TransitionTransformFn | slideTransition | Функція переходу між слайдами. Імпортуйте вбудовану (slideTransition, flipTransition, lightboxFadeTransition, lightboxZoomTransition) або передайте власну. Якщо не задано, використовується slideTransition. |
showInfo | boolean | true | Чи показувати інформаційний оверлей із заголовком та описом |
showControls | boolean | true | Чи показувати верхню смугу керування (закриття, лічильник, повний екран) |
showNavigation | boolean | true | Чи показувати стрілки навігації вперед і назад |
transitionDuration | number | 300 | Тривалість анімації слайда в мілісекундах |
swipeDistanceFactor | number | 0.12 | Мінімальна частка відстані свайпу (0–1), щоб змінити слайд |
swipeToCloseDirection | 'up' | 'down' | 'up' | Напрямок жесту свайпу для закриття на мобільних |
loop | boolean | false | Чи переходить слайдер з останнього слайда на перший |
enableNavKeys | boolean | true | Вмикає навігацію стрілками клавіатури |
enableWheel | boolean | true | Вмикає навігацію колесом миші |
wheelDebounceMs | number | 200 | Тривалість дебаунсу подій колеса в мілісекундах |
autoAdvance | boolean | false | Грати галерею як слайдшоу. Див. Автоперехід. |
autoAdvanceInterval | number | 5000 | Скільки кожне зображення лишається на екрані під час слайдшоу, у мілісекундах, з моменту його завантаження |
showDownload | boolean | false | Додає кнопку завантаження для активного елемента. Див. Завантаження. |
ariaLabel | string | 'Image gallery' | Доступна назва області діалогу |
Входи слайдера вище (transitionDuration, swipeDistanceFactor, loop, enableNavKeys, enableWheel, wheelDebounceMs) типізує ReelProxyProps. Типізуйте ним компонент-обгортку, що передає їх у lightbox.
Виходи RkLightboxOverlayComponent
| Output | Тип | Опис |
|---|---|---|
closed | EventEmitter<void> | Видається, коли користувач закриває Lightbox |
slideChange | EventEmitter<number> | Видається, коли змінюється індекс активного слайда |
Інтерфейс LightboxItem
| Field | Тип | Required | Опис |
|---|---|---|---|
src | string | yes | URL зображення або відео |
type | 'image' | 'video' | no | Тип елемента. Типово 'image' |
poster | string | no | Мініатюра для елементів-відео |
title | string | no | Заголовок в інформаційному оверлеї |
description | string | no | Опис під заголовком |
width | number | no | Власна ширина зображення в пікселях |
height | number | no | Власна висота зображення в пікселях |
downloadUrl | string | no | Що зберігає кнопка завантаження. Типово — src |
downloadName | string | no | Ім’я файлу для збереження. Типово — останній сегмент шляху URL |
Типи контексту шаблонних слотів
| Тип | Fields |
|---|---|
LightboxControlsContext | { item, activeIndex, count, isFullscreen, isAutoAdvancing, isDownloading, onClose, onToggleFullscreen, onToggleAutoAdvance?, onDownload? } |
LightboxNavContext | { item, onPrev, onNext, activeIndex, count } |
LightboxInfoContext | { $implicit: LightboxItem, index } |
LightboxSlideContext | { $implicit: LightboxItem, index, size: [number, number], isActive, autoAdvance, onReady, onWaiting, onError, onEnded } |
LightboxLoadingContext | { $implicit: activeIndex, item } — що отримує шаблон rkLightboxLoading |
LightboxErrorContext | { $implicit: activeIndex, item } — що отримує шаблон rkLightboxError |
Переходи
Передайте будь-яку TransitionTransformFn via the transitionFn . Якщо імпортувати лише той перехід, який використовуєте, решту збирач прибере через tree-shaking. Типово — slideTransition , коли не задано.
| Function | From | Опис |
|---|---|---|
slideTransition | @reelkit/angular-lightbox | Звичайний горизонтальний зсув (типово) |
lightboxFadeTransition | @reelkit/angular-lightbox | Плавне перетікання між зображеннями |
flipTransition | @reelkit/angular-lightbox | Ефект 3D-перевороту картки |
lightboxZoomTransition | @reelkit/angular-lightbox | Наближення від меншого до звичайного розміру |
import {
RkLightboxOverlayComponent,
lightboxFadeTransition,
} from '@reelkit/angular-lightbox';
@Component({
imports: [RkLightboxOverlayComponent],
template: `
<rk-lightbox-overlay
[isOpen]="isOpen"
[items]="images"
[transitionFn]="lightboxFadeTransition"
(closed)="isOpen = false"
/>
`,
})
export class GalleryComponent {
protected readonly lightboxFadeTransition = lightboxFadeTransition;
}Завантаження вмісту та обробка помилок
Коли використовуєте слот rkLightboxSlide , в контексті доступні три колбеки життєвого циклу, щоб повідомляти стан завантаження. Lightbox стежить за станом кожного слайда й показує індикатор або значок помилки. Попереднє завантаження кешує зіпсовані URL, тож повторний перехід до невдалого слайда обходиться без нової спроби.
Колбеки життєвого циклу
| Колбек | Тип | Опис |
|---|---|---|
onReady | () => void | Повідомляє, що вміст слайда ус пішно завантажився (наприклад, зображення декодовано) |
onWaiting | () => void | Повідомляє, що вміст слайда вантажиться або буферизується (показує індикатор) |
onError | () => void | Повідомляє, що вміст слайда не завантажився (показує значок помилки) |
Підключення колбеків у rkLightboxSlide
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxSlide
let-item
let-size="size"
let-isActive="isActive"
let-onReady="onReady"
let-onWaiting="onWaiting"
let-onError="onError">
@if (item.type === 'video') {
<rk-lightbox-video-slide
[item]="item"
[size]="size"
[isActive]="isActive"
/>
} @else {
<img [src]="item.src"
[style.width.px]="size[0]"
[style.height.px]="size[1]"
style="object-fit:contain"
(load)="onReady()"
(error)="onError()" />
}
</ng-template>
</rk-lightbox-overlay>Власний шаблон завантаження
Скористайтеся пропсом rkLightboxLoading щоб замінити стандартний індикатор.
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxLoading let-index let-item="item">
<div style="display:flex;flex-direction:column;align-items:center;color:#fff">
<span>Loading image {{ index + 1 }}...</span>
<span style="opacity:0.6">{{ item.title }}</span>
</div>
</ng-template>
</rk-lightbox-overlay>Власний шаблон помилки
Скористайтеся пропсом rkLightboxError щоб замінити стандартний значок помилки.
<rk-lightbox-overlay [isOpen]="isOpen" [items]="items" (closed)="isOpen = false">
<ng-template rkLightboxError let-index let-item="item">
<div style="display:flex;flex-direction:column;align-items:center;color:#ef4444">
<span>Failed to load</span>
<span style="opacity:0.6">{{ item.title ?? item.src }}</span>
</div>
</ng-template>
</rk-lightbox-overlay>Класи CSS
Усі класи CSS звичайні (не scoped), тож їх можна перекрити селекторами вищої специфічності в таблиці стилів, підключеній після @reelkit/angular-lightbox/styles.css. Для змін кольору, розміру та z-index краще беріть власні властивості CSS, описані в розділі Theming нижче.
| Class | Component | Опис |
|---|---|---|
.rk-lightbox-overlay | Overlay | Кореневий контейнер (повноекранне тло) |
.rk-lightbox-top-shade | Overlay | Верхній градієнтний шар за елементами керування |
.rk-lightbox-spinner | Overlay | Стандартний індикатор завантаження |
.rk-lightbox-img-error | Overlay | Контейнер стану помилки (зіпсоване зображення) |
.rk-lightbox-img-error-text | Overlay | Текст стану помилки |
.rk-lightbox-swipe-hint | Overlay | Підказка про свайп на мобільних |
.rk-lightbox-empty | Overlay | Текст порожнього стану |
.rk-lightbox-controls-left | Controls | Контейнер елементів керування вгорі ліворуч |
.rk-lightbox-btn | Controls | Кнопка керування (повний екран тощо) |
.rk-lightbox-play-pause | Controls | Кнопка відтворення й паузи слайдшоу (разом із .rk-lightbox-btn) |
.rk-lightbox-download | Controls | Кнопка завантаження (разом із .rk-lightbox-btn) |
.rk-lightbox-close | Controls | Кнопка закриття |
.rk-lightbox-counter | Controls | Значок лічильника зображень |
.rk-lightbox-nav | Навігація | Стрілка навігації (і вперед, і назад) |
.rk-lightbox-nav-prev | Навігація | Стрілка назад |
.rk-lightbox-nav-next | Навігація | Стрілка вперед |
.rk-lightbox-info | Info | Контейнер заголовка й опису |
.rk-lightbox-title | Info | Заголовок зображення |
.rk-lightbox-description | Info | Опис зображення |
.rk-lightbox-slide | Slide | Контейнер слайда |
.rk-lightbox-img | Slide | Елемент зображення |
.rk-lightbox-video-container | VideoSlide | Контейнер слайда-відео (за бажанням) |
.rk-lightbox-video-element | VideoSlide | Елемент відео (за бажанням) |
.rk-lightbox-video-poster | VideoSlide | Постер відео (за бажанням) |
.rk-lightbox-video-error | VideoSlide | Контейнер стану помилки відео |
Theming
Кожен колір, розмір, z-index і перехід живе у власній властивості CSS. Перевизначайте одну чи кілька на :root (або на будь-якому предку Lightbox), щоб змінити тему, не чіпаючи код компонентів. Токени збігаються з Lightbox для React, тож перевизначення переносяться між прив’язками.
| Token | Типове значення | Controls |
|---|---|---|
--rk-lightbox-overlay-bg | #000 | Колір повноекранного фону |
--rk-lightbox-overlay-z | 9999 | z-index оверлею |
--rk-lightbox-top-shade-height | 80px | Висота верхнього градієнтного затемнення |
--rk-lightbox-top-shade-bg | linear-gradient(rgba(0,0,0,0.6), transparent) | Колір верхнього градієнтного затемнення |
--rk-lightbox-edge-padding | 16px | Відступ від краю для кнопок закриття, навігації та елементів керування зл іва вгорі |
--rk-lightbox-controls-gap | 12px | Відстань між елементами керування зліва вгорі |
--rk-lightbox-transition | 0.2s | Тривалість переходу кнопки під час наведення |
--rk-lightbox-blur | 8px | Радіус розмиття фону для кнопок і плашок |
--rk-lightbox-btn-bg | rgba(0, 0, 0, 0.5) | Типовий фон кнопок закриття, навігації та малих кнопок |
--rk-lightbox-btn-bg-hover | rgba(255, 255, 255, 0.2) | Фон кнопок закриття, навігації та малих кнопок під час наведення |
--rk-lightbox-btn-fg | #fff | Колір іконок кнопок закриття, навігації та малих кнопок |
--rk-lightbox-btn-size | 36px | Розмір малої кнопки (перемикач повноекранного режиму тощо) |
--rk-lightbox-btn-disabled-opacity | 0.5 | Непрозорість вимкненої малої кнопки (під час завантаження) |
--rk-lightbox-close-size | 40px | Розмір кнопки закриття |
--rk-lightbox-nav-size | 48px | Розмір стрілок «назад» і «далі» |
--rk-lightbox-nav-opacity | 0.7 | Непрозорість стрілок «назад» і «далі» у спокої |
--rk-lightbox-counter-fg | #fff | Колір тексту лічильника |
--rk-lightbox-counter-bg | rgba(0, 0, 0, 0.5) | Фон плашки лічильника |
--rk-lightbox-counter-size | 14px | Розмір шрифту лічильника |
--rk-lightbox-counter-padding | 6px 12px | Внутрішній відступ плашки лічильника |
--rk-lightbox-counter-radius | 20px | Радіус заокруглення плашки лічильника |
--rk-lightbox-spinner-size | 28px | Типова ширина й висота спінера |
--rk-lightbox-spinner-duration | 0.8s | Тривалість обертання спінера |
--rk-lightbox-error-fg | rgba(255, 255, 255, 0.4) | Колір іконки й тексту помилки |
--rk-lightbox-info-bg | linear-gradient(transparent, rgba(0,0,0,0.8)) | Градієнт затемнення під підписом |
--rk-lightbox-info-padding | 24px | Внутрішній відступ підпису |
--rk-lightbox-title-size | 18px | Розмір шрифту заголовка |
--rk-lightbox-description-size | 14px | Розмір шрифту опису |
--rk-lightbox-hint-fg | rgba(255, 255, 255, 0.5) | Колір тексту підказки про свайп |
--rk-lightbox-hint-bg | rgba(0, 0, 0, 0.3) | Фон плашки підказки про свайп |
--rk-lightbox-video-bg | #000 | Фон смуг навколо <video> |
Вставте фрагмент нижче в таблицю стилів, підключену після @reelkit/angular-lightbox/styles.css.
/* Brand the lightbox */
:root {
--rk-lightbox-overlay-bg: #0f172a;
--rk-lightbox-btn-bg: rgba(99, 102, 241, 0.65);
--rk-lightbox-btn-bg-hover: rgba(168, 85, 247, 0.85);
--rk-lightbox-nav-size: 56px;
--rk-lightbox-counter-bg: rgba(99, 102, 241, 0.65);
--rk-lightbox-info-bg: linear-gradient(
transparent,
rgba(99, 102, 241, 0.55) 60%,
rgba(168, 85, 247, 0.85)
);
}Accessibility
Корінь оверлея — модальний діалог (role="dialog", aria-modal="true"). Set the ariaLabel щоб змінити оголошення для екранного читача; типове значення — «Image gallery». Кожен слайд несе role="group", aria-roledescription="slide", and an aria-label виведений із заголовка зображення та позиції.
Lightbox захоплює фокус під час відкриття й повертає його на елемент-тригер після закриття. Tab і Shift+Tab циклічно проходять фокусовані елементи всередині; фокус, що вислизнув (клік поза Lightbox, програмна установка), повертається назад. Реалізовано через captureFocusForReturn та createFocusTrap from @reelkit/core.
Клавіатурні скорочення
| Key | Action |
|---|---|
ArrowLeft | Попереднє зображення |
ArrowRight | Наступне зображення |
Escape | Закрити Lightbox (або вийти з повноекранного режиму, якщо він активний) |