Update banner design (#13420)

This commit is contained in:
Adib234
2025-11-20 08:52:15 -08:00
committed by GitHub
parent 4adfdad47f
commit e20d282088
3 changed files with 63 additions and 27 deletions

View File

@@ -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()) && (
<>
<Header version={version} nightly={nightly} />
{bannerVisible && unescapedBannerText && (
{bannerVisible && bannerText && (
<Banner
width={mainAreaWidth}
bannerText={unescapedBannerText}
color={fontColor}
bannerText={bannerText}
isWarning={warningText !== ''}
/>
)}
</>

View File

@@ -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 (
<Text color={theme.status.warning}>{rawText.replace(/\\n/g, '\n')}</Text>
);
}
const text = rawText.replace(/\\n/g, '\n');
const lines = text.split('\n');
return lines.map((line, index) => {
if (index === 0) {
return (
<ThemedGradient key={index}>
<Text>{line}</Text>
</ThemedGradient>
);
}
return (
<Text key={index} color={subsequentLineColor}>
{line}
</Text>
);
});
}
interface BannerProps {
bannerText: string;
color: string;
isWarning: boolean;
width: number;
}
export const Banner = ({ bannerText, color, width }: BannerProps) => (
<Box
flexDirection="column"
borderStyle="round"
borderColor={color}
width={width}
paddingLeft={1}
paddingRight={1}
>
<ThemedGradient>
<Text>{bannerText}</Text>
</ThemedGradient>
</Box>
);
export const Banner = ({ bannerText, isWarning, width }: BannerProps) => {
const subsequentLineColor = theme.text.primary;
const formattedBannerContent = getFormattedBannerContent(
bannerText,
isWarning,
subsequentLineColor,
);
return (
<Box
flexDirection="column"
borderStyle="round"
borderColor={isWarning ? theme.status.warning : theme.border.default}
width={width}
paddingLeft={1}
paddingRight={1}
>
{formattedBannerContent}
</Box>
);
};

View File

@@ -88,7 +88,7 @@ describe('Gradient Crash Regression Tests', () => {
it('<Banner /> should not crash when theme.ui.gradient is empty', () => {
const { lastFrame } = renderWithProviders(
<Banner bannerText="Test Banner" color="blue" width={80} />,
<Banner bannerText="Test Banner" isWarning={false} width={80} />,
{
width: 120,
},