diff --git a/CHANGELOG.md b/CHANGELOG.md index 100f640b796..afac6696318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ - Added more color options to `EuiButtonIcon` ([#907](https://github.com/elastic/eui/pull/907)) - Added icon for EMS (Elastic Map Service) (`emsApp`) ([#914](https://github.com/elastic/eui/pull/914)) - Added support for `href`, `target`, and `rel` properties for `EuiContextMenu` items ([#911](https://github.com/elastic/eui/pull/911)) +- Added responsive helpers in the form of `EuiShowFor` and `EuiHideFor` components and corresponding CSS classes. ([#909](https://github.com/elastic/eui/pull/909)) + +**Deprecations** + +- Replaced `$breakpoints` in favor of better named `$euiBreakpoints` ([#909](https://github.com/elastic/eui/pull/909)) +- Replaced the following mixin `screenXSmall()`, `screenSmall()`, `screenMedium()`, `screenLarge()`, `screenSmallMediumLarge()` in favor of a single `euiBreakpoint()`. ([#909](https://github.com/elastic/eui/pull/909)) **Bug fixes** diff --git a/src-docs/src/components/guide_components.scss b/src-docs/src/components/guide_components.scss index 4905de52968..e01fc8ab0dc 100644 --- a/src-docs/src/components/guide_components.scss +++ b/src-docs/src/components/guide_components.scss @@ -174,7 +174,7 @@ $guideZLevelHighest: $euiZLevel9 + 1000; @import "guide_section/index"; @import "guide_rule/index"; -@include screenXSmall { +@include euiBreakpoint('xs','s') { .guideBody { background: none; diff --git a/src-docs/src/routes.js b/src-docs/src/routes.js index cae4d6180bd..2b4839ba7f7 100644 --- a/src-docs/src/routes.js +++ b/src-docs/src/routes.js @@ -174,6 +174,9 @@ import { PortalExample } import { ProgressExample } from './views/progress/progress_example'; + import { ResponsiveExample } + from './views/responsive/responsive_example'; + import { SearchBarExample } from './views/search_bar/search_bar_example'; @@ -341,6 +344,7 @@ const navigation = [{ name: 'Utilities', items: [ AccessibilityExample, + ResponsiveExample, DelayHideExample, ErrorBoundaryExample, HighlightExample, diff --git a/src-docs/src/views/responsive/responsive.js b/src-docs/src/views/responsive/responsive.js new file mode 100644 index 00000000000..02cbeb83e99 --- /dev/null +++ b/src-docs/src/views/responsive/responsive.js @@ -0,0 +1,46 @@ +import React from 'react'; + +import { + EuiCode, + EuiHideFor, + EuiShowFor, +} from '../../../../src/components'; + +export default () => ( +
+ + Hiding from xs screens only + +
+ + Hiding from xs, s screens + +
+ + Hiding from xs, s, m, l screens + +
+ + Hiding from xl screens only + + +
+
+ + + Showing for xs screens only + +
+ + Showing for xs, s screens + +
+ + Showing for xs, s, m, l screens + +
+ + Showing for xl screen only + +
+); diff --git a/src-docs/src/views/responsive/responsive_example.js b/src-docs/src/views/responsive/responsive_example.js new file mode 100644 index 00000000000..2dbe1a65ae9 --- /dev/null +++ b/src-docs/src/views/responsive/responsive_example.js @@ -0,0 +1,71 @@ +import React from 'react'; + +import { renderToHtml } from '../../services'; +import sizes from '!!sass-vars-to-js-loader!../../../../src/global_styling/variables/_responsive.scss'; + +import { + GuideSectionTypes, +} from '../../components'; + +import { + EuiCode, + EuiShowFor, + EuiHideFor, + EuiCodeBlock, +} from '../../../../src/components'; + +import Responsive from './responsive'; +const responsiveSource = require('!!raw-loader!./responsive'); +const responsiveHtml = renderToHtml(Responsive); + +function renderSizes(size, index) { + let code = `'${size}': ${sizes.euiBreakpoints[size]}px`; + + if (index < sizes.euiBreakpointKeys.length - 1) { + code += ` (to ${(sizes.euiBreakpoints[sizes.euiBreakpointKeys[index+1]] - 1)}px)`; + } else { + code += ` +`; + } + + return ( +
+ {code} +
+ ) +} + +export const ResponsiveExample = { + title: 'Responsive', + sections: [{ + title: 'EuiShowFor and EuiHideFor', + source: [{ + type: GuideSectionTypes.JS, + code: responsiveSource, + }, { + type: GuideSectionTypes.HTML, + code: responsiveHtml, + }], + text: ( +
+

+ Pass an array of named breakpoints to either + the EuiShowFor or EuiHideFor components + to make them responsive. +

+ +

+ The sizing correlates with our $euiBreakpoints SASS map. The named + breakpoint starts at the pixel value provided and ends before the next one. +

+ + + {sizes.euiBreakpointKeys.map(function (size, index) { + return renderSizes(size, index); + })} + +
+ ), + props: { EuiShowFor, EuiHideFor }, + demo: , + }], +}; diff --git a/src-docs/src/views/utility_classes/utility_classes.js b/src-docs/src/views/utility_classes/utility_classes.js index f4aad5ed3e5..ff5f1b68bf3 100644 --- a/src-docs/src/views/utility_classes/utility_classes.js +++ b/src-docs/src/views/utility_classes/utility_classes.js @@ -93,5 +93,30 @@ export default () => ( .eui-displayInlineBlock +

Responsive

+ + .eui-hideFor--xs + + .eui-hideFor--s + + .eui-hideFor--m + + .eui-hideFor--l + + .eui-hideFor--xl + + + + .eui-showFor--xs + + .eui-showFor--s + + .eui-showFor--m + + .eui-showFor--l + + .eui-showFor--xl + + ); diff --git a/src/components/breadcrumbs/_breadcrumbs.scss b/src/components/breadcrumbs/_breadcrumbs.scss index c150e59e000..7fba6ac2206 100644 --- a/src/components/breadcrumbs/_breadcrumbs.scss +++ b/src/components/breadcrumbs/_breadcrumbs.scss @@ -30,7 +30,7 @@ .euiBreadcrumbs--responsive { // Laptop - @include screenMedium { + @include euiBreakpoint('l') { .euiBreadcrumbSeparator, .euiBreadcrumb { display: none; @@ -43,7 +43,7 @@ } // Tablets - @include screenSmall { + @include euiBreakpoint('m') { .euiBreadcrumbSeparator, .euiBreadcrumb { display: none; @@ -56,7 +56,7 @@ } // Mobile - @include screenXSmall { + @include euiBreakpoint('xs','s') { .euiBreadcrumbSeparator, .euiBreadcrumb { display: none; diff --git a/src/components/button/button_group/_button_group.scss b/src/components/button/button_group/_button_group.scss index 8d9b5922f18..22d8e1cb9e3 100644 --- a/src/components/button/button_group/_button_group.scss +++ b/src/components/button/button_group/_button_group.scss @@ -60,7 +60,7 @@ border-bottom-right-radius: $euiBorderRadius; } - @include screenXSmall(){ + @include euiBreakpoint('xs','s'){ flex: 1; min-width: 0; diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index 3509710fec5..856f6e9912a 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -586,7 +586,7 @@ } // We drop the time picker on mobile. They can still type in the time directly. -@include screenXSmall { +@include euiBreakpoint('xs','s') { .react-datepicker__time-container { display: none; } diff --git a/src/components/flex/_flex_group.scss b/src/components/flex/_flex_group.scss index 599ce499437..5c18dba489e 100644 --- a/src/components/flex/_flex_group.scss +++ b/src/components/flex/_flex_group.scss @@ -96,7 +96,7 @@ $gutterTypes: ( flex-wrap: wrap; } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiFlexGroup--responsive { flex-wrap: wrap; margin-left: 0; diff --git a/src/components/flex/_flex_item.scss b/src/components/flex/_flex_item.scss index cb64e19bd25..7eddf8002e2 100644 --- a/src/components/flex/_flex_item.scss +++ b/src/components/flex/_flex_item.scss @@ -22,7 +22,7 @@ } // On mobile we force them to stack and act the same. -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiFlexGroup--responsive > .euiFlexItem, .euiFlexGrid > .euiFlexItem { width: 100% !important; diff --git a/src/components/flyout/_flyout.scss b/src/components/flyout/_flyout.scss index fb8014644a1..69254d23f9d 100644 --- a/src/components/flyout/_flyout.scss +++ b/src/components/flyout/_flyout.scss @@ -21,15 +21,15 @@ $euiFlyoutBorderColor: tintOrShade($euiShadowColorLarge, 50%, 0%) !default; // m */ $flyoutSizes: ( "small": ( - min: map-get($breakpoints, "small") * .5, /* 1 */ + min: map-get($euiBreakpoints, "m") * .5, /* 1 */ width: 25vw ), "medium": ( - min: map-get($breakpoints, "small") * .7, /* 1 */ + min: map-get($euiBreakpoints, "m") * .7, /* 1 */ width: 50vw ), "large": ( - min: map-get($breakpoints, "small") * .9, /* 1 */ + min: map-get($euiBreakpoints, "m") * .9, /* 1 */ width: 75vw ) ); @@ -52,7 +52,7 @@ $flyoutSizes: ( } } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiFlyout:not(.euiFlyout--small) { /* 2 */ left: 0; min-width: 0; diff --git a/src/components/form/described_form_group/_described_form_group.scss b/src/components/form/described_form_group/_described_form_group.scss index af35b7b59b8..541b2bcd5de 100644 --- a/src/components/form/described_form_group/_described_form_group.scss +++ b/src/components/form/described_form_group/_described_form_group.scss @@ -39,7 +39,7 @@ } } - @include screenXSmall { + @include euiBreakpoint('xs','s') { .euiDescribedFormGroup__fields { padding-top: 0; diff --git a/src/components/header/_header_logo.scss b/src/components/header/_header_logo.scss index 82886f72fea..0e787f8d3f0 100644 --- a/src/components/header/_header_logo.scss +++ b/src/components/header/_header_logo.scss @@ -28,7 +28,7 @@ padding-left: $euiSize; font-weight: $euiFontWeightLight; - @include screenXSmall() { + @include euiBreakpoint('xs','s') { @include euiTitle("xxs"); font-weight: $euiFontWeightLight; } diff --git a/src/components/header/header_links/_header_links.scss b/src/components/header/header_links/_header_links.scss index 0fff5ae9d07..ec9e3829c5f 100644 --- a/src/components/header/header_links/_header_links.scss +++ b/src/components/header/header_links/_header_links.scss @@ -11,7 +11,7 @@ white-space: nowrap; overflow: hidden; - @include screenXSmall(){ + @include euiBreakpoint('xs','s'){ display: none; } } @@ -21,7 +21,7 @@ position: absolute !important; // override popover relative right: 0; - @include screenXSmall(){ + @include euiBreakpoint('xs','s'){ display: block !important; } } diff --git a/src/components/index.js b/src/components/index.js index 9b6ca6ccd9d..2c41840fd58 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -307,3 +307,9 @@ export { EuiIconTip, EuiToolTip, } from './tool_tip'; + +export { + EuiHideFor, + EuiShowFor, +} from './responsive'; + diff --git a/src/components/modal/_modal.scss b/src/components/modal/_modal.scss index 349b1c814f3..5d408714aa8 100644 --- a/src/components/modal/_modal.scss +++ b/src/components/modal/_modal.scss @@ -84,7 +84,7 @@ $euiModalBorderColor: tintOrShade($euiShadowColorLarge, 50%, 0%) !default; // ma } // On mobile we fix modals as a takeover. -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiModal { position: fixed; width: calc(100vw + 2px); diff --git a/src/components/page/page_body/_page_body.scss b/src/components/page/page_body/_page_body.scss index b465ea11474..1ad87fdd38e 100644 --- a/src/components/page/page_body/_page_body.scss +++ b/src/components/page/page_body/_page_body.scss @@ -5,7 +5,7 @@ min-height: 400px; // Temporary till we have a better doc system. } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageBody { flex-direction: column; } diff --git a/src/components/page/page_content/_page_content.scss b/src/components/page/page_content/_page_content.scss index bb49966587d..72758807415 100644 --- a/src/components/page/page_content/_page_content.scss +++ b/src/components/page/page_content/_page_content.scss @@ -13,7 +13,7 @@ } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageContent { border-radius: 0; border: none; diff --git a/src/components/page/page_content/_page_content_header.scss b/src/components/page/page_content/_page_content_header.scss index ab3cf45431d..756205ff562 100644 --- a/src/components/page/page_content/_page_content_header.scss +++ b/src/components/page/page_content/_page_content_header.scss @@ -6,7 +6,7 @@ align-items: center; } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageContentHeader { flex-direction: column; } diff --git a/src/components/page/page_content/_page_content_header_section.scss b/src/components/page/page_content/_page_content_header_section.scss index 33252b0ed07..218dbdb1583 100644 --- a/src/components/page/page_content/_page_content_header_section.scss +++ b/src/components/page/page_content/_page_content_header_section.scss @@ -5,7 +5,7 @@ } } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageContentHeaderSection { width: 100%; diff --git a/src/components/page/page_header/_page_header.scss b/src/components/page/page_header/_page_header.scss index 048d586b4d3..2b475b7a6ed 100644 --- a/src/components/page/page_header/_page_header.scss +++ b/src/components/page/page_header/_page_header.scss @@ -6,7 +6,7 @@ align-items: center; } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageHeader { flex-direction: column; padding: 0 $euiSize; diff --git a/src/components/page/page_header/_page_header_section.scss b/src/components/page/page_header/_page_header_section.scss index 4cfcf237759..dddf6e0b550 100644 --- a/src/components/page/page_header/_page_header_section.scss +++ b/src/components/page/page_header/_page_header_section.scss @@ -4,7 +4,7 @@ margin-left: $euiSizeXL; } } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageHeaderSection { width: 100%; diff --git a/src/components/page/page_side_bar/_page_side_bar.scss b/src/components/page/page_side_bar/_page_side_bar.scss index 55157b880b7..74f0a3d387a 100644 --- a/src/components/page/page_side_bar/_page_side_bar.scss +++ b/src/components/page/page_side_bar/_page_side_bar.scss @@ -7,7 +7,7 @@ margin-right: $euiSizeL; } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPageSideBar { width: 100%; } diff --git a/src/components/pagination/_pagination_button.scss b/src/components/pagination/_pagination_button.scss index f3ffdd1457c..421786f877f 100644 --- a/src/components/pagination/_pagination_button.scss +++ b/src/components/pagination/_pagination_button.scss @@ -17,7 +17,7 @@ cursor: default; } -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiPaginationButton--hideOnMobile { display: none; } diff --git a/src/components/responsive/__snapshots__/hide_from.test.js.snap b/src/components/responsive/__snapshots__/hide_from.test.js.snap new file mode 100644 index 00000000000..9795956dd66 --- /dev/null +++ b/src/components/responsive/__snapshots__/hide_from.test.js.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EuiHideFor l is rendered 1`] = ` + +`; + +exports[`EuiHideFor m is rendered 1`] = ` + +`; + +exports[`EuiHideFor s is rendered 1`] = ` + +`; + +exports[`EuiHideFor xl is rendered 1`] = ` + +`; + +exports[`EuiHideFor xs is rendered 1`] = ` + +`; diff --git a/src/components/responsive/__snapshots__/show_for.test.js.snap b/src/components/responsive/__snapshots__/show_for.test.js.snap new file mode 100644 index 00000000000..64a350a9654 --- /dev/null +++ b/src/components/responsive/__snapshots__/show_for.test.js.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EuiShowFor l is rendered 1`] = ` + +`; + +exports[`EuiShowFor m is rendered 1`] = ` + +`; + +exports[`EuiShowFor s is rendered 1`] = ` + +`; + +exports[`EuiShowFor xl is rendered 1`] = ` + +`; + +exports[`EuiShowFor xs is rendered 1`] = ` + +`; diff --git a/src/components/responsive/hide_from.js b/src/components/responsive/hide_from.js new file mode 100644 index 00000000000..fc3d3e1ac6d --- /dev/null +++ b/src/components/responsive/hide_from.js @@ -0,0 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +const responsiveSizesToClassNameMap = { + xs: 'eui-hideFor--xs', + s: 'eui-hideFor--s', + m: 'eui-hideFor--m', + l: 'eui-hideFor--l', + xl: 'eui-hideFor--xl', +} + +export const RESPONSIVE_SIZES = Object.keys(responsiveSizesToClassNameMap); + +export const EuiHideFor = ({ + children, + className, + sizes, + ...rest, +}) => { + + const sizingClasses = sizes.map(function(item){ + return responsiveSizesToClassNameMap[item]; + }); + + const classes = classNames( + 'euiHideFor', + sizingClasses, + className + ); + + return ( + + {children} + + ); +}; + +EuiHideFor.propTypes = { + children: PropTypes.node, + className: PropTypes.string, + /** + * List of all the responsive sizes to hide the children from + */ + sizes: PropTypes.arrayOf(PropTypes.oneOf(RESPONSIVE_SIZES)).isRequired, +}; diff --git a/src/components/responsive/hide_from.test.js b/src/components/responsive/hide_from.test.js new file mode 100644 index 00000000000..cecd8623d12 --- /dev/null +++ b/src/components/responsive/hide_from.test.js @@ -0,0 +1,18 @@ +import React from 'react'; +import { render } from 'enzyme'; +import { requiredProps } from '../../test'; + +import { RESPONSIVE_SIZES, EuiHideFor } from './hide_from'; + +describe('EuiHideFor', () => { + RESPONSIVE_SIZES.forEach(size => { + test(`${size} is rendered`, () => { + const component = render( + + ); + + expect(component) + .toMatchSnapshot(); + }); + }); +}); diff --git a/src/components/responsive/index.js b/src/components/responsive/index.js new file mode 100644 index 00000000000..7365d058188 --- /dev/null +++ b/src/components/responsive/index.js @@ -0,0 +1,7 @@ +export { + EuiHideFor, +} from './hide_from'; + +export { + EuiShowFor, +} from './show_for'; diff --git a/src/components/responsive/show_for.js b/src/components/responsive/show_for.js new file mode 100644 index 00000000000..31f0379d4ee --- /dev/null +++ b/src/components/responsive/show_for.js @@ -0,0 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +const responsiveSizesToClassNameMap = { + xs: 'eui-showFor--xs', + s: 'eui-showFor--s', + m: 'eui-showFor--m', + l: 'eui-showFor--l', + xl: 'eui-showFor--xl', +} + +export const RESPONSIVE_SIZES = Object.keys(responsiveSizesToClassNameMap); + +export const EuiShowFor = ({ + children, + className, + sizes, + ...rest, +}) => { + + const sizingClasses = sizes.map(function(item){ + return responsiveSizesToClassNameMap[item]; + }); + + const classes = classNames( + 'euiShowFor', + sizingClasses, + className + ); + + return ( + + {children} + + ); +}; + +EuiShowFor.propTypes = { + children: PropTypes.node, + className: PropTypes.string, + /** + * List of all the responsive sizes to show the children for + */ + sizes: PropTypes.arrayOf(PropTypes.oneOf(RESPONSIVE_SIZES)).isRequired, +}; diff --git a/src/components/responsive/show_for.test.js b/src/components/responsive/show_for.test.js new file mode 100644 index 00000000000..fb70c3208c6 --- /dev/null +++ b/src/components/responsive/show_for.test.js @@ -0,0 +1,18 @@ +import React from 'react'; +import { render } from 'enzyme'; +import { requiredProps } from '../../test'; + +import { RESPONSIVE_SIZES, EuiShowFor } from './show_for'; + +describe('EuiShowFor', () => { + RESPONSIVE_SIZES.forEach(size => { + test(`${size} is rendered`, () => { + const component = render( + + ); + + expect(component) + .toMatchSnapshot(); + }); + }); +}); diff --git a/src/components/side_nav/_side_nav.scss b/src/components/side_nav/_side_nav.scss index 7c9b51524ee..2240ed6aa2f 100644 --- a/src/components/side_nav/_side_nav.scss +++ b/src/components/side_nav/_side_nav.scss @@ -45,7 +45,7 @@ top: $euiSizeXL; } -@include screenXSmall { +@include euiBreakpoint('xs','s') { /** * 1. Animation doesn't work against height. Need max-height instead. * We set a value larger than what is needed to fake "auto". diff --git a/src/components/steps/_steps_horizontal.scss b/src/components/steps/_steps_horizontal.scss index 6536d5738a5..ae58f5585b4 100644 --- a/src/components/steps/_steps_horizontal.scss +++ b/src/components/steps/_steps_horizontal.scss @@ -132,7 +132,7 @@ } // RESPONSIVE -@include screenXSmall { +@include euiBreakpoint('xs','s') { .euiStepHorizontal { // reduce top padding and shift lines padding-top: $euiSize; diff --git a/src/components/table/_responsive.scss b/src/components/table/_responsive.scss index 4f316ac5e1c..20bc267e814 100644 --- a/src/components/table/_responsive.scss +++ b/src/components/table/_responsive.scss @@ -1,6 +1,6 @@ @import '../panel/mixins'; -@include screenXSmall(){ +@include euiBreakpoint('xs','s'){ .euiTable.euiTable--responsive { // Not allowing compressed styles in mobile view (for now) diff --git a/src/components/table/_table.scss b/src/components/table/_table.scss index 35a887f2eb6..0c96b2029fd 100644 --- a/src/components/table/_table.scss +++ b/src/components/table/_table.scss @@ -13,7 +13,7 @@ } // Compressed styles not for mobile -@include screenSmallMediumLarge { +@include euiBreakpoint('m','l','xl') { .euiTable--compressed { .euiTableCellContent { @include euiFontSizeXS; diff --git a/src/components/table/mobile/_mobile.scss b/src/components/table/mobile/_mobile.scss index b99ee69da43..b449e9505a4 100644 --- a/src/components/table/mobile/_mobile.scss +++ b/src/components/table/mobile/_mobile.scss @@ -4,7 +4,7 @@ display: none; } -@include screenXSmall(){ +@include euiBreakpoint('xs','s'){ .euiTableHeaderMobile { display: flex; diff --git a/src/components/toast/_global_toast_list.scss b/src/components/toast/_global_toast_list.scss index 12c13474ede..817bb2ff58c 100644 --- a/src/components/toast/_global_toast_list.scss +++ b/src/components/toast/_global_toast_list.scss @@ -55,7 +55,7 @@ } } -@include screenXSmall { +@include euiBreakpoint('xs','s') { /** * 1. Mobile we make these 100%. Matching change happens on the item as well. */ diff --git a/src/global_styling/mixins/_responsive.scss b/src/global_styling/mixins/_responsive.scss index c3123b65735..1c847d75afd 100644 --- a/src/global_styling/mixins/_responsive.scss +++ b/src/global_styling/mixins/_responsive.scss @@ -1,34 +1,96 @@ -// Responsiveness +@import '../variables/responsive'; + +// A sem-complicated mixin for breakpoints, that takes any number of +// named breakpoints that exists in $euiBreakpoints. + +@mixin euiBreakpoint($sizes...) { + // Loop through each size parameter + @each $size in $sizes { + // Store the location of the size in the list to check against + $index: index($euiBreakpointKeys, $size); + + // Check to make sure it exists in the allowed breakpoint names + @if ( $index ) { + + // Set the min size to the value of the size + $minSize: map-get($euiBreakpoints, $size); + + // If it is the last item, don't give it a max-width + @if ( $index == length($euiBreakpointKeys) ) { + @media only screen and (min-width: $minSize) { + @content; + } + } + + // If it's not the last item, add a max-width + @else { + + // Set the max size to the value of the next size (-1px as to not overlap) + $maxSize: map-get($euiBreakpoints, nth($euiBreakpointKeys, $index + 1)) - 1px; + + // If it's the the first item, don't set a min-width + @if ( $index == 1 ) { + @media only screen and (max-width: $maxSize) { + @content; + } + } + + // Otherwise it should have a min and max width + @else { + @media only screen and (min-width: $minSize) and (max-width: $maxSize) { + @content; + } + } + } + } + + // If it's not a known breakpoint, throw a warning + @else { + @warn 'euiBreakpoint(): "#{$size}" is not a valid size in $euiBreakpoints. + The acceptable values are "#{$euiBreakpointKeys}"'; + } + } +} + + +//** DEPRECATED **// +//** DEPRECATED **// +//** DEPRECATED **// +//** DEPRECATED **// $breakpoints: ("xSmall": 575px, "small": 768px, "medium": 992px, "large": 1200px) !default; @mixin screenXSmall { + @warn "screenXSmall() has been deprecated. Please use euiBreakpoint('xs','s') instead."; @media only screen and (max-width: map-get($breakpoints, "small")) { @content; } } - @mixin screenSmall { + @warn "screenSmall() has been deprecated. Please use euiBreakpoint('m') instead."; @media only screen and (min-width: map-get($breakpoints, "small") + 1) and (max-width: map-get($breakpoints, "medium") - 1) { @content; } } @mixin screenMedium { + @warn "screenMedium() has been deprecated. Please use euiBreakpoint('l') instead."; @media only screen and (min-width: map-get($breakpoints, "medium")) and (max-width: map-get($breakpoints, "large") - 1) { @content; } } @mixin screenLarge { + @warn "screenLarge() has been deprecated. Please use euiBreakpoint('xl') instead."; @media only screen and (min-width: map-get($breakpoints, "large")) { @content; } } @mixin screenSmallMediumLarge { + @warn "screenSmallMediumLarge() has been deprecated. Please use euiBreakpoint('m','l','xl') instead."; @media only screen and (min-width: map-get($breakpoints, "small")) { @content; } diff --git a/src/global_styling/utility/_utility.scss b/src/global_styling/utility/_utility.scss index c3bef018aef..10ab91659b8 100644 --- a/src/global_styling/utility/_utility.scss +++ b/src/global_styling/utility/_utility.scss @@ -40,3 +40,24 @@ white-space: nowrap !important; word-wrap: normal !important; /* 2 */ } + +/** + * Responsive + * + * 3. Be sure to hide/show the element initially + */ +[class*="eui-hideFor"] { + display: initial !important; /* 3 */ +} +[class*="eui-showFor"] { + display: none !important; /* 3 */ +} + +@each $size in $euiBreakpointKeys { + .eui-hideFor--#{$size} { + @include euiBreakpoint($size) { display: none !important; } + } + .eui-showFor--#{$size} { + @include euiBreakpoint($size) { display: initial !important; } + } +} diff --git a/src/global_styling/variables/_responsive.scss b/src/global_styling/variables/_responsive.scss new file mode 100644 index 00000000000..24afb52f981 --- /dev/null +++ b/src/global_styling/variables/_responsive.scss @@ -0,0 +1,9 @@ +$euiBreakpoints: ( + "xs": 0px, + "s": 575px, + "m": 768px, + "l": 992px, + "xl": 1200px +) !default; + +$euiBreakpointKeys: map-keys($euiBreakpoints); diff --git a/yarn.lock b/yarn.lock index 79fcd2775b7..fcb7da39fe3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2888,10 +2888,6 @@ es6-promise@^3.0.2: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" -es6-promise@^4.0.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" - es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" @@ -3681,14 +3677,6 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - fs-extra@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" @@ -4212,13 +4200,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" -hasha@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-2.2.0.tgz#78d7cbfc1e6d66303fe79837365984517b2f6ee1" - dependencies: - is-stream "^1.0.1" - pinkie-promise "^2.0.0" - hawk@3.1.3, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -7146,20 +7127,6 @@ performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" -phantomjs-prebuilt@^2.1.16: - version "2.1.16" - resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz#efd212a4a3966d3647684ea8ba788549be2aefef" - dependencies: - es6-promise "^4.0.3" - extract-zip "^1.6.5" - fs-extra "^1.0.0" - hasha "^2.2.0" - kew "^0.7.0" - progress "^1.1.8" - request "^2.81.0" - request-progress "^2.0.1" - which "^1.2.10" - pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -7617,10 +7584,6 @@ progress@2.0.0, progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" -progress@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" - promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -8243,12 +8206,6 @@ replace-ext@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" -request-progress@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-2.0.1.tgz#5d36bb57961c673aa5b788dbc8141fdf23b44e08" - dependencies: - throttleit "^1.0.0" - request-promise-core@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" @@ -9435,10 +9392,6 @@ throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" -throttleit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" - through2@^2.0.0, through2@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"