feat: change component name 'Header' to 'header' & update icons version

This commit is contained in:
QiShaoXuan
2022-12-06 18:59:26 +08:00
parent d3d45a9dd7
commit f160b68a19
9 changed files with 11 additions and 11 deletions
@@ -0,0 +1,110 @@
import React, { PropsWithChildren, useState } from 'react';
import {
StyledHeader,
StyledHeaderRightSide,
StyledHeaderContainer,
StyledBrowserWarning,
StyledCloseButton,
} from './styles';
import {
MiddleExportIcon,
EdgelessIcon,
PaperIcon,
MiddleExportToHtmlIcon,
MiddleExportToMarkdownIcon,
MoreVertical_24pxIcon,
} from '@blocksuite/icons';
import { useEditor } from '@/providers/editor-provider';
import ThemeModeSwitch from '@/components/theme-mode-switch';
import { IconButton } from '@/ui/button';
import CloseIcon from '@mui/icons-material/Close';
import { getWarningMessage, shouldShowWarning } from './utils';
import { Menu, MenuItem } from '@/ui/menu';
const PopoverContent = () => {
const { editor, mode, setMode } = useEditor();
return (
<>
<MenuItem
icon={mode === 'page' ? <EdgelessIcon /> : <PaperIcon />}
onClick={() => {
setMode(mode === 'page' ? 'edgeless' : 'page');
}}
>
Convert to {mode === 'page' ? 'Edgeless' : 'Page'}
</MenuItem>
<Menu
placement="left-start"
content={
<>
<MenuItem
onClick={() => {
editor && editor.contentParser.onExportHtml();
}}
icon={<MiddleExportToHtmlIcon />}
>
Export to HTML
</MenuItem>
<MenuItem
onClick={() => {
editor && editor.contentParser.onExportMarkdown();
}}
icon={<MiddleExportToMarkdownIcon />}
>
Export to Markdown
</MenuItem>
</>
}
>
<MenuItem icon={<MiddleExportIcon />} isDir={true}>
Export
</MenuItem>
</Menu>
</>
);
};
const BrowserWarning = ({
show,
onClose,
}: {
show: boolean;
onClose: () => void;
}) => {
return (
<StyledBrowserWarning show={show}>
{getWarningMessage()}
<StyledCloseButton onClick={onClose}>
<CloseIcon />
</StyledCloseButton>
</StyledBrowserWarning>
);
};
export const Header = ({ children }: PropsWithChildren<{}>) => {
const [showWarning, setShowWarning] = useState(shouldShowWarning());
return (
<StyledHeaderContainer hasWarning={showWarning}>
<BrowserWarning
show={showWarning}
onClose={() => {
setShowWarning(false);
}}
/>
<StyledHeader hasWarning={showWarning}>
{children}
<StyledHeaderRightSide>
<ThemeModeSwitch />
<Menu content={<PopoverContent />} placement="bottom-end">
<IconButton>
<MoreVertical_24pxIcon />
</IconButton>
</Menu>
</StyledHeaderRightSide>
</StyledHeader>
</StyledHeaderContainer>
);
};
export default Header;
@@ -0,0 +1,2 @@
export * from './header';
export * from './page-header';
@@ -0,0 +1,47 @@
import React, { useEffect, useState } from 'react';
import { StyledTitle, StyledTitleWrapper } from './styles';
import { useEditor } from '@/providers/editor-provider';
import EditorModeSwitch from '@/components/editor-mode-switch';
import Header from './header';
export const PageHeader = () => {
const [title, setTitle] = useState('');
const [isHover, setIsHover] = useState(false);
const { editor } = useEditor();
useEffect(() => {
if (editor?.model) {
setTitle(editor.model.title ?? '');
editor.model.propsUpdated.on(() => {
setTitle(editor.model.title);
});
}
}, [editor]);
return (
<Header>
{title ? (
<StyledTitle
onMouseEnter={() => {
setIsHover(true);
}}
onMouseLeave={() => {
setIsHover(false);
}}
>
<EditorModeSwitch
isHover={isHover}
style={{
marginRight: '12px',
}}
/>
<StyledTitleWrapper>{title}</StyledTitleWrapper>
</StyledTitle>
) : null}
</Header>
);
};
export default PageHeader;
@@ -0,0 +1,91 @@
import { displayFlex, styled } from '@/styles';
export const StyledHeaderContainer = styled.div<{ hasWarning: boolean }>(
({ hasWarning }) => {
return {
position: 'relative',
height: hasWarning ? '96px' : '60px',
};
}
);
export const StyledHeader = styled.div<{ hasWarning: boolean }>(
({ hasWarning, theme }) => {
return {
height: '60px',
width: '100%',
...displayFlex('flex-end', 'center'),
background: 'var(--affine-page-background)',
transition: 'background-color 0.5s',
position: 'absolute',
left: '0',
top: hasWarning ? '36px' : '0',
padding: '0 22px',
zIndex: 99,
};
}
);
export const StyledTitle = styled('div')(({ theme }) => ({
width: '720px',
height: '100%',
position: 'absolute',
left: 0,
right: 0,
top: 0,
margin: 'auto',
...displayFlex('center', 'center'),
fontSize: theme.font.base,
}));
export const StyledTitleWrapper = styled('div')({
maxWidth: '720px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
position: 'relative',
});
export const StyledHeaderRightSide = styled('div')({
height: '100%',
display: 'flex',
alignItems: 'center',
});
export const StyledBrowserWarning = styled.div<{ show: boolean }>(
({ theme, show }) => {
return {
backgroundColor: theme.colors.warningBackground,
color: theme.colors.warningColor,
height: '36px',
width: '100vw',
fontSize: theme.font.sm,
position: 'fixed',
left: '0',
top: '0',
display: show ? 'flex' : 'none',
justifyContent: 'center',
alignItems: 'center',
};
}
);
export const StyledCloseButton = styled.div(({ theme }) => {
return {
width: '36px',
height: '36px',
color: theme.colors.iconColor,
cursor: 'pointer',
...displayFlex('center', 'center'),
position: 'absolute',
right: '15px',
top: '0',
svg: {
width: '15px',
height: '15px',
position: 'relative',
zIndex: 1,
},
};
});
@@ -0,0 +1,37 @@
import getIsMobile from '@/utils/get-is-mobile';
// Inspire by https://stackoverflow.com/a/4900484/8415727
const getChromeVersion = () => {
const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
return raw ? parseInt(raw[2], 10) : false;
};
const getIsChrome = () => {
return (
/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)
);
};
const minimumChromeVersion = 102;
export const shouldShowWarning = () => {
return (
!getIsMobile() &&
(!getIsChrome() || getChromeVersion() < minimumChromeVersion)
);
};
export const getWarningMessage = () => {
if (!getIsChrome()) {
return (
<span>
We recommend the <strong>Chrome</strong> browser for optimal experience.
</span>
);
}
if (getChromeVersion() < minimumChromeVersion) {
return (
<span>
Please upgrade to the latest version of Chrome for the best experience.
</span>
);
}
return '';
};