|
1 | 1 | import { useMediaQuery, useTheme } from '@mui/material'; |
2 | | -import React from 'react'; |
| 2 | +import React, { useMemo } from 'react'; |
3 | 3 |
|
4 | 4 | type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl'; |
5 | 5 |
|
| 6 | +const BREAKPOINTS: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl']; |
| 7 | + |
| 8 | +const extractCondition = (mediaQuery: string) => mediaQuery.replace(/^@media\s*/i, ''); |
| 9 | + |
6 | 10 | export interface HiddenProps { |
7 | 11 | children?: React.ReactNode; |
8 | 12 | only?: Breakpoint | Breakpoint[]; |
@@ -33,61 +37,44 @@ export const Hidden = ({ |
33 | 37 | xlDown = false |
34 | 38 | }: HiddenProps) => { |
35 | 39 | const theme = useTheme(); |
36 | | - const onlyValues = Array.isArray(only) ? only : only ? [only] : []; |
37 | | - |
38 | | - const conditions: string[] = []; |
39 | | - |
40 | | - const extractCondition = (mediaQuery: string) => mediaQuery.replace(/^@media\s*/i, ''); |
41 | | - |
42 | | - if (onlyValues.includes('xs')) { |
43 | | - conditions.push(extractCondition(theme.breakpoints.only('xs'))); |
44 | | - } |
45 | | - if (onlyValues.includes('sm')) { |
46 | | - conditions.push(extractCondition(theme.breakpoints.only('sm'))); |
47 | | - } |
48 | | - if (onlyValues.includes('md')) { |
49 | | - conditions.push(extractCondition(theme.breakpoints.only('md'))); |
50 | | - } |
51 | | - if (onlyValues.includes('lg')) { |
52 | | - conditions.push(extractCondition(theme.breakpoints.only('lg'))); |
53 | | - } |
54 | | - if (onlyValues.includes('xl')) { |
55 | | - conditions.push(extractCondition(theme.breakpoints.only('xl'))); |
56 | | - } |
| 40 | + const onlyKey = Array.isArray(only) ? [...only].sort().join(',') : only ?? ''; |
57 | 41 |
|
58 | | - if (xsUp) { |
59 | | - conditions.push(extractCondition(theme.breakpoints.up('xs'))); |
60 | | - } |
61 | | - if (smUp) { |
62 | | - conditions.push(extractCondition(theme.breakpoints.up('sm'))); |
63 | | - } |
64 | | - if (mdUp) { |
65 | | - conditions.push(extractCondition(theme.breakpoints.up('md'))); |
66 | | - } |
67 | | - if (lgUp) { |
68 | | - conditions.push(extractCondition(theme.breakpoints.up('lg'))); |
69 | | - } |
70 | | - if (xlUp) { |
71 | | - conditions.push(extractCondition(theme.breakpoints.up('xl'))); |
72 | | - } |
| 42 | + const mediaQuery = useMemo(() => { |
| 43 | + const onlyValues = onlyKey ? (onlyKey.split(',') as Breakpoint[]) : []; |
| 44 | + const upProps: Record<Breakpoint, boolean> = { |
| 45 | + xs: xsUp, |
| 46 | + sm: smUp, |
| 47 | + md: mdUp, |
| 48 | + lg: lgUp, |
| 49 | + xl: xlUp |
| 50 | + }; |
| 51 | + const downProps: Record<Breakpoint, boolean> = { |
| 52 | + xs: xsDown, |
| 53 | + sm: smDown, |
| 54 | + md: mdDown, |
| 55 | + lg: lgDown, |
| 56 | + xl: xlDown |
| 57 | + }; |
| 58 | + const conditions: string[] = []; |
73 | 59 |
|
74 | | - if (xsDown) { |
75 | | - conditions.push(extractCondition(theme.breakpoints.down('xs'))); |
76 | | - } |
77 | | - if (smDown) { |
78 | | - conditions.push(extractCondition(theme.breakpoints.down('sm'))); |
79 | | - } |
80 | | - if (mdDown) { |
81 | | - conditions.push(extractCondition(theme.breakpoints.down('md'))); |
82 | | - } |
83 | | - if (lgDown) { |
84 | | - conditions.push(extractCondition(theme.breakpoints.down('lg'))); |
85 | | - } |
86 | | - if (xlDown) { |
87 | | - conditions.push(extractCondition(theme.breakpoints.down('xl'))); |
88 | | - } |
| 60 | + for (const breakpoint of BREAKPOINTS) { |
| 61 | + if (onlyValues.includes(breakpoint)) { |
| 62 | + conditions.push(extractCondition(theme.breakpoints.only(breakpoint))); |
| 63 | + } |
| 64 | + if (upProps[breakpoint]) { |
| 65 | + conditions.push(extractCondition(theme.breakpoints.up(breakpoint))); |
| 66 | + } |
| 67 | + if (downProps[breakpoint]) { |
| 68 | + conditions.push( |
| 69 | + extractCondition( |
| 70 | + breakpoint === 'xs' ? theme.breakpoints.only('xs') : theme.breakpoints.down(breakpoint) |
| 71 | + ) |
| 72 | + ); |
| 73 | + } |
| 74 | + } |
89 | 75 |
|
90 | | - const mediaQuery = conditions.length > 0 ? `@media ${conditions.join(', ')}` : '@media not all'; |
| 76 | + return conditions.length > 0 ? `@media ${conditions.join(', ')}` : '@media not all'; |
| 77 | + }, [onlyKey, xsUp, smUp, mdUp, lgUp, xlUp, xsDown, smDown, mdDown, lgDown, xlDown, theme.breakpoints]); |
91 | 78 |
|
92 | 79 | const matches = useMediaQuery(mediaQuery); |
93 | 80 |
|
|
0 commit comments