1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-11-10 01:19:53 +01:00
unleash.unleash/frontend/src/component/common/PageHeader/PageHeader.tsx
Jaanus Sellin 3acb3ad2c2
feat: upgrade from react v17 to v18 (#7265)
**Upgrade to React v18 for Unleash v6. Here's why I think it's a good
time to do it:**
- Command Bar project: We've begun work on the command bar project, and
there's a fantastic library we want to use. However, it requires React
v18 support.
- Straightforward Upgrade: I took a look at the upgrade guide
https://react.dev/blog/2022/03/08/react-18-upgrade-guide and it seems
fairly straightforward. In fact, I was able to get React v18 running
with minimal changes in just 10 minutes!
- Dropping IE Support: React v18 no longer supports Internet Explorer
(IE), which is no longer supported by Microsoft as of June 15, 2022.
Upgrading to v18 in v6 would be a good way to align with this change.

TS updates:
* FC children has to be explicit:
https://stackoverflow.com/questions/71788254/react-18-typescript-children-fc
* forcing version 18 types in resolutions:
https://sentry.io/answers/type-is-not-assignable-to-type-reactnode/

Test updates:
* fixing SWR issue that we have always had but it manifests more in new
React (https://github.com/vercel/swr/issues/2373)

---------

Co-authored-by: kwasniew <kwasniewski.mateusz@gmail.com>
2024-06-11 13:59:52 +03:00

122 lines
3.2 KiB
TypeScript

import type React from 'react';
import type { ReactNode, FC, VFC } from 'react';
import classnames from 'classnames';
import {
Divider,
styled,
type SxProps,
type Theme,
Typography,
type TypographyProps,
} from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { usePageTitle } from 'hooks/usePageTitle';
const StyledDivider = styled(Divider)(({ theme }) => ({
height: '100%',
borderColor: theme.palette.divider,
width: '1px',
display: 'inline-block',
marginLeft: theme.spacing(2),
marginRight: theme.spacing(2),
padding: theme.spacing(0.5, 0),
verticalAlign: 'middle',
}));
const StyledHeaderContainer = styled('div')(() => ({
display: 'flex',
flexDirection: 'column',
}));
const StyledTopContainer = styled('div')(() => ({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
position: 'relative',
}));
const StyledHeader = styled('div')(({ theme }) => ({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
marginRight: theme.spacing(5),
}));
const StyledHeaderTitle = styled(Typography)(({ theme }) => ({
fontSize: theme.fontSizes.mainHeader,
fontWeight: 'normal',
lineHeight: theme.spacing(5),
}));
const StyledHeaderActions = styled('div')(({ theme }) => ({
display: 'flex',
flexGrow: 1,
justifyContent: 'flex-end',
alignItems: 'center',
gap: theme.spacing(1),
}));
interface IPageHeaderProps {
title?: string;
titleElement?: ReactNode;
subtitle?: string;
variant?: TypographyProps['variant'];
loading?: boolean;
actions?: ReactNode;
className?: string;
secondary?: boolean;
children?: React.ReactNode;
}
const PageHeaderComponent: FC<IPageHeaderProps> & {
Divider: typeof PageHeaderDivider;
} = ({
title,
titleElement,
actions,
subtitle,
variant,
loading,
className = '',
secondary,
children,
}) => {
const headerClasses = classnames({ skeleton: loading });
usePageTitle(secondary ? '' : title);
return (
<StyledHeaderContainer>
<StyledTopContainer>
<StyledHeader
className={classnames(headerClasses)}
data-loading
>
<StyledHeaderTitle
variant={variant || secondary ? 'h2' : 'h1'}
className={classnames(className)}
>
{titleElement || title}
</StyledHeaderTitle>
{subtitle && <small>{subtitle}</small>}
</StyledHeader>
<ConditionallyRender
condition={Boolean(actions)}
show={<StyledHeaderActions>{actions}</StyledHeaderActions>}
/>
</StyledTopContainer>
{children}
</StyledHeaderContainer>
);
};
const PageHeaderDivider: VFC<{ sx?: SxProps<Theme> }> = ({ sx }) => {
return <StyledDivider orientation='vertical' variant='middle' sx={sx} />;
};
PageHeaderComponent.Divider = PageHeaderDivider;
export const PageHeader = PageHeaderComponent;