diff --git a/__tests__/src/components/ThumbnailNavigation.test.js b/__tests__/src/components/ThumbnailNavigation.test.js index b418a310ec80fd480ab0e16cfa31566d2bcf7b68..fb31364882d8128d94f585812af8fb0b1899283c 100644 --- a/__tests__/src/components/ThumbnailNavigation.test.js +++ b/__tests__/src/components/ThumbnailNavigation.test.js @@ -64,8 +64,7 @@ describe('ThumbnailNavigation', () => { expect(setCanvas).toHaveBeenCalledWith('foobar', 0); }); it('sets up calculated width based off of height of area and dimensions of canvas', () => { - expect(renderedGrid.find('.mirador-thumbnail-nav-container').first().prop('style').width).toEqual(108); - expect(renderedGrid.find('.mirador-thumbnail-nav-canvas').first().prop('style').width).toEqual(100); + expect(renderedGrid.find('.mirador-thumbnail-nav-container').first().prop('style').width).toEqual(93); }); it('renders canvas thumbnails', () => { expect(renderedGrid.find('CanvasThumbnail').length).toBe(3); @@ -109,7 +108,7 @@ describe('ThumbnailNavigation', () => { }); it('style', () => { expect(wrapper.instance().style()).toMatchObject({ height: '150px', width: '100%' }); - expect(rightWrapper.instance().style()).toMatchObject({ height: '100%', width: '100px' }); + expect(rightWrapper.instance().style()).toMatchObject({ height: '100%', width: '122px' }); }); it('rightWidth', () => { expect(wrapper.instance().rightWidth()).toEqual(100); @@ -126,12 +125,12 @@ describe('ThumbnailNavigation', () => { expect(wrapper.instance().rightWidth()).toEqual(200); }); it('calculateScaledWidth', () => { - expect(wrapper.instance().calculateScaledWidth({ index: 0 })).toEqual(108); + expect(wrapper.instance().calculateScaledWidth({ index: 0 })).toEqual(93); expect(rightWrapper.instance().calculateScaledWidth({ index: 0 })).toEqual(100); }); it('calculateScaledHeight', () => { - expect(wrapper.instance().calculateScaledHeight({ index: 0 })).toEqual(150); - expect(rightWrapper.instance().calculateScaledHeight({ index: 0 })).toEqual(150); + expect(wrapper.instance().calculateScaledHeight({ index: 0 })).toEqual(140); + expect(rightWrapper.instance().calculateScaledHeight({ index: 0 })).toEqual(132); }); it('columnCount', () => { diff --git a/src/components/ThumbnailNavigation.js b/src/components/ThumbnailNavigation.js index 2626aaadbb367d23dfe07edb4e5afab6c22dae20..512e9987129733b5260e6326de239f02cc6bcc10 100644 --- a/src/components/ThumbnailNavigation.js +++ b/src/components/ThumbnailNavigation.js @@ -2,9 +2,11 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; import Grid from 'react-virtualized/dist/commonjs/Grid'; +import GridList from '@material-ui/core/GridList'; import GridListTile from '@material-ui/core/GridListTile'; import GridListTileBar from '@material-ui/core/GridListTileBar'; import Typography from '@material-ui/core/Typography'; +import classNames from 'classnames'; import { CanvasThumbnail } from './CanvasThumbnail'; import ManifestoCanvas from '../lib/ManifestoCanvas'; import ns from '../config/css-ns'; @@ -18,6 +20,8 @@ export class ThumbnailNavigation extends Component { constructor(props) { super(props); + this.scrollbarSize = 10; + this.spacing = 12; // 2 * (2px margin + 2px border + 2px padding) this.cellRenderer = this.cellRenderer.bind(this); this.calculateScaledHeight = this.calculateScaledHeight.bind(this); this.calculateScaledWidth = this.calculateScaledWidth.bind(this); @@ -58,7 +62,8 @@ export class ThumbnailNavigation extends Component { classes, window, setCanvas, config, canvasGroupings, position, } = this.props; const currentIndex = (position === 'far-right') ? rowIndex : columnIndex; - + const maxHeight = (position === 'far-right') ? null : config.thumbnailNavigation.height - (this.scrollbarSize + 12); + const maxWidth = (position === 'far-right') ? config.thumbnailNavigation.width : null; const currentGroupings = canvasGroupings.groupings()[currentIndex]; return ( <div @@ -66,30 +71,35 @@ export class ThumbnailNavigation extends Component { style={style} className={ns('thumbnail-nav-container')} > - <div - style={{ - width: style.width - 8, - }} - className={ns(['thumbnail-nav-canvas', `thumbnail-nav-canvas-${currentIndex}`, this.currentCanvasClass(currentGroupings.map(canvas => canvas.index))])} + <GridList + component="div" + spacing={0} + className={classNames( + ns(['thumbnail-nav-canvas', `thumbnail-nav-canvas-${currentIndex}`, this.currentCanvasClass(currentGroupings.map(canvas => canvas.index))]), + classes.canvas, + { + [classes.currentCanvas]: currentGroupings + .map(canvas => canvas.index).includes(window.canvasIndex), + }, + )} > {currentGroupings.map((canvas, i) => { - const { height } = config.thumbnailNavigation; const manifestoCanvas = new ManifestoCanvas(canvas); - return ( <GridListTile component="div" key={canvas.index} onClick={() => setCanvas(window.id, currentGroupings[0].index)} style={{ - position: 'absolute', left: (style.width - 8) * i / 2, top: 2, + height: style.height - this.spacing / 2, + width: currentGroupings.length === 2 ? '50%' : '100%', }} > <CanvasThumbnail - imageUrl={manifestoCanvas.thumbnail(null, height)} + imageUrl={manifestoCanvas.thumbnail(null, maxHeight)} isValid={manifestoCanvas.hasValidDimensions} - maxHeight={config.thumbnailNavigation.height} - maxWidth={style.width} + maxHeight={maxHeight} + maxWidth={maxWidth} aspectRatio={manifestoCanvas.aspectRatio} /> <GridListTileBar @@ -103,7 +113,7 @@ export class ThumbnailNavigation extends Component { </GridListTile> ); })} - </div> + </GridList> </div> ); } @@ -122,7 +132,7 @@ export class ThumbnailNavigation extends Component { default: return canvasGroupings.getCanvases(options.index) .map(canvas => new ManifestoCanvas(canvas)) - .reduce((acc, currentCanvas) => { return acc + (currentCanvas.hasValidDimensions ? Math.floor(config.thumbnailNavigation.height * currentCanvas.aspectRatio) : config.thumbnailNavigation.width); }, 8); // eslint-disable-line arrow-body-style, max-len + .reduce((acc, currentCanvas) => { return acc + (currentCanvas.hasValidDimensions ? Math.floor((config.thumbnailNavigation.height - this.scrollbarSize) * currentCanvas.aspectRatio) : config.thumbnailNavigation.width); }, 0); // eslint-disable-line arrow-body-style, max-len } } @@ -138,11 +148,11 @@ export class ThumbnailNavigation extends Component { return Math.max( ...canvasGroupings.getCanvases(options.index) .map(canvas => new ManifestoCanvas(canvas)) - .map(canvas => (canvas.hasValidDimensions ? Math.floor(config.thumbnailNavigation.width / canvas.aspectRatio) : config.thumbnailNavigation.height)), // eslint-disable-line arrow-body-style, max-len + .map(canvas => (canvas.hasValidDimensions ? Math.floor((config.thumbnailNavigation.width - this.spacing) / canvas.aspectRatio) : config.thumbnailNavigation.height - 12)), // eslint-disable-line arrow-body-style, max-len ); // Default case bottom default: - return config.thumbnailNavigation.height; + return config.thumbnailNavigation.height - this.scrollbarSize; } } @@ -167,7 +177,7 @@ export class ThumbnailNavigation extends Component { case 'far-right': return { height: '100%', - width: `${this.rightWidth()}px`, + width: `${this.rightWidth() + this.scrollbarSize + this.spacing}px`, display: 'flex', minHeight: 0, }; @@ -185,7 +195,7 @@ export class ThumbnailNavigation extends Component { const { window, config } = this.props; switch (window.view) { case 'book': - return config.thumbnailNavigation.width * 2; + return (config.thumbnailNavigation.width * 2); default: return config.thumbnailNavigation.width; } diff --git a/src/containers/ThumbnailNavigation.js b/src/containers/ThumbnailNavigation.js index caf749915c08ff23d9fa48cf251eca71e911b8e2..fdbea6d9f160ba4ac3c13ce23f27a477f5d5e0b2 100644 --- a/src/containers/ThumbnailNavigation.js +++ b/src/containers/ThumbnailNavigation.js @@ -36,14 +36,24 @@ const mapDispatchToProps = { /** * Styles for withStyles HOC */ -const styles = { +const styles = theme => ({ + currentCanvas: { + }, + canvas: { + border: '2px solid transparent', + color: theme.palette.common.white, + cursor: 'pointer', + '&$currentCanvas': { + border: `2px solid ${theme.palette.secondary.main}`, + }, + }, root: { background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 70%, rgba(0,0,0,0) 100%)', }, title: { color: '#ffffff', }, -}; +}); const enhance = compose( withStyles(styles), diff --git a/src/styles/index.scss b/src/styles/index.scss index c27b0e559b37eebdbf0f8d07a23ab736f9028075..0ac95a47fa4829bb97590e5bab97de8eeee6ce9c 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -183,17 +183,8 @@ } &-thumb-navigation { - - .mirador-thumbnail-nav-canvas { - border: 1px solid $black; - color: $white; - cursor: pointer; - height: 100%; - - &.mirador-current-canvas { - border: 3px solid $blue; - } - } + margin: 2px; + padding: 2px; } &-label-value-metadata {