open-slide

ImagePlaceholder

A typed stand-in for a real image the user has to supply.

ImagePlaceholder is a small runtime component that renders a sized, dashed box with a hint label. Drop it into a slide whenever the layout calls for a real image — a product screenshot, a team photo, a customer dashboard — that you don't have on disk yet.

slides/q2-launch/index.tsx
import { ImagePlaceholder } from '@open-slide/core';

const Hero = () => (
  <ImagePlaceholder hint="Product hero screenshot" width={1280} height={720} />
);

export default [Hero];

The user uploads the real file via the Assets panel, clicks the placeholder in the inspector, and picks Replace… — the JSX is rewritten to a real <img> and the asset import is added at the top of the file. The replacement keeps the placeholder's width and height so the image lands in exactly the same slot.

Props

Prop

Type

Any other <div> attribute is passed through too (except children, style, and className, which the component owns).

When both width and height are set, the placeholder renders the dimensions under the hint so you can eyeball aspect ratios while drafting.

Sizing

Pick one of two modes:

  • Fixed box — pass width and height when the layout has a hard image slot (a hero card, a logo lockup at a known size).
  • Fill the parent — omit both when the placeholder sits inside a flex or grid cell that already controls its size. The component defaults to width: 100%; height: 100%.
// Fixed
<ImagePlaceholder hint="Q3 revenue chart" width={960} height={540} />

// Fill a flex/grid cell
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 32 }}>
  <ImagePlaceholder hint="Before — old dashboard" />
  <ImagePlaceholder hint="After — new dashboard" />
</div>

The hint should describe the content the user has to supply ("Q3 revenue chart"), not its layout role ("hero image").

Replacement workflow

The inspector's Replace… action is wired to a Vite-plugin op called replace-placeholder-with-image. Given an asset path, it:

  1. Confirms the targeted JSX is an <ImagePlaceholder>.

  2. Adds import <ident> from './assets/<file>' if the asset isn't already imported.

  3. Rewrites the element to:

    <img
      src={<ident>}
      alt="<hint>"
      style={{ width, height, objectFit: 'cover', objectPosition: '50% 50%' }}
    />

The asset path must start with ./assets/ (slide-local) or @assets/ (global). If you skip the inspector and want to swap the placeholder by hand, the snippet above is exactly what to write.

Cropping

After replacement the image is a regular <img> with objectFit: 'cover', which means the asset's aspect ratio rarely matches the slot exactly. To reframe the visible region:

  • Double-click the image while the inspector is active, or
  • Click it once and choose Crop in the property panel.

The crop dialog writes objectFit (Fill = cover, Fit = contain) and stores the crop rectangle as an objectViewBox: inset(…) value on the same inline style block — no asset is mutated, so you can reopen the dialog later and adjust.

When to use it

Use a placeholder only when a specific concrete image is required by the deck's topic — a product screenshot, a team photo, a customer logo. Don't use it for decoration or generic stock-photo filler; if a typographic or iconographic solution would do, prefer that.

On this page