Skip to content
Snippets Groups Projects
Unverified Commit afe3a3a6 authored by Justin Coyne's avatar Justin Coyne Committed by GitHub
Browse files

Merge pull request #3868 from ProjectMirador/mui5-clean-up-wrappers

Clean up some unnecessary wrappers and clean up workspace styles
parents ec6b7641 bc0cc020
Branches
No related tags found
1 merge request!19Draft: Merge video support into mui5
......@@ -83,22 +83,6 @@ describe('Workspace', () => {
});
});
describe('when the workspace control panel is displayed', () => {
it('has the *-with-control-panel class applied', () => {
const { container } = createWrapper();
expect(container.querySelector('.mirador-workspace-with-control-panel')).toBeInTheDocument();
});
});
describe('when the workspace control panel is not displayed', () => {
it('does not have the *-with-control-panel class applied', () => {
const { container } = createWrapper({ isWorkspaceControlPanelVisible: false });
expect(container.querySelector('.mirador-workspace-with-control-panel')).not.toBeInTheDocument();
});
});
describe('drag and drop', () => {
it('adds a new catalog entry from a manifest', async () => {
const manifestJson = '{ "data": "123" }';
......@@ -106,7 +90,7 @@ describe('Workspace', () => {
const addWindow = jest.fn();
const { container } = createWrapper({ addWindow });
const dropTarget = container.querySelector('.mirador-workspace-with-control-panel');
const dropTarget = container.querySelector('.mirador-workspace-viewport');
const file = new File([manifestJson], 'manifest.json', { type: 'application/json' });
const dataTransfer = {
......@@ -129,7 +113,7 @@ describe('Workspace', () => {
const { container } = createWrapper({ addWindow, allowNewWindows: false });
const dropTarget = container.querySelector('.mirador-workspace-with-control-panel');
const dropTarget = container.querySelector('.mirador-workspace-viewport');
const file = new File([manifestJson], 'manifest.json', { type: 'application/json' });
const dataTransfer = {
......
......@@ -4,16 +4,17 @@ 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 classNames from 'classnames';
import CompanionWindowFactory from '../containers/CompanionWindowFactory';
import MiradorMenuButton from '../containers/MiradorMenuButton';
import ns from '../config/css-ns';
const Root = styled('div', { name: 'CompanionArea', slot: 'root' })(({ position, theme }) => ({
const Root = styled('div', { name: 'CompanionArea', slot: 'root' })(({ ownerState, theme }) => ({
display: 'flex',
minHeight: 0,
position: 'relative',
zIndex: theme.zIndex.appBar - 2,
...((position === 'bottom' || position === 'far-bottom') && {
...((ownerState.position === 'bottom' || ownerState.position === 'far-bottom') && {
flexDirection: 'column',
width: '100%',
}),
......@@ -89,12 +90,13 @@ export class CompanionArea extends Component {
/** */
render() {
const {
className,
companionWindowIds, companionAreaOpen, setCompanionAreaOpen,
position, sideBarOpen, t, windowId,
} = this.props;
const className = [this.areaLayoutClass(), ns(`companion-area-${position}`)].join(' ');
const classes = classNames(this.areaLayoutClass(), ns(`companion-area-${position}`), className);
return (
<Root className={className}>
<Root ownerState={this.props} className={classes}>
<Slide in={companionAreaOpen} direction={this.slideDirection()}>
<Container
ownerState={this.props}
......@@ -125,6 +127,7 @@ export class CompanionArea extends Component {
CompanionArea.propTypes = {
classes: PropTypes.objectOf(PropTypes.string),
className: PropTypes.string,
companionAreaOpen: PropTypes.bool.isRequired,
companionWindowIds: PropTypes.arrayOf(PropTypes.string).isRequired,
direction: PropTypes.string.isRequired,
......@@ -137,6 +140,7 @@ CompanionArea.propTypes = {
CompanionArea.defaultProps = {
classes: {},
className: undefined,
setCompanionAreaOpen: () => {},
sideBarOpen: false,
};
import { Component, lazy, Suspense } from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import classNames from 'classnames';
import WindowSideBar from '../containers/WindowSideBar';
import CompanionArea from '../containers/CompanionArea';
import CollectionDialog from '../containers/CollectionDialog';
......@@ -16,7 +17,7 @@ GalleryView.displayName = 'GalleryView';
SelectCollection.displayName = 'SelectCollection';
WindowViewer.displayName = 'WindowViewer';
const StyledPrimaryWindowContainer = styled('div')(() => ({
const Root = styled('div', { name: 'PrimaryWindow', slot: 'root' })(() => ({
display: 'flex',
flex: 1,
position: 'relative',
......@@ -80,17 +81,18 @@ export class PrimaryWindow extends Component {
*/
render() {
const {
isCollectionDialogVisible, windowId, children,
isCollectionDialogVisible, windowId, children, className,
} = this.props;
return (
<StyledPrimaryWindowContainer data-testid="test-window" className={ns('primary-window')}>
<Root data-testid="test-window" className={classNames(ns('primary-window'), className)}>
<WindowSideBar windowId={windowId} />
<CompanionArea windowId={windowId} position="left" />
{ isCollectionDialogVisible && <CollectionDialog windowId={windowId} /> }
<Suspense fallback={<div />}>
{children || this.renderViewer()}
</Suspense>
</StyledPrimaryWindowContainer>
</Root>
);
}
}
......@@ -98,6 +100,7 @@ export class PrimaryWindow extends Component {
PrimaryWindow.propTypes = {
audioResources: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
children: PropTypes.node,
className: PropTypes.string,
isCollection: PropTypes.bool,
isCollectionDialogVisible: PropTypes.bool,
isFetching: PropTypes.bool,
......@@ -109,6 +112,7 @@ PrimaryWindow.propTypes = {
PrimaryWindow.defaultProps = {
audioResources: [],
children: undefined,
className: undefined,
isCollection: false,
isCollectionDialogVisible: false,
isFetching: false,
......
import { Component } from 'react';
import { Component, useContext } from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import Paper from '@mui/material/Paper';
......@@ -12,13 +12,25 @@ import ErrorContent from '../containers/ErrorContent';
import IIIFAuthentication from '../containers/IIIFAuthentication';
import { PluginHook } from './PluginHook';
const Root = styled(Paper)(({ ownerState, theme }) => ({
backgroundColor: theme.palette.shades?.dark,
borderRadius: 0,
const rowMixin = {
display: 'flex',
flex: '1',
flexDirection: 'row',
minHeight: 0,
};
const columnMixin = {
display: 'flex',
flex: '1',
flexDirection: 'column',
height: '100%',
minHeight: 0,
};
const Root = styled(Paper, { name: 'Window', slot: 'root' })(({ ownerState, theme }) => ({
...columnMixin,
backgroundColor: theme.palette.shades?.dark,
borderRadius: 0,
height: '100%',
overflow: 'hidden',
width: '100%',
...(ownerState?.maximized && {
......@@ -29,41 +41,39 @@ const Root = styled(Paper)(({ ownerState, theme }) => ({
}),
}));
const StyledMiddle = styled('div')(() => ({
display: 'flex',
flex: '1',
flexDirection: 'row',
minHeight: 0,
const ContentRow = styled('div', { name: 'Window', slot: 'row' })(() => ({
...rowMixin,
}));
const StyledMiddleLeft = styled('div')(() => ({
display: 'flex',
flex: '1',
flexDirection: 'column',
minHeight: 0,
const ContentColumn = styled('div', { name: 'Window', slot: 'column' })(() => ({
...columnMixin,
}));
const StyledPrimaryWindow = styled('div')(() => ({
display: 'flex',
flex: '1',
const StyledPrimaryWindow = styled(PrimaryWindow, { name: 'Window', slot: 'primary' })(() => ({
...rowMixin,
height: '300px',
minHeight: 0,
position: 'relative',
}));
const StyledCompanionAreaBottom = styled('div')(() => ({
display: 'flex',
const StyledCompanionAreaBottom = styled(CompanionArea, { name: 'Window', slot: 'bottom' })(() => ({
...rowMixin,
flex: '0',
flexBasis: 'auto',
minHeight: 0,
}));
const StyledCompanionAreaRight = styled('div')(() => ({
display: 'flex',
const StyledCompanionAreaRight = styled('div', { name: 'Window', slot: 'right' })(() => ({
...rowMixin,
flex: '0 1 auto',
minHeight: 0,
}));
/** Window title bar wrapper for drag controls in the mosaic view */
const DraggableNavBar = ({ children, ...props }) => {
const { mosaicWindowActions } = useContext(MosaicWindowContext);
return mosaicWindowActions.connectDragSource(
<nav {...props}>{children}</nav>,
);
};
/**
* Represents a Window in the mirador workspace
* @param {object} window
......@@ -81,40 +91,13 @@ export class Window extends Component {
return { error, hasError: true };
}
/**
* wrappedTopBar - will conditionally wrap a WindowTopBar for needed
* additional functionality based on workspace type
*/
wrappedTopBar() {
const {
windowId, workspaceType, windowDraggable,
} = this.props;
const topBar = (
<div>
<WindowTopBar
windowId={windowId}
windowDraggable={windowDraggable}
/>
<IIIFAuthentication windowId={windowId} />
</div>
);
if (workspaceType === 'mosaic' && windowDraggable) {
const { mosaicWindowActions } = this.context;
return mosaicWindowActions.connectDragSource(
topBar,
);
}
return topBar;
}
/**
* Renders things
*/
render() {
const {
focusWindow, label, isFetching, sideBarOpen,
view, windowId, t,
view, windowDraggable, windowId, workspaceType, t,
manifestError,
} = this.props;
......@@ -138,27 +121,28 @@ export class Window extends Component {
className={ns('window')}
aria-label={t('window', { label })}
>
{this.wrappedTopBar()}
<WindowTopBar
component={workspaceType === 'mosaic' && windowDraggable ? DraggableNavBar : undefined}
windowId={windowId}
windowDraggable={windowDraggable}
/>
<IIIFAuthentication windowId={windowId} />
{ manifestError && <ErrorContent error={{ stack: manifestError }} windowId={windowId} /> }
<StyledMiddle>
<StyledMiddleLeft>
<StyledPrimaryWindow>
<PrimaryWindow
<ContentRow>
<ContentColumn>
<StyledPrimaryWindow
view={view}
windowId={windowId}
isFetching={isFetching}
sideBarOpen={sideBarOpen}
/>
</StyledPrimaryWindow>
<StyledCompanionAreaBottom>
<CompanionArea windowId={windowId} position="bottom" />
</StyledCompanionAreaBottom>
</StyledMiddleLeft>
<StyledCompanionAreaBottom windowId={windowId} position="bottom" />
</ContentColumn>
<StyledCompanionAreaRight>
<CompanionArea windowId={windowId} position="right" />
<CompanionArea windowId={windowId} position="far-right" />
</StyledCompanionAreaRight>
</StyledMiddle>
</ContentRow>
<CompanionArea windowId={windowId} position="far-bottom" />
<PluginHook {...this.props} />
</Root>
......
......@@ -6,11 +6,15 @@ import WindowSideBarButtons from '../containers/WindowSideBarButtons';
const Root = styled(Drawer, { name: 'WindowSideBar', slot: 'root' })(({ theme }) => ({
flexShrink: 0,
height: '100%',
order: -1000,
zIndex: theme.zIndex.appBar - 1,
}));
const Nav = styled('nav', { name: 'WindowSideBar', slot: 'nav' })({
position: 'relative !important',
width: 48,
});
/**
* WindowSideBar
*/
......@@ -31,15 +35,7 @@ export class WindowSideBar extends Component {
anchor={direction === 'rtl' ? 'right' : 'left'}
PaperProps={{
'aria-label': t('sidebarPanelsNavigation'),
component: 'nav',
sx: {
borderBlock: 0,
borderInlineStart: 0,
height: '100%',
overflowX: 'hidden',
position: 'relative',
width: 48,
},
component: Nav,
variant: 'outlined',
}}
SlideProps={{ direction: direction === 'rtl' ? 'left' : 'right', mountOnEnter: true, unmountOnExit: true }}
......
......@@ -45,10 +45,11 @@ export class WindowTopBar extends Component {
removeWindow, windowId, toggleWindowSideBar, t,
maximizeWindow, maximized, minimizeWindow, allowClose, allowMaximize,
focusWindow, allowFullscreen, allowTopMenuButton, allowWindowSideBar,
component,
} = this.props;
return (
<Root component="nav" aria-label={t('windowNavigation')} position="relative" color="default" enableColorOnDark>
<Root component={component} aria-label={t('windowNavigation')} position="relative" color="default" enableColorOnDark>
<StyledToolbar
disableGutters
onMouseDown={focusWindow}
......@@ -106,6 +107,7 @@ WindowTopBar.propTypes = {
allowMaximize: PropTypes.bool,
allowTopMenuButton: PropTypes.bool,
allowWindowSideBar: PropTypes.bool,
component: PropTypes.elementType,
focused: PropTypes.bool, // eslint-disable-line react/no-unused-prop-types
focusWindow: PropTypes.func,
maximized: PropTypes.bool,
......@@ -124,6 +126,7 @@ WindowTopBar.defaultProps = {
allowMaximize: true,
allowTopMenuButton: true,
allowWindowSideBar: true,
component: 'nav',
focused: false,
focusWindow: () => {},
maximized: false,
......
......@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import classNames from 'classnames';
import Grid from '@mui/material/Grid';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import { visuallyHidden } from '@mui/utils';
import Window from '../containers/Window';
......@@ -12,23 +11,10 @@ import WorkspaceElastic from '../containers/WorkspaceElastic';
import ns from '../config/css-ns';
import { IIIFDropTarget } from './IIIFDropTarget';
const Root = styled('div', { name: 'Workspace', slot: 'root' })(({ ownerState, theme }) => ({
'@media (min-width: 600px)': {
...(ownerState.isWorkspaceControlPanelVisible && {
paddingLeft: theme.spacing(8.5),
paddingTop: 0,
}),
},
...(ownerState.isWorkspaceControlPanelVisible && {
paddingTop: theme.spacing(9.25),
}),
bottom: 0,
left: 0,
margin: 0,
overflow: 'hidden',
position: 'absolute',
right: 0,
top: 0,
const Root = styled('div', { name: 'Workspace', slot: 'root' })(() => ({
height: '100%',
position: 'relative',
width: '100%',
}));
/**
......@@ -84,11 +70,7 @@ export class Workspace extends Component {
const { t } = this.props;
return (
<Paper
style={{
height: '100%',
}}
>
<Root>
<Grid
alignItems="center"
container
......@@ -109,7 +91,7 @@ export class Workspace extends Component {
</Typography>
</Grid>
</Grid>
</Paper>
</Root>
);
}
......@@ -135,7 +117,7 @@ export class Workspace extends Component {
* render
*/
render() {
const { isWorkspaceControlPanelVisible, t } = this.props;
const { t } = this.props;
return (
<IIIFDropTarget onDrop={this.handleDrop}>
......@@ -144,7 +126,6 @@ export class Workspace extends Component {
className={
classNames(
ns('workspace-viewport'),
(isWorkspaceControlPanelVisible && ns('workspace-with-control-panel')),
)
}
>
......@@ -159,7 +140,6 @@ export class Workspace extends Component {
Workspace.propTypes = {
addWindow: PropTypes.func,
allowNewWindows: PropTypes.bool,
isWorkspaceControlPanelVisible: PropTypes.bool.isRequired,
maximizedWindowIds: PropTypes.arrayOf(PropTypes.string),
t: PropTypes.func.isRequired,
windowIds: PropTypes.arrayOf(PropTypes.string),
......
......@@ -25,13 +25,6 @@ const StyledWorkspaceAdd = styled('div')(() => ({
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
paddingTop: 68,
// injection order matters
// eslint-disable-next-line sort-keys
'@media (min-width: 600px)': {
paddingLeft: 68,
paddingTop: 0,
},
}));
const StyledMiradorMenuButton = styled(MiradorMenuButton)(() => ({
......
......@@ -8,20 +8,29 @@ import WorkspaceAdd from '../containers/WorkspaceAdd';
import BackgroundPluginArea from '../containers/BackgroundPluginArea';
import ns from '../config/css-ns';
const StyledMain = styled('main')(({ theme }) => {
const Root = styled('div', { name: 'WorkspaceArea', slot: 'root' })(({ theme }) => {
const getBackgroundColor = theme.palette.mode === 'light' ? darken : lighten;
return {
background: getBackgroundColor(theme.palette.grey.A200, 0.1),
background: getBackgroundColor(theme.palette.shades.light, 0.1),
bottom: 0,
display: 'flex',
flexDirection: 'column',
left: 0,
overflow: 'hidden',
position: 'absolute',
right: 0,
top: 0,
[theme.breakpoints.up('sm')]: {
flexDirection: 'row',
},
};
});
const ViewerArea = styled('main', { name: 'WorkspaceArea', slot: 'viewer' })(() => ({
flexGrow: 1,
position: 'relative',
}));
/**
* This is the top level Mirador component.
* @prop {Object} manifests
......@@ -42,12 +51,12 @@ export class WorkspaceArea extends Component {
} = this.props;
return (
<>
<Root ownerState={this.props}>
{
isWorkspaceControlPanelVisible
&& <WorkspaceControlPanel variant={controlPanelVariant} />
}
<StyledMain
<ViewerArea
className={ns('viewer')}
lang={lang}
aria-label={t('workspace')}
......@@ -60,8 +69,8 @@ export class WorkspaceArea extends Component {
}
<ErrorDialog />
<BackgroundPluginArea />
</StyledMain>
</>
</ViewerArea>
</Root>
);
}
}
......
......@@ -14,10 +14,9 @@ const Root = styled(AppBar, { name: 'WorkspaceControlPanel', slot: 'root' })(({
height: 64,
padding: theme.spacing(1),
paddingBottom: 0,
position: 'relative',
[theme.breakpoints.up('sm')]: {
height: '100%',
left: 0,
right: 'auto',
height: 'auto',
width: ownerState.variant === 'wide' ? 'auto' : 64,
},
...(ownerState.variant === 'wide' && {
......
......@@ -6,6 +6,12 @@ import ResizeObserver from 'react-resize-observer';
import WorkspaceElasticWindow from '../containers/WorkspaceElasticWindow';
import ns from '../config/css-ns';
const Root = styled('div', { name: 'WorkspaceElastic', slot: 'root' })({
height: '100%',
position: 'relative',
width: '100%',
});
const StyledRnd = styled(Rnd)({
boxSizing: 'border-box',
margin: 0,
......@@ -39,7 +45,7 @@ class WorkspaceElastic extends Component {
const offsetY = workspace.height / 2;
return (
<div style={{ height: '100%', position: 'relative', width: '100%' }}>
<Root>
<ResizeObserver
onReflow={() => {}}
onResize={(rect) => { setWorkspaceViewportDimensions(rect); }}
......@@ -79,7 +85,7 @@ class WorkspaceElastic extends Component {
))
}
</StyledRnd>
</div>
</Root>
);
}
}
......
......@@ -17,7 +17,6 @@ import * as actions from '../state/actions';
const mapStateToProps = state => (
{
allowNewWindows: getConfig(state).workspace.allowNewWindows,
isWorkspaceControlPanelVisible: getConfig(state).workspaceControlPanel.enabled,
maximizedWindowIds: getMaximizedWindowsIds(state),
windowIds: getWindowIds(state),
workspaceId: getWorkspace(state).id,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment