From f5e3c1a27dd67813cfdb1aa9ba0021afab59afc2 Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:23:02 -0800 Subject: [PATCH 01/12] [Emotion] Convert EuiEmptyPrompt (#7494) --- changelogs/upcoming/7494.md | 4 + .../comment_list/comment_event.styles.ts | 35 +- src/components/comment_list/comment_event.tsx | 4 +- .../__snapshots__/empty_prompt.test.tsx.snap | 342 +++++++----------- .../empty_prompt/_empty_prompt.scss | 128 ------- src/components/empty_prompt/_index.scss | 1 - .../empty_prompt/empty_prompt.styles.ts | 169 +++++++++ .../empty_prompt/empty_prompt.test.tsx | 6 +- src/components/empty_prompt/empty_prompt.tsx | 159 ++++---- src/components/index.scss | 1 - .../page_empty_prompt.test.tsx.snap | 196 ++++------ .../mixins/__snapshots__/_color.test.ts.snap | 16 + src/global_styling/mixins/_color.test.ts | 13 + src/global_styling/mixins/_color.ts | 109 ++++-- 14 files changed, 563 insertions(+), 620 deletions(-) create mode 100644 changelogs/upcoming/7494.md delete mode 100644 src/components/empty_prompt/_empty_prompt.scss delete mode 100644 src/components/empty_prompt/_index.scss create mode 100644 src/components/empty_prompt/empty_prompt.styles.ts diff --git a/changelogs/upcoming/7494.md b/changelogs/upcoming/7494.md new file mode 100644 index 00000000000..760e10f64f6 --- /dev/null +++ b/changelogs/upcoming/7494.md @@ -0,0 +1,4 @@ +**CSS-in-JS conversions** + +- Converted `EuiEmptyPrompt` to Emotion +- Added `euiBorderColor` and `useEuiBorderColorCSS` style utilities diff --git a/src/components/comment_list/comment_event.styles.ts b/src/components/comment_list/comment_event.styles.ts index 42530c43101..8ef8471d794 100644 --- a/src/components/comment_list/comment_event.styles.ts +++ b/src/components/comment_list/comment_event.styles.ts @@ -7,42 +7,9 @@ */ import { css } from '@emotion/react'; -import { UseEuiTheme, tintOrShade } from '../../services'; +import { UseEuiTheme } from '../../services'; import { logicalCSS } from '../../global_styling'; -export const euiCommentEventBorderColors = ({ - euiTheme, - colorMode, -}: UseEuiTheme) => { - const ratio = 0.6; - return { - warning: css` - border-color: ${tintOrShade(euiTheme.colors.warning, 0.4, colorMode)}; - `, - accent: css` - border-color: ${tintOrShade(euiTheme.colors.accent, ratio, colorMode)}; - `, - primary: css` - border-color: ${tintOrShade(euiTheme.colors.primary, ratio, colorMode)}; - `, - success: css` - border-color: ${tintOrShade(euiTheme.colors.success, ratio, colorMode)}; - `, - danger: css` - border-color: ${tintOrShade(euiTheme.colors.danger, ratio, colorMode)}; - `, - subdued: css` - border-color: ${euiTheme.border.color}; - `, - transparent: css` - border-color: ${euiTheme.border.color}; - `, - plain: css` - border-color: ${euiTheme.border.color}; - `, - }; -}; - export const euiCommentEventStyles = (euiThemeContext: UseEuiTheme) => { const { euiTheme } = euiThemeContext; return { diff --git a/src/components/comment_list/comment_event.tsx b/src/components/comment_list/comment_event.tsx index 4747e3910c9..7e1a56af706 100644 --- a/src/components/comment_list/comment_event.tsx +++ b/src/components/comment_list/comment_event.tsx @@ -10,13 +10,13 @@ import React, { FunctionComponent, ReactNode, useMemo } from 'react'; import classNames from 'classnames'; import { useEuiTheme } from '../../services'; +import { useEuiBorderColorCSS } from '../../global_styling'; import { CommonProps } from '../common'; import { IconType } from '../icon'; import { EuiPanel, EuiPanelProps } from '../panel'; import { EuiAvatar } from '../avatar'; import { - euiCommentEventBorderColors, euiCommentEventStyles, euiCommentEventHeaderStyles, euiCommentEventBodyStyles, @@ -119,7 +119,7 @@ export const EuiCommentEvent: FunctionComponent = ({ * Styles */ const euiTheme = useEuiTheme(); - const borderStyles = euiCommentEventBorderColors(euiTheme); + const borderStyles = useEuiBorderColorCSS(); const styles = euiCommentEventStyles(euiTheme); const cssStyles = [ diff --git a/src/components/empty_prompt/__snapshots__/empty_prompt.test.tsx.snap b/src/components/empty_prompt/__snapshots__/empty_prompt.test.tsx.snap index 8682a97dbf0..b0316cdf1ab 100644 --- a/src/components/empty_prompt/__snapshots__/empty_prompt.test.tsx.snap +++ b/src/components/empty_prompt/__snapshots__/empty_prompt.test.tsx.snap @@ -3,14 +3,14 @@ exports[`EuiEmptyPrompt is rendered 1`] = `
+

+ Title +

+
-

- Title -

-
-
-

- Body -

-
-
-
- Actions -
+

+ Body +

+
+
+
+ Actions
@@ -52,22 +48,15 @@ exports[`EuiEmptyPrompt is rendered 1`] = ` exports[`EuiEmptyPrompt props actions renders alone 1`] = `
-
-
- actions -
+ actions
@@ -75,33 +64,26 @@ exports[`EuiEmptyPrompt props actions renders alone 1`] = ` exports[`EuiEmptyPrompt props actions renders an array 1`] = `
+ class="euiFlexItem emotion-euiFlexItem-growZero" + > + action1 +
-
- action1 -
-
- action2 -
+ action2
@@ -111,22 +93,18 @@ exports[`EuiEmptyPrompt props actions renders an array 1`] = ` exports[`EuiEmptyPrompt props body renders alone 1`] = `
-
- body -
+ body
@@ -135,165 +113,129 @@ exports[`EuiEmptyPrompt props body renders alone 1`] = ` exports[`EuiEmptyPrompt props color accent is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color danger is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color plain is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color primary is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color subdued is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color success is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color transparent is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props color warning is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props footer renders alone 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -302,38 +244,34 @@ exports[`EuiEmptyPrompt props footer renders alone 1`] = ` exports[`EuiEmptyPrompt props icon renders alone 1`] = `
Custom icon
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props iconType renders alone 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props iconType renders with iconColor 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props layout renders alone 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-horizontal" + />
`; exports[`EuiEmptyPrompt props paddingSize l is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props paddingSize m is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props paddingSize none is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props paddingSize s is rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props styles are rendered 1`] = `
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
`; exports[`EuiEmptyPrompt props title renders alone 1`] = `
-
- title -
+ title
diff --git a/src/components/empty_prompt/_empty_prompt.scss b/src/components/empty_prompt/_empty_prompt.scss deleted file mode 100644 index 188da8b0365..00000000000 --- a/src/components/empty_prompt/_empty_prompt.scss +++ /dev/null @@ -1,128 +0,0 @@ -.euiEmptyPrompt { - text-align: center; - margin: auto; - - @include euiBreakpoint('l', 'xl') { - max-width: max-content; // the width becomes as wide as necessary to contain all of its contents - } - - .euiEmptyPrompt__icon { - // Consumers should use an EuiImage (recommended) with the horizontal layout - // But they can use for example an img or other react node - > * { - flex-shrink: 1; - max-width: convertToRem(360px); - } - } - - // Footer background colors - @each $modifier, $color in $euiPanelBackgroundColorModifiers { - @if ($modifier == 'transparent') { - &.euiPanel--#{$modifier} { - .euiEmptyPrompt__footer { - background-color: $euiPageBackgroundColor; - } - - &:not(.euiPanel--hasBorder) .euiEmptyPrompt__footer { - border-radius: $euiBorderRadius; - } - - &.euiPanel--hasBorder .euiEmptyPrompt__footer { - border-radius: 0 0 $euiBorderRadius $euiBorderRadius; - } - } - } @else if ($modifier == 'plain') { - &.euiPanel--#{$modifier} .euiEmptyPrompt__footer { - background-color: $euiPageBackgroundColor; - border-radius: 0 0 $euiBorderRadius $euiBorderRadius; - } - } @else if ($modifier == 'subdued') { - &.euiPanel--#{$modifier} .euiEmptyPrompt__footer { - border-top: $euiBorderThin; - border-radius: 0 0 $euiBorderRadius $euiBorderRadius; - } - } @else { - &.euiPanel--#{$modifier} .euiEmptyPrompt__footer { - border-top: 1px solid lightOrDarkTheme(darken($color, 10%), lighten($color, 6%)); - border-radius: 0 0 $euiBorderRadius $euiBorderRadius; - } - } - } -} - -$euiEmptyPromptContentMaxWidth: 36em; - -.euiEmptyPrompt--vertical { - .euiEmptyPrompt__main { - display: flex; - flex-direction: column; - justify-content: center; - } - - .euiEmptyPrompt__contentInner { - max-width: $euiEmptyPromptContentMaxWidth; - margin: auto; - } - - .euiEmptyPrompt__icon { - margin-bottom: $euiSize; - } -} - -.euiEmptyPrompt--horizontal { - @include euiBreakpoint('l', 'xl') { - justify-content: flex-start; - text-align: left; - } - - .euiEmptyPrompt__main { - display: flex; - flex-direction: column; - align-items: center; - - @include euiBreakpoint('l', 'xl') { - flex-direction: row-reverse; - } - } - - .euiEmptyPrompt__icon { - display: flex; - align-items: center; - justify-content: center; - - @include euiBreakpoint('l', 'xl') { - min-width: 40%; - max-width: 50%; - } - } - - .euiEmptyPrompt__content { - max-width: $euiEmptyPromptContentMaxWidth; - - @include euiBreakpoint('l', 'xl') { - padding: $euiSizeL 0; - } - } - - .euiEmptyPrompt__actions { - @include euiBreakpoint('l', 'xl') { - justify-content: flex-start; - } - } -} - -// Padding -@each $modifier, $amount in $euiPanelPaddingModifiers { - .euiEmptyPrompt--#{$modifier} { - .euiEmptyPrompt__main, - .euiEmptyPrompt__footer { - padding: $amount; - } - - &.euiEmptyPrompt--horizontal { - .euiEmptyPrompt__main { - gap: $amount; - } - } - } -} diff --git a/src/components/empty_prompt/_index.scss b/src/components/empty_prompt/_index.scss deleted file mode 100644 index 7b7dacf4a1d..00000000000 --- a/src/components/empty_prompt/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'empty_prompt'; diff --git a/src/components/empty_prompt/empty_prompt.styles.ts b/src/components/empty_prompt/empty_prompt.styles.ts new file mode 100644 index 00000000000..81a18d02ef9 --- /dev/null +++ b/src/components/empty_prompt/empty_prompt.styles.ts @@ -0,0 +1,169 @@ +/* + * 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 { css } from '@emotion/react'; +import { + euiBreakpoint, + euiPaddingSize, + euiBorderColor, + logicalCSS, + mathWithUnits, +} from '../../global_styling'; +import { UseEuiTheme } from '../../services'; + +export const euiEmptyPromptStyles = (euiThemeContext: UseEuiTheme) => { + const { euiTheme } = euiThemeContext; + + const iconMaxWidth = mathWithUnits(euiTheme.size.l, (x) => x * 15); + + const generatePaddingStyles = (property = 'padding') => ({ + none: null, + s: css` + ${property}: ${euiPaddingSize(euiThemeContext, 's')} + `, + m: css` + ${property}: ${euiPaddingSize(euiThemeContext, 'm')} + `, + l: css` + ${property}: ${euiPaddingSize(euiThemeContext, 'l')} + `, + }); + + const generateFooterBorder = (color: Parameters[1]) => + `${euiTheme.border.width.thin} solid ${euiBorderColor( + euiThemeContext, + color + )}`; + + return { + euiEmptyPrompt: css` + text-align: center; + margin: auto; + + ${euiBreakpoint(euiThemeContext, ['l', 'xl'])} { + /* the width becomes as wide as necessary to contain all of its contents */ + ${logicalCSS('max-width', 'max-content')} + } + `, + vertical: css``, + horizontal: css` + ${euiBreakpoint(euiThemeContext, ['l', 'xl'])} { + justify-content: flex-start; + text-align: start; + } + `, + main: { + euiEmptyPrompt__main: css` + display: flex; + flex-direction: column; + `, + vertical: css` + justify-content: center; + `, + horizontal: css` + align-items: center; + + ${euiBreakpoint(euiThemeContext, ['l', 'xl'])} { + flex-direction: row-reverse; + } + `, + ...generatePaddingStyles(), + horizontalPadding: generatePaddingStyles('gap'), + }, + content: { + euiEmptyPrompt__content: css` + ${logicalCSS('max-width', '36em')} + `, + vertical: css` + margin: auto; + `, + horizontal: css` + ${euiBreakpoint(euiThemeContext, ['l', 'xl'])} { + padding-block: ${euiTheme.size.l}; + padding-inline: 0; + } + `, + }, + icon: { + euiEmptyPrompt__icon: css` + ${logicalCSS('max-width', iconMaxWidth)} + margin: auto; + + /* Consumers should use an EuiImage (recommended) with the horizontal layout + * But they can use for example an img or other react node */ + & > * { + flex-shrink: 1; + ${logicalCSS('max-width', '100%')} + } + `, + vertical: css` + ${logicalCSS('margin-bottom', euiTheme.size.base)} + `, + horizontal: css` + ${euiBreakpoint(euiThemeContext, ['l', 'xl'])} { + ${logicalCSS('min-width', '40%')} + ${logicalCSS('max-width', '50%')} + + /* I'm not totally sure why setting a percentage max width on the wrapper and a static + max-width on the underlying image/icon makes sense, but this ports over the previous Sass + styles as-is to avoid UI changes/regressions 🤷 */ + /* Note: The extra && selector specificity is there to override euiImageWrapper's CSS */ + && > * { + ${logicalCSS('max-width', iconMaxWidth)} + } + } + `, + }, + actions: { + euiEmptyPrompt__actions: css``, + vertical: css``, + horizontal: css` + ${euiBreakpoint(euiThemeContext, ['l', 'xl'])} { + justify-content: flex-start; + } + `, + }, + footer: { + euiEmptyPrompt__footer: css` + /* Round bottom corners only */ + border-end-end-radius: inherit; + border-end-start-radius: inherit; + `, + roundedBorders: css` + /* Round all corners */ + border-radius: inherit; + `, + // Colors + transparent: css` + background-color: ${euiTheme.colors.body}; + `, + plain: css` + background-color: ${euiTheme.colors.body}; + `, + subdued: css` + ${logicalCSS('border-top', generateFooterBorder('subdued'))} + `, + primary: css` + ${logicalCSS('border-top', generateFooterBorder('primary'))} + `, + accent: css` + ${logicalCSS('border-top', generateFooterBorder('accent'))} + `, + danger: css` + ${logicalCSS('border-top', generateFooterBorder('danger'))} + `, + warning: css` + ${logicalCSS('border-top', generateFooterBorder('warning'))} + `, + success: css` + ${logicalCSS('border-top', generateFooterBorder('success'))} + `, + ...generatePaddingStyles(), + }, + }; +}; diff --git a/src/components/empty_prompt/empty_prompt.test.tsx b/src/components/empty_prompt/empty_prompt.test.tsx index e63ecf36f18..dd87ba4166e 100644 --- a/src/components/empty_prompt/empty_prompt.test.tsx +++ b/src/components/empty_prompt/empty_prompt.test.tsx @@ -8,11 +8,15 @@ import React from 'react'; import { requiredProps } from '../../test'; +import { shouldRenderCustomStyles } from '../../test/internal'; import { render } from '../../test/rtl'; -import { EuiEmptyPrompt, PADDING_SIZES } from './empty_prompt'; + import { COLORS } from '../panel/panel'; +import { EuiEmptyPrompt, PADDING_SIZES } from './empty_prompt'; describe('EuiEmptyPrompt', () => { + shouldRenderCustomStyles(); + test('is rendered', () => { const { container } = render( = ({ footer, ...rest }) => { - const isVerticalLayout = layout === 'vertical'; + const classes = classNames('euiEmptyPrompt', className); + const euiTheme = useEuiTheme(); + const styles = useMemo(() => euiEmptyPromptStyles(euiTheme), [euiTheme]); + const cssStyles = [styles.euiEmptyPrompt, styles[layout]]; + const mainStyles = [ + styles.main.euiEmptyPrompt__main, + styles.main[layout], + styles.main[paddingSize], + layout === 'horizontal' && styles.main.horizontalPadding[paddingSize], + ]; + const contentStyles = [ + styles.content.euiEmptyPrompt__content, + styles.content[layout], + ]; + // Default the iconColor to `subdued`, // otherwise try to match the iconColor with the panel color unless iconColor is specified const iconColor = _iconColor ?? (isNamedColor(color) ? color : 'subdued'); + const iconNode = useMemo(() => { + if (!iconType && !icon) return null; + + const iconStyles = [styles.icon.euiEmptyPrompt__icon, styles.icon[layout]]; + return ( +
+ {iconType ? ( + + ) : ( + icon + )} +
+ ); + }, [icon, iconType, iconColor, layout, styles.icon]); - const iconNode = iconType ? ( - - ) : ( - icon - ); - - let titleNode; - let bodyNode; - if (body || title) { - if (title) { - titleNode = {title}; - } - - if (body) { - bodyNode = ( - <> - {title && } - {body} - - ); - } - } - - let actionsNode; - if (actions) { - let actionsRow; + const actionsNode = useMemo(() => { + if (!actions) return null; if (Array.isArray(actions)) { - actionsRow = ( + const actionStyles = [ + styles.actions.euiEmptyPrompt__actions, + styles.actions[layout], + ]; + return ( {actions.map((action, index) => ( @@ -145,50 +154,46 @@ export const EuiEmptyPrompt: FunctionComponent = ({ ); } else { - actionsRow = actions; + return actions; } - - actionsNode = ( - <> - - {actionsRow} - + }, [actions, layout, styles.actions]); + + const footerNode = useMemo(() => { + if (!footer) return null; + const footerStyles = [ + styles.footer.euiEmptyPrompt__footer, + styles.footer[paddingSize], + styles.footer[color], + color === 'transparent' && !hasBorder && styles.footer.roundedBorders, + ]; + return ( +
+ {footer} +
); - } - - const contentNodes = ( - <> - {titleNode} - {bodyNode} - {actionsNode} - - ); - - const classes = classNames( - 'euiEmptyPrompt', - [`euiEmptyPrompt--${layout}`], - paddingSizeToClassNameMap[paddingSize], - className - ); - - const panelProps: _EuiPanelDivlike = { - className: classes, - color: color, - paddingSize: 'none', - hasBorder: hasBorder, - grow: false, - ...rest, - }; + }, [footer, paddingSize, color, hasBorder, styles.footer]); return ( - -
- {iconNode &&
{iconNode}
} -
-
{contentNodes}
+ +
+ {iconNode} +
+ {title && {title}} + {title && body && } + {body && {body}} + {actionsNode && (body || title) && } + {actionsNode}
- {footer &&
{footer}
} + {footerNode}
); }; diff --git a/src/components/index.scss b/src/components/index.scss index 0cba396fc05..89b68c2b2f9 100644 --- a/src/components/index.scss +++ b/src/components/index.scss @@ -4,7 +4,6 @@ @import 'combo_box/index'; @import 'date_picker/index'; @import 'datagrid/index'; -@import 'empty_prompt/index'; @import 'form/index'; @import 'markdown_editor/index'; @import 'tree_view/index'; diff --git a/src/components/page_template/empty_prompt/__snapshots__/page_empty_prompt.test.tsx.snap b/src/components/page_template/empty_prompt/__snapshots__/page_empty_prompt.test.tsx.snap index 60e931b2974..e9932078add 100644 --- a/src/components/page_template/empty_prompt/__snapshots__/page_empty_prompt.test.tsx.snap +++ b/src/components/page_template/empty_prompt/__snapshots__/page_empty_prompt.test.tsx.snap @@ -8,13 +8,13 @@ exports[`_EuiPageEmptyPrompt EuiEmptyPromptProps is rendered 1`] = ` class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-horizontal" + />
@@ -47,18 +43,14 @@ exports[`_EuiPageEmptyPrompt EuiPageSectionProps is rendered 1`] = ` class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -74,19 +66,15 @@ exports[`_EuiPageEmptyPrompt is rendered 1`] = ` >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -101,18 +89,14 @@ exports[`_EuiPageEmptyPrompt paddingSize l is rendered 1`] = ` class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -127,18 +111,14 @@ exports[`_EuiPageEmptyPrompt paddingSize m is rendered 1`] = ` class="emotion-euiPageSection__content-m-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -153,18 +133,14 @@ exports[`_EuiPageEmptyPrompt paddingSize none is rendered 1`] = ` class="emotion-euiPageSection__content-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -179,18 +155,14 @@ exports[`_EuiPageEmptyPrompt paddingSize s is rendered 1`] = ` class="emotion-euiPageSection__content-s-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -205,18 +177,14 @@ exports[`_EuiPageEmptyPrompt paddingSize xl is rendered 1`] = ` class="emotion-euiPageSection__content-xl-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -231,18 +199,14 @@ exports[`_EuiPageEmptyPrompt paddingSize xs is rendered 1`] = ` class="emotion-euiPageSection__content-xs-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -257,18 +221,14 @@ exports[`_EuiPageEmptyPrompt panelled is false and color is defined, then the pr class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -283,18 +243,14 @@ exports[`_EuiPageEmptyPrompt panelled is false and color is not defined, then th class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -309,18 +265,14 @@ exports[`_EuiPageEmptyPrompt panelled is true and color is defined, then the pro class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -335,18 +287,14 @@ exports[`_EuiPageEmptyPrompt panelled is true and color is not defined, then the class="emotion-euiPageSection__content-l-center" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -362,18 +310,14 @@ exports[`_EuiPageEmptyPrompt restrict width can be set to a custom number 1`] = style="max-width: 1024px;" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -389,18 +333,14 @@ exports[`_EuiPageEmptyPrompt restrict width can be set to a custom value and mea style="max-width: 24rem;" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
@@ -416,18 +356,14 @@ exports[`_EuiPageEmptyPrompt restrict width can be set to a default 1`] = ` style="max-width: 1200px;" >
-
-
+ class="euiEmptyPrompt__content emotion-euiEmptyPrompt__content-vertical" + />
diff --git a/src/global_styling/mixins/__snapshots__/_color.test.ts.snap b/src/global_styling/mixins/__snapshots__/_color.test.ts.snap index 683633a24d1..4bb1d1a0dc4 100644 --- a/src/global_styling/mixins/__snapshots__/_color.test.ts.snap +++ b/src/global_styling/mixins/__snapshots__/_color.test.ts.snap @@ -47,3 +47,19 @@ exports[`useEuiBackgroundColorCSS hook returns an object of Emotion background-c exports[`useEuiBackgroundColorCSS hook returns an object of Emotion background-color properties for each color: transparent 1`] = `"background-color:transparent;;label:transparent;"`; exports[`useEuiBackgroundColorCSS hook returns an object of Emotion background-color properties for each color: warning 1`] = `"background-color:#fff9e8;;label:warning;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: accent 1`] = `"border-color:#f9b8d6;;label:accent;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: danger 1`] = `"border-color:#e5a9a5;;label:danger;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: plain 1`] = `"border-color:#D3DAE6;;label:plain;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: primary 1`] = `"border-color:#99c9eb;;label:primary;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: subdued 1`] = `"border-color:#D3DAE6;;label:subdued;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: success 1`] = `"border-color:#99e5e1;;label:success;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: transparent 1`] = `"border-color:#D3DAE6;;label:transparent;"`; + +exports[`useEuiBorderColorCSS hook returns an object of Emotion border-color properties for each color: warning 1`] = `"border-color:#fedc72;;label:warning;"`; diff --git a/src/global_styling/mixins/_color.test.ts b/src/global_styling/mixins/_color.test.ts index 7f7470c31e5..bd0dc237dc5 100644 --- a/src/global_styling/mixins/_color.test.ts +++ b/src/global_styling/mixins/_color.test.ts @@ -11,6 +11,7 @@ import { BACKGROUND_COLORS, useEuiBackgroundColor, useEuiBackgroundColorCSS, + useEuiBorderColorCSS, } from './_color'; describe('useEuiBackgroundColor mixin returns a calculated background version', () => { @@ -46,3 +47,15 @@ describe('useEuiBackgroundColorCSS hook returns an object of Emotion background- }); }); }); + +describe('useEuiBorderColorCSS hook returns an object of Emotion border-color properties', () => { + const colors = renderHook(useEuiBorderColorCSS).result.current as any; + + describe('for each color:', () => { + Object.entries(colors).map(([color, cssObj]) => { + it(color, () => { + expect((cssObj as any).styles).toMatchSnapshot(); + }); + }); + }); +}); diff --git a/src/global_styling/mixins/_color.ts b/src/global_styling/mixins/_color.ts index 4c2090c5e50..80c35b5c336 100644 --- a/src/global_styling/mixins/_color.ts +++ b/src/global_styling/mixins/_color.ts @@ -6,10 +6,12 @@ * Side Public License, v 1. */ +import { useMemo } from 'react'; import { css } from '@emotion/react'; import { shade, tint, + tintOrShade, transparentize, useEuiTheme, UseEuiTheme, @@ -77,30 +79,85 @@ export const useEuiBackgroundColor = ( }; export const useEuiBackgroundColorCSS = () => { - return { - transparent: css` - background-color: ${useEuiBackgroundColor('transparent')}; - `, - plain: css` - background-color: ${useEuiBackgroundColor('plain')}; - `, - subdued: css` - background-color: ${useEuiBackgroundColor('subdued')}; - `, - accent: css` - background-color: ${useEuiBackgroundColor('accent')}; - `, - primary: css` - background-color: ${useEuiBackgroundColor('primary')}; - `, - success: css` - background-color: ${useEuiBackgroundColor('success')}; - `, - warning: css` - background-color: ${useEuiBackgroundColor('warning')}; - `, - danger: css` - background-color: ${useEuiBackgroundColor('danger')}; - `, - }; + const euiThemeContext = useEuiTheme(); + + return useMemo( + () => ({ + transparent: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'transparent')}; + `, + plain: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'plain')}; + `, + subdued: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'subdued')}; + `, + accent: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'accent')}; + `, + primary: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'primary')}; + `, + success: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'success')}; + `, + warning: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'warning')}; + `, + danger: css` + background-color: ${euiBackgroundColor(euiThemeContext, 'danger')}; + `, + }), + [euiThemeContext] + ); +}; + +export const euiBorderColor = ( + { euiTheme, colorMode }: UseEuiTheme, + color: _EuiBackgroundColor +) => { + switch (color) { + case 'transparent': + case 'plain': + case 'subdued': + return euiTheme.border.color; + case 'warning': + return tintOrShade(euiTheme.colors.warning, 0.4, colorMode); + default: + return tintOrShade(euiTheme.colors[color], 0.6, colorMode); + } +}; + +export const useEuiBorderColorCSS = () => { + const euiThemeContext = useEuiTheme(); + + return useMemo( + () => ({ + transparent: css` + border-color: ${euiBorderColor(euiThemeContext, 'transparent')}; + `, + plain: css` + border-color: ${euiBorderColor(euiThemeContext, 'plain')}; + `, + subdued: css` + border-color: ${euiBorderColor(euiThemeContext, 'subdued')}; + `, + accent: css` + border-color: ${euiBorderColor(euiThemeContext, 'accent')}; + `, + primary: css` + border-color: ${euiBorderColor(euiThemeContext, 'primary')}; + `, + success: css` + border-color: ${euiBorderColor(euiThemeContext, 'success')}; + `, + warning: css` + border-color: ${euiBorderColor(euiThemeContext, 'warning')}; + `, + danger: css` + border-color: ${euiBorderColor(euiThemeContext, 'danger')}; + `, + }), + [euiThemeContext] + ); }; From ff192553ecaa74513ad9fa6167e90a30e7fe56dc Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Fri, 2 Feb 2024 09:16:39 -0800 Subject: [PATCH 02/12] [EuiTourStep] `className` consistency with EuiPopover + performance/cleanups (#7497) --- changelogs/upcoming/7497.md | 4 + .../beacon/__snapshots__/beacon.test.tsx.snap | 16 +- src/components/beacon/beacon.tsx | 20 +- .../__snapshots__/tour_step.test.tsx.snap | 592 ++---------------- src/components/tour/_tour_footer.styles.ts | 28 + src/components/tour/_tour_footer.tsx | 125 ++++ src/components/tour/_tour_header.styles.ts | 29 + src/components/tour/_tour_header.tsx | 47 ++ src/components/tour/tour.styles.ts | 50 +- src/components/tour/tour_step.test.tsx | 96 ++- src/components/tour/tour_step.tsx | 237 ++----- 11 files changed, 456 insertions(+), 788 deletions(-) create mode 100644 changelogs/upcoming/7497.md create mode 100644 src/components/tour/_tour_footer.styles.ts create mode 100644 src/components/tour/_tour_footer.tsx create mode 100644 src/components/tour/_tour_header.styles.ts create mode 100644 src/components/tour/_tour_header.tsx diff --git a/changelogs/upcoming/7497.md b/changelogs/upcoming/7497.md new file mode 100644 index 00000000000..89b9fccebcd --- /dev/null +++ b/changelogs/upcoming/7497.md @@ -0,0 +1,4 @@ +**Breaking changes** + +- `EuiTourStep`'s `className` and `style` props now apply to the anchoring element instead of to the popover panel, to match `EuiPopover` behavior. + - Convert your existing usages to `panelClassName` and `panelStyle` respectively instead. diff --git a/src/components/beacon/__snapshots__/beacon.test.tsx.snap b/src/components/beacon/__snapshots__/beacon.test.tsx.snap index 55c5dfc918b..bfc036891eb 100644 --- a/src/components/beacon/__snapshots__/beacon.test.tsx.snap +++ b/src/components/beacon/__snapshots__/beacon.test.tsx.snap @@ -5,7 +5,7 @@ exports[`EuiBeacon is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-success-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -14,7 +14,7 @@ exports[`EuiBeacon props color accent is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-accent-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -23,7 +23,7 @@ exports[`EuiBeacon props color danger is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-danger-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -32,7 +32,7 @@ exports[`EuiBeacon props color primary is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-primary-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -41,7 +41,7 @@ exports[`EuiBeacon props color subdued is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-subdued-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -50,7 +50,7 @@ exports[`EuiBeacon props color success is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-success-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -59,7 +59,7 @@ exports[`EuiBeacon props color warning is rendered 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-warning-euiTestCss" data-test-subj="test subject string" - style="height: 12px; width: 12px;" + style="block-size: 12px; inline-size: 12px;" /> `; @@ -68,6 +68,6 @@ exports[`EuiBeacon props size accepts size 1`] = ` aria-label="aria-label" class="euiBeacon testClass1 testClass2 emotion-euiBeacon-success-euiTestCss" data-test-subj="test subject string" - style="height: 14px; width: 14px;" + style="block-size: 14px; inline-size: 14px;" /> `; diff --git a/src/components/beacon/beacon.tsx b/src/components/beacon/beacon.tsx index b0070e00217..acea33586f2 100644 --- a/src/components/beacon/beacon.tsx +++ b/src/components/beacon/beacon.tsx @@ -6,13 +6,15 @@ * Side Public License, v 1. */ -import React, { FunctionComponent, HTMLAttributes } from 'react'; +import React, { FunctionComponent, HTMLAttributes, useMemo } from 'react'; import { CommonProps } from '../common'; import classNames from 'classnames'; -import { euiBeaconStyles } from './beacon.styles'; +import { logicalStyles } from '../../global_styling'; import { useEuiTheme } from '../../services'; +import { euiBeaconStyles } from './beacon.styles'; + export const COLORS = [ 'subdued', 'primary', @@ -51,11 +53,15 @@ export const EuiBeacon: FunctionComponent = ({ const styles = euiBeaconStyles(euiTheme); const cssStyles = [styles.euiBeacon, styles[color]]; - const beaconStyle = { - ...style, - height: size, - width: size, - }; + const beaconStyle = useMemo( + () => + logicalStyles({ + ...style, + height: size, + width: size, + }), + [style, size] + ); return (
diff --git a/src/components/tour/__snapshots__/tour_step.test.tsx.snap b/src/components/tour/__snapshots__/tour_step.test.tsx.snap index 4ba2a0953aa..0aa353e4849 100644 --- a/src/components/tour/__snapshots__/tour_step.test.tsx.snap +++ b/src/components/tour/__snapshots__/tour_step.test.tsx.snap @@ -1,565 +1,99 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`EuiTourStep accepts an array of buttons in the footerAction prop 1`] = ` -
- - Test - -
-
+exports[`EuiTourStep renders 1`] = ` + +
-
-
-`; - -exports[`EuiTourStep can be closed 1`] = ` -
- - Test - -
-`; - -exports[`EuiTourStep can change the minWidth and maxWidth 1`] = ` -
- - Test - -
-
- -
-
-`; - -exports[`EuiTourStep can have subtitle 1`] = ` -
- - Test - -
-
-