Skip to content

Commit

Permalink
Migrate components to MUI v5 with sx/styled API
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerd Müller committed Sep 14, 2023
1 parent 4726ec9 commit 261ebb4
Show file tree
Hide file tree
Showing 20 changed files with 135 additions and 248 deletions.
48 changes: 36 additions & 12 deletions src/components/MinimalWindow.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import MenuIcon from '@mui/icons-material/MenuSharp';
import cn from 'classnames';
import Paper from '@mui/material/Paper';
Expand All @@ -10,6 +11,9 @@ import CloseIcon from '@mui/icons-material/CloseSharp';
import MiradorMenuButton from '../containers/MiradorMenuButton';
import ns from '../config/css-ns';

const StyledMiradorMenuButton = styled(MiradorMenuButton)(({}) => ({
marginLeft: 'auto',
}));
/** */
export class MinimalWindow extends Component {
/** */
Expand All @@ -19,7 +23,6 @@ export class MinimalWindow extends Component {
allowWindowSideBar,
ariaLabel,
children,
classes,
label,
removeWindow,
t,
Expand All @@ -32,17 +35,31 @@ export class MinimalWindow extends Component {
elevation={1}
id={windowId}
className={
cn(classes.window, ns('placeholder-window'))
cn(ns('placeholder-window'))
}
sx={{
backgroundColor: 'shades?.dark',
borderRadius: 0,
display: 'flex',
flexDirection: 'column',
height: '100%',
minHeight: 0,
overflow: 'hidden',
width: '100%',
}}
aria-label={label && ariaLabel ? t('window', { label }) : null}
>
<AppBar position="relative" color="default">
<Toolbar
disableGutters
className={cn(
classes.windowTopBarStyle,
ns('window-top-bar'),
)}
className={cn(ns('window-top-bar'))}
sx={{
backgroundColor: 'shades?.main',
borderTop: '2px solid transparent',
minHeight: 32,
paddingLeft: 0.5,
paddingRight: 0.5,
}}
variant="dense"
>
{allowWindowSideBar && (
Expand All @@ -53,20 +70,29 @@ export class MinimalWindow extends Component {
<MenuIcon />
</MiradorMenuButton>
)}
<Typography variant="h2" noWrap color="inherit" className={classes.title}>
<Typography
variant="h2"
noWrap
color="inherit"
sx={{
flexGrow: 1,
paddingLeft: 0.5,
typography: 'h6',
}}
>
{label}
</Typography>
{allowClose && removeWindow && (
<MiradorMenuButton
<StyledMiradorMenuButton
aria-label={t('closeWindow')}
className={cn(classes.button, ns('window-close'))}
className={cn(ns('window-close'))}
onClick={removeWindow}
TooltipProps={{
tabIndex: ariaLabel ? 0 : -1,
}}
>
<CloseIcon />
</MiradorMenuButton>
</StyledMiradorMenuButton>
)}
</Toolbar>
</AppBar>
Expand All @@ -81,7 +107,6 @@ MinimalWindow.propTypes = {
allowWindowSideBar: PropTypes.bool,
ariaLabel: PropTypes.bool,
children: PropTypes.node,
classes: PropTypes.objectOf(PropTypes.string),
label: PropTypes.string,
removeWindow: PropTypes.func,
t: PropTypes.func,
Expand All @@ -93,7 +118,6 @@ MinimalWindow.defaultProps = {
allowWindowSideBar: true,
ariaLabel: true,
children: null,
classes: {},
label: '',
removeWindow: () => {},
t: key => key,
Expand Down
15 changes: 10 additions & 5 deletions src/components/OpenSeadragonViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
createRef, Children, cloneElement, Component,
} from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import debounce from 'lodash/debounce';
import isEqual from 'lodash/isEqual';
import OpenSeadragon from 'openseadragon';
Expand All @@ -12,6 +13,11 @@ import CanvasWorld from '../lib/CanvasWorld';
import { PluginHook } from './PluginHook';
import { OSDReferences } from '../plugins/OSDReferences';

const StyledSection = styled('section')(({ theme }) => ({
cursor: 'grab',
flex: 1,
position: 'relative',
}));
/**
* Represents a OpenSeadragonViewer in the mirador workspace. Responsible for mounting
* and rendering OSD.
Expand Down Expand Up @@ -340,7 +346,7 @@ export class OpenSeadragonViewer extends Component {
*/
render() {
const {
children, classes, label, t, windowId,
children, label, t, windowId,
drawAnnotations,
} = this.props;
const { viewer, grabbing } = this.state;
Expand All @@ -355,8 +361,8 @@ export class OpenSeadragonViewer extends Component {
));

return (
<section
className={classNames(ns('osd-container'), classes.osdContainer)}
<StyledSection
className={classNames(ns('osd-container'))}
style={{ cursor: grabbing ? 'grabbing' : undefined }}
id={`${windowId}-osd`}
ref={this.ref}
Expand All @@ -367,7 +373,7 @@ export class OpenSeadragonViewer extends Component {
&& <AnnotationsOverlay viewer={viewer} windowId={windowId} /> }
{ enhancedChildren }
<PluginHook viewer={viewer} {...{ ...this.props, children: null }} />
</section>
</StyledSection>
);
}
}
Expand All @@ -385,7 +391,6 @@ OpenSeadragonViewer.defaultProps = {
OpenSeadragonViewer.propTypes = {
canvasWorld: PropTypes.instanceOf(CanvasWorld).isRequired,
children: PropTypes.node,
classes: PropTypes.objectOf(PropTypes.string).isRequired,
drawAnnotations: PropTypes.bool,
infoResponses: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
label: PropTypes.string,
Expand Down
18 changes: 10 additions & 8 deletions src/components/SanitizedHtml.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import DOMPurify from 'dompurify';
import ns from '../config/css-ns';
import htmlRules from '../lib/htmlRules';

const StyledSpan = styled('span')(({ theme }) => ({
'& a': {
color: theme.palette.primary.main,
textDecoration: 'underline',
},
}));
/**
*/
export class SanitizedHtml extends Component {
/**
*/
render() {
const {
classes, htmlString, ruleSet, ...props
htmlString, ruleSet, ...props
} = this.props;

// Add a hook to make all links open a new window
Expand All @@ -25,8 +32,8 @@ export class SanitizedHtml extends Component {
});

return (
<span
className={[classes.root, ns('third-party-html')].join(' ')}
<StyledSpan
className={[ns('third-party-html')].join(' ')}
dangerouslySetInnerHTML={{ // eslint-disable-line react/no-danger
__html: DOMPurify.sanitize(htmlString, htmlRules[ruleSet]),
}}
Expand All @@ -37,11 +44,6 @@ export class SanitizedHtml extends Component {
}

SanitizedHtml.propTypes = {
classes: PropTypes.objectOf(PropTypes.string),
htmlString: PropTypes.string.isRequired,
ruleSet: PropTypes.string.isRequired,
};

SanitizedHtml.defaultProps = {
classes: {},
};
33 changes: 25 additions & 8 deletions src/components/ScrollIndicatedDialogContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,36 @@ import DialogContent from '@mui/material/DialogContent';
* to indicate there is scrollable content
*/
export function ScrollIndicatedDialogContent(props) {
const { classes, className, ...otherProps } = props;
const ourClassName = [className, classes.shadowScrollDialog].join(' ');

const { className, ...otherProps } = props;

return (
<DialogContent className={ourClassName} {...otherProps} />
<DialogContent
sx={{
/* Shadow covers */
background: `linear-gradient(${'background.paper'} 30%, rgba(255, 255, 255, 0)), `
+ `linear-gradient(rgba(255, 255, 255, 0), ${'background.paper'} 70%) 0 100%, `
// Shaddows
+ 'radial-gradient(50% 0, farthest-side, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), '
+ 'radial-gradient(50% 100%, farthest-side, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%,',
/* Shadow covers */
background: `linear-gradient(${'background.paper'} 30%, rgba(255, 255, 255, 0)), ` // eslint-disable-line no-dupe-keys
+ `linear-gradient(rgba(255, 255, 255, 0), ${'background.paper'} 70%) 0 100%, `
// Shaddows
+ 'radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), '
+ 'radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%;',

backgroundAttachment: 'local, local, scroll, scroll',
backgroundRepeat: 'no-repeat',
backgroundSize: '100% 40px, 100% 40px, 100% 14px, 100% 14px',
overflowY: 'auto',
}}
className={className}
{...otherProps}
/>
);
}

ScrollIndicatedDialogContent.propTypes = {
classes: PropTypes.shape({
shadowScrollDialog: PropTypes.string,
}).isRequired,

className: PropTypes.string,
};

Expand Down
22 changes: 14 additions & 8 deletions src/components/SearchPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export class SearchPanel extends Component {
/** */
render() {
const {
classes,
fetchSearch,
windowId,
id,
Expand All @@ -40,7 +39,7 @@ export class SearchPanel extends Component {
query && query !== '' && (
<Chip
role="button"
className={classes.clearChip}
sx={{ marginLeft: 1 }}
color="secondary"
label={t('clearSearch')}
onClick={removeSearch}
Expand All @@ -66,7 +65,19 @@ export class SearchPanel extends Component {
{
fetchSearch && suggestedSearches && query === '' && suggestedSearches.map(search => (
<Typography component="p" key={search} variant="body1">
<Button className={classes.inlineButton} color="secondary" onClick={() => fetchSearch(`${searchService.id}?q=${search}`, search)}>
<Button
sx={{
'& span': {
lineHeight: '1.5em',
},
margin: 2,
padding: 0,
textAlign: 'inherit',
textTransform: 'none',
}}
color="secondary"
onClick={() => fetchSearch(`${searchService.id}?q=${search}`, search)}
>
{t('suggestSearch', { query: search })}
</Button>
</Typography>
Expand All @@ -78,10 +89,6 @@ export class SearchPanel extends Component {
}

SearchPanel.propTypes = {
classes: PropTypes.shape({
clearChip: PropTypes.string,
inlineButton: PropTypes.string,
}),
fetchSearch: PropTypes.func,
id: PropTypes.string.isRequired,
query: PropTypes.string,
Expand All @@ -95,7 +102,6 @@ SearchPanel.propTypes = {
};

SearchPanel.defaultProps = {
classes: {},
fetchSearch: undefined,
query: '',
suggestedSearches: [],
Expand Down
Loading

0 comments on commit 261ebb4

Please sign in to comment.