@lobehub/ui 6.0.5 → 6.0.6
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/es/Accordion/style.d.mts +1 -1
- package/es/Video/context.mjs.map +1 -1
- package/es/Video/parts/Frame.mjs +10 -2
- package/es/Video/parts/Frame.mjs.map +1 -1
- package/es/Video/parts/Root.mjs +4 -2
- package/es/Video/parts/Root.mjs.map +1 -1
- package/es/Video/sizing.mjs +7 -0
- package/es/Video/sizing.mjs.map +1 -0
- package/package.json +1 -1
package/es/Accordion/style.d.mts
CHANGED
package/es/Video/context.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.mjs","names":[],"sources":["../../src/Video/context.ts"],"sourcesContent":["'use client';\n\nimport { createContext, use } from 'react';\n\nimport type { VideoStore } from './store';\nimport type { VideoMarker, VideoMediaProps, VideoSection } from './type';\n\nexport interface VideoConfig {\n fps: number;\n markers: VideoMarker[];\n onMarkerClick?: (marker: VideoMarker) => void;\n onRetry?: () => Promise<unknown> | void;\n playbackRates?: number[];\n sections: VideoSection[];\n}\n\nexport interface VideoContextValue {\n config: VideoConfig;\n media: VideoMediaProps;\n store: VideoStore;\n}\n\nexport const VideoContext = createContext<VideoContextValue | null>(null);\n\nexport const useVideoContext = () => {\n const value = use(VideoContext);\n if (!value) throw new Error('Video parts must be rendered inside <Video.Root>.');\n return value;\n};\n\nexport interface FrameContextValue {\n hold: (held: boolean) => void;\n overlay: boolean;\n setOverlay: (overlay: boolean) => void;\n visible: boolean;\n}\n\nexport const FrameContext = createContext<FrameContextValue | null>(null);\n"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../../src/Video/context.ts"],"sourcesContent":["'use client';\n\nimport { createContext, use } from 'react';\n\nimport type { VideoStore } from './store';\nimport type { VideoMarker, VideoMediaProps, VideoSection } from './type';\n\nexport interface VideoConfig {\n fps: number;\n markers: VideoMarker[];\n maxHeight?: number;\n onMarkerClick?: (marker: VideoMarker) => void;\n onRetry?: () => Promise<unknown> | void;\n playbackRates?: number[];\n sections: VideoSection[];\n}\n\nexport interface VideoContextValue {\n config: VideoConfig;\n media: VideoMediaProps;\n store: VideoStore;\n}\n\nexport const VideoContext = createContext<VideoContextValue | null>(null);\n\nexport const useVideoContext = () => {\n const value = use(VideoContext);\n if (!value) throw new Error('Video parts must be rendered inside <Video.Root>.');\n return value;\n};\n\nexport interface FrameContextValue {\n hold: (held: boolean) => void;\n overlay: boolean;\n setOverlay: (overlay: boolean) => void;\n visible: boolean;\n}\n\nexport const FrameContext = createContext<FrameContextValue | null>(null);\n"],"mappings":";;;AAuBA,MAAa,eAAe,cAAwC,IAAI;AAExE,MAAa,wBAAwB;CACnC,MAAM,QAAQ,IAAI,YAAY;CAC9B,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,mDAAmD;CAC/E,OAAO;AACT;AASA,MAAa,eAAe,cAAwC,IAAI"}
|
package/es/Video/parts/Frame.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import { styleProps } from "../../styles/stylex/props.mjs";
|
|
|
3
3
|
import { FrameContext, useVideoContext } from "../context.mjs";
|
|
4
4
|
import { styles } from "../style.mjs";
|
|
5
5
|
import { useVideo } from "../useVideo.mjs";
|
|
6
|
+
import { useFullscreen } from "../useFullscreen.mjs";
|
|
7
|
+
import { aspectOf, frameWidthOf } from "../sizing.mjs";
|
|
6
8
|
import { useControlsIdle } from "../useControlsIdle.mjs";
|
|
7
9
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
8
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -15,7 +17,8 @@ const isFocusVisible = (element) => {
|
|
|
15
17
|
}
|
|
16
18
|
};
|
|
17
19
|
const Frame = ({ children, className, style }) => {
|
|
18
|
-
const { media, store } = useVideoContext();
|
|
20
|
+
const { config, media, store } = useVideoContext();
|
|
21
|
+
const fullscreen = useFullscreen(store);
|
|
19
22
|
const videoRef = useRef(null);
|
|
20
23
|
const pointerTypeRef = useRef("mouse");
|
|
21
24
|
const size = useVideo((state) => state.size);
|
|
@@ -38,11 +41,16 @@ const Frame = ({ children, className, style }) => {
|
|
|
38
41
|
overlay
|
|
39
42
|
]);
|
|
40
43
|
const aspectRatio = size?.height ? `${size.width} / ${size.height}` : "16 / 9";
|
|
44
|
+
const sizing = !(config.maxHeight !== void 0 && !fullscreen && frameWidthOf(config.maxHeight, aspectOf(size)) < 480) ? { aspectRatio } : overlay ? { aspectRatio: `480 / ${config.maxHeight}` } : {
|
|
45
|
+
aspectRatio,
|
|
46
|
+
marginInline: "auto",
|
|
47
|
+
maxWidth: `${frameWidthOf(config.maxHeight, aspectOf(size))}px`
|
|
48
|
+
};
|
|
41
49
|
return /* @__PURE__ */ jsx(FrameContext, {
|
|
42
50
|
value: frame,
|
|
43
51
|
children: /* @__PURE__ */ jsxs("div", {
|
|
44
52
|
...styleProps(styles.frame, className, {
|
|
45
|
-
|
|
53
|
+
...sizing,
|
|
46
54
|
...style
|
|
47
55
|
}),
|
|
48
56
|
onBlur: (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Frame.mjs","names":[],"sources":["../../../src/Video/parts/Frame.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { FrameContext, type FrameContextValue, useVideoContext } from '../context';\nimport { styles } from '../style';\nimport type { VideoFrameProps } from '../type';\nimport { useControlsIdle } from '../useControlsIdle';\nimport { useVideo } from '../useVideo';\n\nconst isFocusVisible = (element: Element) => {\n try {\n return element.matches(':focus-visible');\n } catch {\n return true;\n }\n};\n\nconst Frame = ({ children, className, style }: VideoFrameProps) => {\n const { media, store } = useVideoContext();\n const videoRef = useRef<HTMLVideoElement>(null);\n const pointerTypeRef = useRef('mouse');\n const size = useVideo((state) => state.size);\n const idleForced = useVideo((state) => state.paused || state.status !== 'ready');\n const idle = useControlsIdle(idleForced);\n const [overlay, setOverlay] = useState(false);\n\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n return store.attach(video);\n }, [store, media.src]);\n\n const frame = useMemo<FrameContextValue>(\n () => ({ hold: idle.hold, overlay, setOverlay, visible: idle.visible }),\n [idle.hold, idle.visible, overlay],\n );\n\n const aspectRatio = size?.height ? `${size.width} / ${size.height}` : '16 / 9';\n\n return (\n <FrameContext value={frame}>\n <div\n {...styleProps(styles.frame, className, {
|
|
1
|
+
{"version":3,"file":"Frame.mjs","names":[],"sources":["../../../src/Video/parts/Frame.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { FrameContext, type FrameContextValue, useVideoContext } from '../context';\nimport { aspectOf, frameWidthOf, MIN_PLAYER_WIDTH } from '../sizing';\nimport { styles } from '../style';\nimport type { VideoFrameProps } from '../type';\nimport { useControlsIdle } from '../useControlsIdle';\nimport { useFullscreen } from '../useFullscreen';\nimport { useVideo } from '../useVideo';\n\nconst isFocusVisible = (element: Element) => {\n try {\n return element.matches(':focus-visible');\n } catch {\n return true;\n }\n};\n\nconst Frame = ({ children, className, style }: VideoFrameProps) => {\n const { config, media, store } = useVideoContext();\n const fullscreen = useFullscreen(store);\n const videoRef = useRef<HTMLVideoElement>(null);\n const pointerTypeRef = useRef('mouse');\n const size = useVideo((state) => state.size);\n const idleForced = useVideo((state) => state.paused || state.status !== 'ready');\n const idle = useControlsIdle(idleForced);\n const [overlay, setOverlay] = useState(false);\n\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n return store.attach(video);\n }, [store, media.src]);\n\n const frame = useMemo<FrameContextValue>(\n () => ({ hold: idle.hold, overlay, setOverlay, visible: idle.visible }),\n [idle.hold, idle.visible, overlay],\n );\n\n const aspectRatio = size?.height ? `${size.width} / ${size.height}` : '16 / 9';\n const narrow =\n config.maxHeight !== undefined &&\n !fullscreen &&\n frameWidthOf(config.maxHeight, aspectOf(size)) < MIN_PLAYER_WIDTH;\n // Overlay controls live inside the frame, so it widens and letterboxes the\n // video; controls below leave the frame at the video's own width, keeping\n // children positioned in video coordinates aligned.\n const sizing = !narrow\n ? { aspectRatio }\n : overlay\n ? { aspectRatio: `${MIN_PLAYER_WIDTH} / ${config.maxHeight}` }\n : {\n aspectRatio,\n marginInline: 'auto',\n maxWidth: `${frameWidthOf(config.maxHeight!, aspectOf(size))}px`,\n };\n\n return (\n <FrameContext value={frame}>\n <div\n {...styleProps(styles.frame, className, { ...sizing, ...style })}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null))\n idle.setFocused(false);\n }}\n onFocus={(event) => {\n idle.setFocused(isFocusVisible(event.target));\n }}\n onPointerDownCapture={(event) => {\n pointerTypeRef.current = event.pointerType || 'mouse';\n }}\n onPointerLeave={(event) => {\n if (event.pointerType !== 'touch') idle.sleep();\n }}\n onPointerMove={(event) => {\n if (event.pointerType !== 'touch') idle.wake();\n }}\n >\n <video\n playsInline\n autoPlay={media.autoPlay}\n loop={media.loop}\n poster={media.poster}\n preload={media.preload}\n ref={videoRef}\n src={media.src}\n onEnded={media.onEnded}\n onError={media.onError}\n onPause={media.onPause}\n onPlay={media.onPlay}\n onTimeUpdate={media.onTimeUpdate}\n {...styleProps(styles.video)}\n />\n <div\n data-video-surface=\"\"\n {...styleProps(styles.surface)}\n onDoubleClick={() => store.toggleFullscreen()}\n onClick={() => {\n if (pointerTypeRef.current === 'touch' && !idle.visible) {\n idle.wake();\n return;\n }\n if (pointerTypeRef.current === 'touch') idle.wake();\n store.toggle();\n }}\n />\n {children}\n </div>\n </FrameContext>\n );\n};\n\nFrame.displayName = 'VideoFrame';\n\nexport default Frame;\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,kBAAkB,YAAqB;CAC3C,IAAI;EACF,OAAO,QAAQ,QAAQ,gBAAgB;CACzC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAM,SAAS,EAAE,UAAU,WAAW,YAA6B;CACjE,MAAM,EAAE,QAAQ,OAAO,UAAU,gBAAgB;CACjD,MAAM,aAAa,cAAc,KAAK;CACtC,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,iBAAiB,OAAO,OAAO;CACrC,MAAM,OAAO,UAAU,UAAU,MAAM,IAAI;CAC3C,MAAM,aAAa,UAAU,UAAU,MAAM,UAAU,MAAM,WAAW,OAAO;CAC/E,MAAM,OAAO,gBAAgB,UAAU;CACvC,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,gBAAgB;EACd,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OAAO;EACZ,OAAO,MAAM,OAAO,KAAK;CAC3B,GAAG,CAAC,OAAO,MAAM,GAAG,CAAC;CAErB,MAAM,QAAQ,eACL;EAAE,MAAM,KAAK;EAAM;EAAS;EAAY,SAAS,KAAK;CAAQ,IACrE;EAAC,KAAK;EAAM,KAAK;EAAS;CAAO,CACnC;CAEA,MAAM,cAAc,MAAM,SAAS,GAAG,KAAK,MAAM,KAAK,KAAK,WAAW;CAQtE,MAAM,SAAS,EANb,OAAO,cAAc,KAAA,KACrB,CAAC,cACD,aAAa,OAAO,WAAW,SAAS,IAAI,CAAC,IAAA,OAK3C,EAAE,YAAY,IACd,UACE,EAAE,aAAa,SAAyB,OAAO,YAAY,IAC3D;EACE;EACA,cAAc;EACd,UAAU,GAAG,aAAa,OAAO,WAAY,SAAS,IAAI,CAAC,EAAE;CAC/D;CAEN,OACE,oBAAC,cAAD;EAAc,OAAO;EACnB,UAAA,qBAAC,OAAD;GACE,GAAI,WAAW,OAAO,OAAO,WAAW;IAAE,GAAG;IAAQ,GAAG;GAAM,CAAC;GAC/D,SAAS,UAAU;IACjB,IAAI,CAAC,MAAM,cAAc,SAAS,MAAM,aAA4B,GAClE,KAAK,WAAW,KAAK;GACzB;GACA,UAAU,UAAU;IAClB,KAAK,WAAW,eAAe,MAAM,MAAM,CAAC;GAC9C;GACA,uBAAuB,UAAU;IAC/B,eAAe,UAAU,MAAM,eAAe;GAChD;GACA,iBAAiB,UAAU;IACzB,IAAI,MAAM,gBAAgB,SAAS,KAAK,MAAM;GAChD;GACA,gBAAgB,UAAU;IACxB,IAAI,MAAM,gBAAgB,SAAS,KAAK,KAAK;GAC/C;GAjBF,UAAA;IAmBE,oBAAC,SAAD;KACE,aAAA;KACA,UAAU,MAAM;KAChB,MAAM,MAAM;KACZ,QAAQ,MAAM;KACd,SAAS,MAAM;KACf,KAAK;KACL,KAAK,MAAM;KACX,SAAS,MAAM;KACf,SAAS,MAAM;KACf,SAAS,MAAM;KACf,QAAQ,MAAM;KACd,cAAc,MAAM;KACpB,GAAI,WAAW,OAAO,KAAK;IAC5B,CAAA;IACD,oBAAC,OAAD;KACE,sBAAmB;KACnB,GAAI,WAAW,OAAO,OAAO;KAC7B,qBAAqB,MAAM,iBAAiB;KAC5C,eAAe;MACb,IAAI,eAAe,YAAY,WAAW,CAAC,KAAK,SAAS;OACvD,KAAK,KAAK;OACV;MACF;MACA,IAAI,eAAe,YAAY,SAAS,KAAK,KAAK;MAClD,MAAM,OAAO;KACf;IACD,CAAA;IACA;GACE;;CACO,CAAA;AAElB;AAEA,MAAM,cAAc"}
|
package/es/Video/parts/Root.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { sortSections } from "../time.mjs";
|
|
|
6
6
|
import { createVideoStore } from "../store.mjs";
|
|
7
7
|
import { useVideoState } from "../useVideo.mjs";
|
|
8
8
|
import { handleVideoKey } from "../useKeyboard.mjs";
|
|
9
|
+
import { aspectOf, playerWidthOf } from "../sizing.mjs";
|
|
9
10
|
import { useImperativeHandle, useLayoutEffect, useMemo, useState } from "react";
|
|
10
11
|
import { jsx } from "react/jsx-runtime";
|
|
11
12
|
//#region src/Video/parts/Root.tsx
|
|
@@ -38,18 +39,18 @@ const Root = ({ ref, player, src, poster, autoPlay, loop, preload = "metadata",
|
|
|
38
39
|
if (!captions) store.setCaptions(false);
|
|
39
40
|
}, [store]);
|
|
40
41
|
const size = useVideoState(store, (state) => state.size);
|
|
41
|
-
const aspect = size?.height ? size.width / size.height : 16 / 9;
|
|
42
42
|
const sizing = maxHeight === void 0 ? {
|
|
43
43
|
height,
|
|
44
44
|
width
|
|
45
45
|
} : {
|
|
46
|
-
maxWidth: `${
|
|
46
|
+
maxWidth: `${playerWidthOf(maxHeight, aspectOf(size))}px`,
|
|
47
47
|
width: "100%"
|
|
48
48
|
};
|
|
49
49
|
const value = useMemo(() => ({
|
|
50
50
|
config: {
|
|
51
51
|
fps,
|
|
52
52
|
markers,
|
|
53
|
+
maxHeight,
|
|
53
54
|
onMarkerClick,
|
|
54
55
|
onRetry,
|
|
55
56
|
playbackRates,
|
|
@@ -73,6 +74,7 @@ const Root = ({ ref, player, src, poster, autoPlay, loop, preload = "metadata",
|
|
|
73
74
|
fps,
|
|
74
75
|
loop,
|
|
75
76
|
markers,
|
|
77
|
+
maxHeight,
|
|
76
78
|
onEnded,
|
|
77
79
|
onError,
|
|
78
80
|
onMarkerClick,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Root.mjs","names":[],"sources":["../../../src/Video/parts/Root.tsx"],"sourcesContent":["'use client';\n\nimport { useImperativeHandle, useLayoutEffect, useMemo, useState } from 'react';\n\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { VideoContext, type VideoContextValue } from '../context';\nimport { createVideoStore, type VideoStore } from '../store';\nimport { styles } from '../style';\nimport { sortSections } from '../time';\nimport type { VideoMarker, VideoRootProps, VideoSection } from '../type';\nimport { handleVideoKey } from '../useKeyboard';\nimport { useVideoState } from '../useVideo';\n\nconst NO_MARKERS: VideoMarker[] = [];\nconst NO_SECTIONS: VideoSection[] = [];\n\nconst Root = ({\n ref,\n player,\n src,\n poster,\n autoPlay,\n loop,\n preload = 'metadata',\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n sections = NO_SECTIONS,\n markers = NO_MARKERS,\n fps = 30,\n playbackRates,\n defaultPlaybackRate,\n muted,\n onMutedChange,\n onRateChange,\n onMarkerClick,\n onRetry,\n captions = true,\n width,\n height,\n maxHeight,\n className,\n style,\n children,\n}: VideoRootProps) => {\n const [ownStore] = useState(createVideoStore);\n const store = (player as VideoStore | undefined) ?? ownStore;\n\n // Assigned during render so the store already has them when a child Frame\n // attaches its <video> in an effect, which runs before this component's own.\n store.setOptions({ defaultPlaybackRate, muted, onMutedChange, onRateChange });\n\n useImperativeHandle(ref, () => store, [store]);\n\n const sorted = useMemo(() => sortSections(sections), [sections]);\n\n useLayoutEffect(() => {\n store.setData({ fps, markers, sections: sorted });\n }, [store, fps, markers, sorted]);\n\n useLayoutEffect(() => {\n if (!captions) store.setCaptions(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store]);\n\n const size = useVideoState(store, (state) => state.size);\n const
|
|
1
|
+
{"version":3,"file":"Root.mjs","names":[],"sources":["../../../src/Video/parts/Root.tsx"],"sourcesContent":["'use client';\n\nimport { useImperativeHandle, useLayoutEffect, useMemo, useState } from 'react';\n\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { VideoContext, type VideoContextValue } from '../context';\nimport { aspectOf, playerWidthOf } from '../sizing';\nimport { createVideoStore, type VideoStore } from '../store';\nimport { styles } from '../style';\nimport { sortSections } from '../time';\nimport type { VideoMarker, VideoRootProps, VideoSection } from '../type';\nimport { handleVideoKey } from '../useKeyboard';\nimport { useVideoState } from '../useVideo';\n\nconst NO_MARKERS: VideoMarker[] = [];\nconst NO_SECTIONS: VideoSection[] = [];\n\nconst Root = ({\n ref,\n player,\n src,\n poster,\n autoPlay,\n loop,\n preload = 'metadata',\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n sections = NO_SECTIONS,\n markers = NO_MARKERS,\n fps = 30,\n playbackRates,\n defaultPlaybackRate,\n muted,\n onMutedChange,\n onRateChange,\n onMarkerClick,\n onRetry,\n captions = true,\n width,\n height,\n maxHeight,\n className,\n style,\n children,\n}: VideoRootProps) => {\n const [ownStore] = useState(createVideoStore);\n const store = (player as VideoStore | undefined) ?? ownStore;\n\n // Assigned during render so the store already has them when a child Frame\n // attaches its <video> in an effect, which runs before this component's own.\n store.setOptions({ defaultPlaybackRate, muted, onMutedChange, onRateChange });\n\n useImperativeHandle(ref, () => store, [store]);\n\n const sorted = useMemo(() => sortSections(sections), [sections]);\n\n useLayoutEffect(() => {\n store.setData({ fps, markers, sections: sorted });\n }, [store, fps, markers, sorted]);\n\n useLayoutEffect(() => {\n if (!captions) store.setCaptions(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store]);\n\n const size = useVideoState(store, (state) => state.size);\n const sizing =\n maxHeight === undefined\n ? { height, width }\n : { maxWidth: `${playerWidthOf(maxHeight, aspectOf(size))}px`, width: '100%' };\n\n const value = useMemo<VideoContextValue>(\n () => ({\n config: { fps, markers, maxHeight, onMarkerClick, onRetry, playbackRates, sections: sorted },\n media: {\n autoPlay,\n loop,\n onEnded,\n onError,\n onPause,\n onPlay,\n onTimeUpdate,\n poster,\n preload,\n src,\n },\n store,\n }),\n [\n autoPlay,\n fps,\n loop,\n markers,\n maxHeight,\n onEnded,\n onError,\n onMarkerClick,\n onPause,\n onPlay,\n onRetry,\n onTimeUpdate,\n playbackRates,\n poster,\n preload,\n sorted,\n src,\n store,\n ],\n );\n\n return (\n <VideoContext value={value}>\n <div\n ref={store.attachRoot}\n tabIndex={0}\n onKeyDown={(event) => {\n if (handleVideoKey(event, store, playbackRates)) event.preventDefault();\n }}\n {...styleProps(styles.root, className, { ...sizing, ...style })}\n >\n {children}\n </div>\n </VideoContext>\n );\n};\n\nRoot.displayName = 'VideoRoot';\n\nexport default Root;\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,aAA4B,CAAC;AACnC,MAAM,cAA8B,CAAC;AAErC,MAAM,QAAQ,EACZ,KACA,QACA,KACA,QACA,UACA,MACA,UAAU,YACV,QACA,SACA,SACA,SACA,cACA,WAAW,aACX,UAAU,YACV,MAAM,IACN,eACA,qBACA,OACA,eACA,cACA,eACA,SACA,WAAW,MACX,OACA,QACA,WACA,WACA,OACA,eACoB;CACpB,MAAM,CAAC,YAAY,SAAS,gBAAgB;CAC5C,MAAM,QAAS,UAAqC;CAIpD,MAAM,WAAW;EAAE;EAAqB;EAAO;EAAe;CAAa,CAAC;CAE5E,oBAAoB,WAAW,OAAO,CAAC,KAAK,CAAC;CAE7C,MAAM,SAAS,cAAc,aAAa,QAAQ,GAAG,CAAC,QAAQ,CAAC;CAE/D,sBAAsB;EACpB,MAAM,QAAQ;GAAE;GAAK;GAAS,UAAU;EAAO,CAAC;CAClD,GAAG;EAAC;EAAO;EAAK;EAAS;CAAM,CAAC;CAEhC,sBAAsB;EACpB,IAAI,CAAC,UAAU,MAAM,YAAY,KAAK;CAExC,GAAG,CAAC,KAAK,CAAC;CAEV,MAAM,OAAO,cAAc,QAAQ,UAAU,MAAM,IAAI;CACvD,MAAM,SACJ,cAAc,KAAA,IACV;EAAE;EAAQ;CAAM,IAChB;EAAE,UAAU,GAAG,cAAc,WAAW,SAAS,IAAI,CAAC,EAAE;EAAK,OAAO;CAAO;CAEjF,MAAM,QAAQ,eACL;EACL,QAAQ;GAAE;GAAK;GAAS;GAAW;GAAe;GAAS;GAAe,UAAU;EAAO;EAC3F,OAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA;CACF,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OACE,oBAAC,cAAD;EAAqB;EACnB,UAAA,oBAAC,OAAD;GACE,KAAK,MAAM;GACX,UAAU;GACV,YAAY,UAAU;IACpB,IAAI,eAAe,OAAO,OAAO,aAAa,GAAG,MAAM,eAAe;GACxE;GACA,GAAI,WAAW,OAAO,MAAM,WAAW;IAAE,GAAG;IAAQ,GAAG;GAAM,CAAC;GAE7D;EACE,CAAA;CACO,CAAA;AAElB;AAEA,KAAK,cAAc"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const aspectOf = (size) => size?.height ? size.width / size.height : 16 / 9;
|
|
2
|
+
const frameWidthOf = (maxHeight, aspect) => Math.round(maxHeight * aspect);
|
|
3
|
+
const playerWidthOf = (maxHeight, aspect) => Math.max(480, frameWidthOf(maxHeight, aspect));
|
|
4
|
+
//#endregion
|
|
5
|
+
export { aspectOf, frameWidthOf, playerWidthOf };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=sizing.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sizing.mjs","names":[],"sources":["../../src/Video/sizing.ts"],"sourcesContent":["import type { VideoState } from './type';\n\n// Room for the widest control row (frame stepping, captions, speed, fullscreen),\n// so a portrait recording capped by maxHeight never pushes controls out of view.\nexport const MIN_PLAYER_WIDTH = 480;\n\nexport const aspectOf = (size: VideoState['size']) =>\n size?.height ? size.width / size.height : 16 / 9;\n\nexport const frameWidthOf = (maxHeight: number, aspect: number) => Math.round(maxHeight * aspect);\n\nexport const playerWidthOf = (maxHeight: number, aspect: number) =>\n Math.max(MIN_PLAYER_WIDTH, frameWidthOf(maxHeight, aspect));\n"],"mappings":"AAMA,MAAa,YAAY,SACvB,MAAM,SAAS,KAAK,QAAQ,KAAK,SAAS,KAAK;AAEjD,MAAa,gBAAgB,WAAmB,WAAmB,KAAK,MAAM,YAAY,MAAM;AAEhG,MAAa,iBAAiB,WAAmB,WAC/C,KAAK,IAAA,KAAsB,aAAa,WAAW,MAAM,CAAC"}
|