+ Hide the toolbar when the mouse is not within the Canvas?
+
+
+
+
+`;
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.components.examples.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.components.examples.tsx
new file mode 100644
index 00000000000000..409c21a9a45617
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.components.examples.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+import { action } from '@storybook/addon-actions';
+
+import { Title } from '../footer/title';
+import { PageControls } from '../footer/page_controls';
+
+storiesOf('runtime/Footer/components', module)
+ .add('Title', () => (
+
+
+
+ ))
+ .add('PageControls', () => (
+
+ ));
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.examples.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.examples.tsx
new file mode 100644
index 00000000000000..7d26b0a5d05e9e
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.examples.tsx
@@ -0,0 +1,41 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { storiesOf } from '@storybook/react';
+import React from 'react';
+import { Context } from '../../context/mock';
+
+import { Footer } from '../footer/footer.container';
+import { Title } from '../footer/title.container';
+import { PageControls } from '../footer/page_controls.container';
+import { PagePreview } from '../footer/page_preview.container';
+import { Scrubber } from '../footer/scrubber.container';
+
+storiesOf('runtime/Footer', module)
+ .add('Footer', () => (
+
+
+
+ ))
+ .add('Title', () => (
+
+
+
+ ))
+ .add('Scrubber', () => (
+
+
+
+ ))
+ .add('PageControls', () => (
+
+
+
+ ))
+ .add('PagePreview', () => (
+
+
+
+ ));
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/runtime.examples.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/runtime.examples.tsx
new file mode 100644
index 00000000000000..a66e85c9afa706
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/runtime.examples.tsx
@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { storiesOf } from '@storybook/react';
+import React from 'react';
+import { Context } from '../../context/mock';
+
+import hello from '../../test/hello.json';
+import { Canvas } from '../canvas.container';
+import { Page } from '../page.container';
+import { RenderedElement } from '../rendered_element.container';
+
+storiesOf('runtime', module)
+ .add('Canvas', () => (
+
+
+
+ ))
+ .add('Page', () => (
+
+
+
+ ))
+ .add('RenderedElement', () => (
+
+
+
+ ));
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/settings.components.examples.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/settings.components.examples.tsx
new file mode 100644
index 00000000000000..6c0c337cdcd53a
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/settings.components.examples.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+import { action } from '@storybook/addon-actions';
+
+import { AutoplaySettings } from '../footer/settings/autoplay_settings';
+import { ToolbarSettings } from '../footer/settings/toolbar_settings';
+
+storiesOf('runtime/Settings/components', module)
+ .add('AutoplaySettings, autoplay disabled', () => (
+
+ ))
+ .add('AutoplaySettings, autoplay enabled', () => (
+
+ ))
+ .add('ToolbarSettings, autohide enabled', () => (
+
+ ))
+ .add('ToolbarSettings, autohide disabled', () => (
+
+ ));
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/settings.examples.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/settings.examples.tsx
new file mode 100644
index 00000000000000..c2f481007fa7c8
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/settings.examples.tsx
@@ -0,0 +1,29 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { storiesOf } from '@storybook/react';
+import React from 'react';
+import { Context } from '../../context/mock';
+
+import { AutoplaySettings } from '../footer/settings/autoplay_settings.container';
+import { Settings } from '../footer/settings/settings.container';
+import { ToolbarSettings } from '../footer/settings/toolbar_settings.container';
+
+storiesOf('runtime/Settings', module)
+ .add('Settings', () => (
+
+
+
+ ))
+ .add('AutoplaySettings', () => (
+
+
+
+ ))
+ .add('ToolbarSettings', () => (
+
+
+
+ ));
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/app.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/app.tsx
index 936349155ff90a..55edc4217d5df4 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/app.tsx
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/app.tsx
@@ -5,22 +5,15 @@
*/
import React from 'react';
-// @ts-ignore Untyped package
-import { RenderFunctionsRegistry } from 'data/interpreter';
-import { Canvas } from './canvas';
-import {
- initialExternalEmbedState,
- ExternalEmbedStateProvider,
- ExternalEmbedState,
-} from '../context';
+import { Canvas } from './canvas.container';
+import { initialExternalEmbedState, ExternalEmbedStateProvider } from '../context';
// @ts-ignore Untyped local
import { renderFunctions } from '../../canvas_plugin_src/renderers';
-import { CanvasRenderedWorkpad } from '../types';
+import { CanvasRenderedWorkpad, ExternalEmbedState, Stage } from '../types';
+import { RendererFactory, RendererSpec } from '../../types';
interface Props {
- height: number;
- width: number;
- page: number;
+ stage: Stage;
workpad: CanvasRenderedWorkpad;
}
@@ -28,23 +21,20 @@ interface Props {
* The overall Embedded Workpad app; the highest-layer component.
*/
export const App = (props: Props) => {
- const { workpad, page, height, width } = props;
+ const { workpad, stage } = props;
- // Register all of the rendering experessions with a bespoke registry.
- const renderersRegistry = new RenderFunctionsRegistry();
-
- renderFunctions.forEach((fn: Function | undefined) => {
+ const renderers: { [key: string]: RendererSpec } = {};
+ renderFunctions.forEach((fn: RendererFactory | undefined) => {
if (fn) {
- renderersRegistry.register(fn);
+ const func = fn();
+ renderers[func.name] = func;
}
});
const initialState: ExternalEmbedState = {
...initialExternalEmbedState,
- height,
- page,
- renderersRegistry,
- width,
+ stage,
+ renderers,
workpad,
};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.container.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.container.tsx
new file mode 100644
index 00000000000000..b15b91cb09b369
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.container.tsx
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { useExternalEmbedState, setPageAction, setScrubberVisibleAction } from '../context';
+import { Canvas as CanvasComponent, onSetPageProp, onSetScrubberVisibleProp } from './canvas';
+
+export const Canvas = () => {
+ const [{ workpad, stage, settings, refs }, dispatch] = useExternalEmbedState();
+
+ if (!workpad) {
+ return null;
+ }
+
+ const onSetPage: onSetPageProp = (page: number) => {
+ dispatch(setPageAction(page));
+ };
+
+ const onSetScrubberVisible: onSetScrubberVisibleProp = (visible: boolean) => {
+ dispatch(setScrubberVisibleAction(visible));
+ };
+
+ return (
+
+ );
+};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.tsx
index 7a999157f2fd9e..d7d3b4e6bab341 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.tsx
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/canvas.tsx
@@ -5,42 +5,52 @@
*/
import React, { useState } from 'react';
-import { useExternalEmbedState, setPage, setScrubberVisible } from '../context';
-import { Page } from './page';
+import { Page } from './page.container';
import { Footer, FOOTER_HEIGHT } from './footer';
import { getTimeInterval } from '../../public/lib/time_interval';
-// @ts-ignore CSS Module
-import css from './canvas.module';
+import css from './canvas.module.scss';
+import { CanvasRenderedWorkpad, Stage, Settings, Refs } from '../types';
let timeout: number = 0;
+export type onSetPageProp = (page: number) => void;
+export type onSetScrubberVisibleProp = (visible: boolean) => void;
+
+interface Props {
+ onSetPage: onSetPageProp;
+ onSetScrubberVisible: onSetScrubberVisibleProp;
+ refs: Pick;
+ settings: Settings;
+ stage: Stage;
+ workpad: Pick;
+}
+
/**
* The "stage" for a workpad, which composes the toolbar and other components.
*/
-export const Canvas = () => {
- const [
- { workpad, height: containerHeight, width: containerWidth, page, settings, refs },
- dispatch,
- ] = useExternalEmbedState();
-
- if (!workpad) {
- return null;
- }
-
+export const Canvas = ({
+ onSetPage = () => {},
+ onSetScrubberVisible = () => {},
+ refs,
+ settings,
+ stage,
+ workpad,
+}: Props) => {
const { toolbar, autoplay } = settings;
- const { height, width, pages } = workpad;
- const ratio = Math.max(width / containerWidth, height / containerHeight);
- const transform = `scale3d(${containerHeight / (containerHeight * ratio)}, ${containerWidth /
- (containerWidth * ratio)}, 1)`;
+ const { height: stageHeight, width: stageWidth, page } = stage;
+ const { height: workpadHeight, width: workpadWidth } = workpad;
+ const ratio = Math.max(workpadWidth / stageWidth, workpadHeight / stageHeight);
+ const transform = `scale3d(${stageHeight / (stageHeight * ratio)}, ${stageWidth /
+ (stageWidth * ratio)}, 1)`;
const pageStyle = {
- height,
+ height: workpadHeight,
transform,
- width,
+ width: workpadWidth,
};
- if (autoplay.enabled && autoplay.interval) {
+ if (autoplay.isEnabled && autoplay.interval) {
// We need to clear the timeout every time, even if it doesn't need to be or
// it's null. Since one could select a different page from the scrubber at
// any point, or change the interval, we need to make sure the interval is
@@ -49,19 +59,19 @@ export const Canvas = () => {
clearTimeout(timeout);
timeout = setTimeout(
- () => dispatch(setPage(page >= workpad.pages.length - 1 ? 0 : page + 1)),
+ () => onSetPage(page >= workpad.pages.length - 1 ? 0 : page + 1),
getTimeInterval(autoplay.interval)
);
}
- const [toolbarHidden, setToolbarHidden] = useState(toolbar.autohide);
- const rootHeight = containerHeight + (toolbar.autohide ? 0 : FOOTER_HEIGHT);
+ const [toolbarHidden, setToolbarHidden] = useState(toolbar.isAutohide);
+ const rootHeight = stageHeight + (toolbar.isAutohide ? 0 : FOOTER_HEIGHT);
const hideToolbar = (hidden: boolean) => {
- if (settings.toolbar.autohide) {
+ if (toolbar.isAutohide) {
if (hidden) {
// Hide the scrubber if we hide the toolbar.
- dispatch(setScrubberVisible(false));
+ onSetScrubberVisible(false);
}
setToolbarHidden(hidden);
}
@@ -70,17 +80,17 @@ export const Canvas = () => {
return (
);
};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.container.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.container.tsx
new file mode 100644
index 00000000000000..9fe43496092ff9
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.container.tsx
@@ -0,0 +1,39 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { useExternalEmbedState, setScrubberVisibleAction } from '../../context';
+import { Footer as FooterComponent } from './footer';
+export { FOOTER_HEIGHT } from './footer';
+
+interface Props {
+ isHidden?: boolean;
+}
+
+/**
+ * The footer of the Embedded Workpad.
+ */
+export const Footer = ({ isHidden = false }: Props) => {
+ const [{ workpad, settings, footer }, dispatch] = useExternalEmbedState();
+
+ if (!workpad) {
+ return null;
+ }
+
+ const { toolbar } = settings;
+ const { isAutohide } = toolbar;
+ const { isScrubberVisible } = footer;
+
+ // If autohide is enabled, and the toolbar is hidden, set the scrubber
+ // visibility to hidden. This is useful for state changes where one
+ // sets the footer to hidden, and the scrubber would be left open with
+ // no toolbar.
+ if (isAutohide && isHidden && isScrubberVisible) {
+ dispatch(setScrubberVisibleAction(false));
+ }
+
+ return ;
+};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.tsx
index 6716d46fba52ad..04ca1a270fdcfe 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.tsx
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/footer.tsx
@@ -6,46 +6,32 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
-import { useExternalEmbedState, setScrubberVisible } from '../../context';
-import { Scrubber } from './scrubber';
-import { Title } from './title';
-import { PageControls } from './page_controls';
+import { Scrubber } from './scrubber.container';
+import { Title } from './title.container';
+import { PageControls } from './page_controls.container';
import { Settings } from './settings';
-// @ts-ignore CSS Module
-import css from './footer.module';
+import css from './footer.module.scss';
export const FOOTER_HEIGHT = 48;
interface Props {
- hidden?: boolean;
+ isAutohide?: boolean;
+ isHidden?: boolean;
}
/**
* The footer of the Embedded Workpad.
*/
-export const Footer = ({ hidden = false }: Props) => {
- const [{ workpad, settings }] = useExternalEmbedState();
- if (!workpad) {
- return null;
- }
-
- const { autohide } = settings.toolbar;
-
- // If autohide is enabled, and the toolbar is hidden, set the scrubber
- // visibility to hidden. This is useful for state changes where one
- // sets the footer to hidden, and the scrubber would be left open with
- // no toolbar.
- if (autohide && hidden) {
- setScrubberVisible(false);
- }
+export const Footer = ({ isAutohide = false, isHidden = false }: Props) => {
+ const { root, bar, title } = css;
return (
-
+
-
+
-
+
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/index.ts b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/index.ts
index 72acba529b25b7..42fc2a38e59096 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/index.ts
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/index.ts
@@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export * from './footer';
+export * from './footer.container';
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.container.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.container.tsx
new file mode 100644
index 00000000000000..e7aaafd3947021
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.container.tsx
@@ -0,0 +1,37 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import {
+ useExternalEmbedState,
+ setScrubberVisibleAction,
+ setPageAction,
+ setAutoplayAction,
+} from '../../context';
+import { PageControls as PageControlsComponent } from './page_controls';
+
+/**
+ * The page count and paging controls within the footer of the Embedded Workpad.
+ */
+export const PageControls = () => {
+ const [{ workpad, footer, stage }, dispatch] = useExternalEmbedState();
+
+ if (!workpad) {
+ return null;
+ }
+
+ const { isScrubberVisible } = footer;
+ const { page } = stage;
+ const totalPages = workpad.pages.length;
+
+ const onToggleScrubber = () => {
+ dispatch(setAutoplayAction(false));
+ dispatch(setScrubberVisibleAction(!isScrubberVisible));
+ };
+ const onSetPageNumber = (number: number) => dispatch(setPageAction(number));
+
+ return ;
+};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.tsx
index 86075c274740d6..b1c993f515adc5 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.tsx
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_controls.tsx
@@ -6,42 +6,36 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon, EuiButtonEmpty, EuiText } from '@elastic/eui';
-import { useExternalEmbedState, setScrubberVisible, setPage, setAutoplay } from '../../context';
+
+export type onSetPageNumberProp = (page: number) => void;
+export type onToggleScrubberProp = () => void;
+
+interface Props {
+ page: number;
+ totalPages: number;
+ onSetPageNumber: onSetPageNumberProp;
+ onToggleScrubber: onToggleScrubberProp;
+}
/**
* The page count and paging controls within the footer of the Embedded Workpad.
*/
-export const PageControls = () => {
- const [{ workpad, footer, page }, dispatch] = useExternalEmbedState();
-
- if (!workpad) {
- return null;
- }
-
- const { isScrubberVisible } = footer;
-
- const toggleScrubber = () => {
- dispatch(setAutoplay(false));
- dispatch(setScrubberVisible(!isScrubberVisible));
- };
-
- const setPageNumber = (number: number) => dispatch(setPage(number));
+export const PageControls = ({ onSetPageNumber, page, totalPages, onToggleScrubber }: Props) => {
const currentPage = page + 1;
- const totalPages = workpad.pages.length;
return (
setPageNumber(page - 1)}
+ onClick={() => onSetPageNumber(page - 1)}
iconType="arrowLeft"
disabled={currentPage <= 1}
aria-label="Previous Page"
/>
-
+
Page {currentPage}
{totalPages > 1 ? ` of ${totalPages}` : null}
@@ -51,7 +45,7 @@ export const PageControls = () => {
setPageNumber(page + 1)}
+ onClick={() => onSetPageNumber(page + 1)}
iconType="arrowRight"
disabled={currentPage >= totalPages}
aria-label="Next Page"
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.container.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.container.tsx
new file mode 100644
index 00000000000000..41495f330b4f39
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.container.tsx
@@ -0,0 +1,33 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { useExternalEmbedState } from '../../context';
+import { setPageAction } from '../../context/actions';
+import { PagePreview as PagePreviewComponent } from './page_preview';
+
+interface Props {
+ index: number;
+ height: number;
+}
+
+/**
+ * The small preview of the page shown within the `Scrubber`.
+ */
+export const PagePreview = ({ index, height }: Props) => {
+ const [{ workpad }, dispatch] = useExternalEmbedState();
+ if (!workpad) {
+ return null;
+ }
+
+ const page = workpad.pages[index];
+ const onClick = (pageIndex: number) => dispatch(setPageAction(pageIndex));
+ const { height: workpadHeight, width: workpadWidth } = workpad;
+
+ return (
+
+ );
+};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.tsx
index 805d68a9e2f2c5..213cc94a865d12 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.tsx
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/page_preview.tsx
@@ -5,36 +5,39 @@
*/
import React from 'react';
-import { useExternalEmbedState } from '../../context';
import { Page } from '../page';
-import { setPage } from '../../context/actions';
import { CanvasRenderedPage } from '../../types';
-// @ts-ignore CSS Module
-import css from './page_preview.module';
+import css from './page_preview.module.scss';
-interface Props {
- number: number;
+export type onClickProp = (index: number) => void;
+
+export interface Props {
height: number;
+ index: number;
+ onClick: onClickProp;
page: CanvasRenderedPage;
+ workpadHeight: number;
+ workpadWidth: number;
}
/**
* The small preview of the page shown within the `Scrubber`.
*/
-export const PagePreview = ({ number, page, height }: Props) => {
- const [{ workpad }, dispatch] = useExternalEmbedState();
- if (!workpad) {
- return null;
- }
-
- const onClick = (index: number) => dispatch(setPage(index));
- const { height: workpadHeight, width: workpadWidth } = workpad;
+export const PagePreview = ({
+ height,
+ index,
+ onClick,
+ page,
+ workpadHeight,
+ workpadWidth,
+}: Props) => {
const scale = height / workpadHeight;
const style = {
height: workpadHeight * scale,
width: workpadWidth * scale,
};
+
const transform = {
...style,
transform: `scale3d(${scale}, ${scale}, 1)`,
@@ -43,12 +46,12 @@ export const PagePreview = ({ number, page, height }: Props) => {
return (
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.container.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.container.tsx
new file mode 100644
index 00000000000000..96740d2e679788
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.container.tsx
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { useExternalEmbedState } from '../../context';
+import { Title as TitleComponent } from './title';
+
+/**
+ * The title of the workpad displayed in the right-hand of the footer.
+ */
+export const Title = () => {
+ const [{ workpad }] = useExternalEmbedState();
+
+ if (!workpad) {
+ return null;
+ }
+
+ const { name: title } = workpad;
+
+ return ;
+};
diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.tsx
index 6296e55007ef60..c7339fe14d739f 100644
--- a/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.tsx
+++ b/x-pack/legacy/plugins/canvas/external_runtime/components/footer/title.tsx
@@ -6,28 +6,22 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from '@elastic/eui';
-import { useExternalEmbedState } from '../../context';
+interface Props {
+ title: string;
+}
/**
* The title of the workpad displayed in the right-hand of the footer.
*/
-export const Title = () => {
- const [{ workpad }] = useExternalEmbedState();
-
- if (!workpad) {
- return null;
- }
-
- return (
-
-
-
-
-
-
-