Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Ensure that `EuiCallOut` components rendered conditionally have the `announceOnM

### `@elastic/eui/no-unnamed-interactive-element`

Ensure that appropriate aria-attributes are set for `EuiBetaBadge`, `EuiButtonIcon`, `EuiComboBox`, `EuiSelect`, `EuiSelectWithWidth`,`EuiSuperSelect`,`EuiPagination`, `EuiTreeView`, `EuiBreadcrumbs`. Without this rule, screen reader users lose context, keyboard navigation can be confusing.
Ensure that appropriate aria-attributes are set for `EuiBadge`, `EuiButtonIcon`, `EuiComboBox`, `EuiSelect`, `EuiSelectWithWidth`,`EuiSuperSelect`,`EuiPagination`, `EuiTreeView`, `EuiBreadcrumbs`. Without this rule, screen reader users lose context, keyboard navigation can be confusing.

### `@elastic/eui/tooltip-focusable-anchor`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const languageOptions = {
ruleTester.run('NoUnnamedInteractiveElement', NoUnnamedInteractiveElement, {
valid: [
// Components with allowed a11y props
{ code: '<EuiBetaBadge aria-label="Beta badge" />', languageOptions },
{ code: '<EuiBadge aria-label="Badge" />', languageOptions },
{ code: '<EuiButtonIcon aria-label="Icon" />', languageOptions },
{ code: '<EuiComboBox aria-label="Combo label" />', languageOptions },
{ code: '<EuiSelect aria-label="Select label" />', languageOptions },
Expand Down Expand Up @@ -57,7 +57,7 @@ ruleTester.run('NoUnnamedInteractiveElement', NoUnnamedInteractiveElement, {
invalid: [
// Missing a11y prop for interactive components
{
code: '<EuiBetaBadge />',
code: '<EuiBadge />',
languageOptions,
errors: [{ messageId: 'missingA11y' }],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { hasA11yPropForComponent } from '../../utils/has_a11y_prop_for_component';

const interactiveComponents = [
'EuiBetaBadge',
'EuiBadge',
'EuiButtonIcon',
'EuiComboBox',
'EuiSelect',
Expand All @@ -27,7 +27,7 @@ const interactiveComponents = [
] as const;

const wrappingComponents = ['EuiFormRow'] as const;
const interactiveComponentsWithLabel = ['EuiBetaBadge'] as const;
const interactiveComponentsWithLabel = ['EuiBadge'] as const;
const baseA11yProps = ['aria-label', 'aria-labelledby'] as const;

// Single source of truth for the utils (keeps them reusable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const NON_INTERACTIVE_ELEMENTS = [
'EuiText',
'EuiImage',
'EuiBadge',
'EuiBetaBadge'
];

const INTERACTIVE_ATTRS = [
Expand Down
1 change: 0 additions & 1 deletion packages/eslint-plugin/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export const INTERACTIVE_EUI_COMPONENTS = [
'EuiFilterSelectItem',
'EuiFilterSelectable',
'EuiBadge',
'EuiBetaBadge',
'EuiSelectable',
'EuiComboBox',
'EuiSuperSelect',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/eui/src/components/badge/beta_badge/beta_badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ export type EuiBetaBadgeProps = CommonProps &
> &
BadgeProps;

/**
* @deprecated Use `EuiBadge` instead
*/
export const EuiBetaBadge: FunctionComponent<EuiBetaBadgeProps> = ({
className,
label,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,21 @@ exports[`EuiCard betaBadgeProps renders href 1`] = `
class="emotion-euiCard__betaBadgeAnchor"
>
<a
class="euiBetaBadge emotion-euiBetaBadge-hollow-m-baseline-euiCard__betaBadge"
class="euiBadge emotion-euiBadge-hollow-hollow-euiCard__betaBadge"
href="http://www.elastic.co/"
id="generated-idBetaBadge"
rel="noreferrer"
title="Link"
>
Link
<span
class="euiBadge__content emotion-euiBadge__content"
>
<span
class="euiBadge__text emotion-euiBadge__text-clickable"
>
Link
</span>
</span>
</a>
</span>
</div>
Expand Down
7 changes: 7 additions & 0 deletions packages/eui/src/components/card/card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ export const Playground: Story = {
title: 'Card title',
description: 'Card description',
footer: '',
betaBadgeProps: {
"color": "accent",
"children": "Hello"
},
betaBadgeTooltipProps: {
"content": "hello"
}
},
render: function Render({
icon,
Expand Down
10 changes: 10 additions & 0 deletions packages/eui/src/components/card/card.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,16 @@ export const euiCardBetaBadgeStyles = (

euiCard__betaBadge: css`
${logicalCSS('width', '100%')}

/* Styles to keep visual parity with EuiBetaBadge */
align-items: center;
block-size: ${euiTheme.size.l};
display: flex;
font-weight: ${euiTheme.font.weight.semiBold};
letter-spacing: 0.05em;
padding-inline: ${euiTheme.size.base};
text-align: center;
text-transform: uppercase;
`,
};
};
6 changes: 3 additions & 3 deletions packages/eui/src/components/card/card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ describe('EuiCard', () => {
});

shouldRenderCustomStyles(
<EuiCard title="Card title" betaBadgeProps={{ label: 'beta' }} />,
{ childProps: ['betaBadgeProps', 'betaBadgeProps.anchorProps'] }
<EuiCard title="Card title" betaBadgeProps={{ children: 'beta' }} />,
{ childProps: ['betaBadgeProps', 'betaBadgeTooltipProps.anchorProps'] }
);

describe('props', () => {
Expand Down Expand Up @@ -329,7 +329,7 @@ describe('EuiCard', () => {
description="Card description"
betaBadgeProps={{
href: 'http://www.elastic.co/',
label: 'Link',
children: 'Link',
}}
/>
);
Expand Down
73 changes: 52 additions & 21 deletions packages/eui/src/components/card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import { useGeneratedHtmlId } from '../../services/accessibility';
import { validateHref } from '../../services/security/href_validator';

import { CommonProps, ExclusiveUnion } from '../common';
import { EuiText } from '../text';
import { EuiTitle } from '../title';
import { EuiBetaBadge, EuiBetaBadgeProps } from '../badge/beta_badge';
import { EuiBadge, EuiBadgeProps } from '../badge';
import { EuiIconProps } from '../icon';
import { EuiPanel, EuiPanelProps } from '../panel';
import { EuiSpacer } from '../spacer';
import { EuiText } from '../text';
import { EuiTitle } from '../title';
import { EuiToolTip, EuiToolTipProps } from '../tool_tip';

import { EuiCardSelect, EuiCardSelectProps } from './card_select';
import {
Expand Down Expand Up @@ -114,10 +115,15 @@ export type EuiCardProps = Omit<CommonProps, 'aria-label'> &
target?: string;
rel?: string;
/**
* Adds a badge to top of the card to label it as "Beta" or other non-GA state.
* Accepts all the props of [EuiBetaBadge](#/display/badge#beta-badge-type), where `label` is required.
* Adds a badge to top of the card.
* Accepts all the props of {@link https://eui.elastic.co/docs/components/display/badge/ | EuiBadge}.
*/
betaBadgeProps?: EuiBadgeProps;
/**
* Extends the wrapping {@link https://eui.elastic.co/docs/components/display/tooltip/ | EuiToolTip} props
* when `betaBadgeProps` is provided.
*/
betaBadgeProps?: EuiBetaBadgeProps;
betaBadgeTooltipProps?: Omit<EuiToolTipProps, 'children'>;
/**
* Matches to the color property of EuiPanel. If defined, removes any border & shadow.
* Leave as `undefined` to display as a default panel.
Expand Down Expand Up @@ -155,6 +161,7 @@ export const EuiCard: FunctionComponent<EuiCardProps> = ({
target,
textAlign = 'center',
betaBadgeProps,
betaBadgeTooltipProps,
layout = 'vertical',
selectable,
display,
Expand Down Expand Up @@ -267,37 +274,61 @@ export const EuiCard: FunctionComponent<EuiCardProps> = ({
}

/**
* Optional EuiBetaBadge
* Optional `EuiBadge`
*/

let optionalBetaBadge;
let optionalBetaBadgeID = '';
let optionalBetaCSS;
if (betaBadgeProps?.label) {

if (betaBadgeProps?.children) {
const betaStyles = euiCardBetaBadgeStyles(euiThemeContext, paddingSize);
optionalBetaCSS = betaStyles.hasBetaBadge;

const { anchorProps, ...cleanedBetaBadgeProps } = betaBadgeProps;
const anchorCSS = [betaStyles.euiCard__betaBadgeAnchor, anchorProps?.css];
const { anchorProps: tooltipAnchorProps, ...tooltipPropsRest } =
betaBadgeTooltipProps ?? {};
const { css: tooltipAnchorCss, ...tooltipAnchorRest } =
tooltipAnchorProps ?? {};

const anchorCSS = [betaStyles.euiCard__betaBadgeAnchor, tooltipAnchorCss];
const badgeCSS = [betaStyles.euiCard__betaBadge, betaBadgeProps?.css];

optionalBetaBadgeID = `${ariaId}BetaBadge`;
optionalBetaBadge = (
<EuiBetaBadge
color={
isDisabled && !betaBadgeProps.onClick && !betaBadgeProps.href
? 'subdued'
: 'hollow'
}
{...cleanedBetaBadgeProps}
const defaultBetaBadgeColor =
isDisabled && !betaBadgeProps.onClick && !betaBadgeProps.href
? 'subdued'
: 'hollow';
const badgeColor = betaBadgeProps.color ?? defaultBetaBadgeColor;
const badgeFill =
betaBadgeProps.fill ??
(badgeColor !== 'hollow' &&
badgeColor !== 'subdued' &&
badgeColor !== 'default');

const badge = (
<EuiBadge
{...betaBadgeProps}
color={badgeColor}
css={badgeCSS}
anchorProps={{ ...anchorProps, css: anchorCSS }}
fill={badgeFill}
id={optionalBetaBadgeID}
/>
);

// Increase padding size when there is a beta badge unless it's already determined
// paddingSize = paddingSize || 'l';
const hasTooltip =
betaBadgeTooltipProps?.content != null ||
betaBadgeTooltipProps?.title != null;

optionalBetaBadge = (
// Card positioning must live on an outer wrapper
<span {...tooltipAnchorRest} css={anchorCSS}>
{hasTooltip ? (
<EuiToolTip {...tooltipPropsRest}>{badge}</EuiToolTip>
) : (
badge
)}
</span>
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,19 @@ exports[`EuiKeyPadMenuItem props betaBadge renders 1`] = `
<span
class="euiKeyPadMenuItem__inner emotion-euiKeyPadMenuItem__inner"
>
<span>
<span
aria-hidden="true"
class="euiBadge euiKeyPadMenuItem__betaBadge emotion-euiBadge-default-euiKeyPadMenuItem__betaBadge-euiKeyPadMenuItem__betaBadgeLetter-betaBadge"
title="B"
>
<span
aria-hidden="true"
class="euiBetaBadge euiKeyPadMenuItem__betaBadge emotion-euiBetaBadge-subdued-s-baseline-euiKeyPadMenuItem__betaBadge"
title="B"
class="euiBadge__content emotion-euiBadge__content"
>
B
<span
class="euiBadge__text emotion-euiBadge__text"
>
B
</span>
</span>
</span>
<span
Expand Down Expand Up @@ -152,13 +158,19 @@ exports[`EuiKeyPadMenuItem props betaBadge renders extra betaBadgeTooltipProps 1
<span
class="euiKeyPadMenuItem__inner emotion-euiKeyPadMenuItem__inner"
>
<span>
<span
aria-hidden="true"
class="euiBadge euiKeyPadMenuItem__betaBadge emotion-euiBadge-default-euiKeyPadMenuItem__betaBadge-euiKeyPadMenuItem__betaBadgeLetter-betaBadge"
title="B"
>
<span
aria-hidden="true"
class="euiBetaBadge euiKeyPadMenuItem__betaBadge emotion-euiBetaBadge-subdued-s-baseline-euiKeyPadMenuItem__betaBadge"
title="B"
class="euiBadge__content emotion-euiBadge__content"
>
B
<span
class="euiBadge__text emotion-euiBadge__text"
>
B
</span>
</span>
</span>
<span
Expand Down Expand Up @@ -188,15 +200,15 @@ exports[`EuiKeyPadMenuItem props betaBadge renders with betaBadgeIconType 1`] =
<span
class="euiKeyPadMenuItem__inner emotion-euiKeyPadMenuItem__inner"
>
<span>
<span
aria-hidden="true"
class="euiBadge euiKeyPadMenuItem__betaBadge emotion-euiBadge-iconOnly-default-euiKeyPadMenuItem__betaBadge-betaBadge"
>
<span
aria-hidden="true"
class="euiBetaBadge euiKeyPadMenuItem__betaBadge emotion-euiBetaBadge-subdued-s-baseline-euiKeyPadMenuItem__betaBadge"
title="B"
class="euiBadge__content emotion-euiBadge__content"
>
<span
aria-hidden="true"
class="euiBetaBadge__icon emotion-euiBetaBadge__icon"
class="euiBadge__icon emotion-euiBadge__icon-left"
color="inherit"
data-euiicon-type="bolt"
/>
Expand Down Expand Up @@ -229,13 +241,19 @@ exports[`EuiKeyPadMenuItem props betaBadge renders with betaBadgeTooltipContent
<span
class="euiKeyPadMenuItem__inner emotion-euiKeyPadMenuItem__inner"
>
<span>
<span
aria-hidden="true"
class="euiBadge euiKeyPadMenuItem__betaBadge emotion-euiBadge-default-euiKeyPadMenuItem__betaBadge-euiKeyPadMenuItem__betaBadgeLetter-betaBadge"
title="B"
>
<span
aria-hidden="true"
class="euiBetaBadge euiKeyPadMenuItem__betaBadge emotion-euiBetaBadge-subdued-s-baseline-euiKeyPadMenuItem__betaBadge"
title="B"
class="euiBadge__content emotion-euiBadge__content"
>
B
<span
class="euiBadge__text emotion-euiBadge__text"
>
B
</span>
</span>
</span>
<span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
logicalSizeCSS,
euiCanAnimate,
euiFontSize,
mathWithUnits,
} from '../../global_styling';
import { highContrastModeStyles } from '../../global_styling/functions/high_contrast';
import { euiScreenReaderOnly } from '../accessibility';
Expand Down Expand Up @@ -145,6 +146,20 @@ export const euiKeyPadMenuItemChildStyles = (euiThemeContext: UseEuiTheme) => {
${topRightChildren}
`,

euiKeyPadMenuItem__betaBadgeLetter: css`
align-items: center;
border-radius: 50%;
display: inline-flex;
justify-content: center;
line-height: 1;
padding: 0;

${logicalSizeCSS(
mathWithUnits(euiTheme.size.base, (base) => base * 1.25)
)}
${logicalCSS('max-width', 'none')}
`,

euiKeyPadMenuItem__checkableInput: css`
position: absolute;
${topRightChildren}
Expand Down
Loading
Loading