Skip to content

Commit

Permalink
fix(layout): use useBreakpoint utils
Browse files Browse the repository at this point in the history
close #7564
  • Loading branch information
chenshuai2144 committed Aug 23, 2023
1 parent 8091a13 commit 3a174d1
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 18 deletions.
24 changes: 6 additions & 18 deletions packages/layout/src/ProLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import {
import {
coverToNewToken,
isBrowser,
useBreakpoint,
useDocumentTitle,
useMountMergeState,
} from '@ant-design/pro-utils';
import { getMatchMenu } from '@umijs/route-utils';
import type { BreadcrumbProps } from 'antd';
import { ConfigProvider, Grid, Layout } from 'antd';
import { ConfigProvider, Layout } from 'antd';
import classNames from 'classnames';
import Omit from 'omit.js';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
Expand Down Expand Up @@ -558,24 +559,11 @@ const BaseProLayout: React.FC<ProLayoutProps> = (props) => {
...currentMenuLayoutProps,
};

const defaultCol = useMemo(
() => ({
lg: true,
md: true,
sm: true,
xl: false,
xs: true,
xxl: false,
}),
[],
);
const col = Grid.useBreakpoint() || defaultCol;

const isMobile = (col.sm || col.xs) && !col.md && !props.disableMobile;
const colSize = useBreakpoint();

const colSize = useMemo(() => {
return Object.keys(col).filter((key) => col[key] === true)[0] || 'md';
}, [col]);
const isMobile = useMemo(() => {
return (colSize === 'sm' || colSize === 'xs') && !props.disableMobile;
}, [colSize, props.disableMobile]);

// If it is a fix menu, calculate padding
// don't need padding in phone mode
Expand Down
2 changes: 2 additions & 0 deletions packages/utils/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import type {
UseEditableMapUtilType,
} from './useEditableMap';
import { useEditableMap } from './useEditableMap';
import { useBreakpoint } from './useMediaQuery';
import { useMountMergeState } from './useMountMergeState';

export * from './typing';
Expand Down Expand Up @@ -143,4 +144,5 @@ export {
lighten,
useReactiveRef,
useRefCallback,
useBreakpoint,
};
108 changes: 108 additions & 0 deletions packages/utils/src/useMediaQuery/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { useEffect, useState } from 'react';
import useMediaQuery from './query';

export const MediaQueryEnum = {
xs: {
maxWidth: 575,
matchMedia: '(max-width: 575px)',
},
sm: {
minWidth: 576,
maxWidth: 767,
matchMedia: '(min-width: 576px) and (max-width: 767px)',
},
md: {
minWidth: 768,
maxWidth: 991,
matchMedia: '(min-width: 768px) and (max-width: 991px)',
},
lg: {
minWidth: 992,
maxWidth: 1199,
matchMedia: '(min-width: 992px) and (max-width: 1199px)',
},
xl: {
minWidth: 1200,
maxWidth: 1599,
matchMedia: '(min-width: 1200px) and (max-width: 1599px)',
},
xxl: {
minWidth: 1600,
matchMedia: '(min-width: 1600px)',
},
};

export type MediaQueryKey = keyof typeof MediaQueryEnum;

/**
* loop query screen className
* Array.find will throw a error
* `Rendered more hooks than during the previous render.`
* So should use Array.forEach
*/
export const getScreenClassName = () => {
let className: MediaQueryKey = 'md';
// support ssr
if (typeof window === 'undefined') {
return className;
}
const mediaQueryKey = (Object.keys(MediaQueryEnum) as MediaQueryKey[]).find(
(key) => {
const { matchMedia } = MediaQueryEnum[key];
if (window.matchMedia(matchMedia).matches) {
return true;
}
return false;
},
);
className = mediaQueryKey as unknown as MediaQueryKey;
return className;
};

const useBreakpoint = () => {
const isMd = useMediaQuery(MediaQueryEnum.md.matchMedia);
const isLg = useMediaQuery(MediaQueryEnum.lg.matchMedia);
const isXxl = useMediaQuery(MediaQueryEnum.xxl.matchMedia);
const isXl = useMediaQuery(MediaQueryEnum.xl.matchMedia);
const isSm = useMediaQuery(MediaQueryEnum.sm.matchMedia);
const isXs = useMediaQuery(MediaQueryEnum.xs.matchMedia);
const [colSpan, setColSpan] = useState<keyof typeof MediaQueryEnum>(
getScreenClassName(),
);

useEffect(() => {
if (process.env.NODE_ENV === 'TEST') {
setColSpan((process.env.USE_MEDIA as 'xs') || 'xs');
return;
}
if (isXxl) {
setColSpan('xxl');
return;
}
if (isXl) {
setColSpan('xl');
return;
}
if (isLg) {
setColSpan('lg');
return;
}
if (isMd) {
setColSpan('md');
return;
}
if (isSm) {
setColSpan('sm');
return;
}
if (isXs) {
setColSpan('xs');
return;
}
setColSpan('md');
}, [isMd, isLg, isXxl, isXl, isSm, isXs]);

return colSpan;
};

export { useBreakpoint };
19 changes: 19 additions & 0 deletions packages/utils/src/useMediaQuery/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useLayoutEffect, useState } from 'react';

export default function useMediaQuery(mediaQuery: string) {
const isSsr = typeof window === 'undefined';

const [matches, setMatches] = useState(() =>
isSsr ? false : window.matchMedia(mediaQuery).matches,
);
useLayoutEffect(() => {
if (isSsr) {
return;
}
const mediaQueryList = window.matchMedia(mediaQuery);
const listener = (e: any) => setMatches(e.matches);
mediaQueryList.addListener(listener);
return () => mediaQueryList.removeListener(listener);
}, [mediaQuery]);
return matches;
}

0 comments on commit 3a174d1

Please sign in to comment.