import React, { type PropsWithChildren, type Ref } from 'react' import Box from '../components/Box.js' import type { DOMElement } from '../core/dom.js' import type { ClickEvent } from '../core/events/click-event.js' import type { FocusEvent } from '../core/events/focus-event.js' import type { KeyboardEvent } from '../core/events/keyboard-event.js' import type { Color, Styles } from '../core/styles.js' import { getTheme, type Theme } from './theme-types.js' import { useTheme } from './ThemeProvider.js' // Color props that accept theme keys type ThemedColorProps = { readonly borderColor?: keyof Theme | Color readonly borderTopColor?: keyof Theme | Color readonly borderBottomColor?: keyof Theme | Color readonly borderLeftColor?: keyof Theme | Color readonly borderRightColor?: keyof Theme | Color readonly backgroundColor?: keyof Theme | Color } // Base Styles without color props (they'll be overridden) type BaseStylesWithoutColors = Omit< Styles, | 'textWrap' | 'borderColor' | 'borderTopColor' | 'borderBottomColor' | 'borderLeftColor' | 'borderRightColor' | 'backgroundColor' > export type Props = BaseStylesWithoutColors & ThemedColorProps & { ref?: Ref tabIndex?: number autoFocus?: boolean onClick?: (event: ClickEvent) => void onFocus?: (event: FocusEvent) => void onFocusCapture?: (event: FocusEvent) => void onBlur?: (event: FocusEvent) => void onBlurCapture?: (event: FocusEvent) => void onKeyDown?: (event: KeyboardEvent) => void onKeyDownCapture?: (event: KeyboardEvent) => void onMouseEnter?: () => void onMouseLeave?: () => void } /** * Resolves a color value that may be a theme key to a raw Color. */ function resolveColor( color: keyof Theme | Color | undefined, theme: Theme, ): Color | undefined { if (!color) return undefined // Check if it's a raw color (starts with rgb(, #, ansi256(, or ansi:) if ( color.startsWith('rgb(') || color.startsWith('#') || color.startsWith('ansi256(') || color.startsWith('ansi:') ) { return color as Color } // It's a theme key - resolve it return theme[color as keyof Theme] as Color } /** * Theme-aware Box component that resolves theme color keys to raw colors. * This wraps the base Box component with theme resolution for border colors. */ function ThemedBox({ borderColor, borderTopColor, borderBottomColor, borderLeftColor, borderRightColor, backgroundColor, children, ref, ...rest }: PropsWithChildren): React.ReactNode { const [themeName] = useTheme() const theme = getTheme(themeName) // Resolve theme keys to raw colors const resolvedBorderColor = resolveColor(borderColor, theme) const resolvedBorderTopColor = resolveColor(borderTopColor, theme) const resolvedBorderBottomColor = resolveColor(borderBottomColor, theme) const resolvedBorderLeftColor = resolveColor(borderLeftColor, theme) const resolvedBorderRightColor = resolveColor(borderRightColor, theme) const resolvedBackgroundColor = resolveColor(backgroundColor, theme) return ( {children} ) } export default ThemedBox