Skip to content

Commit e7e3600

Browse files
authored
Add video component (#71)
1 parent c34d212 commit e7e3600

File tree

5 files changed

+123
-0
lines changed

5 files changed

+123
-0
lines changed

demo/components_list.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,19 @@ class Delivery(BaseModel):
184184
],
185185
class_name='border-top mt-3 pt-1',
186186
),
187+
c.Div(
188+
components=[
189+
c.Heading(text='Video', level=2),
190+
c.Paragraph(text='A video component.'),
191+
c.Video(
192+
sources=['https://www.w3schools.com/html/mov_bbb.mp4'],
193+
autoplay=False,
194+
controls=True,
195+
loop=False,
196+
),
197+
],
198+
class_name='border-top mt-3 pt-1',
199+
),
187200
c.Div(
188201
components=[
189202
c.Heading(text='Custom', level=2),

src/npm-fastui/src/components/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { JsonComp, JsonProps } from './Json'
4040
import { ServerLoadComp, ServerLoadProps } from './ServerLoad'
4141
import { ImageComp, ImageProps } from './image'
4242
import { IframeComp, IframeProps } from './Iframe'
43+
import { VideoComp, VideoProps } from './video'
4344
import { CustomComp, CustomProps } from './Custom'
4445

4546
export type {
@@ -68,6 +69,7 @@ export type {
6869
ServerLoadProps,
6970
ImageProps,
7071
IframeProps,
72+
VideoProps,
7173
CustomProps,
7274
}
7375

@@ -99,6 +101,7 @@ export type FastProps =
99101
| ServerLoadProps
100102
| ImageProps
101103
| IframeProps
104+
| VideoProps
102105
| CustomProps
103106

104107
export type FastClassNameProps = Exclude<FastProps, TextProps | AllDisplayProps | ServerLoadProps | PageTitleProps>
@@ -182,6 +185,8 @@ export const AnyComp: FC<FastProps> = (props) => {
182185
return <ImageComp {...props} />
183186
case 'Iframe':
184187
return <IframeComp {...props} />
188+
case 'Video':
189+
return <VideoComp {...props} />
185190
case 'Custom':
186191
return <CustomComp {...props} />
187192
default:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { FC } from 'react'
2+
3+
import { ClassName } from '../hooks/className'
4+
5+
export interface VideoProps {
6+
type: 'Video'
7+
/**
8+
* @items {"type":"string", "format": "uri", "minLength": 1}
9+
*/
10+
sources: string[]
11+
autoplay?: boolean
12+
controls?: boolean
13+
loop?: boolean
14+
muted?: boolean
15+
/**
16+
* @format uri
17+
* @minLength 1
18+
*/
19+
poster?: string
20+
/** @TJS-type ["string", "integer"] */
21+
width?: string | number
22+
/** @TJS-type ["string", "integer"] */
23+
height?: string | number
24+
className?: ClassName
25+
}
26+
27+
export const VideoComp: FC<VideoProps> = (props) => {
28+
const { sources, autoplay, controls, loop, muted, poster, width, height } = props
29+
return (
30+
<video
31+
autoPlay={autoplay}
32+
controls={controls}
33+
loop={loop}
34+
muted={muted}
35+
poster={poster}
36+
width={width}
37+
height={height}
38+
>
39+
{sources.map((src, i) => (
40+
<source key={i} src={src} />
41+
))}
42+
</video>
43+
)
44+
}

src/python-fastui/fastui/components/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,19 @@ class Iframe(_p.BaseModel, extra='forbid'):
223223
type: _t.Literal['Iframe'] = 'Iframe'
224224

225225

226+
class Video(_p.BaseModel, extra='forbid'):
227+
sources: _t.List[_p.AnyUrl]
228+
autoplay: _t.Union[bool, None] = None
229+
controls: _t.Union[bool, None] = None
230+
loop: _t.Union[bool, None] = None
231+
muted: _t.Union[bool, None] = None
232+
poster: _t.Union[_p.AnyUrl, None] = None
233+
width: _t.Union[str, int, None] = None
234+
height: _t.Union[str, int, None] = None
235+
type: _t.Literal['Video'] = 'Video'
236+
class_name: _class_name.ClassNameField = None
237+
238+
226239
class Custom(_p.BaseModel, extra='forbid'):
227240
data: json_schema.JsonData
228241
sub_type: str = _p.Field(serialization_alias='subType')
@@ -250,6 +263,7 @@ class Custom(_p.BaseModel, extra='forbid'):
250263
ServerLoad,
251264
Image,
252265
Iframe,
266+
Video,
253267
Custom,
254268
Table,
255269
Pagination,

src/python-fastui/tests/react-fastui-json-schema.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@
369369
{
370370
"$ref": "#/definitions/IframeProps"
371371
},
372+
{
373+
"$ref": "#/definitions/VideoProps"
374+
},
372375
{
373376
"$ref": "#/definitions/CustomProps"
374377
}
@@ -1309,6 +1312,50 @@
13091312
},
13101313
"required": ["text", "type"],
13111314
"type": "object"
1315+
},
1316+
"VideoProps": {
1317+
"properties": {
1318+
"autoplay": {
1319+
"type": "boolean"
1320+
},
1321+
"className": {
1322+
"$ref": "#/definitions/ClassName"
1323+
},
1324+
"controls": {
1325+
"type": "boolean"
1326+
},
1327+
"height": {
1328+
"type": ["string", "integer"]
1329+
},
1330+
"loop": {
1331+
"type": "boolean"
1332+
},
1333+
"muted": {
1334+
"type": "boolean"
1335+
},
1336+
"poster": {
1337+
"format": "uri",
1338+
"minLength": 1,
1339+
"type": "string"
1340+
},
1341+
"sources": {
1342+
"items": {
1343+
"format": "uri",
1344+
"minLength": 1,
1345+
"type": "string"
1346+
},
1347+
"type": "array"
1348+
},
1349+
"type": {
1350+
"const": "Video",
1351+
"type": "string"
1352+
},
1353+
"width": {
1354+
"type": ["string", "integer"]
1355+
}
1356+
},
1357+
"required": ["sources", "type"],
1358+
"type": "object"
13121359
}
13131360
}
13141361
}

0 commit comments

Comments
 (0)