+ Emotion mixin for adding full height scrolling to a container or
+ flex child.
+
+ {'@include euiFullHeight'}}
+ type="mixin"
+ description={
+ <>
+
+ Sass mixin for adding full height scrolling to a container or
+ flex child.
+
+
+ It applies{' '}
+
+ height: 100%; overflow: hidden;
+ {' '}
+ but also adds flex: 1 1 auto;{' '}
+ for uses within flex{' '}
+ containers.
+
+ >
+ }
+ snippet="@include euiFullHeight;"
+ snippetLanguage="sass"
+ />
+ )}
>
);
};
diff --git a/src-docs/src/views/scroll/scroll_example.js b/src-docs/src/views/scroll/scroll_example.js
index 9ac8eadc3a5..e03db71f831 100644
--- a/src-docs/src/views/scroll/scroll_example.js
+++ b/src-docs/src/views/scroll/scroll_example.js
@@ -9,9 +9,9 @@ import {
} from '../../../../src';
import ScrollBar from './scroll';
-import Utilities from './utility_classes_overflow';
import ScrollX from './scroll_x';
import ScrollY from './scroll_y';
+import FullHeight from './full_height';
export const ScrollExample = {
title: 'Scroll',
@@ -101,11 +101,7 @@ export const ScrollExample = {
title: 'Full height layout',
color: 'subdued',
wrapText: false,
- text: (
- <>
-
- >
- ),
+ text: ,
},
],
};
diff --git a/src-docs/src/views/scroll/scroll_x.tsx b/src-docs/src/views/scroll/scroll_x.tsx
index 349914f6e48..e932a402dfd 100644
--- a/src-docs/src/views/scroll/scroll_x.tsx
+++ b/src-docs/src/views/scroll/scroll_x.tsx
@@ -84,7 +84,7 @@ export default () => {
To mask the top and bottom of the scrolled content, indicating
visually that there is more content below, pass in true to the
- second paremeter mask.
+ second parameter mask.
{"useEuiOverflowScroll('x', true);"}
diff --git a/src-docs/src/views/scroll/scroll_y.tsx b/src-docs/src/views/scroll/scroll_y.tsx
index 4942934e67b..c022aabfed9 100644
--- a/src-docs/src/views/scroll/scroll_y.tsx
+++ b/src-docs/src/views/scroll/scroll_y.tsx
@@ -60,7 +60,7 @@ export default () => {
To mask the top and bottom of the scrolled content, indicating
visually that there is more content below, pass in true to the
- second paremeter mask.
+ second parameter mask.
{"useEuiOverflowScroll('y', true);"}
diff --git a/src/components/breadcrumbs/breadcrumb.styles.ts b/src/components/breadcrumbs/breadcrumb.styles.ts
index 845992f287d..c1300c03b07 100644
--- a/src/components/breadcrumbs/breadcrumb.styles.ts
+++ b/src/components/breadcrumbs/breadcrumb.styles.ts
@@ -81,10 +81,10 @@ export const euiBreadcrumbContentStyles = (euiThemeContext: UseEuiTheme) => {
// Types
page: css`
&:is(a):focus {
- ${euiFocusRing(euiTheme, 'inset')};
+ ${euiFocusRing(euiThemeContext, 'inset')};
}
&:is(button):focus {
- ${euiFocusRing(euiTheme, 'center')};
+ ${euiFocusRing(euiThemeContext, 'center')};
}
`,
application: css`
@@ -109,7 +109,7 @@ export const euiBreadcrumbContentStyles = (euiThemeContext: UseEuiTheme) => {
color: ${euiTheme.colors.link};
:focus {
- ${euiFocusRing(euiTheme, 'inset')};
+ ${euiFocusRing(euiThemeContext, 'inset')};
:focus-visible {
border-radius: ${euiTheme.border.radius.medium};
diff --git a/src/components/image/image_button.styles.ts b/src/components/image/image_button.styles.ts
index 219409f9ec2..99e27699164 100644
--- a/src/components/image/image_button.styles.ts
+++ b/src/components/image/image_button.styles.ts
@@ -51,7 +51,7 @@ export const euiImageButtonStyles = (euiThemeContext: UseEuiTheme) => {
}
&:focus {
- ${euiFocusRing(euiTheme, 'outset')}
+ ${euiFocusRing(euiThemeContext, 'outset')}
}
`,
fullWidth: css`
diff --git a/src/components/link/link.styles.ts b/src/components/link/link.styles.ts
index d17b5b6648d..fccd16b75e0 100644
--- a/src/components/link/link.styles.ts
+++ b/src/components/link/link.styles.ts
@@ -39,7 +39,8 @@ export const euiLinkFocusCSS = (euiTheme: UseEuiTheme['euiTheme']) => {
`;
};
-export const euiLinkCSS = (euiTheme: UseEuiTheme['euiTheme']) => {
+export const euiLinkCSS = (euiThemeContext: UseEuiTheme) => {
+ const { euiTheme } = euiThemeContext;
return `
font-weight: ${euiTheme.font.weight.medium};
text-align: left;
@@ -49,16 +50,17 @@ export const euiLinkCSS = (euiTheme: UseEuiTheme['euiTheme']) => {
}
&:focus {
- ${euiFocusRing(euiTheme, 'outset')}
+ ${euiFocusRing(euiThemeContext, 'outset')}
${euiLinkFocusCSS(euiTheme)}
}
`;
};
-export const euiLinkStyles = ({ euiTheme }: UseEuiTheme) => {
+export const euiLinkStyles = (euiThemeContext: UseEuiTheme) => {
+ const { euiTheme } = euiThemeContext;
return {
euiLink: css`
- ${euiLinkCSS(euiTheme)}
+ ${euiLinkCSS(euiThemeContext)}
user-select: text;
&[target='_blank'] {
diff --git a/src/components/text/text.styles.ts b/src/components/text/text.styles.ts
index e5b08c01a60..2387ff2e3bb 100644
--- a/src/components/text/text.styles.ts
+++ b/src/components/text/text.styles.ts
@@ -226,7 +226,7 @@ export const euiTextStyles = (euiThemeContext: UseEuiTheme) => {
// Style anchors that don't have a class. This prevents overwriting "buttons"
// and other stylized elements passed in.
a:not([class]) {
- ${euiLinkCSS(euiTheme)}
+ ${euiLinkCSS(euiThemeContext)}
}
img {
diff --git a/src/components/toast/global_toast_list.styles.ts b/src/components/toast/global_toast_list.styles.ts
index 8134cc27b7c..8429a1d2173 100644
--- a/src/components/toast/global_toast_list.styles.ts
+++ b/src/components/toast/global_toast_list.styles.ts
@@ -11,6 +11,7 @@ import {
euiBreakpoint,
euiScrollBarStyles,
logicalCSS,
+ logicalCSSWithFallback,
logicalSizeCSS,
} from '../../global_styling';
import { UseEuiTheme } from '../../services';
@@ -34,8 +35,7 @@ export const euiGlobalToastListStyles = (euiThemeContext: UseEuiTheme) => {
${logicalCSS('bottom', 0)};
${logicalCSS('width', `${euiToastWidth + euiTheme.base * 5}px`)}; /* 2 */
${logicalCSS('max-height', '100vh')}; /* 1 */
- overflow-y: auto; // Fallback for the 'overflow-inline' logical property, which is not yet supported
- ${logicalCSS('overflow-y', 'auto')};
+ ${logicalCSSWithFallback('overflow-y', 'auto')};
// Hide the scrollbar entirely
scrollbar-width: none;
diff --git a/src/global_styling/functions/__snapshots__/logicals.test.ts.snap b/src/global_styling/functions/__snapshots__/logicals.test.ts.snap
index 5cb2bec1b29..97b8d3b60da 100644
--- a/src/global_styling/functions/__snapshots__/logicals.test.ts.snap
+++ b/src/global_styling/functions/__snapshots__/logicals.test.ts.snap
@@ -86,9 +86,9 @@ exports[`logicalCSS mixin returns a string property for each directional propert
exports[`logicalCSS mixin returns a string property for each directional property: min-width 1`] = `"min-inline-size: 8px;"`;
-exports[`logicalCSS mixin returns a string property for each directional property: overflow-x 1`] = `"overflow-block: 8px;"`;
+exports[`logicalCSS mixin returns a string property for each directional property: overflow-x 1`] = `"overflow-inline: 8px;"`;
-exports[`logicalCSS mixin returns a string property for each directional property: overflow-y 1`] = `"overflow-inline: 8px;"`;
+exports[`logicalCSS mixin returns a string property for each directional property: overflow-y 1`] = `"overflow-block: 8px;"`;
exports[`logicalCSS mixin returns a string property for each directional property: padding-bottom 1`] = `"padding-block-end: 8px;"`;
@@ -110,6 +110,13 @@ exports[`logicalCSS mixin returns a string property for each directional propert
exports[`logicalCSS mixin returns a string property for each directional property: width 1`] = `"inline-size: 8px;"`;
+exports[`logicalCSSWithFallback returns both the original property and the logical property 1`] = `
+"
+ overflow-x: auto;
+ overflow-inline: auto;
+"
+`;
+
exports[`logicalStyle mixin returns an object property for each directional property: border-bottom 1`] = `
Object {
"borderBlockEnd": "8px",
@@ -370,13 +377,13 @@ Object {
exports[`logicalStyle mixin returns an object property for each directional property: overflow-x 1`] = `
Object {
- "overflowBlock": "8px",
+ "overflowInline": "8px",
}
`;
exports[`logicalStyle mixin returns an object property for each directional property: overflow-y 1`] = `
Object {
- "overflowInline": "8px",
+ "overflowBlock": "8px",
}
`;
diff --git a/src/global_styling/functions/logicals.test.ts b/src/global_styling/functions/logicals.test.ts
index 535f6274469..dd67fe7f9cc 100644
--- a/src/global_styling/functions/logicals.test.ts
+++ b/src/global_styling/functions/logicals.test.ts
@@ -11,6 +11,7 @@ import {
LOGICAL_PROPERTIES,
LOGICAL_TEXT_ALIGNMENT,
logicalCSS,
+ logicalCSSWithFallback,
logicalStyle,
logicalTextAlignCSS,
logicalTextAlignStyle,
@@ -28,6 +29,14 @@ describe('logicalCSS mixin returns a string property', () => {
});
});
+describe('logicalCSSWithFallback ', () => {
+ it('returns both the original property and the logical property', () => {
+ expect(
+ testCustomHook(() => logicalCSSWithFallback('overflow-x', 'auto')).return
+ ).toMatchSnapshot();
+ });
+});
+
describe('logicalStyle mixin returns an object property', () => {
describe('for each directional property:', () => {
LOGICAL_PROPERTIES.forEach((prop) => {
diff --git a/src/global_styling/functions/logicals.ts b/src/global_styling/functions/logicals.ts
index 711fc440ca6..b1d5bc0c400 100644
--- a/src/global_styling/functions/logicals.ts
+++ b/src/global_styling/functions/logicals.ts
@@ -65,8 +65,8 @@ const logicalSize = {
};
const logicalOverflow = {
- 'overflow-x': 'overflow-block',
- 'overflow-y': 'overflow-inline',
+ 'overflow-x': 'overflow-inline',
+ 'overflow-y': 'overflow-block',
};
const logicalBorders = {
@@ -122,6 +122,24 @@ export const logicalCSS = (property: LogicalProperties, value?: any) => {
return `${logicals[property]}: ${value};`;
};
+/**
+ * Some logical properties are not yet fully supported by all browsers.
+ * For those cases, we should use the old property as a fallback for
+ * browsers missing support, while allowing supporting browsers to use
+ * the logical properties.
+ *
+ * Examples:
+ * https://caniuse.com/?search=overflow-block
+ * https://caniuse.com/mdn-css_properties_float_flow_relative_values
+ */
+export const logicalCSSWithFallback = (
+ property: LogicalProperties,
+ value?: any
+) => `
+ ${property}: ${value};
+ ${logicalCSS(property, value)}
+`;
+
/**
*
* @param property A string that is a valid CSS logical property
diff --git a/src/global_styling/mixins/__snapshots__/_typography.test.ts.snap b/src/global_styling/mixins/__snapshots__/_typography.test.ts.snap
index 064d2dc3298..5d3de5e0af1 100644
--- a/src/global_styling/mixins/__snapshots__/_typography.test.ts.snap
+++ b/src/global_styling/mixins/__snapshots__/_typography.test.ts.snap
@@ -205,7 +205,7 @@ exports[`euiTextBreakWord returns a string of CSS text 1`] = `
exports[`euiTextTruncate allows customizing max-width 1`] = `
"
- max-width: 150px; // Ensure that the node has a maximum width after which truncation can occur
+ max-inline-size: 150px;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
@@ -214,7 +214,7 @@ exports[`euiTextTruncate allows customizing max-width 1`] = `
exports[`euiTextTruncate returns a string of CSS text 1`] = `
"
- max-width: 100%; // Ensure that the node has a maximum width after which truncation can occur
+ max-inline-size: 100%;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
diff --git a/src/global_styling/mixins/_helpers.scss b/src/global_styling/mixins/_helpers.scss
index 5d937d609e1..db1c6fbd935 100644
--- a/src/global_styling/mixins/_helpers.scss
+++ b/src/global_styling/mixins/_helpers.scss
@@ -82,6 +82,15 @@
@include euiOverflowShadow('x');
}
+/**
+ * For quickly applying a full-height element whether using flex or not
+ */
+@mixin euiFullHeight {
+ height: 100%;
+ flex: 1 1 auto;
+ overflow: hidden;
+}
+
// Hiding elements offscreen to only be read by screen reader
// See https://github.com/elastic/eui/pull/5130 and https://github.com/elastic/eui/pull/5152 for more info
@mixin euiScreenReaderOnly {
diff --git a/src/global_styling/mixins/_helpers.ts b/src/global_styling/mixins/_helpers.ts
index cafae90b1e6..46c460ff05f 100644
--- a/src/global_styling/mixins/_helpers.ts
+++ b/src/global_styling/mixins/_helpers.ts
@@ -9,6 +9,7 @@
import { CSSProperties } from 'react';
import { useEuiTheme, UseEuiTheme } from '../../services/theme';
import { transparentize } from '../../services/color';
+import { logicalCSS, logicalCSSWithFallback } from '../functions';
/**
* Set scroll bar appearance on Chrome (and firefox).
@@ -54,8 +55,8 @@ export const euiScrollBarStyles = (
return `scrollbar-width: ${width};
&::-webkit-scrollbar {
- width: ${scrollBarSize};
- height: ${scrollBarSize};
+ ${logicalCSS('width', scrollBarSize)}
+ ${logicalCSS('height', scrollBarSize)}
}
&::-webkit-scrollbar-thumb {
@@ -127,15 +128,14 @@ const euiOverflowShadowStyles = (
interface _EuiYScroll {
height?: CSSProperties['height'];
}
-// TODO: How do we use Emotion to output the CSS class utilities instead?
export const euiYScroll = (
euiTheme: UseEuiTheme,
{ height }: _EuiYScroll = {}
) => `
${euiScrollBarStyles(euiTheme)}
- height: ${height || '100%'};
- overflow-y: auto;
- overflow-x: hidden;
+ ${logicalCSS('height', height || '100%')}
+ ${logicalCSSWithFallback('overflow-y', 'auto')}
+ ${logicalCSSWithFallback('overflow-x', 'hidden')}
&:focus {
outline: none; /* 1 */
}
@@ -159,7 +159,7 @@ export const useEuiYScrollWithShadows = ({ height }: _EuiYScroll = {}) => {
export const euiXScroll = (euiTheme: UseEuiTheme) => `
${euiScrollBarStyles(euiTheme)}
- overflow-x: auto;
+ ${logicalCSSWithFallback('overflow-x', 'auto')}
&:focus {
outline: none; /* 1 */
}
@@ -206,3 +206,12 @@ export const useEuiOverflowScroll = (
const euiTheme = useEuiTheme();
return euiOverflowScroll(euiTheme, { direction, mask });
};
+
+/**
+ * For quickly applying a full-height element whether using flex or not
+ */
+export const euiFullHeight = () => `
+ ${logicalCSS('height', '100%')}
+ flex: 1 1 auto;
+ overflow: hidden;
+`;
diff --git a/src/global_styling/mixins/_states.ts b/src/global_styling/mixins/_states.ts
index 744eab0796a..09741801086 100644
--- a/src/global_styling/mixins/_states.ts
+++ b/src/global_styling/mixins/_states.ts
@@ -24,7 +24,7 @@ export type _EuiFocusRingOffset =
* @param color Accepts any CSS color, **Note: only works in -webkit-**
*/
export const euiFocusRing = (
- euiTheme: UseEuiTheme['euiTheme'],
+ { euiTheme }: UseEuiTheme,
offset: _EuiFocusRingOffset = 'center',
options?: { color?: CSSProperties['outlineColor'] }
) => {
@@ -66,6 +66,6 @@ export const useEuiFocusRing = (
offset?: _EuiFocusRingOffset,
color?: CSSProperties['outlineColor']
) => {
- const { euiTheme } = useEuiTheme();
+ const euiTheme = useEuiTheme();
return euiFocusRing(euiTheme, offset, { color });
};
diff --git a/src/global_styling/mixins/_typography.ts b/src/global_styling/mixins/_typography.ts
index 372b0fdb46a..db62a90a287 100644
--- a/src/global_styling/mixins/_typography.ts
+++ b/src/global_styling/mixins/_typography.ts
@@ -14,6 +14,7 @@ import {
} from '../functions/typography';
import { useEuiTheme, UseEuiTheme } from '../../services/theme/hooks';
import { _EuiThemeFontScale } from '../variables/typography';
+import { logicalCSS } from '../functions';
export type EuiThemeFontSize = {
fontSize: CSSProperties['fontSize'];
@@ -57,7 +58,9 @@ export const euiTextBreakWord = () => `
export const euiTextTruncate = (
maxWidth: CSSProperties['maxWidth'] = '100%'
) => `
- max-width: ${maxWidth}; // Ensure that the node has a maximum width after which truncation can occur
+ ${
+ logicalCSS('max-width', maxWidth) // Ensure that the node has a maximum width after which truncation can occur
+ }
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
diff --git a/src/global_styling/reset/global_styles.tsx b/src/global_styling/reset/global_styles.tsx
index dbff38e5743..8574ac45ca5 100644
--- a/src/global_styling/reset/global_styles.tsx
+++ b/src/global_styling/reset/global_styles.tsx
@@ -85,7 +85,7 @@ export const EuiGlobalStyles = ({}: EuiGlobalStylesProps) => {
}
*:focus {
- ${euiFocusRing(euiTheme)}
+ ${euiFocusRing(euiThemeContext)}
}
// Dark mode's highlighted doesn't work well so lets just set it the same as our focus background
diff --git a/src/global_styling/utility/__snapshots__/utility.test.tsx.snap b/src/global_styling/utility/__snapshots__/utility.test.tsx.snap
new file mode 100644
index 00000000000..a233f829e4e
--- /dev/null
+++ b/src/global_styling/utility/__snapshots__/utility.test.tsx.snap
@@ -0,0 +1,350 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`global utility styles generates static global styles 1`] = `
+".euiScreenReaderOnly{
+ // Take the element out of the layout
+ position: absolute;
+ // Keep it vertically inline
+ top: auto;
+ // Chrome requires a left value, and Selenium (used by Kibana's FTR) requires an off-screen position for its .getVisibleText() to not register SR-only text
+ left: -10000px;
+ // The element must have a size (for some screen readers)
+ width: 1px;
+ height: 1px;
+ // But reduce the visible size to nothing
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ // And ensure no overflows occur
+ overflow: hidden;
+ // Chrome requires the negative margin to not cause overflows of parent containers
+ margin: -1px;
+;}
+.eui-alignBaseline{vertical-align:baseline!important;}
+.eui-alignBottom{vertical-align:bottom!important;}
+.eui-alignMiddle{vertical-align:middle!important;}
+.eui-alignTop{vertical-align:top!important;}
+.eui-displayBlock{display:block!important;}
+.eui-displayInline{display:inline!important;}
+.eui-displayInlineBlock{display:inline-block!important;}
+.eui-fullWidth{display:block!important;inline-size: 100% !important;;}
+.eui-fullHeight{
+ block-size: 100%;
+ flex: 1 1 auto;
+ overflow: hidden;
+;}
+.eui-textCenter{text-align:center!important;}
+.eui-textLeft{text-align:start!important;}
+.eui-textRight{text-align:end!important;}
+.eui-textNoWrap{white-space:nowrap!important;}
+.eui-textInheritColor{color:inherit!important;}
+.eui-textBreakWord{
+ overflow-wrap: break-word !important; // makes sure the long string will wrap and not bust out of the container
+ word-wrap: break-word !important; // spec says, they are literally just alternate names for each other but some browsers support one and not the other
+ word-break: break-word; // IE doesn't understand but that's ok
+;}
+.eui-textBreakAll{overflow-wrap:break-word!important;word-break:break-all!important;}
+.eui-textBreakNormal{overflow-wrap:normal!important;word-wrap:normal!important;word-break:normal!important;}
+.eui-textTruncate{
+ max-inline-size: 100%;
+ overflow: hidden !important;
+ text-overflow: ellipsis !important;
+ white-space: nowrap !important;
+;}
+.eui-textNumber{
+ font-feature-settings: 'calt' 1, 'kern' 1, 'liga' 1, 'tnum' 1;
+;}
+.eui-scrollBar{scrollbar-width: thin;
+
+ &::-webkit-scrollbar {
+ inline-size: 16px;
+ block-size: 16px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(105,112,125,0.5);
+ background-clip: content-box;
+ border-radius: 16px;
+ border: calc(8px * 0.75) solid transparent;
+ }
+
+ &::-webkit-scrollbar-corner,
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ scrollbar-color: rgba(105,112,125,0.5) transparent;
+ ;}
+.eui-yScroll{
+ scrollbar-width: thin;
+
+ &::-webkit-scrollbar {
+ inline-size: 16px;
+ block-size: 16px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(105,112,125,0.5);
+ background-clip: content-box;
+ border-radius: 16px;
+ border: calc(8px * 0.75) solid transparent;
+ }
+
+ &::-webkit-scrollbar-corner,
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ scrollbar-color: rgba(105,112,125,0.5) transparent;
+
+ block-size: 100%;
+
+ overflow-y: auto;
+ overflow-block: auto;
+
+
+ overflow-x: hidden;
+ overflow-inline: hidden;
+
+ &:focus {
+ outline: none; /* 1 */
+ }
+;}
+.eui-xScroll{
+ scrollbar-width: thin;
+
+ &::-webkit-scrollbar {
+ inline-size: 16px;
+ block-size: 16px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(105,112,125,0.5);
+ background-clip: content-box;
+ border-radius: 16px;
+ border: calc(8px * 0.75) solid transparent;
+ }
+
+ &::-webkit-scrollbar-corner,
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ scrollbar-color: rgba(105,112,125,0.5) transparent;
+
+
+ overflow-x: auto;
+ overflow-inline: auto;
+
+ &:focus {
+ outline: none; /* 1 */
+ }
+;}
+.eui-yScrollWithShadows{
+
+ scrollbar-width: thin;
+
+ &::-webkit-scrollbar {
+ inline-size: 16px;
+ block-size: 16px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(105,112,125,0.5);
+ background-clip: content-box;
+ border-radius: 16px;
+ border: calc(8px * 0.75) solid transparent;
+ }
+
+ &::-webkit-scrollbar-corner,
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ scrollbar-color: rgba(105,112,125,0.5) transparent;
+
+ block-size: 100%;
+
+ overflow-y: auto;
+ overflow-block: auto;
+
+
+ overflow-x: hidden;
+ overflow-inline: hidden;
+
+ &:focus {
+ outline: none; /* 1 */
+ }
+
+ mask-image: linear-gradient(to bottom,
+ rgba(255,0,0,0.1) 0%,
+ rgb(255,0,0) calc(16px * 0.75 * 1.25)
+ ,
+ rgb(255,0,0) calc(100% - calc(16px * 0.75 * 1.25)),
+ rgba(255,0,0,0.1) 100%
+ );
+;}
+.eui-xScrollWithShadows{
+
+ scrollbar-width: thin;
+
+ &::-webkit-scrollbar {
+ inline-size: 16px;
+ block-size: 16px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: rgba(105,112,125,0.5);
+ background-clip: content-box;
+ border-radius: 16px;
+ border: calc(8px * 0.75) solid transparent;
+ }
+
+ &::-webkit-scrollbar-corner,
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+
+ scrollbar-color: rgba(105,112,125,0.5) transparent;
+
+
+ overflow-x: auto;
+ overflow-inline: auto;
+
+ &:focus {
+ outline: none; /* 1 */
+ }
+
+ mask-image: linear-gradient(to right,
+ rgba(255,0,0,0.1) 0%,
+ rgb(255,0,0) calc(16px * 0.75 * 1.25)
+ ,
+ rgb(255,0,0) calc(100% - calc(16px * 0.75 * 1.25)),
+ rgba(255,0,0,0.1) 100%
+ );
+;}[class*='eui-showFor']{display:none!important;}
+ .eui-hideFor--xl {
+ @media only screen and (min-width: 1200px) {
+ display: none !important;
+ }
+ }
+ .eui-showFor--xl {
+ @media only screen and (min-width: 1200px) {
+ display: inline !important;
+ }
+ }
+ .eui-showFor--xl--block {
+ @media only screen and (min-width: 1200px) {
+ display: block !important;
+ }
+ }
+ .eui-showFor--xl--inlineBlock {
+ @media only screen and (min-width: 1200px) {
+ display: inline-block !important;
+ }
+ }
+ .eui-showFor--xl--flex {
+ @media only screen and (min-width: 1200px) {
+ display: flex !important;
+ }
+ };
+ .eui-hideFor--l {
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
+ display: none !important;
+ }
+ }
+ .eui-showFor--l {
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
+ display: inline !important;
+ }
+ }
+ .eui-showFor--l--block {
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
+ display: block !important;
+ }
+ }
+ .eui-showFor--l--inlineBlock {
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
+ display: inline-block !important;
+ }
+ }
+ .eui-showFor--l--flex {
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
+ display: flex !important;
+ }
+ };
+ .eui-hideFor--m {
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
+ display: none !important;
+ }
+ }
+ .eui-showFor--m {
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
+ display: inline !important;
+ }
+ }
+ .eui-showFor--m--block {
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
+ display: block !important;
+ }
+ }
+ .eui-showFor--m--inlineBlock {
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
+ display: inline-block !important;
+ }
+ }
+ .eui-showFor--m--flex {
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
+ display: flex !important;
+ }
+ };
+ .eui-hideFor--s {
+ @media only screen and (min-width: 575px) and (max-width: 767px) {
+ display: none !important;
+ }
+ }
+ .eui-showFor--s {
+ @media only screen and (min-width: 575px) and (max-width: 767px) {
+ display: inline !important;
+ }
+ }
+ .eui-showFor--s--block {
+ @media only screen and (min-width: 575px) and (max-width: 767px) {
+ display: block !important;
+ }
+ }
+ .eui-showFor--s--inlineBlock {
+ @media only screen and (min-width: 575px) and (max-width: 767px) {
+ display: inline-block !important;
+ }
+ }
+ .eui-showFor--s--flex {
+ @media only screen and (min-width: 575px) and (max-width: 767px) {
+ display: flex !important;
+ }
+ };
+ .eui-hideFor--xs {
+ @media only screen and (max-width: 574px) {
+ display: none !important;
+ }
+ }
+ .eui-showFor--xs {
+ @media only screen and (max-width: 574px) {
+ display: inline !important;
+ }
+ }
+ .eui-showFor--xs--block {
+ @media only screen and (max-width: 574px) {
+ display: block !important;
+ }
+ }
+ .eui-showFor--xs--inlineBlock {
+ @media only screen and (max-width: 574px) {
+ display: inline-block !important;
+ }
+ }
+ .eui-showFor--xs--flex {
+ @media only screen and (max-width: 574px) {
+ display: flex !important;
+ }
+ };;;label:globalStyles;"
+`;
diff --git a/src/global_styling/utility/_utility.scss b/src/global_styling/utility/_utility.scss
index 26c4d8b44e0..b7cae579552 100644
--- a/src/global_styling/utility/_utility.scss
+++ b/src/global_styling/utility/_utility.scss
@@ -1,84 +1,6 @@
// This file utilizes !importants on purpose
// sass-lint:disable no-important
-// Vertical alignment
-.eui-alignBaseline { vertical-align: baseline !important; }
-.eui-alignBottom { vertical-align: bottom !important; }
-.eui-alignMiddle { vertical-align: middle !important; }
-.eui-alignTop { vertical-align: top !important; }
-
-// Display
-.eui-displayBlock {display: block !important;}
-.eui-displayInline {display: inline !important;}
-.eui-displayInlineBlock {display: inline-block !important;}
-
-.eui-fullWidth {
- display: block !important;
- width: 100% !important;
-}
-
-// Text
-.eui-textCenter {text-align: center !important;}
-.eui-textLeft {text-align: left !important;}
-.eui-textRight {text-align: right !important;}
-.eui-textNoWrap {white-space: nowrap !important;}
-.eui-textInheritColor {color: inherit !important;}
-
-.eui-textBreakWord {
- @include euiTextBreakWord;
-}
-
-.eui-textBreakAll {
- overflow-wrap: break-word !important; // Fixes FF when dashes are involved #2288
- word-break: break-all !important;
-}
-
-.eui-textBreakNormal {
- overflow-wrap: normal !important;
- word-wrap: normal !important;
- word-break: normal !important;
-}
-
-.eui-textTruncate {
- @include euiTextTruncate;
-}
-
-.eui-textNumber {
- @include euiNumberFormat;
-}
-
-/**
- * Responsive
- *
- * 1. Be sure to hide the element initially
- */
-
-[class*='eui-showFor'] {
- display: none !important; /* 1 */
-}
-
-@each $size in $euiBreakpointKeys {
- .eui-hideFor--#{$size} {
- @include euiBreakpoint($size) { display: none !important; }
- }
-
- .eui-showFor--#{$size} {
- @include euiBreakpoint($size) { display: inline !important; }
- }
-
- .eui-showFor--#{$size}--block {
- @include euiBreakpoint($size) { display: block !important; }
- }
-
- .eui-showFor--#{$size}--inlineBlock {
- @include euiBreakpoint($size) { display: inline-block !important; }
- }
-
- .eui-showFor--#{$size}--flex {
- @include euiBreakpoint($size) { display: flex !important; }
- }
-}
-
/**
* IE doesn't properly wrap groups if it is within a flex-item of a flex-group.
* Adding the following styles to the flex-item that contains the wrapping group, will fix IE.
@@ -91,52 +13,3 @@
flex-basis: 0%;
}
}
-
-/**
- * Scroll bar only
- */
-.eui-scrollBar {
- @include euiScrollBar;
-}
-
-/**
- * Overflow scrolling
- */
-.eui-yScroll {
- @include euiYScroll;
-}
-
-.eui-xScroll {
- @include euiXScroll;
-}
-
-/**
- * Overflow scrolling with shadows
- */
-.eui-yScrollWithShadows {
- @include euiYScrollWithShadows;
-}
-
-.eui-xScrollWithShadows {
- @include euiXScrollWithShadows;
-}
-
-/**
- * Forcing focus ring on non-EUI elements
- */
-.eui-isFocusable:focus {
- @include euiFocusRing('large');
-}
-
-/**
- * For quickly applying a full-height element whether using flex or not
- */
-@mixin euiFullHeight {
- height: 100%;
- flex: 1 1 auto;
- overflow: hidden;
-}
-
-.eui-fullHeight {
- @include euiFullHeight;
-}
diff --git a/src/global_styling/utility/utility.test.tsx b/src/global_styling/utility/utility.test.tsx
new file mode 100644
index 00000000000..7a5a1725dce
--- /dev/null
+++ b/src/global_styling/utility/utility.test.tsx
@@ -0,0 +1,25 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { testCustomHook } from '../../test/internal';
+import { useEuiTheme } from '../../services';
+import { globalStyles } from './utility';
+
+describe('global utility styles', () => {
+ const useTestHook = () => {
+ const euiTheme = useEuiTheme();
+ return globalStyles(euiTheme);
+ };
+
+ it('generates static global styles', () => {
+ const rawStyles = (testCustomHook(useTestHook) as any).return.styles;
+ // Make Emotion's minification a little less annoying to read
+ const globalStyles = rawStyles.replace(/}\.eui-/g, '}\n.eui-');
+ expect(globalStyles).toMatchSnapshot();
+ });
+});
diff --git a/src/global_styling/utility/utility.tsx b/src/global_styling/utility/utility.tsx
index 72d7bf31a7d..b0ba9ce4543 100644
--- a/src/global_styling/utility/utility.tsx
+++ b/src/global_styling/utility/utility.tsx
@@ -9,11 +9,149 @@
import React from 'react';
import { Global, css } from '@emotion/react';
+import { useEuiTheme, UseEuiTheme } from '../../services/theme/hooks';
import { euiScreenReaderOnly } from '../../components/accessibility/screen_reader_only/screen_reader_only.styles';
+import {
+ euiFullHeight,
+ euiTextBreakWord,
+ euiTextTruncate,
+ euiNumberFormat,
+ euiScrollBarStyles,
+ euiYScroll,
+ euiXScroll,
+ euiYScrollWithShadows,
+ euiXScrollWithShadows,
+ euiBreakpoint,
+} from '../mixins';
+import { logicalCSS } from '../functions';
-const globalStyles = css`
- .euiScreenReaderOnly {
- ${euiScreenReaderOnly()}
- }
-`;
-export const EuiUtilityClasses = () => ;
+export const globalStyles = (euiThemeContext: UseEuiTheme) => {
+ return css`
+ // Accessibility
+ .euiScreenReaderOnly {
+ ${euiScreenReaderOnly()}
+ }
+
+ // Vertical alignment
+ .eui-alignBaseline {
+ vertical-align: baseline !important;
+ }
+ .eui-alignBottom {
+ vertical-align: bottom !important;
+ }
+ .eui-alignMiddle {
+ vertical-align: middle !important;
+ }
+ .eui-alignTop {
+ vertical-align: top !important;
+ }
+
+ // Display
+ .eui-displayBlock {
+ display: block !important;
+ }
+ .eui-displayInline {
+ display: inline !important;
+ }
+ .eui-displayInlineBlock {
+ display: inline-block !important;
+ }
+
+ .eui-fullWidth {
+ display: block !important;
+ ${logicalCSS('width', '100% !important')}
+ }
+ .eui-fullHeight {
+ ${euiFullHeight()}
+ }
+
+ // Text
+ .eui-textCenter {
+ text-align: center !important;
+ }
+ .eui-textLeft {
+ text-align: start !important;
+ }
+ .eui-textRight {
+ text-align: end !important;
+ }
+ .eui-textNoWrap {
+ white-space: nowrap !important;
+ }
+ .eui-textInheritColor {
+ color: inherit !important;
+ }
+ .eui-textBreakWord {
+ ${euiTextBreakWord()}
+ }
+ .eui-textBreakAll {
+ overflow-wrap: break-word !important; // Fixes FF when dashes are involved #2288
+ word-break: break-all !important;
+ }
+ .eui-textBreakNormal {
+ overflow-wrap: normal !important;
+ word-wrap: normal !important;
+ word-break: normal !important;
+ }
+ .eui-textTruncate {
+ ${euiTextTruncate()}
+ }
+ .eui-textNumber {
+ ${euiNumberFormat(euiThemeContext)}
+ }
+
+ // Scroll
+ .eui-scrollBar {
+ ${euiScrollBarStyles(euiThemeContext)}
+ }
+ .eui-yScroll {
+ ${euiYScroll(euiThemeContext)}
+ }
+ .eui-xScroll {
+ ${euiXScroll(euiThemeContext)}
+ }
+ .eui-yScrollWithShadows {
+ ${euiYScrollWithShadows(euiThemeContext)}
+ }
+ .eui-xScrollWithShadows {
+ ${euiXScrollWithShadows(euiThemeContext)}
+ }
+
+ // Responsive
+ [class*='eui-showFor'] {
+ display: none !important; // Be sure to hide the element initially
+ }
+ ${Object.keys(euiThemeContext.euiTheme.breakpoint).map(
+ (size) => `
+ .eui-hideFor--${size} {
+ ${euiBreakpoint(euiThemeContext, [size])} {
+ display: none !important;
+ }
+ }
+ .eui-showFor--${size} {
+ ${euiBreakpoint(euiThemeContext, [size])} {
+ display: inline !important;
+ }
+ }
+ .eui-showFor--${size}--block {
+ ${euiBreakpoint(euiThemeContext, [size])} {
+ display: block !important;
+ }
+ }
+ .eui-showFor--${size}--inlineBlock {
+ ${euiBreakpoint(euiThemeContext, [size])} {
+ display: inline-block !important;
+ }
+ }
+ .eui-showFor--${size}--flex {
+ ${euiBreakpoint(euiThemeContext, [size])} {
+ display: flex !important;
+ }
+ }`
+ )}
+ `;
+};
+export const EuiUtilityClasses = () => {
+ const euiTheme = useEuiTheme();
+ return ;
+};
diff --git a/upcoming_changelogs/6124.md b/upcoming_changelogs/6124.md
new file mode 100644
index 00000000000..9b8923e5181
--- /dev/null
+++ b/upcoming_changelogs/6124.md
@@ -0,0 +1,5 @@
+**CSS-in-JS conversions**
+
+- Added `logicalCSSWithFallback()` utility for logical properties without full browser support
+- Converted `euiFullHeight()` Sass mixin to Emotion
+- Converted all global CSS utility classes to Emotion