Navigated to /docs/ui/shared-component-props

Shared component props

Understand BaseProps, shared values, responsive styling, polymorphic roots, passthrough, and where props are applied.

Shared component props

Most single-root Tavo.js UI components extend BaseProps. A component can narrow that contract when it owns a native control or a structured composition, so its component page remains the final authority.

PropTypeBehavior
childrenChild

Content rendered by the component.

classNamestring

A class added to the public root element.

sxSx

Token-aware local styles compiled into the overrides layer.

styleRecord<string, unknown>

Inline styles forwarded to the public root.

id, role, tabIndexnative values

Identity, semantics, and keyboard order for the root.

hidden, disabledboolean

Native state where the rendered element supports it.

eventsevent handlers

Click, change, input, keyboard, focus, and blur handlers.

aria-* and data-*unknown

Accessible state and application-owned data attributes.

Sizes, tones, spacing, and responsive values

  • Size is sm, md, or lg. Interactive controls normally default to md.

  • Shared semantic tones are primary, secondary, neutral, success, warning, danger, and info. Individual components intentionally expose only the tones they can represent.

  • Spacing is sm, md, or lg. Gap additionally accepts none; layout gaps may also accept numbers or CSS strings.

  • ResponsiveValue<T> accepts one static value or an object keyed by base, sm, md, and lg.

  • Numeric responsive gaps become pixel values. Named gaps resolve through theme spacing tokens; CSS strings pass through unchanged.

TSX
tsximport { Flex, Grid, Stack } from "@tavojs/ui";

export const ResultsLayout = () => {
  return (
    <Stack gap={{ base: "sm", lg: "lg" }}>
      <Flex direction={{ base: "column", md: "row" }} gap="md" />
      <Grid columns={{ base: 1, sm: 2, lg: 4 }} spacing="md" />
    </Stack>
  );
};

Know where sx is applied

sx converts camelCase declarations to CSS, supports nested selectors containing &, and emits mobile-first breakpoint rules. Generated rules live in @layer tavo-ui.overrides, after component styles. The runtime keeps a bounded cache of 256 style records and retains styles while their elements remain mounted.

  • base applies at every width; sm, md, and lg add min-width rules.

  • Use &:hover, &:focus-visible, &[data-state='open'], and descendant selectors for local states.

  • Nested at-rules are supported. A nested object without an at-rule or & selector is ignored rather than converted to CSS.

  • sx is consumed by Tavo.js UI. It is not forwarded as a DOM attribute.

  • A raw DOM node or arbitrary custom component does not process sx unless a Tavo.js UI component owns that prop.

Polymorphic roots and forwarding

Single-root primitives that expose as use it in place of the component default. A custom component receives the generated className, style, children, accessibility attributes, events, and remaining public props and must forward them to its real root.

  • Changing the root changes native behavior; styling does not recreate button, link, landmark, or heading semantics.

  • Do not replace owned input, table, dialog, or menu structure with as.

  • Button does not infer anchor rendering from href. Use as="a" or a routing adapter.

  • When a disabled Button renders as an anchor or custom component, href is removed, aria-disabled is set, and tabIndex becomes -1.