# Video galerisi: ücretsiz Shopify bölümü

> Erişilebilir bir lightbox’ta açılan video kapaklarından bir ızgara. Shopify, YouTube ya da Vimeo; oynat’a basılana kadar üçüncü taraf hiçbir şey yüklenmez.

Video galerisi, birkaç videoyu kapak görsellerinden oluşan bir ızgarada, başlıkları ve süre gibi isteğe bağlı bir açıklamayla gösteren ve tıklanan videoyu bir lightbox’ta oynatan ücretsiz bir Shopify bölümüdür. Her video bir bloktur: Shopify’a yüklenmiş bir video ya da bir YouTube veya Vimeo bağlantısı. Oynatıcı yalnızca tıklanınca oluşturulur (YouTube youtube-nocookie.com üzerinden, Vimeo Do Not Track ile) ve lightbox kapanınca kaldırılır; yani sayfayla birlikte hiçbir üçüncü taraf oynatıcı yüklenmez. Lightbox, Esc, kapat düğmesi ya da dışarıya tıklamayla kapanan ve odağı tıklanan videoya geri veren yerleşik bir modal penceredir. Online Store 2.0 temalarında uygulama olmadan çalışır.

- **Kategori:** Görsel ve video
- **Kullanıldığı yerler:** Ana sayfa, Hakkımızda, Ürün, Açılış sayfaları
- **Okuduğu veri:** Shopify’da barındırılan videolar ya da YouTube/Vimeo bağlantıları
- **Boyut:** 1 dosyada 22 KB, küçük bir betikle
- **Lisans:** MIT, © 2026 Lintel
- **Sayfa:** https://lintelagency.com/tr/kaynaklar/shopify-bolumleri/video-galerisi
- **Canlı demo:** https://lintelagency.com/resources/shopify-sections/demo/lib-video-gallery.html
- **Eklenme tarihi:** 2026-11-02

## Ne işe yarar

- Bir ürün grubuna ait kullanım, bakım ya da kombin videolarını tek sayfada toplamak
- Hakkımızda sayfasında atölyenizin perde arkası videoları
- Açılış sayfasında kampanya ya da lansman filmlerinden bir galeri

## Tema düzenleyici ayarları

Bölüm tema düzenleyicide “Lib · Video gallery” adıyla görünür. Kimlikler, türler, etiketler ve varsayılan değerler bölümün şemasından gelir. Etiketler tema düzenleyicide göründüğü gibi İngilizcedir.

### Heading

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `heading` | `inline_richtext` | Heading | Inside the studio |  |
| `heading_tag` | `select` | Heading tag | h2 | `h1`, `h2`, `h3`, `p` |
| `heading_size` | `select` | Heading size | large | `small`, `medium`, `large`, `xlarge` |
| `text` | `richtext` | Text | `<p>Short films from the wheel, the kiln and the packing table.</p>` |  |

### Grid

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `columns_desktop` | `range` | Columns on desktop | `3` | 2–4, step 1 |
| `columns_mobile` | `select` | Columns on mobile | 1 | `1`, `2` |
| `tile_ratio` | `select` | Poster shape | landscape | `landscape`, `square`, `portrait` |
| `image_radius` | `range` | Poster corner radius | `12` | 0–32 px, step 2 |

### Words for shoppers and screen readers

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `play_label` | `text` | Play label | Play video |  |
| `close_label` | `text` | Close button label | Close video |  |

### Layout

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `section_width` | `select` | Width | page | `page`, `full` |
| `text_alignment` | `text_alignment` | Heading alignment on desktop | left |  |
| `text_alignment_mobile` | `select` | Heading alignment on mobile | left | `left`, `center`, `right` |

### Colors

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `color_bg` | `color` | Background | #F4EFE8 |  |
| `color_bg_gradient` | `color_background` | Background gradient | – |  |
| `color_text` | `color` | Text | #2A2420 |  |
| `color_accent` | `color` | Accent (play button, focus ring) | #2A2420 |  |
| `color_accent_text` | `color` | Text on accent | #FFFFFF |  |

### Spacing and visibility

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `padding_top` | `range` | Top padding on desktop | `80` | 0–200 px, step 4 |
| `padding_bottom` | `range` | Bottom padding on desktop | `80` | 0–200 px, step 4 |
| `padding_top_mobile` | `range` | Top padding on mobile | `48` | 0–160 px, step 4 |
| `padding_bottom_mobile` | `range` | Bottom padding on mobile | `48` | 0–160 px, step 4 |
| `show_on` | `select` | Show on | all | `all`, `desktop`, `mobile` |
| `anchor_id` | `text` | Anchor ID | – |  |

### Motion

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `animate` | `checkbox` | Rise in on scroll | `false` |  |

## Bloklar

Toplamda en fazla 12 blok.

### Video (`video`)

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `video` | `video` | Shopify-hosted video | – |  |
| `video_url` | `video_url` | Or a YouTube or Vimeo link | – |  |
| `poster` | `image_picker` | Poster image | – |  |
| `title` | `text` | Title | Video title |  |
| `caption` | `text` | Caption | – |  |

## Kurulum

### Shopify yönetim panelinde

1. Canlı temanızda değil, bir kopyasında çalışın: Shopify yönetim panelinde **Online Mağaza > Temalar** sayfasına gidin, mevcut temanızın **…** menüsünü açın ve **Kopya oluştur**’u seçin.
2. Kopyada **…** menüsünü açın ve **Kodu düzenle**’yi seçin.
3. `sections` klasörüne `lib-video-gallery.liquid` adında yeni bir dosya ekleyin, aşağıdaki kaynak koddan `sections/lib-video-gallery.liquid` içeriğini yapıştırıp kaydedin.
4. Kopyada **Özelleştir**’i açın, **Bölüm ekle**’yi seçin ve **Lib · Video gallery** bölümünü ekleyin. Örnek içeriği kendi içeriğinizle değiştirin, renkleri ayarlayın.
5. Kopyayı önizleyin, her şey doğru göründüğünde yayınlayın.

### Shopify CLI ile

Yerel tema klasörünüzde dosyaları indirin ve yalnızca bunları yayında olmayan bir temaya gönderin (temanın kimliğini `shopify theme list` gösterir):

```sh
curl -fsSL -o sections/lib-video-gallery.liquid https://lintelagency.com/resources/shopify-sections/files/lib-video-gallery.liquid
shopify theme push --theme <unpublished-theme-id> --only sections/lib-video-gallery.liquid
```

Canlı temaya asla göndermeyin: her zaman yayında olmayan bir temanın kimliğini verin, `--live` ya da `--allow-live` kullanmayın. Ardından bölümü yukarıdaki gibi tema düzenleyicide ekleyin.

## Dosyalar

- [sections/lib-video-gallery.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-video-gallery.liquid): `sections/` klasörüne

## Sık sorulan sorular

### Sayfayı yavaşlatır mı?

Hayır. Sayfayla birlikte hiçbir oynatıcı yüklenmez, yalnızca geç yüklenen (lazy load) kapak görselleri gelir. YouTube, Vimeo ya da Shopify oynatıcısı, müşteri bir videoya tıklayınca eklenir ve lightbox kapanınca kaldırılır; bu da oynatmayı durdurur.

### YouTube ve Vimeo çerez bırakıyor mu?

Müşteri bir videoyu oynatmadan önce hayır. Oynatıldığında YouTube videoları YouTube’un gizlilik geliştirilmiş modu olan youtube-nocookie.com’dan, Vimeo videoları ise Do Not Track açıkken oynar. Oynatıcılar çalışmaya başladıktan sonra ziyaretçiden onay almanız gerekip gerekmediği, satış yaptığınız pazara bağlıdır; bölüm oynatıcıları asla kendiliğinden yüklemez.

### Lightbox erişilebilir mi?

Videonun başlığıyla etiketlenmiş yerleşik bir modal penceredir. Açıkken sayfanın geri kalanı kullanılamaz; Esc, kapat düğmesi ya da karanlık alana tıklamak onu kapatır ve odak açtığınız videoya döner. Oynat ve kapat etiketleri birer ayardır; değiştirebilir ya da çevirebilirsiniz.

### JavaScript olmadan ne oluyor?

Her kapak normal bir bağlantı olarak çalışır: Shopify videosu kendi dosyasını açar, YouTube ya da Vimeo videosu kendi sitesinde açılır.

### YouTube ve Vimeo videoları için kapak görseli gerekiyor mu?

Evet, her bloğa bir tane ekleyin; Shopify’da barındırılan videolar kapak boşsa kendi önizleme görsellerini kullanır. Kapağın oynayan videoyla uyumlu olması için videonun kendisinden bir kare kullanın.

## Kaynak kod

### sections/lib-video-gallery.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{%- comment -%}
  Video gallery: a grid of video tiles (one block each: a Shopify-hosted video or a YouTube/Vimeo
  link, a poster image, a title and an optional caption such as the length). A tile opens the video
  in one shared lightbox (a native modal <dialog>: labelled, closes with Esc, the close button or a
  click on the backdrop, focus goes back to the tile). Nothing third-party loads with the page: the
  player is created on click (YouTube through youtube-nocookie.com, Vimeo with dnt=1) and removed
  on close. Without JavaScript each tile is a plain link to the video.
  Depends on: none
{%- endcomment -%}

{%- liquid
  assign s = section.settings
  assign heading_tag = s.heading_tag | default: 'h2'
  assign dialog_title_id = 'LibVideoGalleryTitle-' | append: section.id
  assign play_label = s.play_label | default: 'Play video' | escape
-%}

<div
  class="lib-vgallery lib-vgallery--{{ s.section_width }}"
  {% if s.anchor_id != blank %}
    id="{{ s.anchor_id | handleize }}"
  {% endif %}
  data-show="{{ s.show_on }}"
  data-ratio="{{ s.tile_ratio }}"
  {% if s.animate %}
    data-animate
  {% endif %}
  style="
    --lib-bg: {{ s.color_bg }};
    {% if s.color_bg_gradient != blank %}--lib-bg-image: {{ s.color_bg_gradient }};{% endif %}
    --lib-text: {{ s.color_text }};
    --lib-accent: {{ s.color_accent }};
    --lib-accent-text: {{ s.color_accent_text }};
    --lib-cols: {{ s.columns_desktop }};
    --lib-cols-m: {{ s.columns_mobile }};
    --lib-radius-img: {{ s.image_radius }}px;
    --lib-pt: {{ s.padding_top }}px;
    --lib-pb: {{ s.padding_bottom }}px;
    --lib-pt-m: {{ s.padding_top_mobile }}px;
    --lib-pb-m: {{ s.padding_bottom_mobile }}px;
  "
>
  <lib-video-gallery class="lib-vgallery__inner">
    {%- if s.heading != blank or s.text != blank -%}
      <div class="lib-vgallery__header" data-align="{{ s.text_alignment }}" data-align-m="{{ s.text_alignment_mobile }}">
        {%- if s.heading != blank -%}
          <{{ heading_tag }} class="lib-vgallery__heading lib-vgallery__heading--{{ s.heading_size }}">
            {{- s.heading -}}
          </{{ heading_tag }}>
        {%- endif -%}
        {%- if s.text != blank -%}
          <div class="lib-vgallery__text">{{ s.text }}</div>
        {%- endif -%}
      </div>
    {%- endif -%}

    <ul class="lib-vgallery__grid" role="list">
      {%- for block in section.blocks -%}
        {%- liquid
          assign b = block.settings
          assign src_type = ''
          assign src_id = ''
          assign href = ''
          assign embed = ''
          assign ratio = '16 / 9'
          if b.video != blank
            assign src_type = 'shopify'
            for source in b.video.sources
              if source.mime_type == 'video/mp4'
                assign href = source.url
                break
              endif
            endfor
            if b.video.aspect_ratio != blank
              assign ratio = b.video.aspect_ratio
            endif
          elsif b.video_url != blank
            assign src_type = b.video_url.type
            assign src_id = b.video_url.id
            if src_type == 'youtube'
              assign href = 'https://www.youtube.com/watch?v=' | append: src_id
              assign embed = 'https://www.youtube-nocookie.com/embed/' | append: src_id | append: '?autoplay=1&playsinline=1&rel=0'
            elsif src_type == 'vimeo'
              assign href = 'https://vimeo.com/' | append: src_id
              assign embed = 'https://player.vimeo.com/video/' | append: src_id | append: '?dnt=1&autoplay=1'
            endif
          endif
          assign poster = b.poster
          if poster == blank and src_type == 'shopify'
            assign poster = b.video.preview_image
          endif
          assign title = b.title | default: 'Video' | escape
        -%}
        <li class="lib-vgallery__item" {{ block.shopify_attributes }}>
          {%- capture tile_inner -%}
            <span class="lib-vgallery__poster">
              {%- if poster != blank -%}
                {{
                  poster
                  | image_url: width: 1200
                  | image_tag:
                    class: 'lib-vgallery__img',
                    loading: 'lazy',
                    alt: '',
                    sizes: '(min-width: 990px) 33vw, (min-width: 750px) 50vw, 100vw',
                    widths: '400, 600, 800, 1000, 1200'
                }}
              {%- else -%}
                {{ 'lifestyle-1' | placeholder_svg_tag: 'lib-vgallery__img' }}
              {%- endif -%}
              <span class="lib-vgallery__play" aria-hidden="true">
                <svg viewBox="0 0 24 24" width="22" height="22" focusable="false"><path d="M8 5.5v13l10.5-6.5z" fill="currentColor"/></svg>
              </span>
            </span>
            <span class="lib-vgallery__meta">
              <span class="lib-vgallery__title">{{ title }}</span>
              {%- if b.caption != blank -%}
                <span class="lib-vgallery__caption">{{ b.caption | escape }}</span>
              {%- endif -%}
            </span>
          {%- endcapture -%}

          {%- if href != blank -%}
            <a
              class="lib-vgallery__tile"
              href="{{ href }}"
              data-title="{{ title }}"
              data-ratio="{{ ratio }}"
              aria-label="{{ play_label }}: {{ title }}{% if b.caption != blank %}, {{ b.caption | escape }}{% endif %}"
            >
              {{- tile_inner -}}
            </a>
            <template class="lib-vgallery__tpl">
              {%- if src_type == 'shopify' -%}
                {{
                  b.video
                  | video_tag:
                    class: 'lib-vgallery__media',
                    autoplay: true,
                    controls: true,
                    playsinline: true,
                    preload: 'metadata'
                }}
              {%- else -%}
                <iframe
                  class="lib-vgallery__media"
                  src="{{ embed | escape }}"
                  title="{{ title }}"
                  allow="autoplay; encrypted-media; picture-in-picture; fullscreen"
                  allowfullscreen
                  referrerpolicy="strict-origin-when-cross-origin"
                ></iframe>
              {%- endif -%}
            </template>
          {%- else -%}
            <div class="lib-vgallery__tile lib-vgallery__tile--empty">{{- tile_inner -}}</div>
          {%- endif -%}
        </li>
      {%- endfor -%}
    </ul>

    <dialog class="lib-vgallery__dialog" aria-labelledby="{{ dialog_title_id }}">
      <p class="lib-vgallery__dialog-title" id="{{ dialog_title_id }}"></p>
      <button type="button" class="lib-vgallery__close" aria-label="{{ s.close_label | default: 'Close video' | escape }}">
        <svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true" focusable="false"><path d="M6 6l12 12M18 6 6 18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
      </button>
      <div class="lib-vgallery__frame"></div>
    </dialog>
  </lib-video-gallery>
</div>

{% stylesheet %}
  .lib-vgallery {
    background-color: var(--lib-bg);
    background-image: var(--lib-bg-image, none);
    color: var(--lib-text);
    padding: var(--lib-pt) 1rem var(--lib-pb);
  }
  .lib-vgallery__inner { display: block; max-width: 1200px; margin: 0 auto; }
  .lib-vgallery--full .lib-vgallery__inner { max-width: none; }
  @media (max-width: 749px) {
    .lib-vgallery { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); }
    .lib-vgallery[data-show='desktop'] { display: none; }
  }
  @media (min-width: 750px) {
    .lib-vgallery[data-show='mobile'] { display: none; }
  }

  .lib-vgallery__header { display: flex; flex-direction: column; align-items: flex-start; text-align: left; margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
  .lib-vgallery__header[data-align='center'] { align-items: center; text-align: center; }
  .lib-vgallery__header[data-align='right'] { align-items: flex-end; text-align: right; }
  @media (max-width: 749px) {
    .lib-vgallery__header[data-align-m='left'] { align-items: flex-start; text-align: left; }
    .lib-vgallery__header[data-align-m='center'] { align-items: center; text-align: center; }
    .lib-vgallery__header[data-align-m='right'] { align-items: flex-end; text-align: right; }
  }
  .lib-vgallery__heading { margin: 0; font-size: clamp(1.75rem, 3.4vw, 2.75rem); line-height: 1.1; letter-spacing: -0.02em; text-wrap: balance; }
  .lib-vgallery__heading--small { font-size: clamp(1.375rem, 2.2vw, 1.75rem); }
  .lib-vgallery__heading--medium { font-size: clamp(1.5rem, 2.8vw, 2.25rem); }
  .lib-vgallery__heading--xlarge { font-size: clamp(2.25rem, 5vw, 3.75rem); }
  .lib-vgallery__text { margin-top: 0.875rem; max-width: 40rem; font-size: 1.0625rem; line-height: 1.6; opacity: 0.82; }
  .lib-vgallery__text > :first-child { margin-top: 0; }
  .lib-vgallery__text > :last-child { margin-bottom: 0; }

  .lib-vgallery__grid {
    display: grid;
    grid-template-columns: repeat(var(--lib-cols-m), minmax(0, 1fr));
    gap: clamp(1rem, 2.5vw, 1.75rem);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  @media (min-width: 750px) {
    .lib-vgallery__grid { grid-template-columns: repeat(min(var(--lib-cols), 2), minmax(0, 1fr)); }
  }
  @media (min-width: 990px) {
    .lib-vgallery__grid { grid-template-columns: repeat(var(--lib-cols), minmax(0, 1fr)); }
  }

  .lib-vgallery__tile {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    color: inherit;
    text-decoration: none;
    border-radius: var(--lib-radius-img);
  }
  .lib-vgallery__tile:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 4px; }
  .lib-vgallery__poster {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--lib-radius-img);
    aspect-ratio: 16 / 9;
    background: color-mix(in srgb, var(--lib-text) 8%, transparent);
  }
  .lib-vgallery[data-ratio='square'] .lib-vgallery__poster { aspect-ratio: 1; }
  .lib-vgallery[data-ratio='portrait'] .lib-vgallery__poster { aspect-ratio: 4 / 5; }
  .lib-vgallery__img { display: block; width: 100%; height: 100%; object-fit: cover; }
  .lib-vgallery__img:is(svg) { fill: color-mix(in srgb, var(--lib-text) 25%, transparent); }
  .lib-vgallery__play {
    position: absolute;
    inset: 50% auto auto 50%;
    display: grid;
    place-items: center;
    width: 3.5rem;
    height: 3.5rem;
    margin: -1.75rem 0 0 -1.75rem;
    border-radius: 50%;
    background: var(--lib-accent);
    color: var(--lib-accent-text);
    box-shadow: 0 10px 24px -10px rgb(0 0 0 / 0.5);
  }
  .lib-vgallery__play svg { margin-left: 3px; }
  .lib-vgallery__meta { display: grid; gap: 0.25rem; }
  .lib-vgallery__title { font-weight: 600; font-size: 1.0625rem; line-height: 1.35; }
  .lib-vgallery__caption { font-size: 0.9375rem; opacity: 0.75; }
  @media (prefers-reduced-motion: no-preference) {
    .lib-vgallery__img, .lib-vgallery__play { transition: transform 0.4s ease; }
    .lib-vgallery__tile:hover .lib-vgallery__img { transform: scale(1.03); }
    .lib-vgallery__tile:hover .lib-vgallery__play { transform: scale(1.08); }
  }

  /* Lightbox */
  .lib-vgallery__dialog {
    width: 100vw;
    max-width: none;
    height: 100vh;
    max-height: none;
    margin: 0;
    padding: 4.5rem 1rem 2rem;
    border: 0;
    background: transparent;
    color: #fff;
  }
  .lib-vgallery__dialog[open] { display: grid; grid-template-rows: auto 1fr; justify-items: center; align-items: center; }
  .lib-vgallery__dialog::backdrop { background: rgb(12 10 9 / 0.9); }
  .lib-vgallery__dialog-title {
    position: absolute;
    top: 1.25rem;
    left: 1.25rem;
    right: 4.5rem;
    margin: 0;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .lib-vgallery__frame {
    grid-row: 2;
    width: min(100%, 1280px, calc((100vh - 7rem) * (var(--lib-dialog-ratio, 16 / 9))));
    aspect-ratio: var(--lib-dialog-ratio, 16 / 9);
    background: #000;
  }
  .lib-vgallery__media { display: block; width: 100%; height: 100%; border: 0; }
  .lib-vgallery__close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 0;
    border-radius: 50%;
    background: rgb(255 255 255 / 0.14);
    color: #fff;
    cursor: pointer;
  }
  .lib-vgallery__close:hover { background: rgb(255 255 255 / 0.24); }
  .lib-vgallery__close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .lib-vgallery[data-animate] .lib-vgallery__item {
        animation: lib-vgallery-rise linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 60%;
      }
    }
  }
  @keyframes lib-vgallery-rise {
    from { opacity: 0; transform: translateY(24px); }
  }
{% endstylesheet %}

{% javascript %}
  if (!customElements.get('lib-video-gallery')) {
    customElements.define(
      'lib-video-gallery',
      class extends HTMLElement {
        connectedCallback() {
          if (this._ready) return;
          this.dialog = this.querySelector('.lib-vgallery__dialog');
          if (!this.dialog || typeof this.dialog.showModal !== 'function') return;
          this._ready = true;
          this.frame = this.dialog.querySelector('.lib-vgallery__frame');
          this.titleEl = this.dialog.querySelector('.lib-vgallery__dialog-title');
          this.closeBtn = this.dialog.querySelector('.lib-vgallery__close');
          this.tiles = Array.from(this.querySelectorAll('a.lib-vgallery__tile'));
          this.tiles.forEach((tile) => tile.setAttribute('aria-haspopup', 'dialog'));

          this.onClick = (event) => {
            const tile = event.target.closest('a.lib-vgallery__tile');
            if (!tile || !this.contains(tile)) return;
            if (event.metaKey || event.ctrlKey || event.shiftKey || event.button === 1) return;
            event.preventDefault();
            this.open(tile);
          };
          this.onClose = () => this.closed();
          this.onCloseBtn = () => this.dialog.close();
          this.onBackdrop = (event) => {
            if (event.target === this.dialog) this.dialog.close();
          };
          this.addEventListener('click', this.onClick);
          this.dialog.addEventListener('close', this.onClose);
          this.dialog.addEventListener('click', this.onBackdrop);
          this.closeBtn.addEventListener('click', this.onCloseBtn);
        }

        disconnectedCallback() {
          if (!this._ready) return;
          this._ready = false;
          this.removeEventListener('click', this.onClick);
          this.dialog.removeEventListener('close', this.onClose);
          this.dialog.removeEventListener('click', this.onBackdrop);
          this.closeBtn.removeEventListener('click', this.onCloseBtn);
          if (this.dialog.open) this.dialog.close();
        }

        // The player comes from the tile's inert template, so nothing loads before this click.
        open(tile) {
          const tpl = tile.nextElementSibling;
          if (!tpl || tpl.tagName !== 'TEMPLATE') return;
          this.opener = tile;
          this.titleEl.textContent = tile.dataset.title || '';
          this.dialog.style.setProperty('--lib-dialog-ratio', tile.dataset.ratio || '16 / 9');
          this.frame.replaceChildren(tpl.content.cloneNode(true));
          this.dialog.showModal();
          this.closeBtn.focus();
          const video = this.frame.querySelector('video');
          if (video) {
            const playing = video.play();
            if (playing && playing.catch) playing.catch(() => {});
          }
        }

        // Removing the player stops playback and any third-party connection it opened.
        closed() {
          this.frame.replaceChildren();
          if (this.opener && this.opener.isConnected) this.opener.focus();
          this.opener = null;
        }
      }
    );
  }
{% endjavascript %}

{% schema %}
{
  "name": "Lib · Video gallery",
  "tag": "section",
  "class": "lib-section",
  "max_blocks": 12,
  "settings": [
    { "type": "header", "content": "Heading" },
    { "type": "inline_richtext", "id": "heading", "label": "Heading", "default": "Inside the studio" },
    {
      "type": "select",
      "id": "heading_tag",
      "label": "Heading tag",
      "info": "Use H1 only when this is the page's main heading.",
      "options": [
        { "value": "h1", "label": "H1" },
        { "value": "h2", "label": "H2" },
        { "value": "h3", "label": "H3" },
        { "value": "p", "label": "Paragraph" }
      ],
      "default": "h2"
    },
    {
      "type": "select",
      "id": "heading_size",
      "label": "Heading size",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" },
        { "value": "xlarge", "label": "Extra large" }
      ],
      "default": "large"
    },
    { "type": "richtext", "id": "text", "label": "Text", "default": "<p>Short films from the wheel, the kiln and the packing table.</p>" },

    { "type": "header", "content": "Grid" },
    { "type": "range", "id": "columns_desktop", "label": "Columns on desktop", "min": 2, "max": 4, "step": 1, "default": 3 },
    {
      "type": "select",
      "id": "columns_mobile",
      "label": "Columns on mobile",
      "options": [
        { "value": "1", "label": "1" },
        { "value": "2", "label": "2" }
      ],
      "default": "1"
    },
    {
      "type": "select",
      "id": "tile_ratio",
      "label": "Poster shape",
      "options": [
        { "value": "landscape", "label": "Landscape (16:9)" },
        { "value": "square", "label": "Square" },
        { "value": "portrait", "label": "Portrait (4:5)" }
      ],
      "default": "landscape"
    },
    { "type": "range", "id": "image_radius", "label": "Poster corner radius", "min": 0, "max": 32, "step": 2, "unit": "px", "default": 12 },

    { "type": "header", "content": "Words for shoppers and screen readers" },
    { "type": "text", "id": "play_label", "label": "Play label", "info": "Read before each video's title.", "default": "Play video" },
    { "type": "text", "id": "close_label", "label": "Close button label", "default": "Close video" },

    { "type": "header", "content": "Layout" },
    {
      "type": "select",
      "id": "section_width",
      "label": "Width",
      "options": [
        { "value": "page", "label": "Page width" },
        { "value": "full", "label": "Full width" }
      ],
      "default": "page"
    },
    { "type": "text_alignment", "id": "text_alignment", "label": "Heading alignment on desktop", "default": "left" },
    {
      "type": "select",
      "id": "text_alignment_mobile",
      "label": "Heading alignment on mobile",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "center", "label": "Center" },
        { "value": "right", "label": "Right" }
      ],
      "default": "left"
    },

    { "type": "header", "content": "Colors" },
    { "type": "color", "id": "color_bg", "label": "Background", "default": "#F4EFE8" },
    { "type": "color_background", "id": "color_bg_gradient", "label": "Background gradient", "info": "Optional. Covers the background color." },
    { "type": "color", "id": "color_text", "label": "Text", "default": "#2A2420" },
    { "type": "color", "id": "color_accent", "label": "Accent (play button, focus ring)", "default": "#2A2420" },
    { "type": "color", "id": "color_accent_text", "label": "Text on accent", "default": "#FFFFFF" },

    { "type": "header", "content": "Spacing and visibility" },
    { "type": "range", "id": "padding_top", "label": "Top padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 80 },
    { "type": "range", "id": "padding_bottom", "label": "Bottom padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 80 },
    { "type": "range", "id": "padding_top_mobile", "label": "Top padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 48 },
    { "type": "range", "id": "padding_bottom_mobile", "label": "Bottom padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 48 },
    {
      "type": "select",
      "id": "show_on",
      "label": "Show on",
      "options": [
        { "value": "all", "label": "All devices" },
        { "value": "desktop", "label": "Desktop only" },
        { "value": "mobile", "label": "Mobile only" }
      ],
      "default": "all"
    },
    { "type": "text", "id": "anchor_id", "label": "Anchor ID", "info": "Optional. Link to this section with #your-id." },

    { "type": "header", "content": "Motion" },
    { "type": "checkbox", "id": "animate", "label": "Rise in on scroll", "info": "Only in browsers that support scroll-driven animations; never when reduced motion is on.", "default": false }
  ],
  "blocks": [
    {
      "type": "video",
      "name": "Video",
      "settings": [
        { "type": "video", "id": "video", "label": "Shopify-hosted video", "info": "Upload in Content > Files. Used before the link below." },
        { "type": "video_url", "id": "video_url", "label": "Or a YouTube or Vimeo link", "accept": ["youtube", "vimeo"], "info": "Loads only when a shopper plays it (youtube-nocookie.com, Vimeo with Do Not Track)." },
        { "type": "image_picker", "id": "poster", "label": "Poster image", "info": "Needed for YouTube and Vimeo. Shopify videos use their own preview image when empty." },
        { "type": "text", "id": "title", "label": "Title", "default": "Video title" },
        { "type": "text", "id": "caption", "label": "Caption", "info": "Optional, for example the length: 2 min." }
      ]
    }
  ],
  "presets": [
    {
      "name": "Lib · Video gallery",
      "blocks": [
        { "type": "video", "settings": { "title": "Throwing a vase" } },
        { "type": "video", "settings": { "title": "Glazing day" } },
        { "type": "video", "settings": { "title": "Packing an order" } }
      ]
    }
  ]
}
{% endschema %}
```

## Lisans

MIT Lisansı, © 2026 Lintel. Kendi mağazanızda ya da müşteri işlerinde ücretsiz kullanabilir, değiştirebilir ve yayınlayabilirsiniz; her dosyanın başındaki lisans satırını koruyun.
