Angular Lightbox

Angular के लिए फ़ुलस्क्रीन इमेज और वीडियो गैलरी lightbox, जो @reelkit/angular-lightbox पर बना है।

लाइव डेमो देखें →

फ़ीचर

इमेज और वीडियो
वीडियो स्लाइड का बिल्ट-इन सपोर्ट
टच जेस्चर
स्वाइप करके आगे-पीछे जाएँ
स्वाइप करके बंद करें
हटाने के लिए ऊपर स्वाइप करें
कीबोर्ड नेविगेशन
तीर वाली कुंजियाँ + Escape
फ़ुलस्क्रीन
सभी ब्राउज़र में चलने वाला API
ट्रांज़िशन
Slide, fade, flip, zoom-in
पहले से लोडिंग
आसपास की इमेज पहले से fetch होती हैं
साउंड टॉगल
हर स्लाइड पर mute/unmute
लोडिंग स्टेट
Spinner + कस्टम slot
एरर हैंडलिंग
एरर आइकन + कस्टम slot
टेम्पलेट स्लॉट
कस्टमाइज़ होने वाले 6 slot हिस्से
OnPush
Angular signals + OnPush
URL स्टेट
शेयर और bookmark करने लायक लिंक
स्लाइडशो
play/pause के साथ opt-in अपने-आप आगे बढ़ना
डाउनलोड
सक्रिय आइटम सेव करने वाला opt-in बटन

इंस्टॉलेशन

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"]
आइकन

डिफ़ॉल्ट कंट्रोल आइकन के लिए lucide-angular इस्तेमाल करते हैं। अगर आप कोई और आइकन लाइब्रेरी पसंद करते हैं, तो अपने देने के लिए rkLightboxControls और rkLightboxNavigation template slots इस्तेमाल करें।

क्विक स्टार्ट

styles और standalone RkLightboxOverlayComponent कंपोनेंट को अपने कंपोनेंट के imports array में import करें।

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;
}
ओवरले कहाँ रेंडर होता है

React और Vue के lightbox अपना ओवरले document.body के अंत में ले जाते हैं, पर rk-lightbox-overlay वहीं रेंडर होता है जहाँ आप उसे रखते हैं और position: fixed से पूरी स्क्रीन ढकता है। उसे ऐसे किसी पूर्वज के भीतर न रखें जिस पर transform, perspective, filter या will-change: transform हो: वह पूर्वज ओवरले का containing block बन जाता है, इसलिए lightbox व्यूपोर्ट की जगह उसी के आकार का हो जाता है और उसके overflow से कट जाता है। अपना स्टैकिंग कॉन्टेक्स्ट बनाने वाला पूर्वज भी सीमित करता है कि --rk-lightbox-overlay-z lightbox को कितना ऊपर उठा सकता है। बदले में, किसी भी पूर्वज पर सेट किए गए --rk-lightbox-* टोकन lightbox तक पहुँचते हैं।

टेम्पलेट स्लॉट

चार template slot directives से कंपोनेंट को fork किए बिना overlay UI पूरी तरह कस्टमाइज़ किया जा सकता है। हर slot को strongly-typed context object मिलता है।

DirectiveContext टाइपविवरण
[rkLightboxControls]LightboxControlsContextऊपर का कंट्रोल बार बदलें (बंद करने का बटन, काउंटर, फ़ुलस्क्रीन टॉगल)
[rkLightboxNavigation]LightboxNavContextprev/next नेविगेशन तीर बदलें
[rkLightboxInfo]LightboxInfoContextनीचे का शीर्षक/विवरण gradient overlay बदलें
[rkLightboxSlide]LightboxSlideContextअलग-अलग स्लाइड का कंटेंट बदलें (वीडियो स्लाइड के लिए ज़रूरी)
[rkLightboxLoading]LightboxLoadingContextकस्टम लोडिंग इंडिकेटर; directive class RkLightboxLoadingDirective है
[rkLightboxError]LightboxErrorContextकस्टम एरर इंडिकेटर; directive class 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 template slot और RkLightboxVideoSlideComponent से opt-in करना होता है। इस डिज़ाइन से जिन गैलरी को सिर्फ़ इमेज चाहिए, उनके बंडल में वीडियो प्लेयर नहीं जुड़ता।

अंतर्निर्मित sound button तभी दिखता है जब SoundStateService को <rk-lightbox-overlay> के ऊपर provide किया गया हो — वही साझा instance toggle को वीडियो तक पहुँचाता है, क्योंकि slide आपके template से render होता है। इसके बिना setLightboxVideoMuted से element को सीधे चलाएँ।

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

फ़ुलस्क्रीन

फ़ुलस्क्रीन स्टेट देखने या टॉगल करने के लिए @reelkit/angular के fullscreenSignal, requestFullscreen और exitFullscreen इस्तेमाल करें।

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 एक अलग कंपोनेंट है जिसकी खुले होने की स्टेट address bar में रहती है। createOverlayUrlState से कंट्रोलर बनाएँ और उसे [controller] के रूप में दें: जब parameter किसी स्लाइड का नाम लेता है तो गैलरी खुद खुलती है, और उसके हटते ही बंद हो जाती है। लिंक शेयर किए जा सकते हैं, और back बटन पेज छोड़ने के बजाय गैलरी बंद करता है।

बिल्ट-इन keys

आप बिल्ट-इन key से स्लाइडों को पहचान सकते हैं — कंट्रोलर में urlIndexKey (स्थिति से) या urlStableIdKey (स्थिर id से) spread करें — दोनों @reelkit/angular से भी export होते हैं। URL स्टेट गाइड और Core 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),
  });
}

इसे injection context में कॉल करें — field initialiser या constructor में। यह तुरंत जुड़ता है और DestroyRef से छूटता है, इसलिए गैलरी खुली रहते हुए नष्ट हुआ कंपोनेंट कोई listener पीछे नहीं छोड़ता। सारे विकल्प Angular API रेफ़रेंस में हैं।

  • खोलने पर history में एक entry जुड़ती है। स्लाइड बदलना उसे बदल देता है, इसलिए N कदम कोई entry नहीं जोड़ते और back का एक कदम हमेशा गैलरी छोड़ देता है।
  • Back सिर्फ़ तब बंद करता है जब गैलरी ऐप के अंदर से खोली गई हो — लिंक ने entry जोड़ी हो। नए tab में सीधे खोले गए शेयर किए गए लिंक के पीछे कोई history नहीं होती, इसलिए ब्राउज़र का back साइट छोड़ देता है; ✕ बटन या Escape parameter को उसी जगह हटाकर पेज पर बना रहता है।
  • किसी स्लाइड का नाम न लेने वाला parameter — पुराना bookmark, हाथ से बदली value — न खुल सकने वाली स्लाइड का दावा करते छोड़ने के बजाय URL से हटा दिया जाता है।
  • Template slots बिना बदलाव के काम करते हैं: url कंपोनेंट छहों slot queries खुद चलाता है और हर template गैलरी को आगे भेजता है, इसलिए rkLightboxControls और उसके साथी इसके अंदर ठीक वैसे ही रहते हैं जैसे rk-lightbox-overlay के अंदर रहते।
  • routing वाले ऐप्लिकेशन में Router पर बना adapter पास करें। Router के पीछे history लिखने से उसकी location पुरानी पड़ जाती है और उसका अगला नेविगेशन parameter गिरा देता है।

Routing वाले ऐप में adapter पास करें। Router के पीछे history लिखने से उसकी location पुरानी पड़ जाती है और उसका अगला नेविगेशन parameter गिरा देता है, इसलिए Router पर adapter बनाएँ और उसे adapter के रूप में पास करें:

typescript
import { createRouterUrlAdapter } from '@reelkit/angular/ng-router-url-adapter';

const adapter = createRouterUrlAdapter();

const photo = createOverlayUrlState({
  param: 'photo',
  adapter,
  ...urlIndexKey(() => this.images().length),
});

स्थिर लिंक। Index स्थिति पर आधारित है — सूची का क्रम बदलते ही bookmark किया गया ?photo=3 कोई दूसरी इमेज खोलता है। urlStableIdKey हर आइटम की स्थिर id से key बनाता है और मौजूदा सूची में ढूँढता है — आम मामले के लिए एक कॉल काफ़ी है।

typescript
const photo = createOverlayUrlState({
  param: 'photo',
  ...urlStableIdKey({ items: () => this.images() }),
});

URL में id को base64url में encode करने के लिए hashCodec: base64UrlCodec पास करें — वापस पढ़ा जा सकने वाला छिपाव, cryptographic hash नहीं।

किसी दूसरे field (slug) से key बनाएँ, या locateAsync से अनंत फ़ीड के पेज लोड करें, और codec (wire) और 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 synchronous है, इसलिए यह सिर्फ़ लोड हो चुकी इमेज के लिए जवाब देता है — जिस फ़ीड में 20 इमेज लोड हुई हैं, उसकी इमेज 400 का शेयर किया गया लिंक खाली लौटता है। locateAsync विकल्प है, जो सिर्फ़ locate के न मिलने पर कॉल होता है: ज़रूरी पेज लोड करें, फिर वह index लौटाएँ जो पहचान का निकला। इसके pending रहने तक गैलरी बंद रहती है और parameter को छुआ नहीं जाता, इसलिए सीधा लिंक fetch के बाद भी बना रहता है; null या rejection parameter हटा देता है।

छोटा रास्ता

आइटम की id से key बना रहे हैं? अपना codec और locator लिखना छोड़ें — locateAsync सीधे urlStableIdKey({ items, locateAsync }) को पास करें (न मिलने पर यह fetch करता है, फिर index लौटाता है)। नीचे का पूरा रूप किसी दूसरे field से key बनाने या पूरे नियंत्रण के लिए है।

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 ms) तक रहती हैं, जो इमेज लोड होने के पल से गिना जाता है, इसलिए धीमी इमेज किसी के देखने से पहले कभी नहीं छूटती। जो इमेज लोड नहीं हो पाती, उसकी गिनती उसके error से होती है।
  • वीडियो loop की जगह एक बार चलते हैं और ख़त्म होने पर आगे बढ़ते हैं। rkLightboxSlide टेम्पलेट में rk-lightbox-video-slide पर [loop]="!autoAdvance" और [onEnded]="onEnded" bind करें, जैसा वीडियो सपोर्ट में है।
  • यह रुका रहता है जब माउस किसी कंट्रोल (बटन, लिंक या कैप्शन) पर टिका हो, swipe के दौरान, और जब पेज छिपा हो, फिर वहीं से आगे चलता है जहाँ रुका था।
  • हाथ से आगे बढ़ना (तीर, keys, wheel, swipe) नई स्लाइड का interval शून्य से शुरू करता है; स्लाइडशो चालू रहता है।
  • आख़िरी स्लाइड पर यह रुक जाता है, जब तक loop सेट न हो। कंट्रोल में play/pause बटन स्टेट दिखाता है और दर्शक को इसे बदलने देता है।

स्लाइडशो Angular zone के बाहर चलता है, इसलिए इसके animation frames कोई change detection नहीं चलाते। कस्टम rkLightboxControls टेम्पलेट को isAutoAdvancing मिलता है और, सिर्फ़ autoAdvance चालू होने पर, onToggleAutoAdvance — जब यह मौजूद हो तो rk-play-pause-button रेंडर करें। टाइमिंग ख़ुद @reelkit/core का createSlideshowController है; ऑटोप्ले गाइड और 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 करके सेव की जाती है, क्योंकि ब्राउज़र cross-origin लिंक पर download attribute को नज़रअंदाज़ करता है और फ़ाइल को खोल देता। जब fetch विफल हो — आम तौर पर दूसरे origin का ऐसा सर्वर जो CORS headers नहीं भेजता — तो फ़ाइल नए टैब में खुलती है, जहाँ दर्शक उसे फिर भी सेव कर सकता है। एक क्लिक में सेव के लिए फ़ाइलें Access-Control-Allow-Origin के साथ serve करें। डाउनलोड चलते समय बटन disabled रहता है।

कस्टम rkLightboxControls टेम्पलेट को isDownloading मिलता है और, सिर्फ़ showDownload चालू होने पर, onDownload — जब यह मौजूद हो तो rk-download-button रेंडर करें। helper @reelkit/core का downloadFile है; डाउनलोड गाइड देखें।

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

कंट्रोल बटन

कंपोनेंटSelectorInputs / outputsविवरण
RkPlayPauseButtonComponentrk-play-pause-button[playing], (toggled)स्लाइडशो टॉगल (Play/Pause आइकन, चलते समय aria-pressed)। autoAdvance के साथ डिफ़ॉल्ट कंट्रोल इसे दिखाते हैं।
RkDownloadButtonComponentrk-download-button[downloading], (pressed)डाउनलोड बटन, downloading के दौरान disabled। showDownload के साथ डिफ़ॉल्ट कंट्रोल इसे दिखाते हैं।
RkSoundButtonComponentrk-sound-button[muted], (toggled)वीडियो आइटम के लिए mute टॉगल। वीडियो स्लाइड पर डिफ़ॉल्ट कंट्रोल इसे दिखाते हैं; इसे बनाए रखने के लिए अपने rkLightboxControls template में रखें।

RkLightboxUrlOverlayComponent के inputs

rk-lightbox-overlay के सारे inputs लेता है, सिवाय isOpen के, जिसकी जगह कंट्रोलर है। Outputs वही closed और slideChange हैं; बंद करना URL चलाता है, इसलिए closed तरीका नहीं, बस सूचना है।

Inputटाइपडिफ़ॉल्टविवरण
controllerUrlStateControllerrequiredcreateOverlayUrlState से मिला कंट्रोलर। इसकी स्थिति तय करती है कि गैलरी खुली है या नहीं और कौन-सी स्लाइड दिखती है; स्लाइड बदलने और बंद होने पर कंपोनेंट इसी के ज़रिए वापस लिखता है।

RkLightboxOverlayComponent के inputs

Inputटाइपडिफ़ॉल्टविवरण
isOpenbooleanज़रूरीदिखना नियंत्रित करता है; false होने पर overlay DOM से हट जाता है
itemsLightboxItem[]ज़रूरीlightbox आइटम (इमेज या वीडियो) का array
initialIndexnumber0शुरू में दिखने वाले आइटम का शून्य से शुरू होने वाला index
transitionFnTransitionTransformFnslideTransitionस्लाइड ट्रांज़िशन फ़ंक्शन। कोई बिल्ट-इन (slideTransition, flipTransition, lightboxFadeTransition, lightboxZoomTransition) import करें या अपना पास करें। छोड़ने पर slideTransition लगता है।
showInfobooleantrueशीर्षक/विवरण वाली जानकारी का overlay रेंडर करना है या नहीं
showControlsbooleantrueऊपर का कंट्रोल बार (बंद, काउंटर, फ़ुलस्क्रीन) रेंडर करना है या नहीं
showNavigationbooleantrueprev/next नेविगेशन तीर रेंडर करने हैं या नहीं
transitionDurationnumber300ms में स्लाइड एनिमेशन की अवधि
swipeDistanceFactornumber0.12स्लाइड बदलने के लिए स्वाइप दूरी का न्यूनतम हिस्सा (0–1)
swipeToCloseDirection'up' | 'down''up'मोबाइल पर स्वाइप करके बंद करने वाले जेस्चर की दिशा
loopbooleanfalseस्लाइडर आख़िरी स्लाइड से पहली पर लौटता है या नहीं
enableNavKeysbooleantrueकीबोर्ड की तीर वाली कुंजियों से नेविगेशन चालू करता है
enableWheelbooleantrueमाउस व्हील से नेविगेशन चालू करता है
wheelDebounceMsnumber200ms में व्हील इवेंट के debounce की अवधि
autoAdvancebooleanfalseगैलरी को स्लाइडशो की तरह चलाएँ। अपने-आप आगे बढ़ना देखें।
autoAdvanceIntervalnumber5000स्लाइडशो के दौरान हर इमेज कितनी देर रहती है, ms में, लोड होने के बाद से गिना जाता है
showDownloadbooleanfalseसक्रिय आइटम के लिए डाउनलोड बटन जोड़ें। डाउनलोड देखें।
ariaLabelstring'Image gallery'dialog क्षेत्र का सुलभ लेबल

ऊपर के स्लाइडर inputs (transitionDuration, swipeDistanceFactor, loop, enableNavKeys, enableWheel, wheelDebounceMs) ReelProxyProps से टाइप होते हैं। इन्हें lightbox तक आगे भेजने वाले wrapper कंपोनेंट को टाइप करने के लिए इसका इस्तेमाल करें।

RkLightboxOverlayComponent के outputs

Outputटाइपविवरण
closedEventEmitter<void>यूज़र के lightbox बंद करने पर emit होता है
slideChangeEventEmitter<number>सक्रिय स्लाइड index बदलने पर emit होता है

LightboxItem इंटरफ़ेस

Fieldटाइपज़रूरीविवरण
srcstringहाँइमेज या वीडियो का URL
type'image' | 'video'नहींआइटम का प्रकार। डिफ़ॉल्ट 'image'
posterstringनहींवीडियो आइटम की थंबनेल इमेज
titlestringनहींजानकारी वाले overlay में दिखने वाला शीर्षक
descriptionstringनहींशीर्षक के नीचे दिखने वाला विवरण
widthnumberनहींपिक्सेल में इमेज की असली चौड़ाई
heightnumberनहींपिक्सेल में इमेज की असली ऊँचाई
downloadUrlstringनहींडाउनलोड बटन क्या सेव करता है। डिफ़ॉल्ट src
downloadNamestringनहींकिस फ़ाइल नाम से सेव करना है। डिफ़ॉल्ट URL के path का आख़िरी हिस्सा

टेम्पलेट स्लॉट context के टाइप

टाइप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 template को जो मिलता है
LightboxErrorContext{ $implicit: activeIndex, item } — rkLightboxError template को जो मिलता है

ट्रांज़िशन

transitionFn input के ज़रिए कोई भी TransitionTransformFn पास करें। सिर्फ़ इस्तेमाल होने वाला ट्रांज़िशन import करने से bundler बाकी को tree-shake कर देता है। छोड़ने पर slideTransition लगता है।

फ़ंक्शनकहाँ सेविवरण
slideTransition@reelkit/angular-lightboxसामान्य हॉरिज़ॉन्टल स्लाइड (डिफ़ॉल्ट)
lightboxFadeTransition@reelkit/angular-lightboxइमेज के बीच crossfade
flipTransition@reelkit/angular-lightbox3D कार्ड पलटने का इफ़ेक्ट
lightboxZoomTransition@reelkit/angular-lightboxछोटे से सामान्य आकार तक zoom in
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 template slot इस्तेमाल करते समय लोडिंग स्टेट बताने के लिए context पर तीन lifecycle callbacks मिलते हैं। Lightbox हर स्लाइड की स्टेट ट्रैक करता है और उसके हिसाब से spinner या एरर आइकन दिखाता है। कंटेंट preloader टूटे URL cache करता है, इसलिए फ़ेल हुई स्लाइड पर दोबारा आने पर फिर से कोशिश नहीं होती।

Lifecycle callbacks

Callbackटाइपविवरण
onReady() => voidबताता है कि स्लाइड का कंटेंट सफलता से लोड हो गया (जैसे इमेज decode हुई)
onWaiting() => voidबताता है कि स्लाइड का कंटेंट लोड/buffer हो रहा है (spinner दिखाता है)
onError() => voidबताता है कि स्लाइड का कंटेंट लोड नहीं हुआ (एरर आइकन दिखाता है)

rkLightboxSlide में callbacks जोड़ना

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>

कस्टम loading template

डिफ़ॉल्ट spinner बदलने के लिए rkLightboxLoading directive इस्तेमाल करें।

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>

कस्टम error template

डिफ़ॉल्ट एरर आइकन बदलने के लिए rkLightboxError directive इस्तेमाल करें।

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 के बाद लोड होने वाली stylesheet में ज़्यादा specificity वाले selectors से इन्हें निशाना बनाया जा सकता है। रंग, आकार और z-index बदलने के लिए नीचे थीमिंग हिस्से में बताई CSS custom properties को प्राथमिकता दें।

क्लासकंपोनेंटविवरण
.rk-lightbox-overlayOverlayRoot कंटेनर (फ़ुलस्क्रीन backdrop)
.rk-lightbox-top-shadeOverlayकंट्रोल के पीछे ऊपर का gradient
.rk-lightbox-spinnerOverlayडिफ़ॉल्ट लोडिंग spinner
.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स्लाइडशो play/pause बटन (.rk-lightbox-btn के साथ)
.rk-lightbox-downloadControlsडाउनलोड बटन (.rk-lightbox-btn के साथ)
.rk-lightbox-closeControlsबंद करने का बटन
.rk-lightbox-counterControlsइमेज काउंटर chip
.rk-lightbox-navNavigationनेविगेशन तीर (prev और next दोनों)
.rk-lightbox-nav-prevNavigationपिछला तीर
.rk-lightbox-nav-nextNavigationअगला तीर
.rk-lightbox-infoInfoशीर्षक / विवरण का कंटेनर
.rk-lightbox-titleInfoइमेज का शीर्षक
.rk-lightbox-descriptionInfoइमेज का विवरण
.rk-lightbox-slideSlideस्लाइड कंटेनर
.rk-lightbox-imgSlideइमेज एलिमेंट
.rk-lightbox-video-containerVideoSlideवीडियो स्लाइड कंटेनर (opt-in)
.rk-lightbox-video-elementVideoSlideवीडियो एलिमेंट (opt-in)
.rk-lightbox-video-posterVideoSlideवीडियो की poster इमेज (opt-in)
.rk-lightbox-video-errorVideoSlideवीडियो की एरर स्टेट का कंटेनर

थीमिंग

हर रंग, आकार, z-index और ट्रांज़िशन एक CSS custom property में है। कंपोनेंट का source छुए बिना थीम बदलने के लिए :root (या lightbox के किसी भी ancestor) पर एक या कई override करें। Tokens React lightbox से मेल खाते हैं, इसलिए overrides एक binding से दूसरी में ले जाए जा सकते हैं।

Tokenडिफ़ॉल्टक्या नियंत्रित करता है
--rk-lightbox-overlay-bg#000फ़ुलस्क्रीन backdrop का रंग
--rk-lightbox-overlay-z9999Overlay का z-index
--rk-lightbox-top-shade-height80pxऊपर के gradient की ऊँचाई
--rk-lightbox-top-shade-bglinear-gradient(rgba(0,0,0,0.6), transparent)ऊपर के gradient का रंग
--rk-lightbox-edge-padding16pxबंद / नेविगेशन / ऊपर-बाएँ कंट्रोल की किनारे से दूरी
--rk-lightbox-controls-gap12pxऊपर-बाएँ कंट्रोल के बीच की दूरी
--rk-lightbox-transition0.2sबटन hover ट्रांज़िशन की अवधि
--rk-lightbox-blur8pxबटन / chips के backdrop blur का radius
--rk-lightbox-btn-bgrgba(0, 0, 0, 0.5)बंद, नेविगेशन और छोटे बटन का डिफ़ॉल्ट background
--rk-lightbox-btn-bg-hoverrgba(255, 255, 255, 0.2)बंद, नेविगेशन और छोटे बटन का hover background
--rk-lightbox-btn-fg#fffबंद, नेविगेशन और छोटे बटन के आइकन का रंग
--rk-lightbox-btn-size36pxछोटे बटन का आकार (फ़ुलस्क्रीन टॉगल वगैरह)
--rk-lightbox-btn-disabled-opacity0.5disabled छोटे बटन की opacity (डाउनलोड चलते समय)
--rk-lightbox-close-size40pxबंद करने के बटन का आकार
--rk-lightbox-nav-size48pxprev/next तीर का आकार
--rk-lightbox-nav-opacity0.7आराम की हालत में prev/next तीरों की opacity
--rk-lightbox-counter-fg#fffकाउंटर के टेक्स्ट का रंग
--rk-lightbox-counter-bgrgba(0, 0, 0, 0.5)काउंटर chip का background
--rk-lightbox-counter-size14pxकाउंटर का font size
--rk-lightbox-counter-padding6px 12pxकाउंटर chip की padding
--rk-lightbox-counter-radius20pxकाउंटर chip का border-radius
--rk-lightbox-spinner-size28pxडिफ़ॉल्ट spinner की चौड़ाई/ऊँचाई
--rk-lightbox-spinner-duration0.8sspinner के घूमने की अवधि
--rk-lightbox-error-fgrgba(255, 255, 255, 0.4)एरर आइकन + टेक्स्ट का रंग
--rk-lightbox-info-bglinear-gradient(transparent, rgba(0,0,0,0.8))कैप्शन के पीछे का gradient
--rk-lightbox-info-padding24pxकैप्शन की अंदरूनी padding
--rk-lightbox-title-size18pxशीर्षक का font size
--rk-lightbox-description-size14pxविवरण का font size
--rk-lightbox-hint-fgrgba(255, 255, 255, 0.5)स्वाइप संकेत के टेक्स्ट का रंग
--rk-lightbox-hint-bgrgba(0, 0, 0, 0.3)स्वाइप संकेत chip का background
--rk-lightbox-video-bg#000<video> के पीछे letterbox background

नीचे का snippet @reelkit/angular-lightbox/styles.css के बाद लोड होने वाली stylesheet में डालें।

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)
  );
}

सुलभता

Overlay का root एक modal dialog है (role="dialog", aria-modal="true")। स्क्रीन रीडर की घोषणा बदलने के लिए ariaLabel input सेट करें; डिफ़ॉल्ट "Image gallery" है। हर स्लाइड पर role="group", aria-roledescription="slide" और इमेज के शीर्षक व स्थिति से बना aria-label होता है।

Lightbox खुलने पर फ़ोकस पकड़ता है और बंद होने पर उसे trigger पर लौटा देता है। Tab और Shift+Tab अंदर के फ़ोकस होने वाले एलिमेंट में घूमते हैं; बाहर निकला फ़ोकस (बाहर क्लिक, प्रोग्राम से फ़ोकस) वापस खींच लिया जाता है। यह @reelkit/core के captureFocusForReturn और createFocusTrap से बना है।

कीबोर्ड शॉर्टकट

कुंजीक्रिया
ArrowLeftपिछली इमेज
ArrowRightअगली इमेज
Escapelightbox बंद करें (या चालू हो तो फ़ुलस्क्रीन से बाहर आएँ)