diff --git a/__tests__/src/components/CompanionWindow.test.js b/__tests__/src/components/CompanionWindow.test.js
index 9c8896ccd93e9ac564c92d3a2d163c21093ebef2..3666ce275ee5e3ba83eb39dfee0b19bfc95c421f 100644
--- a/__tests__/src/components/CompanionWindow.test.js
+++ b/__tests__/src/components/CompanionWindow.test.js
@@ -72,4 +72,9 @@ describe('CompanionWindow', () => {
     expect(updateCompanionWindow).toHaveBeenCalledTimes(1);
     expect(updateCompanionWindow).toHaveBeenCalledWith('x', 'abc123', { position: 'right' });
   });
+
+  it('renders title controls', () => {
+    companionWindow = createWrapper({ position: 'bottom', titleControls: <div className="xyz" /> });
+    expect(companionWindow.find('div.xyz').length).toBe(1);
+  });
 });
diff --git a/__tests__/src/components/WindowSideBarCanvasPanel.test.js b/__tests__/src/components/WindowSideBarCanvasPanel.test.js
index 2d3f7f29faf096e945a196b3dbbba5d3cc9372e8..e01de7a023d63ddbb5747e67434e9a7e6450650e 100644
--- a/__tests__/src/components/WindowSideBarCanvasPanel.test.js
+++ b/__tests__/src/components/WindowSideBarCanvasPanel.test.js
@@ -5,40 +5,70 @@ import ListItem from '@material-ui/core/ListItem';
 import Typography from '@material-ui/core/Typography';
 import manifesto from 'manifesto.js';
 import { WindowSideBarCanvasPanel } from '../../../src/components/WindowSideBarCanvasPanel';
+import { CanvasThumbnail } from '../../../src/components/CanvasThumbnail';
 import manifestJson from '../../fixtures/version-2/019.json';
 import { getIdAndLabelOfCanvases } from '../../../src/state/selectors';
 
+/**
+ * Helper function to create a shallow wrapper around WindowSideBarCanvasPanel
+ */
+function createWrapper(props) {
+  const canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
+
+  return shallow(
+    <WindowSideBarCanvasPanel
+      id="asdf"
+      canvases={canvases}
+      classes={{}}
+      t={key => key}
+      windowId="xyz"
+      setCanvas={() => {}}
+      config={{ canvasNavigation: { height: 100 } }}
+      {...props}
+    />,
+  );
+}
+
 describe('WindowSideBarCanvasPanel', () => {
-  let wrapper;
   let setCanvas;
-  let canvases;
 
   beforeEach(() => {
     setCanvas = jest.fn();
-    canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
-
-    wrapper = shallow(
-      <WindowSideBarCanvasPanel
-        id="asdf"
-        canvases={canvases}
-        classes={{}}
-        t={key => key}
-        windowId="xyz"
-        setCanvas={setCanvas}
-        config={{ canvasNavigation: { height: 100 } }}
-      />,
-    );
   });
 
-  it('renders all needed elements', () => {
+  it('renders all needed elements for the thumbnail view', () => {
+    const wrapper = createWrapper();
+    expect(wrapper.props().title).toBe('canvasIndex');
+    expect(wrapper.find(List).length).toBe(1);
+    expect(wrapper.find(ListItem).length).toBe(3);
+    expect(wrapper.find(ListItem).first().props().component).toEqual('li');
+    expect(wrapper.find(List).find(Typography).length).toBe(3);
+    expect(wrapper.find(CanvasThumbnail).length).toBe(3);
+  });
+
+  describe('handleVariantChange', () => {
+    it('toggles state', () => {
+      const wrapper = createWrapper();
+      wrapper.instance().handleVariantChange({ target: { value: 'compact' } });
+      expect(wrapper.state().variant).toBe('compact');
+    });
+  });
+
+  it('renders all needed elements for the compact view', () => {
+    const wrapper = createWrapper();
+    wrapper.setState({ variant: 'compact' });
     expect(wrapper.props().title).toBe('canvasIndex');
     expect(wrapper.find(List).length).toBe(1);
     expect(wrapper.find(ListItem).length).toBe(3);
     expect(wrapper.find(ListItem).first().props().component).toEqual('li');
     expect(wrapper.find(List).find(Typography).length).toBe(3);
+    expect(wrapper.find(CanvasThumbnail).length).toBe(0);
   });
 
+
   it('should set the correct labels', () => {
+    const wrapper = createWrapper();
+    const canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
     const idsAndLabels = getIdAndLabelOfCanvases(canvases);
     expect(wrapper
       .find(List)
@@ -56,6 +86,7 @@ describe('WindowSideBarCanvasPanel', () => {
   });
 
   it('should call the onClick handler of a list item', () => {
+    const wrapper = createWrapper({ setCanvas });
     wrapper.find(ListItem).at(1).simulate('click');
     expect(setCanvas).toHaveBeenCalledTimes(1);
   });
diff --git a/src/components/CompanionWindow.js b/src/components/CompanionWindow.js
index 585009d68f2a16b48366b3dc2c0bf90a8255b5c0..86eb876822abe9362fb38b7741553253ab564e7a 100644
--- a/src/components/CompanionWindow.js
+++ b/src/components/CompanionWindow.js
@@ -21,7 +21,7 @@ export class CompanionWindow extends Component {
   render() {
     const {
       classes, paperClassName, id, onCloseClick, updateCompanionWindow, isDisplayed,
-      position, t, windowId, title, children,
+      position, t, windowId, title, children, titleControls,
     } = this.props;
 
     return (
@@ -35,10 +35,13 @@ export class CompanionWindow extends Component {
         component="aside"
         aria-label={title}
       >
-        <Toolbar variant="dense" className={[position === 'left' ? classes.leftPadding : undefined, ns('companion-window-header')].join(' ')} disableGutters>
+        <Toolbar className={[classes.toolbar, position === 'left' ? classes.leftPadding : undefined, ns('companion-window-header')].join(' ')} disableGutters>
           <Typography variant="h3" className={classes.windowSideBarTitle}>
             {title}
           </Typography>
+          <div className={ns('companion-window-title-controls')}>
+            {titleControls}
+          </div>
           {
             position === 'left'
               ? updateCompanionWindow
@@ -94,6 +97,7 @@ CompanionWindow.propTypes = {
   isDisplayed: PropTypes.bool,
   t: PropTypes.func,
   title: PropTypes.string,
+  titleControls: PropTypes.node,
   windowId: PropTypes.string.isRequired,
   children: PropTypes.node,
 };
@@ -107,4 +111,5 @@ CompanionWindow.defaultProps = {
   title: null,
   t: key => key,
   children: undefined,
+  titleControls: null,
 };
diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js
index 1ddb7b55e691deabdf1781fb93872ef8ed0550f3..e21e817eb191147daf48d592b49beb85e6ba16c8 100644
--- a/src/components/WindowSideBarCanvasPanel.js
+++ b/src/components/WindowSideBarCanvasPanel.js
@@ -4,6 +4,10 @@ import classNames from 'classnames';
 import Typography from '@material-ui/core/Typography';
 import List from '@material-ui/core/List';
 import ListItem from '@material-ui/core/ListItem';
+import FilledInput from '@material-ui/core/FilledInput';
+import MenuItem from '@material-ui/core/MenuItem';
+import FormControl from '@material-ui/core/FormControl';
+import Select from '@material-ui/core/Select';
 import { CanvasThumbnail } from './CanvasThumbnail';
 import ManifestoCanvas from '../lib/ManifestoCanvas';
 import CompanionWindow from '../containers/CompanionWindow';
@@ -13,23 +17,103 @@ import { getIdAndLabelOfCanvases } from '../state/selectors';
  * a panel showing the canvases for a given manifest
  */
 export class WindowSideBarCanvasPanel extends Component {
+  /** */
+  constructor(props) {
+    super(props);
+
+    this.state = { variant: 'thumbnail' };
+    this.handleVariantChange = this.handleVariantChange.bind(this);
+  }
+
+  /** */
+  handleVariantChange(event) {
+    this.setState({ variant: event.target.value });
+  }
+
+  /** */
+  renderCompact(canvas, otherCanvas) {
+    const {
+      classes,
+    } = this.props;
+
+    return (
+      <>
+        <Typography
+          className={classNames(classes.label)}
+          variant="body2"
+        >
+          {canvas.label}
+        </Typography>
+      </>
+    );
+  }
+
+  /** */
+  renderThumbnail(canvas, otherCanvas) {
+    const {
+      classes, config,
+    } = this.props;
+    const { width, height } = config.canvasNavigation;
+    const manifestoCanvas = new ManifestoCanvas(otherCanvas);
+
+    return (
+      <>
+        <div style={{ minWidth: 50 }}>
+          <CanvasThumbnail
+            className={classNames(classes.clickable)}
+            isValid={manifestoCanvas.hasValidDimensions}
+            imageUrl={manifestoCanvas.thumbnail(width, height)}
+            maxHeight={config.canvasNavigation.height}
+            maxWidth={config.canvasNavigation.width}
+            aspectRatio={manifestoCanvas.aspectRatio}
+          />
+        </div>
+        <Typography
+          className={classNames(classes.label)}
+          variant="body2"
+        >
+          {canvas.label}
+        </Typography>
+      </>
+    );
+  }
+
   /**
    * render
    */
   render() {
     const {
-      canvases, classes, config, setCanvas, t, windowId, id,
+      canvases, setCanvas, t, windowId, id,
     } = this.props;
 
+    const { variant } = this.state;
+
+
     const canvasesIdAndLabel = getIdAndLabelOfCanvases(canvases);
     return (
-      <CompanionWindow title={t('canvasIndex')} id={id} windowId={windowId}>
+      <CompanionWindow
+        title={t('canvasIndex')}
+        id={id}
+        windowId={windowId}
+        titleControls={(
+          <FormControl variant="filled">
+            <Select
+              value={variant}
+              onChange={this.handleVariantChange}
+              name="variant"
+              autoWidth
+              variant="filled"
+              input={<FilledInput name="variant" />}
+            >
+              <MenuItem value="compact">Compact List</MenuItem>
+              <MenuItem value="thumbnail">Thumbnail List</MenuItem>
+            </Select>
+          </FormControl>
+          )}
+      >
         <List>
           {
             canvasesIdAndLabel.map((canvas, canvasIndex) => {
-              const { width, height } = config.canvasNavigation;
-              const manifestoCanvas = new ManifestoCanvas(canvases[canvasIndex]);
-              const isValid = manifestoCanvas.hasValidDimensions;
               const onClick = () => { setCanvas(windowId, canvasIndex); }; // eslint-disable-line require-jsdoc, max-len
 
               return (
@@ -40,22 +124,8 @@ export class WindowSideBarCanvasPanel extends Component {
                   button
                   component="li"
                 >
-                  <div style={{ minWidth: 50 }}>
-                    <CanvasThumbnail
-                      className={classNames(classes.clickable)}
-                      isValid={isValid}
-                      imageUrl={manifestoCanvas.thumbnail(width, height)}
-                      maxHeight={config.canvasNavigation.height}
-                      maxWidth={config.canvasNavigation.width}
-                      aspectRatio={manifestoCanvas.aspectRatio}
-                    />
-                  </div>
-                  <Typography
-                    className={classNames(classes.label)}
-                    variant="body2"
-                  >
-                    {canvas.label}
-                  </Typography>
+                  {variant === 'compact' && this.renderCompact(canvas, canvases[canvasIndex])}
+                  {variant === 'thumbnail' && this.renderThumbnail(canvas, canvases[canvasIndex])}
                 </ListItem>
               );
             })
diff --git a/src/containers/CompanionWindow.js b/src/containers/CompanionWindow.js
index 3d7e6724df9b27c38e139c943d1770ec067c1d78..b49ca85c4803c54a6d2ce43a4e97ef6572a577b5 100644
--- a/src/containers/CompanionWindow.js
+++ b/src/containers/CompanionWindow.js
@@ -59,6 +59,9 @@ const styles = theme => ({
   positionButton: {
     order: -100,
   },
+  toolbar: {
+    minHeight: 'max-content',
+  },
   leftPadding: {
     ...theme.mixins.gutters(),
     paddingRight: 0,
diff --git a/src/styles/index.scss b/src/styles/index.scss
index d7a3b3ea2a454126e5ee4f41179efae4983487fe..3ee4ebacd60d346ba7a792df99249db8630ccce5 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -20,6 +20,21 @@
     }
   }
 
+  &-companion-window-header {
+    flex-wrap: wrap;
+  }
+
+  &-companion-window-title-controls {
+    order: 1000;
+    flex-grow: 1;
+  }
+
+  &-companion-window-bottom {
+    .mirador-companion-window-title-controls {
+      order: unset;
+    }
+  }
+
   &-companion-window-header {
     background: $surface-dark;
   }