Skip to content

Commit 2e2d9ea

Browse files
authored
[WC-2724] Add title property for video player (#1571)
2 parents ccda512 + a5caa7c commit 2e2d9ea

24 files changed

+1103
-2816
lines changed

packages/pluggableWidgets/video-player-web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- We improved accessibility by adding Title property for meaningful descriptions of embedded video content.
12+
913
## [3.2.2] - 2023-09-27
1014

1115
### Fixed

packages/pluggableWidgets/video-player-web/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@mendix/video-player-web",
33
"widgetName": "VideoPlayer",
4-
"version": "3.2.2",
4+
"version": "3.2.3",
55
"description": "Player for YouTube, Dailymotion, Vimeo and Mp4 videos",
66
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
77
"license": "Apache-2.0",
@@ -43,9 +43,7 @@
4343
"verify": "rui-verify-package-format"
4444
},
4545
"dependencies": {
46-
"@types/react-test-renderer": "^18.0.7",
47-
"classnames": "^2.3.2",
48-
"react-test-renderer": "^18.2.0"
46+
"classnames": "^2.3.2"
4947
},
5048
"devDependencies": {
5149
"@mendix/automation-utils": "workspace:*",

packages/pluggableWidgets/video-player-web/src/VideoPlayer.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default class VideoPlayer extends Component<VideoPlayerContainerProps> {
1313
const url = useExpressionForLinks ? this.props.urlExpression?.value : this.props.videoUrl?.value;
1414
const poster = useExpressionForLinks ? this.props.posterExpression?.value : this.props.posterUrl?.value;
1515
const key = poster ? `${url}-${poster}` : url;
16+
const title = this.props.iframeTitle?.value;
1617

1718
return (
1819
<SizeContainer
@@ -35,6 +36,7 @@ export default class VideoPlayer extends Component<VideoPlayerContainerProps> {
3536
muted={this.props.muted}
3637
aspectRatio={this.props.heightUnit === "aspectRatio"}
3738
preview={false}
39+
title={title}
3840
/>
3941
</SizeContainer>
4042
);

packages/pluggableWidgets/video-player-web/src/VideoPlayer.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040
<systemProperty key="TabIndex" />
4141
</propertyGroup>
4242
</propertyGroup>
43+
<propertyGroup caption="Accessibility">
44+
<propertyGroup caption="Accessibility">
45+
<property key="iframeTitle" type="textTemplate" required="false">
46+
<caption>Title</caption>
47+
<description>Describe the purpose of the video (e.g., 'Video tutorial on accessibility').</description>
48+
</property>
49+
</propertyGroup>
50+
</propertyGroup>
4351
<propertyGroup caption="Controls">
4452
<propertyGroup caption="Controls">
4553
<property key="autoStart" type="boolean" defaultValue="false">

packages/pluggableWidgets/video-player-web/src/components/Dailymotion.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface DailymotionProps {
77
showControls: boolean;
88
muted: boolean;
99
aspectRatio?: boolean;
10+
title?: string;
1011
}
1112

1213
export class Dailymotion extends Component<DailymotionProps> {
@@ -20,6 +21,7 @@ export class Dailymotion extends Component<DailymotionProps> {
2021
frameBorder="0"
2122
allow="autoplay; fullscreen"
2223
allowFullScreen
24+
title={this.props.title}
2325
/>
2426
);
2527
}

packages/pluggableWidgets/video-player-web/src/components/Html5.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface Html5PlayerProps {
1212
style?: any;
1313
aspectRatio?: boolean;
1414
preview: boolean;
15+
title?: string;
1516
}
1617

1718
export class Html5 extends Component<Html5PlayerProps> {
@@ -57,6 +58,7 @@ export class Html5 extends Component<Html5PlayerProps> {
5758
ref={this.videoElement}
5859
height={!this.props.aspectRatio ? "100%" : undefined}
5960
preload={this.props.poster ? "metadata" : "auto"}
61+
title={this.props.title}
6062
>
6163
{!this.props.preview ? (
6264
<source

packages/pluggableWidgets/video-player-web/src/components/Video.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export interface VideoPlayerProps {
1616
muted: boolean;
1717
aspectRatio: boolean;
1818

19+
title?: string;
20+
1921
preview: boolean;
2022
}
2123

@@ -48,6 +50,7 @@ export class Video extends Component<VideoPlayerProps> {
4850
url={url}
4951
aspectRatio={this.props.aspectRatio}
5052
preview={this.props.preview}
53+
title={this.props.title}
5154
/>
5255
);
5356
}
@@ -61,6 +64,7 @@ export class Video extends Component<VideoPlayerProps> {
6164
muted={this.props.muted}
6265
loop={this.props.loop}
6366
aspectRatio={this.props.aspectRatio}
67+
title={this.props.title}
6468
/>
6569
);
6670
}
@@ -73,6 +77,7 @@ export class Video extends Component<VideoPlayerProps> {
7377
muted={this.props.muted}
7478
loop={this.props.loop}
7579
aspectRatio={this.props.aspectRatio}
80+
title={this.props.title}
7681
/>
7782
);
7883
}
@@ -85,6 +90,7 @@ export class Video extends Component<VideoPlayerProps> {
8590
muted={this.props.muted}
8691
showControls={this.props.showControls}
8792
aspectRatio={this.props.aspectRatio}
93+
title={this.props.title}
8894
/>
8995
);
9096
}

packages/pluggableWidgets/video-player-web/src/components/Vimeo.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface VimeoProps {
77
loop: boolean;
88
muted: boolean;
99
aspectRatio?: boolean;
10+
title?: string;
1011
}
1112

1213
export class Vimeo extends Component<VimeoProps> {
@@ -20,6 +21,7 @@ export class Vimeo extends Component<VimeoProps> {
2021
frameBorder="0"
2122
allow="autoplay; fullscreen"
2223
allowFullScreen
24+
title={this.props.title}
2325
/>
2426
);
2527
}

packages/pluggableWidgets/video-player-web/src/components/Youtube.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface YoutubeProps {
88
loop: boolean;
99
muted: boolean;
1010
aspectRatio?: boolean;
11+
title?: string;
1112
}
1213

1314
export class Youtube extends Component<YoutubeProps> {
@@ -21,6 +22,7 @@ export class Youtube extends Component<YoutubeProps> {
2122
frameBorder="0"
2223
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
2324
allowFullScreen
25+
title={this.props.title}
2426
/>
2527
);
2628
}
Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createElement, ReactElement } from "react";
2-
import { create } from "react-test-renderer";
2+
import { render } from "@testing-library/react";
33

44
import { Dailymotion, DailymotionProps } from "../Dailymotion";
55

@@ -14,27 +14,28 @@ describe("Dailymotion Player", () => {
1414

1515
const defaulPlayer = (props: DailymotionProps): ReactElement => <Dailymotion {...props} />;
1616

17-
it("should renders correctly", () => {
18-
const player = create(defaulPlayer(defaultProps)).toJSON();
19-
20-
expect(player).toMatchSnapshot();
17+
it("should render correctly", () => {
18+
const { asFragment } = render(defaulPlayer(defaultProps));
19+
expect(asFragment()).toMatchSnapshot();
2120
});
2221

23-
it("should renders correctly with autoplay", () => {
24-
const player = create(defaulPlayer({ ...defaultProps, autoPlay: true })).toJSON();
25-
26-
expect(player).toMatchSnapshot();
22+
it("should render correctly with autoplay", () => {
23+
const { asFragment } = render(defaulPlayer({ ...defaultProps, autoPlay: true }));
24+
expect(asFragment()).toMatchSnapshot();
2725
});
2826

29-
it("should renders correctly with muted", () => {
30-
const player = create(defaulPlayer({ ...defaultProps, muted: true })).toJSON();
31-
32-
expect(player).toMatchSnapshot();
27+
it("should render correctly with muted", () => {
28+
const { asFragment } = render(defaulPlayer({ ...defaultProps, muted: true }));
29+
expect(asFragment()).toMatchSnapshot();
3330
});
3431

35-
it("should renders correctly with controls", () => {
36-
const player = create(defaulPlayer({ ...defaultProps, showControls: true })).toJSON();
32+
it("should render correctly with controls", () => {
33+
const { asFragment } = render(defaulPlayer({ ...defaultProps, showControls: true }));
34+
expect(asFragment()).toMatchSnapshot();
35+
});
3736

38-
expect(player).toMatchSnapshot();
37+
it("should render correctly with title", () => {
38+
const { asFragment } = render(defaulPlayer({ ...defaultProps, title: "Sample Video Title" }));
39+
expect(asFragment()).toMatchSnapshot();
3940
});
4041
});

0 commit comments

Comments
 (0)