mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-27 21:44:25 -07:00
feat(ui): Semantic tokens refactor (#8087)
This commit is contained in:
@@ -6,13 +6,13 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Text } from 'ink';
|
||||
import { Colors } from '../colors.js';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import stringWidth from 'string-width';
|
||||
|
||||
// Constants for Markdown parsing
|
||||
const BOLD_MARKER_LENGTH = 2; // For "**"
|
||||
const ITALIC_MARKER_LENGTH = 1; // For "*" or "_"
|
||||
const STRIKETHROUGH_MARKER_LENGTH = 2; // For "~~"
|
||||
const STRIKETHROUGH_MARKER_LENGTH = 2; // For "~~")
|
||||
const INLINE_CODE_MARKER_LENGTH = 1; // For "`"
|
||||
const UNDERLINE_TAG_START_LENGTH = 3; // For "<u>"
|
||||
const UNDERLINE_TAG_END_LENGTH = 4; // For "</u>"
|
||||
@@ -24,7 +24,7 @@ interface RenderInlineProps {
|
||||
const RenderInlineInternal: React.FC<RenderInlineProps> = ({ text }) => {
|
||||
// Early return for plain text without markdown or URLs
|
||||
if (!/[*_~`<[https?:]/.test(text)) {
|
||||
return <Text>{text}</Text>;
|
||||
return <Text color={theme.text.primary}>{text}</Text>;
|
||||
}
|
||||
|
||||
const nodes: React.ReactNode[] = [];
|
||||
@@ -96,7 +96,7 @@ const RenderInlineInternal: React.FC<RenderInlineProps> = ({ text }) => {
|
||||
const codeMatch = fullMatch.match(/^(`+)(.+?)\1$/s);
|
||||
if (codeMatch && codeMatch[2]) {
|
||||
renderedNode = (
|
||||
<Text key={key} color={Colors.AccentPurple}>
|
||||
<Text key={key} color={theme.text.accent}>
|
||||
{codeMatch[2]}
|
||||
</Text>
|
||||
);
|
||||
@@ -113,7 +113,7 @@ const RenderInlineInternal: React.FC<RenderInlineProps> = ({ text }) => {
|
||||
renderedNode = (
|
||||
<Text key={key}>
|
||||
{linkText}
|
||||
<Text color={Colors.AccentBlue}> ({url})</Text>
|
||||
<Text color={theme.text.link}> ({url})</Text>
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ const RenderInlineInternal: React.FC<RenderInlineProps> = ({ text }) => {
|
||||
);
|
||||
} else if (fullMatch.match(/^https?:\/\//)) {
|
||||
renderedNode = (
|
||||
<Text key={key} color={Colors.AccentBlue}>
|
||||
<Text key={key} color={theme.text.link}>
|
||||
{fullMatch}
|
||||
</Text>
|
||||
);
|
||||
@@ -168,6 +168,6 @@ export const getPlainTextLength = (text: string): number => {
|
||||
.replace(/~~(.*?)~~/g, '$1')
|
||||
.replace(/`(.*?)`/g, '$1')
|
||||
.replace(/<u>(.*?)<\/u>/g, '$1')
|
||||
.replace(/\[(.*?)\]\(.*?\)/g, '$1');
|
||||
.replace(/.*\[(.*?)\]\(.*\)/g, '$1');
|
||||
return stringWidth(cleanText);
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import React from 'react';
|
||||
import { Text, Box } from 'ink';
|
||||
import { EOL } from 'node:os';
|
||||
import { Colors } from '../colors.js';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { colorizeCode } from './CodeColorizer.js';
|
||||
import { TableRenderer } from './TableRenderer.js';
|
||||
import { RenderInline } from './InlineMarkdownRenderer.js';
|
||||
@@ -174,14 +174,14 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
switch (level) {
|
||||
case 1:
|
||||
headerNode = (
|
||||
<Text bold color={Colors.AccentCyan}>
|
||||
<Text bold color={theme.text.link}>
|
||||
<RenderInline text={headerText} />
|
||||
</Text>
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
headerNode = (
|
||||
<Text bold color={Colors.AccentBlue}>
|
||||
<Text bold color={theme.text.link}>
|
||||
<RenderInline text={headerText} />
|
||||
</Text>
|
||||
);
|
||||
@@ -195,14 +195,14 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
break;
|
||||
case 4:
|
||||
headerNode = (
|
||||
<Text italic color={Colors.Gray}>
|
||||
<Text italic color={theme.text.secondary}>
|
||||
<RenderInline text={headerText} />
|
||||
</Text>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
headerNode = (
|
||||
<Text>
|
||||
<Text color={theme.text.primary}>
|
||||
<RenderInline text={headerText} />
|
||||
</Text>
|
||||
);
|
||||
@@ -246,7 +246,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
||||
} else {
|
||||
addContentBlock(
|
||||
<Box key={key}>
|
||||
<Text wrap="wrap">
|
||||
<Text wrap="wrap" color={theme.text.primary}>
|
||||
<RenderInline text={line} />
|
||||
</Text>
|
||||
</Box>,
|
||||
@@ -315,7 +315,9 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
||||
// Not enough space to even show the message meaningfully
|
||||
return (
|
||||
<Box paddingLeft={CODE_BLOCK_PREFIX_PADDING}>
|
||||
<Text color={Colors.Gray}>... code is being written ...</Text>
|
||||
<Text color={theme.text.secondary}>
|
||||
... code is being written ...
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -331,7 +333,7 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
||||
return (
|
||||
<Box paddingLeft={CODE_BLOCK_PREFIX_PADDING} flexDirection="column">
|
||||
{colorizedTruncatedCode}
|
||||
<Text color={Colors.Gray}>... generating more ...</Text>
|
||||
<Text color={theme.text.secondary}>... generating more ...</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Text, Box } from 'ink';
|
||||
import { Colors } from '../colors.js';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { RenderInline, getPlainTextLength } from './InlineMarkdownRenderer.js';
|
||||
|
||||
interface TableRendererProps {
|
||||
@@ -89,7 +89,7 @@ export const TableRenderer: React.FC<TableRendererProps> = ({
|
||||
return (
|
||||
<Text>
|
||||
{isHeader ? (
|
||||
<Text bold color={Colors.AccentCyan}>
|
||||
<Text bold color={theme.text.link}>
|
||||
<RenderInline text={cellContent} />
|
||||
</Text>
|
||||
) : (
|
||||
@@ -112,7 +112,7 @@ export const TableRenderer: React.FC<TableRendererProps> = ({
|
||||
const borderParts = adjustedWidths.map((w) => char.horizontal.repeat(w));
|
||||
const border = char.left + borderParts.join(char.middle) + char.right;
|
||||
|
||||
return <Text>{border}</Text>;
|
||||
return <Text color={theme.border.default}>{border}</Text>;
|
||||
};
|
||||
|
||||
// Helper function to render a table row
|
||||
@@ -123,7 +123,7 @@ export const TableRenderer: React.FC<TableRendererProps> = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<Text>
|
||||
<Text color={theme.text.primary}>
|
||||
│{' '}
|
||||
{renderedCells.map((cell, index) => (
|
||||
<React.Fragment key={index}>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { Colors } from '../colors.js';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
|
||||
// --- Thresholds ---
|
||||
export const TOOL_SUCCESS_RATE_HIGH = 95;
|
||||
@@ -23,10 +23,10 @@ export const getStatusColor = (
|
||||
options: { defaultColor?: string } = {},
|
||||
) => {
|
||||
if (value >= thresholds.green) {
|
||||
return Colors.AccentGreen;
|
||||
return theme.status.success;
|
||||
}
|
||||
if (value >= thresholds.yellow) {
|
||||
return Colors.AccentYellow;
|
||||
return theme.status.warning;
|
||||
}
|
||||
return options.defaultColor || Colors.AccentRed;
|
||||
return options.defaultColor || theme.status.error;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user