Skip to content

Commit 47bc5aa

Browse files
Merge pull request appsmithorg#5026 from appsmithorg/feature/1726-iframe-widget
Adding iframe widget
2 parents eae2e46 + 9bc1cd4 commit 47bc5aa

File tree

13 files changed

+298
-0
lines changed

13 files changed

+298
-0
lines changed
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React, { useEffect } from "react";
2+
import styled from "styled-components";
3+
4+
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
5+
import { hexToRgba } from "components/ads/common";
6+
7+
interface IframeContainerProps {
8+
borderColor?: string;
9+
borderOpacity?: number;
10+
borderWidth?: number;
11+
}
12+
13+
export const IframeContainer = styled.div<IframeContainerProps>`
14+
height: 100%;
15+
iframe {
16+
width: 100%;
17+
height: 100%;
18+
border-color: ${(props) =>
19+
hexToRgba(
20+
props.borderColor || props.theme.colors.border,
21+
(props.borderOpacity && !isNaN(props.borderOpacity)
22+
? props.borderOpacity
23+
: 100) / 100,
24+
)};
25+
border-width: ${(props) =>
26+
props.borderWidth ? Number(props.borderWidth) : 0}px;
27+
}
28+
`;
29+
30+
export interface IframeComponentProps extends ComponentProps {
31+
source: string;
32+
title?: string;
33+
onURLChanged: (url: string) => void;
34+
onMessageReceived: (message: MessageEvent) => void;
35+
borderColor?: string;
36+
borderOpacity?: number;
37+
borderWidth?: number;
38+
}
39+
40+
function IframeComponent(props: IframeComponentProps) {
41+
const {
42+
borderColor,
43+
borderOpacity,
44+
borderWidth,
45+
onMessageReceived,
46+
onURLChanged,
47+
source,
48+
title,
49+
} = props;
50+
51+
useEffect(() => {
52+
// add a listener
53+
window.addEventListener("message", onMessageReceived, false);
54+
// clean up
55+
return () =>
56+
window.removeEventListener("message", onMessageReceived, false);
57+
}, []);
58+
59+
useEffect(() => {
60+
onURLChanged(source);
61+
}, [source]);
62+
63+
return (
64+
<IframeContainer
65+
borderColor={borderColor}
66+
borderOpacity={borderOpacity}
67+
borderWidth={borderWidth}
68+
>
69+
<iframe src={source} title={title} />
70+
</IframeContainer>
71+
);
72+
}
73+
74+
export default IframeComponent;

app/client/src/constants/AppsmithActionConstants/ActionConstants.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export enum EventType {
7272
ON_VIDEO_END = "ON_VIDEO_END",
7373
ON_VIDEO_PLAY = "ON_VIDEO_PLAY",
7474
ON_VIDEO_PAUSE = "ON_VIDEO_PAUSE",
75+
ON_IFRAME_URL_CHANGED = "ON_IFRAME_URL_CHANGED",
76+
ON_IFRAME_MESSAGE_RECEIVED = "ON_IFRAME_MESSAGE_RECEIVED",
7577
}
7678

7779
export type ActionType =

app/client/src/constants/FieldExpectedValue.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ const FIELD_VALUES: Record<
169169
isVisible: "boolean",
170170
gridGap: "number",
171171
},
172+
IFRAME_WIDGET: {
173+
source: "string",
174+
title: "string",
175+
borderOpacity: "number",
176+
borderWidth: "number",
177+
},
172178
};
173179

174180
export default FIELD_VALUES;

app/client/src/constants/HelpConstants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ export const HelpMap = {
115115
path: "/widget-reference/switch",
116116
searchKey: "Switch",
117117
},
118+
IFRAME_WIDGET: {
119+
path: "/widget-reference/iframe",
120+
searchKey: "Iframe",
121+
},
118122
};
119123

120124
export const HelpBaseURL = "https://docs.appsmith.com";

app/client/src/constants/WidgetConstants.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export enum WidgetTypes {
2727
LIST_WIDGET = "LIST_WIDGET",
2828
SWITCH_WIDGET = "SWITCH_WIDGET",
2929
TABS_MIGRATOR_WIDGET = "TABS_MIGRATOR_WIDGET",
30+
IFRAME_WIDGET = "IFRAME_WIDGET",
3031
}
3132

3233
export type WidgetType = keyof typeof WidgetTypes;

app/client/src/icons/WidgetIcons.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { ReactComponent as FormIcon } from "assets/icons/widget/form.svg";
2222
import { ReactComponent as MapIcon } from "assets/icons/widget/map.svg";
2323
import { ReactComponent as ModalIcon } from "assets/icons/widget/modal.svg";
2424
import { ReactComponent as ListIcon } from "assets/icons/widget/list.svg";
25+
import { ReactComponent as EmbedIcon } from "assets/icons/widget/embed.svg";
2526
/* eslint-disable react/display-name */
2627

2728
export const WidgetIcons: {
@@ -142,6 +143,11 @@ export const WidgetIcons: {
142143
<ListIcon />
143144
</IconWrapper>
144145
),
146+
IFRAME_WIDGET: (props: IconProps) => (
147+
<IconWrapper {...props}>
148+
<EmbedIcon />
149+
</IconWrapper>
150+
),
145151
};
146152

147153
export type WidgetIcon = typeof WidgetIcons[keyof typeof WidgetIcons];

app/client/src/mockResponses/WidgetConfigResponse.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,15 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
10901090
],
10911091
},
10921092
},
1093+
[WidgetTypes.IFRAME_WIDGET]: {
1094+
source: "https://www.wikipedia.org/",
1095+
borderOpacity: 100,
1096+
borderWidth: 1,
1097+
rows: 8 * GRID_DENSITY_MIGRATION_V1,
1098+
columns: 7 * GRID_DENSITY_MIGRATION_V1,
1099+
widgetName: "Iframe",
1100+
version: 1,
1101+
},
10931102
},
10941103
configVersion: 1,
10951104
};

app/client/src/mockResponses/WidgetSidebarResponse.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ const WidgetSidebarResponse: WidgetCardProps[] = [
105105
widgetCardName: "Modal",
106106
key: generateReactKey(),
107107
},
108+
{
109+
type: "IFRAME_WIDGET",
110+
widgetCardName: "Iframe",
111+
key: generateReactKey(),
112+
},
108113
];
109114

110115
export default WidgetSidebarResponse;

app/client/src/reducers/entityReducers/widgetConfigReducer.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { VideoWidgetProps } from "widgets/VideoWidget";
2929
import { SkeletonWidgetProps } from "../../widgets/SkeletonWidget";
3030
import { SwitchWidgetProps } from "widgets/SwitchWidget";
3131
import { ListWidgetProps } from "../../widgets/ListWidget/ListWidget";
32+
import { IframeWidgetProps } from "widgets/IframeWidget";
3233

3334
const initialState: WidgetConfigReducerState = WidgetConfigResponse;
3435

@@ -82,6 +83,7 @@ export interface WidgetConfigReducerState {
8283
ICON_WIDGET: Partial<IconWidgetProps> & WidgetConfigProps;
8384
SKELETON_WIDGET: Partial<SkeletonWidgetProps> & WidgetConfigProps;
8485
LIST_WIDGET: Partial<ListWidgetProps<WidgetProps>> & WidgetConfigProps;
86+
IFRAME_WIDGET: Partial<IframeWidgetProps> & WidgetConfigProps;
8587
};
8688
configVersion: number;
8789
}

0 commit comments

Comments
 (0)