Lightbox для Angular

Повноекранний Lightbox-галерея зображень і відео для Angular на основі @reelkit/angular-lightbox.

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

Features

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

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

bash
npm install @reelkit/angular-lightbox @reelkit/angular lucide-angular

Зареєструйте таблицю стилів один раз:

typescript
// 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.

gallery.component.ts
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
typescript
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">&#8592;</button>
        <button (click)="onNext()" [disabled]="activeIndex === count - 1">&#8594;</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.

typescript
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 щоб стежити за станом повного екрана або перемикати його.

typescript
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 ядра.

typescript
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:

typescript
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.

typescript
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 (пошук) самі:

typescript
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 }) (він вантажить дані, якщо не знайшов, і повертає індекс). Розгорнутий варіант нижче — для адресації за іншим полем або для повного контролю.

typescript
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 ядра.

typescript
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; див. посібник із завантаження.

typescript
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',
    },
  ];
}

Кнопки керування

КомпонентСелекторВходи / виходиОпис
RkPlayPauseButtonComponentrk-play-pause-button[playing], (toggled)Перемикач слайдшоу (іконка Play або Pause, aria-pressed під час відтворення). Стандартні елементи керування показують його з autoAdvance.
RkDownloadButtonComponentrk-download-button[downloading], (pressed)Кнопка завантаження, вимкнена, поки downloading. Стандартні елементи керування показують її з showDownload.
RkSoundButtonComponentrk-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ТипТипове значенняОпис
controllerUrlStateControllerrequiredКонтролер із createOverlayUrlState. Його position вирішує, чи галерея відкрита і який слайд показує; компонент записує через нього назад на зміну слайда та на закриття.

Входи RkLightboxOverlayComponent

InputТипТипове значенняОпис
isOpenbooleanrequiredКерує видимістю; якщо false, оверлей прибирається з DOM
itemsLightboxItem[]requiredМасив елементів Lightbox (зображення або відео)
initialIndexnumber0Індекс початково видимого елемента, від нуля
transitionFnTransitionTransformFnslideTransitionФункція переходу між слайдами. Імпортуйте вбудовану (slideTransition, flipTransition, lightboxFadeTransition, lightboxZoomTransition) або передайте власну. Якщо не задано, використовується slideTransition.
showInfobooleantrueЧи показувати інформаційний оверлей із заголовком та описом
showControlsbooleantrueЧи показувати верхню смугу керування (закриття, лічильник, повний екран)
showNavigationbooleantrueЧи показувати стрілки навігації вперед і назад
transitionDurationnumber300Тривалість анімації слайда в мілісекундах
swipeDistanceFactornumber0.12Мінімальна частка відстані свайпу (0–1), щоб змінити слайд
swipeToCloseDirection'up' | 'down''up'Напрямок жесту свайпу для закриття на мобільних
loopbooleanfalseЧи переходить слайдер з останнього слайда на перший
enableNavKeysbooleantrueВмикає навігацію стрілками клавіатури
enableWheelbooleantrueВмикає навігацію колесом миші
wheelDebounceMsnumber200Тривалість дебаунсу подій колеса в мілісекундах
autoAdvancebooleanfalseГрати галерею як слайдшоу. Див. Автоперехід.
autoAdvanceIntervalnumber5000Скільки кожне зображення лишається на екрані під час слайдшоу, у мілісекундах, з моменту його завантаження
showDownloadbooleanfalseДодає кнопку завантаження для активного елемента. Див. Завантаження.
ariaLabelstring'Image gallery'Доступна назва області діалогу

Входи слайдера вище (transitionDuration, swipeDistanceFactor, loop, enableNavKeys, enableWheel, wheelDebounceMs) типізує ReelProxyProps. Типізуйте ним компонент-обгортку, що передає їх у lightbox.

Виходи RkLightboxOverlayComponent

OutputТипОпис
closedEventEmitter<void>Видається, коли користувач закриває Lightbox
slideChangeEventEmitter<number>Видається, коли змінюється індекс активного слайда

Інтерфейс LightboxItem

FieldТипRequiredОпис
srcstringyesURL зображення або відео
type'image' | 'video'noТип елемента. Типово 'image'
posterstringnoМініатюра для елементів-відео
titlestringnoЗаголовок в інформаційному оверлеї
descriptionstringnoОпис під заголовком
widthnumbernoВласна ширина зображення в пікселях
heightnumbernoВласна висота зображення в пікселях
downloadUrlstringnoЩо зберігає кнопка завантаження. Типово — src
downloadNamestringnoІм’я файлу для збереження. Типово — останній сегмент шляху 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 , коли не задано.

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

html
<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 щоб замінити стандартний індикатор.

html
<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 щоб замінити стандартний значок помилки.

html
<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 нижче.

ClassComponentОпис
.rk-lightbox-overlayOverlayКореневий контейнер (повноекранне тло)
.rk-lightbox-top-shadeOverlayВерхній градієнтний шар за елементами керування
.rk-lightbox-spinnerOverlayСтандартний індикатор завантаження
.rk-lightbox-img-errorOverlayКонтейнер стану помилки (зіпсоване зображення)
.rk-lightbox-img-error-textOverlayТекст стану помилки
.rk-lightbox-swipe-hintOverlayПідказка про свайп на мобільних
.rk-lightbox-emptyOverlayТекст порожнього стану
.rk-lightbox-controls-leftControlsКонтейнер елементів керування вгорі ліворуч
.rk-lightbox-btnControlsКнопка керування (повний екран тощо)
.rk-lightbox-play-pauseControlsКнопка відтворення й паузи слайдшоу (разом із .rk-lightbox-btn)
.rk-lightbox-downloadControlsКнопка завантаження (разом із .rk-lightbox-btn)
.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Постер відео (за бажанням)
.rk-lightbox-video-errorVideoSlideКонтейнер стану помилки відео

Theming

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

TokenТипове значенняControls
--rk-lightbox-overlay-bg#000Колір повноекранного фону
--rk-lightbox-overlay-z9999z-index оверлею
--rk-lightbox-top-shade-height80pxВисота верхнього градієнтного затемнення
--rk-lightbox-top-shade-bglinear-gradient(rgba(0,0,0,0.6), transparent)Колір верхнього градієнтного затемнення
--rk-lightbox-edge-padding16pxВідступ від краю для кнопок закриття, навігації та елементів керування зліва вгорі
--rk-lightbox-controls-gap12pxВідстань між елементами керування зліва вгорі
--rk-lightbox-transition0.2sТривалість переходу кнопки під час наведення
--rk-lightbox-blur8pxРадіус розмиття фону для кнопок і плашок
--rk-lightbox-btn-bgrgba(0, 0, 0, 0.5)Типовий фон кнопок закриття, навігації та малих кнопок
--rk-lightbox-btn-bg-hoverrgba(255, 255, 255, 0.2)Фон кнопок закриття, навігації та малих кнопок під час наведення
--rk-lightbox-btn-fg#fffКолір іконок кнопок закриття, навігації та малих кнопок
--rk-lightbox-btn-size36pxРозмір малої кнопки (перемикач повноекранного режиму тощо)
--rk-lightbox-btn-disabled-opacity0.5Непрозорість вимкненої малої кнопки (під час завантаження)
--rk-lightbox-close-size40pxРозмір кнопки закриття
--rk-lightbox-nav-size48pxРозмір стрілок «назад» і «далі»
--rk-lightbox-nav-opacity0.7Непрозорість стрілок «назад» і «далі» у спокої
--rk-lightbox-counter-fg#fffКолір тексту лічильника
--rk-lightbox-counter-bgrgba(0, 0, 0, 0.5)Фон плашки лічильника
--rk-lightbox-counter-size14pxРозмір шрифту лічильника
--rk-lightbox-counter-padding6px 12pxВнутрішній відступ плашки лічильника
--rk-lightbox-counter-radius20pxРадіус заокруглення плашки лічильника
--rk-lightbox-spinner-size28pxТипова ширина й висота спінера
--rk-lightbox-spinner-duration0.8sТривалість обертання спінера
--rk-lightbox-error-fgrgba(255, 255, 255, 0.4)Колір іконки й тексту помилки
--rk-lightbox-info-bglinear-gradient(transparent, rgba(0,0,0,0.8))Градієнт затемнення під підписом
--rk-lightbox-info-padding24pxВнутрішній відступ підпису
--rk-lightbox-title-size18pxРозмір шрифту заголовка
--rk-lightbox-description-size14pxРозмір шрифту опису
--rk-lightbox-hint-fgrgba(255, 255, 255, 0.5)Колір тексту підказки про свайп
--rk-lightbox-hint-bgrgba(0, 0, 0, 0.3)Фон плашки підказки про свайп
--rk-lightbox-video-bg#000Фон смуг навколо <video>

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

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.

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

KeyAction
ArrowLeftПопереднє зображення
ArrowRightНаступне зображення
EscapeЗакрити Lightbox (або вийти з повноекранного режиму, якщо він активний)