Skip to content
Snippets Groups Projects
Unverified Commit c0806c2b authored by Jack Reed's avatar Jack Reed Committed by GitHub
Browse files

Merge pull request #2752 from ProjectMirador/2741-scrollto

Add ScrollTo for search hits
parents 5f64de8c 195a4676
No related branches found
No related tags found
No related merge requests found
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { SearchHit } from '../../../src/components/SearchHit'; import { SearchHit } from '../../../src/components/SearchHit';
import { ScrollTo } from '../../../src/components/ScrollTo';
/** /**
...@@ -42,6 +43,12 @@ describe('SearchHit', () => { ...@@ -42,6 +43,12 @@ describe('SearchHit', () => {
expect(wrapper.find('WithStyles(ForwardRef(ListItemText))').render().text()).toEqual('1xyz'); expect(wrapper.find('WithStyles(ForwardRef(ListItemText))').render().text()).toEqual('1xyz');
}); });
it('renders a ScrollTo', () => {
const wrapper = createWrapper({ containerRef: 'ref' });
expect(wrapper.find(ScrollTo).prop('containerRef')).toEqual('ref');
expect(wrapper.find(ScrollTo).prop('scrollTo')).toEqual(true);
});
describe('Annotation Labels', () => { describe('Annotation Labels', () => {
it('renders the annotationLabel if present', () => { it('renders the annotationLabel if present', () => {
const wrapper = createWrapper({ annotationLabel: 'The Anno Label' }); const wrapper = createWrapper({ annotationLabel: 'The Anno Label' });
......
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import CompanionWindow from '../../../src/containers/CompanionWindow'; import CompanionWindow from '../../../src/containers/CompanionWindow';
import SearchResults from '../../../src/containers/SearchResults';
import { SearchPanel } from '../../../src/components/SearchPanel'; import { SearchPanel } from '../../../src/components/SearchPanel';
...@@ -49,11 +50,11 @@ describe('SearchPanel', () => { ...@@ -49,11 +50,11 @@ describe('SearchPanel', () => {
}); });
it('has the SearchPanelControls component', () => { it('has the SearchPanelControls component', () => {
const titleControls = createWrapper().prop('titleControls'); const titleControls = createWrapper().find(CompanionWindow).prop('titleControls');
expect(titleControls.type.displayName).toEqual('Connect(WithStyles(WithPlugins(SearchPanelControls)))'); expect(titleControls.type.displayName).toEqual('Connect(WithStyles(WithPlugins(SearchPanelControls)))');
}); });
it('has the SearchResults', () => { it('has the SearchResults', () => {
const wrapper = createWrapper(); const wrapper = createWrapper();
expect(wrapper.find('Connect(WithStyles(WithPlugins(SearchResults)))').length).toEqual(1); expect(wrapper.find(SearchResults).length).toEqual(1);
}); });
}); });
...@@ -8,6 +8,7 @@ import Typography from '@material-ui/core/Typography'; ...@@ -8,6 +8,7 @@ import Typography from '@material-ui/core/Typography';
import Chip from '@material-ui/core/Chip'; import Chip from '@material-ui/core/Chip';
import SanitizedHtml from '../containers/SanitizedHtml'; import SanitizedHtml from '../containers/SanitizedHtml';
import TruncatedHit from '../lib/TruncatedHit'; import TruncatedHit from '../lib/TruncatedHit';
import { ScrollTo } from './ScrollTo';
/** */ /** */
export class SearchHit extends Component { export class SearchHit extends Component {
...@@ -35,6 +36,7 @@ export class SearchHit extends Component { ...@@ -35,6 +36,7 @@ export class SearchHit extends Component {
annotationLabel, annotationLabel,
canvasLabel, canvasLabel,
classes, classes,
containerRef,
hit, hit,
focused, focused,
index, index,
...@@ -49,6 +51,11 @@ export class SearchHit extends Component { ...@@ -49,6 +51,11 @@ export class SearchHit extends Component {
const truncated = hit && truncatedHit.before !== hit.before && truncatedHit.after !== hit.after; const truncated = hit && truncatedHit.before !== hit.before && truncatedHit.after !== hit.after;
return ( return (
<ScrollTo
containerRef={containerRef}
offsetTop={96} // offset for the height of the form above
scrollTo={selected}
>
<ListItem <ListItem
className={clsx( className={clsx(
classes.listItem, classes.listItem,
...@@ -91,6 +98,7 @@ export class SearchHit extends Component { ...@@ -91,6 +98,7 @@ export class SearchHit extends Component {
{!hit && annotation && <SanitizedHtml ruleSet="iiif" htmlString={annotation.chars} />} {!hit && annotation && <SanitizedHtml ruleSet="iiif" htmlString={annotation.chars} />}
</ListItemText> </ListItemText>
</ListItem> </ListItem>
</ScrollTo>
); );
} }
} }
...@@ -104,6 +112,10 @@ SearchHit.propTypes = { ...@@ -104,6 +112,10 @@ SearchHit.propTypes = {
annotationLabel: PropTypes.string, annotationLabel: PropTypes.string,
canvasLabel: PropTypes.string, canvasLabel: PropTypes.string,
classes: PropTypes.objectOf(PropTypes.string), classes: PropTypes.objectOf(PropTypes.string),
containerRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
]),
focused: PropTypes.bool, focused: PropTypes.bool,
hit: PropTypes.shape({ hit: PropTypes.shape({
after: PropTypes.string, after: PropTypes.string,
...@@ -125,6 +137,7 @@ SearchHit.defaultProps = { ...@@ -125,6 +137,7 @@ SearchHit.defaultProps = {
annotationLabel: undefined, annotationLabel: undefined,
canvasLabel: undefined, canvasLabel: undefined,
classes: {}, classes: {},
containerRef: undefined,
focused: false, focused: false,
hit: undefined, hit: undefined,
index: undefined, index: undefined,
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Chip from '@material-ui/core/Chip'; import Chip from '@material-ui/core/Chip';
import RootRef from '@material-ui/core/RootRef';
import CompanionWindow from '../containers/CompanionWindow'; import CompanionWindow from '../containers/CompanionWindow';
import SearchPanelControls from '../containers/SearchPanelControls'; import SearchPanelControls from '../containers/SearchPanelControls';
import SearchResults from '../containers/SearchResults'; import SearchResults from '../containers/SearchResults';
/** */ /** */
export class SearchPanel extends Component { export class SearchPanel extends Component {
/** */
constructor(props) {
super(props);
this.containerRef = React.createRef();
}
/** */ /** */
render() { render() {
const { const {
...@@ -19,6 +27,7 @@ export class SearchPanel extends Component { ...@@ -19,6 +27,7 @@ export class SearchPanel extends Component {
} = this.props; } = this.props;
return ( return (
<RootRef rootRef={this.containerRef}>
<CompanionWindow <CompanionWindow
title={( title={(
<> <>
...@@ -43,10 +52,12 @@ export class SearchPanel extends Component { ...@@ -43,10 +52,12 @@ export class SearchPanel extends Component {
titleControls={<SearchPanelControls companionWindowId={id} windowId={windowId} />} titleControls={<SearchPanelControls companionWindowId={id} windowId={windowId} />}
> >
<SearchResults <SearchResults
containerRef={this.containerRef}
companionWindowId={id} companionWindowId={id}
windowId={windowId} windowId={windowId}
/> />
</CompanionWindow> </CompanionWindow>
</RootRef>
); );
} }
} }
......
...@@ -31,6 +31,7 @@ export class SearchResults extends Component { ...@@ -31,6 +31,7 @@ export class SearchResults extends Component {
const { const {
classes, classes,
companionWindowId, companionWindowId,
containerRef,
isFetching, isFetching,
fetchSearch, fetchSearch,
nextSearch, nextSearch,
...@@ -66,6 +67,7 @@ export class SearchResults extends Component { ...@@ -66,6 +67,7 @@ export class SearchResults extends Component {
{ {
searchHits.map((hit, index) => ( searchHits.map((hit, index) => (
<SearchHit <SearchHit
containerRef={containerRef}
companionWindowId={companionWindowId} companionWindowId={companionWindowId}
key={hit.annotations[0]} key={hit.annotations[0]}
focused={focused} focused={focused}
...@@ -82,6 +84,7 @@ export class SearchResults extends Component { ...@@ -82,6 +84,7 @@ export class SearchResults extends Component {
<SearchHit <SearchHit
annotationId={anno.id} annotationId={anno.id}
companionWindowId={companionWindowId} companionWindowId={companionWindowId}
containerRef={containerRef}
key={anno.id} key={anno.id}
focused={focused} focused={focused}
index={index} index={index}
...@@ -103,6 +106,10 @@ export class SearchResults extends Component { ...@@ -103,6 +106,10 @@ export class SearchResults extends Component {
SearchResults.propTypes = { SearchResults.propTypes = {
classes: PropTypes.objectOf(PropTypes.string), classes: PropTypes.objectOf(PropTypes.string),
companionWindowId: PropTypes.string.isRequired, companionWindowId: PropTypes.string.isRequired,
containerRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
]),
fetchSearch: PropTypes.func.isRequired, fetchSearch: PropTypes.func.isRequired,
isFetching: PropTypes.bool, isFetching: PropTypes.bool,
nextSearch: PropTypes.string, nextSearch: PropTypes.string,
...@@ -115,6 +122,7 @@ SearchResults.propTypes = { ...@@ -115,6 +122,7 @@ SearchResults.propTypes = {
SearchResults.defaultProps = { SearchResults.defaultProps = {
classes: {}, classes: {},
containerRef: undefined,
isFetching: false, isFetching: false,
nextSearch: undefined, nextSearch: undefined,
query: undefined, query: undefined,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment