UNPKG

3.64 kBJavaScriptView Raw
1import PropTypes from 'prop-types';
2import { exactProp } from '@material-ui/utils';
3import withWidth, { isWidthDown, isWidthUp } from '../withWidth';
4import useTheme from '../styles/useTheme';
5/**
6 * @ignore - internal component.
7 */
8
9function HiddenJs(props) {
10 const {
11 children,
12 only,
13 width
14 } = props;
15 const theme = useTheme();
16 let visible = true; // `only` check is faster to get out sooner if used.
17
18 if (only) {
19 if (Array.isArray(only)) {
20 for (let i = 0; i < only.length; i += 1) {
21 const breakpoint = only[i];
22
23 if (width === breakpoint) {
24 visible = false;
25 break;
26 }
27 }
28 } else if (only && width === only) {
29 visible = false;
30 }
31 } // Allow `only` to be combined with other props. If already hidden, no need to check others.
32
33
34 if (visible) {
35 // determine visibility based on the smallest size up
36 for (let i = 0; i < theme.breakpoints.keys.length; i += 1) {
37 const breakpoint = theme.breakpoints.keys[i];
38 const breakpointUp = props[`${breakpoint}Up`];
39 const breakpointDown = props[`${breakpoint}Down`];
40
41 if (breakpointUp && isWidthUp(breakpoint, width) || breakpointDown && isWidthDown(breakpoint, width)) {
42 visible = false;
43 break;
44 }
45 }
46 }
47
48 if (!visible) {
49 return null;
50 }
51
52 return children;
53}
54
55HiddenJs.propTypes = {
56 /**
57 * The content of the component.
58 */
59 children: PropTypes.node,
60
61 /**
62 * @ignore
63 */
64 className: PropTypes.string,
65
66 /**
67 * Specify which implementation to use. 'js' is the default, 'css' works better for
68 * server-side rendering.
69 */
70 implementation: PropTypes.oneOf(['js', 'css']),
71
72 /**
73 * You can use this prop when choosing the `js` implementation with server-side rendering.
74 *
75 * As `window.innerWidth` is unavailable on the server,
76 * we default to rendering an empty component during the first mount.
77 * You might want to use an heuristic to approximate
78 * the screen width of the client browser screen width.
79 *
80 * For instance, you could be using the user-agent or the client-hints.
81 * https://caniuse.com/#search=client%20hint
82 */
83 initialWidth: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
84
85 /**
86 * If `true`, screens this size and down will be hidden.
87 */
88 lgDown: PropTypes.bool,
89
90 /**
91 * If `true`, screens this size and up will be hidden.
92 */
93 lgUp: PropTypes.bool,
94
95 /**
96 * If `true`, screens this size and down will be hidden.
97 */
98 mdDown: PropTypes.bool,
99
100 /**
101 * If `true`, screens this size and up will be hidden.
102 */
103 mdUp: PropTypes.bool,
104
105 /**
106 * Hide the given breakpoint(s).
107 */
108 only: PropTypes.oneOfType([PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), PropTypes.arrayOf(PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']))]),
109
110 /**
111 * If `true`, screens this size and down will be hidden.
112 */
113 smDown: PropTypes.bool,
114
115 /**
116 * If `true`, screens this size and up will be hidden.
117 */
118 smUp: PropTypes.bool,
119
120 /**
121 * @ignore
122 * width prop provided by withWidth decorator.
123 */
124 width: PropTypes.string.isRequired,
125
126 /**
127 * If `true`, screens this size and down will be hidden.
128 */
129 xlDown: PropTypes.bool,
130
131 /**
132 * If `true`, screens this size and up will be hidden.
133 */
134 xlUp: PropTypes.bool,
135
136 /**
137 * If `true`, screens this size and down will be hidden.
138 */
139 xsDown: PropTypes.bool,
140
141 /**
142 * If `true`, screens this size and up will be hidden.
143 */
144 xsUp: PropTypes.bool
145};
146
147if (process.env.NODE_ENV !== 'production') {
148 HiddenJs.propTypes = exactProp(HiddenJs.propTypes);
149}
150
151export default withWidth()(HiddenJs);
\No newline at end of file