feat: add Flexoki themes for Shiki syntax highlighting
This commit is contained in:
@@ -5,7 +5,9 @@ import type { Part } from '@opencode-ai/sdk';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { RiFileCopyLine, RiCheckLine, RiDownloadLine } from '@remixicon/react';
|
||||
|
||||
const SHIKI_THEMES = ['vitesse-light', 'vitesse-dark'] as const;
|
||||
import { flexokiStreamdownThemes } from '@/lib/shiki/flexokiThemes';
|
||||
|
||||
const SHIKI_THEMES = flexokiStreamdownThemes;
|
||||
|
||||
// Table utility functions
|
||||
const extractTableData = (tableEl: HTMLTableElement): { headers: string[]; rows: string[][] } => {
|
||||
@@ -243,6 +245,50 @@ const CodeBlockWrapper: React.FC<CodeBlockWrapperProps> = ({ children, className
|
||||
const [copied, setCopied] = React.useState(false);
|
||||
const codeRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
const normalizedStyle = React.useMemo<React.CSSProperties | undefined>(() => {
|
||||
if (!style) return style;
|
||||
|
||||
const next: React.CSSProperties = { ...style };
|
||||
|
||||
const normalizeDeclarationString = (
|
||||
raw: unknown
|
||||
): { value?: string; vars: Record<string, string> } => {
|
||||
if (typeof raw !== 'string') return { value: undefined, vars: {} };
|
||||
|
||||
const [valuePart, ...rest] = raw.split(';').map((p) => p.trim()).filter(Boolean);
|
||||
const vars: Record<string, string> = {};
|
||||
for (const decl of rest) {
|
||||
const idx = decl.indexOf(':');
|
||||
if (idx === -1) continue;
|
||||
const prop = decl.slice(0, idx).trim();
|
||||
const value = decl.slice(idx + 1).trim();
|
||||
if (!prop.startsWith('--') || value.length === 0) continue;
|
||||
vars[prop] = value;
|
||||
}
|
||||
return { value: valuePart, vars };
|
||||
};
|
||||
|
||||
const bg = normalizeDeclarationString((style as React.CSSProperties).backgroundColor);
|
||||
if (bg.value) {
|
||||
next.backgroundColor = bg.value;
|
||||
(next as Record<string, string>)['--shiki-light-bg'] = bg.value;
|
||||
}
|
||||
for (const [k, v] of Object.entries(bg.vars)) {
|
||||
(next as Record<string, string>)[k] = v;
|
||||
}
|
||||
|
||||
const fg = normalizeDeclarationString((style as React.CSSProperties).color);
|
||||
if (fg.value) {
|
||||
next.color = fg.value;
|
||||
(next as Record<string, string>)['--shiki-light'] = fg.value;
|
||||
}
|
||||
for (const [k, v] of Object.entries(fg.vars)) {
|
||||
(next as Record<string, string>)[k] = v;
|
||||
}
|
||||
|
||||
return next;
|
||||
}, [style]);
|
||||
|
||||
const getCodeContent = (): string => {
|
||||
if (!codeRef.current) return '';
|
||||
const codeEl = codeRef.current.querySelector('code');
|
||||
@@ -267,11 +313,7 @@ const CodeBlockWrapper: React.FC<CodeBlockWrapperProps> = ({ children, className
|
||||
<pre
|
||||
{...props}
|
||||
className={cn(className)}
|
||||
style={{
|
||||
...style,
|
||||
background: 'transparent',
|
||||
backgroundColor: 'transparent',
|
||||
}}
|
||||
style={normalizedStyle}
|
||||
>
|
||||
{children}
|
||||
</pre>
|
||||
|
||||
@@ -4,6 +4,8 @@ import { parseDiffFromFile, type FileContents, type FileDiffMetadata } from '@pi
|
||||
|
||||
import { useOptionalThemeSystem } from '@/contexts/useThemeSystem';
|
||||
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
||||
import { ensureFlexokiThemesRegistered } from '@/lib/shiki/registerFlexokiThemes';
|
||||
import { flexokiThemeNames } from '@/lib/shiki/flexokiThemes';
|
||||
|
||||
interface PierreDiffViewerProps {
|
||||
original: string;
|
||||
@@ -51,6 +53,8 @@ export const PierreDiffViewer: React.FC<PierreDiffViewerProps> = ({
|
||||
const themeSystem = useOptionalThemeSystem();
|
||||
const isDark = themeSystem?.currentTheme?.metadata?.variant === 'dark';
|
||||
|
||||
ensureFlexokiThemesRegistered();
|
||||
|
||||
// Cache the last computed diff to avoid recomputing on every render
|
||||
const diffCacheRef = useRef<{
|
||||
key: string;
|
||||
@@ -90,8 +94,8 @@ export const PierreDiffViewer: React.FC<PierreDiffViewerProps> = ({
|
||||
|
||||
const options = useMemo(() => ({
|
||||
theme: {
|
||||
dark: 'vitesse-dark' as const,
|
||||
light: 'vitesse-light' as const,
|
||||
dark: flexokiThemeNames.dark,
|
||||
light: flexokiThemeNames.light,
|
||||
},
|
||||
themeType: isDark ? ('dark' as const) : ('light' as const),
|
||||
diffStyle: renderSideBySide ? ('split' as const) : ('unified' as const),
|
||||
|
||||
Reference in New Issue
Block a user