diff --git a/README.md b/README.md index 3be94d0c2bdcae0c22e37d1c06cfb97075c6bf3d..0799ad78e1d4014da493d0fda6599dc0c9ec2148 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,20 @@ -*NOTE: This README reflects the in development version of Mirador 3. For previous versions, please reference that release's README directly. Latest 2.x release: [v.2.7.0](https://github.com/ProjectMirador/mirador/tree/v2.7.0)* +*NOTE: This README reflects the latest version of Mirador, Mirador 3. For previous versions, please reference that release's README directly. Latest 2.x release: [v.2.7.0](https://github.com/ProjectMirador/mirador/tree/v2.7.0)* # Mirador -[](https://travis-ci.com/ProjectMirador/mirador) [](https://codecov.io/gh/ProjectMirador/mirador) + [](https://codecov.io/gh/ProjectMirador/mirador) ## For Mirador Users You can quickly use and configure Mirador by remixing the [mirador-start](https://mirador-start.glitch.me/) Glitch. +We recommend installing Mirador using a JavaScript package manager like [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/). + +```sh +$ npm install mirador + +# or + +$ yarn add mirador +``` + If you are interested in integrating Mirador with plugins into your project, we recommend using webpack or parcel to integrate the es version of the packages. Examples are here: [https://github.com/ProjectMirador/mirador-integration](https://github.com/ProjectMirador/mirador-integration) @@ -12,13 +22,13 @@ If you are interested in integrating Mirador with plugins into your project, we ## Adding translations to Mirador For help with adding a translation, see [src/locales/README.md](src/locales/README.md) -## Running Mirador locally +## Running Mirador locally for development Mirador local development requires [nodejs](https://nodejs.org/en/download/) to be installed. 1. Run `npm install` to install the dependencies. -## Starting the project +### Starting the project ```sh $ npm start diff --git a/src/components/CanvasLayers.js b/src/components/CanvasLayers.js index c58a0eab8f7dd214dd68379f46e37616deaa8f40..3058725144710ac1240ba79139e02abec5aadff9 100644 --- a/src/components/CanvasLayers.js +++ b/src/components/CanvasLayers.js @@ -48,6 +48,19 @@ export class CanvasLayers extends Component { this.moveToTop = this.moveToTop.bind(this); } + /** */ + handleOpacityChange(layerId, value) { + const { + canvasId, updateLayers, windowId, + } = this.props; + + const payload = { + [layerId]: { opacity: value / 100.0 }, + }; + + updateLayers(windowId, canvasId, payload); + } + /** */ onDragEnd(result) { const { @@ -100,19 +113,6 @@ export class CanvasLayers extends Component { updateLayers(windowId, canvasId, payload); } - /** */ - handleOpacityChange(layerId, value) { - const { - canvasId, updateLayers, windowId, - } = this.props; - - const payload = { - [layerId]: { opacity: value / 100.0 }, - }; - - updateLayers(windowId, canvasId, payload); - } - /** @private */ renderLayer(resource, index) { const { diff --git a/src/components/IIIFThumbnail.js b/src/components/IIIFThumbnail.js index a22c153a373529256747a16923356ba68943a06e..174e9af0bb922b4441b194df073241420c1f22db 100644 --- a/src/components/IIIFThumbnail.js +++ b/src/components/IIIFThumbnail.js @@ -44,6 +44,18 @@ export class IIIFThumbnail extends Component { } } + /** + * Handles the intersection (visibility) of a given thumbnail, by requesting + * the image and then updating the state. + */ + handleIntersection(event) { + const { loaded } = this.state; + + if (loaded || !event.isIntersecting) return; + + this.setState(state => ({ ...state, loaded: true })); + } + /** * */ @@ -94,18 +106,6 @@ export class IIIFThumbnail extends Component { }; } - /** - * Handles the intersection (visibility) of a given thumbnail, by requesting - * the image and then updating the state. - */ - handleIntersection(event) { - const { loaded } = this.state; - - if (loaded || !event.isIntersecting) return; - - this.setState(state => ({ ...state, loaded: true })); - } - /** */ image() { const { diff --git a/src/components/ManifestForm.js b/src/components/ManifestForm.js index 8c35fc20c431e8dd4aa2b9c34f19469bd3c7af0e..c4e03ec51ec756c26c5ada8b82489bdbdf63d626 100644 --- a/src/components/ManifestForm.js +++ b/src/components/ManifestForm.js @@ -36,20 +36,6 @@ export class ManifestForm extends Component { } } - /** - * formSubmit - triggers manifest update and sets lastRequested - * @param {Event} event - * @private - */ - formSubmit(event) { - const { addResource, onSubmit } = this.props; - const { formValue } = this.state; - event.preventDefault(); - onSubmit(); - addResource(formValue); - this.setState({ formValue: '' }); - } - /** * Reset the form state */ @@ -73,6 +59,20 @@ export class ManifestForm extends Component { }); } + /** + * formSubmit - triggers manifest update and sets lastRequested + * @param {Event} event + * @private + */ + formSubmit(event) { + const { addResource, onSubmit } = this.props; + const { formValue } = this.state; + event.preventDefault(); + onSubmit(); + addResource(formValue); + this.setState({ formValue: '' }); + } + /** * render * @return {String} - HTML markup for the component diff --git a/src/components/SearchHit.js b/src/components/SearchHit.js index f83fa2aa17fa7f706ff4f9842c8c01c7cb6787a8..f27228fe15fbc9fe02ad9cbaf0fcdb2ffab817f6 100644 --- a/src/components/SearchHit.js +++ b/src/components/SearchHit.js @@ -39,6 +39,15 @@ export class SearchHit extends Component { } } + /** */ + handleClick() { + const { + annotation, annotationId, selectAnnotation, + } = this.props; + + if (annotation && annotationId) selectAnnotation(annotationId); + } + /** * Pass content describing the hit to the announcer prop (intended for screen readers) */ @@ -59,15 +68,6 @@ export class SearchHit extends Component { ].join(' ')); } - /** */ - handleClick() { - const { - annotation, annotationId, selectAnnotation, - } = this.props; - - if (annotation && annotationId) selectAnnotation(annotationId); - } - /** */ render() { const { diff --git a/src/components/SearchPanelControls.js b/src/components/SearchPanelControls.js index 9a37eef51e310c506a6b050b01acda7fcba99e04..91d045ddedb98b7d208c802280ac7d4bbc9bc6e7 100644 --- a/src/components/SearchPanelControls.js +++ b/src/components/SearchPanelControls.js @@ -39,18 +39,6 @@ export class SearchPanelControls extends Component { } } - /** */ - getSuggestions(value, { showEmpty = false } = {}) { - const { suggestions } = this.state; - - const inputValue = deburr(value.trim()).toLowerCase(); - const inputLength = inputValue.length; - - return inputLength === 0 && !showEmpty - ? [] - : suggestions; - } - /** */ handleChange(event, value, reason) { if (value) { @@ -63,6 +51,18 @@ export class SearchPanelControls extends Component { } } + /** */ + getSuggestions(value, { showEmpty = false } = {}) { + const { suggestions } = this.state; + + const inputValue = deburr(value.trim()).toLowerCase(); + const inputLength = inputValue.length; + + return inputLength === 0 && !showEmpty + ? [] + : suggestions; + } + /** */ fetchAutocomplete(value) { const { autocompleteService } = this.props; diff --git a/src/components/SidebarIndexTableOfContents.js b/src/components/SidebarIndexTableOfContents.js index fd596f7bdf6db194db781b58d387a70565d6deed..bea3b9c9d7841984402499ace1c848e58ae0cdf0 100644 --- a/src/components/SidebarIndexTableOfContents.js +++ b/src/components/SidebarIndexTableOfContents.js @@ -26,6 +26,20 @@ function getStartCanvasId(node) { /** */ export class SidebarIndexTableOfContents extends Component { + /** */ + handleKeyPressed(event, node) { + const { expandedNodeIds, toggleNode } = this.props; + if (event.key === 'Enter' + || event.key === ' ' + || event.key === 'Spacebar') { + this.selectTreeItem(node); + } + if ((event.key === 'ArrowLeft' && expandedNodeIds.indexOf(node.id) !== -1) + || (event.key === 'ArrowRight' && expandedNodeIds.indexOf(node.id) === -1 && node.nodes.length > 0)) { + toggleNode(node.id); + } + } + /** */ selectTreeItem(node) { const { setCanvas, toggleNode, windowId } = this.props; @@ -44,20 +58,6 @@ export class SidebarIndexTableOfContents extends Component { setCanvas(windowId, canvasId); } - /** */ - handleKeyPressed(event, node) { - const { expandedNodeIds, toggleNode } = this.props; - if (event.key === 'Enter' - || event.key === ' ' - || event.key === 'Spacebar') { - this.selectTreeItem(node); - } - if ((event.key === 'ArrowLeft' && expandedNodeIds.indexOf(node.id) !== -1) - || (event.key === 'ArrowRight' && expandedNodeIds.indexOf(node.id) === -1 && node.nodes.length > 0)) { - toggleNode(node.id); - } - } - /** */ buildTreeItems(nodes, visibleNodeIds, containerRef, nodeIdToScrollTo) { const { classes } = this.props; diff --git a/src/components/ThumbnailNavigation.js b/src/components/ThumbnailNavigation.js index 252e458243868b6f5b6c6ece55639dd510548595..d887f8bf94143389fd6566b4ac6d7a5c7dd123b6 100644 --- a/src/components/ThumbnailNavigation.js +++ b/src/components/ThumbnailNavigation.js @@ -42,6 +42,27 @@ export class ThumbnailNavigation extends Component { } } + /** */ + handleKeyUp(e) { + const { position } = this.props; + let nextKey = 'ArrowRight'; + let previousKey = 'ArrowLeft'; + if (position === 'far-right') { + nextKey = 'ArrowDown'; + previousKey = 'ArrowUp'; + } + switch (e.key) { + case nextKey: + this.nextCanvas(); + break; + case previousKey: + this.previousCanvas(); + break; + default: + break; + } + } + /** * When on right, row height * When on bottom, column width @@ -128,27 +149,6 @@ export class ThumbnailNavigation extends Component { return canvasGroupings.length; } - /** */ - handleKeyUp(e) { - const { position } = this.props; - let nextKey = 'ArrowRight'; - let previousKey = 'ArrowLeft'; - if (position === 'far-right') { - nextKey = 'ArrowDown'; - previousKey = 'ArrowUp'; - } - switch (e.key) { - case nextKey: - this.nextCanvas(); - break; - case previousKey: - this.previousCanvas(); - break; - default: - break; - } - } - /** */ nextCanvas() { diff --git a/src/components/WorkspaceAdd.js b/src/components/WorkspaceAdd.js index c0b91f38f20447cb56704ce43cd9efdb721f2d8e..696038d3b07fec4144f26e03cce0f38bc8333cb3 100644 --- a/src/components/WorkspaceAdd.js +++ b/src/components/WorkspaceAdd.js @@ -36,19 +36,6 @@ export class WorkspaceAdd extends React.Component { this.handleDrop = this.handleDrop.bind(this); } - /** @private */ - onSubmit() { - this.setAddResourcesVisibility(false); - this.scrollToTop(); - } - - /** - * @private - */ - setAddResourcesVisibility(bool) { - this.setState({ addResourcesOpen: bool }); - } - /** */ handleDrop({ manifestId, manifestJson }, props, monitor) { const { addResource } = this.props; @@ -62,6 +49,19 @@ export class WorkspaceAdd extends React.Component { this.scrollToTop(); } + /** @private */ + onSubmit() { + this.setAddResourcesVisibility(false); + this.scrollToTop(); + } + + /** + * @private + */ + setAddResourcesVisibility(bool) { + this.setState({ addResourcesOpen: bool }); + } + /** Scroll the list back to the top */ scrollToTop() { if (this.ref.current) { diff --git a/src/components/WorkspaceExport.js b/src/components/WorkspaceExport.js index c752f393cbde46c1d88cfb9dab2c87a80ddcecf5..a9ce6ed290f8274d88a1912ad26e115a3b25d0bc 100644 --- a/src/components/WorkspaceExport.js +++ b/src/components/WorkspaceExport.js @@ -23,11 +23,6 @@ export class WorkspaceExport extends Component { this.handleClose = this.handleClose.bind(this); } - /** Show the snackbar */ - onCopy() { - this.setState({ copied: true }); - } - /** Handle closing after the content is copied and the snackbar is done */ handleClose() { const { handleClose } = this.props; @@ -35,6 +30,11 @@ export class WorkspaceExport extends Component { handleClose(); } + /** Show the snackbar */ + onCopy() { + this.setState({ copied: true }); + } + /** * @private */