Skip to content

Commit 3a7eb12

Browse files
MoonfaceXjianliang00
authored andcommitted
[Feature] Add experimental video element typings
- Add public TypeScript declarations for the experimental video element attributes, events, and UI methods. - Wire the video element into JSX intrinsic element and UI method exports. - Add type coverage for video props, event payloads, and selector query methods. - Bump the types packages to 4.1.0 and update changelogs for the new video typings. TEST: bash tools/oliver/types/types-version-check.sh TEST: Node 24.8.0 pnpm --dir lynx --filter @lynx-js/types test
1 parent 13f66ea commit 3a7eb12

6 files changed

Lines changed: 409 additions & 1 deletion

File tree

js_libraries/types/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CHANGELOG
22

3+
## 4.1.0
4+
- Introduce experimental `<video>` element types.
5+
36
## 4.0.0
47
- Introduce `<blur-view>`.
58
- Add missing `lynx.loadScript<T>(sectionName, { bundleName }): T` declaration on `CommonLynx`. The platform API has existed since LynxSDK 3.7; this is a types-only fix.

js_libraries/types/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lynx-js/types",
3-
"version": "4.0.0",
3+
"version": "4.1.0",
44
"description": "",
55
"keywords": [
66
"lynx",
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2026 The Lynx Authors. All rights reserved.
2+
// Licensed under the Apache License Version 2.0 that can be found in the
3+
// LICENSE file in the root directory of this source tree.
4+
5+
import { assertType } from 'vitest';
6+
import { IntrinsicElements, UIMethods, VideoBufferingEvent, VideoErrorEvent, VideoFirstFrameEvent, VideoProps, VideoTimeUpdateEvent, VideoUIMethods } from '../../types';
7+
8+
let a: unknown;
9+
10+
{
11+
<video src="https://example.com/video.mp4" loop={true} volume={0.5} muted={false} speed={1.25} object-fit="cover" mode="latest" timeupdate-interval={0.2} />;
12+
13+
assertType<VideoProps>(a as IntrinsicElements['video']);
14+
assertType<string | undefined>(a as IntrinsicElements['video']['src']);
15+
assertType<boolean | undefined>(a as IntrinsicElements['video']['loop']);
16+
assertType<number | undefined>(a as IntrinsicElements['video']['volume']);
17+
assertType<boolean | undefined>(a as IntrinsicElements['video']['muted']);
18+
assertType<number | undefined>(a as IntrinsicElements['video']['speed']);
19+
assertType<'contain' | 'cover' | 'fill' | undefined>(a as IntrinsicElements['video']['object-fit']);
20+
assertType<'queue' | 'direct' | 'latest' | undefined>(a as IntrinsicElements['video']['mode']);
21+
assertType<number | undefined>(a as IntrinsicElements['video']['timeupdate-interval']);
22+
}
23+
24+
{
25+
<video
26+
bindfirstframe={(e: VideoFirstFrameEvent) => {
27+
assertType<number>(e.detail.duration);
28+
}}
29+
/>;
30+
31+
<video
32+
bindtimeupdate={(e: VideoTimeUpdateEvent) => {
33+
assertType<number>(e.detail.current);
34+
assertType<number>(e.detail.duration);
35+
}}
36+
/>;
37+
38+
<video
39+
binderror={(e: VideoErrorEvent) => {
40+
assertType<number>(e.detail.errorCode);
41+
assertType<string>(e.detail.errorMsg);
42+
}}
43+
/>;
44+
45+
<video
46+
bindbuffering={(e: VideoBufferingEvent) => {
47+
assertType<number>(e.detail.buffering);
48+
}}
49+
/>;
50+
51+
<video bindplaying={() => {}} bindpaused={() => {}} bindstopped={() => {}} bindended={() => {}} bindlooped={() => {}} />;
52+
}
53+
54+
function invoke<T extends keyof { video: VideoUIMethods }>(_param: { video: VideoUIMethods }[T]) {}
55+
56+
{
57+
invoke<'video'>({
58+
method: 'play',
59+
success: (res) => {
60+
assertType<boolean | undefined>(res.success);
61+
},
62+
});
63+
64+
invoke<'video'>({
65+
method: 'pause',
66+
fail: (res) => {
67+
assertType<number | undefined>(res.errorCode);
68+
assertType<string | undefined>(res.msg);
69+
assertType<string | undefined>(res.errorMsg);
70+
},
71+
});
72+
73+
invoke<'video'>({
74+
method: 'stop',
75+
});
76+
77+
invoke<'video'>({
78+
method: 'seek',
79+
params: {
80+
position: 2,
81+
},
82+
});
83+
84+
assertType<VideoUIMethods>(a as UIMethods['video']);
85+
assertType<'play' | 'pause' | 'stop' | 'seek'>(a as UIMethods['video']['method']);
86+
}

js_libraries/types/types/common/element/element.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { ViewPagerItemProps, ViewPagerProps, ViewPagerUIMethods } from './viewpa
3232
import { BlurViewProps } from './blur-view';
3333
import { WebviewProps, WebviewUIMethods } from './webview';
3434
import { MarkdownProps, MarkdownUIMethods } from './markdown';
35+
import { VideoProps, VideoUIMethods } from './video';
3536

3637

3738
export interface UIMethods {
@@ -46,6 +47,7 @@ export interface UIMethods {
4647
'viewpager': ViewPagerUIMethods;
4748
'webview': WebviewUIMethods;
4849
'markdown': MarkdownUIMethods;
50+
'video': VideoUIMethods;
4951
}
5052

5153
type LynxComponentProps = ComponentProps;
@@ -84,6 +86,7 @@ export interface IntrinsicElements {
8486
'blur-view': BlurViewProps;
8587
'webview': WebviewProps;
8688
'markdown': MarkdownProps;
89+
'video': VideoProps;
8790
}
8891

8992
declare module 'react' {
@@ -122,6 +125,7 @@ declare module 'react' {
122125
'blur-view': BlurViewProps;
123126
'webview': WebviewProps;
124127
'markdown': MarkdownProps;
128+
'video': VideoProps;
125129
}
126130
}
127131
}

js_libraries/types/types/common/element/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export * from './viewpager';
2121
export * from './blur-view';
2222
export * from './webview';
2323
export * from './markdown';
24+
export * from './video';
2425
export * from './element';
2526
export * from './methods';
2627
export * from './attributes';

0 commit comments

Comments
 (0)