import { colors, radii, space, type } from '@atiraui/foundations/tokens.stylex' import * as stylex from '@stylexjs/stylex' import { useId, type ComponentPropsWithRef, type ReactNode } from 'react' export type OutcomeState = | { status: 'complete' } | { status: 'failed' } | { status: 'cancelled' } | { status: 'blocked' } | { status: 'reviewable' } type NativeSectionProps = Omit< ComponentPropsWithRef<'section'>, 'children' | 'className' | 'id' | 'style' | 'title' > export type OutcomeProps = NativeSectionProps & { actions?: ReactNode children?: ReactNode headingLevel?: 2 | 3 | 4 | 5 | 6 id: string state: OutcomeState title: ReactNode } const stateLabels: Record = { blocked: 'Blocked', cancelled: 'Cancelled', complete: 'Complete', failed: 'Failed', reviewable: 'Ready for review', } export function Outcome({ actions, children, headingLevel = 2, id, state, title, ...props }: OutcomeProps) { const titleId = useId() const Heading = `h${headingLevel}` as const return (

{stateLabels[state.status]}

{title} {children && (
{children}
)} {actions && (
{actions}
)}
) } const styles = stylex.create({ root: { backgroundColor: colors.surface, borderColor: colors.border, borderRadius: radii.surface, borderStyle: 'solid', borderWidth: '1px', boxSizing: 'border-box', color: colors.text, display: 'flex', flexDirection: 'column', fontFamily: type.family, gap: space.x2, inlineSize: '100%', padding: space.x3, }, state: { color: colors.textMuted, fontSize: type.sizeCaption, fontWeight: type.weightMedium, lineHeight: type.lineCompact, margin: 0, }, failed: { color: colors.danger, }, title: { fontSize: type.sizeTitle, fontWeight: type.weightMedium, lineHeight: type.lineCompact, margin: 0, textWrap: 'balance', }, content: { color: colors.textMuted, fontSize: type.sizeSmall, lineHeight: type.lineBody, maxInlineSize: '65ch', }, actions: { alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: space.x2, paddingBlockStart: space.x1, }, })