import React, { type PropsWithChildren, type Ref } from 'react' import type { Except } from 'type-fest' 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 { Styles } from '../core/styles.js' import * as warn from '../core/warn.js' export type Props = Except & { ref?: Ref /** * Tab order index. Nodes with `tabIndex >= 0` participate in * Tab/Shift+Tab cycling; `-1` means programmatically focusable only. */ tabIndex?: number /** * Focus this element when it mounts. Like the HTML `autofocus` * attribute — the FocusManager calls `focus(node)` during the * reconciler's `commitMount` phase. */ autoFocus?: boolean /** * Fired on left-button click (press + release without drag). Only works * inside `` where mouse tracking is enabled — no-op * otherwise. The event bubbles from the deepest hit Box up through * ancestors; call `event.stopImmediatePropagation()` to stop bubbling. */ 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 /** * Fired when the mouse moves into this Box's rendered rect. Like DOM * `mouseenter`, does NOT bubble — moving between children does not * re-fire on the parent. Only works inside `` where * mode-1003 mouse tracking is enabled. */ onMouseEnter?: () => void /** Fired when the mouse moves out of this Box's rendered rect. */ onMouseLeave?: () => void } /** * `` is an essential Ink component to build your layout. It's like `
` in the browser. */ function Box({ children, flexWrap = 'nowrap', flexDirection = 'row', flexGrow = 0, flexShrink = 1, ref, tabIndex, autoFocus, onClick, onFocus, onFocusCapture, onBlur, onBlurCapture, onMouseEnter, onMouseLeave, onKeyDown, onKeyDownCapture, ...style }: PropsWithChildren): React.ReactNode { // Warn if spacing values are not integers to prevent fractional layout dimensions warn.ifNotInteger(style.margin, 'margin') warn.ifNotInteger(style.marginX, 'marginX') warn.ifNotInteger(style.marginY, 'marginY') warn.ifNotInteger(style.marginTop, 'marginTop') warn.ifNotInteger(style.marginBottom, 'marginBottom') warn.ifNotInteger(style.marginLeft, 'marginLeft') warn.ifNotInteger(style.marginRight, 'marginRight') warn.ifNotInteger(style.padding, 'padding') warn.ifNotInteger(style.paddingX, 'paddingX') warn.ifNotInteger(style.paddingY, 'paddingY') warn.ifNotInteger(style.paddingTop, 'paddingTop') warn.ifNotInteger(style.paddingBottom, 'paddingBottom') warn.ifNotInteger(style.paddingLeft, 'paddingLeft') warn.ifNotInteger(style.paddingRight, 'paddingRight') warn.ifNotInteger(style.gap, 'gap') warn.ifNotInteger(style.columnGap, 'columnGap') warn.ifNotInteger(style.rowGap, 'rowGap') return ( {children} ) } export default Box