[Security Solution][Onboarding] Card icons poor contrast on dark mode (#210870)

## Summary

This PR addresses https://github.com/elastic/kibana/issues/206086
<img width="1142" alt="Screenshot 2025-02-12 at 16 50 32"
src="https://github.com/user-attachments/assets/22d3fe32-729a-499b-8f5e-5a1e30f85e09"
/>
<img width="1097" alt="Screenshot 2025-02-12 at 16 51 10"
src="https://github.com/user-attachments/assets/778d21ac-eec9-4184-9bc0-7714391217c1"
/>


### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
This commit is contained in:
Agustina Nahir Ruidiaz 2025-02-14 13:56:58 +01:00 committed by GitHub
parent d4c40e7821
commit 791be62934
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 84 additions and 14 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before After
Before After

View file

@ -9,12 +9,12 @@ import React from 'react';
import type { OnboardingCardConfig } from '../../../../types';
import { OnboardingCardId } from '../../../../constants';
import { ALERTS_CARD_TITLE } from './translations';
import alertsIcon from './images/alerts_icon.png';
import { getCardIcon } from '../common/card_icon';
export const alertsCardConfig: OnboardingCardConfig = {
id: OnboardingCardId.alerts,
title: ALERTS_CARD_TITLE,
icon: alertsIcon,
icon: () => getCardIcon(OnboardingCardId.alerts),
Component: React.lazy(
() =>
import(

View file

@ -0,0 +1,66 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { useDarkMode } from '@kbn/kibana-react-plugin/public';
import { OnboardingCardId } from '../../../../constants';
import rulesIcon from '../rules/images/rules_icon.png';
import rulesDarkIcon from '../rules/images/rules_icon_dark.png';
import integrationsIcon from '../integrations/images/integrations_icon.png';
import integrationsDarkIcon from '../integrations/images/integrations_icon_dark.png';
import dashboardsIcon from '../dashboards/images/dashboards_icon.png';
import dashboardsDarkIcon from '../dashboards/images/dashboards_icon_dark.png';
import alertsIcon from '../alerts/images/alerts_icon.png';
import alertsDarkIcon from '../alerts/images/alerts_icon_dark.png';
import startMigrationIcon from '../siem_migrations/start_migration/images/start_migration_icon.png';
import startMigrationDarkIcon from '../siem_migrations/start_migration/images/start_migration_icon_dark.png';
interface CardIcons {
[key: string]: {
light: string;
dark: string;
};
}
const cardIcons: CardIcons = {
[OnboardingCardId.rules]: {
light: rulesIcon,
dark: rulesDarkIcon,
},
[OnboardingCardId.integrations]: {
light: integrationsIcon,
dark: integrationsDarkIcon,
},
[OnboardingCardId.dashboards]: {
light: dashboardsIcon,
dark: dashboardsDarkIcon,
},
[OnboardingCardId.alerts]: {
light: alertsIcon,
dark: alertsDarkIcon,
},
[OnboardingCardId.siemMigrationsStart]: {
light: startMigrationIcon,
dark: startMigrationDarkIcon,
},
};
interface CardIconProps {
cardId: OnboardingCardId;
}
export const CardIcon = React.memo<CardIconProps>(({ cardId }) => {
const isDarkMode = useDarkMode();
const icon = cardIcons[cardId]?.[isDarkMode ? 'dark' : 'light'] || '';
if (!icon) return null;
return <img src={icon} alt={`${cardId}-card-icon`} width={24} height={24} />;
});
CardIcon.displayName = 'CardIcon';
export const getCardIcon = (cardId: OnboardingCardId) => <CardIcon cardId={cardId} />;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -9,12 +9,12 @@ import React from 'react';
import type { OnboardingCardConfig } from '../../../../types';
import { OnboardingCardId } from '../../../../constants';
import { DASHBOARDS_CARD_TITLE } from './translations';
import dashboardsIcon from './images/dashboards_icon.png';
import { getCardIcon } from '../common/card_icon';
export const dashboardsCardConfig: OnboardingCardConfig = {
id: OnboardingCardId.dashboards,
title: DASHBOARDS_CARD_TITLE,
icon: dashboardsIcon,
icon: () => getCardIcon(OnboardingCardId.dashboards),
Component: React.lazy(
() =>
import(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

View file

@ -10,15 +10,15 @@ import { i18n } from '@kbn/i18n';
import type { OnboardingCardConfig } from '../../../../types';
import { checkIntegrationsCardComplete } from './integrations_check_complete';
import { OnboardingCardId } from '../../../../constants';
import integrationsIcon from './images/integrations_icon.png';
import type { IntegrationCardMetadata } from './types';
import { getCardIcon } from '../common/card_icon';
export const integrationsCardConfig: OnboardingCardConfig<IntegrationCardMetadata> = {
id: OnboardingCardId.integrations,
title: i18n.translate('xpack.securitySolution.onboarding.integrationsCard.title', {
defaultMessage: 'Add data with integrations',
}),
icon: integrationsIcon,
icon: () => getCardIcon(OnboardingCardId.integrations),
Component: React.lazy(
() =>
import(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

@ -9,13 +9,13 @@ import React from 'react';
import type { OnboardingCardConfig } from '../../../../types';
import { OnboardingCardId } from '../../../../constants';
import { RULES_CARD_TITLE } from './translations';
import rulesIcon from './images/rules_icon.png';
import { checkRulesComplete } from './rules_check_complete';
import { getCardIcon } from '../common/card_icon';
export const rulesCardConfig: OnboardingCardConfig = {
id: OnboardingCardId.rules,
title: RULES_CARD_TITLE,
icon: rulesIcon,
icon: () => getCardIcon(OnboardingCardId.rules),
Component: React.lazy(
() =>
import(

View file

@ -9,14 +9,14 @@ import React from 'react';
import type { OnboardingCardConfig } from '../../../../../types';
import { OnboardingCardId } from '../../../../../constants';
import { START_MIGRATION_CARD_TITLE } from './translations';
import cardIcon from './images/card_header_icon.png';
import type { StartMigrationCardMetadata } from './types';
import { checkStartMigrationCardComplete } from './start_migration_check_complete';
import { getCardIcon } from '../../common/card_icon';
export const startMigrationCardConfig: OnboardingCardConfig<StartMigrationCardMetadata> = {
id: OnboardingCardId.siemMigrationsStart,
title: START_MIGRATION_CARD_TITLE,
icon: cardIcon,
icon: () => getCardIcon(OnboardingCardId.siemMigrationsStart),
licenseTypeRequired: 'enterprise',
Component: React.lazy(
() =>

View file

@ -12,7 +12,7 @@ export const HEIGHT_ANIMATION_DURATION = 250;
export const useCardPanelStyles = () => {
const { euiTheme, colorMode } = useEuiTheme();
const successBackgroundColor = euiTheme.colors.backgroundLightSuccess;
const successBackgroundColor = euiTheme.colors.backgroundBaseSuccess;
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
const darkModeStyles = useDarkPanelStyles(isDarkMode);
@ -24,14 +24,18 @@ export const useCardPanelStyles = () => {
.onboardingCardIcon {
padding: ${euiTheme.size.m};
border-radius: 50%;
background-color: ${euiTheme.colors.backgroundBaseSubdued};
background-color: ${isDarkMode
? euiTheme.colors.lightShade
: euiTheme.colors.backgroundBaseSubdued};
display: flex;
align-items: center;
}
.onboardingCardHeaderTitle {
font-weight: ${euiTheme.font.weight.semiBold};
}
.onboardingCardHeaderCompleteBadge {
background-color: ${successBackgroundColor};
color: ${euiTheme.colors.textSuccess};
background-color: ${isDarkMode ? euiTheme.colors.success : successBackgroundColor};
color: ${isDarkMode ? euiTheme.colors.emptyShade : euiTheme.colors.textSuccess};
}
.onboardingCardContentWrapper {
display: grid;