@growth-labs/video 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-labs/video",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -36,7 +36,14 @@ const src = premium
36
36
  ? premiumManifestUrl(config.premium!.playbackRoute, videoId)
37
37
  : manifestUrl(config.publicDomain, videoId)
38
38
 
39
- const poster = Astro.props.poster ?? posterUrl(config.publicDomain, videoId)
39
+ // Convention-URL fallback fires only when the caller omits `poster` entirely.
40
+ // Explicit `poster={null | undefined | ""}` is treated as "no poster" so that
41
+ // consumers passing through video metadata with a missing posterUrl don't get
42
+ // a 404'd /cdn-cgi/image/.../poster.jpg attribute (broken-image icon).
43
+ const poster =
44
+ 'poster' in Astro.props
45
+ ? Astro.props.poster || undefined
46
+ : posterUrl(config.publicDomain, videoId)
40
47
  const chaptersSrc = showChapters ? chaptersUrl(config.publicDomain, videoId) : null
41
48
  const captionsSrc = showCaptions
42
49
  ? captionsUrl(config.publicDomain, videoId, captionsLang)
@@ -6,6 +6,7 @@ interface Item {
6
6
  title: string
7
7
  href: string
8
8
  durationSeconds?: number
9
+ poster?: string | null
9
10
  }
10
11
 
11
12
  interface Props {
@@ -14,16 +15,24 @@ interface Props {
14
15
  }
15
16
 
16
17
  const { items, class: className } = Astro.props
18
+ // Only forward `poster` to VideoPreview when the item literal carries the key.
19
+ // Preserves VideoPreview's discriminator: items without a `poster` key fall
20
+ // back to the convention URL; items with `poster: null | undefined | ""`
21
+ // explicitly opt out of any <img> render.
22
+ const previewItems = items.map((item) => ({
23
+ common: {
24
+ videoId: item.videoId,
25
+ title: item.title,
26
+ href: item.href,
27
+ durationSeconds: item.durationSeconds,
28
+ },
29
+ posterProps: ('poster' in item ? { poster: item.poster } : {}) as { poster?: string | null },
30
+ }))
17
31
  ---
18
32
 
19
33
  <div class={`gl-video-gallery ${className ?? ''}`.trim()}>
20
- {items.map((item) => (
21
- <VideoPreview
22
- videoId={item.videoId}
23
- title={item.title}
24
- href={item.href}
25
- durationSeconds={item.durationSeconds}
26
- />
34
+ {previewItems.map(({ common, posterProps }) => (
35
+ <VideoPreview {...common} {...posterProps} />
27
36
  ))}
28
37
  </div>
29
38
 
@@ -7,18 +7,26 @@ interface Props {
7
7
  title: string
8
8
  href: string
9
9
  durationSeconds?: number
10
+ poster?: string | null
10
11
  class?: string
11
12
  }
12
13
 
13
14
  const { videoId, title, href, durationSeconds, class: className } = Astro.props
14
- const poster = posterUrl(config.publicDomain, videoId)
15
+ // Convention-URL fallback fires only when the caller omits `poster` entirely.
16
+ // Explicit `poster={null | undefined | ""}` is treated as "no poster" so that
17
+ // gallery items passing through video metadata with a missing posterUrl don't
18
+ // render a 404'd /cdn-cgi/image/.../poster.jpg <img> (broken-image icon).
19
+ const poster =
20
+ 'poster' in Astro.props
21
+ ? Astro.props.poster || undefined
22
+ : posterUrl(config.publicDomain, videoId)
15
23
  const durationLabel = durationSeconds
16
24
  ? `${Math.floor(durationSeconds / 60)}:${String(durationSeconds % 60).padStart(2, '0')}`
17
25
  : null
18
26
  ---
19
27
 
20
28
  <a class={`gl-video-preview ${className ?? ''}`.trim()} href={href} aria-label={title}>
21
- <img src={poster} alt="" loading="lazy" decoding="async" />
29
+ {poster && <img src={poster} alt="" loading="lazy" decoding="async" />}
22
30
  <span aria-hidden="true" class="gl-video-preview-play">▶</span>
23
31
  <span class="gl-video-preview-title">{title}</span>
24
32
  {durationLabel ? <span class="gl-video-preview-duration">{durationLabel}</span> : null}