From 441dec242236d54222127fe720bd084aee2ae6a6 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Wed, 21 Sep 2022 13:04:03 -0700 Subject: [PATCH 1/8] Convert EuiBadgeGroup to Emotion - opinionated refactor: Use `inline-flex` and `gap` instead of inline-block and margins - doing so remove the needs for `euiBadgeGroup__item` --- src/components/badge/_index.scss | 1 - .../__snapshots__/badge_group.test.tsx.snap | 22 +++++------- .../badge/badge_group/_badge_group.scss | 23 ------------- src/components/badge/badge_group/_index.scss | 1 - .../badge/badge_group/badge_group.styles.ts | 34 +++++++++++++++++++ .../badge/badge_group/badge_group.test.tsx | 3 ++ .../badge/badge_group/badge_group.tsx | 33 ++++++++---------- 7 files changed, 60 insertions(+), 57 deletions(-) delete mode 100644 src/components/badge/badge_group/_badge_group.scss delete mode 100644 src/components/badge/badge_group/_index.scss create mode 100644 src/components/badge/badge_group/badge_group.styles.ts diff --git a/src/components/badge/_index.scss b/src/components/badge/_index.scss index f35a82d92fb..0c0e83aac4f 100644 --- a/src/components/badge/_index.scss +++ b/src/components/badge/_index.scss @@ -1,3 +1,2 @@ -@import 'badge_group/index'; @import 'beta_badge/index'; @import 'notification_badge/index'; diff --git a/src/components/badge/badge_group/__snapshots__/badge_group.test.tsx.snap b/src/components/badge/badge_group/__snapshots__/badge_group.test.tsx.snap index 18b270c05e1..e77c89dd12f 100644 --- a/src/components/badge/badge_group/__snapshots__/badge_group.test.tsx.snap +++ b/src/components/badge/badge_group/__snapshots__/badge_group.test.tsx.snap @@ -2,43 +2,39 @@ exports[`EuiBadgeGroup gutterSize none is rendered 1`] = `
`; exports[`EuiBadgeGroup gutterSize s is rendered 1`] = `
`; exports[`EuiBadgeGroup gutterSize xs is rendered 1`] = `
`; exports[`EuiBadgeGroup is rendered 1`] = `
- - Content - + Content diff --git a/src/components/badge/badge_group/_badge_group.scss b/src/components/badge/badge_group/_badge_group.scss deleted file mode 100644 index a1a0b0ec5d3..00000000000 --- a/src/components/badge/badge_group/_badge_group.scss +++ /dev/null @@ -1,23 +0,0 @@ -$euiBadgeGroupGutterTypes: ( - gutterExtraSmall: $euiSizeXS, - gutterSmall: $euiSizeS, -); - -.euiBadgeGroup__item { - display: inline-block; - max-width: 100%; -} - -// Gutter Sizes -@each $gutterName, $gutterSize in $euiBadgeGroupGutterTypes { - $halfGutterSize: $gutterSize * .5; - - .euiBadgeGroup--#{$gutterName} { - margin: -$halfGutterSize; - - & > .euiBadgeGroup__item { - margin: $halfGutterSize; - max-width: calc(100% - #{$gutterSize}); - } - } -} diff --git a/src/components/badge/badge_group/_index.scss b/src/components/badge/badge_group/_index.scss deleted file mode 100644 index 21500c4a8cf..00000000000 --- a/src/components/badge/badge_group/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './badge_group'; diff --git a/src/components/badge/badge_group/badge_group.styles.ts b/src/components/badge/badge_group/badge_group.styles.ts new file mode 100644 index 00000000000..2258dcc7a4c --- /dev/null +++ b/src/components/badge/badge_group/badge_group.styles.ts @@ -0,0 +1,34 @@ +/* + * 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 { logicalCSS } from '../../../global_styling'; +import { UseEuiTheme } from '../../../services'; + +export const euiBadgeGroupStyles = ({ euiTheme }: UseEuiTheme) => { + return { + euiBadgeGroup: css` + display: inline-flex; + flex-wrap: wrap; + ${logicalCSS('max-width', '100%')} + + // Override the .euiBadge + .euiBadge CSS in badge.styles.ts + .euiBadge { + ${logicalCSS('margin-left', 0)} + } + `, + // Gutter sizes + none: css``, + s: css` + gap: ${euiTheme.size.s}; + `, + xs: css` + gap: ${euiTheme.size.xs}; + `, + }; +}; diff --git a/src/components/badge/badge_group/badge_group.test.tsx b/src/components/badge/badge_group/badge_group.test.tsx index 455a42bc282..20d844315b7 100644 --- a/src/components/badge/badge_group/badge_group.test.tsx +++ b/src/components/badge/badge_group/badge_group.test.tsx @@ -9,11 +9,14 @@ import React from 'react'; import { render } from 'enzyme'; import { requiredProps } from '../../../test/required_props'; +import { shouldRenderCustomStyles } from '../../../test/internal'; import { EuiBadge } from '../badge'; import { EuiBadgeGroup, GUTTER_SIZES } from './badge_group'; describe('EuiBadgeGroup', () => { + shouldRenderCustomStyles(); + test('is rendered', () => { const component = render( diff --git a/src/components/badge/badge_group/badge_group.tsx b/src/components/badge/badge_group/badge_group.tsx index 02f64c3c663..29ae779d684 100644 --- a/src/components/badge/badge_group/badge_group.tsx +++ b/src/components/badge/badge_group/badge_group.tsx @@ -8,16 +8,13 @@ import React, { forwardRef, HTMLAttributes, Ref, ReactNode } from 'react'; import classNames from 'classnames'; -import { CommonProps, keysOf } from '../../common'; +import { CommonProps } from '../../common'; +import { useEuiTheme } from '../../../services'; -const gutterSizeToClassNameMap = { - none: null, - xs: 'euiBadgeGroup--gutterExtraSmall', - s: 'euiBadgeGroup--gutterSmall', -}; +import { euiBadgeGroupStyles } from './badge_group.styles'; -export const GUTTER_SIZES = keysOf(gutterSizeToClassNameMap); -type BadgeGroupGutterSize = keyof typeof gutterSizeToClassNameMap; +export const GUTTER_SIZES = ['none', 'xs', 's'] as const; +type BadgeGroupGutterSize = typeof GUTTER_SIZES[number]; export interface EuiBadgeGroupProps { /** @@ -25,8 +22,7 @@ export interface EuiBadgeGroupProps { */ gutterSize?: BadgeGroupGutterSize; /** - * Should be a list of EuiBadge's but can also be any other element - * Will apply an extra class to add spacing + * Should be a list of `EuiBadge`s, but can also be any other element */ children?: ReactNode; } @@ -39,17 +35,16 @@ export const EuiBadgeGroup = forwardRef< { children, className, gutterSize = 'xs', ...rest }, ref: Ref ) => { - const classes = classNames( - 'euiBadgeGroup', - gutterSizeToClassNameMap[gutterSize as BadgeGroupGutterSize], - className - ); + const euiTheme = useEuiTheme(); + + const styles = euiBadgeGroupStyles(euiTheme); + const cssStyles = [styles.euiBadgeGroup, styles[gutterSize]]; + + const classes = classNames('euiBadgeGroup', className); return ( -
- {React.Children.map(children, (child: ReactNode) => ( - {child} - ))} +
+ {children}
); } From 9c99675e4a39bff763f9188a93faa8cdaf321462 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Wed, 21 Sep 2022 14:15:59 -0700 Subject: [PATCH 2/8] Convert EuiBetaBadge to Emotion - opinionated refactor: simplify `s` font-size to static rem (since .625 doesn't match the ratio of any current font scales) - remove isClickable CSS / classNames - it's not actually being used anywhere that I can tell - add unit tests for badge circle display --- src/components/badge/_index.scss | 1 - .../__snapshots__/beta_badge.test.tsx.snap | 37 +++++-- .../badge/beta_badge/_beta_badge.scss | 91 ----------------- src/components/badge/beta_badge/_index.scss | 1 - .../badge/beta_badge/beta_badge.styles.ts | 97 +++++++++++++++++++ .../badge/beta_badge/beta_badge.test.tsx | 12 +++ .../badge/beta_badge/beta_badge.tsx | 71 +++++++------- .../card/__snapshots__/card.test.tsx.snap | 2 +- .../key_pad_menu_item.test.tsx.snap | 10 +- 9 files changed, 182 insertions(+), 140 deletions(-) delete mode 100644 src/components/badge/beta_badge/_beta_badge.scss delete mode 100644 src/components/badge/beta_badge/_index.scss create mode 100644 src/components/badge/beta_badge/beta_badge.styles.ts diff --git a/src/components/badge/_index.scss b/src/components/badge/_index.scss index 0c0e83aac4f..99e21b9d265 100644 --- a/src/components/badge/_index.scss +++ b/src/components/badge/_index.scss @@ -1,2 +1 @@ -@import 'beta_badge/index'; @import 'notification_badge/index'; diff --git a/src/components/badge/beta_badge/__snapshots__/beta_badge.test.tsx.snap b/src/components/badge/beta_badge/__snapshots__/beta_badge.test.tsx.snap index aaf2530f6db..e4b97cf2866 100644 --- a/src/components/badge/beta_badge/__snapshots__/beta_badge.test.tsx.snap +++ b/src/components/badge/beta_badge/__snapshots__/beta_badge.test.tsx.snap @@ -3,7 +3,7 @@ exports[`EuiBetaBadge is rendered 1`] = ` @@ -13,7 +13,7 @@ exports[`EuiBetaBadge is rendered 1`] = ` exports[`EuiBetaBadge props color accent is rendered 1`] = ` Beta @@ -22,7 +22,7 @@ exports[`EuiBetaBadge props color accent is rendered 1`] = ` exports[`EuiBetaBadge props color hollow is rendered 1`] = ` Beta @@ -31,16 +31,39 @@ exports[`EuiBetaBadge props color hollow is rendered 1`] = ` exports[`EuiBetaBadge props color subdued is rendered 1`] = ` Beta `; +exports[`EuiBetaBadge props iconType 1`] = ` + + +`; + +exports[`EuiBetaBadge props single letter 1`] = ` + + B + +`; + exports[`EuiBetaBadge props size m is rendered 1`] = ` Beta @@ -49,7 +72,7 @@ exports[`EuiBetaBadge props size m is rendered 1`] = ` exports[`EuiBetaBadge props size s is rendered 1`] = ` Beta @@ -62,7 +85,7 @@ exports[`EuiBetaBadge props tooltip and anchorProps are rendered 1`] = ` data-test-subj="DTS" > diff --git a/src/components/badge/beta_badge/_beta_badge.scss b/src/components/badge/beta_badge/_beta_badge.scss deleted file mode 100644 index 30609421115..00000000000 --- a/src/components/badge/beta_badge/_beta_badge.scss +++ /dev/null @@ -1,91 +0,0 @@ -.euiBetaBadge { - display: inline-block; - padding: 0 $euiSize; - border-radius: $euiSizeL; - box-shadow: inset 0 0 0 1px $euiBorderColor; - vertical-align: super; // if displayed inline with text - - font-size: $euiFontSizeXS; - font-weight: $euiFontWeightBold; - text-transform: uppercase; - letter-spacing: .05em; - line-height: $euiSizeL; - text-align: center; - white-space: nowrap; - cursor: default; - overflow: hidden; - text-overflow: ellipsis; - - &:focus { - @include euiFocusRing; - // Can't use `currentColor` because of possible white text, so always keep it black - outline-color: lightOrDarkTheme($euiColorInk, $euiColorGhost); - // The rounded corners of the badge doesn't match well with the outline, so push it outward - outline-offset: 2px; - } - - &:not(.euiBetaBadge--hollow) { - box-shadow: none; - } - - &.euiBetaBadge--small { - @include fontSize($euiFontSize * .625); - line-height: $euiSize + $euiSizeXS; - padding: 0 $euiSizeM; - } -} - -// When it's just an icon, make it a circle -.euiBetaBadge--iconOnly { - padding: 0; - width: $euiSizeL; - - .euiBetaBadge__icon { - position: relative; - transform: translate(0, -1px); - } - - &.euiBetaBadge--small { - width: $euiSize + $euiSizeXS; - padding: 0; - } -} - -.euiBetaBadge--singleLetter { - padding: 0; - width: $euiSizeL; - - &.euiBetaBadge--small { - width: $euiSize + $euiSizeXS; - padding: 0; - } -} - -.euiBetaBadge--subdued { - $backgroundColor: tint($euiColorLightShade, 30%); - background: $backgroundColor; - color: chooseLightOrDarkText($backgroundColor, $euiColorGhost, $euiColorInk); - - &.euiBetaBadge-isClickable { - color: chooseLightOrDarkText($backgroundColor, $euiColorGhost, $euiColorInk); - } -} - -.euiBetaBadge--hollow { - background-color: $euiColorEmptyShade; - - &.euiBetaBadge-isClickable { - $backgroundColor: tint($euiColorLightShade, 30%); - color: chooseLightOrDarkText($euiColorEmptyShade, $euiColorGhost, $euiColorInk); - } -} - -.euiBetaBadge--accent { - $backgroundColor: $euiColorAccentText; - background: $backgroundColor; - color: chooseLightOrDarkText($backgroundColor, $euiColorGhost, $euiColorInk); - - &.euiBetaBadge-isClickable { - color: chooseLightOrDarkText($backgroundColor, $euiColorGhost, $euiColorInk); - } -} diff --git a/src/components/badge/beta_badge/_index.scss b/src/components/badge/beta_badge/_index.scss deleted file mode 100644 index 10c53901b29..00000000000 --- a/src/components/badge/beta_badge/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'beta_badge'; diff --git a/src/components/badge/beta_badge/beta_badge.styles.ts b/src/components/badge/beta_badge/beta_badge.styles.ts new file mode 100644 index 00000000000..41150c11acf --- /dev/null +++ b/src/components/badge/beta_badge/beta_badge.styles.ts @@ -0,0 +1,97 @@ +/* + * 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 { + logicalCSS, + euiFocusRing, + euiFontSizeFromScale, + mathWithUnits, +} from '../../../global_styling'; +import { UseEuiTheme, tint } from '../../../services'; + +export const euiBetaBadgeStyles = (euiThemeContext: UseEuiTheme) => { + const { euiTheme, colorMode } = euiThemeContext; + + const textColor = + colorMode === 'DARK' ? euiTheme.colors.ghost : euiTheme.colors.ink; + const invertedTextColor = + colorMode === 'DARK' ? euiTheme.colors.ink : euiTheme.colors.ghost; + + return { + euiBetaBadge: css` + display: inline-block; + vertical-align: super; // if displayed inline with text + border-radius: ${euiTheme.size.l}; + cursor: default; + + font-weight: ${euiTheme.font.weight.bold}; + text-transform: uppercase; + letter-spacing: 0.05em; + text-align: center; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:focus { + ${euiFocusRing(euiThemeContext, 'outset', { + color: textColor, + })} + } + `, + // Colors + accent: css` + background-color: ${euiTheme.colors.accentText}; + color: ${invertedTextColor}; + `, + subdued: css` + background-color: ${tint(euiTheme.colors.lightShade, 0.3)}; + color: ${textColor}; + `, + hollow: css` + background-color: ${euiTheme.colors.emptyShade}; + color: ${textColor}; + box-shadow: inset 0 0 0 ${euiTheme.border.width.thin} + ${euiTheme.border.color}; + `, + // Font sizes + m: css` + font-size: ${euiFontSizeFromScale('xs', euiTheme)}; + line-height: ${euiTheme.size.l}; + `, + s: css` + font-size: 0.625rem; + line-height: ${mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base)}; + `, + // Padding/width sizes + badgeSizes: { + default: { + m: ` + ${logicalCSS('padding-horizontal', euiTheme.size.base)}`, + s: ` + ${logicalCSS('padding-horizontal', euiTheme.size.m)}`, + }, + // When it's just an icon or a single letter, make the badge a circle + circle: { + m: ` + ${logicalCSS('width', euiTheme.size.l)} + `, + s: ` + ${logicalCSS( + 'width', + mathWithUnits(euiTheme.size.xs, (x) => x + euiTheme.base) + )} + `, + }, + }, + euiBetaBadge__icon: css` + position: relative; + transform: translate(0, -1px); + `, + }; +}; diff --git a/src/components/badge/beta_badge/beta_badge.test.tsx b/src/components/badge/beta_badge/beta_badge.test.tsx index 165fc3e6f71..7537cdef2d8 100644 --- a/src/components/badge/beta_badge/beta_badge.test.tsx +++ b/src/components/badge/beta_badge/beta_badge.test.tsx @@ -46,6 +46,18 @@ describe('EuiBetaBadge', () => { }); }); + test('iconType', () => { + const component = render(); + + expect(component).toMatchSnapshot(); + }); + + test('single letter', () => { + const component = render(); + + expect(component).toMatchSnapshot(); + }); + test('tooltip and anchorProps are rendered', () => { const component = render( = ({ size = 'm', ...rest }) => { - let singleLetter = false; - if (typeof label === 'string' && label.length === 1) { - singleLetter = true; - } + const euiTheme = useEuiTheme(); + + const singleLetter = !!(typeof label === 'string' && label.length === 1); + const isCircular = iconType || singleLetter; - const classes = classNames( - 'euiBetaBadge', - { - 'euiBetaBadge--iconOnly': iconType, - 'euiBetaBadge--singleLetter': singleLetter, - 'euiBetaBadge-isClickable': onClick || href, - }, - colorToClassMap[color], - sizeToClassMap[size], - className - ); + const classes = classNames('euiBetaBadge', className); + + const styles = euiBetaBadgeStyles(euiTheme); + const cssStyles = [ + styles.euiBetaBadge, + styles[color], + styles[size], + isCircular + ? styles.badgeSizes.circle[size] + : styles.badgeSizes.default[size], + ]; let icon: JSX.Element | undefined; if (iconType) { icon = ( = ({ content = ( )} @@ -234,7 +226,13 @@ export const EuiBetaBadge: FunctionComponent = ({ title={title || label} anchorProps={anchorProps} > - + {icon || label} @@ -247,7 +245,12 @@ export const EuiBetaBadge: FunctionComponent = ({ ); } return ( - + {icon || label} ); diff --git a/src/components/card/__snapshots__/card.test.tsx.snap b/src/components/card/__snapshots__/card.test.tsx.snap index 134f3993802..b75bbc0d28e 100644 --- a/src/components/card/__snapshots__/card.test.tsx.snap +++ b/src/components/card/__snapshots__/card.test.tsx.snap @@ -27,7 +27,7 @@ exports[`EuiCard betaBadgeProps renders href 1`] = `