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 53b9b16 commit 4726ec9
Show file tree
Hide file tree
Showing 20 changed files with 224 additions and 348 deletions.
36 changes: 26 additions & 10 deletions src/components/AttributionPanel.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 Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';
import Skeleton from '@mui/material/Skeleton';
Expand All @@ -9,6 +10,25 @@ import { LabelValueMetadata } from './LabelValueMetadata';
import ns from '../config/css-ns';
import { PluginHook } from './PluginHook';

/**
*
* @param theme
* @returns {label: {paddingLeft: number}}}
*/
const Logo = styled(Img)(() => ({
maxWidth: '100%',
}));
const Placeholder = styled(Skeleton)(({ theme }) => ({
backgroundColor: theme.palette.grey[300],
}));
const Section = styled('div')(({ theme }) => ({
borderBottom: `.5px solid ${theme.palette.section_divider}`,
paddingBottom: theme.spacing(1),
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(1),
paddingTop: theme.spacing(2),
}));

/**
* WindowSideBarInfoPanel
*/
Expand All @@ -24,7 +44,6 @@ export class AttributionPanel extends Component {
rights,
windowId,
id,
classes,
t,
} = this.props;

Expand All @@ -35,7 +54,7 @@ export class AttributionPanel extends Component {
windowId={windowId}
id={id}
>
<div className={classes.section}>
<Section>
{ requiredStatement && (
<LabelValueMetadata labelValuePairs={requiredStatement} defaultLabel={t('attribution')} />
)}
Expand All @@ -53,20 +72,19 @@ export class AttributionPanel extends Component {
</dl>
)
}
</div>
</Section>

{ manifestLogo && (
<div className={classes.section}>
<Img
<Section>
<Logo
src={[manifestLogo]}
alt=""
role="presentation"
className={classes.logo}
unloader={
<Skeleton className={classes.placeholder} variant="rectangular" height={60} width={60} />
<Placeholder variant="rectangular" height={60} width={60} />
}
/>
</div>
</Section>
)}

<PluginHook {...this.props} />
Expand All @@ -76,7 +94,6 @@ export class AttributionPanel extends Component {
}

AttributionPanel.propTypes = {
classes: PropTypes.objectOf(PropTypes.string),
id: PropTypes.string.isRequired,
manifestLogo: PropTypes.string,
requiredStatement: PropTypes.arrayOf(PropTypes.shape({
Expand All @@ -89,7 +106,6 @@ AttributionPanel.propTypes = {
};

AttributionPanel.defaultProps = {
classes: {},
manifestLogo: null,
requiredStatement: null,
rights: null,
Expand Down
95 changes: 49 additions & 46 deletions src/components/CanvasAnnotations.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ import Typography from '@mui/material/Typography';
import SanitizedHtml from '../containers/SanitizedHtml';
import { ScrollTo } from './ScrollTo';

const annotationListItem = {
'&$hovered': {
backgroundColor: (theme) => theme.palette.action.hover,
},
'&:hover,&:focus': {
backgroundColor: (theme) => theme.palette.action.hover,
},
borderBottom: (theme) => `0.5px solid ${theme.palette.divider}`,
cursor: 'pointer',
whiteSpace: 'normal',
};

/**
* CanvasAnnotations ~
*/
Expand Down Expand Up @@ -58,61 +70,54 @@ export class CanvasAnnotations extends Component {
*/
render() {
const {
annotations, classes, index, label, selectedAnnotationId, t, totalSize,
annotations, index, label, selectedAnnotationId, t, totalSize,
listContainerComponent, htmlSanitizationRuleSet, hoveredAnnotationIds,
containerRef,
} = this.props;
if (annotations.length === 0) return null;

return (
<>
<Typography className={classes.sectionHeading} variant="overline">
<Typography sx={{ paddingLeft: 2, paddingRight: 1, paddingTop: 2 }} variant="overline">
{t('annotationCanvasLabel', { context: `${index + 1}/${totalSize}`, label })}
</Typography>
<MenuList autoFocusItem variant="selectedMenu">
{
annotations.map(annotation => (
<MenuItem
button
component={listContainerComponent}
className={clsx(
classes.annotationListItem,
{
[classes.hovered]: hoveredAnnotationIds.includes(annotation.id),
},
)}
key={annotation.id}
annotationid={annotation.id}
selected={selectedAnnotationId === annotation.id}
onClick={e => this.handleClick(e, annotation)}
onFocus={() => this.handleAnnotationHover(annotation)}
onBlur={this.handleAnnotationBlur}
onMouseEnter={() => this.handleAnnotationHover(annotation)}
onMouseLeave={this.handleAnnotationBlur}
{annotations.map((annotation) => (
<MenuItem
button
component={listContainerComponent}
className={clsx(
{
[hoveredAnnotationIds.includes(annotation.id) ? 'hovered' : '']: true,
},
annotationListItem,
)}
key={annotation.id}
annotationid={annotation.id}
selected={selectedAnnotationId === annotation.id}
onClick={(e) => this.handleClick(e, annotation)}
onFocus={() => this.handleAnnotationHover(annotation)}
onBlur={this.handleAnnotationBlur}
onMouseEnter={() => this.handleAnnotationHover(annotation)}
onMouseLeave={this.handleAnnotationBlur}
>
<ScrollTo
containerRef={containerRef}
key={`${annotation.id}-scroll`}
offsetTop={96} // offset for the height of the form above
scrollTo={selectedAnnotationId === annotation.id}
>
<ScrollTo
containerRef={containerRef}
key={`${annotation.id}-scroll`}
offsetTop={96} // offset for the height of the form above
scrollTo={selectedAnnotationId === annotation.id}
>
<ListItemText primaryTypographyProps={{ variant: 'body2' }}>
<SanitizedHtml
ruleSet={htmlSanitizationRuleSet}
htmlString={annotation.content}
/>
<div>
{
annotation.tags.map(tag => (
<Chip size="small" variant="outlined" label={tag} id={tag} className={classes.chip} key={tag.toString()} />
))
}
</div>
</ListItemText>
</ScrollTo>
</MenuItem>
))
}
<ListItemText primaryTypographyProps={{ variant: 'body2' }}>
<SanitizedHtml ruleSet={htmlSanitizationRuleSet} htmlString={annotation.content} />
<div>
{annotation.tags.map((tag) => (
<Chip size="small" variant="outlined" label={tag} id={tag} key={tag.toString()} />
))}
</div>
</ListItemText>
</ScrollTo>
</MenuItem>
))}
</MenuList>
</>
);
Expand All @@ -126,7 +131,6 @@ CanvasAnnotations.propTypes = {
id: PropTypes.string.isRequired,
}),
),
classes: PropTypes.objectOf(PropTypes.string),
containerRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
Expand All @@ -146,7 +150,6 @@ CanvasAnnotations.propTypes = {
};
CanvasAnnotations.defaultProps = {
annotations: [],
classes: {},
containerRef: undefined,
hoveredAnnotationIds: [],
htmlSanitizationRuleSet: 'iiif',
Expand Down
105 changes: 67 additions & 38 deletions src/components/CompanionArea.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,44 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import Slide from '@mui/material/Slide';
import ArrowLeftIcon from '@mui/icons-material/ArrowLeftSharp';
import ArrowRightIcon from '@mui/icons-material/ArrowRightSharp';
import CompanionWindowFactory from '../containers/CompanionWindowFactory';
import MiradorMenuButton from '../containers/MiradorMenuButton';
import ns from '../config/css-ns';

/** */
export class CompanionArea extends Component {
/** */
areaLayoutClass() {
const {
classes, position,
} = this.props;
const StyledRoot = styled('div')(({ theme }) => ({
display: 'flex',
minHeight: 0,
position: 'relative',
zIndex: theme.zIndex.appBar - 2,
}));

return (position === 'bottom' || position === 'far-bottom') ? classes.horizontal : null;
}
const StyledWrapper = styled('div')(({ }) => ({
}));

const StyledToggle = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.paper,
border: `1px solid ${theme.palette.mode === 'dark' ? theme.palette.divider : theme.palette.shades?.dark}`,
borderRadius: 0,
height: '48px',
left: '100%',
marginTop: '1rem',
padding: 2,
position: 'absolute',
width: '23px',
zIndex: theme.zIndex.drawer,
}));

const StyledToggleButton = styled(MiradorMenuButton)({
marginBottom: 12,
marginTop: 12,
padding: 0,
});

/** */
export class CompanionArea extends Component {
/** */
collapseIcon() {
const { companionAreaOpen, direction } = this.props;
Expand Down Expand Up @@ -51,45 +72,54 @@ export class CompanionArea extends Component {
/** */
render() {
const {
classes, companionWindowIds, companionAreaOpen, setCompanionAreaOpen,
companionWindowIds, companionAreaOpen, setCompanionAreaOpen,
position, sideBarOpen, t, windowId,
} = this.props;

return (
<div className={[classes.root, this.areaLayoutClass(), ns(`companion-area-${position}`)].join(' ')}>
<StyledRoot
sx={{
...((position === 'bottom' || position === 'far-bottom') && {
flexDirection: 'column',
width: '100%',
}),
}}
className={`companion-area-${position}`}
>
<Slide in={companionAreaOpen} direction={this.slideDirection()}>
<div className={[ns('companion-windows'), companionWindowIds.length > 0 && classes[position], this.areaLayoutClass()].join(' ')} style={{ display: companionAreaOpen ? 'flex' : 'none' }}>
{
companionWindowIds.map(id => (
<CompanionWindowFactory id={id} key={id} windowId={windowId} />
))
}
</div>
<StyledWrapper
className={`${ns('companion-windows')} ${companionWindowIds.length > 0 && classes[position]}`}
style={{ display: companionAreaOpen ? 'flex' : 'none' }}
sx={{
...((position === 'bottom' || position === 'far-bottom') && {
flexDirection: 'column',
width: '100%',
}),
}}
>
{companionWindowIds.map((id) => (
<CompanionWindowFactory id={id} key={id} windowId={windowId} />
))}
</StyledWrapper>
</Slide>
{
setCompanionAreaOpen && position === 'left' && sideBarOpen && companionWindowIds.length > 0
&& (
<div className={classes.toggle}>
<MiradorMenuButton
aria-expanded={companionAreaOpen}
aria-label={companionAreaOpen ? t('collapseSidePanel') : t('expandSidePanel')}
className={classes.toggleButton}
key={companionAreaOpen ? 'collapse' : 'expand'}
onClick={() => { setCompanionAreaOpen(windowId, !companionAreaOpen); }}
TooltipProps={{ placement: 'right' }}
>
{this.collapseIcon()}
</MiradorMenuButton>
</div>
)
}
</div>
{setCompanionAreaOpen && position === 'left' && sideBarOpen && companionWindowIds.length > 0 && (
<StyledToggle>
<StyledToggleButton
aria-expanded={companionAreaOpen}
aria-label={companionAreaOpen ? t('collapseSidePanel') : t('expandSidePanel')}
onClick={() => { setCompanionAreaOpen(windowId, !companionAreaOpen); }}
TooltipProps={{ placement: 'right' }}
>
{this.collapseIcon()}
</StyledToggleButton>
</StyledToggle>
)}
</StyledRoot>
);
}
}

CompanionArea.propTypes = {
classes: PropTypes.objectOf(PropTypes.string),
companionAreaOpen: PropTypes.bool.isRequired,
companionWindowIds: PropTypes.arrayOf(PropTypes.string).isRequired,
direction: PropTypes.string.isRequired,
Expand All @@ -101,7 +131,6 @@ CompanionArea.propTypes = {
};

CompanionArea.defaultProps = {
classes: {},
setCompanionAreaOpen: () => {},
sideBarOpen: false,
};
Loading

0 comments on commit 4726ec9

Please sign in to comment.