diff --git a/app/scripts/components/common/blocks/embed.tsx b/app/scripts/components/common/blocks/embed.tsx new file mode 100644 index 000000000..d0234e8c3 --- /dev/null +++ b/app/scripts/components/common/blocks/embed.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import styled from 'styled-components'; +import { HintedError } from '$utils/hinted-error'; +import BrowserFrame from '$styles/browser-frame'; + +const EmbedWrapper = styled.div` + width: 100%; + + > div { + width: 100%; + } +`; + +const IframeWrapper = styled.iframe` + width: 100%; + border: 0; + height: ${(props: { height: number }) => props.height}px; +`; + +interface EmbedProps { + src: string; + height: number; +} + +export default function Embed({ src, height = 800 }: EmbedProps) { + if (!src) { + throw new HintedError('Embed block requires a URL'); + } + + return ( + + + + + + ); +} diff --git a/app/scripts/components/common/mdx-content.js b/app/scripts/components/common/mdx-content.js index cb84dfcde..0fd155001 100644 --- a/app/scripts/components/common/mdx-content.js +++ b/app/scripts/components/common/mdx-content.js @@ -19,6 +19,7 @@ import { } from '$components/common/blocks/lazy-components'; import { NotebookConnectCalloutBlock } from '$components/common/notebook-connect'; import SmartLink from '$components/common/smart-link'; +import Embed from '$components/common/blocks/embed'; function MdxContent(props) { const pageMdx = useMdxPageLoader(props.loader); @@ -43,7 +44,8 @@ function MdxContent(props) { CompareImage: LazyCompareImage, NotebookConnectCallout: NotebookConnectCalloutBlock, Link: SmartLink, - Table: LazyTable + Table: LazyTable, + Embed }} > diff --git a/app/scripts/styles/browser-frame.tsx b/app/scripts/styles/browser-frame.tsx index 048abb7b7..c01af50be 100644 --- a/app/scripts/styles/browser-frame.tsx +++ b/app/scripts/styles/browser-frame.tsx @@ -1,15 +1,26 @@ import React, { ReactNode } from 'react'; import styled from 'styled-components'; import { themeVal } from '@devseed-ui/theme-provider'; +import { CollecticonExpandTopRight } from '@devseed-ui/collecticons'; -function BrowserFrameComponent(props: { children: ReactNode }) { - const { children, ...rest } = props; +function BrowserFrameComponent(props: { children: ReactNode; link?: string }) { + const { children, link, ...rest } = props; return (
- - - +
+ + + +
+ {link && ( + + )}
{children}
@@ -25,17 +36,28 @@ const BrowserFrame = styled(BrowserFrameComponent)` border-radius: ${themeVal('shape.rounded')}; .controls { + width: 100%; display: flex; - gap: 0.5rem; - padding: 0.625rem 0.5rem; + align-items: center; + justify-content: space-between; - span { - display: block; - width: 0.75rem; - height: 0.75rem; - content: ''; - border-radius: ${themeVal('shape.ellipsoid')}; - background: ${themeVal('color.base-300')}; + .buttons { + gap: 0.5rem; + padding: 0.625rem 0.5rem; + display: flex; + span { + display: block; + width: 0.75rem; + height: 0.75rem; + content: ''; + border-radius: ${themeVal('shape.ellipsoid')}; + background: ${themeVal('color.base-300')}; + } + } + + .link { + padding-right: .625rem; + font-size: 0.875rem; } } `; diff --git a/docs/content/MDX_BLOCKS.md b/docs/content/MDX_BLOCKS.md index d57521327..25faf04e8 100644 --- a/docs/content/MDX_BLOCKS.md +++ b/docs/content/MDX_BLOCKS.md @@ -563,6 +563,25 @@ The scrollytelling is defined as a series os `Chapters` inside the `Scrollytelli - As with other properties, the user is not allowed to change the projection used in a chapter - Once a chapter with a set projection is reached, that projection will be used on subsequent chapters, until one specifies a different projection. + +## Embed + +It is possible to embed individual webpages within a Story, like an interactive notebook, like so: + +```jsx + +
+ +
+
+``` + +### Embed properties +| Option | Type | Description | +|---|---|---| +| src | string | URL for the page that needs to be embedded | +| height | number | Height needed for the embedded block within the story. Note that the width is automatically set to the full page witdh. | + ## Some gotchas - Do not use h1(`# heading 1`) for your header. `h1` is reserved for page title.