From 117a081056545414c049b85684c85decbe49eb40 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 23 Jun 2021 16:52:01 +0700 Subject: [PATCH] Revert "[Hidden] Remove component (#26135)" This reverts commit 2b50b0f975de07f505120b8999128354898aa7fc. --- docs/pages/api-docs/hidden.js | 19 ++ docs/pages/api-docs/hidden.json | 39 ++++ docs/pages/components/hidden.js | 20 ++ docs/src/modules/branding/ComparisonTable.tsx | 80 ++++---- .../pages/components/hidden/BreakpointDown.js | 60 ++++++ .../components/hidden/BreakpointDown.tsx | 55 ++++++ .../pages/components/hidden/BreakpointOnly.js | 54 +++++ .../components/hidden/BreakpointOnly.tsx | 49 +++++ .../pages/components/hidden/BreakpointUp.js | 60 ++++++ .../pages/components/hidden/BreakpointUp.tsx | 55 ++++++ .../components/hidden/GridIntegration.js | 65 ++++++ .../components/hidden/GridIntegration.tsx | 60 ++++++ docs/src/pages/components/hidden/hidden-de.md | 66 +++++++ docs/src/pages/components/hidden/hidden-es.md | 66 +++++++ docs/src/pages/components/hidden/hidden-fr.md | 66 +++++++ docs/src/pages/components/hidden/hidden-ja.md | 66 +++++++ docs/src/pages/components/hidden/hidden-pt.md | 66 +++++++ docs/src/pages/components/hidden/hidden-ru.md | 66 +++++++ docs/src/pages/components/hidden/hidden-zh.md | 66 +++++++ docs/src/pages/components/hidden/hidden.md | 72 +++++++ .../templates/blog/FeaturedPost.js | 13 +- .../templates/blog/FeaturedPost.tsx | 13 +- .../pages/guides/migration-v4/migration-v4.md | 2 +- .../pages/premium-themes/paperbase/Header.js | 23 ++- .../pages/premium-themes/paperbase/Header.tsx | 23 ++- docs/src/pagesApi.js | 1 + .../api-docs/hidden/hidden-de.json | 20 ++ .../api-docs/hidden/hidden-es.json | 20 ++ .../api-docs/hidden/hidden-fr.json | 20 ++ .../api-docs/hidden/hidden-ja.json | 20 ++ .../api-docs/hidden/hidden-pt.json | 20 ++ .../api-docs/hidden/hidden-ru.json | 20 ++ .../api-docs/hidden/hidden-zh.json | 20 ++ docs/translations/api-docs/hidden/hidden.json | 20 ++ packages/material-ui/src/Hidden/Hidden.d.ts | 96 +++++++++ packages/material-ui/src/Hidden/Hidden.js | 146 ++++++++++++++ .../material-ui/src/Hidden/Hidden.test.js | 23 +++ .../material-ui/src/Hidden/HiddenCss.d.ts | 20 ++ packages/material-ui/src/Hidden/HiddenCss.js | 187 ++++++++++++++++++ .../material-ui/src/Hidden/HiddenCss.test.js | 152 ++++++++++++++ packages/material-ui/src/Hidden/HiddenJs.d.ts | 21 ++ packages/material-ui/src/Hidden/HiddenJs.js | 138 +++++++++++++ .../material-ui/src/Hidden/HiddenJs.test.js | 144 ++++++++++++++ .../src/Hidden/hiddenCssClasses.js | 26 +++ packages/material-ui/src/Hidden/index.d.ts | 2 + packages/material-ui/src/Hidden/index.js | 1 + packages/material-ui/src/index.d.ts | 3 + packages/material-ui/src/index.js | 3 + 48 files changed, 2276 insertions(+), 71 deletions(-) create mode 100644 docs/pages/api-docs/hidden.js create mode 100644 docs/pages/api-docs/hidden.json create mode 100644 docs/pages/components/hidden.js create mode 100644 docs/src/pages/components/hidden/BreakpointDown.js create mode 100644 docs/src/pages/components/hidden/BreakpointDown.tsx create mode 100644 docs/src/pages/components/hidden/BreakpointOnly.js create mode 100644 docs/src/pages/components/hidden/BreakpointOnly.tsx create mode 100644 docs/src/pages/components/hidden/BreakpointUp.js create mode 100644 docs/src/pages/components/hidden/BreakpointUp.tsx create mode 100644 docs/src/pages/components/hidden/GridIntegration.js create mode 100644 docs/src/pages/components/hidden/GridIntegration.tsx create mode 100644 docs/src/pages/components/hidden/hidden-de.md create mode 100644 docs/src/pages/components/hidden/hidden-es.md create mode 100644 docs/src/pages/components/hidden/hidden-fr.md create mode 100644 docs/src/pages/components/hidden/hidden-ja.md create mode 100644 docs/src/pages/components/hidden/hidden-pt.md create mode 100644 docs/src/pages/components/hidden/hidden-ru.md create mode 100644 docs/src/pages/components/hidden/hidden-zh.md create mode 100644 docs/src/pages/components/hidden/hidden.md create mode 100644 docs/translations/api-docs/hidden/hidden-de.json create mode 100644 docs/translations/api-docs/hidden/hidden-es.json create mode 100644 docs/translations/api-docs/hidden/hidden-fr.json create mode 100644 docs/translations/api-docs/hidden/hidden-ja.json create mode 100644 docs/translations/api-docs/hidden/hidden-pt.json create mode 100644 docs/translations/api-docs/hidden/hidden-ru.json create mode 100644 docs/translations/api-docs/hidden/hidden-zh.json create mode 100644 docs/translations/api-docs/hidden/hidden.json create mode 100644 packages/material-ui/src/Hidden/Hidden.d.ts create mode 100644 packages/material-ui/src/Hidden/Hidden.js create mode 100644 packages/material-ui/src/Hidden/Hidden.test.js create mode 100644 packages/material-ui/src/Hidden/HiddenCss.d.ts create mode 100644 packages/material-ui/src/Hidden/HiddenCss.js create mode 100644 packages/material-ui/src/Hidden/HiddenCss.test.js create mode 100644 packages/material-ui/src/Hidden/HiddenJs.d.ts create mode 100644 packages/material-ui/src/Hidden/HiddenJs.js create mode 100644 packages/material-ui/src/Hidden/HiddenJs.test.js create mode 100644 packages/material-ui/src/Hidden/hiddenCssClasses.js create mode 100644 packages/material-ui/src/Hidden/index.d.ts create mode 100644 packages/material-ui/src/Hidden/index.js diff --git a/docs/pages/api-docs/hidden.js b/docs/pages/api-docs/hidden.js new file mode 100644 index 00000000000000..f04b85a8271521 --- /dev/null +++ b/docs/pages/api-docs/hidden.js @@ -0,0 +1,19 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './hidden.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context('docs/translations/api-docs/hidden', false, /hidden.*.json$/); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/api-docs/hidden.json b/docs/pages/api-docs/hidden.json new file mode 100644 index 00000000000000..90d50d8e7c15dc --- /dev/null +++ b/docs/pages/api-docs/hidden.json @@ -0,0 +1,39 @@ +{ + "props": { + "children": { "type": { "name": "node" } }, + "implementation": { + "type": { "name": "enum", "description": "'css'
| 'js'" }, + "default": "'js'" + }, + "initialWidth": { + "type": { + "name": "enum", + "description": "'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'" + } + }, + "lgDown": { "type": { "name": "bool" } }, + "lgUp": { "type": { "name": "bool" } }, + "mdDown": { "type": { "name": "bool" } }, + "mdUp": { "type": { "name": "bool" } }, + "only": { + "type": { + "name": "union", + "description": "'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'
| Array<'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'>" + } + }, + "smDown": { "type": { "name": "bool" } }, + "smUp": { "type": { "name": "bool" } }, + "xlDown": { "type": { "name": "bool" } }, + "xlUp": { "type": { "name": "bool" } }, + "xsDown": { "type": { "name": "bool" } }, + "xsUp": { "type": { "name": "bool" } } + }, + "name": "Hidden", + "styles": { "classes": [], "globalClasses": {}, "name": null }, + "spread": true, + "filename": "/packages/material-ui/src/Hidden/Hidden.js", + "inheritance": null, + "demos": "", + "styledComponent": true, + "cssComponent": false +} diff --git a/docs/pages/components/hidden.js b/docs/pages/components/hidden.js new file mode 100644 index 00000000000000..260edf0c2013ed --- /dev/null +++ b/docs/pages/components/hidden.js @@ -0,0 +1,20 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; + +const pageFilename = 'components/hidden'; +const requireDemo = require.context('docs/src/pages/components/hidden', false, /\.(js|tsx)$/); +const requireRaw = require.context( + '!raw-loader!../../src/pages/components/hidden', + false, + /\.(js|md|tsx)$/, +); + +export default function Page({ demos, docs }) { + return ; +} + +Page.getInitialProps = () => { + const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); + return { demos, docs }; +}; diff --git a/docs/src/modules/branding/ComparisonTable.tsx b/docs/src/modules/branding/ComparisonTable.tsx index 55062e697d2223..25ba70aa5c83c6 100644 --- a/docs/src/modules/branding/ComparisonTable.tsx +++ b/docs/src/modules/branding/ComparisonTable.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { styled, alpha, useTheme } from '@material-ui/core/styles'; -import useMediaQuery from '@material-ui/core/useMediaQuery'; +import { styled, alpha } from '@material-ui/core/styles'; import Table from '@material-ui/core/Table'; import Box from '@material-ui/core/Box'; import TableBody from '@material-ui/core/TableBody'; @@ -11,6 +10,7 @@ import Button from '@material-ui/core/Button'; import Link from 'docs/src/modules/components/Link'; import Typography from '@material-ui/core/Typography'; import NavigateNextIcon from '@material-ui/icons/NavigateNext'; +import Hidden from '@material-ui/core/Hidden'; import Grid from '@material-ui/core/Grid'; import CheckIcon from 'docs/src/modules/branding/icons/Check'; import CloseIcon from 'docs/src/modules/branding/icons/Close'; @@ -301,39 +301,42 @@ const rows = [ variant="body3" sx={{ color: 'grey87' }} />, - , - , - , + + + , + + + , + + + , ), ]; @@ -352,12 +355,9 @@ const tableHeader = [ ]; export default function ComparisonTable() { - const theme = useTheme(); - const isSmUp = useMediaQuery(theme.breakpoints.up('sm')); - return ( - {isSmUp ? null : ( + {tableHeader.map((header) => ( @@ -368,7 +368,7 @@ export default function ComparisonTable() { ))} - )} + diff --git a/docs/src/pages/components/hidden/BreakpointDown.js b/docs/src/pages/components/hidden/BreakpointDown.js new file mode 100644 index 00000000000000..befbe0fb253517 --- /dev/null +++ b/docs/src/pages/components/hidden/BreakpointDown.js @@ -0,0 +1,60 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme) => ({ + root: { + flexGrow: 1, + }, + container: { + display: 'flex', + flexWrap: 'wrap', + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + flex: '1 0 auto', + margin: theme.spacing(1), + }, +})); + +function BreakpointDown(props) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + +
+ + xsDown + + + smDown + + + mdDown + + + lgDown + + + xlDown + +
+
+ ); +} + +BreakpointDown.propTypes = { + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, +}; + +export default withWidth()(BreakpointDown); diff --git a/docs/src/pages/components/hidden/BreakpointDown.tsx b/docs/src/pages/components/hidden/BreakpointDown.tsx new file mode 100644 index 00000000000000..59156d9896bb27 --- /dev/null +++ b/docs/src/pages/components/hidden/BreakpointDown.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { makeStyles, Theme } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth, { WithWidth } from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme: Theme) => ({ + root: { + flexGrow: 1, + }, + container: { + display: 'flex', + flexWrap: 'wrap', + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + flex: '1 0 auto', + margin: theme.spacing(1), + }, +})); + +function BreakpointDown(props: WithWidth) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + +
+ + xsDown + + + smDown + + + mdDown + + + lgDown + + + xlDown + +
+
+ ); +} + +export default withWidth()(BreakpointDown); diff --git a/docs/src/pages/components/hidden/BreakpointOnly.js b/docs/src/pages/components/hidden/BreakpointOnly.js new file mode 100644 index 00000000000000..b8ebed79dd0174 --- /dev/null +++ b/docs/src/pages/components/hidden/BreakpointOnly.js @@ -0,0 +1,54 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme) => ({ + root: { + flexGrow: 1, + }, + container: { + display: 'flex', + flexWrap: 'wrap', + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + flex: '1 0 auto', + margin: theme.spacing(1), + }, +})); + +function BreakpointOnly(props) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + +
+ + Hidden on lg + + + Hidden on sm + + + Hidden on sm and lg + +
+
+ ); +} + +BreakpointOnly.propTypes = { + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, +}; + +export default withWidth()(BreakpointOnly); diff --git a/docs/src/pages/components/hidden/BreakpointOnly.tsx b/docs/src/pages/components/hidden/BreakpointOnly.tsx new file mode 100644 index 00000000000000..c4bb5466874c54 --- /dev/null +++ b/docs/src/pages/components/hidden/BreakpointOnly.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import { makeStyles, Theme } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth, { WithWidth } from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme: Theme) => ({ + root: { + flexGrow: 1, + }, + container: { + display: 'flex', + flexWrap: 'wrap', + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + flex: '1 0 auto', + margin: theme.spacing(1), + }, +})); + +function BreakpointOnly(props: WithWidth) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + +
+ + Hidden on lg + + + Hidden on sm + + + Hidden on sm and lg + +
+
+ ); +} + +export default withWidth()(BreakpointOnly); diff --git a/docs/src/pages/components/hidden/BreakpointUp.js b/docs/src/pages/components/hidden/BreakpointUp.js new file mode 100644 index 00000000000000..603bec7311a0c0 --- /dev/null +++ b/docs/src/pages/components/hidden/BreakpointUp.js @@ -0,0 +1,60 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme) => ({ + root: { + flexGrow: 1, + }, + container: { + display: 'flex', + flexWrap: 'wrap', + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + flex: '1 0 auto', + margin: theme.spacing(1), + }, +})); + +function BreakpointUp(props) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + +
+ + xsUp + + + smUp + + + mdUp + + + lgUp + + + xlUp + +
+
+ ); +} + +BreakpointUp.propTypes = { + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, +}; + +export default withWidth()(BreakpointUp); diff --git a/docs/src/pages/components/hidden/BreakpointUp.tsx b/docs/src/pages/components/hidden/BreakpointUp.tsx new file mode 100644 index 00000000000000..a31ff2a196f97d --- /dev/null +++ b/docs/src/pages/components/hidden/BreakpointUp.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { makeStyles, Theme } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth, { WithWidth } from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme: Theme) => ({ + root: { + flexGrow: 1, + }, + container: { + display: 'flex', + flexWrap: 'wrap', + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + flex: '1 0 auto', + margin: theme.spacing(1), + }, +})); + +function BreakpointUp(props: WithWidth) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + +
+ + xsUp + + + smUp + + + mdUp + + + lgUp + + + xlUp + +
+
+ ); +} + +export default withWidth()(BreakpointUp); diff --git a/docs/src/pages/components/hidden/GridIntegration.js b/docs/src/pages/components/hidden/GridIntegration.js new file mode 100644 index 00000000000000..f662c17204056c --- /dev/null +++ b/docs/src/pages/components/hidden/GridIntegration.js @@ -0,0 +1,65 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Grid from '@material-ui/core/Grid'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme) => ({ + root: { + flexGrow: 1, + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + }, +})); + +function GridIntegration(props) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + + + + + xsUp + + + + + smUp + + + + + mdUp + + + + + lgUp + + + + + xlUp + + + +
+ ); +} + +GridIntegration.propTypes = { + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, +}; + +export default withWidth()(GridIntegration); diff --git a/docs/src/pages/components/hidden/GridIntegration.tsx b/docs/src/pages/components/hidden/GridIntegration.tsx new file mode 100644 index 00000000000000..dc325858527121 --- /dev/null +++ b/docs/src/pages/components/hidden/GridIntegration.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; +import { makeStyles, Theme } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Grid from '@material-ui/core/Grid'; +import Hidden from '@material-ui/core/Hidden'; +import withWidth, { WithWidth } from '@material-ui/core/withWidth'; +import Typography from '@material-ui/core/Typography'; + +const useStyles = makeStyles((theme: Theme) => ({ + root: { + flexGrow: 1, + }, + paper: { + padding: theme.spacing(2), + textAlign: 'center', + color: theme.palette.text.secondary, + }, +})); + +function GridIntegration(props: WithWidth) { + const classes = useStyles(); + const { width } = props; + + return ( +
+ + Current width: {width} + + + + + xsUp + + + + + smUp + + + + + mdUp + + + + + lgUp + + + + + xlUp + + + +
+ ); +} + +export default withWidth()(GridIntegration); diff --git a/docs/src/pages/components/hidden/hidden-de.md b/docs/src/pages/components/hidden/hidden-de.md new file mode 100644 index 00000000000000..7c8149d1002d8e --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-de.md @@ -0,0 +1,66 @@ +--- +title: React Hidden component +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Quickly and responsively toggle the visibility value of components and more with the hidden utilities.

+ +Alle Elemente sind sichtbar, außer **sie explizit versteckt**. To ease integration with Material-UI's [responsive breakpoints](/customization/breakpoints/), this component can be used to hide any content, or you can use it in conjunction with the [`Grid`](/components/grid/) component. + +Die Style-Funktion der [Palette](/system/palette/). + +## So funktioniert es + +Hidden funktioniert mit einem Bereich von Haltepunkten, z. `xsUp` oder `mdDown`, oder einem oder mehreren Haltepunkten, z. `only='sm'` oder `only {['md','xl']}`. Bereiche und individuelle Haltepunkte können gleichzeitig verwendet werden, um ein sehr benutzerdefiniertes Verhalten zu erreichen. Die Bereiche enthalten die angegebenen Haltepunkte. + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## Implementierungen + +### js + +Standardmäßig wird die `js` Implementierung verwendet, die den Inhalt basierend auf der [`withWidth()`](/customization/breakpoints/#withwidth)-Komponente höherer Ordnung, die die Bildschirmgröße überwacht, ansprechend versteckt. Dies hat den Vorteil, dass überhaupt kein Inhalt dargestellt wird, wenn der Haltepunkt nicht erreicht wird. + +### css + +Wenn Sie serverseitiges Rendering verwenden, können Sie `implementation="css"` festlegen, wenn der Browser Ihren Inhalt nicht erneut auf dem Bildschirm anzeigen soll. + +## Haltepunkte Up + +Unter Verwendung einer beliebigen Haltepunkte `down` Eigenschaft, werden die angegebenen *Kinder* ausgeblendet *bei oder unter* dem Haltepunkt. + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## Haltepunkte Down + +Unter Verwendung der Haltepunkt `only` Eigenschaft, werden die angegebenen *Kinder* *bei* dem Haltepunkt(en) ausgeblendet. + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## Haltepunkte einzeln + +Die `only` Eigenschaft kann auf zwei Arten verwendet werden: + +The `only` prop can be used in two ways: + +- Einzelnen Haltepunkt auflisten +- Listen Sie ein Array von Haltepunkten auf + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## Integration mit Grid + +Es ist üblich, das`Grid` an verschiedenen Haltepunkten zu ändern, und in vielen Fällen möchten Sie einige dieser Elemente ausblenden. + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden-es.md b/docs/src/pages/components/hidden/hidden-es.md new file mode 100644 index 00000000000000..765a571a6e5819 --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-es.md @@ -0,0 +1,66 @@ +--- +title: React Hidden component +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Hidden: Cambia rápida y de manera responsiva el valor de visibilidad de los componentes y más con nuestras utilidades ocultas.

+ +Todos los elementos son visibles a menos que **estén explícitamente ocultos**. Para facilitar la integración con [interrupción responsivas](/customization/breakpoints/) de Material-UI, éste componente se puede usar para ocultar cualquier contenido, o puede usarlo junto con el componente [`Grid`](/components/grid/). + +[La función de estilo de la paleta](/system/palette/). + +## Cómo funciona + +Hidden funciona con un rango de puntos de interrupción, por ejemplo, `xsUp` o `mdDown`, o uno o más puntos de interrupción, por ejemplo, `only = 'sm'` o `only = {['md', 'xl']}`. Los rangos y los puntos de interrupción individuales se pueden usar simultáneamente para lograr un comportamiento muy personalizado. Los rangos son inclusivas de los puntos de interrupción. + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## Implementación + +### js + +By default, the `js` implementation is used, responsively hiding content based on using the [`withWidth()`](/customization/breakpoints/#withwidth) higher-order component that watches screen size. This has the benefit of not rendering any content at all unless the breakpoint is met. + +### css + +If you are using server-side rendering, you can set `implementation="css"` if you don't want the browser to re-flow your content on the screen. + +## Breakpoint up + +Using any breakpoint `up` property, the given *children* will be hidden *at or above* the breakpoint. + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## Breakpoint down + +Using any breakpoint `down` property, the given *children* will be hidden *at or below* the breakpoint. + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## Breakpoint only + +The `only` property can be used in two ways: + +The `only` prop can be used in two ways: + +- list a single breakpoint +- list an array of breakpoints + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## Integration with Grid + +It is quite common to alter `Grid` at different responsive breakpoints, and in many cases, you want to hide some of those elements. + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden-fr.md b/docs/src/pages/components/hidden/hidden-fr.md new file mode 100644 index 00000000000000..fe2d539e224fad --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-fr.md @@ -0,0 +1,66 @@ +--- +title: React Hidden component +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Quickly and responsively toggle the visibility value of components and more with the hidden utilities.

+ +Tous les éléments sont visibles à moins **qu'ils soient explicitement cachés**. To ease integration with Material-UI's [responsive breakpoints](/customization/breakpoints/), this component can be used to hide any content, or you can use it in conjunction with the [`Grid`](/components/grid/) component. + +{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} + +## Comment ça marche + +Hidden works with a range of breakpoints e.g. `xsUp` or `mdDown`, or one or more breakpoints e.g. `only='sm'` or `only={['md', 'xl']}`. Ranges and individual breakpoints can be used simultaneously to achieve very customized behavior. The ranges are inclusive of the specified breakpoints. + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## Implementations + +### js + +By default, the `js` implementation is used, responsively hiding content based on using the [`withWidth()`](/customization/breakpoints/#withwidth) higher-order component that watches screen size. This has the benefit of not rendering any content at all unless the breakpoint is met. + +### css + +If you are using server-side rendering, you can set `implementation="css"` if you don't want the browser to re-flow your content on the screen. + +## Breakpoint up + +Using any breakpoint `up` property, the given *children* will be hidden *at or above* the breakpoint. + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## Breakpoint down + +Using any breakpoint `down` property, the given *children* will be hidden *at or below* the breakpoint. + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## Breakpoint only + +The `only` property can be used in two ways: + +The `only` prop can be used in two ways: + +- list a single breakpoint +- list an array of breakpoints + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## Integration with Grid + +It is quite common to alter `Grid` at different responsive breakpoints, and in many cases, you want to hide some of those elements. + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden-ja.md b/docs/src/pages/components/hidden/hidden-ja.md new file mode 100644 index 00000000000000..60c3e38e8c67ce --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-ja.md @@ -0,0 +1,66 @@ +--- +title: React Hidden component +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Quickly and responsively toggle the visibility value of components and more with the hidden utilities.

+ +**明示的に非表示にしない限り**、すべての要素が表示されます。 **明示的に非表示にしない限り**、すべての要素が表示されます。 **明示的に非表示にしない限り**、すべての要素が表示されます。 **明示的に非表示にしない限り**、すべての要素が表示されます。 To ease integration with Material-UI's [responsive breakpoints](/customization/breakpoints/), this component can be used to hide any content, or you can use it in conjunction with the [`Grid`](/components/grid/) component. + +[The palette](/system/palette/) style関数。 + +## 仕組み + +Hiddenは、`xsUp`または`mdDown` などのブレークポイントの範囲、 `{['sm','md','xl']}`などのブレークポイントで機能します。 範囲と個々のブレークポイントを同時に使用して、非常にカスタマイズされた動作を実現できます。 範囲には、指定したブレークポイントが含まれます。 + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## 実装 + +### js + +デフォルトでは、`js`実装が使用され、画面サイズを監視する [`withWidth()`](/customization/breakpoints/#withwidth)高次コンポーネントの使用に基づいて、応答的にコンテンツが非表示にされます これには、ブレークポイントに到達しない限りコンテンツをまったくレンダリングしないという利点があります。 + +### css + +サーバ側レンダリングを使用している場合、ブラウザで画面上のコンテンツを再フローしないようにするには、`implementation="css"`と設定します。 + +## ブレイクポイント + +ブレークポイントの`down`プロパティを使用すると、指定した*children*がブレークポイントの位置またはその上*at or below*になります。 + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## ブレイクポイント + +ブレークポイントの `only`プロパティを使用すると、指定した*children*がブレークポイントの位置またはその上*at*>になります。 + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## ブレークポイントのみ + +`only` プロパティは、次の2つの方法で使用できます。 + +The `only` prop can be used in two ways: + +- 単一のブレークポイントをリストする +- ブレークポイントの配列をリストします + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## グリッドとの統合 + +さまざまな応答ブレークポイントで`Grid` を変更することはよくあり、多くの場合、これらの要素の一部を非表示にする必要があります。 + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden-pt.md b/docs/src/pages/components/hidden/hidden-pt.md new file mode 100644 index 00000000000000..38d8dc414ac1cd --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-pt.md @@ -0,0 +1,66 @@ +--- +title: Componente React Hidden +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Modifique rapidamente e de forma responsiva a visibilidade dos componentes e faça muito mais com o utilitário hidden.

+ +Todos os elementos são visíveis a menos que **estejam explicitamente ocultos**. Para facilitar a integração com [pontos de quebra responsivos](/customization/breakpoints/) do Material-UI, este componente pode ser utilizado para ocultar qualquer conteúdo, ou você pode usa-lo de forma conjunta com um componente [`Grid`](/components/grid/). + +[A paleta](/system/palette/) com funções de estilo. + +## Como funciona + +Hidden trabalha com um intervalo de pontos de quebra, por exemplo, `xsUp` ou `mdDown`, ou com um ou mais pontos de quebra, por exemplo, `only='sm'` ou `only={['md', 'xl']}`. Intervalos e pontos de quebra individuais podem ser usados simultaneamente para obter um comportamento muito mais customizado. Os intervalos são inclusivos com os pontos de quebra especificados. + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## Implementações + +### js + +Por padrão, a implementação `js` é usada, responsivamente oculta o conteúdo baseando-se no uso de [`withWidth()`](/customization/breakpoints/#withwidth), componente de ordem elevada (higher-order) que observa o tamanho da tela. Isso tem o benefício de não renderizar nenhum conteúdo, a menos que o ponto de quebra seja atingido. + +### css + +Se você estiver usando a renderização do lado do servidor, poderá definir `implementation="css"` se não quer que o navegador reprocesse seu conteúdo na tela. + +## Ponto de quebra acima + +Usando qualquer propriedade de ponto de quebra com `down`, o componente *children* será ocultado *em ou abaixo* do ponto de quebra. + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## Ponto de quebra abaixo + +Usando a propriedade de ponto de quebra `only`, o componente *children* será ocultado *no(s) ponto(s) de quebra* especificado(s). + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## Ponto de quebra somente + +A propriedade `only` pode ser usada de duas maneiras: + +A propriedade `only` pode ser usada de duas maneiras: + +- com um único ponto de quebra +- com um array de pontos de quebra + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## Integração com Grade + +É bastante comum alterar um `Grid` em pontos de quebra responsivos diferentes e, em muitos casos, você deseja ocultar alguns desses elementos. + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden-ru.md b/docs/src/pages/components/hidden/hidden-ru.md new file mode 100644 index 00000000000000..9ba0977425116b --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-ru.md @@ -0,0 +1,66 @@ +--- +title: Компонент React Hidden +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Быстро и адаптивно изменяйте видимость компонент и многое другое с помощью наших утилит управления видимостью.

+ +Все элементы видны, если **они явно не скрыты**. Чтобы упростить интеграцию с [ точками остановки](/customization/breakpoints/) Material-UI, этот компонент можно использовать для скрытия любого контента, или использовать его в сочетании с нашим компонентом [`Grid`](/components/grid/). + +{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} + +## Как это работает + +Скрытие работает с диапазоном точек остановки, например, `xsUp` или `mdDown`, или использует одну или несколько точек остановки, например, `only='sm'` или `only={['md', 'xl']}`. Диапазоны и отдельные точки остановки могут использоваться одновременно для достижения индивидуального поведения. Диапазоны включают указанные точки остановки. + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## Реализации + +### js + +По умолчанию используется реализация `js`, которая быстро скрывает контент, используя компонент высшего порядка [`withWidth()`](/customization/breakpoints/#withwidth), который следит за размером экрана. Преимущество этого заключается в том, что контент вообще не отображается, если не достигнута точка остановки. + +### css + +Если вы используете рендеринг на стороне сервера, вы можете установить `implementation="css"`, если вы не хотите, чтобы браузер повторно выводил ваш контент на экран. + +## Точка остановки Вверх (up) + +Используя любое свойство точки остановки от `down`, данные *дочерних элементов* будут скрыты *на уровне или ниже* точки остановки. + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## Точка остановки Вниз + +Используя свойство точки остановки `only`, данные *дочерних элементов* будут скрыты *на* указанной точке (точках) остановки. + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## Точка остановки Только (only) + +Свойство `only` можно использовать двумя способами: + +The `only` prop can be used in two ways: + +- указать одну точку остановки +- перечислить массив точек остановки + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## Интеграция с Grid (Сеткой) + +Весьма обычным является изменение `Grid` в разных точках остановки, и во многих случаях вы хотите скрыть некоторые из этих элементов. + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden-zh.md b/docs/src/pages/components/hidden/hidden-zh.md new file mode 100644 index 00000000000000..7762af4c36d80a --- /dev/null +++ b/docs/src/pages/components/hidden/hidden-zh.md @@ -0,0 +1,66 @@ +--- +title: React Hidden(隐藏)组件 +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden 隐藏组件 + +

您可以使用隐藏组件来实现快速并响应式地控制元素的显隐。

+ +除非**明确指定是隐藏的**,否则所有元素默认都是可见的。 为了简化与 [响应式断点](/customization/breakpoints/) 的集成,此组件可用于隐藏任何内容,或者您可以将它与我们的 [`栅格(Grid)`](/components/grid/) 组件结合使用。 + +{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} + +## 工作原理 + +通常我们将隐藏组件和一系列 breakpoint(断点)放在一起使用。例如 `xsUp` 或 `mdDown`,或一个或多个断点,例如 `only='sm'` 或 `only={['md', 'xl']}`。 可以同时使用范围(Ranges)和单独的断点(breakpoints)来实现极其定制的行为。 范围包括指定的断点。 + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## 实现 + +### js + +默认情况下,使用 `js` 实现,响应性的隐藏内容基于 [`withWidth()`](/customization/breakpoints/#withwidth) 这个高阶组件所观察到的屏幕大小。 这样的好处是,除非达到断点,否则根本不会呈现任何内容。 + +### css + +如果您正在使用服务器端渲染,如果您不希望浏览器在屏幕上重新过一遍您的内容,则可以设置 `implementation="css"` 。 + +## 断点之上(Breakpoint up) + +使用任何断点的 `up` 属性,所给定的_子代_将在断点处或其之上_隐藏_。 + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## 断点之下(Breakpoint down) + +使用任何断点的 `down` 属性,所给定的_子代_将在断点_处或其之下_隐藏。 + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## 仅限断点 + +当使用断点 `only` 属性,给定的_子元素_将在 _在_ 指定的断点(们)被隐藏。 + +`only` 属性可以通过以下两种方式来调用: + +- 列出单独一个断点 +- 列出一个断点数组 + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## 与栅格(Grid)整合 + +在不同的响应断点处更改 `Grid` 是很常见的,并且在许多情况下,您会希望隐藏其中一些元素。 + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/components/hidden/hidden.md b/docs/src/pages/components/hidden/hidden.md new file mode 100644 index 00000000000000..6c82137706a133 --- /dev/null +++ b/docs/src/pages/components/hidden/hidden.md @@ -0,0 +1,72 @@ +--- +title: React Hidden component +components: Hidden +githubLabel: 'component: Hidden' +--- + +# Hidden + +

Quickly and responsively toggle the visibility value of components and more with the hidden utilities.

+ +All elements are visible unless **they are explicitly hidden**. +To ease integration with Material-UI's [responsive breakpoints](/customization/breakpoints/), +this component can be used to hide any content, +or you can use it in conjunction with the [`Grid`](/components/grid/) component. + +{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} + +## How it works + +Hidden works with a range of breakpoints e.g. `xsUp` or `mdDown`, or one or more breakpoints e.g. `only='sm'` or `only={['md', 'xl']}`. +Ranges and individual breakpoints can be used simultaneously to achieve very customized behavior. +The ranges are inclusive of the specified breakpoints. + +```js +innerWidth |xs sm md lg xl + |--------|--------|--------|--------|--------> +width | xs | sm | md | lg | xl + +smUp | show | hide +mdDown | hide | show + +``` + +## Implementations + +### js + +By default, the `js` implementation is used, responsively hiding content based on using the [`withWidth()`](/customization/breakpoints/#withwidth) higher-order component that watches screen size. +This has the benefit of not rendering any content at all unless the breakpoint is met. + +### css + +If you are using server-side rendering, you can set `implementation="css"` if you don't want the browser to re-flow your content on the screen. + +## Breakpoint up + +Using any breakpoint `up` prop, the given _children_ will be hidden _at or above_ the breakpoint. + +{{"demo": "pages/components/hidden/BreakpointUp.js", "bg": true}} + +## Breakpoint down + +Using any breakpoint `down` prop, the given _children_ will be hidden _at or below_ the breakpoint. + +{{"demo": "pages/components/hidden/BreakpointDown.js", "bg": true}} + +## Breakpoint only + +Using the breakpoint `only` prop, the given _children_ will be hidden _at_ the specified breakpoint(s). + +The `only` prop can be used in two ways: + +- list a single breakpoint +- list an array of breakpoints + +{{"demo": "pages/components/hidden/BreakpointOnly.js", "bg": true}} + +## Integration with Grid + +It is quite common to alter `Grid` at different responsive breakpoints, and in many cases, you want to hide some of those elements. + +{{"demo": "pages/components/hidden/GridIntegration.js", "bg": true}} diff --git a/docs/src/pages/getting-started/templates/blog/FeaturedPost.js b/docs/src/pages/getting-started/templates/blog/FeaturedPost.js index c2ae3c080b8372..421e82d19a8f10 100644 --- a/docs/src/pages/getting-started/templates/blog/FeaturedPost.js +++ b/docs/src/pages/getting-started/templates/blog/FeaturedPost.js @@ -6,6 +6,7 @@ import Card from '@material-ui/core/Card'; import CardActionArea from '@material-ui/core/CardActionArea'; import CardContent from '@material-ui/core/CardContent'; import CardMedia from '@material-ui/core/CardMedia'; +import Hidden from '@material-ui/core/Hidden'; function FeaturedPost(props) { const { post } = props; @@ -28,11 +29,13 @@ function FeaturedPost(props) { Continue reading... - + + + diff --git a/docs/src/pages/getting-started/templates/blog/FeaturedPost.tsx b/docs/src/pages/getting-started/templates/blog/FeaturedPost.tsx index 440916fffb5370..76c7a35a1accc0 100644 --- a/docs/src/pages/getting-started/templates/blog/FeaturedPost.tsx +++ b/docs/src/pages/getting-started/templates/blog/FeaturedPost.tsx @@ -5,6 +5,7 @@ import Card from '@material-ui/core/Card'; import CardActionArea from '@material-ui/core/CardActionArea'; import CardContent from '@material-ui/core/CardContent'; import CardMedia from '@material-ui/core/CardMedia'; +import Hidden from '@material-ui/core/Hidden'; interface FeaturedPostProps { post: { @@ -37,11 +38,13 @@ export default function FeaturedPost(props: FeaturedPostProps) { Continue reading... - + + + diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index 1fb87506905f60..cd6dd74da4fcfc 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -974,7 +974,7 @@ You can use the [`collapse-rename-collapsedheight` codemod](https://github.com/m ### Hidden -- This component was removed because its functionality can be created with the [`sx`](/system/basics/#the-sx-prop) prop or the [`useMediaQuery`](/components/use-media-query) hook. +- This component is deprecated because its functionality can be created with the [`sx`](/system/basics/#the-sx-prop) prop or the [`useMediaQuery`](/components/use-media-query) hook. Use the `sx` prop to replace `implementation="css"`: diff --git a/docs/src/pages/premium-themes/paperbase/Header.js b/docs/src/pages/premium-themes/paperbase/Header.js index d97199c0ddccdb..263481f58a9ec4 100644 --- a/docs/src/pages/premium-themes/paperbase/Header.js +++ b/docs/src/pages/premium-themes/paperbase/Header.js @@ -5,6 +5,7 @@ import Avatar from '@material-ui/core/Avatar'; import Button from '@material-ui/core/Button'; import Grid from '@material-ui/core/Grid'; import HelpIcon from '@material-ui/icons/Help'; +import Hidden from '@material-ui/core/Hidden'; import IconButton from '@material-ui/core/IconButton'; import Link from '@material-ui/core/Link'; import MenuIcon from '@material-ui/icons/Menu'; @@ -25,16 +26,18 @@ function Header(props) { - - - - - + + + + + + + - - - - - + + + + + + + js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden-es.json b/docs/translations/api-docs/hidden/hidden-es.json new file mode 100644 index 00000000000000..7bc5b483e804d3 --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden-es.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "The content of the component.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden-fr.json b/docs/translations/api-docs/hidden/hidden-fr.json new file mode 100644 index 00000000000000..60dbc5d9bbb76d --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden-fr.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "Le contenu du composant.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden-ja.json b/docs/translations/api-docs/hidden/hidden-ja.json new file mode 100644 index 00000000000000..7bc5b483e804d3 --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden-ja.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "The content of the component.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden-pt.json b/docs/translations/api-docs/hidden/hidden-pt.json new file mode 100644 index 00000000000000..7bc5b483e804d3 --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden-pt.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "The content of the component.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden-ru.json b/docs/translations/api-docs/hidden/hidden-ru.json new file mode 100644 index 00000000000000..7bc5b483e804d3 --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden-ru.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "The content of the component.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden-zh.json b/docs/translations/api-docs/hidden/hidden-zh.json new file mode 100644 index 00000000000000..7bc5b483e804d3 --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden-zh.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "The content of the component.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/hidden/hidden.json b/docs/translations/api-docs/hidden/hidden.json new file mode 100644 index 00000000000000..7bc5b483e804d3 --- /dev/null +++ b/docs/translations/api-docs/hidden/hidden.json @@ -0,0 +1,20 @@ +{ + "componentDescription": "Responsively hides children based on the selected implementation.", + "propDescriptions": { + "children": "The content of the component.", + "implementation": "Specify which implementation to use. 'js' is the default, 'css' works better for server-side rendering.", + "initialWidth": "You can use this prop when choosing the js implementation with server-side rendering.
As window.innerWidth is unavailable on the server, we default to rendering an empty component during the first mount. You might want to use a heuristic to approximate the screen width of the client browser screen width.
For instance, you could be using the user-agent or the client-hints. https://caniuse.com/#search=client%20hint", + "lgDown": "If true, screens this size and down are hidden.", + "lgUp": "If true, screens this size and up are hidden.", + "mdDown": "If true, screens this size and down are hidden.", + "mdUp": "If true, screens this size and up are hidden.", + "only": "Hide the given breakpoint(s).", + "smDown": "If true, screens this size and down are hidden.", + "smUp": "If true, screens this size and up are hidden.", + "xlDown": "If true, screens this size and down are hidden.", + "xlUp": "If true, screens this size and up are hidden.", + "xsDown": "If true, screens this size and down are hidden.", + "xsUp": "If true, screens this size and up are hidden." + }, + "classDescriptions": {} +} diff --git a/packages/material-ui/src/Hidden/Hidden.d.ts b/packages/material-ui/src/Hidden/Hidden.d.ts new file mode 100644 index 00000000000000..e8d9ea62dc8996 --- /dev/null +++ b/packages/material-ui/src/Hidden/Hidden.d.ts @@ -0,0 +1,96 @@ +import * as React from 'react'; +import { Breakpoint } from '../styles/createBreakpoints'; + +export interface HiddenProps { + /** + * The content of the component. + */ + children?: React.ReactNode; + /** + * Specify which implementation to use. 'js' is the default, 'css' works better for + * server-side rendering. + * @default 'js' + */ + implementation?: 'js' | 'css'; + /** + * You can use this prop when choosing the `js` implementation with server-side rendering. + * + * As `window.innerWidth` is unavailable on the server, + * we default to rendering an empty component during the first mount. + * You might want to use a heuristic to approximate + * the screen width of the client browser screen width. + * + * For instance, you could be using the user-agent or the client-hints. + * https://caniuse.com/#search=client%20hint + */ + initialWidth?: Breakpoint; + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + lgDown?: boolean; + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + lgUp?: boolean; + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + mdDown?: boolean; + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + mdUp?: boolean; + /** + * Hide the given breakpoint(s). + */ + only?: Breakpoint | Breakpoint[]; + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + smDown?: boolean; + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + smUp?: boolean; + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + xlDown?: boolean; + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + xlUp?: boolean; + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + xsDown?: boolean; + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + xsUp?: boolean; +} + +/** + * Responsively hides children based on the selected implementation. + * + * Demos: + * + * - [Hidden](https://material-ui.com/components/hidden/) + * + * API: + * + * - [Hidden API](https://material-ui.com/api/hidden/) + */ +declare const Hidden: React.JSXElementConstructor; + +export default Hidden; diff --git a/packages/material-ui/src/Hidden/Hidden.js b/packages/material-ui/src/Hidden/Hidden.js new file mode 100644 index 00000000000000..604e99d93cf32d --- /dev/null +++ b/packages/material-ui/src/Hidden/Hidden.js @@ -0,0 +1,146 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import HiddenJs from './HiddenJs'; +import HiddenCss from './HiddenCss'; + +/** + * Responsively hides children based on the selected implementation. + */ +function Hidden(props) { + const { + implementation = 'js', + lgDown = false, + lgUp = false, + mdDown = false, + mdUp = false, + smDown = false, + smUp = false, + xlDown = false, + xlUp = false, + xsDown = false, + xsUp = false, + ...other + } = props; + + if (implementation === 'js') { + return ( + + ); + } + + return ( + + ); +} + +Hidden.propTypes /* remove-proptypes */ = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the d.ts file and run "yarn proptypes" | + // ---------------------------------------------------------------------- + /** + * The content of the component. + */ + children: PropTypes.node, + /** + * Specify which implementation to use. 'js' is the default, 'css' works better for + * server-side rendering. + * @default 'js' + */ + implementation: PropTypes.oneOf(['css', 'js']), + /** + * You can use this prop when choosing the `js` implementation with server-side rendering. + * + * As `window.innerWidth` is unavailable on the server, + * we default to rendering an empty component during the first mount. + * You might want to use a heuristic to approximate + * the screen width of the client browser screen width. + * + * For instance, you could be using the user-agent or the client-hints. + * https://caniuse.com/#search=client%20hint + */ + initialWidth: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + lgDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + lgUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + mdDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + mdUp: PropTypes.bool, + /** + * Hide the given breakpoint(s). + */ + only: PropTypes.oneOfType([ + PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), + PropTypes.arrayOf(PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired), + ]), + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + smDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + smUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + xlDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + xlUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + * @default false + */ + xsDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + * @default false + */ + xsUp: PropTypes.bool, +}; + +export default Hidden; diff --git a/packages/material-ui/src/Hidden/Hidden.test.js b/packages/material-ui/src/Hidden/Hidden.test.js new file mode 100644 index 00000000000000..77c29004cfd16a --- /dev/null +++ b/packages/material-ui/src/Hidden/Hidden.test.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { expect } from 'chai'; +import { createClientRender } from 'test/utils'; +import Hidden from '@material-ui/core/Hidden'; + +describe('', () => { + const render = createClientRender(); + const child = Hello; + + describe('prop: implementation', () => { + it('should use HiddenJs by default', () => { + const { container } = render({child}); + // JS implementation doesn't requires wrapping
+ expect(container.firstChild).to.have.tagName('span'); + }); + + it('should change the implementation', () => { + const { container } = render({child}); + // CSS implementation requires wrapping
+ expect(container.firstChild).to.have.tagName('div'); + }); + }); +}); diff --git a/packages/material-ui/src/Hidden/HiddenCss.d.ts b/packages/material-ui/src/Hidden/HiddenCss.d.ts new file mode 100644 index 00000000000000..95e05744628a01 --- /dev/null +++ b/packages/material-ui/src/Hidden/HiddenCss.d.ts @@ -0,0 +1,20 @@ +import * as React from 'react'; +import { Breakpoint } from '../styles/createBreakpoints'; + +export interface HiddenCssProps { + lgDown?: boolean; + lgUp?: boolean; + mdDown?: boolean; + mdUp?: boolean; + only?: Breakpoint | Breakpoint[]; + smDown?: boolean; + smUp?: boolean; + xlDown?: boolean; + xlUp?: boolean; + xsDown?: boolean; + xsUp?: boolean; +} + +declare const HiddenCss: React.JSXElementConstructor; + +export default HiddenCss; diff --git a/packages/material-ui/src/Hidden/HiddenCss.js b/packages/material-ui/src/Hidden/HiddenCss.js new file mode 100644 index 00000000000000..6efb287833b919 --- /dev/null +++ b/packages/material-ui/src/Hidden/HiddenCss.js @@ -0,0 +1,187 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import PropTypes from 'prop-types'; +import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; +import capitalize from '../utils/capitalize'; +import experimentalStyled from '../styles/experimentalStyled'; +import useTheme from '../styles/useTheme'; +import { getHiddenCssUtilityClass } from './hiddenCssClasses'; + +const useUtilityClasses = (styleProps) => { + const { classes, breakpoints } = styleProps; + + const slots = { + root: [ + 'root', + ...breakpoints.map(({ breakpoint, dir }) => { + return dir === 'only' + ? `${dir}${capitalize(breakpoint)}` + : `${breakpoint}${capitalize(dir)}`; + }), + ], + }; + + return composeClasses(slots, getHiddenCssUtilityClass, classes); +}; + +const HiddenCssRoot = experimentalStyled( + 'div', + {}, + { + name: 'PrivateHiddenCss', + slot: 'Root', + }, +)(({ theme, styleProps }) => { + const hidden = { + display: 'none', + }; + + return { + ...styleProps.breakpoints + .map(({ breakpoint, dir }) => { + if (dir === 'only') { + return { + [theme.breakpoints.only(breakpoint)]: hidden, + }; + } + return dir === 'up' + ? { + [theme.breakpoints.up(breakpoint)]: hidden, + } + : { + [theme.breakpoints.down(breakpoint)]: hidden, + }; + }) + .reduce((r, o) => { + Object.keys(o).forEach((k) => { + r[k] = o[k]; + }); + return r; + }, {}), + }; +}); + +/** + * @ignore - internal component. + */ +function HiddenCss(props) { + const { children, className, only, ...other } = props; + const theme = useTheme(); + + if (process.env.NODE_ENV !== 'production') { + const unknownProps = Object.keys(other).filter((propName) => { + const isUndeclaredBreakpoint = !theme.breakpoints.keys.some((breakpoint) => { + return `${breakpoint}Up` === propName || `${breakpoint}Down` === propName; + }); + return !['classes', 'theme', 'isRtl', 'sx'].includes(propName) && isUndeclaredBreakpoint; + }); + + if (unknownProps.length > 0) { + console.error( + `Material-UI: Unsupported props received by \`\`: ${unknownProps.join( + ', ', + )}. Did you forget to wrap this component in a ThemeProvider declaring these breakpoints?`, + ); + } + } + + const breakpoints = []; + + for (let i = 0; i < theme.breakpoints.keys.length; i += 1) { + const breakpoint = theme.breakpoints.keys[i]; + const breakpointUp = other[`${breakpoint}Up`]; + const breakpointDown = other[`${breakpoint}Down`]; + + if (breakpointUp) { + breakpoints.push({ breakpoint, dir: 'up' }); + } + if (breakpointDown) { + breakpoints.push({ breakpoint, dir: 'down' }); + } + } + + if (only) { + const onlyBreakpoints = Array.isArray(only) ? only : [only]; + onlyBreakpoints.forEach((breakpoint) => { + breakpoints.push({ breakpoint, dir: 'only' }); + }); + } + + const styleProps = { + ...props, + breakpoints, + }; + + const classes = useUtilityClasses(styleProps); + + return ( + + {children} + + ); +} + +HiddenCss.propTypes = { + /** + * The content of the component. + */ + children: PropTypes.node, + /** + * @ignore + */ + className: PropTypes.string, + /** + * Specify which implementation to use. 'js' is the default, 'css' works better for + * server-side rendering. + */ + implementation: PropTypes.oneOf(['js', 'css']), + /** + * If `true`, screens this size and down are hidden. + */ + lgDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + lgUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + */ + mdDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + mdUp: PropTypes.bool, + /** + * Hide the given breakpoint(s). + */ + only: PropTypes.oneOfType([ + PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), + PropTypes.arrayOf(PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl'])), + ]), + /** + * If `true`, screens this size and down are hidden. + */ + smDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + smUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + */ + xlDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + xlUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + */ + xsDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + xsUp: PropTypes.bool, +}; + +export default HiddenCss; diff --git a/packages/material-ui/src/Hidden/HiddenCss.test.js b/packages/material-ui/src/Hidden/HiddenCss.test.js new file mode 100644 index 00000000000000..2ea1a20b2f2b3c --- /dev/null +++ b/packages/material-ui/src/Hidden/HiddenCss.test.js @@ -0,0 +1,152 @@ +import * as React from 'react'; +import { expect } from 'chai'; +import { createMount, createClientRender } from 'test/utils'; +import HiddenCss from './HiddenCss'; +import { createTheme, MuiThemeProvider } from '../styles'; +import classes from './hiddenCssClasses'; + +const TestChild = () =>
bar
; + +describe('', () => { + /** + * @type {ReturnType} + */ + const mount = createMount(); + const render = createClientRender(); + + describe('the generated class names', () => { + it('should be ok with only', () => { + const { container } = render( + +
+ , + ); + const root = container.firstChild; + + expect(root).to.have.tagName('div'); + expect(root).to.have.class(classes.onlySm); + expect(root.firstChild).to.have.tagName('div'); + expect(root.firstChild).to.have.class('foo'); + }); + + it('should be ok with only as an array', () => { + const { container } = render( + +
+ , + ); + const root = container.firstChild; + + expect(root).to.have.tagName('div'); + expect(root).to.have.class(classes.onlyXs); + expect(root).to.have.class(classes.onlySm); + }); + + it('should be ok with only as an empty array', () => { + const { container } = render( + +
+ , + ); + const root = container.firstChild; + + expect(root).to.have.tagName('div'); + Object.keys(classes).forEach((className) => expect(root).not.to.have.class(className)); + }); + + it('should be ok with mdDown', () => { + const { container } = render( + +
+ , + ); + + expect(container.firstChild).to.have.class(classes.mdDown); + }); + + it('should be ok with mdUp', () => { + const { container } = render( + +
+ , + ); + + expect(container.firstChild).to.have.class(classes.mdUp); + }); + it('should handle provided className prop', () => { + const { container } = render( + +
+ , + ); + + expect(container.firstChild).to.have.class('custom'); + }); + + it('allows custom breakpoints', () => { + const theme = createTheme({ breakpoints: { keys: ['xxl'] } }); + const { container } = render( + + +
+ + , + ); + + expect(container.querySelector('.testid')).to.have.class('xxlUp'); + }); + }); + + describe('prop: children', () => { + it('should work when text Node', () => { + const { container, queryByText } = render(foo); + const root = container.firstChild; + + expect(root).to.have.tagName('div'); + expect(root).to.have.class(classes.mdUp); + expect(queryByText('foo')).not.to.equal(null); + }); + + it('should work when Element', () => { + const { container, queryByTestId } = render( + + + , + ); + const root = container.firstChild; + + expect(root).to.have.tagName('div'); + expect(root).to.have.class(classes.mdUp); + expect(queryByTestId('test-child')).not.to.equal(null); + }); + + it('should work when mixed ChildrenArray', () => { + const { container, queryAllByTestId, queryByText } = render( + + + + foo + , + ); + const root = container.firstChild; + const children = queryAllByTestId('test-child'); + + expect(root).to.have.tagName('div'); + expect(root).to.have.class(classes.mdUp); + expect(children.length).to.equal(2); + expect(queryByText('foo')).not.to.equal(null); + }); + }); + + it('warns about excess props (potentially undeclared breakpoints)', () => { + expect(() => { + mount( + +
+ , + ); + }).toErrorDev( + 'Material-UI: Unsupported props received by ``: xxlUp.', + ); + }); +}); diff --git a/packages/material-ui/src/Hidden/HiddenJs.d.ts b/packages/material-ui/src/Hidden/HiddenJs.d.ts new file mode 100644 index 00000000000000..2782116285689f --- /dev/null +++ b/packages/material-ui/src/Hidden/HiddenJs.d.ts @@ -0,0 +1,21 @@ +import * as React from 'react'; +import { Breakpoint } from '../styles/createBreakpoints'; + +export interface HiddenJsProps { + initialWidth?: Breakpoint; + lgDown?: boolean; + lgUp?: boolean; + mdDown?: boolean; + mdUp?: boolean; + only?: Breakpoint | Breakpoint[]; + smDown?: boolean; + smUp?: boolean; + xlDown?: boolean; + xlUp?: boolean; + xsDown?: boolean; + xsUp?: boolean; +} + +declare const HiddenJs: React.JSXElementConstructor; + +export default HiddenJs; diff --git a/packages/material-ui/src/Hidden/HiddenJs.js b/packages/material-ui/src/Hidden/HiddenJs.js new file mode 100644 index 00000000000000..9d756b7c0c167a --- /dev/null +++ b/packages/material-ui/src/Hidden/HiddenJs.js @@ -0,0 +1,138 @@ +import PropTypes from 'prop-types'; +import { exactProp } from '@material-ui/utils'; +import withWidth, { isWidthDown, isWidthUp } from '../withWidth'; +import useTheme from '../styles/useTheme'; + +/** + * @ignore - internal component. + */ +function HiddenJs(props) { + const { children, only, width } = props; + const theme = useTheme(); + + let visible = true; + + // `only` check is faster to get out sooner if used. + if (only) { + if (Array.isArray(only)) { + for (let i = 0; i < only.length; i += 1) { + const breakpoint = only[i]; + if (width === breakpoint) { + visible = false; + break; + } + } + } else if (only && width === only) { + visible = false; + } + } + + // Allow `only` to be combined with other props. If already hidden, no need to check others. + if (visible) { + // determine visibility based on the smallest size up + for (let i = 0; i < theme.breakpoints.keys.length; i += 1) { + const breakpoint = theme.breakpoints.keys[i]; + const breakpointUp = props[`${breakpoint}Up`]; + const breakpointDown = props[`${breakpoint}Down`]; + if ( + (breakpointUp && isWidthUp(breakpoint, width)) || + (breakpointDown && isWidthDown(breakpoint, width)) + ) { + visible = false; + break; + } + } + } + + if (!visible) { + return null; + } + + return children; +} + +HiddenJs.propTypes = { + /** + * The content of the component. + */ + children: PropTypes.node, + /** + * @ignore + */ + className: PropTypes.string, + /** + * Specify which implementation to use. 'js' is the default, 'css' works better for + * server-side rendering. + */ + implementation: PropTypes.oneOf(['js', 'css']), + /** + * You can use this prop when choosing the `js` implementation with server-side rendering. + * + * As `window.innerWidth` is unavailable on the server, + * we default to rendering an empty component during the first mount. + * You might want to use a heuristic to approximate + * the screen width of the client browser screen width. + * + * For instance, you could be using the user-agent or the client-hints. + * https://caniuse.com/#search=client%20hint + */ + initialWidth: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), + /** + * If `true`, screens this size and down are hidden. + */ + lgDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + lgUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + */ + mdDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + mdUp: PropTypes.bool, + /** + * Hide the given breakpoint(s). + */ + only: PropTypes.oneOfType([ + PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), + PropTypes.arrayOf(PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl'])), + ]), + /** + * If `true`, screens this size and down are hidden. + */ + smDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + smUp: PropTypes.bool, + /** + * @ignore + * width prop provided by withWidth decorator. + */ + width: PropTypes.string.isRequired, + /** + * If `true`, screens this size and down are hidden. + */ + xlDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + xlUp: PropTypes.bool, + /** + * If `true`, screens this size and down are hidden. + */ + xsDown: PropTypes.bool, + /** + * If `true`, screens this size and up are hidden. + */ + xsUp: PropTypes.bool, +}; + +if (process.env.NODE_ENV !== 'production') { + HiddenJs.propTypes = exactProp(HiddenJs.propTypes); +} + +export default withWidth()(HiddenJs); diff --git a/packages/material-ui/src/Hidden/HiddenJs.test.js b/packages/material-ui/src/Hidden/HiddenJs.test.js new file mode 100644 index 00000000000000..75993c82f4b2ef --- /dev/null +++ b/packages/material-ui/src/Hidden/HiddenJs.test.js @@ -0,0 +1,144 @@ +import * as React from 'react'; +import { expect } from 'chai'; +import { createClientRender } from 'test/utils'; +import HiddenJs from './HiddenJs'; + +describe('', () => { + const render = createClientRender(); + + function resolvePropName(upDownOnly, breakpoint) { + if (upDownOnly === 'only') { + return 'only'; + } + + return `${breakpoint}${upDownOnly}`; + } + + function isHidden(hiddenBreakpoints, upDownOnly, width) { + hiddenBreakpoints.forEach((breakpoint) => { + const prop = resolvePropName(upDownOnly, breakpoint); + const descriptions = { + Up: `${prop} is hidden for width: ${width} >= ${breakpoint}`, + Down: `${prop} is hidden for width: ${width} < ${breakpoint}`, + only: `${prop} is hidden for width: ${width} === ${breakpoint}`, + }; + const props = { [prop]: upDownOnly === 'only' ? breakpoint : true }; + + it(descriptions[upDownOnly], () => { + const { container } = render( + +
foo
+
, + ); + + expect(container.firstChild).to.equal(null); + }); + }); + } + + function isVisible(visibleBreakpoints, upDownOnly, width) { + visibleBreakpoints.forEach((breakpoint) => { + const prop = resolvePropName(upDownOnly, breakpoint); + const descriptions = { + Up: `${prop} is visible for width: ${width} < ${breakpoint}`, + Down: `${prop} is visible for width: ${width} >= ${breakpoint}`, + only: `${prop} is visible for width: ${width} !== ${breakpoint}`, + }; + const props = { [prop]: upDownOnly === 'only' ? breakpoint : true }; + + it(descriptions[upDownOnly], () => { + const { container, queryByText } = render( + +
foo
+
, + ); + + expect(container.firstChild).to.have.tagName('div'); + expect(queryByText('foo')).not.to.equal(null); + }); + }); + } + + describe('screen width: xs', () => { + describe('up', () => { + isHidden(['xs'], 'Up', 'xs'); + isVisible(['sm', 'md', 'lg', 'xl'], 'Up', 'xs'); + }); + + describe('down', () => { + isHidden(['sm', 'md', 'lg', 'xl'], 'Down', 'xs'); + isVisible(['xs'], 'Down', 'xs'); + }); + + describe('only', () => { + isHidden(['xs', ['xs', 'xl']], 'only', 'xs'); + isVisible(['sm', 'md', 'lg', 'xl', ['sm', 'md', 'lg', 'xl']], 'only', 'xs'); + }); + }); + + describe('screen width: sm', () => { + describe('up', () => { + isHidden(['xs', 'sm'], 'Up', 'sm'); + isVisible(['md', 'lg', 'xl'], 'Up', 'sm'); + }); + + describe('down', () => { + isHidden(['md', 'lg', 'xl'], 'Down', 'sm'); + isVisible(['xs', 'sm'], 'Down', 'sm'); + }); + + describe('only', () => { + isHidden(['sm', ['sm', 'md']], 'only', 'sm'); + isVisible(['xs', 'md', 'lg', 'xl', ['xs', 'md', 'lg', 'xl']], 'only', 'sm'); + }); + }); + + describe('screen width: md', () => { + describe('up', () => { + isHidden(['xs', 'sm', 'md'], 'Up', 'md'); + isVisible(['lg', 'xl'], 'Up', 'md'); + }); + + describe('down', () => { + isHidden(['lg', 'xl'], 'Down', 'md'); + isVisible(['xs', 'sm', 'md'], 'Down', 'md'); + }); + + describe('only', () => { + isHidden(['md', ['md', 'lg']], 'only', 'md'); + isVisible(['xs', 'sm', 'lg', 'xl', ['xs', 'sm', 'lg', 'xl']], 'only', 'md'); + }); + }); + + describe('screen width: lg', () => { + describe('up', () => { + isHidden(['xs', 'sm', 'md', 'lg'], 'Up', 'lg'); + isVisible(['xl'], 'Up', 'lg'); + }); + + describe('down', () => { + isHidden(['xl'], 'Down', 'lg'); + isVisible(['xs', 'sm', 'md', 'lg'], 'Down', 'lg'); + }); + + describe('only', () => { + isHidden(['lg', ['lg', 'xl']], 'only', 'lg'); + isVisible(['xs', 'sm', 'md', 'xl', ['xs', 'sm', 'md', 'xl']], 'only', 'lg'); + }); + }); + + describe('screen width: xl', () => { + describe('up', () => { + isHidden(['xs', 'sm', 'md', 'lg', 'xl'], 'Up', 'xl'); + }); + + describe('down', () => { + isVisible(['xs', 'sm', 'md', 'lg', 'xl'], 'Down', 'xl'); + }); + + describe('only', () => { + isHidden(['xl', ['xl', 'xs']], 'only', 'xl'); + isVisible(['xs', 'sm', 'md', 'lg', ['xs', 'sm', 'md', 'lg']], 'only', 'xl'); + }); + }); +}); diff --git a/packages/material-ui/src/Hidden/hiddenCssClasses.js b/packages/material-ui/src/Hidden/hiddenCssClasses.js new file mode 100644 index 00000000000000..49003ab415857e --- /dev/null +++ b/packages/material-ui/src/Hidden/hiddenCssClasses.js @@ -0,0 +1,26 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export function getHiddenCssUtilityClass(slot) { + return generateUtilityClass('PrivateHiddenCss', slot); +} + +const hiddenCssClasses = generateUtilityClasses('PrivateHiddenCss', [ + 'root', + 'xlDown', + 'xlUp', + 'onlyXl', + 'lgDown', + 'lgUp', + 'onlyLg', + 'mdDown', + 'mdUp', + 'onlyMd', + 'smDown', + 'smUp', + 'onlySm', + 'xsDown', + 'xsUp', + 'onlyXs', +]); + +export default hiddenCssClasses; diff --git a/packages/material-ui/src/Hidden/index.d.ts b/packages/material-ui/src/Hidden/index.d.ts new file mode 100644 index 00000000000000..3cb2966071530f --- /dev/null +++ b/packages/material-ui/src/Hidden/index.d.ts @@ -0,0 +1,2 @@ +export { default } from './Hidden'; +export * from './Hidden'; diff --git a/packages/material-ui/src/Hidden/index.js b/packages/material-ui/src/Hidden/index.js new file mode 100644 index 00000000000000..b786254d40f3d3 --- /dev/null +++ b/packages/material-ui/src/Hidden/index.js @@ -0,0 +1 @@ +export { default } from './Hidden'; diff --git a/packages/material-ui/src/index.d.ts b/packages/material-ui/src/index.d.ts index 05506035e2a1f4..d086638b6919b4 100644 --- a/packages/material-ui/src/index.d.ts +++ b/packages/material-ui/src/index.d.ts @@ -225,6 +225,9 @@ export * from './Grid'; export { default as Grow } from './Grow'; export * from './Grow'; +export { default as Hidden } from './Hidden'; +export * from './Hidden'; + export { default as Icon } from './Icon'; export * from './Icon'; diff --git a/packages/material-ui/src/index.js b/packages/material-ui/src/index.js index 720a0ffa70ba5b..6783fbbb0161f6 100644 --- a/packages/material-ui/src/index.js +++ b/packages/material-ui/src/index.js @@ -158,6 +158,9 @@ export * from './Grid'; export { default as Grow } from './Grow'; export * from './Grow'; +export { default as Hidden } from './Hidden'; +export * from './Hidden'; + export { default as Icon } from './Icon'; export * from './Icon';