feishin/src/renderer/components/page-header/index.tsx

134 lines
3.2 KiB
TypeScript
Raw Normal View History

2023-03-30 06:44:33 -07:00
import { useRef } from 'react';
2022-12-31 17:50:05 -08:00
import { Flex, FlexProps } from '@mantine/core';
2023-01-02 17:03:33 -08:00
import { AnimatePresence, motion, Variants } from 'framer-motion';
2022-12-19 15:59:14 -08:00
import styled from 'styled-components';
2023-01-02 18:54:48 -08:00
import { useShouldPadTitlebar, useTheme } from '/@/renderer/hooks';
2023-03-30 06:44:33 -07:00
import { useWindowSettings } from '/@/renderer/store/settings.store';
import { Platform } from '/@/renderer/types';
2022-12-19 15:59:14 -08:00
2023-01-02 17:03:33 -08:00
const Container = styled(motion(Flex))<{
height?: string;
position?: string;
}>`
2022-12-31 17:50:05 -08:00
position: ${(props) => props.position || 'relative'};
z-index: 2000;
2022-12-19 15:59:14 -08:00
width: 100%;
height: ${(props) => props.height || '65px'};
background: var(--titlebar-bg);
2022-12-19 15:59:14 -08:00
`;
const Header = styled(motion.div)<{
$isDraggable?: boolean;
$isHidden?: boolean;
$padRight?: boolean;
}>`
2022-12-31 17:50:05 -08:00
position: relative;
2022-12-29 18:50:57 -08:00
z-index: 15;
2022-12-31 17:50:05 -08:00
width: 100%;
2022-12-19 15:59:14 -08:00
height: 100%;
margin-right: ${(props) => (props.$padRight ? '140px' : '1rem')};
2023-01-02 17:03:33 -08:00
user-select: ${(props) => (props.$isHidden ? 'none' : 'auto')};
pointer-events: ${(props) => (props.$isHidden ? 'none' : 'auto')};
-webkit-app-region: ${(props) => props.$isDraggable && 'drag'};
2022-12-19 15:59:14 -08:00
button {
-webkit-app-region: no-drag;
}
2022-12-21 01:27:29 -08:00
input {
-webkit-app-region: no-drag;
}
2022-12-19 15:59:14 -08:00
`;
2022-12-31 17:50:05 -08:00
const BackgroundImage = styled.div<{ background: string }>`
position: absolute;
top: 0;
z-index: 1;
width: 100%;
height: 100%;
background: ${(props) => props.background || 'var(--titlebar-bg)'};
`;
2022-12-29 18:50:57 -08:00
2023-01-02 18:54:48 -08:00
const BackgroundImageOverlay = styled.div<{ theme: 'light' | 'dark' }>`
2022-12-31 17:50:05 -08:00
position: absolute;
top: 0;
left: 0;
2023-01-02 17:03:33 -08:00
z-index: 10;
2022-12-31 17:50:05 -08:00
width: 100%;
height: 100%;
2023-01-02 18:54:48 -08:00
background: ${(props) =>
props.theme === 'light'
? 'linear-gradient(rgba(255, 255, 255, 25%), rgba(255, 255, 255, 25%))'
2023-01-02 18:54:48 -08:00
: 'linear-gradient(rgba(0, 0, 0, 50%), rgba(0, 0, 0, 50%))'};
2022-12-31 17:50:05 -08:00
`;
2022-12-29 18:50:57 -08:00
2023-01-02 17:03:33 -08:00
export interface PageHeaderProps
2022-12-31 17:50:05 -08:00
extends Omit<FlexProps, 'onAnimationStart' | 'onDragStart' | 'onDragEnd' | 'onDrag'> {
2022-12-19 15:59:14 -08:00
backgroundColor?: string;
children?: React.ReactNode;
height?: string;
2022-12-31 17:50:05 -08:00
isHidden?: boolean;
2022-12-29 18:50:57 -08:00
position?: string;
2022-12-19 15:59:14 -08:00
}
2023-01-02 17:03:33 -08:00
const TitleWrapper = styled(motion.div)`
2023-01-08 02:01:12 -08:00
position: absolute;
display: flex;
2023-01-02 17:03:33 -08:00
width: 100%;
height: 100%;
`;
const variants: Variants = {
animate: { opacity: 1 },
exit: { opacity: 0 },
initial: { opacity: 0 },
};
2022-12-29 18:50:57 -08:00
export const PageHeader = ({
position,
height,
backgroundColor,
2022-12-31 17:50:05 -08:00
isHidden,
2022-12-29 18:50:57 -08:00
children,
2022-12-31 17:50:05 -08:00
...props
2022-12-29 18:50:57 -08:00
}: PageHeaderProps) => {
2022-12-19 15:59:14 -08:00
const ref = useRef(null);
const padRight = useShouldPadTitlebar();
2023-03-30 06:44:33 -07:00
const { windowBarStyle } = useWindowSettings();
2023-01-02 18:54:48 -08:00
const theme = useTheme();
2022-12-19 15:59:14 -08:00
return (
<Container
ref={ref}
height={height}
2022-12-29 18:50:57 -08:00
position={position}
2022-12-31 17:50:05 -08:00
{...props}
2022-12-19 15:59:14 -08:00
>
2023-01-02 17:03:33 -08:00
<Header
$isDraggable={windowBarStyle === Platform.WEB}
2023-01-02 17:03:33 -08:00
$isHidden={isHidden}
$padRight={padRight}
>
<AnimatePresence initial={false}>
2023-01-02 17:03:33 -08:00
{!isHidden && (
<TitleWrapper
animate="animate"
exit="exit"
initial="initial"
variants={variants}
>
{children}
</TitleWrapper>
)}
</AnimatePresence>
</Header>
2022-12-31 17:50:05 -08:00
{backgroundColor && (
<>
2023-01-02 17:03:33 -08:00
<BackgroundImage background={backgroundColor || 'var(--titlebar-bg)'} />
2023-01-02 18:54:48 -08:00
<BackgroundImageOverlay theme={theme} />
2022-12-31 17:50:05 -08:00
</>
)}
2022-12-19 15:59:14 -08:00
</Container>
);
};