Skip to content

Commit

Permalink
[CSS-in-JS] Fix EUI media queries to more flexibly account for custom…
Browse files Browse the repository at this point in the history
… breakpoints (elastic#6431)

* Create `euiMinBreakpoint` and `euiMaxBreakpoint` utilities

- for better future-proofing for consumers who add custom (e.g.) `xxl`/`xxs` breakpoints

* [Docs] Add docs example

* Update simple components to use new min/max breakpoint util

* [REVERT ME] Test observability app use case w/ flyouts

- set screen size to 2400 px to see bug

* [EuiFlyout] Fix responsive media queries to work with custom breakpoints

+ query organization - move smaller/mobile styles before larger desktop styles

* changelog

* wording is hard

* Revert "[REVERT ME] Test observability app use case w/ flyouts"

This reverts commit aff41f9.

* Fix incorrect mobile margins on `responsiveColumn` `EuiDescriptionList`s

* [EuiToastList] Clean up unnecessarily convoluted CSS

- base padding is already set on the base CSS, so using min-width means we don't have 2 unnecessary overrides

- use nesting instead of repeating :not:empty selectors

- not even sure what is going on with that euiToastWidth math
  • Loading branch information
Cee authored and cee-chen committed Nov 23, 2022
1 parent 4131e65 commit 178a0ba
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 72 deletions.
59 changes: 46 additions & 13 deletions src-docs/src/views/theme/breakpoints/_breakpoints_js.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
EuiCode,
EuiText,
useEuiBreakpoint,
useEuiMaxBreakpoint,
useEuiMinBreakpoint,
useCurrentEuiBreakpoint,
useIsWithinBreakpoints,
useIsWithinMaxBreakpoint,
Expand Down Expand Up @@ -110,19 +112,10 @@ useIsWithinMinBreakpoint('s')`}
title={<code>useEuiBreakpoint(sizes[])</code>}
type="hook"
description={
<>
<p>
Given an array of breakpoint keys, this hook generates a CSS media
query string based on the minimum width and maximum width
provided.
</p>
<p>
You can also create media queries with a{' '}
<EuiCode>(max-width)</EuiCode> only or{' '}
<EuiCode>(min-width)</EuiCode> only by utilizing the{' '}
<EuiCode>xs</EuiCode> and <EuiCode>xl</EuiCode> arguments.
</p>
</>
<p>
Given an array of screen sizes, this hook generates a CSS media
query string based on the minimum and maximum screen sizes provided.
</p>
}
example={
<p
Expand Down Expand Up @@ -157,6 +150,46 @@ useIsWithinMinBreakpoint('s')`}
}
\${useEuiBreakpoint(['l', 'xl'])} {
color: green;
}`}
snippetLanguage="emotion"
/>

<ThemeExample
title={
<>
<code>useEuiMaxBreakpoint(size)</code>
<br />
<code>useEuiMinBreakpoint(size)</code>
</>
}
type="hook"
description={
<p>
Given a single breakpoint key, these hooks generate a min or max CSS
media query string based on the single breakpoint dimension
returned.
</p>
}
example={
<p
css={css`
${useEuiMaxBreakpoint('m')} {
color: ${euiTheme.colors.dangerText};
}
${useEuiMinBreakpoint('m')} {
color: ${euiTheme.colors.successText};
}
`}
>
This text is red on screens below the medium breakpoint, and green
on screens above.
</p>
}
snippet={`\${useEuiMaxBreakpoint('m')} {
color: red;
}
\${useEuiMinBreakpoint('m')} {
color: green;
}`}
snippetLanguage="emotion"
/>
Expand Down
4 changes: 2 additions & 2 deletions src/components/description_list/description_list.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { css } from '@emotion/react';
import { logicalTextAlignCSS, euiBreakpoint } from '../../global_styling';
import { logicalTextAlignCSS, euiMinBreakpoint } from '../../global_styling';
import { UseEuiTheme } from '../../services';

export const euiDescriptionListStyles = (euiThemeContext: UseEuiTheme) => {
Expand All @@ -29,7 +29,7 @@ export const euiDescriptionListStyles = (euiThemeContext: UseEuiTheme) => {
`,
// Responsive columns behave as a row on breakpoints xs-s
responsiveColumn: css`
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${euiMinBreakpoint(euiThemeContext, 'm')} {
${columnDisplay}
}
`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import { css } from '@emotion/react';
import {
euiFontSize,
euiBreakpoint,
euiMaxBreakpoint,
euiMinBreakpoint,
logicalTextAlignCSS,
logicalCSS,
} from '../../global_styling';
Expand All @@ -35,11 +36,11 @@ export const euiDescriptionListDescriptionStyles = (
${columnDisplay}
`,
responsiveColumn: css`
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
${logicalCSS('width', '100%')}
padding: 0;
}
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${euiMinBreakpoint(euiThemeContext, 'm')} {
${columnDisplay}
}
`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React, { HTMLAttributes, FunctionComponent, useContext } from 'react';
import classNames from 'classnames';
import { CommonProps } from '../common';
import { useEuiTheme } from '../../services';
import { useEuiTheme, useIsWithinMinBreakpoint } from '../../services';
import { euiDescriptionListDescriptionStyles } from './description_list_description.styles';
import { EuiDescriptionListContext } from './description_list_context';

Expand All @@ -26,6 +26,7 @@ export const EuiDescriptionListDescription: FunctionComponent<EuiDescriptionList
const { type, textStyle, compressed, align, gutterSize } = useContext(
EuiDescriptionListContext
);
const showResponsiveColumns = useIsWithinMinBreakpoint('m');

const theme = useEuiTheme();
const styles = euiDescriptionListDescriptionStyles(theme);
Expand All @@ -47,7 +48,9 @@ export const EuiDescriptionListDescription: FunctionComponent<EuiDescriptionList
if (align === 'center') {
conditionalStyles.push(styles.left);
}
conditionalStyles.push(styles[gutterSize]);
if (type === 'column' || showResponsiveColumns) {
conditionalStyles.push(styles[gutterSize]);
}
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
euiFontSize,
euiTextBreakWord,
logicalTextAlignCSS,
euiBreakpoint,
euiMaxBreakpoint,
euiMinBreakpoint,
logicalCSS,
} from '../../global_styling';
import { tint, UseEuiTheme } from '../../services';
Expand All @@ -35,11 +36,11 @@ export const euiDescriptionListTitleStyles = (euiThemeContext: UseEuiTheme) => {
${columnDisplay}
`,
responsiveColumn: css`
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
${logicalCSS('width', '100%')}
padding: 0;
}
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${euiMinBreakpoint(euiThemeContext, 'm')} {
${columnDisplay}
}
`,
Expand Down
31 changes: 16 additions & 15 deletions src/components/flyout/flyout.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { css, keyframes } from '@emotion/react';
import { _EuiFlyoutPaddingSize, EuiFlyoutSize } from './flyout';
import {
euiCanAnimate,
euiBreakpoint,
euiMaxBreakpoint,
euiMinBreakpoint,
logicalCSS,
mathWithUnits,
} from '../../global_styling';
Expand Down Expand Up @@ -66,22 +67,22 @@ export const euiFlyoutCloseButtonStyles = (euiThemeContext: UseEuiTheme) => {
right: css`
${logicalCSS('left', 0)}
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
transform: translateX(calc(-100% - ${euiTheme.size.l})) !important;
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
transform: translateX(calc(-100% - ${euiTheme.size.xs})) !important;
}
${euiMinBreakpoint(euiThemeContext, 'm')} {
transform: translateX(calc(-100% - ${euiTheme.size.l})) !important;
}
`,
left: css`
${logicalCSS('right', 0)}
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
transform: translateX(calc(100% + ${euiTheme.size.l})) !important;
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
transform: translateX(calc(100% + ${euiTheme.size.xs})) !important;
}
${euiMinBreakpoint(euiThemeContext, 'm')} {
transform: translateX(calc(100% + ${euiTheme.size.l})) !important;
}
`,
},
};
Expand All @@ -107,7 +108,7 @@ export const euiFlyoutStyles = (euiThemeContext: UseEuiTheme) => {
outline: none;
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
// 1. Leave only a small sliver exposed on small screens so users understand that this is not a new page
// 2. If a custom maxWidth is set, we need to override it.
${logicalCSS('max-width', '90vw !important')}
Expand Down Expand Up @@ -217,14 +218,14 @@ const composeFlyoutSizing = (
return `
${logicalCSS('max-width', flyoutSizes[size].max)}
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${logicalCSS('min-width', flyoutSizes[size].min)}
${logicalCSS('width', flyoutSizes[size].width)}
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
${logicalCSS('min-width', 0)}
${logicalCSS('width', flyoutSizes[size].min)}
}
${euiMinBreakpoint(euiThemeContext, 'm')} {
${logicalCSS('min-width', flyoutSizes[size].min)}
${logicalCSS('width', flyoutSizes[size].width)}
}
`;
};

Expand Down
6 changes: 3 additions & 3 deletions src/components/image/image_wrapper.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { css } from '@emotion/react';
import {
euiBreakpoint,
euiMinBreakpoint,
logicalCSS,
logicalTextAlignCSS,
logicalSide,
Expand Down Expand Up @@ -49,15 +49,15 @@ export const euiImageWrapperStyles = (euiThemeContext: UseEuiTheme) => {
// 1: Logical properties/values in `float` is currently not yet supported by all browsers w/o flags
// @see https://caniuse.com/mdn-css_properties_float_flow_relative_values for when we can remove left/right fallbacks
left: css`
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${euiMinBreakpoint(euiThemeContext, 'm')} {
float: left; /* 1 */
float: ${logicalSide.left};
${logicalCSS('margin-left', '0')};
${logicalCSS('margin-top', '0')};
}
`,
right: css`
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${euiMinBreakpoint(euiThemeContext, 'm')} {
float: right; /* 1 */
float: ${logicalSide.right};
${logicalCSS('margin-right', '0')};
Expand Down
4 changes: 2 additions & 2 deletions src/components/page/page.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { css } from '@emotion/react';
import { euiBreakpoint, logicalCSS } from '../../global_styling';
import { euiMinBreakpoint, logicalCSS } from '../../global_styling';
import { UseEuiTheme } from '../../services';

export const euiPageStyles = (euiThemeContext: UseEuiTheme) => {
Expand Down Expand Up @@ -36,7 +36,7 @@ export const euiPageStyles = (euiThemeContext: UseEuiTheme) => {
row: css`
flex-direction: column;
${euiBreakpoint(euiThemeContext, ['m', 'xl'])} {
${euiMinBreakpoint(euiThemeContext, 'm')} {
flex-direction: row;
}
`,
Expand Down
25 changes: 11 additions & 14 deletions src/components/toast/global_toast_list.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

import { css, keyframes } from '@emotion/react';
import {
euiBreakpoint,
euiMaxBreakpoint,
euiMinBreakpoint,
euiScrollBarStyles,
logicalCSS,
logicalCSSWithFallback,
Expand All @@ -18,7 +19,7 @@ import { UseEuiTheme } from '../../services';

export const euiGlobalToastListStyles = (euiThemeContext: UseEuiTheme) => {
const { euiTheme } = euiThemeContext;
const euiToastWidth = euiTheme.base * 20;
const euiToastWidth = euiTheme.base * 25;
return {
/**
* 1. Allow list to expand as items are added, but cap it at the screen height.
Expand All @@ -33,7 +34,7 @@ export const euiGlobalToastListStyles = (euiThemeContext: UseEuiTheme) => {
position: fixed;
z-index: ${euiTheme.levels.toast};
${logicalCSS('bottom', 0)};
${logicalCSS('width', `${euiToastWidth + euiTheme.base * 5}px`)}; /* 2 */
${logicalCSS('width', `${euiToastWidth}px`)}; /* 2 */
${logicalCSS('max-height', '100vh')}; /* 1 */
${logicalCSSWithFallback('overflow-y', 'auto')};
Expand All @@ -53,7 +54,7 @@ export const euiGlobalToastListStyles = (euiThemeContext: UseEuiTheme) => {
${logicalCSS('padding-vertical', euiTheme.size.base)};
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
${euiMaxBreakpoint(euiThemeContext, 'm')} {
&:not(:empty) {
${logicalCSS('left', 0)};
${logicalCSS('width', '100%')}; /* 1 */
Expand All @@ -64,22 +65,18 @@ export const euiGlobalToastListStyles = (euiThemeContext: UseEuiTheme) => {
right: css`
&:not(:empty) {
${logicalCSS('right', 0)};
${logicalCSS('padding-left', `${euiTheme.base * 4}px`)}; /* 2 */
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
&:not(:empty) {
${logicalCSS('padding-left', euiTheme.size.base)};
${euiMinBreakpoint(euiThemeContext, 'm')} {
${logicalCSS('padding-left', `${euiTheme.base * 4}px`)}; /* 2 */
}
}
`,
left: css`
&:not(:empty) {
${logicalCSS('left', 0)};
${logicalCSS('padding-right', `${euiTheme.base * 4}px`)}; /* 2 */
}
${euiBreakpoint(euiThemeContext, ['xs', 's'])} {
&:not(:empty) {
${logicalCSS('padding-right', euiTheme.size.base)};
${euiMinBreakpoint(euiThemeContext, 'm')} {
${logicalCSS('padding-right', `${euiTheme.base * 4}px`)}; /* 2 */
}
}
`,
Expand Down
16 changes: 16 additions & 0 deletions src/global_styling/mixins/__snapshots__/_responsive.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`euiMaxBreakpoint generates a max-width only media query (l) 1`] = `"@media only screen and (max-width: 991px)"`;

exports[`euiMaxBreakpoint generates a max-width only media query (m) 1`] = `"@media only screen and (max-width: 767px)"`;

exports[`euiMaxBreakpoint generates a max-width only media query (s) 1`] = `"@media only screen and (max-width: 574px)"`;

exports[`euiMaxBreakpoint generates a max-width only media query (xl) 1`] = `"@media only screen and (max-width: 1199px)"`;

exports[`euiMinBreakpoint generates a min-width only media query (l) 1`] = `"@media only screen and (min-width: 992px)"`;

exports[`euiMinBreakpoint generates a min-width only media query (m) 1`] = `"@media only screen and (min-width: 768px)"`;

exports[`euiMinBreakpoint generates a min-width only media query (s) 1`] = `"@media only screen and (min-width: 575px)"`;

exports[`euiMinBreakpoint generates a min-width only media query (xl) 1`] = `"@media only screen and (min-width: 1200px)"`;

exports[`useEuiBreakpoint common breakpoint size arrays returns a media query for two element breakpoint combinations (l and xl) 1`] = `"@media only screen and (min-width: 992px)"`;

exports[`useEuiBreakpoint common breakpoint size arrays returns a media query for two element breakpoint combinations (m and l) 1`] = `"@media only screen and (min-width: 768px) and (max-width: 1199px)"`;
Expand Down
Loading

0 comments on commit 178a0ba

Please sign in to comment.