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
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.
<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 fullbootstrap.css) via your global stylesheet or bundler alongsideBootstrapStyledProvider. 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 0–5 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 0–5 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 (0–5). rounded takes a radius step (0–5) 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 (0–100 in steps of 25), and zIndex (-1–3) 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
| Prop | Type | Default | Description |
|---|---|---|---|
| as | React.ElementType | — | The element (or component) to render. Defaults to `div`. |
| className | string | — | — |
| m | Responsive<MarginScale> | — | — |
| mt | Responsive<MarginScale> | — | — |
| mb | Responsive<MarginScale> | — | — |
| ms | Responsive<MarginScale> | — | — |
| me | Responsive<MarginScale> | — | — |
| mx | Responsive<MarginScale> | — | — |
| my | Responsive<MarginScale> | — | — |
| p | Responsive<SpaceScale> | — | — |
| pt | Responsive<SpaceScale> | — | — |
| pb | Responsive<SpaceScale> | — | — |
| ps | Responsive<SpaceScale> | — | — |
| pe | Responsive<SpaceScale> | — | — |
| px | Responsive<SpaceScale> | — | — |
| py | Responsive<SpaceScale> | — | — |
| d | Responsive<Display> | — | — |
| flex | Responsive<FlexValue> | — | — |
| justify | Responsive<Justify> | — | — |
| align | Responsive<Align> | — | — |
| alignSelf | Responsive<AlignSelf> | — | — |
| gap | Responsive<SpaceScale> | — | — |
| bg | BgColor | — | — |
| text | TextValue | — | — |
| border | Border | — | — |
| borderColor | "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | "white" | "black" | — | — |
| borderWidth | BorderWidth | — | — |
| rounded | Rounded | — | — |
| shadow | Shadow | — | — |
| w | Sizing | — | — |
| h | Sizing | — | — |
| position | "static" | "relative" | "absolute" | "fixed" | "sticky" | — | — |
| overflow | "hidden" | "auto" | "visible" | "scroll" | — | — |
| opacity | Opacity | — | — |
| zIndex | ZIndex | — | — |
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.