// @flow import { observable } from "mobx"; import { observer } from "mobx-react"; import { OpenIcon } from "outline-icons"; import * as React from "react"; import styled from "styled-components"; import Flex from "components/Flex"; type Props = { src?: string, border?: boolean, title?: string, icon?: React.Node, canonicalUrl?: string, isSelected?: boolean, width?: string, height?: string, }; type PropsWithRef = Props & { forwardedRef: React.Ref, }; @observer class Frame extends React.Component { mounted: boolean; @observable isLoaded: boolean = false; componentDidMount() { this.mounted = true; setImmediate(this.loadIframe); } componentWillUnmount() { this.mounted = false; } loadIframe = () => { if (!this.mounted) return; this.isLoaded = true; }; render() { const { border, width = "100%", height = "400px", forwardedRef, icon, title, canonicalUrl, isSelected, src, } = this.props; const Component = border ? StyledIframe : "iframe"; const withBar = !!(icon || canonicalUrl); return ( {this.isLoaded && ( )} {withBar && ( {icon} {title} {canonicalUrl && ( Open )} )} ); } } const Rounded = styled.div` border-radius: ${(props) => (props.withBar ? "3px 3px 0 0" : "3px")}; overflow: hidden; width: ${(props) => props.width}; height: ${(props) => (props.withBar ? props.height + 28 : props.height)}; `; const Open = styled.a` color: ${(props) => props.theme.textSecondary} !important; font-size: 13px; font-weight: 500; align-items: center; display: flex; position: absolute; right: 0; padding: 0 8px; `; const Title = styled.span` font-size: 13px; font-weight: 500; padding-left: 4px; `; const Bar = styled(Flex)` background: ${(props) => props.theme.secondaryBackground}; color: ${(props) => props.theme.textSecondary}; padding: 0 8px; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; user-select: none; `; // This wrapper allows us to pass non-standard HTML attributes through to the DOM element // https://www.styled-components.com/docs/basics#passed-props const Iframe = (props) =>