From e20d282088f77bb2fef21bc6f3f48af5689bec47 Mon Sep 17 00:00:00 2001 From: Adib234 <30782825+Adib234@users.noreply.github.com> Date: Thu, 20 Nov 2025 08:52:15 -0800 Subject: [PATCH] Update banner design (#13420) --- packages/cli/src/ui/components/AppHeader.tsx | 17 ++--- packages/cli/src/ui/components/Banner.tsx | 71 +++++++++++++++---- .../ui/components/GradientRegression.test.tsx | 2 +- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/packages/cli/src/ui/components/AppHeader.tsx b/packages/cli/src/ui/components/AppHeader.tsx index d66fad4a95..05e528f6c7 100644 --- a/packages/cli/src/ui/components/AppHeader.tsx +++ b/packages/cli/src/ui/components/AppHeader.tsx @@ -10,11 +10,9 @@ import { Tips } from './Tips.js'; import { useSettings } from '../contexts/SettingsContext.js'; import { useConfig } from '../contexts/ConfigContext.js'; import { useUIState } from '../contexts/UIStateContext.js'; -import { Banner } from './Banner.js'; -import { theme } from '../semantic-colors.js'; -import { Colors } from '../colors.js'; import { persistentState } from '../../utils/persistentState.js'; -import { useState, useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; +import { Banner } from './Banner.js'; interface AppHeaderProps { version: string; @@ -35,11 +33,8 @@ export const AppHeader = ({ version }: AppHeaderProps) => { warningText === '' && !config.getPreviewFeatures() && defaultBannerShownCount < 5; - const bannerText = showDefaultBanner ? defaultText : warningText; - const unescapedBannerText = bannerText.replace(/\\n/g, '\n'); - const defaultColor = Colors.AccentBlue; - const fontColor = warningText === '' ? defaultColor : theme.status.warning; + const bannerText = showDefaultBanner ? defaultText : warningText; const hasIncrementedRef = useRef(false); useEffect(() => { @@ -55,11 +50,11 @@ export const AppHeader = ({ version }: AppHeaderProps) => { {!(settings.merged.ui?.hideBanner || config.getScreenReader()) && ( <>
- {bannerVisible && unescapedBannerText && ( + {bannerVisible && bannerText && ( )} diff --git a/packages/cli/src/ui/components/Banner.tsx b/packages/cli/src/ui/components/Banner.tsx index 460bef540f..99f573a68e 100644 --- a/packages/cli/src/ui/components/Banner.tsx +++ b/packages/cli/src/ui/components/Banner.tsx @@ -6,24 +6,65 @@ import { Box, Text } from 'ink'; import { ThemedGradient } from './ThemedGradient.js'; +import { theme } from '../semantic-colors.js'; +import type { ReactNode } from 'react'; + +export function getFormattedBannerContent( + rawText: string, + isWarning: boolean, + subsequentLineColor: string, +): ReactNode { + if (isWarning) { + return ( + {rawText.replace(/\\n/g, '\n')} + ); + } + + const text = rawText.replace(/\\n/g, '\n'); + const lines = text.split('\n'); + + return lines.map((line, index) => { + if (index === 0) { + return ( + + {line} + + ); + } + + return ( + + {line} + + ); + }); +} interface BannerProps { bannerText: string; - color: string; + isWarning: boolean; width: number; } -export const Banner = ({ bannerText, color, width }: BannerProps) => ( - - - {bannerText} - - -); +export const Banner = ({ bannerText, isWarning, width }: BannerProps) => { + const subsequentLineColor = theme.text.primary; + + const formattedBannerContent = getFormattedBannerContent( + bannerText, + isWarning, + subsequentLineColor, + ); + + return ( + + {formattedBannerContent} + + ); +}; diff --git a/packages/cli/src/ui/components/GradientRegression.test.tsx b/packages/cli/src/ui/components/GradientRegression.test.tsx index af6d5c1df0..ab0990b370 100644 --- a/packages/cli/src/ui/components/GradientRegression.test.tsx +++ b/packages/cli/src/ui/components/GradientRegression.test.tsx @@ -88,7 +88,7 @@ describe('Gradient Crash Regression Tests', () => { it(' should not crash when theme.ui.gradient is empty', () => { const { lastFrame } = renderWithProviders( - , + , { width: 120, },