Box & utility props

Box is a polymorphic layout primitive that carries Bootstrap’s utility API as typed props. Each prop maps 1:1 to the exact Bootstrap utility class — so <Box m={3} d="flex" bg="primary" /> renders as <div class="m-3 d-flex bg-primary" />. You get spacing, flexbox, color, borders, and sizing as props, with full TypeScript autocompletion, instead of hand-writing utility class strings.

Import

tsx
import { Box } from '@metatoy/bootstrap-styled';

How it works

Box doesn’t generate any CSS of its own. It splits its props into two groups: the utility props (m, p, d, flex, bg, rounded, …) are compiled to a space-joined string of real Bootstrap utility class names, and everything else (onClick, id, role, native attributes) passes straight through to the rendered element. The emission is deterministic and memoized per unique prop set.

tsx
<Box p={3} bg="primary" text="white" rounded />
// → <div class="p-3 bg-primary text-white rounded" />

<Box d="flex" justify="between" align="center" gap={2} />
// → <div class="d-flex justify-content-between align-items-center gap-2" />

Box emits class names — it does not ship the CSS that styles them. The utility classes only have any visual effect when Bootstrap’s utility CSS is present on the page. In your app that stylesheet is a theme-owner decision: include Bootstrap’s utilities (for example bootstrap-utilities.css, or the full bootstrap.css) via your global stylesheet or bundler alongside BootstrapStyledProvider. The provider sets the --bs-* design tokens the utilities read, but it deliberately does not inject the utility rules themselves. On this page the demos are rendered against a copy of Bootstrap’s stylesheet that is scoped to the demo areas only, so the classes below show their real effect without restyling the rest of the docs.

Spacing

Margin (m, mt, mb, ms, me, mx, my) and padding (p, pt, …, px, py) take the 05 spacing scale — the same steps the grid gutters and Stack gap use. Margin props also accept 'auto' to push siblings apart.

Display & flexbox

d sets the CSS display value; flex, justify, align, alignSelf, and gap build a flex container. justify maps to justify-content, align to align-items, and gap takes the same 05 scale as spacing.

Background & text color

bg sets a contextual background and text sets the foreground color. Both accept the eight theme colors plus Bootstrap’s body, white/black, *-subtle backgrounds, and *-emphasis / muted text tokens. text also takes the three alignment keywords (start, end, center).

Border, radius & shadow

border toggles all sides (or a single side, or 0 to remove one); pair it with borderColor and borderWidth (05). rounded takes a radius step (05) or a shape (pill, circle, top…). shadow is true (regular), 'sm', or 'lg'.

Sizing

w and h set width and height as a percentage of the parent — 25, 50, 75, 100, or 'auto'.

Position, overflow, opacity & z-index

position, overflow, opacity (0100 in steps of 25), and zIndex (-13) cover the remaining layout utilities for layering and clipping content.

Responsive object values

The responsive utilities — spacing, d, flex, justify, align, alignSelf, and gap — accept a per-breakpoint object whose keys are the tier names (base, sm, md, lg, xl, xxl). Each key emits one class; base has no infix and the rest are breakpoint-infixed, so m={{ base: 2, md: 4 }} becomes m-2 m-md-4. Like the grid, the tiers are mobile-first: a value applies at its breakpoint and every width above it until a larger tier overrides. The non-responsive utilities (bg, text, rounded, shadow, w, h, position, …) take a single value; for responsive alignment or color, reach for className (e.g. className="text-md-center").

Polymorphic as

Box renders a <div> by default. Set as to any element or component to change the tag; the utility props still apply, and native attributes for the chosen element (href on an <a>, type on a <button>) pass through with full typing.

className passthrough

A className you pass is appended after the generated utility classes, so it can add utilities the props don’t cover or override one that does — the later class wins the cascade order for equal specificity.

Props

PropTypeDefaultDescription
asReact.ElementTypeThe element (or component) to render. Defaults to `div`.
classNamestring
mResponsive<MarginScale>
mtResponsive<MarginScale>
mbResponsive<MarginScale>
msResponsive<MarginScale>
meResponsive<MarginScale>
mxResponsive<MarginScale>
myResponsive<MarginScale>
pResponsive<SpaceScale>
ptResponsive<SpaceScale>
pbResponsive<SpaceScale>
psResponsive<SpaceScale>
peResponsive<SpaceScale>
pxResponsive<SpaceScale>
pyResponsive<SpaceScale>
dResponsive<Display>
flexResponsive<FlexValue>
justifyResponsive<Justify>
alignResponsive<Align>
alignSelfResponsive<AlignSelf>
gapResponsive<SpaceScale>
bgBgColor
textTextValue
borderBorder
borderColor"primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | "white" | "black"
borderWidthBorderWidth
roundedRounded
shadowShadow
wSizing
hSizing
position"static" | "relative" | "absolute" | "fixed" | "sticky"
overflow"hidden" | "auto" | "visible" | "scroll"
opacityOpacity
zIndexZIndex

Box also accepts all native attributes of whatever element as resolves to.

Theming

Box reads no theme tokens directly — it only emits class names. The colors, radii, shadows, and spacing you see come from the Bootstrap utility CSS resolving the --bs-* custom properties that BootstrapStyledProvider sets (and flips in dark mode). So a theme override of, say, --bs-primary or --bs-border-radius reshades every Box that uses the matching utility automatically — the same way it reshades the rest of the library. To change the spacing steps or breakpoints the utilities map to, override the corresponding Bootstrap utility CSS rather than styling a Box directly.

Accessibility

Box renders a plain element with no implied semantics — by default a <div>, which is layout only. When a Box represents a real structure (a section, list, navigation region, or interactive control), give it the correct element via as so the semantics and keyboard behavior come for free, and add a label where the element needs one. Utility props change only presentation; keep the DOM order meaningful, since a visual reorder (via flex or order utilities) does not change the order keyboard and screen-reader users encounter.

Explore in Ladle

Note: Ladle doesn’t load Bootstrap’s utility CSS, so the Box stories appear unstyled there — they demonstrate the emitted class names, not the rendered effect. The live demos above are the styled reference.