@kolkrabbi/kol-component 0.69.1 → 0.70.0

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,10 +1,9 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-component",
3
- "version": "0.69.1",
3
+ "version": "0.70.0",
4
4
  "description": "KOL design-system components — atoms through organisms, emitting canonical kol-* classes. Pairs with @kolkrabbi/kol-theme for styling.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
- "sideEffects": false,
8
7
  "main": "./src/index.js",
9
8
  "module": "./src/index.js",
10
9
  "exports": {
@@ -15,24 +14,13 @@
15
14
  "./utilities/*": "./src/utilities/*.jsx",
16
15
  "./hooks/*": "./src/hooks/*.js"
17
16
  },
18
- "files": [
19
- "src",
20
- "README.md"
21
- ],
22
- "keywords": [
23
- "kol",
24
- "kolkrabbi",
25
- "design-system",
26
- "react",
27
- "components"
28
- ],
29
17
  "dependencies": {
30
18
  "@floating-ui/react": "^0.27.19",
31
19
  "embla-carousel-react": "^8.6.0",
32
- "react-syntax-highlighter": "^16.1.1",
33
- "@kolkrabbi/kol-icons": "^0.18.0"
20
+ "react-syntax-highlighter": "^16.1.1"
34
21
  },
35
22
  "peerDependencies": {
23
+ "@kolkrabbi/kol-icons": ">=0.18.0",
36
24
  "framer-motion": "^12.0.0",
37
25
  "gsap": "^3.13.0",
38
26
  "hls.js": "^1.6.0",
@@ -41,14 +29,20 @@
41
29
  "react-dom": "^18.3.0 || ^19.0.0",
42
30
  "react-router-dom": "^6.0.0 || ^7.0.0"
43
31
  },
44
- "peerDependenciesMeta": {
45
- "react-router-dom": {
46
- "optional": true
47
- },
48
- "opentype.js": {
49
- "optional": true
50
- }
32
+ "devDependencies": {
33
+ "@kolkrabbi/kol-icons": "^0.18.0"
51
34
  },
35
+ "files": [
36
+ "src",
37
+ "README.md"
38
+ ],
39
+ "keywords": [
40
+ "kol",
41
+ "kolkrabbi",
42
+ "design-system",
43
+ "react",
44
+ "components"
45
+ ],
52
46
  "repository": {
53
47
  "type": "git",
54
48
  "url": "git+https://github.com/Tor-Grimsson/kol-ds.git",
@@ -56,5 +50,14 @@
56
50
  },
57
51
  "publishConfig": {
58
52
  "access": "public"
53
+ },
54
+ "sideEffects": false,
55
+ "peerDependenciesMeta": {
56
+ "react-router-dom": {
57
+ "optional": true
58
+ },
59
+ "opentype.js": {
60
+ "optional": true
61
+ }
59
62
  }
60
63
  }
@@ -15,10 +15,20 @@ import Hls from 'hls.js'
15
15
  * @param {string} poster native poster frame shown before playback
16
16
  * @param {string} className all layout/sizing/positioning (consumer-supplied)
17
17
  * @param {Function} onEnded end-of-playback callback; its presence disables `loop`
18
+ * @param {boolean} active plays only while true (default true) — an
19
+ * off-stage carousel slide pauses instead of autoplaying beside the
20
+ * active one (FeaturedCarouselFullWidth, 2026-08-26)
18
21
  */
19
- export default function HlsVideo({ src, poster, className, onEnded, ...props }) {
22
+ export default function HlsVideo({ src, poster, className, onEnded, active = true, ...props }) {
20
23
  const videoRef = useRef(null)
21
24
 
25
+ useEffect(() => {
26
+ const video = videoRef.current
27
+ if (!video) return
28
+ if (active) video.play?.()?.catch?.(() => {})
29
+ else video.pause()
30
+ }, [active])
31
+
22
32
  useEffect(() => {
23
33
  const video = videoRef.current
24
34
  if (!video || !src) return
@@ -40,7 +50,7 @@ export default function HlsVideo({ src, poster, className, onEnded, ...props })
40
50
  poster={poster}
41
51
  className={className}
42
52
  style={{ pointerEvents: 'none' }}
43
- autoPlay
53
+ autoPlay={active}
44
54
  loop={!onEnded}
45
55
  muted
46
56
  onEnded={onEnded}
@@ -1,4 +1,4 @@
1
- import { isValidElement, useCallback, useEffect, useState } from 'react'
1
+ import { isValidElement, useCallback, useEffect, useRef, useState } from 'react'
2
2
  import useEmblaCarousel from 'embla-carousel-react'
3
3
  import Image from '../atoms/Image.jsx'
4
4
  import HlsVideo from '../atoms/HlsVideo.jsx'
@@ -14,7 +14,21 @@ import OverlayGlassPanel from '../utilities/OverlayGlassPanel.jsx'
14
14
  * `onTimeUpdate` attach to video elements only — they drive the active slide's
15
15
  * auto-advance and the progress bar; images ignore them.
16
16
  */
17
- function SlideMedia({ media, onEnded, onTimeUpdate }) {
17
+ /* The plain (non-HLS) video plays only while its slide is on stage
18
+ * (FeaturedCarouselFullWidth, 2026-08-26): every slide's video used to
19
+ * autoplay, so the peeking neighbours ran beside the active one. */
20
+ function InertVideo({ active, ...props }) {
21
+ const ref = useRef(null)
22
+ useEffect(() => {
23
+ const v = ref.current
24
+ if (!v) return
25
+ if (active) v.play?.()?.catch?.(() => {})
26
+ else v.pause()
27
+ }, [active])
28
+ return <video ref={ref} autoPlay={active} {...props} />
29
+ }
30
+
31
+ function SlideMedia({ media, active = true, onEnded, onTimeUpdate }) {
18
32
  if (!media) return null
19
33
  if (isValidElement(media)) return media
20
34
 
@@ -27,12 +41,12 @@ function SlideMedia({ media, onEnded, onTimeUpdate }) {
27
41
  // wired so the active slide plays once, then advances.
28
42
  if (src && !src.endsWith('.m3u8')) {
29
43
  return (
30
- <video
44
+ <InertVideo
45
+ active={active}
31
46
  src={src}
32
47
  poster={poster}
33
48
  className="kol-featured-carousel-media"
34
49
  style={{ pointerEvents: 'none' }}
35
- autoPlay
36
50
  loop={!onEnded}
37
51
  muted
38
52
  playsInline
@@ -46,6 +60,7 @@ function SlideMedia({ media, onEnded, onTimeUpdate }) {
46
60
  <HlsVideo
47
61
  src={src}
48
62
  poster={poster}
63
+ active={active}
49
64
  className="kol-featured-carousel-media"
50
65
  onEnded={onEnded}
51
66
  onTimeUpdate={onTimeUpdate}
@@ -110,8 +125,10 @@ function SlideMedia({ media, onEnded, onTimeUpdate }) {
110
125
  * @param {boolean} showTitle global title visibility; per-item `showTitle` overrides (default true)
111
126
  * @param {boolean} showDescription global description visibility; per-item overrides (default true)
112
127
  * @param {boolean} showCta global CTA visibility; per-item `showCta` overrides (default true)
113
- * @param {boolean} fullWidth drop the section's own vertical padding — the
114
- * slide frame spans its container (default false)
128
+ * @param {boolean} fullWidth the slide FILLS the container (`.is-full`,
129
+ * kol-framework.css ≥0.25.0) and the section
130
+ * drops its own vertical padding; default false
131
+ * keeps the 72vw peek
115
132
  * @param {boolean} rounded frame border + radius (default true)
116
133
  * @param {'stack'|'header'} navPosition prev/next under the viewport, or in the
117
134
  * header row beside the counter (default 'stack')
@@ -223,7 +240,7 @@ export default function FeaturedCarousel({
223
240
 
224
241
  return (
225
242
  <section
226
- className={`kol-featured-carousel w-full ${fullWidth ? '' : 'py-16'} ${className}`.trim()}
243
+ className={`kol-featured-carousel w-full ${fullWidth ? 'is-full' : 'py-16'} ${className}`.trim()}
227
244
  onMouseEnter={autoPlay ? () => setPaused(true) : undefined}
228
245
  onMouseLeave={autoPlay ? () => setPaused(false) : undefined}
229
246
  >
@@ -260,6 +277,7 @@ export default function FeaturedCarousel({
260
277
  >
261
278
  <SlideMedia
262
279
  media={item.media}
280
+ active={active}
263
281
  onEnded={autoPlay && items.length > 1 && active ? advance : undefined}
264
282
  onTimeUpdate={autoPlay && active ? handleVideoTime : undefined}
265
283
  />