Aspect Ratio
Hold a child at a fixed width-to-height ratio.
import { Div, Img } from "@implementjs/core";
import { AspectRatio } from "@/lib/components/ui/aspect-ratio";
export default function AspectRatioDemo() {
return Div(
{ class: "w-full max-w-sm" },
AspectRatio(
{ ratio: 16 / 9, class: "overflow-hidden rounded-lg bg-muted" },
Img({
src: "https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80",
alt: "Photo by Alvaro Pinot",
class: "size-full object-cover",
}),
),
);
}Installation
npx jsrepo add @implementjs/ui/aspect-ratio
Nothing else comes with it — this one stands alone on @implementjs/core and @implementjs/primitives.
Copy the file below to src/lib/components/ui/aspect-ratio.ts. It imports cn, so copy utils.ts to src/lib/utils.ts too.
import { type Child, type ComponentProps } from "@implementjs/core";
import { AspectRatio as AspectRatioPrimitive } from "@implementjs/primitives";
import { createComponent } from "@implementjs/primitives";
export type AspectRatioProps = ComponentProps<typeof AspectRatioPrimitive>;
export const AspectRatio = createComponent(function AspectRatio(
props: AspectRatioProps,
...children: Child[]
) {
return AspectRatioPrimitive({ "data-slot": "aspect-ratio", ...props }, ...children);
});Usage
The thinnest component here — the primitive already does the work, and the styled file only adds a data-slot. It is in the registry so that class and the import path match everything else.
Give the ratio as a number, and put the clipping and rounding on the same element.
import { AspectRatio } from "@/lib/components/ui/aspect-ratio";
AspectRatio(
{ ratio: 16 / 9, class: "overflow-hidden rounded-lg bg-muted" },
Img({ src: photo, alt: "", class: "size-full object-cover" }),
);
API Reference
Every prop the styling does not consume is forwarded to the Aspect Ratio primitive, so the tables below are the whole surface — the behavior props and the styling ones together.
AspectRatio
Constrains content to a width / height ratio. Renders a sized wrapper around the root your props and children land on. Renders a Div; extra props are forwarded onto it.
| Prop | Type | Default | Description |
|---|---|---|---|
ratio | Signal<number> | number | 1 | Width divided by height, e.g. 16 / 9. |
| Data attribute | Value |
|---|---|
[data-aspect-ratio-root] | Present |